Takashi Iwai d0c4bf
From 091296d30917f6e63a9402974f546412dfb2a8e6 Mon Sep 17 00:00:00 2001
Takashi Iwai d0c4bf
From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Takashi Iwai d0c4bf
Date: Sat, 5 Feb 2022 11:21:36 +0200
Takashi Iwai d0c4bf
Subject: [PATCH] iwlwifi: mvm: refactor setting PPE thresholds in STA_HE_CTXT_CMD
Takashi Iwai d0c4bf
Git-commit: 091296d30917f6e63a9402974f546412dfb2a8e6
Takashi Iwai d0c4bf
Patch-mainline: v5.18-rc1
Takashi Iwai d0c4bf
References: bsc#1202131
Takashi Iwai d0c4bf
Takashi Iwai d0c4bf
We are setting the PPE Thresholds in STA_HE_CTXT_CMD according
Takashi Iwai d0c4bf
to HE PHY Capabilities IE. As EHT is introduced, we will have to
Takashi Iwai d0c4bf
set this thresholds according to EHT PHY Capabilities IE if we're
Takashi Iwai d0c4bf
in an EHT connection. Some parts of the code can be used for both
Takashi Iwai d0c4bf
HE and EHT. Put this parts in functions which will be used in the
Takashi Iwai d0c4bf
patch which adds support for EHT PPE.
Takashi Iwai d0c4bf
Takashi Iwai d0c4bf
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Takashi Iwai d0c4bf
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Takashi Iwai d0c4bf
Link: https://lore.kernel.org/r/iwlwifi.20220205112029.48a508dfffef.If392e44d88f96ebed7fadf827e327194d4bd97b1@changeid
Takashi Iwai d0c4bf
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai d0c4bf
Takashi Iwai d0c4bf
---
Takashi Iwai d0c4bf
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c |  204 ++++++++++++----------
Takashi Iwai d0c4bf
 include/linux/ieee80211.h                         |    1 
Takashi Iwai d0c4bf
 2 files changed, 114 insertions(+), 91 deletions(-)
Takashi Iwai d0c4bf
Takashi Iwai d0c4bf
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
Takashi Iwai d0c4bf
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
Takashi Iwai d0c4bf
@@ -1,6 +1,6 @@
Takashi Iwai d0c4bf
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
Takashi Iwai d0c4bf
 /*
Takashi Iwai d0c4bf
- * Copyright (C) 2012-2014, 2018-2020 Intel Corporation
Takashi Iwai d0c4bf
+ * Copyright (C) 2012-2014, 2018-2022 Intel Corporation
Takashi Iwai d0c4bf
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
Takashi Iwai d0c4bf
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
Takashi Iwai d0c4bf
  */
Takashi Iwai d0c4bf
@@ -1807,6 +1807,103 @@ static u8 iwl_mvm_he_get_ppe_val(u8 *ppe
Takashi Iwai d0c4bf
 	return res;
Takashi Iwai d0c4bf
 }
Takashi Iwai d0c4bf
 
