Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mac80211: support (partial) VHT radiotap information

Add some information that we have about VHT to radiotap.
This at least lets one see the MCS and NSS information.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>

+71
+24
include/net/ieee80211_radiotap.h
··· 186 186 * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless 187 187 * 188 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 194 enum ieee80211_radiotap_type { 191 195 IEEE80211_RADIOTAP_TSFT = 0, ··· 213 209 214 210 IEEE80211_RADIOTAP_MCS = 19, 215 211 IEEE80211_RADIOTAP_AMPDU_STATUS = 20, 212 + IEEE80211_RADIOTAP_VHT = 21, 216 213 217 214 /* valid in every it_present bitmap, even vendor namespaces */ 218 215 IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29, ··· 286 281 #define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008 287 282 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 288 283 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 284 + 285 + /* For IEEE80211_RADIOTAP_VHT */ 286 + #define IEEE80211_RADIOTAP_VHT_KNOWN_STBC 0x0001 287 + #define IEEE80211_RADIOTAP_VHT_KNOWN_TXOP_PS_NA 0x0002 288 + #define IEEE80211_RADIOTAP_VHT_KNOWN_GI 0x0004 289 + #define IEEE80211_RADIOTAP_VHT_KNOWN_SGI_NSYM_DIS 0x0008 290 + #define IEEE80211_RADIOTAP_VHT_KNOWN_LDPC_EXTRA_OFDM_SYM 0x0010 291 + #define IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED 0x0020 292 + #define IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH 0x0040 293 + #define IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID 0x0080 294 + #define IEEE80211_RADIOTAP_VHT_KNOWN_PARTIAL_AID 0x0100 295 + 296 + #define IEEE80211_RADIOTAP_VHT_FLAG_STBC 0x01 297 + #define IEEE80211_RADIOTAP_VHT_FLAG_TXOP_PS_NA 0x02 298 + #define IEEE80211_RADIOTAP_VHT_FLAG_SGI 0x04 299 + #define IEEE80211_RADIOTAP_VHT_FLAG_SGI_NSYM_M10_9 0x08 300 + #define IEEE80211_RADIOTAP_VHT_FLAG_LDPC_EXTRA_OFDM_SYM 0x10 301 + #define IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED 0x20 302 + 289 303 290 304 /* helpers */ 291 305 static inline int ieee80211_get_radiotap_len(unsigned char *data)
+5
include/net/mac80211.h
··· 1473 1473 * include _FMT. Use %IEEE80211_RADIOTAP_MCS_HAVE_* values, only 1474 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 1480 * @netdev_features: netdev features to be set in each netdev created 1477 1481 * from this HW. Note only HW checksum features are currently 1478 1482 * compatible with mac80211. Other feature bits will be rejected. ··· 1503 1499 u8 max_tx_aggregation_subframes; 1504 1500 u8 offchannel_tx_hw_queue; 1505 1501 u8 radiotap_mcs_details; 1502 + u16 radiotap_vht_details; 1506 1503 netdev_features_t netdev_features; 1507 1504 }; 1508 1505
+2
net/mac80211/main.c
··· 638 638 local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS | 639 639 IEEE80211_RADIOTAP_MCS_HAVE_GI | 640 640 IEEE80211_RADIOTAP_MCS_HAVE_BW; 641 + local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | 642 + IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; 641 643 local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; 642 644 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; 643 645
+40
net/mac80211/rx.c
··· 111 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 119 if (status->vendor_radiotap_len) { 115 120 if (WARN_ON_ONCE(status->vendor_radiotap_align == 0)) 116 121 status->vendor_radiotap_align = 1; ··· 300 295 else 301 296 *pos++ = 0; 302 297 *pos++ = 0; 298 + } 299 + 300 + if (status->flag & RX_FLAG_VHT) { 301 + u16 known = local->hw.radiotap_vht_details; 302 + 303 + rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT); 304 + /* known field - how to handle 80+80? */ 305 + if (status->flag & RX_FLAG_80P80MHZ) 306 + known &= ~IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; 307 + put_unaligned_le16(known, pos); 308 + pos += 2; 309 + /* flags */ 310 + if (status->flag & RX_FLAG_SHORT_GI) 311 + *pos |= IEEE80211_RADIOTAP_VHT_FLAG_SGI; 312 + pos++; 313 + /* bandwidth */ 314 + if (status->flag & RX_FLAG_80MHZ) 315 + *pos++ = 4; 316 + else if (status->flag & RX_FLAG_80P80MHZ) 317 + *pos++ = 0; /* marked not known above */ 318 + else if (status->flag & RX_FLAG_160MHZ) 319 + *pos++ = 11; 320 + else if (status->flag & RX_FLAG_40MHZ) 321 + *pos++ = 1; 322 + else /* 20 MHz */ 323 + *pos++ = 0; 324 + /* MCS/NSS */ 325 + *pos = (status->rate_idx << 4) | status->vht_nss; 326 + pos += 4; 327 + /* coding field */ 328 + pos++; 329 + /* group ID */ 330 + pos++; 331 + /* partial_aid */ 332 + pos += 2; 303 333 } 304 334 305 335 if (status->vendor_radiotap_len) {