aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-11-09 09:07:02 -0500
committerJohannes Berg <johannes.berg@intel.com>2012-11-26 06:42:59 -0500
commit5614618ec498320e3b686fea246e50b833865c34 (patch)
treea319fd5575bc7ee090136e6e7829200a152886cf /net/mac80211/rx.c
parentdb9c64cf8d9d3fcbc34b09d037f266d1fc9f928c (diff)
mac80211: support drivers reporting VHT RX
Add support to mac80211 for having drivers report received VHT MCS information. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b2ae2baefc9a..825f33cf7bbc 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -193,7 +193,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
193 pos++; 193 pos++;
194 194
195 /* IEEE80211_RADIOTAP_RATE */ 195 /* IEEE80211_RADIOTAP_RATE */
196 if (!rate || status->flag & RX_FLAG_HT) { 196 if (!rate || status->flag & (RX_FLAG_HT | RX_FLAG_VHT)) {
197 /* 197 /*
198 * Without rate information don't add it. If we have, 198 * Without rate information don't add it. If we have,
199 * MCS information is a separate field in radiotap, 199 * MCS information is a separate field in radiotap,
@@ -213,7 +213,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
213 if (status->band == IEEE80211_BAND_5GHZ) 213 if (status->band == IEEE80211_BAND_5GHZ)
214 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, 214 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ,
215 pos); 215 pos);
216 else if (status->flag & RX_FLAG_HT) 216 else if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
217 put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ, 217 put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,
218 pos); 218 pos);
219 else if (rate && rate->flags & IEEE80211_RATE_ERP_G) 219 else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
@@ -1356,6 +1356,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1356 if (ieee80211_is_data(hdr->frame_control)) { 1356 if (ieee80211_is_data(hdr->frame_control)) {
1357 sta->last_rx_rate_idx = status->rate_idx; 1357 sta->last_rx_rate_idx = status->rate_idx;
1358 sta->last_rx_rate_flag = status->flag; 1358 sta->last_rx_rate_flag = status->flag;
1359 sta->last_rx_rate_vht_nss = status->vht_nss;
1359 } 1360 }
1360 } 1361 }
1361 } else if (!is_multicast_ether_addr(hdr->addr1)) { 1362 } else if (!is_multicast_ether_addr(hdr->addr1)) {
@@ -1367,6 +1368,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1367 if (ieee80211_is_data(hdr->frame_control)) { 1368 if (ieee80211_is_data(hdr->frame_control)) {
1368 sta->last_rx_rate_idx = status->rate_idx; 1369 sta->last_rx_rate_idx = status->rate_idx;
1369 sta->last_rx_rate_flag = status->flag; 1370 sta->last_rx_rate_flag = status->flag;
1371 sta->last_rx_rate_vht_nss = status->vht_nss;
1370 } 1372 }
1371 } 1373 }
1372 1374
@@ -2710,7 +2712,8 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
2710 status = IEEE80211_SKB_RXCB((rx->skb)); 2712 status = IEEE80211_SKB_RXCB((rx->skb));
2711 2713
2712 sband = rx->local->hw.wiphy->bands[status->band]; 2714 sband = rx->local->hw.wiphy->bands[status->band];
2713 if (!(status->flag & RX_FLAG_HT)) 2715 if (!(status->flag & RX_FLAG_HT) &&
2716 !(status->flag & RX_FLAG_VHT))
2714 rate = &sband->bitrates[status->rate_idx]; 2717 rate = &sband->bitrates[status->rate_idx];
2715 2718
2716 ieee80211_rx_cooked_monitor(rx, rate); 2719 ieee80211_rx_cooked_monitor(rx, rate);
@@ -2877,8 +2880,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2877 status->rx_flags &= ~IEEE80211_RX_RA_MATCH; 2880 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2878 } else if (!rx->sta) { 2881 } else if (!rx->sta) {
2879 int rate_idx; 2882 int rate_idx;
2880 if (status->flag & RX_FLAG_HT) 2883 if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
2881 rate_idx = 0; /* TODO: HT rates */ 2884 rate_idx = 0; /* TODO: HT/VHT rates */
2882 else 2885 else
2883 rate_idx = status->rate_idx; 2886 rate_idx = status->rate_idx;
2884 ieee80211_ibss_rx_no_sta(sdata, bssid, hdr->addr2, 2887 ieee80211_ibss_rx_no_sta(sdata, bssid, hdr->addr2,
@@ -3154,6 +3157,13 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
3154 status->rate_idx, 3157 status->rate_idx,
3155 status->rate_idx)) 3158 status->rate_idx))
3156 goto drop; 3159 goto drop;
3160 } else if (status->flag & RX_FLAG_VHT) {
3161 if (WARN_ONCE(status->rate_idx > 9 ||
3162 !status->vht_nss ||
3163 status->vht_nss > 8,
3164 "Rate marked as a VHT rate but data is invalid: MCS: %d, NSS: %d\n",
3165 status->rate_idx, status->vht_nss))
3166 goto drop;
3157 } else { 3167 } else {
3158 if (WARN_ON(status->rate_idx >= sband->n_bitrates)) 3168 if (WARN_ON(status->rate_idx >= sband->n_bitrates))
3159 goto drop; 3169 goto drop;