提交 a8241310 编写于 作者: K Karl Beldan 提交者: Johannes Berg

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: NKarl Beldan <karl.beldan@rivierawaves.com>
Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
上级 9e2bc79b
...@@ -235,7 +235,8 @@ static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册