aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211/ieee80211_tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee80211/ieee80211_tx.c')
-rw-r--r--net/ieee80211/ieee80211_tx.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index 24ade5f68e02..8d87897d7eb7 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -227,7 +227,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
227 rts_required; 227 rts_required;
228 unsigned long flags; 228 unsigned long flags;
229 struct net_device_stats *stats = &ieee->stats; 229 struct net_device_stats *stats = &ieee->stats;
230 int ether_type, encrypt, host_encrypt, host_encrypt_msdu; 230 int ether_type, encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
231 int bytes, fc, hdr_len; 231 int bytes, fc, hdr_len;
232 struct sk_buff *skb_frag; 232 struct sk_buff *skb_frag;
233 struct ieee80211_hdr_3addr header = { /* Ensure zero initialized */ 233 struct ieee80211_hdr_3addr header = { /* Ensure zero initialized */
@@ -263,8 +263,10 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
263 263
264 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && 264 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
265 ieee->sec.encrypt; 265 ieee->sec.encrypt;
266
266 host_encrypt = ieee->host_encrypt && encrypt; 267 host_encrypt = ieee->host_encrypt && encrypt;
267 host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt; 268 host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt;
269 host_build_iv = ieee->host_build_iv && encrypt;
268 270
269 if (!encrypt && ieee->ieee802_1x && 271 if (!encrypt && ieee->ieee802_1x &&
270 ieee->drop_unencrypted && ether_type != ETH_P_PAE) { 272 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
@@ -310,8 +312,10 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
310 int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len + 312 int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len +
311 crypt->ops->extra_msdu_postfix_len; 313 crypt->ops->extra_msdu_postfix_len;
312 struct sk_buff *skb_new = dev_alloc_skb(len); 314 struct sk_buff *skb_new = dev_alloc_skb(len);
315
313 if (unlikely(!skb_new)) 316 if (unlikely(!skb_new))
314 goto failed; 317 goto failed;
318
315 skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len); 319 skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);
316 memcpy(skb_put(skb_new, hdr_len), &header, hdr_len); 320 memcpy(skb_put(skb_new, hdr_len), &header, hdr_len);
317 snapped = 1; 321 snapped = 1;
@@ -418,7 +422,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
418 for (; i < nr_frags; i++) { 422 for (; i < nr_frags; i++) {
419 skb_frag = txb->fragments[i]; 423 skb_frag = txb->fragments[i];
420 424
421 if (host_encrypt) 425 if (host_encrypt || host_build_iv)
422 skb_reserve(skb_frag, 426 skb_reserve(skb_frag,
423 crypt->ops->extra_mpdu_prefix_len); 427 crypt->ops->extra_mpdu_prefix_len);
424 428
@@ -453,6 +457,16 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
453 * to insert the IV between the header and the payload */ 457 * to insert the IV between the header and the payload */
454 if (host_encrypt) 458 if (host_encrypt)
455 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); 459 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
460 else if (host_build_iv) {
461 struct ieee80211_crypt_data *crypt;
462
463 crypt = ieee->crypt[ieee->tx_keyidx];
464 atomic_inc(&crypt->refcnt);
465 if (crypt->ops->build_iv)
466 crypt->ops->build_iv(skb_frag, hdr_len,
467 crypt->priv);
468 atomic_dec(&crypt->refcnt);
469 }
456 470
457 if (ieee->config & 471 if (ieee->config &
458 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) 472 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))