Commit c3d1f875 authored by Shaul Triebitz's avatar Shaul Triebitz Committed by Johannes Berg

mac80211: support reporting 0-length PSDU in radiotap

For certain sounding frames, it may be useful to report them
to userspace even though they don't have a PSDU in order to
determine the PHY parameters (e.g. VHT rate/stream config.)
Add support for this to mac80211.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarShaul Triebitz <shaul.triebitz@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 62872a9b
...@@ -75,6 +75,7 @@ enum ieee80211_radiotap_presence { ...@@ -75,6 +75,7 @@ enum ieee80211_radiotap_presence {
IEEE80211_RADIOTAP_TIMESTAMP = 22, IEEE80211_RADIOTAP_TIMESTAMP = 22,
IEEE80211_RADIOTAP_HE = 23, IEEE80211_RADIOTAP_HE = 23,
IEEE80211_RADIOTAP_HE_MU = 24, IEEE80211_RADIOTAP_HE_MU = 24,
IEEE80211_RADIOTAP_ZERO_LEN_PSDU = 26,
IEEE80211_RADIOTAP_LSIG = 27, IEEE80211_RADIOTAP_LSIG = 27,
/* valid in every it_present bitmap, even vendor namespaces */ /* valid in every it_present bitmap, even vendor namespaces */
...@@ -340,6 +341,11 @@ struct ieee80211_radiotap_lsig { ...@@ -340,6 +341,11 @@ struct ieee80211_radiotap_lsig {
__le16 data1, data2; __le16 data1, data2;
}; };
enum ieee80211_radiotap_zero_len_psdu_type {
IEEE80211_RADIOTAP_ZERO_LEN_PSDU_SOUNDING = 0,
IEEE80211_RADIOTAP_ZERO_LEN_PSDU_VENDOR = 0xff,
};
/** /**
* ieee80211_get_radiotap_len - get radiotap header length * ieee80211_get_radiotap_len - get radiotap header length
*/ */
......
...@@ -1142,6 +1142,10 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) ...@@ -1142,6 +1142,10 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* @RX_FLAG_RADIOTAP_HE_MU: HE MU radiotap data is present * @RX_FLAG_RADIOTAP_HE_MU: HE MU radiotap data is present
* (&struct ieee80211_radiotap_he_mu) * (&struct ieee80211_radiotap_he_mu)
* @RX_FLAG_RADIOTAP_LSIG: L-SIG radiotap data is present * @RX_FLAG_RADIOTAP_LSIG: L-SIG radiotap data is present
* @RX_FLAG_NO_PSDU: use the frame only for radiotap reporting, with
* the "0-length PSDU" field included there. The value for it is
* in &struct ieee80211_rx_status. Note that if this value isn't
* known the frame shouldn't be reported.
*/ */
enum mac80211_rx_flags { enum mac80211_rx_flags {
RX_FLAG_MMIC_ERROR = BIT(0), RX_FLAG_MMIC_ERROR = BIT(0),
...@@ -1173,6 +1177,7 @@ enum mac80211_rx_flags { ...@@ -1173,6 +1177,7 @@ enum mac80211_rx_flags {
RX_FLAG_RADIOTAP_HE = BIT(26), RX_FLAG_RADIOTAP_HE = BIT(26),
RX_FLAG_RADIOTAP_HE_MU = BIT(27), RX_FLAG_RADIOTAP_HE_MU = BIT(27),
RX_FLAG_RADIOTAP_LSIG = BIT(28), RX_FLAG_RADIOTAP_LSIG = BIT(28),
RX_FLAG_NO_PSDU = BIT(29),
}; };
/** /**
...@@ -1245,6 +1250,7 @@ enum mac80211_rx_encoding { ...@@ -1245,6 +1250,7 @@ enum mac80211_rx_encoding {
* @ampdu_reference: A-MPDU reference number, must be a different value for * @ampdu_reference: A-MPDU reference number, must be a different value for
* each A-MPDU but the same for each subframe within one A-MPDU * each A-MPDU but the same for each subframe within one A-MPDU
* @ampdu_delimiter_crc: A-MPDU delimiter CRC * @ampdu_delimiter_crc: A-MPDU delimiter CRC
* @zero_length_psdu_type: radiotap type of the 0-length PSDU
*/ */
struct ieee80211_rx_status { struct ieee80211_rx_status {
u64 mactime; u64 mactime;
...@@ -1265,6 +1271,7 @@ struct ieee80211_rx_status { ...@@ -1265,6 +1271,7 @@ struct ieee80211_rx_status {
u8 chains; u8 chains;
s8 chain_signal[IEEE80211_MAX_CHAINS]; s8 chain_signal[IEEE80211_MAX_CHAINS];
u8 ampdu_delimiter_crc; u8 ampdu_delimiter_crc;
u8 zero_length_psdu_type;
}; };
/** /**
......
...@@ -115,7 +115,8 @@ static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len, ...@@ -115,7 +115,8 @@ static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len,
if (status->flag & (RX_FLAG_FAILED_FCS_CRC | if (status->flag & (RX_FLAG_FAILED_FCS_CRC |
RX_FLAG_FAILED_PLCP_CRC | RX_FLAG_FAILED_PLCP_CRC |
RX_FLAG_ONLY_MONITOR)) RX_FLAG_ONLY_MONITOR |
RX_FLAG_NO_PSDU))
return true; return true;
if (unlikely(skb->len < 16 + present_fcs_len + rtap_space)) if (unlikely(skb->len < 16 + present_fcs_len + rtap_space))
...@@ -189,6 +190,9 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local, ...@@ -189,6 +190,9 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he_mu) != 12); BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he_mu) != 12);
} }
if (status->flag & RX_FLAG_NO_PSDU)
len += 1;
if (status->flag & RX_FLAG_RADIOTAP_LSIG) { if (status->flag & RX_FLAG_RADIOTAP_LSIG) {
len = ALIGN(len, 2); len = ALIGN(len, 2);
len += 4; len += 4;
...@@ -642,6 +646,12 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, ...@@ -642,6 +646,12 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
pos += sizeof(he_mu); pos += sizeof(he_mu);
} }
if (status->flag & RX_FLAG_NO_PSDU) {
rthdr->it_present |=
cpu_to_le32(1 << IEEE80211_RADIOTAP_ZERO_LEN_PSDU);
*pos++ = status->zero_length_psdu_type;
}
if (status->flag & RX_FLAG_RADIOTAP_LSIG) { if (status->flag & RX_FLAG_RADIOTAP_LSIG) {
/* ensure 2 byte alignment */ /* ensure 2 byte alignment */
while ((pos - (u8 *)rthdr) & 1) while ((pos - (u8 *)rthdr) & 1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment