mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
mac80211: report some VHT radiotap infos for tx status
The radiotap VHT info is 12 bytes (required to be aligned on 2) : u16 known - IEEE80211_RADIOTAP_VHT_KNOWN_* u8 flags - IEEE80211_RADIOTAP_VHT_FLAG_* u8 bandwidth u8 mcs_nss[4] u8 coding u8 group_id u16 partial_aid ATM mac80211 can handle IEEE80211_RADIOTAP_VHT_KNOWN_{GI,BANDWIDTH} and mcs_nss[0] (i.e single user) in simple cases. This is more a placeholder to let sniffers give more clues for VHT, since we don't have yet the proper infrastructure/conventions in mac80211 for complete feedback (e.g consider dynamic BW). Signed-off-by: Karl Beldan <karl.beldan@rivierawaves.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
9e2bc79bce
commit
a824131017
@ -235,7 +235,8 @@ static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info)
|
||||
|
||||
/* IEEE80211_RADIOTAP_RATE rate */
|
||||
if (info->status.rates[0].idx >= 0 &&
|
||||
!(info->status.rates[0].flags & IEEE80211_TX_RC_MCS))
|
||||
!(info->status.rates[0].flags & (IEEE80211_TX_RC_MCS |
|
||||
IEEE80211_TX_RC_VHT_MCS)))
|
||||
len += 2;
|
||||
|
||||
/* IEEE80211_RADIOTAP_TX_FLAGS */
|
||||
@ -244,16 +245,21 @@ static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info)
|
||||
/* IEEE80211_RADIOTAP_DATA_RETRIES */
|
||||
len += 1;
|
||||
|
||||
/* IEEE80211_TX_RC_MCS */
|
||||
if (info->status.rates[0].idx >= 0 &&
|
||||
info->status.rates[0].flags & IEEE80211_TX_RC_MCS)
|
||||
len += 3;
|
||||
/* IEEE80211_RADIOTAP_MCS
|
||||
* IEEE80211_RADIOTAP_VHT */
|
||||
if (info->status.rates[0].idx >= 0) {
|
||||
if (info->status.rates[0].flags & IEEE80211_TX_RC_MCS)
|
||||
len += 3;
|
||||
else if (info->status.rates[0].flags & IEEE80211_TX_RC_VHT_MCS)
|
||||
len = ALIGN(len, 2) + 12;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void
|
||||
ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band *sband,
|
||||
ieee80211_add_tx_radiotap_header(struct ieee80211_local *local,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct sk_buff *skb, int retry_count,
|
||||
int rtap_len, int shift)
|
||||
{
|
||||
@ -280,7 +286,8 @@ ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band *sband,
|
||||
|
||||
/* IEEE80211_RADIOTAP_RATE */
|
||||
if (info->status.rates[0].idx >= 0 &&
|
||||
!(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) {
|
||||
!(info->status.rates[0].flags & (IEEE80211_TX_RC_MCS |
|
||||
IEEE80211_TX_RC_VHT_MCS))) {
|
||||
u16 rate;
|
||||
|
||||
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
|
||||
@ -310,9 +317,12 @@ ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band *sband,
|
||||
*pos = retry_count;
|
||||
pos++;
|
||||
|
||||
/* IEEE80211_TX_RC_MCS */
|
||||
if (info->status.rates[0].idx >= 0 &&
|
||||
info->status.rates[0].flags & IEEE80211_TX_RC_MCS) {
|
||||
if (info->status.rates[0].idx < 0)
|
||||
return;
|
||||
|
||||
/* IEEE80211_RADIOTAP_MCS
|
||||
* IEEE80211_RADIOTAP_VHT */
|
||||
if (info->status.rates[0].flags & IEEE80211_TX_RC_MCS) {
|
||||
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS);
|
||||
pos[0] = IEEE80211_RADIOTAP_MCS_HAVE_MCS |
|
||||
IEEE80211_RADIOTAP_MCS_HAVE_GI |
|
||||
@ -325,8 +335,48 @@ ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band *sband,
|
||||
pos[1] |= IEEE80211_RADIOTAP_MCS_FMT_GF;
|
||||
pos[2] = info->status.rates[0].idx;
|
||||
pos += 3;
|
||||
}
|
||||
} else if (info->status.rates[0].flags & IEEE80211_TX_RC_VHT_MCS) {
|
||||
u16 known = local->hw.radiotap_vht_details &
|
||||
(IEEE80211_RADIOTAP_VHT_KNOWN_GI |
|
||||
IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH);
|
||||
|
||||
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT);
|
||||
|
||||
/* required alignment from rthdr */
|
||||
pos = (u8 *)rthdr + ALIGN(pos - (u8 *)rthdr, 2);
|
||||
|
||||
/* u16 known - IEEE80211_RADIOTAP_VHT_KNOWN_* */
|
||||
put_unaligned_le16(known, pos);
|
||||
pos += 2;
|
||||
|
||||
/* u8 flags - IEEE80211_RADIOTAP_VHT_FLAG_* */
|
||||
if (info->status.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
*pos |= IEEE80211_RADIOTAP_VHT_FLAG_SGI;
|
||||
pos++;
|
||||
|
||||
/* u8 bandwidth */
|
||||
if (info->status.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
*pos = 1;
|
||||
else if (info->status.rates[0].flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
|
||||
*pos = 4;
|
||||
else if (info->status.rates[0].flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
|
||||
*pos = 11;
|
||||
else /* IEEE80211_TX_RC_{20_MHZ_WIDTH,FIXME:DUP_DATA} */
|
||||
*pos = 0;
|
||||
pos++;
|
||||
|
||||
/* u8 mcs_nss[4] */
|
||||
*pos = (ieee80211_rate_get_vht_mcs(&info->status.rates[0]) << 4) |
|
||||
ieee80211_rate_get_vht_nss(&info->status.rates[0]);
|
||||
pos += 4;
|
||||
|
||||
/* u8 coding */
|
||||
pos++;
|
||||
/* u8 group_id */
|
||||
pos++;
|
||||
/* u16 partial_aid */
|
||||
pos += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void ieee80211_report_used_skb(struct ieee80211_local *local,
|
||||
@ -631,8 +681,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
dev_kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
ieee80211_add_tx_radiotap_header(sband, skb, retry_count, rtap_len,
|
||||
shift);
|
||||
ieee80211_add_tx_radiotap_header(local, sband, skb, retry_count,
|
||||
rtap_len, shift);
|
||||
|
||||
/* XXX: is this sufficient for BPF? */
|
||||
skb_set_mac_header(skb, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user