Takashi Iwai d0c4bf
+static void iwl_mvm_parse_ppe(struct iwl_mvm *mvm,
Takashi Iwai d0c4bf
+			      struct iwl_he_pkt_ext_v2 *pkt_ext, u8 nss,
Takashi Iwai d0c4bf
+			      u8 ru_index_bitmap, u8 *ppe, u8 ppe_pos_bit)
Takashi Iwai d0c4bf
+{
Takashi Iwai d0c4bf
+	int i;
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+	/*
Takashi Iwai d0c4bf
+	* FW currently supports only nss == MAX_HE_SUPP_NSS
Takashi Iwai d0c4bf
+	*
Takashi Iwai d0c4bf
+	* If nss > MAX: we can ignore values we don't support
Takashi Iwai d0c4bf
+	* If nss < MAX: we can set zeros in other streams
Takashi Iwai d0c4bf
+	*/
Takashi Iwai d0c4bf
+	if (nss > MAX_HE_SUPP_NSS) {
Takashi Iwai d0c4bf
+		IWL_INFO(mvm, "Got NSS = %d - trimming to %d\n", nss,
Takashi Iwai d0c4bf
+			 MAX_HE_SUPP_NSS);
Takashi Iwai d0c4bf
+		nss = MAX_HE_SUPP_NSS;
Takashi Iwai d0c4bf
+	}
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+	for (i = 0; i < nss; i++) {
Takashi Iwai d0c4bf
+		u8 ru_index_tmp = ru_index_bitmap << 1;
Takashi Iwai d0c4bf
+		u8 low_th = IWL_HE_PKT_EXT_NONE, high_th = IWL_HE_PKT_EXT_NONE;
Takashi Iwai d0c4bf
+		u8 bw;
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+		for (bw = 0;
Takashi Iwai d0c4bf
+		     bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
Takashi Iwai d0c4bf
+		     bw++) {
Takashi Iwai d0c4bf
+			ru_index_tmp >>= 1;
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+			if (!(ru_index_tmp & 1))
Takashi Iwai d0c4bf
+				continue;
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+			high_th = iwl_mvm_he_get_ppe_val(ppe, ppe_pos_bit);
Takashi Iwai d0c4bf
+			ppe_pos_bit += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
Takashi Iwai d0c4bf
+			low_th = iwl_mvm_he_get_ppe_val(ppe, ppe_pos_bit);
Takashi Iwai d0c4bf
+			ppe_pos_bit += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+			pkt_ext->pkt_ext_qam_th[i][bw][0] = low_th;
Takashi Iwai d0c4bf
+			pkt_ext->pkt_ext_qam_th[i][bw][1] = high_th;
Takashi Iwai d0c4bf
+		}
Takashi Iwai d0c4bf
+	}
Takashi Iwai d0c4bf
+}
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+static void iwl_mvm_set_pkt_ext_from_he_ppe(struct iwl_mvm *mvm,
Takashi Iwai d0c4bf
+					    struct ieee80211_sta *sta,
Takashi Iwai d0c4bf
+					    struct iwl_he_pkt_ext_v2 *pkt_ext)
Takashi Iwai d0c4bf
+{
Takashi Iwai d0c4bf
+	u8 nss = (sta->he_cap.ppe_thres[0] & IEEE80211_PPE_THRES_NSS_MASK) + 1;
Takashi Iwai d0c4bf
+	u8 *ppe = &sta->he_cap.ppe_thres[0];
Takashi Iwai d0c4bf
+	u8 ru_index_bitmap =
Takashi Iwai d0c4bf
+		u8_get_bits(*ppe,
Takashi Iwai d0c4bf
+			    IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK);
Takashi Iwai d0c4bf
+	/* Starting after PPE header */
Takashi Iwai d0c4bf
+	u8 ppe_pos_bit = IEEE80211_HE_PPE_THRES_INFO_HEADER_SIZE;
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+	iwl_mvm_parse_ppe(mvm, pkt_ext, nss, ru_index_bitmap, ppe, ppe_pos_bit);
Takashi Iwai d0c4bf
+}
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+static void iwl_mvm_set_pkt_ext_from_nominal_padding(struct iwl_he_pkt_ext_v2 *pkt_ext,
Takashi Iwai d0c4bf
+						     u8 nominal_padding,
Takashi Iwai d0c4bf
+						     u32 *flags)
Takashi Iwai d0c4bf
+{
Takashi Iwai d0c4bf
+	int low_th = -1;
Takashi Iwai d0c4bf
+	int high_th = -1;
Takashi Iwai d0c4bf
+	int i;
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+	switch (nominal_padding) {
Takashi Iwai d0c4bf
+	case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_0US:
Takashi Iwai d0c4bf
+		low_th = IWL_HE_PKT_EXT_NONE;
Takashi Iwai d0c4bf
+		high_th = IWL_HE_PKT_EXT_NONE;
Takashi Iwai d0c4bf
+		break;
Takashi Iwai d0c4bf
+	case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_8US:
Takashi Iwai d0c4bf
+		low_th = IWL_HE_PKT_EXT_BPSK;
Takashi Iwai d0c4bf
+		high_th = IWL_HE_PKT_EXT_NONE;
Takashi Iwai d0c4bf
+		break;
Takashi Iwai d0c4bf
+	case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US:
Takashi Iwai d0c4bf
+		low_th = IWL_HE_PKT_EXT_NONE;
Takashi Iwai d0c4bf
+		high_th = IWL_HE_PKT_EXT_BPSK;
Takashi Iwai d0c4bf
+		break;
Takashi Iwai d0c4bf
+	}
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+	/* Set the PPE thresholds accordingly */
Takashi Iwai d0c4bf
+	if (low_th >= 0 && high_th >= 0) {
Takashi Iwai d0c4bf
+		for (i = 0; i < MAX_HE_SUPP_NSS; i++) {
Takashi Iwai d0c4bf
+			u8 bw;
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+			for (bw = 0;
Takashi Iwai d0c4bf
+			     bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
Takashi Iwai d0c4bf
+			     bw++) {
Takashi Iwai d0c4bf
+				pkt_ext->pkt_ext_qam_th[i][bw][0] = low_th;
Takashi Iwai d0c4bf
+				pkt_ext->pkt_ext_qam_th[i][bw][1] = high_th;
Takashi Iwai d0c4bf
+			}
Takashi Iwai d0c4bf
+		}
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
+		*flags |= STA_CTXT_HE_PACKET_EXT;
Takashi Iwai d0c4bf
+	}
Takashi Iwai d0c4bf
+}
Takashi Iwai d0c4bf
+
Takashi Iwai d0c4bf
 static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
