aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/status.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-11-06 08:13:34 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-09 16:14:09 -0500
commita729cff8ad5120d0d5172ec28a3843d1cb458f79 (patch)
tree96e85c0805050ba03a2df2a4278640da8f0454c5 /net/mac80211/status.c
parent1f074bd8eb7a4a210a5119cd7220f89da6c7a2c3 (diff)
mac80211: implement wifi TX status
Implement the socket wifi TX status error queue reflection in mac80211. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/status.c')
-rw-r--r--net/mac80211/status.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 94702f103cfc..83b800d17a9a 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -548,6 +548,24 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
548 } 548 }
549 } 549 }
550 550
551 if (unlikely(info->ack_frame_id)) {
552 struct sk_buff *ack_skb;
553 unsigned long flags;
554
555 spin_lock_irqsave(&local->ack_status_lock, flags);
556 ack_skb = idr_find(&local->ack_status_frames,
557 info->ack_frame_id);
558 if (ack_skb)
559 idr_remove(&local->ack_status_frames,
560 info->ack_frame_id);
561 spin_unlock_irqrestore(&local->ack_status_lock, flags);
562
563 /* consumes ack_skb */
564 if (ack_skb)
565 skb_complete_wifi_ack(ack_skb,
566 info->flags & IEEE80211_TX_STAT_ACK);
567 }
568
551 /* this was a transmitted frame, but now we want to reuse it */ 569 /* this was a transmitted frame, but now we want to reuse it */
552 skb_orphan(skb); 570 skb_orphan(skb);
553 571
@@ -621,6 +639,26 @@ EXPORT_SYMBOL(ieee80211_report_low_ack);
621 639
622void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb) 640void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb)
623{ 641{
642 struct ieee80211_local *local = hw_to_local(hw);
643 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
644
645 if (unlikely(info->ack_frame_id)) {
646 struct sk_buff *ack_skb;
647 unsigned long flags;
648
649 spin_lock_irqsave(&local->ack_status_lock, flags);
650 ack_skb = idr_find(&local->ack_status_frames,
651 info->ack_frame_id);
652 if (ack_skb)
653 idr_remove(&local->ack_status_frames,
654 info->ack_frame_id);
655 spin_unlock_irqrestore(&local->ack_status_lock, flags);
656
657 /* consumes ack_skb */
658 if (ack_skb)
659 dev_kfree_skb_any(ack_skb);
660 }
661
624 dev_kfree_skb_any(skb); 662 dev_kfree_skb_any(skb);
625} 663}
626EXPORT_SYMBOL(ieee80211_free_txskb); 664EXPORT_SYMBOL(ieee80211_free_txskb);