@@ -192,7 +192,9 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
if (info->control.hw_key &&
!(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
- !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
+ !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
+ !(info->control.hw_key->flags &
+ IEEE80211_KEY_FLAG_RESERVE_TAILROOM)) {
/* hwaccel - with no need for software-generated IV */
return 0;
}
@@ -200,7 +202,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
hdrlen = ieee80211_hdrlen(hdr->frame_control);
len = skb->len - hdrlen;
- if (info->control.hw_key)
+ if (info->control.hw_key && !(info->control.hw_key->flags &
+ IEEE80211_KEY_FLAG_RESERVE_TAILROOM))
tail = 0;
else
tail = IEEE80211_TKIP_ICV_LEN;
@@ -227,8 +230,12 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
spin_unlock(&key->u.tkip.txlock);
/* hwaccel - with software IV */
- if (info->control.hw_key)
+ if (info->control.hw_key) {
+ if (info->control.hw_key->flags &
+ IEEE80211_KEY_FLAG_RESERVE_TAILROOM)
+ skb_put(skb, tail);
return 0;
+ }
/* Add room for ICV */
skb_put(skb, IEEE80211_TKIP_ICV_LEN);
@@ -411,6 +418,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb,
if (info->control.hw_key &&
!(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
!(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
+ !(info->control.hw_key->flags &
+ IEEE80211_KEY_FLAG_RESERVE_TAILROOM) &&
!((info->control.hw_key->flags &
IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) &&
ieee80211_is_mgmt(hdr->frame_control))) {
@@ -424,7 +433,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb,
hdrlen = ieee80211_hdrlen(hdr->frame_control);
len = skb->len - hdrlen;
- if (info->control.hw_key)
+ if (info->control.hw_key && !(info->control.hw_key->flags &
+ IEEE80211_KEY_FLAG_RESERVE_TAILROOM))
tail = 0;
else
tail = mic_len;
@@ -456,8 +466,12 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb,
ccmp_pn2hdr(pos, pn, key->conf.keyidx);
/* hwaccel - with software CCMP header */
- if (info->control.hw_key)
+ if (info->control.hw_key) {
+ if (info->control.hw_key->flags &
+ IEEE80211_KEY_FLAG_RESERVE_TAILROOM)
+ skb_put(skb, tail);
return 0;
+ }
pos += IEEE80211_CCMP_HDR_LEN;
ccmp_special_blocks(skb, pn, b_0, aad);
The change reserves neccessary tailroom in CCMP and TKIP if required by drivers that sets IEEE80211_KEY_FLAG_RESERVE_TAILROOM. For example, ath10k HW engine in raw Tx/Rx encap mode requires SW reserve MIC/ICV space. Signed-off-by: David Liu <cfliu.tw@gmail.com> --- net/mac80211/wpa.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-)