2024-05-20 02:42:24

by Baochen Qiang

[permalink] [raw]
Subject: [PATCH 0/2] wifi: ath11k: fix wrong regdomain after hibernation

We got report that regdomain is not correct after hibernation,
see details in patch 2.

To fix it, host needs to restore country code to firmware using
ath11k_wmi_send_set_current_country_cmd(). There are several places
where it is called and all of them share the same code snippet. So
refactor them to make code clean, this is done in the first patch.
Actual fix comes in the second patch.

Baochen Qiang (2):
wifi: ath11k: refactor setting country code logic
wifi: ath11k: restore country code during resume

drivers/net/wireless/ath/ath11k/core.c | 29 ++++++++++++++++----------
drivers/net/wireless/ath/ath11k/mac.c | 13 +++---------
drivers/net/wireless/ath/ath11k/reg.c | 14 +++++++++----
drivers/net/wireless/ath/ath11k/reg.h | 4 ++--
4 files changed, 33 insertions(+), 27 deletions(-)


base-commit: d11f74006da48efd32f6304ef8fcec5894171641
--
2.25.1



2024-05-20 02:42:36

by Baochen Qiang

[permalink] [raw]
Subject: [PATCH 1/2] wifi: ath11k: refactor setting country code logic

ath11k_wmi_send_set_current_country_cmd() is called in several places
and all of them are just simply repeating the same logic.

Refactor to make code clean.

Compile tested only.

Signed-off-by: Baochen Qiang <[email protected]>
---
drivers/net/wireless/ath/ath11k/core.c | 19 ++++++++-----------
drivers/net/wireless/ath/ath11k/mac.c | 13 +++----------
drivers/net/wireless/ath/ath11k/reg.c | 14 ++++++++++----
drivers/net/wireless/ath/ath11k/reg.h | 4 ++--
4 files changed, 23 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index d4ef556852c2..748e3ad2bec3 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -1978,23 +1978,20 @@ static void ath11k_update_11d(struct work_struct *work)
struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work);
struct ath11k *ar;
struct ath11k_pdev *pdev;
- struct wmi_set_current_country_params set_current_param = {};
int ret, i;

- spin_lock_bh(&ab->base_lock);
- memcpy(&set_current_param.alpha2, &ab->new_alpha2, 2);
- spin_unlock_bh(&ab->base_lock);
-
- ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c\n",
- set_current_param.alpha2[0],
- set_current_param.alpha2[1]);
-
for (i = 0; i < ab->num_radios; i++) {
pdev = &ab->pdevs[i];
ar = pdev->ar;

- memcpy(&ar->alpha2, &set_current_param.alpha2, 2);
- ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
+ spin_lock_bh(&ab->base_lock);
+ memcpy(&ar->alpha2, &ab->new_alpha2, 2);
+ spin_unlock_bh(&ab->base_lock);
+
+ ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c for pdev %d\n",
+ ar->alpha2[0], ar->alpha2[1], i);
+
+ ret = ath11k_reg_set_cc(ar);
if (ret)
ath11k_warn(ar->ab,
"pdev id %d failed set current country code: %d\n",
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 17b06c0cd062..84415187416d 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -8864,12 +8864,8 @@ ath11k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
ieee80211_wake_queues(ar->hw);

if (ar->ab->hw_params.current_cc_support &&
- ar->alpha2[0] != 0 && ar->alpha2[1] != 0) {
- struct wmi_set_current_country_params set_current_param = {};
-
- memcpy(&set_current_param.alpha2, ar->alpha2, 2);
- ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
- }
+ ar->alpha2[0] != 0 && ar->alpha2[1] != 0)
+ ath11k_reg_set_cc(ar);

if (ab->is_reset) {
recovery_count = atomic_inc_return(&ab->recovery_count);
@@ -10311,11 +10307,8 @@ static int __ath11k_mac_register(struct ath11k *ar)
}

