Commit db12847c authored by Ido Yariv's avatar Ido Yariv Committed by Johannes Berg

mac80211: Re-fix accounting of the tailroom-needed counter

When hw acceleration is enabled, the GENERATE_IV or PUT_IV_SPACE flags
only require headroom space. Therefore, the tailroom-needed counter can
safely be decremented for most drivers.

The older incarnation of this patch (ca34e3b5) assumed that the above
holds true for all drivers. As reported by Christopher Chavez and
researched by Christian Lamparter and Larry Finger, this isn't a valid
assumption for p54 and cw1200.

Drivers that still require tailroom for ICV/MIC even when HW encryption
is enabled can use IEEE80211_KEY_FLAG_RESERVE_TAILROOM to indicate it.
Signed-off-by: default avatarIdo Yariv <idox.yariv@intel.com>
Cc: Christopher Chavez <chrischavez@gmx.us>
Cc: Christian Lamparter <chunkeey@googlemail.com>
Cc: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Solomon Peachy <pizza@shaftnet.org>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 3a4b0c94
...@@ -709,7 +709,8 @@ int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, ...@@ -709,7 +709,8 @@ int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
if (sta) if (sta)
peer_addr = sta->addr; peer_addr = sta->addr;
key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE |
IEEE80211_KEY_FLAG_RESERVE_TAILROOM;
switch (key->cipher) { switch (key->cipher) {
case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP40:
......
...@@ -575,6 +575,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, ...@@ -575,6 +575,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
key->hw_key_idx = 0xff; key->hw_key_idx = 0xff;
goto out_unlock; goto out_unlock;
} }
key->flags |= IEEE80211_KEY_FLAG_RESERVE_TAILROOM;
} else { } else {
slot = key->hw_key_idx; slot = key->hw_key_idx;
......
...@@ -1281,7 +1281,8 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); ...@@ -1281,7 +1281,8 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev);
* *
* @IEEE80211_KEY_FLAG_GENERATE_IV: This flag should be set by the * @IEEE80211_KEY_FLAG_GENERATE_IV: This flag should be set by the
* driver to indicate that it requires IV generation for this * driver to indicate that it requires IV generation for this
* particular key. * particular key. Setting this flag does not necessarily mean that SKBs
* will have sufficient tailroom for ICV or MIC.
* @IEEE80211_KEY_FLAG_GENERATE_MMIC: This flag should be set by * @IEEE80211_KEY_FLAG_GENERATE_MMIC: This flag should be set by
* the driver for a TKIP key if it requires Michael MIC * the driver for a TKIP key if it requires Michael MIC
* generation in software. * generation in software.
...@@ -1293,7 +1294,9 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); ...@@ -1293,7 +1294,9 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev);
* @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver
* if space should be prepared for the IV, but the IV * if space should be prepared for the IV, but the IV
* itself should not be generated. Do not set together with * itself should not be generated. Do not set together with
* @IEEE80211_KEY_FLAG_GENERATE_IV on the same key. * @IEEE80211_KEY_FLAG_GENERATE_IV on the same key. Setting this flag does
* not necessarily mean that SKBs will have sufficient tailroom for ICV or
* MIC.
* @IEEE80211_KEY_FLAG_RX_MGMT: This key will be used to decrypt received * @IEEE80211_KEY_FLAG_RX_MGMT: This key will be used to decrypt received
* management frames. The flag can help drivers that have a hardware * management frames. The flag can help drivers that have a hardware
* crypto implementation that doesn't deal with management frames * crypto implementation that doesn't deal with management frames
...@@ -1304,6 +1307,9 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); ...@@ -1304,6 +1307,9 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev);
* @IEEE80211_KEY_FLAG_GENERATE_IV_MGMT: This flag should be set by the * @IEEE80211_KEY_FLAG_GENERATE_IV_MGMT: This flag should be set by the
* driver for a CCMP key to indicate that is requires IV generation * driver for a CCMP key to indicate that is requires IV generation
* only for managment frames (MFP). * only for managment frames (MFP).
* @IEEE80211_KEY_FLAG_RESERVE_TAILROOM: This flag should be set by the
* driver for a key to indicate that sufficient tailroom must always
* be reserved for ICV or MIC, even when HW encryption is enabled.
*/ */
enum ieee80211_key_flags { enum ieee80211_key_flags {
IEEE80211_KEY_FLAG_GENERATE_IV_MGMT = BIT(0), IEEE80211_KEY_FLAG_GENERATE_IV_MGMT = BIT(0),
...@@ -1313,6 +1319,7 @@ enum ieee80211_key_flags { ...@@ -1313,6 +1319,7 @@ enum ieee80211_key_flags {
IEEE80211_KEY_FLAG_SW_MGMT_TX = BIT(4), IEEE80211_KEY_FLAG_SW_MGMT_TX = BIT(4),
IEEE80211_KEY_FLAG_PUT_IV_SPACE = BIT(5), IEEE80211_KEY_FLAG_PUT_IV_SPACE = BIT(5),
IEEE80211_KEY_FLAG_RX_MGMT = BIT(6), IEEE80211_KEY_FLAG_RX_MGMT = BIT(6),
IEEE80211_KEY_FLAG_RESERVE_TAILROOM = BIT(7),
}; };
/** /**
......
...@@ -141,8 +141,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) ...@@ -141,8 +141,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM)))
(key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
sdata->crypto_tx_tailroom_needed_cnt--; sdata->crypto_tx_tailroom_needed_cnt--;
WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
...@@ -191,8 +190,7 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) ...@@ -191,8 +190,7 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
sdata = key->sdata; sdata = key->sdata;
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM)))
(key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
increment_tailroom_need_count(sdata); increment_tailroom_need_count(sdata);
ret = drv_set_key(key->local, DISABLE_KEY, sdata, ret = drv_set_key(key->local, DISABLE_KEY, sdata,
...@@ -889,8 +887,7 @@ void ieee80211_remove_key(struct ieee80211_key_conf *keyconf) ...@@ -889,8 +887,7 @@ void ieee80211_remove_key(struct ieee80211_key_conf *keyconf)
key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM)))
(key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
increment_tailroom_need_count(key->sdata); increment_tailroom_need_count(key->sdata);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment