aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/carl9170
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/carl9170')
-rw-r--r--drivers/net/wireless/ath/carl9170/rx.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index 9cd93f1d8bef..6d22382875bc 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -660,6 +660,35 @@ static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms,
660 return false; 660 return false;
661} 661}
662 662
663static int carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len,
664 struct ieee80211_rx_status *status)
665{
666 struct sk_buff *skb;
667
668 /* (driver) frame trap handler
669 *
670 * Because power-saving mode handing has to be implemented by
671 * the driver/firmware. We have to check each incoming beacon
672 * from the associated AP, if there's new data for us (either
673 * broadcast/multicast or unicast) we have to react quickly.
674 *
675 * So, if you have you want to add additional frame trap
676 * handlers, this would be the perfect place!
677 */
678
679 carl9170_ps_beacon(ar, buf, len);
680
681 carl9170_ba_check(ar, buf, len);
682
683 skb = carl9170_rx_copy_data(buf, len);
684 if (!skb)
685 return -ENOMEM;
686
687 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
688 ieee80211_rx(ar->hw, skb);
689 return 0;
690}
691
663/* 692/*
664 * If the frame alignment is right (or the kernel has 693 * If the frame alignment is right (or the kernel has
665 * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there 694 * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
@@ -669,14 +698,12 @@ static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms,
669 * mode, and we need to observe the proper ordering, 698 * mode, and we need to observe the proper ordering,
670 * this is non-trivial. 699 * this is non-trivial.
671 */ 700 */
672 701static void carl9170_rx_untie_data(struct ar9170 *ar, u8 *buf, int len)
673static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
674{ 702{
675 struct ar9170_rx_head *head; 703 struct ar9170_rx_head *head;
676 struct ar9170_rx_macstatus *mac; 704 struct ar9170_rx_macstatus *mac;
677 struct ar9170_rx_phystatus *phy = NULL; 705 struct ar9170_rx_phystatus *phy = NULL;
678 struct ieee80211_rx_status status; 706 struct ieee80211_rx_status status;
679 struct sk_buff *skb;
680 int mpdu_len; 707 int mpdu_len;
681 u8 mac_status; 708 u8 mac_status;
682 709
@@ -788,18 +815,10 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
788 if (phy) 815 if (phy)
789 carl9170_rx_phy_status(ar, phy, &status); 816 carl9170_rx_phy_status(ar, phy, &status);
790 817
791 carl9170_ps_beacon(ar, buf, mpdu_len); 818 if (carl9170_handle_mpdu(ar, buf, mpdu_len, &status))
792
793 carl9170_ba_check(ar, buf, mpdu_len);
794
795 skb = carl9170_rx_copy_data(buf, mpdu_len);
796 if (!skb)
797 goto drop; 819 goto drop;
798 820
799 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
800 ieee80211_rx(ar->hw, skb);
801 return; 821 return;
802
803drop: 822drop:
804 ar->rx_dropped++; 823 ar->rx_dropped++;
805} 824}
@@ -851,7 +870,7 @@ static void __carl9170_rx(struct ar9170 *ar, u8 *buf, unsigned int len)
851 if (i == 12) 870 if (i == 12)
852 carl9170_rx_untie_cmds(ar, buf, len); 871 carl9170_rx_untie_cmds(ar, buf, len);
853 else 872 else
854 carl9170_handle_mpdu(ar, buf, len); 873 carl9170_rx_untie_data(ar, buf, len);
855} 874}
856 875
857static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len) 876static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len)