diff options
Diffstat (limited to 'net/ieee80211/ieee80211_tx.c')
| -rw-r--r-- | net/ieee80211/ieee80211_tx.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c index 233d527c6953..6a5de1b84459 100644 --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c | |||
| @@ -555,7 +555,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 555 | /* Incoming 802.11 strucure is converted to a TXB | 555 | /* Incoming 802.11 strucure is converted to a TXB |
| 556 | * a block of 802.11 fragment packets (stored as skbs) */ | 556 | * a block of 802.11 fragment packets (stored as skbs) */ |
| 557 | int ieee80211_tx_frame(struct ieee80211_device *ieee, | 557 | int ieee80211_tx_frame(struct ieee80211_device *ieee, |
| 558 | struct ieee80211_hdr *frame, int len) | 558 | struct ieee80211_hdr *frame, int hdr_len, int total_len, |
| 559 | int encrypt_mpdu) | ||
| 559 | { | 560 | { |
| 560 | struct ieee80211_txb *txb = NULL; | 561 | struct ieee80211_txb *txb = NULL; |
| 561 | unsigned long flags; | 562 | unsigned long flags; |
| @@ -565,6 +566,9 @@ int ieee80211_tx_frame(struct ieee80211_device *ieee, | |||
| 565 | 566 | ||
| 566 | spin_lock_irqsave(&ieee->lock, flags); | 567 | spin_lock_irqsave(&ieee->lock, flags); |
| 567 | 568 | ||
| 569 | if (encrypt_mpdu && !ieee->sec.encrypt) | ||
| 570 | encrypt_mpdu = 0; | ||
| 571 | |||
| 568 | /* If there is no driver handler to take the TXB, dont' bother | 572 | /* If there is no driver handler to take the TXB, dont' bother |
| 569 | * creating it... */ | 573 | * creating it... */ |
| 570 | if (!ieee->hard_start_xmit) { | 574 | if (!ieee->hard_start_xmit) { |
| @@ -572,32 +576,41 @@ int ieee80211_tx_frame(struct ieee80211_device *ieee, | |||
| 572 | goto success; | 576 | goto success; |
| 573 | } | 577 | } |
| 574 | 578 | ||
| 575 | if (unlikely(len < 24)) { | 579 | if (unlikely(total_len < 24)) { |
| 576 | printk(KERN_WARNING "%s: skb too small (%d).\n", | 580 | printk(KERN_WARNING "%s: skb too small (%d).\n", |
| 577 | ieee->dev->name, len); | 581 | ieee->dev->name, total_len); |
| 578 | goto success; | 582 | goto success; |
| 579 | } | 583 | } |
| 580 | 584 | ||
| 585 | if (encrypt_mpdu) | ||
| 586 | frame->frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); | ||
| 587 | |||
| 581 | /* When we allocate the TXB we allocate enough space for the reserve | 588 | /* When we allocate the TXB we allocate enough space for the reserve |
| 582 | * and full fragment bytes (bytes_per_frag doesn't include prefix, | 589 | * and full fragment bytes (bytes_per_frag doesn't include prefix, |
| 583 | * postfix, header, FCS, etc.) */ | 590 | * postfix, header, FCS, etc.) */ |
| 584 | txb = ieee80211_alloc_txb(1, len, ieee->tx_headroom, GFP_ATOMIC); | 591 | txb = ieee80211_alloc_txb(1, total_len, ieee->tx_headroom, GFP_ATOMIC); |
| 585 | if (unlikely(!txb)) { | 592 | if (unlikely(!txb)) { |
| 586 | printk(KERN_WARNING "%s: Could not allocate TXB\n", | 593 | printk(KERN_WARNING "%s: Could not allocate TXB\n", |
| 587 | ieee->dev->name); | 594 | ieee->dev->name); |
| 588 | goto failed; | 595 | goto failed; |
| 589 | } | 596 | } |
| 590 | txb->encrypted = 0; | 597 | txb->encrypted = 0; |
| 591 | txb->payload_size = len; | 598 | txb->payload_size = total_len; |
| 592 | 599 | ||
| 593 | skb_frag = txb->fragments[0]; | 600 | skb_frag = txb->fragments[0]; |
| 594 | 601 | ||
| 595 | memcpy(skb_put(skb_frag, len), frame, len); | 602 | memcpy(skb_put(skb_frag, total_len), frame, total_len); |
| 596 | 603 | ||
| 597 | if (ieee->config & | 604 | if (ieee->config & |
| 598 | (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) | 605 | (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) |
| 599 | skb_put(skb_frag, 4); | 606 | skb_put(skb_frag, 4); |
| 600 | 607 | ||
| 608 | /* To avoid overcomplicating things, we do the corner-case frame | ||
| 609 | * encryption in software. The only real situation where encryption is | ||
| 610 | * needed here is during software-based shared key authentication. */ | ||
| 611 | if (encrypt_mpdu) | ||
| 612 | ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); | ||
| 613 | |||
| 601 | success: | 614 | success: |
| 602 | spin_unlock_irqrestore(&ieee->lock, flags); | 615 | spin_unlock_irqrestore(&ieee->lock, flags); |
| 603 | 616 | ||
