diff options
author | James Ketrenos <jketreno@linux.intel.com> | 2005-09-21 12:53:54 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-21 23:01:52 -0400 |
commit | f1bf6638af9e9bbbb6fb0b769054fb7db1ae652f (patch) | |
tree | 5cf2dca63f88c1709ae8ee9d913c7f819bfc6ce8 /net/ieee80211/ieee80211_tx.c | |
parent | 20d64713ae71c0b0aa06084acbef2244021baaca (diff) |
[PATCH] ieee80211: Hardware crypto and fragmentation offload support
tree 5322d496af90d03ffbec27292dc1a6268a746ede
parent 6c9364386ccb786e4a84427ab3ad712f0b7b8904
author James Ketrenos <jketreno@linux.intel.com> 1124432367 -0500
committer James Ketrenos <jketreno@linux.intel.com> 1127311810 -0500
Hardware crypto and fragmentation offload support added (Zhu Yi)
Signed-off-by: James Ketrenos <jketreno@linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'net/ieee80211/ieee80211_tx.c')
-rw-r--r-- | net/ieee80211/ieee80211_tx.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c index 435ef5a73d75..785e76f7e4e9 100644 --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c | |||
@@ -231,7 +231,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
231 | int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; | 231 | int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; |
232 | unsigned long flags; | 232 | unsigned long flags; |
233 | struct net_device_stats *stats = &ieee->stats; | 233 | struct net_device_stats *stats = &ieee->stats; |
234 | int ether_type, encrypt; | 234 | int ether_type, encrypt, host_encrypt; |
235 | int bytes, fc, hdr_len; | 235 | int bytes, fc, hdr_len; |
236 | struct sk_buff *skb_frag; | 236 | struct sk_buff *skb_frag; |
237 | struct ieee80211_hdr header = { /* Ensure zero initialized */ | 237 | struct ieee80211_hdr header = { /* Ensure zero initialized */ |
@@ -262,7 +262,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
262 | crypt = ieee->crypt[ieee->tx_keyidx]; | 262 | crypt = ieee->crypt[ieee->tx_keyidx]; |
263 | 263 | ||
264 | encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && | 264 | encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && |
265 | ieee->host_encrypt && crypt && crypt->ops; | 265 | ieee->sec.encrypt; |
266 | host_encrypt = ieee->host_encrypt && encrypt; | ||
266 | 267 | ||
267 | if (!encrypt && ieee->ieee802_1x && | 268 | if (!encrypt && ieee->ieee802_1x && |
268 | ieee->drop_unencrypted && ether_type != ETH_P_PAE) { | 269 | ieee->drop_unencrypted && ether_type != ETH_P_PAE) { |
@@ -280,7 +281,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
280 | /* Determine total amount of storage required for TXB packets */ | 281 | /* Determine total amount of storage required for TXB packets */ |
281 | bytes = skb->len + SNAP_SIZE + sizeof(u16); | 282 | bytes = skb->len + SNAP_SIZE + sizeof(u16); |
282 | 283 | ||
283 | if (encrypt) | 284 | if (host_encrypt) |
284 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | | 285 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | |
285 | IEEE80211_FCTL_PROTECTED; | 286 | IEEE80211_FCTL_PROTECTED; |
286 | else | 287 | else |
@@ -320,7 +321,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
320 | bytes_per_frag -= IEEE80211_FCS_LEN; | 321 | bytes_per_frag -= IEEE80211_FCS_LEN; |
321 | 322 | ||
322 | /* Each fragment may need to have room for encryptiong pre/postfix */ | 323 | /* Each fragment may need to have room for encryptiong pre/postfix */ |
323 | if (encrypt) | 324 | if (host_encrypt) |
324 | bytes_per_frag -= crypt->ops->extra_prefix_len + | 325 | bytes_per_frag -= crypt->ops->extra_prefix_len + |
325 | crypt->ops->extra_postfix_len; | 326 | crypt->ops->extra_postfix_len; |
326 | 327 | ||
@@ -348,7 +349,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
348 | for (i = 0; i < nr_frags; i++) { | 349 | for (i = 0; i < nr_frags; i++) { |
349 | skb_frag = txb->fragments[i]; | 350 | skb_frag = txb->fragments[i]; |
350 | 351 | ||
351 | if (encrypt) | 352 | if (host_encrypt) |
352 | skb_reserve(skb_frag, crypt->ops->extra_prefix_len); | 353 | skb_reserve(skb_frag, crypt->ops->extra_prefix_len); |
353 | 354 | ||
354 | frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len); | 355 | frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len); |
@@ -380,8 +381,22 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
380 | 381 | ||
381 | /* Encryption routine will move the header forward in order | 382 | /* Encryption routine will move the header forward in order |
382 | * to insert the IV between the header and the payload */ | 383 | * to insert the IV between the header and the payload */ |
383 | if (encrypt) | 384 | if (host_encrypt) |
384 | ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); | 385 | ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); |
386 | |||
387 | /* ipw2200/2915 Hardware encryption doesn't support TKIP MIC */ | ||
388 | if (!ieee->host_encrypt && encrypt && | ||
389 | (ieee->sec.level == SEC_LEVEL_2) && | ||
390 | crypt && crypt->ops && crypt->ops->encrypt_msdu) { | ||
391 | int res = 0; | ||
392 | res = crypt->ops->encrypt_msdu(skb_frag, hdr_len, | ||
393 | crypt->priv); | ||
394 | if (res < 0) { | ||
395 | IEEE80211_ERROR("TKIP MIC encryption failed\n"); | ||
396 | goto failed; | ||
397 | } | ||
398 | } | ||
399 | |||
385 | if (ieee->config & | 400 | if (ieee->config & |
386 | (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) | 401 | (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) |
387 | skb_put(skb_frag, 4); | 402 | skb_put(skb_frag, 4); |