Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Feb 2025 20:27:13 GMT
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 6b244c766608 - stable/14 - LinuxKPI: 802.11: fill in a lot more RX status fields
Message-ID:  <202502242027.51OKRDGC027347@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=6b244c766608d70ea4e9e7615f34c4339b86486c

commit 6b244c766608d70ea4e9e7615f34c4339b86486c
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2025-01-28 00:20:01 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2025-02-24 20:26:48 +0000

    LinuxKPI: 802.11: fill in a lot more RX status fields
    
    Convert a lot more LinuxKPI rx_status fields to net80211 rx_stats
    bits for as much as we can see fit.  Factor the entire logic out
    into its own function as it got quite long.
    
    Now only net80211 needs to start using more of these values and
    report them.
    
    Also fix some related fields and struct definitions in LinuxKPI.
    
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit 49010ba706d39fba0d8bc128d96e6122e65eb8ad)
---
 .../linuxkpi/common/include/linux/ieee80211.h      |   4 +-
 sys/compat/linuxkpi/common/include/net/cfg80211.h  |   9 +-
 sys/compat/linuxkpi/common/include/net/mac80211.h  |  10 +-
 sys/compat/linuxkpi/common/src/linux_80211.c       | 196 +++++++++++++++++----
 4 files changed, 170 insertions(+), 49 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/ieee80211.h b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
