diff options
-rw-r--r-- | include/net/ieee80211_radiotap.h | 24 | ||||
-rw-r--r-- | include/net/mac80211.h | 5 | ||||
-rw-r--r-- | net/mac80211/main.c | 2 | ||||
-rw-r--r-- | net/mac80211/rx.c | 40 |
4 files changed, 71 insertions, 0 deletions
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h index 7f0df133d119..c3999632e616 100644 --- a/include/net/ieee80211_radiotap.h +++ b/include/net/ieee80211_radiotap.h | |||
@@ -186,6 +186,10 @@ struct ieee80211_radiotap_header { | |||
186 | * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless | 186 | * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless |
187 | * | 187 | * |
188 | * Contains the AMPDU information for the subframe. | 188 | * Contains the AMPDU information for the subframe. |
189 | * | ||
190 | * IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16 | ||
191 | * | ||
192 | * Contains VHT information about this frame. | ||
189 | */ | 193 | */ |
190 | enum ieee80211_radiotap_type { | 194 | enum ieee80211_radiotap_type { |
191 | IEEE80211_RADIOTAP_TSFT = 0, | 195 | IEEE80211_RADIOTAP_TSFT = 0, |
@@ -209,6 +213,7 @@ enum ieee80211_radiotap_type { | |||
209 | 213 | ||
210 | IEEE80211_RADIOTAP_MCS = 19, | 214 | IEEE80211_RADIOTAP_MCS = 19, |
211 | IEEE80211_RADIOTAP_AMPDU_STATUS = 20, | 215 | IEEE80211_RADIOTAP_AMPDU_STATUS = 20, |
216 | IEEE80211_RADIOTAP_VHT = 21, | ||
212 | 217 | ||
213 | /* valid in every it_present bitmap, even vendor namespaces */ | 218 | /* valid in every it_present bitmap, even vendor namespaces */ |
214 | IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29, | 219 | IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29, |
@@ -282,6 +287,25 @@ enum ieee80211_radiotap_type { | |||
282 | #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 | 287 | #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 |
283 | #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 | 288 | #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 |
284 | 289 | ||
290 | /* For IEEE80211_RADIOTAP_VHT */ | ||
291 | #define IEEE80211_RADIOTAP_VHT_KNOWN_STBC 0x0001 | ||
292 | #define IEEE80211_RADIOTAP_VHT_KNOWN_TXOP_PS_NA 0x0002 | ||
293 | #define IEEE80211_RADIOTAP_VHT_KNOWN_GI 0x0004 | ||
294 | #define IEEE80211_RADIOTAP_VHT_KNOWN_SGI_NSYM_DIS 0x0008 | ||
295 | #define IEEE80211_RADIOTAP_VHT_KNOWN_LDPC_EXTRA_OFDM_SYM 0x0010 | ||
296 | #define IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED 0x0020 | ||
297 | #define IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH 0x0040 | ||
298 | #define IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID 0x0080 | ||
299 | #define IEEE80211_RADIOTAP_VHT_KNOWN_PARTIAL_AID 0x0100 | ||
300 | |||
301 | #define IEEE80211_RADIOTAP_VHT_FLAG_STBC 0x01 | ||
302 | #define IEEE80211_RADIOTAP_VHT_FLAG_TXOP_PS_NA 0x02 | ||
303 | #define IEEE80211_RADIOTAP_VHT_FLAG_SGI 0x04 | ||
304 | #define IEEE80211_RADIOTAP_VHT_FLAG_SGI_NSYM_M10_9 0x08 | ||
305 | #define IEEE80211_RADIOTAP_VHT_FLAG_LDPC_EXTRA_OFDM_SYM 0x10 | ||
306 | #define IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED 0x20 | ||
307 | |||
308 | |||
285 | /* helpers */ | 309 | /* helpers */ |
286 | static inline int ieee80211_get_radiotap_len(unsigned char *data) | 310 | static inline int ieee80211_get_radiotap_len(unsigned char *data) |
287 | { | 311 | { |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index db7680acd0da..e806f1d81f66 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -1473,6 +1473,10 @@ enum ieee80211_hw_flags { | |||
1473 | * include _FMT. Use %IEEE80211_RADIOTAP_MCS_HAVE_* values, only | 1473 | * include _FMT. Use %IEEE80211_RADIOTAP_MCS_HAVE_* values, only |
1474 | * adding _BW is supported today. | 1474 | * adding _BW is supported today. |
1475 | * | 1475 | * |
1476 | * @radiotap_vht_details: lists which VHT MCS information the HW reports, | ||
1477 | * the default is _GI | _BANDWIDTH. | ||
1478 | * Use the %IEEE80211_RADIOTAP_VHT_KNOWN_* values. | ||
1479 | * | ||
1476 | * @netdev_features: netdev features to be set in each netdev created | 1480 | * @netdev_features: netdev features to be set in each netdev created |
1477 | * from this HW. Note only HW checksum features are currently | 1481 | * from this HW. Note only HW checksum features are currently |
1478 | * compatible with mac80211. Other feature bits will be rejected. | 1482 | * compatible with mac80211. Other feature bits will be rejected. |
@@ -1499,6 +1503,7 @@ struct ieee80211_hw { | |||
1499 | u8 max_tx_aggregation_subframes; | 1503 | u8 max_tx_aggregation_subframes; |
1500 | u8 offchannel_tx_hw_queue; | 1504 | u8 offchannel_tx_hw_queue; |
1501 | u8 radiotap_mcs_details; | 1505 | u8 radiotap_mcs_details; |
1506 | u16 radiotap_vht_details; | ||
1502 | netdev_features_t netdev_features; | 1507 | netdev_features_t netdev_features; |
1503 | }; | 1508 | }; |
1504 | 1509 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 6e933409979a..c4ed83b74e52 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -638,6 +638,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
638 | local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS | | 638 | local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS | |
639 | IEEE80211_RADIOTAP_MCS_HAVE_GI | | 639 | IEEE80211_RADIOTAP_MCS_HAVE_GI | |
640 | IEEE80211_RADIOTAP_MCS_HAVE_BW; | 640 | IEEE80211_RADIOTAP_MCS_HAVE_BW; |
641 | local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | | ||
642 | IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; | ||
641 | local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; | 643 | local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; |
642 | wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; | 644 | wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; |
643 | 645 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 825f33cf7bbc..9b13b8b24245 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -111,6 +111,11 @@ ieee80211_rx_radiotap_space(struct ieee80211_local *local, | |||
111 | len += 8; | 111 | len += 8; |
112 | } | 112 | } |
113 | 113 | ||
114 | if (status->flag & RX_FLAG_VHT) { | ||
115 | len = ALIGN(len, 2); | ||
116 | len += 12; | ||
117 | } | ||
118 | |||
114 | if (status->vendor_radiotap_len) { | 119 | if (status->vendor_radiotap_len) { |
115 | if (WARN_ON_ONCE(status->vendor_radiotap_align == 0)) | 120 | if (WARN_ON_ONCE(status->vendor_radiotap_align == 0)) |
116 | status->vendor_radiotap_align = 1; | 121 | status->vendor_radiotap_align = 1; |
@@ -297,6 +302,41 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
297 | *pos++ = 0; | 302 | *pos++ = 0; |
298 | } | 303 | } |
299 | 304 | ||
305 | if (status->flag & RX_FLAG_VHT) { | ||
306 | u16 known = local->hw.radiotap_vht_details; | ||
307 | |||
308 | rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT); | ||
309 | /* known field - how to handle 80+80? */ | ||
310 | if (status->flag & RX_FLAG_80P80MHZ) | ||
311 | known &= ~IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; | ||
312 | put_unaligned_le16(known, pos); | ||
313 | pos += 2; | ||
314 | /* flags */ | ||
315 | if (status->flag & RX_FLAG_SHORT_GI) | ||
316 | *pos |= IEEE80211_RADIOTAP_VHT_FLAG_SGI; | ||
317 | pos++; | ||
318 | /* bandwidth */ | ||
319 | if (status->flag & RX_FLAG_80MHZ) | ||
320 | *pos++ = 4; | ||
321 | else if (status->flag & RX_FLAG_80P80MHZ) | ||
322 | *pos++ = 0; /* marked not known above */ | ||
323 | else if (status->flag & RX_FLAG_160MHZ) | ||
324 | *pos++ = 11; | ||
325 | else if (status->flag & RX_FLAG_40MHZ) | ||
326 | *pos++ = 1; | ||
327 | else /* 20 MHz */ | ||
328 | *pos++ = 0; | ||
329 | /* MCS/NSS */ | ||
330 | *pos = (status->rate_idx << 4) | status->vht_nss; | ||
331 | pos += 4; | ||
332 | /* coding field */ | ||
333 | pos++; | ||
334 | /* group ID */ | ||
335 | pos++; | ||
336 | /* partial_aid */ | ||
337 | pos += 2; | ||
338 | } | ||
339 | |||
300 | if (status->vendor_radiotap_len) { | 340 | if (status->vendor_radiotap_len) { |
301 | /* ensure 2 byte alignment for the vendor field as required */ | 341 | /* ensure 2 byte alignment for the vendor field as required */ |
302 | if ((pos - (u8 *)rthdr) & 1) | 342 | if ((pos - (u8 *)rthdr) & 1) |