Search Linux Wireless

Re: [PATCH] wifi: ath12k: read country code from SMBIOS for WCN7850

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 9/13/2023 3:51 AM, Wen Gong wrote:
This read the country code from SMBIOS and send the country code
to firmware, firmware will indicate the regulatory domain info of the
country code and then ath12k will use the info.

dmesg:
[ 1242.637253] ath12k_pci 0000:02:00.0: worldwide regdomain setting from SMBIOS
[ 1242.637259] ath12k_pci 0000:02:00.0: bdf variant name not found.
[ 1242.637261] ath12k_pci 0000:02:00.0: SMBIOS bdf variant name not set.
[ 1242.927543] ath12k_pci 0000:02:00.0: set current country pdev id 0 alpha2 00

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4

Signed-off-by: Wen Gong <quic_wgong@xxxxxxxxxxx>

Acked-by: Jeff Johnson <quic_jjohnson@xxxxxxxxxxx>

---
depends on 5 patches in public review:
Wen Gong:

https://lore.kernel.org/linux-wireless/20230905105637.10230-1-quic_wgong@xxxxxxxxxxx/
wifi: ath12k: add read variant from SMBIOS for download board data

https://lore.kernel.org/linux-wireless/20230906082948.18452-1-quic_wgong@xxxxxxxxxxx/
wifi: ath12k: add read variant from SMBIOS for download board data
[PATCH 0/4] wifi: ath12k: add 11d scan offload support and handle country code for WCN7850
   wifi: ath12k: add configure country code for WCN7850
   wifi: ath12k: add 11d scan offload support
   wifi: ath12k: avoid firmware crash when reg set for WCN7850
   wifi: ath12k: store and send country code to firmware after recovery

  drivers/net/wireless/ath/ath12k/core.c | 26 +++++++++++++++++++++++--
  drivers/net/wireless/ath/ath12k/core.h | 27 +++++++++++++++++++++++++-
  drivers/net/wireless/ath/ath12k/mac.c  | 11 +++++++++++
  3 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 4c4abeba39c8..de9b7604eaa2 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -377,7 +377,7 @@ static void ath12k_core_stop(struct ath12k_base *ab)
  	/* De-Init of components as needed */
  }
-static void ath12k_core_check_bdfext(const struct dmi_header *hdr, void *data)
+static void ath12k_core_check_cc_code_bdfext(const struct dmi_header *hdr, void *data)
  {
  	struct ath12k_base *ab = data;
  	const char *magic = ATH12K_SMBIOS_BDF_EXT_MAGIC;
@@ -399,6 +399,28 @@ static void ath12k_core_check_bdfext(const struct dmi_header *hdr, void *data)
  		return;
  	}
+ spin_lock_bh(&ab->base_lock);
+
+	switch (smbios->country_code_flag) {
+	case ATH12K_SMBIOS_CC_ISO:
+		ab->new_alpha2[0] = u16_get_bits(smbios->cc_code, 0xff00);
+		ab->new_alpha2[1] = u16_get_bits(smbios->cc_code, 0xff);
+		ath12k_dbg(ab, ATH12K_DBG_BOOT, "boot smbios cc_code %c%c\n",
+			   ab->new_alpha2[0], ab->new_alpha2[1]);
+		break;
+	case ATH12K_SMBIOS_CC_WW:
+		ab->new_alpha2[0] = '0';
+		ab->new_alpha2[1] = '0';
+		ath12k_dbg(ab, ATH12K_DBG_BOOT, "boot smbios worldwide regdomain\n");
+		break;
+	default:
+		ath12k_dbg(ab, ATH12K_DBG_BOOT, "boot ignore smbios country code setting %d\n",
+			   smbios->country_code_flag);
+		break;
+	}
+
+	spin_unlock_bh(&ab->base_lock);
+
  	if (!smbios->bdf_enabled) {
  		ath12k_dbg(ab, ATH12K_DBG_BOOT, "bdf variant name not found.\n");
  		return;
@@ -438,7 +460,7 @@ static void ath12k_core_check_bdfext(const struct dmi_header *hdr, void *data)
  int ath12k_core_check_smbios(struct ath12k_base *ab)
  {
  	ab->qmi.target.bdf_ext[0] = '\0';
-	dmi_walk(ath12k_core_check_bdfext, ab);
+	dmi_walk(ath12k_core_check_cc_code_bdfext, ab);
if (ab->qmi.target.bdf_ext[0] == '\0')
  		return -ENODATA;
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 35a3b6357eb5..d35b97520e6d 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -142,9 +142,34 @@ struct ath12k_ext_irq_grp {
  	struct net_device napi_ndev;
  };
+enum ath12k_smbios_cc_type {
+	/* disable country code setting from SMBIOS */
+	ATH12K_SMBIOS_CC_DISABLE = 0,
+
+	/* set country code by ANSI country name, based on ISO3166-1 alpha2 */
+	ATH12K_SMBIOS_CC_ISO = 1,
+
+	/* worldwide regdomain */
+	ATH12K_SMBIOS_CC_WW = 2,
+};
+
  struct ath12k_smbios_bdf {
  	struct dmi_header hdr;
-	u32 padding;
+	u8 features_disabled;
+
+	/* enum ath12k_smbios_cc_type */
+	u8 country_code_flag;
+
+	/* To set specific country, you need to set country code
+	 * flag=ATH12K_SMBIOS_CC_ISO first, then if country is United
+	 * States, then country code value = 0x5553 ("US",'U' = 0x55, 'S'=
+	 * 0x53). To set country to INDONESIA, then country code value =
+	 * 0x4944 ("IN", 'I'=0x49, 'D'=0x44). If country code flag =
+	 * ATH12K_SMBIOS_CC_WW, then you can use worldwide regulatory
+	 * setting.
+	 */
+	u16 cc_code;
+
  	u8 bdf_enabled;
  	u8 bdf_ext[];
  } __packed;
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 0df154c34f8f..ba292c2873d1 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -7509,6 +7509,17 @@ static int __ath12k_mac_register(struct ath12k *ar)
  		goto err_unregister_hw;
  	}
+ if (ar->ab->hw_params->current_cc_support && ab->new_alpha2[0]) {
+		struct wmi_set_current_country_params set_current_param = {};
+
+		memcpy(&set_current_param.alpha2, ab->new_alpha2, 2);
+		memcpy(&ar->alpha2, ab->new_alpha2, 2);
+		ret = ath12k_wmi_send_set_current_country_cmd(ar, &set_current_param);
+		if (ret)
+			ath12k_warn(ar->ab,
+				    "failed set cc code for mac register: %d\n", ret);
+	}
+
  	return 0;
err_unregister_hw:

base-commit: 3f257461ab0ab19806bae2bfde4c3cd88dbf050e
prerequisite-patch-id: 2ee4ca0fc2ff95861b978c44b2cb04771c927ee1
prerequisite-patch-id: a341b369c2d9f319970dff05a117cc4c6c85c31c
prerequisite-patch-id: 04c82a480f25fa06001c9ff3fb1d30630f9ec82a
prerequisite-patch-id: 9ba56bba555d7c1b7dea4ad394d39d8397e79754
prerequisite-patch-id: 7c1c0cda8e48fee003376e035ac2b472d22cbae9




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux