diff mbox series

[ath-next,v3] wifi: ath12k: read country code from SMBIOS for WCN7850

Message ID 20250321090307.1397-1-quic_kangyang@quicinc.com (mailing list archive)
State Superseded
Delegated to: Jeff Johnson
Headers show
Series [ath-next,v3] wifi: ath12k: read country code from SMBIOS for WCN7850 | expand

Checks

Context Check Description
wifibot/fixes_present success Fixes tag not required for -next series
wifibot/series_format success Single patches do not need cover letters
wifibot/tree_selection success Clearly marked for ath-next
wifibot/ynl success Generated files up to date; no warnings/errors; no diff in generated;
wifibot/build_clang fail Errors and warnings before: 0 this patch: 31
wifibot/build_32bit fail Errors and warnings before: 0 this patch: 32
wifibot/build_allmodconfig_warn fail Errors and warnings before: 0 this patch: 32
wifibot/build_clang_rust success No Rust files in patch. Skipping build
wifibot/build_tools success No tools touched, skip
wifibot/check_selftest success No net selftest shell script
wifibot/checkpatch warning WARNING: line length of 81 exceeds 80 columns WARNING: line length of 86 exceeds 80 columns WARNING: line length of 87 exceeds 80 columns WARNING: line length of 94 exceeds 80 columns
wifibot/deprecated_api success None detected
wifibot/header_inline success No static functions without inline keyword in header files
wifibot/kdoc success Errors and warnings before: 0 this patch: 0
wifibot/source_inline success Was 0 now: 0
wifibot/verify_fixes success No Fixes tag
wifibot/verify_signedoff success Signed-off-by tag matches author and committer

Commit Message

Kang Yang March 21, 2025, 9:03 a.m. UTC
Read the country code from SMBIOS and send it to the firmware. The
firmware will then indicate the regulatory domain information for
the country code, which ath12k will use.

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-02582-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1

Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
---

Depends-On:
        [PATCH ath-next v12 0/4] wifi: ath12k: add 11d scan offload support and handle country code for WCN7850
	https://lore.kernel.org/linux-wireless/20250321084518.1619-1-quic_kangyang@quicinc.com/

Note: This patch is an old patch in public review written by
Wen Gong. Just resend it for him.
Link: https://lore.kernel.org/linux-wireless/20230913105156.17618-1-quic_wgong@quicinc.com/

v3:
    1. rebase on tag: ath-202503172347.
    2. add branch tag.
    3. add descripition for Wen Gong.
v2: 
    1. rebase on tag: ath/main(ath-202502181756).
    2. rewrite commit message.

---
 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(-)


base-commit: b6f473c96421b8b451a8df8ccb620bcd71d4b3f4
prerequisite-patch-id: 4d98208c1659b01545c48494f7a84c5ba4888da0
prerequisite-patch-id: dc095f4a1f0d9f6c4f6f850fa1dfe3d804f41e47
prerequisite-patch-id: 7bffae693031c27eadd2b3452a059bb224070e0b
prerequisite-patch-id: 3711a8bb24847dd69c5805d7425416b239144898

Comments

Zong-Zhe Yang March 21, 2025, 11:06 a.m. UTC | #1
Kang Yang <quic_kangyang@quicinc.com> wrote:
> 
> Read the country code from SMBIOS and send it to the firmware. The firmware will then
> indicate the regulatory domain information for the country code, which ath12k will use.
> 
> [...]
> 
> 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, 0xff);
> +               ab->new_alpha2[1] = u16_get_bits(smbios->cc_code, 0xff);

It seems that one of the masks is wrong.

> +               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;
> @@ -690,7 +712,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 116cf530621f..e2d300bd5972 100644
> --- a/drivers/net/wireless/ath/ath12k/core.h
> +++ b/drivers/net/wireless/ath/ath12k/core.h
> @@ -172,9 +172,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;
> 
> [...]
>
Kang Yang March 21, 2025, 11:14 a.m. UTC | #2
On 3/21/2025 7:06 PM, Zong-Zhe Yang wrote:
> Kang Yang <quic_kangyang@quicinc.com> wrote:
>>
>> Read the country code from SMBIOS and send it to the firmware. The firmware will then
>> indicate the regulatory domain information for the country code, which ath12k will use.
>>
>> [...]
>>
>> 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, 0xff);
>> +               ab->new_alpha2[1] = u16_get_bits(smbios->cc_code, 0xff);
> 
> It seems that one of the masks is wrong.
> 

Oh, yes.

>> +               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;
>> @@ -690,7 +712,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 116cf530621f..e2d300bd5972 100644
>> --- a/drivers/net/wireless/ath/ath12k/core.h
>> +++ b/drivers/net/wireless/ath/ath12k/core.h
>> @@ -172,9 +172,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 mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 11c73fe45308..29a5b8f1fc0d 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -629,7 +629,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;
@@ -651,6 +651,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, 0xff);
+		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;
@@ -690,7 +712,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 116cf530621f..e2d300bd5972 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -172,9 +172,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 ba9dd19b2e1d..4be937abe3ce 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -11619,6 +11619,17 @@  static int ath12k_mac_hw_register(struct ath12k_hw *ah)
 			goto err_unregister_hw;
 		}
 
+		if (ar->ab->hw_params->current_cc_support && ab->new_alpha2[0]) {
+			struct wmi_set_current_country_arg current_cc = {};
+
+			memcpy(&current_cc.alpha2, ab->new_alpha2, 2);
+			memcpy(&ar->alpha2, ab->new_alpha2, 2);
+			ret = ath12k_wmi_send_set_current_country_cmd(ar, &current_cc);
+			if (ret)
+				ath12k_warn(ar->ab,
+					    "failed set cc code for mac register: %d\n", ret);
+		}
+
 		ath12k_fw_stats_init(ar);
 		ath12k_debugfs_register(ar);
 	}