diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-05-15 06:55:29 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-21 21:48:11 -0400 |
commit | e039fa4a4195ac4ee895e6f3d1334beed63256fe (patch) | |
tree | cfd0762d73df96b73052378be7b157c4ac6e7035 /net/mac80211/wpa.c | |
parent | e24549485f859be6518929bb1c9c0257d79f033d (diff) |
mac80211: move TX info into skb->cb
This patch converts mac80211 and all drivers to have transmit
information and status in skb->cb rather than allocating extra
memory for it and copying all the data around. To make it fit,
a union is used where only data that is necessary for all steps
is kept outside of the union.
A number of fixes were done by Ivo, as well as the rt2x00 part
of this patch.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r-- | net/mac80211/wpa.c | 65 |
1 files changed, 31 insertions, 34 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index d7304490d2ec..d6635f6e5618 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -183,15 +183,25 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
183 | } | 183 | } |
184 | 184 | ||
185 | 185 | ||
186 | static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, | 186 | static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) |
187 | struct sk_buff *skb, int test) | ||
188 | { | 187 | { |
189 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 188 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
190 | struct ieee80211_key *key = tx->key; | 189 | struct ieee80211_key *key = tx->key; |
190 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
191 | int hdrlen, len, tailneed; | 191 | int hdrlen, len, tailneed; |
192 | u16 fc; | 192 | u16 fc; |
193 | u8 *pos; | 193 | u8 *pos; |
194 | 194 | ||
195 | info->control.icv_len = TKIP_ICV_LEN; | ||
196 | info->control.iv_len = TKIP_IV_LEN; | ||
197 | |||
198 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | ||
199 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | ||
200 | /* hwaccel - with no need for preallocated room for IV/ICV */ | ||
201 | info->control.hw_key = &tx->key->conf; | ||
202 | return TX_CONTINUE; | ||
203 | } | ||
204 | |||
195 | fc = le16_to_cpu(hdr->frame_control); | 205 | fc = le16_to_cpu(hdr->frame_control); |
196 | hdrlen = ieee80211_get_hdrlen(fc); | 206 | hdrlen = ieee80211_get_hdrlen(fc); |
197 | len = skb->len - hdrlen; | 207 | len = skb->len - hdrlen; |
@@ -228,7 +238,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, | |||
228 | 0x7f), | 238 | 0x7f), |
229 | (u8) key->u.tkip.tx.iv16); | 239 | (u8) key->u.tkip.tx.iv16); |
230 | 240 | ||
231 | tx->control->hw_key = &tx->key->conf; | 241 | info->control.hw_key = &tx->key->conf; |
232 | return 0; | 242 | return 0; |
233 | } | 243 | } |
234 | 244 | ||
@@ -246,28 +256,16 @@ ieee80211_tx_result | |||
246 | ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) | 256 | ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) |
247 | { | 257 | { |
248 | struct sk_buff *skb = tx->skb; | 258 | struct sk_buff *skb = tx->skb; |
249 | int wpa_test = 0, test = 0; | ||
250 | 259 | ||
251 | tx->control->icv_len = TKIP_ICV_LEN; | ||
252 | tx->control->iv_len = TKIP_IV_LEN; | ||
253 | ieee80211_tx_set_protected(tx); | 260 | ieee80211_tx_set_protected(tx); |
254 | 261 | ||
255 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 262 | if (tkip_encrypt_skb(tx, skb) < 0) |
256 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) && | ||
257 | !wpa_test) { | ||
258 | /* hwaccel - with no need for preallocated room for IV/ICV */ | ||
259 | tx->control->hw_key = &tx->key->conf; | ||
260 | return TX_CONTINUE; | ||
261 | } | ||
262 | |||
263 | if (tkip_encrypt_skb(tx, skb, test) < 0) | ||
264 | return TX_DROP; | 263 | return TX_DROP; |
265 | 264 | ||
266 | if (tx->extra_frag) { | 265 | if (tx->extra_frag) { |
267 | int i; | 266 | int i; |
268 | for (i = 0; i < tx->num_extra_frag; i++) { | 267 | for (i = 0; i < tx->num_extra_frag; i++) { |
269 | if (tkip_encrypt_skb(tx, tx->extra_frag[i], test) | 268 | if (tkip_encrypt_skb(tx, tx->extra_frag[i]) < 0) |
270 | < 0) | ||
271 | return TX_DROP; | 269 | return TX_DROP; |
272 | } | 270 | } |
273 | } | 271 | } |
@@ -429,16 +427,27 @@ static inline int ccmp_hdr2pn(u8 *pn, u8 *hdr) | |||
429 | } | 427 | } |
430 | 428 | ||
431 | 429 | ||
432 | static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, | 430 | static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) |
433 | struct sk_buff *skb, int test) | ||
434 | { | 431 | { |
435 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 432 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
436 | struct ieee80211_key *key = tx->key; | 433 | struct ieee80211_key *key = tx->key; |
434 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
437 | int hdrlen, len, tailneed; | 435 | int hdrlen, len, tailneed; |
438 | u16 fc; | 436 | u16 fc; |
439 | u8 *pos, *pn, *b_0, *aad, *scratch; | 437 | u8 *pos, *pn, *b_0, *aad, *scratch; |
440 | int i; | 438 | int i; |
441 | 439 | ||
440 | info->control.icv_len = CCMP_MIC_LEN; | ||
441 | info->control.iv_len = CCMP_HDR_LEN; | ||
442 | |||
443 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | ||
444 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | ||
445 | /* hwaccel - with no need for preallocated room for CCMP " | ||
446 | * header or MIC fields */ | ||
447 | info->control.hw_key = &tx->key->conf; | ||
448 | return TX_CONTINUE; | ||
449 | } | ||
450 | |||
442 | scratch = key->u.ccmp.tx_crypto_buf; | 451 | scratch = key->u.ccmp.tx_crypto_buf; |
443 | b_0 = scratch + 3 * AES_BLOCK_LEN; | 452 | b_0 = scratch + 3 * AES_BLOCK_LEN; |
444 | aad = scratch + 4 * AES_BLOCK_LEN; | 453 | aad = scratch + 4 * AES_BLOCK_LEN; |
@@ -478,7 +487,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, | |||
478 | 487 | ||
479 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 488 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
480 | /* hwaccel - with preallocated room for CCMP header */ | 489 | /* hwaccel - with preallocated room for CCMP header */ |
481 | tx->control->hw_key = &tx->key->conf; | 490 | info->control.hw_key = &tx->key->conf; |
482 | return 0; | 491 | return 0; |
483 | } | 492 | } |
484 | 493 | ||
@@ -495,28 +504,16 @@ ieee80211_tx_result | |||
495 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) | 504 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) |
496 | { | 505 | { |
497 | struct sk_buff *skb = tx->skb; | 506 | struct sk_buff *skb = tx->skb; |
498 | int test = 0; | ||
499 | 507 | ||
500 | tx->control->icv_len = CCMP_MIC_LEN; | ||
501 | tx->control->iv_len = CCMP_HDR_LEN; | ||
502 | ieee80211_tx_set_protected(tx); | 508 | ieee80211_tx_set_protected(tx); |
503 | 509 | ||
504 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 510 | if (ccmp_encrypt_skb(tx, skb) < 0) |
505 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | ||
506 | /* hwaccel - with no need for preallocated room for CCMP " | ||
507 | * header or MIC fields */ | ||
508 | tx->control->hw_key = &tx->key->conf; | ||
509 | return TX_CONTINUE; | ||
510 | } | ||
511 | |||
512 | if (ccmp_encrypt_skb(tx, skb, test) < 0) | ||
513 | return TX_DROP; | 511 | return TX_DROP; |
514 | 512 | ||
515 | if (tx->extra_frag) { | 513 | if (tx->extra_frag) { |
516 | int i; | 514 | int i; |
517 | for (i = 0; i < tx->num_extra_frag; i++) { | 515 | for (i = 0; i < tx->num_extra_frag; i++) { |
518 | if (ccmp_encrypt_skb(tx, tx->extra_frag[i], test) | 516 | if (ccmp_encrypt_skb(tx, tx->extra_frag[i]) < 0) |
519 | < 0) | ||
520 | return TX_DROP; | 517 | return TX_DROP; |
521 | } | 518 | } |
522 | } | 519 | } |