if (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 = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
+ ret = ath11k_reg_set_cc(ar);
if (ret)
ath11k_warn(ar->ab,
"failed set cc code for mac register: %d\n", ret);
diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c
index 4c3aefbbabbe..b0f289784dd3 100644
--- a/drivers/net/wireless/ath/ath11k/reg.c
+++ b/drivers/net/wireless/ath/ath11k/reg.c
@@ -49,7 +49,6 @@ ath11k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
{
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct wmi_init_country_params init_country_param;
- struct wmi_set_current_country_params set_current_param = {};
struct ath11k *ar = hw->priv;
int ret;

@@ -83,9 +82,8 @@ ath11k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
* reg info
*/
if (ar->ab->hw_params.current_cc_support) {
- memcpy(&set_current_param.alpha2, request->alpha2, 2);
- memcpy(&ar->alpha2, &set_current_param.alpha2, 2);
- ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
+ memcpy(&ar->alpha2, request->alpha2, 2);
+ ret = ath11k_reg_set_cc(ar);
if (ret)
ath11k_warn(ar->ab,
"failed set current country code: %d\n", ret);
@@ -1017,3 +1015,11 @@ void ath11k_reg_free(struct ath11k_base *ab)
kfree(ab->new_regd[i]);
}
}
+
+int ath11k_reg_set_cc(struct ath11k *ar)
+{
+ struct wmi_set_current_country_params set_current_param = {};
+
+ memcpy(&set_current_param.alpha2, ar->alpha2, 2);
+ return ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
+}
diff --git a/drivers/net/wireless/ath/ath11k/reg.h b/drivers/net/wireless/ath/ath11k/reg.h
index 64edb794260a..263ea9061948 100644
--- a/drivers/net/wireless/ath/ath11k/reg.h
+++ b/drivers/net/wireless/ath/ath11k/reg.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/

#ifndef ATH11K_REG_H
@@ -45,5 +45,5 @@ ath11k_reg_ap_pwr_convert(enum ieee80211_ap_reg_power power_type);
int ath11k_reg_handle_chan_list(struct ath11k_base *ab,
struct cur_regulatory_info *reg_info,
enum ieee80211_ap_reg_power power_type);
-
+int ath11k_reg_set_cc(struct ath11k *ar);
#endif
--
2.25.1


2024-05-20 02:42:39

by Baochen Qiang

[permalink] [raw]
Subject: [PATCH 2/2] wifi: ath11k: restore country code during resume

We got report that regdomain is not correct after
return from hibernation:

Before hibernation:
% iw reg get
[...]
phy#0 (self-managed)
country CH: DFS-ETSI
(2402 - 2482 @ 40), (N/A, 20), (N/A)
(5170 - 5250 @ 80), (N/A, 23), (N/A), NO-OUTDOOR, AUTO-BW
(5250 - 5330 @ 80), (N/A, 23), (0 ms), NO-OUTDOOR, DFS, AUTO-BW
(5490 - 5590 @ 80), (N/A, 30), (0 ms), DFS, AUTO-BW
(5590 - 5650 @ 40), (N/A, 30), (600000 ms), DFS, AUTO-BW
(5650 - 5730 @ 80), (N/A, 30), (0 ms), DFS, AUTO-BW
(5735 - 5875 @ 80), (N/A, 14), (N/A), AUTO-BW

After hibernation:
% iw reg get
[...]
phy#0 (self-managed)
country na: DFS-UNSET
(2402 - 2472 @ 40), (N/A, 20), (N/A)
(2457 - 2482 @ 20), (N/A, 20), (N/A), PASSIVE-SCAN
(5170 - 5330 @ 160), (N/A, 20), (N/A), AUTO-BW, PASSIVE-SCAN
(5490 - 5730 @ 160), (N/A, 20), (N/A), AUTO-BW, PASSIVE-SCAN
(5735 - 5895 @ 160), (N/A, 20), (N/A), AUTO-BW, PASSIVE-SCAN
(5945 - 7125 @ 160), (N/A, 30), (N/A), AUTO-BW, PASSIVE-SCAN

The reason is, during resume, firmware is reinitialized but host does
not send current country code to firmware. So default reg rules with
country code set to 'na' is uploaded to host, as shown above.

Fix it by restoring country code to firmware during resume.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30

Fixes: 166a490f59ac ("wifi: ath11k: support hibernation")
Signed-off-by: Baochen Qiang <[email protected]>
---
drivers/net/wireless/ath/ath11k/core.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index 748e3ad2bec3..3772e64d4976 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -1009,6 +1009,16 @@ int ath11k_core_resume(struct ath11k_base *ab)
return -ETIMEDOUT;
}

