diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-11-09 09:07:02 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-11-26 06:42:59 -0500 |
commit | 5614618ec498320e3b686fea246e50b833865c34 (patch) | |
tree | a319fd5575bc7ee090136e6e7829200a152886cf /net/mac80211/rx.c | |
parent | db9c64cf8d9d3fcbc34b09d037f266d1fc9f928c (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.c | 20 |
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; |