aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/carl9170/rx.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-07-12 13:44:50 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-07-12 13:44:50 -0400
commit38a00840638b4932152bca48098dbfa069d942a2 (patch)
treedd12897854f6df8aac237d5fd46551c74be8153a /drivers/net/wireless/ath/carl9170/rx.c
parent391e5c22f5f4e55817f8ba18a08ea717ed2d4a1f (diff)
parent2f8684ce7a47c91da7e0ccba2686277c103d02b6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Diffstat (limited to 'drivers/net/wireless/ath/carl9170/rx.c')
-rw-r--r--drivers/net/wireless/ath/carl9170/rx.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index 7a8e90eaad83..6f6a34155667 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -576,6 +576,53 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
576 } 576 }
577} 577}
578 578
579static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len)
580{
581 struct ieee80211_bar *bar = (void *) data;
582 struct carl9170_bar_list_entry *entry;
583 unsigned int queue;
584
585 if (likely(!ieee80211_is_back(bar->frame_control)))
586 return;
587
588 if (len <= sizeof(*bar) + FCS_LEN)
589 return;
590
591 queue = TID_TO_WME_AC(((le16_to_cpu(bar->control) &
592 IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
593 IEEE80211_BAR_CTRL_TID_INFO_SHIFT) & 7);
594
595 rcu_read_lock();
596 list_for_each_entry_rcu(entry, &ar->bar_list[queue], list) {
597 struct sk_buff *entry_skb = entry->skb;
598 struct _carl9170_tx_superframe *super = (void *)entry_skb->data;
599 struct ieee80211_bar *entry_bar = (void *)super->frame_data;
600
601#define TID_CHECK(a, b) ( \
602 ((a) & cpu_to_le16(IEEE80211_BAR_CTRL_TID_INFO_MASK)) == \
603 ((b) & cpu_to_le16(IEEE80211_BAR_CTRL_TID_INFO_MASK))) \
604
605 if (bar->start_seq_num == entry_bar->start_seq_num &&
606 TID_CHECK(bar->control, entry_bar->control) &&
607 compare_ether_addr(bar->ra, entry_bar->ta) == 0 &&
608 compare_ether_addr(bar->ta, entry_bar->ra) == 0) {
609 struct ieee80211_tx_info *tx_info;
610
611 tx_info = IEEE80211_SKB_CB(entry_skb);
612 tx_info->flags |= IEEE80211_TX_STAT_ACK;
613
614 spin_lock_bh(&ar->bar_list_lock[queue]);
615 list_del_rcu(&entry->list);
616 spin_unlock_bh(&ar->bar_list_lock[queue]);
617 kfree_rcu(entry, head);
618 break;
619 }
620 }
621 rcu_read_unlock();
622
623#undef TID_CHECK
624}
625
579static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms) 626static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms)
580{ 627{
581 __le16 fc; 628 __le16 fc;
@@ -738,6 +785,8 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
738 785
739 carl9170_ps_beacon(ar, buf, mpdu_len); 786 carl9170_ps_beacon(ar, buf, mpdu_len);
740 787
788 carl9170_ba_check(ar, buf, mpdu_len);
789
741 skb = carl9170_rx_copy_data(buf, mpdu_len); 790 skb = carl9170_rx_copy_data(buf, mpdu_len);
742 if (!skb) 791 if (!skb)
743 goto drop; 792 goto drop;