mac80211: parse VHT info in injected frames

Add VHT radiotap parsing support to ieee80211_parse_tx_radiotap().
That capability has been tested using a d-link dir-860l rev b1 running
OpenWrt trunk and mt76 driver

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Lorenzo Bianconi 2016-02-23 15:43:35 +01:00 committed by Johannes Berg
parent 1948b2a2ec
commit 646e76bb5d
2 changed files with 44 additions and 0 deletions

View file

@ -45,6 +45,19 @@ radiotap headers and used to control injection:
number of retries when either IEEE80211_RADIOTAP_RATE or number of retries when either IEEE80211_RADIOTAP_RATE or
IEEE80211_RADIOTAP_MCS was used IEEE80211_RADIOTAP_MCS was used
* IEEE80211_RADIOTAP_VHT
VHT mcs and number of streams used in the transmission (only for devices
without own rate control). Also other fields are parsed
flags field
IEEE80211_RADIOTAP_VHT_FLAG_SGI: use short guard interval
bandwidth field
1: send using 40MHz channel width
4: send using 80MHz channel width
11: send using 160MHz channel width
The injection code can also skip all other currently defined radiotap fields The injection code can also skip all other currently defined radiotap fields
facilitating replay of captured radiotap headers directly. facilitating replay of captured radiotap headers directly.

View file

@ -1692,6 +1692,8 @@ static bool ieee80211_parse_tx_radiotap(struct ieee80211_local *local,
u8 rate_retries = 0; u8 rate_retries = 0;
u16 rate_flags = 0; u16 rate_flags = 0;
u8 mcs_known, mcs_flags; u8 mcs_known, mcs_flags;
u16 vht_known;
u8 vht_mcs = 0, vht_nss = 0;
int i; int i;
info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
@ -1772,6 +1774,32 @@ static bool ieee80211_parse_tx_radiotap(struct ieee80211_local *local,
rate_flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; rate_flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
break; break;
case IEEE80211_RADIOTAP_VHT:
vht_known = get_unaligned_le16(iterator.this_arg);
rate_found = true;
rate_flags = IEEE80211_TX_RC_VHT_MCS;
if ((vht_known & IEEE80211_RADIOTAP_VHT_KNOWN_GI) &&
(iterator.this_arg[2] &
IEEE80211_RADIOTAP_VHT_FLAG_SGI))
rate_flags |= IEEE80211_TX_RC_SHORT_GI;
if (vht_known &
IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH) {
if (iterator.this_arg[3] == 1)
rate_flags |=
IEEE80211_TX_RC_40_MHZ_WIDTH;
else if (iterator.this_arg[3] == 4)
rate_flags |=
IEEE80211_TX_RC_80_MHZ_WIDTH;
else if (iterator.this_arg[3] == 11)
rate_flags |=
IEEE80211_TX_RC_160_MHZ_WIDTH;
}
vht_mcs = iterator.this_arg[4] >> 4;
vht_nss = iterator.this_arg[4] & 0xF;
break;
/* /*
* Please update the file * Please update the file
* Documentation/networking/mac80211-injection.txt * Documentation/networking/mac80211-injection.txt
@ -1797,6 +1825,9 @@ static bool ieee80211_parse_tx_radiotap(struct ieee80211_local *local,
if (rate_flags & IEEE80211_TX_RC_MCS) { if (rate_flags & IEEE80211_TX_RC_MCS) {
info->control.rates[0].idx = rate; info->control.rates[0].idx = rate;
} else if (rate_flags & IEEE80211_TX_RC_VHT_MCS) {
ieee80211_rate_set_vht(info->control.rates, vht_mcs,
vht_nss);
} else { } else {
for (i = 0; i < sband->n_bitrates; i++) { for (i = 0; i < sband->n_bitrates; i++) {
if (rate * 5 != sband->bitrates[i].bitrate) if (rate * 5 != sband->bitrates[i].bitrate)