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 */
|
/* IEEE80211_RADIOTAP_RATE rate */
|
||||||
if (info->status.rates[0].idx >= 0 &&
|
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;
|
len += 2;
|
||||||
|
|
||||||
/* IEEE80211_RADIOTAP_TX_FLAGS */
|
/* IEEE80211_RADIOTAP_TX_FLAGS */
|
||||||
@ -244,16 +245,21 @@ static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info)
|
|||||||
/* IEEE80211_RADIOTAP_DATA_RETRIES */
|
/* IEEE80211_RADIOTAP_DATA_RETRIES */
|
||||||
len += 1;
|
len += 1;
|
||||||
|
|
||||||
/* IEEE80211_TX_RC_MCS */
|
/* IEEE80211_RADIOTAP_MCS
|
||||||
if (info->status.rates[0].idx >= 0 &&
|
* IEEE80211_RADIOTAP_VHT */
|
||||||
info->status.rates[0].flags & IEEE80211_TX_RC_MCS)
|
if (info->status.rates[0].idx >= 0) {
|
||||||
len += 3;
|
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;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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,
|
struct sk_buff *skb, int retry_count,
|
||||||
int rtap_len, int shift)
|
int rtap_len, int shift)
|
||||||
{
|
{
|
||||||
@ -280,7 +286,8 @@ ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band *sband,
|
|||||||
|
|
||||||
/* IEEE80211_RADIOTAP_RATE */
|
/* IEEE80211_RADIOTAP_RATE */
|
||||||
if (info->status.rates[0].idx >= 0 &&
|
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;
|
u16 rate;
|
||||||
|
|
||||||
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_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 = retry_count;
|
||||||
pos++;
|
pos++;
|
||||||
|
|
||||||
/* IEEE80211_TX_RC_MCS */
|
if (info->status.rates[0].idx < 0)
|
||||||
if (info->status.rates[0].idx >= 0 &&
|
return;
|
||||||
info->status.rates[0].flags & IEEE80211_TX_RC_MCS) {
|
|
||||||
|
/* 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);
|
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS);
|
||||||
pos[0] = IEEE80211_RADIOTAP_MCS_HAVE_MCS |
|
pos[0] = IEEE80211_RADIOTAP_MCS_HAVE_MCS |
|
||||||
IEEE80211_RADIOTAP_MCS_HAVE_GI |
|
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[1] |= IEEE80211_RADIOTAP_MCS_FMT_GF;
|
||||||
pos[2] = info->status.rates[0].idx;
|
pos[2] = info->status.rates[0].idx;
|
||||||
pos += 3;
|
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,
|
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);
|
dev_kfree_skb(skb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ieee80211_add_tx_radiotap_header(sband, skb, retry_count, rtap_len,
|
ieee80211_add_tx_radiotap_header(local, sband, skb, retry_count,
|
||||||
shift);
|
rtap_len, shift);
|
||||||
|
|
||||||
/* XXX: is this sufficient for BPF? */
|
/* XXX: is this sufficient for BPF? */
|
||||||
skb_set_mac_header(skb, 0);
|
skb_set_mac_header(skb, 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user