Takashi Iwai d0c4bf
 			       struct ieee80211_vif *vif, u8 sta_id)
Takashi Iwai d0c4bf
 {
Takashi Iwai d0c4bf
@@ -1916,100 +2013,25 @@ static void iwl_mvm_cfg_he_sta(struct iw
Takashi Iwai d0c4bf
 	 * Initialize the PPE thresholds to "None" (7), as described in Table
Takashi Iwai d0c4bf
 	 * 9-262ac of 80211.ax/D3.0.
Takashi Iwai d0c4bf
 	 */
Takashi Iwai d0c4bf
-	memset(&sta_ctxt_cmd.pkt_ext, 7, sizeof(sta_ctxt_cmd.pkt_ext));
Takashi Iwai d0c4bf
+	memset(&sta_ctxt_cmd.pkt_ext, IWL_HE_PKT_EXT_NONE,
Takashi Iwai d0c4bf
+	       sizeof(sta_ctxt_cmd.pkt_ext));
Takashi Iwai d0c4bf
 
Takashi Iwai d0c4bf
 	/* If PPE Thresholds exist, parse them into a FW-familiar format. */
Takashi Iwai d0c4bf
 	if (sta->he_cap.he_cap_elem.phy_cap_info[6] &
Takashi Iwai d0c4bf
-	    IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
Takashi Iwai d0c4bf
-		u8 nss = (sta->he_cap.ppe_thres[0] &
Takashi Iwai d0c4bf
-			  IEEE80211_PPE_THRES_NSS_MASK) + 1;
Takashi Iwai d0c4bf
-		u8 ru_index_bitmap =
Takashi Iwai d0c4bf
-			(sta->he_cap.ppe_thres[0] &
Takashi Iwai d0c4bf
-			 IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK) >>
Takashi Iwai d0c4bf
-			IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS;
Takashi Iwai d0c4bf
-		u8 *ppe = &sta->he_cap.ppe_thres[0];
Takashi Iwai d0c4bf
-		u8 ppe_pos_bit = 7; /* Starting after PPE header */
Takashi Iwai d0c4bf
-
Takashi Iwai d0c4bf
-		/*
Takashi Iwai d0c4bf
-		 * FW currently supports only nss == MAX_HE_SUPP_NSS
Takashi Iwai d0c4bf
-		 *
Takashi Iwai d0c4bf
-		 * If nss > MAX: we can ignore values we don't support
Takashi Iwai d0c4bf
-		 * If nss < MAX: we can set zeros in other streams
Takashi Iwai d0c4bf
-		 */
Takashi Iwai d0c4bf
-		if (nss > MAX_HE_SUPP_NSS) {
Takashi Iwai d0c4bf
-			IWL_INFO(mvm, "Got NSS = %d - trimming to %d\n", nss,
Takashi Iwai d0c4bf
-				 MAX_HE_SUPP_NSS);
Takashi Iwai d0c4bf
-			nss = MAX_HE_SUPP_NSS;
Takashi Iwai d0c4bf
-		}
Takashi Iwai d0c4bf
-
Takashi Iwai d0c4bf
-		for (i = 0; i < nss; i++) {
Takashi Iwai d0c4bf
-			u8 ru_index_tmp = ru_index_bitmap << 1;
Takashi Iwai d0c4bf
-			u8 bw;
Takashi Iwai d0c4bf
-
Takashi Iwai d0c4bf
-			for (bw = 0;
Takashi Iwai d0c4bf
-			     bw < ARRAY_SIZE(sta_ctxt_cmd.pkt_ext.pkt_ext_qam_th[i]);
Takashi Iwai d0c4bf
-			     bw++) {
Takashi Iwai d0c4bf
-				ru_index_tmp >>= 1;
Takashi Iwai d0c4bf
-				if (!(ru_index_tmp & 1))
Takashi Iwai d0c4bf
-					continue;
Takashi Iwai d0c4bf
-
Takashi Iwai d0c4bf
-				sta_ctxt_cmd.pkt_ext.pkt_ext_qam_th[i][bw][1] =
Takashi Iwai d0c4bf
-					iwl_mvm_he_get_ppe_val(ppe,
Takashi Iwai d0c4bf
-							       ppe_pos_bit);
Takashi Iwai d0c4bf
-				ppe_pos_bit +=
Takashi Iwai d0c4bf
-					IEEE80211_PPE_THRES_INFO_PPET_SIZE;
Takashi Iwai d0c4bf
-				sta_ctxt_cmd.pkt_ext.pkt_ext_qam_th[i][bw][0] =
Takashi Iwai d0c4bf
-					iwl_mvm_he_get_ppe_val(ppe,
Takashi Iwai d0c4bf
-							       ppe_pos_bit);
Takashi Iwai d0c4bf
-				ppe_pos_bit +=
Takashi Iwai d0c4bf
-					IEEE80211_PPE_THRES_INFO_PPET_SIZE;
Takashi Iwai d0c4bf
-			}
Takashi Iwai d0c4bf
-		}
Takashi Iwai d0c4bf
-
Takashi Iwai d0c4bf
+		IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
Takashi Iwai d0c4bf
+		iwl_mvm_set_pkt_ext_from_he_ppe(mvm, sta,
Takashi Iwai d0c4bf
+						&sta_ctxt_cmd.pkt_ext);
Takashi Iwai d0c4bf
 		flags |= STA_CTXT_HE_PACKET_EXT;
Takashi Iwai d0c4bf
-	} else if (u8_get_bits(sta->he_cap.he_cap_elem.phy_cap_info[9],
Takashi Iwai d0c4bf
-			       IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK)
Takashi Iwai d0c4bf
-		   != IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_RESERVED) {
Takashi Iwai d0c4bf
-		int low_th = -1;
Takashi Iwai d0c4bf
-		int high_th = -1;
Takashi Iwai d0c4bf
-
Takashi Iwai d0c4bf
-		/* Take the PPE thresholds from the nominal padding info */
Takashi Iwai d0c4bf
-		switch (u8_get_bits(sta->he_cap.he_cap_elem.phy_cap_info[9],
Takashi Iwai d0c4bf
-				    IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK)) {
Takashi Iwai d0c4bf
-		case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_0US:
Takashi Iwai d0c4bf
-			low_th = IWL_HE_PKT_EXT_NONE;
Takashi Iwai d0c4bf
-			high_th = IWL_HE_PKT_EXT_NONE;
Takashi Iwai d0c4bf
-			break;
Takashi Iwai d0c4bf
-		case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_8US:
Takashi Iwai d0c4bf
-			low_th = IWL_HE_PKT_EXT_BPSK;
Takashi Iwai d0c4bf
-			high_th = IWL_HE_PKT_EXT_NONE;
Takashi Iwai d0c4bf
-			break;
Takashi Iwai d0c4bf
-		case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US:
Takashi Iwai d0c4bf
-			low_th = IWL_HE_PKT_EXT_NONE;
Takashi Iwai d0c4bf
-			high_th = IWL_HE_PKT_EXT_BPSK;
Takashi Iwai d0c4bf
-			break;
Takashi Iwai d0c4bf
-		}
Takashi Iwai d0c4bf
-
Takashi Iwai d0c4bf
-		/* Set the PPE thresholds accordingly */
Takashi Iwai d0c4bf
-		if (low_th >= 0 && high_th >= 0) {
Takashi Iwai d0c4bf
-			struct iwl_he_pkt_ext_v2 *pkt_ext =
Takashi Iwai d0c4bf
-				&sta_ctxt_cmd.pkt_ext;
Takashi Iwai d0c4bf
-
Takashi Iwai d0c4bf
-			for (i = 0; i < MAX_HE_SUPP_NSS; i++) {
Takashi Iwai d0c4bf
-				u8 bw;
Takashi Iwai d0c4bf
-
Takashi Iwai d0c4bf
-				for (bw = 0;
Takashi Iwai d0c4bf
-				     bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
Takashi Iwai d0c4bf
-				     bw++) {
Takashi Iwai d0c4bf
-					pkt_ext->pkt_ext_qam_th[i][bw][0] =
Takashi Iwai d0c4bf
-						low_th;
Takashi Iwai d0c4bf
-					pkt_ext->pkt_ext_qam_th[i][bw][1] =
Takashi Iwai d0c4bf
-						high_th;
Takashi Iwai d0c4bf
-				}
Takashi Iwai d0c4bf
-			}
Takashi Iwai d0c4bf
-
Takashi Iwai d0c4bf
-			flags |= STA_CTXT_HE_PACKET_EXT;
Takashi Iwai d0c4bf
-		}
Takashi Iwai d0c4bf
+	/* PPE Thresholds doesn't exist - set the API PPE values
Takashi Iwai d0c4bf
+	* according to Common Nominal Packet Padding fiels. */
Takashi Iwai d0c4bf
+	} else {
Takashi Iwai d0c4bf
+		u8 nominal_padding =
Takashi Iwai d0c4bf
+			u8_get_bits(sta->he_cap.he_cap_elem.phy_cap_info[9],
Takashi Iwai d0c4bf
+				    IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK);
Takashi Iwai d0c4bf
+		if (nominal_padding != IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_RESERVED)
Takashi Iwai d0c4bf
+			iwl_mvm_set_pkt_ext_from_nominal_padding(&sta_ctxt_cmd.pkt_ext,
Takashi Iwai d0c4bf
+								 nominal_padding,
Takashi Iwai d0c4bf
+								 &flags);
Takashi Iwai d0c4bf
 	}
Takashi Iwai d0c4bf
 
Takashi Iwai d0c4bf
 	if (sta->he_cap.he_cap_elem.mac_cap_info[2] &
Takashi Iwai d0c4bf
--- a/include/linux/ieee80211.h
Takashi Iwai d0c4bf
+++ b/include/linux/ieee80211.h
Takashi Iwai d0c4bf
@@ -2228,6 +2228,7 @@ ieee80211_he_mcs_nss_size(const struct i
Takashi Iwai d0c4bf
 #define IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK		0x78
Takashi Iwai d0c4bf
 #define IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS		(3)
Takashi Iwai d0c4bf
 #define IEEE80211_PPE_THRES_INFO_PPET_SIZE			(3)
Takashi Iwai d0c4bf
+#define IEEE80211_HE_PPE_THRES_INFO_HEADER_SIZE			(7)
Takashi Iwai d0c4bf
 
Takashi Iwai d0c4bf
 /*
Takashi Iwai d0c4bf
  * Calculate 802.11ax HE capabilities IE PPE field size