diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 174 |
1 files changed, 103 insertions, 71 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index cf6b121e1bbf..7175ae80c36a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -26,10 +26,11 @@ | |||
26 | #include "tkip.h" | 26 | #include "tkip.h" |
27 | #include "wme.h" | 27 | #include "wme.h" |
28 | 28 | ||
29 | u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 29 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, |
30 | struct tid_ampdu_rx *tid_agg_rx, | 30 | struct tid_ampdu_rx *tid_agg_rx, |
31 | struct sk_buff *skb, u16 mpdu_seq_num, | 31 | struct sk_buff *skb, |
32 | int bar_req); | 32 | u16 mpdu_seq_num, |
33 | int bar_req); | ||
33 | /* | 34 | /* |
34 | * monitor mode reception | 35 | * monitor mode reception |
35 | * | 36 | * |
@@ -122,7 +123,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
122 | /* radiotap header, set always present flags */ | 123 | /* radiotap header, set always present flags */ |
123 | rthdr->it_present = | 124 | rthdr->it_present = |
124 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | 125 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | |
125 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
126 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | 126 | (1 << IEEE80211_RADIOTAP_CHANNEL) | |
127 | (1 << IEEE80211_RADIOTAP_ANTENNA) | | 127 | (1 << IEEE80211_RADIOTAP_ANTENNA) | |
128 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); | 128 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); |
@@ -148,7 +148,19 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
148 | pos++; | 148 | pos++; |
149 | 149 | ||
150 | /* IEEE80211_RADIOTAP_RATE */ | 150 | /* IEEE80211_RADIOTAP_RATE */ |
151 | *pos = rate->bitrate / 5; | 151 | if (status->flag & RX_FLAG_HT) { |
152 | /* | ||
153 | * TODO: add following information into radiotap header once | ||
154 | * suitable fields are defined for it: | ||
155 | * - MCS index (status->rate_idx) | ||
156 | * - HT40 (status->flag & RX_FLAG_40MHZ) | ||
157 | * - short-GI (status->flag & RX_FLAG_SHORT_GI) | ||
158 | */ | ||
159 | *pos = 0; | ||
160 | } else { | ||
161 | rthdr->it_present |= (1 << IEEE80211_RADIOTAP_RATE); | ||
162 | *pos = rate->bitrate / 5; | ||
163 | } | ||
152 | pos++; | 164 | pos++; |
153 | 165 | ||
154 | /* IEEE80211_RADIOTAP_CHANNEL */ | 166 | /* IEEE80211_RADIOTAP_CHANNEL */ |
@@ -653,13 +665,16 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
653 | static void ap_sta_ps_start(struct sta_info *sta) | 665 | static void ap_sta_ps_start(struct sta_info *sta) |
654 | { | 666 | { |
655 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 667 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
656 | DECLARE_MAC_BUF(mac); | 668 | struct ieee80211_local *local = sdata->local; |
657 | 669 | ||
658 | atomic_inc(&sdata->bss->num_sta_ps); | 670 | atomic_inc(&sdata->bss->num_sta_ps); |
659 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); | 671 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); |
672 | if (local->ops->sta_notify) | ||
673 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, | ||
674 | STA_NOTIFY_SLEEP, &sta->sta); | ||
660 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 675 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
661 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", | 676 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", |
662 | sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid); | 677 | sdata->dev->name, sta->sta.addr, sta->sta.aid); |
663 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 678 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
664 | } | 679 | } |
665 | 680 | ||
@@ -669,38 +684,37 @@ static int ap_sta_ps_end(struct sta_info *sta) | |||
669 | struct ieee80211_local *local = sdata->local; | 684 | struct ieee80211_local *local = sdata->local; |
670 | struct sk_buff *skb; | 685 | struct sk_buff *skb; |
671 | int sent = 0; | 686 | int sent = 0; |
672 | struct ieee80211_tx_info *info; | ||
673 | DECLARE_MAC_BUF(mac); | ||
674 | 687 | ||
675 | atomic_dec(&sdata->bss->num_sta_ps); | 688 | atomic_dec(&sdata->bss->num_sta_ps); |
676 | 689 | ||
677 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); | 690 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); |
691 | if (local->ops->sta_notify) | ||
692 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, | ||
693 | STA_NOTIFY_AWAKE, &sta->sta); | ||
678 | 694 | ||
679 | if (!skb_queue_empty(&sta->ps_tx_buf)) | 695 | if (!skb_queue_empty(&sta->ps_tx_buf)) |
680 | sta_info_clear_tim_bit(sta); | 696 | sta_info_clear_tim_bit(sta); |
681 | 697 | ||
682 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 698 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
683 | printk(KERN_DEBUG "%s: STA %s aid %d exits power save mode\n", | 699 | printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", |
684 | sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid); | 700 | sdata->dev->name, sta->sta.addr, sta->sta.aid); |
685 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 701 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
686 | 702 | ||
687 | /* Send all buffered frames to the station */ | 703 | /* Send all buffered frames to the station */ |
688 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { | 704 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { |
689 | info = IEEE80211_SKB_CB(skb); | ||
690 | sent++; | 705 | sent++; |
691 | info->flags |= IEEE80211_TX_CTL_REQUEUE; | 706 | skb->requeue = 1; |
692 | dev_queue_xmit(skb); | 707 | dev_queue_xmit(skb); |
693 | } | 708 | } |
694 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { | 709 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { |
695 | info = IEEE80211_SKB_CB(skb); | ||
696 | local->total_ps_buffered--; | 710 | local->total_ps_buffered--; |
697 | sent++; | 711 | sent++; |
698 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 712 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
699 | printk(KERN_DEBUG "%s: STA %s aid %d send PS frame " | 713 | printk(KERN_DEBUG "%s: STA %pM aid %d send PS frame " |
700 | "since STA not sleeping anymore\n", sdata->dev->name, | 714 | "since STA not sleeping anymore\n", sdata->dev->name, |
701 | print_mac(mac, sta->sta.addr), sta->sta.aid); | 715 | sta->sta.addr, sta->sta.aid); |
702 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 716 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
703 | info->flags |= IEEE80211_TX_CTL_REQUEUE; | 717 | skb->requeue = 1; |
704 | dev_queue_xmit(skb); | 718 | dev_queue_xmit(skb); |
705 | } | 719 | } |
706 | 720 | ||
@@ -745,17 +759,29 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
745 | sta->last_qual = rx->status->qual; | 759 | sta->last_qual = rx->status->qual; |
746 | sta->last_noise = rx->status->noise; | 760 | sta->last_noise = rx->status->noise; |
747 | 761 | ||
762 | /* | ||
763 | * Change STA power saving mode only at the end of a frame | ||
764 | * exchange sequence. | ||
765 | */ | ||
748 | if (!ieee80211_has_morefrags(hdr->frame_control) && | 766 | if (!ieee80211_has_morefrags(hdr->frame_control) && |
749 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || | 767 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || |
750 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { | 768 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { |
751 | /* Change STA power saving mode only in the end of a frame | 769 | if (test_sta_flags(sta, WLAN_STA_PS)) { |
752 | * exchange sequence */ | 770 | /* |
753 | if (test_sta_flags(sta, WLAN_STA_PS) && | 771 | * Ignore doze->wake transitions that are |
754 | !ieee80211_has_pm(hdr->frame_control)) | 772 | * indicated by non-data frames, the standard |
755 | rx->sent_ps_buffered += ap_sta_ps_end(sta); | 773 | * is unclear here, but for example going to |
756 | else if (!test_sta_flags(sta, WLAN_STA_PS) && | 774 | * PS mode and then scanning would cause a |
757 | ieee80211_has_pm(hdr->frame_control)) | 775 | * doze->wake transition for the probe request, |
758 | ap_sta_ps_start(sta); | 776 | * and that is clearly undesirable. |
777 | */ | ||
778 | if (ieee80211_is_data(hdr->frame_control) && | ||
779 | !ieee80211_has_pm(hdr->frame_control)) | ||
780 | rx->sent_ps_buffered += ap_sta_ps_end(sta); | ||
781 | } else { | ||
782 | if (ieee80211_has_pm(hdr->frame_control)) | ||
783 | ap_sta_ps_start(sta); | ||
784 | } | ||
759 | } | 785 | } |
760 | 786 | ||
761 | /* Drop data::nullfunc frames silently, since they are used only to | 787 | /* Drop data::nullfunc frames silently, since they are used only to |
@@ -789,15 +815,12 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
789 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 815 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
790 | struct ieee80211_hdr *hdr = | 816 | struct ieee80211_hdr *hdr = |
791 | (struct ieee80211_hdr *) entry->skb_list.next->data; | 817 | (struct ieee80211_hdr *) entry->skb_list.next->data; |
792 | DECLARE_MAC_BUF(mac); | ||
793 | DECLARE_MAC_BUF(mac2); | ||
794 | printk(KERN_DEBUG "%s: RX reassembly removed oldest " | 818 | printk(KERN_DEBUG "%s: RX reassembly removed oldest " |
795 | "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " | 819 | "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " |
796 | "addr1=%s addr2=%s\n", | 820 | "addr1=%pM addr2=%pM\n", |
797 | sdata->dev->name, idx, | 821 | sdata->dev->name, idx, |
798 | jiffies - entry->first_frag_time, entry->seq, | 822 | jiffies - entry->first_frag_time, entry->seq, |
799 | entry->last_frag, print_mac(mac, hdr->addr1), | 823 | entry->last_frag, hdr->addr1, hdr->addr2); |
800 | print_mac(mac2, hdr->addr2)); | ||
801 | #endif | 824 | #endif |
802 | __skb_queue_purge(&entry->skb_list); | 825 | __skb_queue_purge(&entry->skb_list); |
803 | } | 826 | } |
@@ -866,7 +889,6 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
866 | unsigned int frag, seq; | 889 | unsigned int frag, seq; |
867 | struct ieee80211_fragment_entry *entry; | 890 | struct ieee80211_fragment_entry *entry; |
868 | struct sk_buff *skb; | 891 | struct sk_buff *skb; |
869 | DECLARE_MAC_BUF(mac); | ||
870 | 892 | ||
871 | hdr = (struct ieee80211_hdr *)rx->skb->data; | 893 | hdr = (struct ieee80211_hdr *)rx->skb->data; |
872 | fc = hdr->frame_control; | 894 | fc = hdr->frame_control; |
@@ -970,7 +992,6 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
970 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 992 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); |
971 | struct sk_buff *skb; | 993 | struct sk_buff *skb; |
972 | int no_pending_pkts; | 994 | int no_pending_pkts; |
973 | DECLARE_MAC_BUF(mac); | ||
974 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; | 995 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; |
975 | 996 | ||
976 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || | 997 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || |
@@ -1001,8 +1022,8 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1001 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); | 1022 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); |
1002 | 1023 | ||
1003 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1024 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1004 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", | 1025 | printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n", |
1005 | print_mac(mac, rx->sta->sta.addr), rx->sta->sta.aid, | 1026 | rx->sta->sta.addr, rx->sta->sta.aid, |
1006 | skb_queue_len(&rx->sta->ps_tx_buf)); | 1027 | skb_queue_len(&rx->sta->ps_tx_buf)); |
1007 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1028 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1008 | 1029 | ||
@@ -1025,9 +1046,9 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1025 | * Should we send it a null-func frame indicating we | 1046 | * Should we send it a null-func frame indicating we |
1026 | * have nothing buffered for it? | 1047 | * have nothing buffered for it? |
1027 | */ | 1048 | */ |
1028 | printk(KERN_DEBUG "%s: STA %s sent PS Poll even " | 1049 | printk(KERN_DEBUG "%s: STA %pM sent PS Poll even " |
1029 | "though there are no buffered frames for it\n", | 1050 | "though there are no buffered frames for it\n", |
1030 | rx->dev->name, print_mac(mac, rx->sta->sta.addr)); | 1051 | rx->dev->name, rx->sta->sta.addr); |
1031 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1052 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1032 | } | 1053 | } |
1033 | 1054 | ||
@@ -1097,10 +1118,6 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1097 | u8 src[ETH_ALEN] __aligned(2); | 1118 | u8 src[ETH_ALEN] __aligned(2); |
1098 | struct sk_buff *skb = rx->skb; | 1119 | struct sk_buff *skb = rx->skb; |
1099 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1120 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1100 | DECLARE_MAC_BUF(mac); | ||
1101 | DECLARE_MAC_BUF(mac2); | ||
1102 | DECLARE_MAC_BUF(mac3); | ||
1103 | DECLARE_MAC_BUF(mac4); | ||
1104 | 1121 | ||
1105 | if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) | 1122 | if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) |
1106 | return -1; | 1123 | return -1; |
@@ -1279,7 +1296,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1279 | int remaining, err; | 1296 | int remaining, err; |
1280 | u8 dst[ETH_ALEN]; | 1297 | u8 dst[ETH_ALEN]; |
1281 | u8 src[ETH_ALEN]; | 1298 | u8 src[ETH_ALEN]; |
1282 | DECLARE_MAC_BUF(mac); | ||
1283 | 1299 | ||
1284 | if (unlikely(!ieee80211_is_data(fc))) | 1300 | if (unlikely(!ieee80211_is_data(fc))) |
1285 | return RX_CONTINUE; | 1301 | return RX_CONTINUE; |
@@ -1552,14 +1568,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1552 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) | 1568 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) |
1553 | return RX_DROP_MONITOR; | 1569 | return RX_DROP_MONITOR; |
1554 | 1570 | ||
1555 | /* | ||
1556 | * FIXME: revisit this, I'm sure we should handle most | ||
1557 | * of these frames in other modes as well! | ||
1558 | */ | ||
1559 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | ||
1560 | sdata->vif.type != NL80211_IFTYPE_ADHOC) | ||
1561 | return RX_CONTINUE; | ||
1562 | |||
1563 | switch (mgmt->u.action.category) { | 1571 | switch (mgmt->u.action.category) { |
1564 | case WLAN_CATEGORY_BACK: | 1572 | case WLAN_CATEGORY_BACK: |
1565 | switch (mgmt->u.action.u.addba_req.action_code) { | 1573 | switch (mgmt->u.action.u.addba_req.action_code) { |
@@ -1632,8 +1640,6 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1632 | { | 1640 | { |
1633 | int keyidx; | 1641 | int keyidx; |
1634 | unsigned int hdrlen; | 1642 | unsigned int hdrlen; |
1635 | DECLARE_MAC_BUF(mac); | ||
1636 | DECLARE_MAC_BUF(mac2); | ||
1637 | 1643 | ||
1638 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1644 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1639 | if (rx->skb->len >= hdrlen + 4) | 1645 | if (rx->skb->len >= hdrlen + 4) |
@@ -1854,10 +1860,15 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1854 | if (!(sdata->dev->flags & IFF_PROMISC)) | 1860 | if (!(sdata->dev->flags & IFF_PROMISC)) |
1855 | return 0; | 1861 | return 0; |
1856 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 1862 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
1857 | } else if (!rx->sta) | 1863 | } else if (!rx->sta) { |
1858 | rx->sta = ieee80211_ibss_add_sta(sdata, rx->skb, | 1864 | int rate_idx; |
1859 | bssid, hdr->addr2, | 1865 | if (rx->status->flag & RX_FLAG_HT) |
1860 | BIT(rx->status->rate_idx)); | 1866 | rate_idx = 0; /* TODO: HT rates */ |
1867 | else | ||
1868 | rate_idx = rx->status->rate_idx; | ||
1869 | rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2, | ||
1870 | BIT(rate_idx)); | ||
1871 | } | ||
1861 | break; | 1872 | break; |
1862 | case NL80211_IFTYPE_MESH_POINT: | 1873 | case NL80211_IFTYPE_MESH_POINT: |
1863 | if (!multicast && | 1874 | if (!multicast && |
@@ -2002,17 +2013,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2002 | 2013 | ||
2003 | static inline int seq_less(u16 sq1, u16 sq2) | 2014 | static inline int seq_less(u16 sq1, u16 sq2) |
2004 | { | 2015 | { |
2005 | return (((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1)); | 2016 | return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1); |
2006 | } | 2017 | } |
2007 | 2018 | ||
2008 | static inline u16 seq_inc(u16 sq) | 2019 | static inline u16 seq_inc(u16 sq) |
2009 | { | 2020 | { |
2010 | return ((sq + 1) & SEQ_MASK); | 2021 | return (sq + 1) & SEQ_MASK; |
2011 | } | 2022 | } |
2012 | 2023 | ||
2013 | static inline u16 seq_sub(u16 sq1, u16 sq2) | 2024 | static inline u16 seq_sub(u16 sq1, u16 sq2) |
2014 | { | 2025 | { |
2015 | return ((sq1 - sq2) & SEQ_MASK); | 2026 | return (sq1 - sq2) & SEQ_MASK; |
2016 | } | 2027 | } |
2017 | 2028 | ||
2018 | 2029 | ||
@@ -2020,10 +2031,11 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) | |||
2020 | * As it function blongs to Rx path it must be called with | 2031 | * As it function blongs to Rx path it must be called with |
2021 | * the proper rcu_read_lock protection for its flow. | 2032 | * the proper rcu_read_lock protection for its flow. |
2022 | */ | 2033 | */ |
2023 | u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 2034 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, |
2024 | struct tid_ampdu_rx *tid_agg_rx, | 2035 | struct tid_ampdu_rx *tid_agg_rx, |
2025 | struct sk_buff *skb, u16 mpdu_seq_num, | 2036 | struct sk_buff *skb, |
2026 | int bar_req) | 2037 | u16 mpdu_seq_num, |
2038 | int bar_req) | ||
2027 | { | 2039 | { |
2028 | struct ieee80211_local *local = hw_to_local(hw); | 2040 | struct ieee80211_local *local = hw_to_local(hw); |
2029 | struct ieee80211_rx_status status; | 2041 | struct ieee80211_rx_status status; |
@@ -2062,7 +2074,13 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2062 | tid_agg_rx->reorder_buf[index]->cb, | 2074 | tid_agg_rx->reorder_buf[index]->cb, |
2063 | sizeof(status)); | 2075 | sizeof(status)); |
2064 | sband = local->hw.wiphy->bands[status.band]; | 2076 | sband = local->hw.wiphy->bands[status.band]; |
2065 | rate = &sband->bitrates[status.rate_idx]; | 2077 | if (status.flag & RX_FLAG_HT) { |
2078 | /* TODO: HT rates */ | ||
2079 | rate = sband->bitrates; | ||
2080 | } else { | ||
2081 | rate = &sband->bitrates | ||
2082 | [status.rate_idx]; | ||
2083 | } | ||
2066 | __ieee80211_rx_handle_packet(hw, | 2084 | __ieee80211_rx_handle_packet(hw, |
2067 | tid_agg_rx->reorder_buf[index], | 2085 | tid_agg_rx->reorder_buf[index], |
2068 | &status, rate); | 2086 | &status, rate); |
@@ -2106,7 +2124,10 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2106 | memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, | 2124 | memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, |
2107 | sizeof(status)); | 2125 | sizeof(status)); |
2108 | sband = local->hw.wiphy->bands[status.band]; | 2126 | sband = local->hw.wiphy->bands[status.band]; |
2109 | rate = &sband->bitrates[status.rate_idx]; | 2127 | if (status.flag & RX_FLAG_HT) |
2128 | rate = sband->bitrates; /* TODO: HT rates */ | ||
2129 | else | ||
2130 | rate = &sband->bitrates[status.rate_idx]; | ||
2110 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], | 2131 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], |
2111 | &status, rate); | 2132 | &status, rate); |
2112 | tid_agg_rx->stored_mpdu_num--; | 2133 | tid_agg_rx->stored_mpdu_num--; |
@@ -2194,15 +2215,26 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2194 | } | 2215 | } |
2195 | 2216 | ||
2196 | sband = local->hw.wiphy->bands[status->band]; | 2217 | sband = local->hw.wiphy->bands[status->band]; |
2197 | 2218 | if (!sband) { | |
2198 | if (!sband || | ||
2199 | status->rate_idx < 0 || | ||
2200 | status->rate_idx >= sband->n_bitrates) { | ||
2201 | WARN_ON(1); | 2219 | WARN_ON(1); |
2202 | return; | 2220 | return; |
2203 | } | 2221 | } |
2204 | 2222 | ||
2205 | rate = &sband->bitrates[status->rate_idx]; | 2223 | if (status->flag & RX_FLAG_HT) { |
2224 | /* rate_idx is MCS index */ | ||
2225 | if (WARN_ON(status->rate_idx < 0 || | ||
2226 | status->rate_idx >= 76)) | ||
2227 | return; | ||
2228 | /* HT rates are not in the table - use the highest legacy rate | ||
2229 | * for now since other parts of mac80211 may not yet be fully | ||
2230 | * MCS aware. */ | ||
2231 | rate = &sband->bitrates[sband->n_bitrates - 1]; | ||
2232 | } else { | ||
2233 | if (WARN_ON(status->rate_idx < 0 || | ||
2234 | status->rate_idx >= sband->n_bitrates)) | ||
2235 | return; | ||
2236 | rate = &sband->bitrates[status->rate_idx]; | ||
2237 | } | ||
2206 | 2238 | ||
2207 | /* | 2239 | /* |
2208 | * key references and virtual interfaces are protected using RCU | 2240 | * key references and virtual interfaces are protected using RCU |