Commit 85e02a0a authored by Ping-Ke Shih's avatar Ping-Ke Shih
Browse files

wifi: rtw89: add LDPC and STBC to rx_status and radiotap known fields for monitor mode



Add LDPC and STBC to rx_status by hardware PPDU status, and set them as
known fields of radiotap, so we can check these capabilities in monitor
mode.

Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Link: https://msgid.link/20240522023830.9798-2-pkshih@realtek.com
parent f12fc206
Loading
Loading
Loading
Loading
+35 −1
Original line number Diff line number Diff line
@@ -1557,6 +1557,12 @@ static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev,
	u32 t;

	phy_ppdu->chan_idx = le32_get_bits(ie->w0, RTW89_PHY_STS_IE01_W0_CH_IDX);

	if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR) {
		phy_ppdu->ldpc = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_LDPC);
		phy_ppdu->stbc = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_STBC);
	}

	if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6)
		return;

@@ -1982,6 +1988,23 @@ static void rtw89_core_hw_to_sband_rate(struct ieee80211_rx_status *rx_status)
	rx_status->rate_idx -= 4;
}

static
void rtw89_core_update_rx_status_by_ppdu(struct rtw89_dev *rtwdev,
					 struct ieee80211_rx_status *rx_status,
					 struct rtw89_rx_phy_ppdu *phy_ppdu)
{
	if (!(rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR))
		return;

	if (!phy_ppdu)
		return;

	if (phy_ppdu->ldpc)
		rx_status->enc_flags |= RX_ENC_FLAG_LDPC;
	if (phy_ppdu->stbc)
		rx_status->enc_flags |= u8_encode_bits(1, RX_ENC_FLAG_STBC_MASK);
}

static const u8 rx_status_bw_to_radiotap_eht_usig[] = {
	[RATE_INFO_BW_20] = IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_20MHZ,
	[RATE_INFO_BW_5] = U8_MAX,
@@ -2025,10 +2048,14 @@ static void rtw89_core_update_radiotap_eht(struct rtw89_dev *rtwdev,

	eht->user_info[0] =
		cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN |
			    IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O);
			    IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O |
			    IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN);
	eht->user_info[0] |=
		le32_encode_bits(rx_status->rate_idx, IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) |
		le32_encode_bits(rx_status->nss, IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O);
	if (rx_status->enc_flags & RX_ENC_FLAG_LDPC)
		eht->user_info[0] |=
			cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_CODING);

	/* U-SIG */
	tlv = (void *)tlv + sizeof(*tlv) + ALIGN(eht_len, 4);
@@ -2054,6 +2081,8 @@ static void rtw89_core_update_radiotap(struct rtw89_dev *rtwdev,
{
	static const struct ieee80211_radiotap_he known_he = {
		.data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
				     IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN |
				     IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN |
				     IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN),
		.data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN),
	};
@@ -2085,6 +2114,7 @@ static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev,

	rtw89_core_hw_to_sband_rate(rx_status);
	rtw89_core_rx_stats(rtwdev, phy_ppdu, desc_info, skb_ppdu);
	rtw89_core_update_rx_status_by_ppdu(rtwdev, rx_status, phy_ppdu);
	rtw89_core_update_radiotap(rtwdev, skb_ppdu, rx_status);
	/* In low power mode, it does RX in thread context. */
	local_bh_disable();
@@ -4496,6 +4526,10 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
	hw->max_tx_aggregation_subframes = RTW89_MAX_TX_AGG_NUM;
	hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;

	hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FEC |
				    IEEE80211_RADIOTAP_MCS_HAVE_STBC;
	hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC;

	ieee80211_hw_set(hw, SIGNAL_DBM);
	ieee80211_hw_set(hw, HAS_RATE_CONTROL);
	ieee80211_hw_set(hw, MFP_CAPABLE);
+2 −0
Original line number Diff line number Diff line
@@ -793,6 +793,8 @@ struct rtw89_rx_phy_ppdu {
		u8 evm_max;
		u8 evm_min;
	} ofdm;
	bool ldpc;
	bool stbc;
	bool to_self;
	bool valid;
};
+2 −0
Original line number Diff line number Diff line
@@ -558,6 +558,8 @@ struct rtw89_phy_sts_ie0 {
#define RTW89_PHY_STS_IE01_W2_AVG_SNR GENMASK(5, 0)
#define RTW89_PHY_STS_IE01_W2_EVM_MAX GENMASK(15, 8)
#define RTW89_PHY_STS_IE01_W2_EVM_MIN GENMASK(23, 16)
#define RTW89_PHY_STS_IE01_W2_LDPC BIT(28)
#define RTW89_PHY_STS_IE01_W2_STBC BIT(30)

enum rtw89_tx_channel {
	RTW89_TXCH_ACH0	= 0,