summaryrefslogtreecommitdiffstats
path: root/net/ieee80211/ieee80211_tx.c
diff options
context:
space:
mode:
authorJames Ketrenos <jketreno@linux.intel.com>2005-09-21 18:58:49 +0200
committerJeff Garzik <jgarzik@pobox.com>2005-09-22 21:39:41 +0200
commit31b59eaee8f8ec29d8cb6ac0c8eed086689d8030 (patch)
tree5ab119a07e98aaf623dc8ce6f04f7b3403b6b971 /net/ieee80211/ieee80211_tx.c
parent[PATCH] ieee80211: Added subsystem version string and reporting via MODULE_VE... (diff)
downloadlinux-31b59eaee8f8ec29d8cb6ac0c8eed086689d8030.tar.xz
linux-31b59eaee8f8ec29d8cb6ac0c8eed086689d8030.zip
[PATCH] ieee80211: Added handle_deauth() callback, enhanced tkip/ccmp support of varying hw/sw offload
tree de81b55e78e85997642c651ea677078d0554a14f parent c8030da8c159f8b82712172a6748a42523aea83a author James Ketrenos <jketreno@linux.intel.com> 1127104380 -0500 committer James Ketrenos <jketreno@linux.intel.com> 1127315225 -0500 Added handle_deauth() callback. Enhanced crypt_{tkip,ccmp} to support varying splits of HW/SW offload. Changed channel freq to u32 from u16. Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
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)
rts_required;
unsigned long flags;
struct net_device_stats *stats = &ieee->stats;
- int ether_type, encrypt, host_encrypt, host_encrypt_msdu;
+ int ether_type, encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
int bytes, fc, hdr_len;
struct sk_buff *skb_frag;
struct ieee80211_hdr_3addr header = { /* Ensure zero initialized */
@@ -263,8 +263,10 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
ieee->sec.encrypt;
+
host_encrypt = ieee->host_encrypt && encrypt;
host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt;
+ host_build_iv = ieee->host_build_iv && encrypt;
if (!encrypt && ieee->ieee802_1x &&
ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
@@ -310,8 +312,10 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len +
crypt->ops->extra_msdu_postfix_len;
struct sk_buff *skb_new = dev_alloc_skb(len);
+
if (unlikely(!skb_new))
goto failed;
+
skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);
memcpy(skb_put(skb_new, hdr_len), &header, hdr_len);
snapped = 1;
@@ -418,7 +422,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
for (; i < nr_frags; i++) {
skb_frag = txb->fragments[i];
- if (host_encrypt)
+ if (host_encrypt || host_build_iv)
skb_reserve(skb_frag,
crypt->ops->extra_mpdu_prefix_len);
@@ -453,6 +457,16 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
* to insert the IV between the header and the payload */
if (host_encrypt)
ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
+ else if (host_build_iv) {
+ struct ieee80211_crypt_data *crypt;
+
+ crypt = ieee->crypt[ieee->tx_keyidx];
+ atomic_inc(&crypt->refcnt);
+ if (crypt->ops->build_iv)
+ crypt->ops->build_iv(skb_frag, hdr_len,
+ crypt->priv);
+ atomic_dec(&crypt->refcnt);
+ }
if (ieee->config &
(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))