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.c25
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) */
557int ieee80211_tx_frame(struct ieee80211_device *ieee, 557int 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