Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ enum ieee80211_radiotap_presence {
	IEEE80211_RADIOTAP_TIMESTAMP = 22,
	IEEE80211_RADIOTAP_HE = 23,
	IEEE80211_RADIOTAP_HE_MU = 24,
	IEEE80211_RADIOTAP_ZERO_LEN_PSDU = 26,
	IEEE80211_RADIOTAP_LSIG = 27,

	/* valid in every it_present bitmap, even vendor namespaces */
@@ -340,6 +341,11 @@ struct ieee80211_radiotap_lsig {
	__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
 */
+7 −0
Original line number Diff line number Diff line
@@ -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
 *	(&struct ieee80211_radiotap_he_mu)
 * @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 {
	RX_FLAG_MMIC_ERROR		= BIT(0),
@@ -1173,6 +1177,7 @@ enum mac80211_rx_flags {
	RX_FLAG_RADIOTAP_HE		= BIT(26),
	RX_FLAG_RADIOTAP_HE_MU		= BIT(27),
	RX_FLAG_RADIOTAP_LSIG		= BIT(28),
	RX_FLAG_NO_PSDU			= BIT(29),
};

/**
@@ -1245,6 +1250,7 @@ enum mac80211_rx_encoding {
 * @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
 * @ampdu_delimiter_crc: A-MPDU delimiter CRC
 * @zero_length_psdu_type: radiotap type of the 0-length PSDU
 */
struct ieee80211_rx_status {
	u64 mactime;
@@ -1265,6 +1271,7 @@ struct ieee80211_rx_status {
	u8 chains;
	s8 chain_signal[IEEE80211_MAX_CHAINS];
	u8 ampdu_delimiter_crc;
	u8 zero_length_psdu_type;
};

/**
+11 −1
Original line number Diff line number Diff line
@@ -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 |
			    RX_FLAG_FAILED_PLCP_CRC |
			    RX_FLAG_ONLY_MONITOR))
			    RX_FLAG_ONLY_MONITOR |
			    RX_FLAG_NO_PSDU))
		return true;

	if (unlikely(skb->len < 16 + present_fcs_len + rtap_space))
@@ -189,6 +190,9 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
		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) {
		len = ALIGN(len, 2);
		len += 4;
@@ -642,6 +646,12 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
		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) {
		/* ensure 2 byte alignment */
		while ((pos - (u8 *)rthdr) & 1)