index 0169e12b1804..20527a8174f5 100644
--- a/sys/compat/linuxkpi/common/include/linux/ieee80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
@@ -100,7 +100,9 @@ struct ieee80211_mmie_16 {
 #define	IEEE80211_QOS_CTL_ACK_POLICY_NOACK	0x0020
 #define	IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT	0x0100
 
-#define	IEEE80211_RATE_SHORT_PREAMBLE		BIT(0)
+enum ieee80211_rate_flags {
+	IEEE80211_RATE_SHORT_PREAMBLE		= BIT(0),
+};
 
 enum ieee80211_rate_control_changed_flags {
 	IEEE80211_RC_BW_CHANGED			= BIT(0),
diff --git a/sys/compat/linuxkpi/common/include/net/cfg80211.h b/sys/compat/linuxkpi/common/include/net/cfg80211.h
index ee16449ecd1c..bcbf629abb2f 100644
--- a/sys/compat/linuxkpi/common/include/net/cfg80211.h
+++ b/sys/compat/linuxkpi/common/include/net/cfg80211.h
@@ -175,11 +175,10 @@ struct rate_info {
 };
 
 struct ieee80211_rate {
-	/* TODO FIXME */
-	uint32_t		bitrate;
-	uint32_t		hw_value;
-	uint32_t		hw_value_short;
-	uint32_t		flags;
+	uint32_t		flags;					/* enum ieee80211_rate_flags */
+	uint16_t		bitrate;
+	uint16_t		hw_value;
+	uint16_t		hw_value_short;
 };
 
 struct ieee80211_sta_ht_cap {
diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h
index f5d3e1036edc..43df740b0bd0 100644
--- a/sys/compat/linuxkpi/common/include/net/mac80211.h
+++ b/sys/compat/linuxkpi/common/include/net/mac80211.h
@@ -600,8 +600,10 @@ enum ieee80211_rx_status_flags {
 	RX_FLAG_DUP_VALIDATED		= BIT(5),
 	RX_FLAG_FAILED_FCS_CRC		= BIT(6),
 	RX_FLAG_ICV_STRIPPED		= BIT(7),
-	RX_FLAG_MACTIME_PLCP_START	= BIT(8),
-	RX_FLAG_MACTIME_START		= BIT(9),
+	RX_FLAG_MACTIME			= BIT(8) | BIT(9),
+	RX_FLAG_MACTIME_PLCP_START	= 1 << 8,
+	RX_FLAG_MACTIME_START		= 2 << 8,
+	RX_FLAG_MACTIME_END		= 3 << 8,
 	RX_FLAG_MIC_STRIPPED		= BIT(10),
 	RX_FLAG_MMIC_ERROR		= BIT(11),
 	RX_FLAG_MMIC_STRIPPED		= BIT(12),
@@ -616,12 +618,12 @@ enum ieee80211_rx_status_flags {
 	RX_FLAG_AMPDU_IS_LAST		= BIT(21),
 	RX_FLAG_AMPDU_LAST_KNOWN	= BIT(22),
 	RX_FLAG_AMSDU_MORE		= BIT(23),
-	RX_FLAG_MACTIME_END		= BIT(24),
+				/*	= BIT(24), */
 	RX_FLAG_ONLY_MONITOR		= BIT(25),
 	RX_FLAG_SKIP_MONITOR		= BIT(26),
 	RX_FLAG_8023			= BIT(27),
 	RX_FLAG_RADIOTAP_TLV_AT_END	= BIT(28),
-	RX_FLAG_MACTIME			= BIT(29),
+				/*	= BIT(29), */
 	RX_FLAG_MACTIME_IS_RTAP_TS64	= BIT(30),
 	RX_FLAG_FAILED_PLCP_CRC		= BIT(31),
 };
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index 7b0ddc3cbf9a..0cffa36d96cb 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -5309,6 +5309,160 @@ lkpi_80211_lhw_rxq_task(void *ctx, int pending)
 	}
 }
 
+static void
+lkpi_convert_rx_status(struct ieee80211_hw *hw,
+    struct ieee80211_rx_status *rx_status,
+    struct ieee80211_rx_stats *rx_stats,
+    uint8_t *rssip)
+{
+	struct ieee80211_supported_band *supband;
+	int i;
+	uint8_t rssi;
+
+	memset(rx_stats, 0, sizeof(*rx_stats));
+	rx_stats->r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI;
+	/* XXX-BZ correct hardcoded noise floor, survey data? */
+	rx_stats->c_nf = -96;
+	if (ieee80211_hw_check(hw, SIGNAL_DBM) &&
+	    !(rx_status->flag & RX_FLAG_NO_SIGNAL_VAL))
+		rssi = rx_status->signal;
+	else
+		rssi = rx_stats->c_nf;
+	/*
+	 * net80211 signal strength data are in .5 dBm units relative to
+	 * the current noise floor (see comment in ieee80211_node.h).
+	 */
+	rssi -= rx_stats->c_nf;
+	if (rssip != NULL)
+		*rssip = rssi;
+	rx_stats->c_rssi = rssi * 2;
+	rx_stats->r_flags |= IEEE80211_R_BAND;
+	rx_stats->c_band =
+	    lkpi_nl80211_band_to_net80211_band(rx_status->band);
+	rx_stats->r_flags |= IEEE80211_R_FREQ | IEEE80211_R_IEEE;
+	rx_stats->c_freq = rx_status->freq;
+	rx_stats->c_ieee = ieee80211_mhz2ieee(rx_stats->c_freq, rx_stats->c_band);
+
+	rx_stats->c_rx_tsf = rx_status->mactime;
+
+	/* XXX RX_FLAG_MACTIME_IS_RTAP_TS64 ? */
+	if ((rx_status->flag & RX_FLAG_MACTIME) ==
+	    (RX_FLAG_MACTIME_START|RX_FLAG_MACTIME_END)) {
+		rx_stats->r_flags |= IEEE80211_R_TSF64;
+		/* XXX RX_FLAG_MACTIME_PLCP_START ? */
+		if ((rx_status->flag & RX_FLAG_MACTIME) == RX_FLAG_MACTIME_START)
+			rx_stats->r_flags |= IEEE80211_R_TSF_START;
+		if ((rx_status->flag & RX_FLAG_MACTIME) == RX_FLAG_MACTIME_END)
+			rx_stats->r_flags |= IEEE80211_R_TSF_END;
+		/* XXX-BZ if TSF_END will net80211 do the unwind of time? */
+	}
+
+	if (rx_status->chains != 0) {
+		int cc;
+		int8_t crssi;
+
+		rx_stats->c_chain = rx_status->chains;
+		rx_stats->r_flags |= IEEE80211_R_C_CHAIN;
+
+		cc = 0;
+		for (i = 0; i < nitems(rx_status->chain_signal); i++) {
+			if (!(rx_status->chains & BIT(i)))
+				continue;
+			crssi = rx_status->chain_signal[i];
+			crssi -= rx_stats->c_nf;
+			rx_stats->c_rssi_ctl[i] = crssi * 2;
+			rx_stats->c_rssi_ext[i] = crssi * 2;	/* XXX _ext ??? ATH thing? */
+			/* We currently only have the global noise floor value. */
+			rx_stats->c_nf_ctl[i] = rx_stats->c_nf;
+			rx_stats->c_nf_ext[i] = rx_stats->c_nf;
+			cc++;
+		}
+		if (cc > 0)
+			 rx_stats->r_flags |= (IEEE80211_R_C_NF | IEEE80211_R_C_RSSI);
+	}
+
+	/* XXX-NET80211 We are not going to populate c_phytype! */
+
+	switch (rx_status->encoding) {
+	case RX_ENC_LEGACY:
+		supband = hw->wiphy->bands[rx_status->band];
+		if (supband != NULL)
+			rx_stats->c_rate = supband->bitrates[rx_status->rate_idx].bitrate;
+		/* Is there a LinuxKPI way of reporting IEEE80211_RX_F_CCK / _OFDM? */
+		break;
+	case RX_ENC_HT:
+		rx_stats->c_pktflags |= IEEE80211_RX_F_HT;
+		if ((rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI) != 0)
+			rx_stats->c_pktflags |= IEEE80211_RX_F_SHORTGI;
+		rx_stats->c_rate = rx_status->rate_idx;		/* mcs */
+		break;
+	case RX_ENC_VHT:
+		rx_stats->c_pktflags |= IEEE80211_RX_F_VHT;
+		if ((rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI) != 0)
+			rx_stats->c_pktflags |= IEEE80211_RX_F_SHORTGI;
+		rx_stats->c_rate = rx_status->rate_idx;		/* mcs */
+		rx_stats->c_vhtnss = rx_status->nss;
+		break;
+	case RX_ENC_HE:
+	case RX_ENC_EHT:
+		TODO("net80211 has not matching encoding for %u", rx_status->encoding);
+		break;
+	}
+
+	switch (rx_status->bw) {
+	case RATE_INFO_BW_20:
+		rx_stats->c_width = IEEE80211_RX_FW_20MHZ;
+		break;
+	case RATE_INFO_BW_40:
+		rx_stats->c_width = IEEE80211_RX_FW_40MHZ;
+		break;
+	case RATE_INFO_BW_80:
+		rx_stats->c_width = IEEE80211_RX_FW_80MHZ;
+		break;
+	case RATE_INFO_BW_160:
+		rx_stats->c_width = IEEE80211_RX_FW_160MHZ;
+		break;
+	case RATE_INFO_BW_320:
+	case RATE_INFO_BW_HE_RU:
+	case RATE_INFO_BW_EHT_RU:
+	case RATE_INFO_BW_5:
+	case RATE_INFO_BW_10:
+		TODO("net80211 has not matching bandwidth for %u", rx_status->bw);
+		break;
+	}
+
+	if ((rx_status->enc_flags & RX_ENC_FLAG_LDPC) != 0)
+		rx_stats->c_pktflags |= IEEE80211_RX_F_LDPC;
+	if ((rx_status->enc_flags & RX_ENC_FLAG_STBC_MASK) != 0)
+		 rx_stats->c_pktflags |= IEEE80211_RX_F_STBC;
+
+	/*
+	 * We only need these for LKPI_80211_HW_CRYPTO in theory but in
+	 * case the hardware does something we do not expect always leave
+	 * these enabled.  Leaving this commant as documentation for the || 1.
+	 */
+#if defined(LKPI_80211_HW_CRYPTO) || 1
+	if (rx_status->flag & RX_FLAG_DECRYPTED) {
+		rx_stats->c_pktflags |= IEEE80211_RX_F_DECRYPTED;
+		/* Only valid if decrypted is set. */
+		if (rx_status->flag & RX_FLAG_PN_VALIDATED)
+			rx_stats->c_pktflags |= IEEE80211_RX_F_PN_VALIDATED;
+	}
+	if (rx_status->flag & RX_FLAG_MMIC_STRIPPED)
+		rx_stats->c_pktflags |= IEEE80211_RX_F_MMIC_STRIP;
+	if (rx_status->flag & RX_FLAG_MIC_STRIPPED) {
+		/* net80211 re-uses M[ichael]MIC for MIC too. Confusing. */
+		rx_stats->c_pktflags |= IEEE80211_RX_F_MMIC_STRIP;
+	}
+	if (rx_status->flag & RX_FLAG_IV_STRIPPED)
+		rx_stats->c_pktflags |= IEEE80211_RX_F_IV_STRIP;
+	if (rx_status->flag & RX_FLAG_MMIC_ERROR)
+		rx_stats->c_pktflags |= IEEE80211_RX_F_FAIL_MIC;
+	if (rx_status->flag & RX_FLAG_FAILED_FCS_CRC)
+		rx_stats->c_pktflags |= IEEE80211_RX_F_FAIL_FCSCRC;
+#endif
+}
+
 /* For %list see comment towards the end of the function. */
 void
 linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
@@ -5326,7 +5480,7 @@ linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 	struct ieee80211_hdr *hdr;
 	struct lkpi_sta *lsta;
 	int i, offset, ok;
-	int8_t rssi;
+	uint8_t rssi;
 	bool is_beacon;
 
 	if (skb->len < 2) {
@@ -5403,44 +5557,8 @@ linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 no_trace_beacons:
 #endif
 
-	memset(&rx_stats, 0, sizeof(rx_stats));
-	rx_stats.r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI;
-	/* XXX-BZ correct hardcoded rssi and noise floor, how? survey? */
-	rx_stats.c_nf = -96;
-	if (ieee80211_hw_check(hw, SIGNAL_DBM) &&
-	    !(rx_status->flag & RX_FLAG_NO_SIGNAL_VAL))
-		rssi = rx_status->signal;
-	else
-		rssi = rx_stats.c_nf;
-	/*
-	 * net80211 signal strength data are in .5 dBm units relative to
-	 * the current noise floor (see comment in ieee80211_node.h).
-	 */
-	rssi -= rx_stats.c_nf;
-	rx_stats.c_rssi = rssi * 2;
-	rx_stats.r_flags |= IEEE80211_R_BAND;
-	rx_stats.c_band =
-	    lkpi_nl80211_band_to_net80211_band(rx_status->band);
-	rx_stats.r_flags |= IEEE80211_R_FREQ | IEEE80211_R_IEEE;
-	rx_stats.c_freq = rx_status->freq;
-	rx_stats.c_ieee = ieee80211_mhz2ieee(rx_stats.c_freq, rx_stats.c_band);
-
-	/*
-	 * We only need these for LKPI_80211_HW_CRYPTO in theory but in
-	 * case the hardware does something we do not expect always leave
-	 * these enabled.  Leaving this commant as documentation for the || 1.
-	 */
-#if defined(LKPI_80211_HW_CRYPTO) || 1
-	if (rx_status->flag & RX_FLAG_DECRYPTED) {
-		rx_stats.c_pktflags |= IEEE80211_RX_F_DECRYPTED;
-		/* Only valid if decrypted is set. */
-		if (rx_status->flag & RX_FLAG_PN_VALIDATED)
-			rx_stats.c_pktflags |= IEEE80211_RX_F_PN_VALIDATED;
-	}
-#endif
-
-	/* XXX (*sta_statistics)() to get to some of that? */
-	/* XXX-BZ dump the FreeBSD version of rx_stats as well! */
+	rssi = 0;
+	lkpi_convert_rx_status(hw, rx_status, &rx_stats, &rssi);
 
 	lhw = HW_TO_LHW(hw);
 	ic = lhw->ic;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202502242027.51OKRDGC027347>