+ if (ab->hw_params.current_cc_support &&
+ ar->alpha2[0] != 0 && ar->alpha2[1] != 0) {
+ ret = ath11k_reg_set_cc(ar);
+ if (ret) {
+ ath11k_warn(ab, "failed to set country code during resume: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
ret = ath11k_dp_rx_pktlog_start(ab);
if (ret)
ath11k_warn(ab, "failed to start rx pktlog during resume: %d\n",
--
2.25.1


2024-05-20 22:11:45

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH 1/2] wifi: ath11k: refactor setting country code logic

On 5/19/2024 7:41 PM, Baochen Qiang wrote:
> ath11k_wmi_send_set_current_country_cmd() is called in several places
> and all of them are just simply repeating the same logic.
>
> Refactor to make code clean.
>
> Compile tested only.
>
> Signed-off-by: Baochen Qiang <[email protected]>

Acked-by: Jeff Johnson <[email protected]>


2024-05-20 22:11:50

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH 2/2] wifi: ath11k: restore country code during resume

On 5/19/2024 7:41 PM, Baochen Qiang wrote:
> We got report that regdomain is not correct after
> return from hibernation:
>
> Before hibernation:
> % iw reg get
> [...]
> phy#0 (self-managed)
> country CH: DFS-ETSI
> (2402 - 2482 @ 40), (N/A, 20), (N/A)
> (5170 - 5250 @ 80), (N/A, 23), (N/A), NO-OUTDOOR, AUTO-BW
> (5250 - 5330 @ 80), (N/A, 23), (0 ms), NO-OUTDOOR, DFS, AUTO-BW
> (5490 - 5590 @ 80), (N/A, 30), (0 ms), DFS, AUTO-BW
> (5590 - 5650 @ 40), (N/A, 30), (600000 ms), DFS, AUTO-BW
> (5650 - 5730 @ 80), (N/A, 30), (0 ms), DFS, AUTO-BW
> (5735 - 5875 @ 80), (N/A, 14), (N/A), AUTO-BW
>
> After hibernation:
> % iw reg get
> [...]
> phy#0 (self-managed)
> country na: DFS-UNSET
> (2402 - 2472 @ 40), (N/A, 20), (N/A)
> (2457 - 2482 @ 20), (N/A, 20), (N/A), PASSIVE-SCAN
> (5170 - 5330 @ 160), (N/A, 20), (N/A), AUTO-BW, PASSIVE-SCAN
> (5490 - 5730 @ 160), (N/A, 20), (N/A), AUTO-BW, PASSIVE-SCAN
> (5735 - 5895 @ 160), (N/A, 20), (N/A), AUTO-BW, PASSIVE-SCAN
> (5945 - 7125 @ 160), (N/A, 30), (N/A), AUTO-BW, PASSIVE-SCAN
>
> The reason is, during resume, firmware is reinitialized but host does
> not send current country code to firmware. So default reg rules with
> country code set to 'na' is uploaded to host, as shown above.
>
> Fix it by restoring country code to firmware during resume.
>
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30
>
> Fixes: 166a490f59ac ("wifi: ath11k: support hibernation")
> Signed-off-by: Baochen Qiang <[email protected]>

Acked-by: Jeff Johnson <[email protected]>


2024-05-25 08:55:48

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 1/2] wifi: ath11k: refactor setting country code logic

Baochen Qiang <[email protected]> wrote:

> ath11k_wmi_send_set_current_country_cmd() is called in several places
> and all of them are just simply repeating the same logic.
>
> Refactor to make code clean.
>
> Compile tested only.
>
> Signed-off-by: Baochen Qiang <[email protected]>
> Signed-off-by: Kalle Valo <[email protected]>

2 patches applied to ath-next branch of ath.git, thanks.

b363614c0c80 wifi: ath11k: refactor setting country code logic
7f0343b7b871 wifi: ath11k: restore country code during resume

--
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches