* [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery
@ 2024-10-17 3:09 Kang Yang
2024-10-17 3:09 ` [PATCH v6 1/4] wifi: ath12k: add configure country code for WCN7850 Kang Yang
` (5 more replies)
0 siblings, 6 replies; 19+ messages in thread
From: Kang Yang @ 2024-10-17 3:09 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, quic_kangyang
This patch-set mainly does four things:
1. Add handler to send WMI_SET_CURRENT_COUNTRY_CMDID to firmware.
2. Implement 11d scan offload, and report country code to firmware by
WMI command WMI_SET_CURRENT_COUNTRY_CMDID.
3. Use WMI_SET_CURRENT_COUNTRY_CMDID to set country code for WCN7850.
4. Store country code, and update it to firmware after device recovery.
With this patch-set, WCN7850 can do 11d offload scan and update country
code to firmware successfully.
Note: This patch-set is an old patch-set in public review written by
Wen Gong. Just resend it for him.
Link: https://patchwork.kernel.org/project/linux-wireless/cover/20230914090746.23560-1-quic_wgong@quicinc.com/
v6: rebase on tag: ath/main(ath-202410161539).
v5: rebase on tag: ath/main(ath-202410111606).
v4: rebase on tag: ath-202410072115.
v3:
1. use wiphy::mtx lock instead of adding a new lock(patch#2).
2. rename struct according to wmi naming convention(patch#1, #2).
3. update copyright in reg.h
4. modifiy patch#3, #4 due to struct name change.
v2: change per Jeff.
1. change alpha2 length from 3 to 2.
2. change wmi_11d_new_cc_ev to wmi_11d_new_cc_event.
Wen Gong (4):
wifi: ath12k: add configure country code for WCN7850
wifi: ath12k: add 11d scan offload support
wifi: ath12k: use correct WMI command to set country code for WCN7850
wifi: ath12k: store and send country code to firmware after recovery
drivers/net/wireless/ath/ath12k/core.c | 34 ++++-
drivers/net/wireless/ath/ath12k/core.h | 17 +++
drivers/net/wireless/ath/ath12k/hw.c | 6 +
drivers/net/wireless/ath/ath12k/hw.h | 1 +
drivers/net/wireless/ath/ath12k/mac.c | 168 ++++++++++++++++++++++++-
drivers/net/wireless/ath/ath12k/mac.h | 7 ++
drivers/net/wireless/ath/ath12k/reg.c | 70 ++++++++---
drivers/net/wireless/ath/ath12k/reg.h | 4 +-
drivers/net/wireless/ath/ath12k/wmi.c | 158 ++++++++++++++++++++++-
drivers/net/wireless/ath/ath12k/wmi.h | 38 ++++++
10 files changed, 481 insertions(+), 22 deletions(-)
base-commit: fa934bf3e0a825ee09f035c6580af513187d59a2
--
2.34.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v6 1/4] wifi: ath12k: add configure country code for WCN7850
2024-10-17 3:09 [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
@ 2024-10-17 3:09 ` Kang Yang
2024-10-17 3:09 ` [PATCH v6 2/4] wifi: ath12k: add 11d scan offload support Kang Yang
` (4 subsequent siblings)
5 siblings, 0 replies; 19+ messages in thread
From: Kang Yang @ 2024-10-17 3:09 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, quic_kangyang
From: Wen Gong <quic_wgong@quicinc.com>
Add handler to send WMI_SET_CURRENT_COUNTRY_CMDID to firmware, which
is used for WCN7850 to update country code.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
---
drivers/net/wireless/ath/ath12k/wmi.c | 36 +++++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/wmi.h | 13 ++++++++++
2 files changed, 49 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index dced2aa9ba1a..28f0428fb172 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -3084,6 +3084,42 @@ int ath12k_wmi_send_init_country_cmd(struct ath12k *ar,
return ret;
}
+int ath12k_wmi_send_set_current_country_cmd(struct ath12k *ar,
+ struct wmi_set_current_country_arg *arg)
+{
+ struct ath12k_wmi_pdev *wmi = ar->wmi;
+ struct wmi_set_current_country_cmd *cmd;
+ struct sk_buff *skb;
+ int ret;
+
+ skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_set_current_country_cmd *)skb->data;
+ cmd->tlv_header =
+ ath12k_wmi_tlv_cmd_hdr(WMI_TAG_SET_CURRENT_COUNTRY_CMD,
+ sizeof(*cmd));
+
+ cmd->pdev_id = cpu_to_le32(ar->pdev->pdev_id);
+ memcpy(&cmd->new_alpha2, &arg->alpha2, sizeof(arg->alpha2));
+ ret = ath12k_wmi_cmd_send(wmi, skb, WMI_SET_CURRENT_COUNTRY_CMDID);
+
+ ath12k_dbg(ar->ab, ATH12K_DBG_WMI,
+ "set current country pdev id %d alpha2 %c%c\n",
+ ar->pdev->pdev_id,
+ arg->alpha2[0],
+ arg->alpha2[1]);
+
+ if (ret) {
+ ath12k_warn(ar->ab,
+ "failed to send WMI_SET_CURRENT_COUNTRY_CMDID: %d\n", ret);
+ dev_kfree_skb(skb);
+ }
+
+ return ret;
+}
+
int
ath12k_wmi_send_twt_enable_cmd(struct ath12k *ar, u32 pdev_id)
{
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index 6f55dbdf629d..220f530da569 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -3945,6 +3945,16 @@ struct ath12k_wmi_eht_rate_set_params {
#define MAX_6G_REG_RULES 5
#define REG_US_5G_NUM_REG_RULES 4
+struct wmi_set_current_country_arg {
+ u8 alpha2[REG_ALPHA2_LEN];
+};
+
+struct wmi_set_current_country_cmd {
+ __le32 tlv_header;
+ __le32 pdev_id;
+ __le32 new_alpha2;
+} __packed;
+
enum wmi_start_event_param {
WMI_VDEV_START_RESP_EVENT = 0,
WMI_VDEV_RESTART_RESP_EVENT,
@@ -5547,6 +5557,9 @@ int ath12k_wmi_send_bcn_offload_control_cmd(struct ath12k *ar,
u32 vdev_id, u32 bcn_ctrl_op);
int ath12k_wmi_send_init_country_cmd(struct ath12k *ar,
struct ath12k_wmi_init_country_arg *arg);
+int
+ath12k_wmi_send_set_current_country_cmd(struct ath12k *ar,
+ struct wmi_set_current_country_arg *arg);
int ath12k_wmi_peer_rx_reorder_queue_setup(struct ath12k *ar,
int vdev_id, const u8 *addr,
dma_addr_t paddr, u8 tid,
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v6 2/4] wifi: ath12k: add 11d scan offload support
2024-10-17 3:09 [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
2024-10-17 3:09 ` [PATCH v6 1/4] wifi: ath12k: add configure country code for WCN7850 Kang Yang
@ 2024-10-17 3:09 ` Kang Yang
2024-10-17 3:09 ` [PATCH v6 3/4] wifi: ath12k: use correct WMI command to set country code for WCN7850 Kang Yang
` (3 subsequent siblings)
5 siblings, 0 replies; 19+ messages in thread
From: Kang Yang @ 2024-10-17 3:09 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, quic_kangyang
From: Wen Gong <quic_wgong@quicinc.com>
Add process of event WMI_11D_NEW_COUNTRY_EVENTID. Add handler for
WMI_11D_SCAN_START_CMDID, WMI_11D_SCAN_STOP_CMDID.
Use WMI_11D_SCAN_START_CMDID to trigger 11d scan then firmware will
report 11d scan result by WMI_11D_NEW_COUNTRY_EVENTID. Host will
update the new country code back to firmware.
The priority of 11d scan is WMI_SCAN_PRIORITY_MEDIUM in firmware, the
priority of hw scan is WMI_SCAN_PRIORITY_LOW. Then hw scan will be
canceled when 11d scan is running.
To avoid this, need to change the priority of first hw scan to
WMI_SCAN_PRIORITY_MEDIUM. Add wait_for_completion_timeout() for
scan.complete in ath12k_reg_update_chan_list(). Plus another existing
wait in ath12k_scan_stop(), there are two places to wait the
scan.complete. They run in different threads so it is possible that both
of the enter into wait status. Therefore use complete_all() instead of
complete() for scan.complete. complete_all() can work well when it is
only one thread wait for scan.complete.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
---
drivers/net/wireless/ath/ath12k/core.c | 33 ++++-
drivers/net/wireless/ath/ath12k/core.h | 16 +++
drivers/net/wireless/ath/ath12k/mac.c | 160 ++++++++++++++++++++++++-
drivers/net/wireless/ath/ath12k/mac.h | 7 ++
drivers/net/wireless/ath/ath12k/reg.c | 40 ++++++-
drivers/net/wireless/ath/ath12k/reg.h | 4 +-
drivers/net/wireless/ath/ath12k/wmi.c | 122 ++++++++++++++++++-
drivers/net/wireless/ath/ath12k/wmi.h | 25 ++++
8 files changed, 397 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index c57322221e1d..0a6b089ae050 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -1014,6 +1014,7 @@ void ath12k_core_halt(struct ath12k *ar)
cancel_delayed_work_sync(&ar->scan.timeout);
cancel_work_sync(&ar->regd_update_work);
cancel_work_sync(&ab->rfkill_work);
+ cancel_work_sync(&ab->update_11d_work);
rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
synchronize_rcu();
@@ -1021,6 +1022,33 @@ void ath12k_core_halt(struct ath12k *ar)
idr_init(&ar->txmgmt_idr);
}
+static void ath12k_update_11d(struct work_struct *work)
+{
+ struct ath12k_base *ab = container_of(work, struct ath12k_base, update_11d_work);
+ struct ath12k *ar;
+ struct ath12k_pdev *pdev;
+ struct wmi_set_current_country_arg arg = {};
+ int ret, i;
+
+ spin_lock_bh(&ab->base_lock);
+ memcpy(&arg.alpha2, &ab->new_alpha2, 2);
+ spin_unlock_bh(&ab->base_lock);
+
+ ath12k_dbg(ab, ATH12K_DBG_WMI, "update 11d new cc %c%c\n",
+ arg.alpha2[0], arg.alpha2[1]);
+
+ for (i = 0; i < ab->num_radios; i++) {
+ pdev = &ab->pdevs[i];
+ ar = pdev->ar;
+
+ ret = ath12k_wmi_send_set_current_country_cmd(ar, &arg);
+ if (ret)
+ ath12k_warn(ar->ab,
+ "pdev id %d failed set current country code: %d\n",
+ i, ret);
+ }
+}
+
static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
{
struct ath12k *ar;
@@ -1045,8 +1073,10 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
ar = &ah->radio[j];
ath12k_mac_drain_tx(ar);
+ ar->state_11d = ATH12K_11D_IDLE;
+ complete(&ar->completed_11d_scan);
complete(&ar->scan.started);
- complete(&ar->scan.completed);
+ complete_all(&ar->scan.completed);
complete(&ar->scan.on_channel);
complete(&ar->peer_assoc_done);
complete(&ar->peer_delete_done);
@@ -1313,6 +1343,7 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
INIT_WORK(&ab->reset_work, ath12k_core_reset);
INIT_WORK(&ab->rfkill_work, ath12k_rfkill_work);
INIT_WORK(&ab->dump_work, ath12k_coredump_upload);
+ INIT_WORK(&ab->update_11d_work, ath12k_update_11d);
timer_setup(&ab->rx_replenish_retry, ath12k_ce_rx_replenish_retry, 0);
init_completion(&ab->htc_suspend);
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 06b637ba8b8f..3d4ab34d50b3 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -200,6 +200,12 @@ enum ath12k_scan_state {
ATH12K_SCAN_ABORTING,
};
+enum ath12k_11d_state {
+ ATH12K_11D_IDLE,
+ ATH12K_11D_PREPARING,
+ ATH12K_11D_RUNNING,
+};
+
enum ath12k_dev_flags {
ATH12K_CAC_RUNNING,
ATH12K_FLAG_CRASH_FLUSH,
@@ -335,6 +341,8 @@ struct ath12k_vif_iter {
#define ATH12K_RX_RATE_TABLE_11AX_NUM 576
#define ATH12K_RX_RATE_TABLE_NUM 320
+#define ATH12K_SCAN_TIMEOUT_HZ (20 * HZ)
+
struct ath12k_rx_peer_rate_stats {
u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1];
u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1];
@@ -676,6 +684,12 @@ struct ath12k {
u32 freq_low;
u32 freq_high;
+ /* Protected by wiphy::mtx lock. */
+ u32 vdev_id_11d_scan;
+ struct completion completed_11d_scan;
+ enum ath12k_11d_state state_11d;
+ bool regdom_set_by_user;
+
bool nlo_enabled;
};
@@ -913,6 +927,8 @@ struct ath12k_base {
/* continuous recovery fail count */
atomic_t fail_cont_count;
unsigned long reset_fail_timeout;
+ struct work_struct update_11d_work;
+ u8 new_alpha2[2];
struct {
/* protected by data_lock */
u32 fw_crash_counter;
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index f5f96a8b1d61..0a71867d2540 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -3016,6 +3016,11 @@ static void ath12k_bss_assoc(struct ath12k *ar,
if (ret)
ath12k_warn(ar->ab, "failed to set vdev %i OBSS PD parameters: %d\n",
arvif->vdev_id, ret);
+
+ if (test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ar->ab->wmi_ab.svc_map) &&
+ ahvif->vdev_type == WMI_VDEV_TYPE_STA &&
+ ahvif->vdev_subtype == WMI_VDEV_SUBTYPE_NONE)
+ ath12k_mac_11d_scan_stop_all(ar->ab);
}
static void ath12k_bss_disassoc(struct ath12k *ar,
@@ -3684,6 +3689,11 @@ static void ath12k_mac_remove_link_interface(struct ieee80211_hw *hw,
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac remove link interface (vdev %d link id %d)",
arvif->vdev_id, arvif->link_id);
+ if (test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ar->ab->wmi_ab.svc_map) &&
+ ahvif->vdev_type == WMI_VDEV_TYPE_STA &&
+ ahvif->vdev_subtype == WMI_VDEV_SUBTYPE_NONE)
+ ath12k_mac_11d_scan_stop(ar);
+
if (ahvif->vdev_type == WMI_VDEV_TYPE_AP) {
ret = ath12k_peer_delete(ar, arvif->vdev_id, arvif->bssid);
if (ret)
@@ -3759,7 +3769,7 @@ void __ath12k_mac_scan_finish(struct ath12k *ar)
ar->scan_channel = NULL;
ar->scan.roc_freq = 0;
cancel_delayed_work(&ar->scan.timeout);
- complete(&ar->scan.completed);
+ complete_all(&ar->scan.completed);
break;
}
}
@@ -4051,7 +4061,12 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
ret = ath12k_start_scan(ar, arg);
if (ret) {
- ath12k_warn(ar->ab, "failed to start hw scan: %d\n", ret);
+ if (ret == -EBUSY)
+ ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
+ "scan engine is busy 11d state %d\n", ar->state_11d);
+ else
+ ath12k_warn(ar->ab, "failed to start hw scan: %d\n", ret);
+
spin_lock_bh(&ar->data_lock);
ar->scan.state = ATH12K_SCAN_IDLE;
spin_unlock_bh(&ar->data_lock);
@@ -4069,6 +4084,11 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
kfree(arg);
}
+ if (ar->state_11d == ATH12K_11D_PREPARING &&
+ ahvif->vdev_type == WMI_VDEV_TYPE_STA &&
+ ahvif->vdev_subtype == WMI_VDEV_SUBTYPE_NONE)
+ ath12k_mac_11d_scan_start(ar, arvif->vdev_id);
+
return ret;
}
@@ -6394,7 +6414,7 @@ static int ath12k_mac_start(struct ath12k *ar)
/* TODO: Do we need to enable ANI? */
- ath12k_reg_update_chan_list(ar);
+ ath12k_reg_update_chan_list(ar, false);
ar->num_started_vdevs = 0;
ar->num_created_vdevs = 0;
@@ -6572,6 +6592,9 @@ static void ath12k_mac_stop(struct ath12k *ar)
cancel_delayed_work_sync(&ar->scan.timeout);
cancel_work_sync(&ar->regd_update_work);
cancel_work_sync(&ar->ab->rfkill_work);
+ cancel_work_sync(&ar->ab->update_11d_work);
+ ar->state_11d = ATH12K_11D_IDLE;
+ complete(&ar->completed_11d_scan);
spin_lock_bh(&ar->data_lock);
list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) {
@@ -6844,6 +6867,118 @@ static void ath12k_mac_op_update_vif_offload(struct ieee80211_hw *hw,
ath12k_mac_update_vif_offload(&ahvif->deflink);
}
+static bool ath12k_mac_vif_ap_active_any(struct ath12k_base *ab)
+{
+ struct ath12k *ar;
+ struct ath12k_pdev *pdev;
+ struct ath12k_link_vif *arvif;
+ int i;
+
+ for (i = 0; i < ab->num_radios; i++) {
+ pdev = &ab->pdevs[i];
+ ar = pdev->ar;
+ list_for_each_entry(arvif, &ar->arvifs, list) {
+ if (arvif->is_up &&
+ arvif->ahvif->vdev_type == WMI_VDEV_TYPE_AP)
+ return true;
+ }
+ }
+ return false;
+}
+
+void ath12k_mac_11d_scan_start(struct ath12k *ar, u32 vdev_id)
+{
+ struct wmi_11d_scan_start_arg arg;
+ int ret;
+
+ lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
+
+ if (ar->regdom_set_by_user)
+ goto fin;
+
+ if (ar->vdev_id_11d_scan != ATH12K_11D_INVALID_VDEV_ID)
+ goto fin;
+
+ if (!test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ar->ab->wmi_ab.svc_map))
+ goto fin;
+
+ if (ath12k_mac_vif_ap_active_any(ar->ab))
+ goto fin;
+
+ arg.vdev_id = vdev_id;
+ arg.start_interval_msec = 0;
+ arg.scan_period_msec = ATH12K_SCAN_11D_INTERVAL;
+
+ ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
+ "mac start 11d scan for vdev %d\n", vdev_id);
+
+ ret = ath12k_wmi_send_11d_scan_start_cmd(ar, &arg);
+ if (ret) {
+ ath12k_warn(ar->ab, "failed to start 11d scan vdev %d ret: %d\n",
+ vdev_id, ret);
+ } else {
+ ar->vdev_id_11d_scan = vdev_id;
+ if (ar->state_11d == ATH12K_11D_PREPARING)
+ ar->state_11d = ATH12K_11D_RUNNING;
+ }
+
+fin:
+ if (ar->state_11d == ATH12K_11D_PREPARING) {
+ ar->state_11d = ATH12K_11D_IDLE;
+ complete(&ar->completed_11d_scan);
+ }
+}
+
+void ath12k_mac_11d_scan_stop(struct ath12k *ar)
+{
+ int ret;
+ u32 vdev_id;
+
+ lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
+
+ if (!test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ar->ab->wmi_ab.svc_map))
+ return;
+
+ ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac stop 11d for vdev %d\n",
+ ar->vdev_id_11d_scan);
+
+ if (ar->state_11d == ATH12K_11D_PREPARING) {
+ ar->state_11d = ATH12K_11D_IDLE;
+ complete(&ar->completed_11d_scan);
+ }
+
+ if (ar->vdev_id_11d_scan != ATH12K_11D_INVALID_VDEV_ID) {
+ vdev_id = ar->vdev_id_11d_scan;
+
+ ret = ath12k_wmi_send_11d_scan_stop_cmd(ar, vdev_id);
+ if (ret) {
+ ath12k_warn(ar->ab,
+ "failed to stopt 11d scan vdev %d ret: %d\n",
+ vdev_id, ret);
+ } else {
+ ar->vdev_id_11d_scan = ATH12K_11D_INVALID_VDEV_ID;
+ ar->state_11d = ATH12K_11D_IDLE;
+ complete(&ar->completed_11d_scan);
+ }
+ }
+}
+
+void ath12k_mac_11d_scan_stop_all(struct ath12k_base *ab)
+{
+ struct ath12k *ar;
+ struct ath12k_pdev *pdev;
+ int i;
+
+ ath12k_dbg(ab, ATH12K_DBG_MAC, "mac stop soc 11d scan\n");
+
+ for (i = 0; i < ab->num_radios; i++) {
+ pdev = &ab->pdevs[i];
+ ar = pdev->ar;
+
+ ath12k_mac_11d_scan_stop(ar);
+ }
+}
+
int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
{
struct ath12k_hw *ah = ar->ah;
@@ -6969,6 +7104,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
arvif->vdev_id, ret);
goto err_peer_del;
}
+ ath12k_mac_11d_scan_stop_all(ar->ab);
break;
case WMI_VDEV_TYPE_STA:
param_id = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
@@ -7007,6 +7143,13 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
arvif->vdev_id, ret);
goto err_peer_del;
}
+
+ if (test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ab->wmi_ab.svc_map) &&
+ ahvif->vdev_type == WMI_VDEV_TYPE_STA &&
+ ahvif->vdev_subtype == WMI_VDEV_SUBTYPE_NONE) {
+ reinit_completion(&ar->completed_11d_scan);
+ ar->state_11d = ATH12K_11D_PREPARING;
+ }
break;
default:
break;
@@ -8231,6 +8374,14 @@ ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
ar->num_started_vdevs == 1 && ar->monitor_vdev_created)
ath12k_mac_monitor_stop(ar);
+ if (test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ab->wmi_ab.svc_map) &&
+ ahvif->vdev_type == WMI_VDEV_TYPE_STA &&
+ ahvif->vdev_subtype == WMI_VDEV_SUBTYPE_NONE &&
+ ar->state_11d != ATH12K_11D_PREPARING) {
+ reinit_completion(&ar->completed_11d_scan);
+ ar->state_11d = ATH12K_11D_PREPARING;
+ }
+
ath12k_mac_remove_link_interface(hw, arvif);
ath12k_mac_unassign_link_vif(arvif);
}
@@ -9827,6 +9978,9 @@ static void ath12k_mac_setup(struct ath12k *ar)
INIT_WORK(&ar->wmi_mgmt_tx_work, ath12k_mgmt_over_wmi_tx_work);
skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
+
+ ar->vdev_id_11d_scan = ATH12K_11D_INVALID_VDEV_ID;
+ init_completion(&ar->completed_11d_scan);
}
int ath12k_mac_register(struct ath12k_base *ab)
diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h
index d382337ba649..1505627a415a 100644
--- a/drivers/net/wireless/ath/ath12k/mac.h
+++ b/drivers/net/wireless/ath/ath12k/mac.h
@@ -54,6 +54,13 @@ enum ath12k_supported_bw {
extern const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default;
+#define ATH12K_SCAN_11D_INTERVAL 600000
+#define ATH12K_11D_INVALID_VDEV_ID 0xFFFF
+
+void ath12k_mac_11d_scan_start(struct ath12k *ar, u32 vdev_id);
+void ath12k_mac_11d_scan_stop(struct ath12k *ar);
+void ath12k_mac_11d_scan_stop_all(struct ath12k_base *ab);
+
void ath12k_mac_destroy(struct ath12k_base *ab);
void ath12k_mac_unregister(struct ath12k_base *ab);
int ath12k_mac_register(struct ath12k_base *ab);
diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c
index 439d61f284d8..aecfd55aef59 100644
--- a/drivers/net/wireless/ath/ath12k/reg.c
+++ b/drivers/net/wireless/ath/ath12k/reg.c
@@ -94,10 +94,16 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
if (ret)
ath12k_warn(ar->ab,
"INIT Country code set to fw failed : %d\n", ret);
+
+ wiphy_lock(wiphy);
+ ath12k_mac_11d_scan_stop(ar);
+ wiphy_unlock(wiphy);
+
+ ar->regdom_set_by_user = true;
}
}
-int ath12k_reg_update_chan_list(struct ath12k *ar)
+int ath12k_reg_update_chan_list(struct ath12k *ar, bool wait)
{
struct ieee80211_supported_band **bands;
struct ath12k_wmi_scan_chan_list_arg *arg;
@@ -106,7 +112,35 @@ int ath12k_reg_update_chan_list(struct ath12k *ar)
struct ath12k_wmi_channel_arg *ch;
enum nl80211_band band;
int num_channels = 0;
- int i, ret;
+ int i, ret, left;
+
+ if (wait && ar->state_11d != ATH12K_11D_IDLE) {
+ left = wait_for_completion_timeout(&ar->completed_11d_scan,
+ ATH12K_SCAN_TIMEOUT_HZ);
+ if (!left) {
+ ath12k_dbg(ar->ab, ATH12K_DBG_REG,
+ "failed to receive 11d scan complete: timed out\n");
+ ar->state_11d = ATH12K_11D_IDLE;
+ }
+ ath12k_dbg(ar->ab, ATH12K_DBG_REG,
+ "reg 11d scan wait left time %d\n", left);
+ }
+
+ if (wait &&
+ (ar->scan.state == ATH12K_SCAN_STARTING ||
+ ar->scan.state == ATH12K_SCAN_RUNNING)) {
+ left = wait_for_completion_timeout(&ar->scan.completed,
+ ATH12K_SCAN_TIMEOUT_HZ);
+ if (!left)
+ ath12k_dbg(ar->ab, ATH12K_DBG_REG,
+ "failed to receive hw scan complete: timed out\n");
+
+ ath12k_dbg(ar->ab, ATH12K_DBG_REG,
+ "reg hw scan wait left time %d\n", left);
+ }
+
+ if (ar->ah->state == ATH12K_HW_STATE_RESTARTING)
+ return 0;
bands = hw->wiphy->bands;
for (band = 0; band < NUM_NL80211_BANDS; band++) {
@@ -295,7 +329,7 @@ int ath12k_regd_update(struct ath12k *ar, bool init)
*/
for_each_ar(ah, ar, i) {
ab = ar->ab;
- ret = ath12k_reg_update_chan_list(ar);
+ ret = ath12k_reg_update_chan_list(ar, true);
if (ret)
goto err;
}
diff --git a/drivers/net/wireless/ath/ath12k/reg.h b/drivers/net/wireless/ath/ath12k/reg.h
index 29c7ec3260da..e4ceae46e556 100644
--- a/drivers/net/wireless/ath/ath12k/reg.h
+++ b/drivers/net/wireless/ath/ath12k/reg.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_REG_H
@@ -96,6 +96,6 @@ struct ieee80211_regdomain *ath12k_reg_build_regd(struct ath12k_base *ab,
struct ath12k_reg_info *reg_info,
bool intersect);
int ath12k_regd_update(struct ath12k *ar, bool init);
-int ath12k_reg_update_chan_list(struct ath12k *ar);
+int ath12k_reg_update_chan_list(struct ath12k *ar, bool wait);
#endif
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 28f0428fb172..6937a3ce7f15 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -171,6 +171,8 @@ static const struct ath12k_wmi_tlv_policy ath12k_wmi_tlv_policies[] = {
.min_len = sizeof(struct ath12k_wmi_p2p_noa_info) },
[WMI_TAG_P2P_NOA_EVENT] = {
.min_len = sizeof(struct wmi_p2p_noa_event) },
+ [WMI_TAG_11D_NEW_COUNTRY_EVENT] = {
+ .min_len = sizeof(struct wmi_11d_new_cc_event) },
};
static __le32 ath12k_wmi_tlv_hdr(u32 cmd, u32 len)
@@ -2364,7 +2366,10 @@ int ath12k_wmi_send_scan_start_cmd(struct ath12k *ar,
cmd->scan_id = cpu_to_le32(arg->scan_id);
cmd->scan_req_id = cpu_to_le32(arg->scan_req_id);
cmd->vdev_id = cpu_to_le32(arg->vdev_id);
- cmd->scan_priority = cpu_to_le32(arg->scan_priority);
+ if (ar->state_11d == ATH12K_11D_PREPARING)
+ arg->scan_priority = WMI_SCAN_PRIORITY_MEDIUM;
+ else
+ arg->scan_priority = WMI_SCAN_PRIORITY_LOW;
cmd->notify_scan_events = cpu_to_le32(arg->notify_scan_events);
ath12k_wmi_copy_scan_event_cntrl_flags(cmd, arg);
@@ -3120,6 +3125,74 @@ int ath12k_wmi_send_set_current_country_cmd(struct ath12k *ar,
return ret;
}
+int ath12k_wmi_send_11d_scan_start_cmd(struct ath12k *ar,
+ struct wmi_11d_scan_start_arg *arg)
+{
+ struct ath12k_wmi_pdev *wmi = ar->wmi;
+ struct wmi_11d_scan_start_cmd *cmd;
+ struct sk_buff *skb;
+ int ret;
+
+ skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_11d_scan_start_cmd *)skb->data;
+ cmd->tlv_header =
+ ath12k_wmi_tlv_cmd_hdr(WMI_TAG_11D_SCAN_START_CMD,
+ sizeof(*cmd));
+
+ cmd->vdev_id = cpu_to_le32(arg->vdev_id);
+ cmd->scan_period_msec = cpu_to_le32(arg->scan_period_msec);
+ cmd->start_interval_msec = cpu_to_le32(arg->start_interval_msec);
+ ret = ath12k_wmi_cmd_send(wmi, skb, WMI_11D_SCAN_START_CMDID);
+
+ ath12k_dbg(ar->ab, ATH12K_DBG_WMI,
+ "send 11d scan start vdev id %d period %d ms internal %d ms\n",
+ arg->vdev_id, arg->scan_period_msec,
+ arg->start_interval_msec);
+
+ if (ret) {
+ ath12k_warn(ar->ab,
+ "failed to send WMI_11D_SCAN_START_CMDID: %d\n", ret);
+ dev_kfree_skb(skb);
+ }
+
+ return ret;
+}
+
+int ath12k_wmi_send_11d_scan_stop_cmd(struct ath12k *ar, u32 vdev_id)
+{
+ struct ath12k_wmi_pdev *wmi = ar->wmi;
+ struct wmi_11d_scan_stop_cmd *cmd;
+ struct sk_buff *skb;
+ int ret;
+
+ skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_11d_scan_stop_cmd *)skb->data;
+ cmd->tlv_header =
+ ath12k_wmi_tlv_cmd_hdr(WMI_TAG_11D_SCAN_STOP_CMD,
+ sizeof(*cmd));
+
+ cmd->vdev_id = cpu_to_le32(vdev_id);
+ ret = ath12k_wmi_cmd_send(wmi, skb, WMI_11D_SCAN_STOP_CMDID);
+
+ ath12k_dbg(ar->ab, ATH12K_DBG_WMI,
+ "send 11d scan stop vdev id %d\n",
+ cmd->vdev_id);
+
+ if (ret) {
+ ath12k_warn(ar->ab,
+ "failed to send WMI_11D_SCAN_STOP_CMDID: %d\n", ret);
+ dev_kfree_skb(skb);
+ }
+
+ return ret;
+}
+
int
ath12k_wmi_send_twt_enable_cmd(struct ath12k *ar, u32 pdev_id)
{
@@ -5705,6 +5778,50 @@ static void ath12k_wmi_op_ep_tx_credits(struct ath12k_base *ab)
wake_up(&ab->wmi_ab.tx_credits_wq);
}
+static int ath12k_reg_11d_new_cc_event(struct ath12k_base *ab, struct sk_buff *skb)
+{
+ const struct wmi_11d_new_cc_event *ev;
+ struct ath12k *ar;
+ struct ath12k_pdev *pdev;
+ const void **tb;
+ int ret, i;
+
+ tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ if (IS_ERR(tb)) {
+ ret = PTR_ERR(tb);
+ ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
+ return ret;
+ }
+
+ ev = tb[WMI_TAG_11D_NEW_COUNTRY_EVENT];
+ if (!ev) {
+ kfree(tb);
+ ath12k_warn(ab, "failed to fetch 11d new cc ev");
+ return -EPROTO;
+ }
+
+ spin_lock_bh(&ab->base_lock);
+ memcpy(&ab->new_alpha2, &ev->new_alpha2, REG_ALPHA2_LEN);
+ spin_unlock_bh(&ab->base_lock);
+
+ ath12k_dbg(ab, ATH12K_DBG_WMI, "wmi 11d new cc %c%c\n",
+ ab->new_alpha2[0],
+ ab->new_alpha2[1]);
+
+ kfree(tb);
+
+ for (i = 0; i < ab->num_radios; i++) {
+ pdev = &ab->pdevs[i];
+ ar = pdev->ar;
+ ar->state_11d = ATH12K_11D_IDLE;
+ complete(&ar->completed_11d_scan);
+ }
+
+ queue_work(ab->workqueue, &ab->update_11d_work);
+
+ return 0;
+}
+
static void ath12k_wmi_htc_tx_complete(struct ath12k_base *ab,
struct sk_buff *skb)
{
@@ -7308,6 +7425,9 @@ static void ath12k_wmi_op_rx(struct ath12k_base *ab, struct sk_buff *skb)
case WMI_GTK_OFFLOAD_STATUS_EVENTID:
ath12k_wmi_gtk_offload_status_event(ab, skb);
break;
+ case WMI_11D_NEW_COUNTRY_EVENTID:
+ ath12k_reg_11d_new_cc_event(ab, skb);
+ break;
/* TODO: Add remaining events */
default:
ath12k_dbg(ab, ATH12K_DBG_WMI, "Unknown eventid: 0x%x\n", id);
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index 220f530da569..c4e785a31e04 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -3860,6 +3860,28 @@ struct wmi_init_country_cmd {
} cc_info;
} __packed;
+struct wmi_11d_scan_start_arg {
+ u32 vdev_id;
+ u32 scan_period_msec;
+ u32 start_interval_msec;
+};
+
+struct wmi_11d_scan_start_cmd {
+ __le32 tlv_header;
+ __le32 vdev_id;
+ __le32 scan_period_msec;
+ __le32 start_interval_msec;
+} __packed;
+
+struct wmi_11d_scan_stop_cmd {
+ __le32 tlv_header;
+ __le32 vdev_id;
+} __packed;
+
+struct wmi_11d_new_cc_event {
+ __le32 new_alpha2;
+} __packed;
+
struct wmi_delba_send_cmd {
__le32 tlv_header;
__le32 vdev_id;
@@ -5565,6 +5587,9 @@ int ath12k_wmi_peer_rx_reorder_queue_setup(struct ath12k *ar,
dma_addr_t paddr, u8 tid,
u8 ba_window_size_valid,
u32 ba_window_size);
+int ath12k_wmi_send_11d_scan_start_cmd(struct ath12k *ar,
+ struct wmi_11d_scan_start_arg *arg);
+int ath12k_wmi_send_11d_scan_stop_cmd(struct ath12k *ar, u32 vdev_id);
int
ath12k_wmi_rx_reord_queue_remove(struct ath12k *ar,
struct ath12k_wmi_rx_reorder_queue_remove_arg *arg);
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v6 3/4] wifi: ath12k: use correct WMI command to set country code for WCN7850
2024-10-17 3:09 [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
2024-10-17 3:09 ` [PATCH v6 1/4] wifi: ath12k: add configure country code for WCN7850 Kang Yang
2024-10-17 3:09 ` [PATCH v6 2/4] wifi: ath12k: add 11d scan offload support Kang Yang
@ 2024-10-17 3:09 ` Kang Yang
2024-10-17 3:09 ` [PATCH v6 4/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
` (2 subsequent siblings)
5 siblings, 0 replies; 19+ messages in thread
From: Kang Yang @ 2024-10-17 3:09 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, quic_kangyang
From: Wen Gong <quic_wgong@quicinc.com>
When userspace try to set country code by NL80211_REGDOM_SET_BY_USER
hint(like iw reg set XX), it will pass new country code to ath12k.
Then ath12k will set this new country code to firmware by
WMI_SET_INIT_COUNTRY_CMDID. But for WCN7850, this WMI command won't
take effect.
For AP based chips(QCN92xx), WMI_SET_INIT_COUNTRY_CMDID is the correct
command. However, for STATION based chips(WCN7850), it need to use
WMI_SET_CURRENT_COUNTRY_CMDID.
Add flag current_cc_support in hardware parameters. It is used to
distinguish AP/STA platform. After that, the firmware will work
normal and the regulatory feature works well for WCN7850.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
---
drivers/net/wireless/ath/ath12k/hw.c | 6 ++++++
drivers/net/wireless/ath/ath12k/hw.h | 1 +
drivers/net/wireless/ath/ath12k/reg.c | 29 ++++++++++++++++-----------
3 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c
index b7b583fadb5a..65c52e3217c5 100644
--- a/drivers/net/wireless/ath/ath12k/hw.c
+++ b/drivers/net/wireless/ath/ath12k/hw.c
@@ -928,6 +928,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.iova_mask = 0,
.supports_aspm = false,
+
+ .current_cc_support = false,
},
{
.name = "wcn7850 hw2.0",
@@ -1008,6 +1010,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.iova_mask = ATH12K_PCIE_MAX_PAYLOAD_SIZE - 1,
.supports_aspm = true,
+
+ .current_cc_support = true,
},
{
.name = "qcn9274 hw2.0",
@@ -1084,6 +1088,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.iova_mask = 0,
.supports_aspm = false,
+
+ .current_cc_support = false,
},
};
diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h
index 8d52182e28ae..8067b103e266 100644
--- a/drivers/net/wireless/ath/ath12k/hw.h
+++ b/drivers/net/wireless/ath/ath12k/hw.h
@@ -190,6 +190,7 @@ struct ath12k_hw_params {
bool reoq_lut_support:1;
bool supports_shadow_regs:1;
bool supports_aspm:1;
+ bool current_cc_support:1;
u32 num_tcl_banks;
u32 max_tx_ring;
diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c
index aecfd55aef59..c7b0d66f4874 100644
--- a/drivers/net/wireless/ath/ath12k/reg.c
+++ b/drivers/net/wireless/ath/ath12k/reg.c
@@ -48,6 +48,7 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
{
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct ath12k_wmi_init_country_arg arg;
+ struct wmi_set_current_country_arg current_arg = {};
struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
int ret, i;
@@ -77,23 +78,27 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
return;
}
- /* Set the country code to the firmware and wait for
- * the WMI_REG_CHAN_LIST_CC EVENT for updating the
- * reg info
- */
- arg.flags = ALPHA_IS_SET;
- memcpy(&arg.cc_info.alpha2, request->alpha2, 2);
- arg.cc_info.alpha2[2] = 0;
-
/* Allow fresh updates to wiphy regd */
ah->regd_updated = false;
/* Send the reg change request to all the radios */
for_each_ar(ah, ar, i) {
- ret = ath12k_wmi_send_init_country_cmd(ar, &arg);
- if (ret)
- ath12k_warn(ar->ab,
- "INIT Country code set to fw failed : %d\n", ret);
+ if (ar->ab->hw_params->current_cc_support) {
+ memcpy(¤t_arg.alpha2, request->alpha2, 2);
+ ret = ath12k_wmi_send_set_current_country_cmd(ar, ¤t_arg);
+ if (ret)
+ ath12k_warn(ar->ab,
+ "failed set current country code: %d\n", ret);
+ } else {
+ arg.flags = ALPHA_IS_SET;
+ memcpy(&arg.cc_info.alpha2, request->alpha2, 2);
+ arg.cc_info.alpha2[2] = 0;
+
+ ret = ath12k_wmi_send_init_country_cmd(ar, &arg);
+ if (ret)
+ ath12k_warn(ar->ab,
+ "failed set INIT Country code: %d\n", ret);
+ }
wiphy_lock(wiphy);
ath12k_mac_11d_scan_stop(ar);
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v6 4/4] wifi: ath12k: store and send country code to firmware after recovery
2024-10-17 3:09 [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
` (2 preceding siblings ...)
2024-10-17 3:09 ` [PATCH v6 3/4] wifi: ath12k: use correct WMI command to set country code for WCN7850 Kang Yang
@ 2024-10-17 3:09 ` Kang Yang
2024-10-17 18:55 ` [PATCH v6 0/4] " Jeff Johnson
2024-11-29 12:18 ` Mihai Moldovan
5 siblings, 0 replies; 19+ messages in thread
From: Kang Yang @ 2024-10-17 3:09 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, quic_kangyang
From: Wen Gong <quic_wgong@quicinc.com>
Currently ath12k does not send the country code to firmware after device
recovery. As a result the country code will be the default one which
is reported from firmware. Country code is important, so ath12k also
need to restore it to the value which was used before recovery.
This is only needed for platforms which support the current_cc_support
hardware parameter.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
---
drivers/net/wireless/ath/ath12k/core.c | 1 +
drivers/net/wireless/ath/ath12k/core.h | 1 +
drivers/net/wireless/ath/ath12k/mac.c | 8 ++++++++
drivers/net/wireless/ath/ath12k/reg.c | 1 +
4 files changed, 11 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 0a6b089ae050..47c1ab2f683e 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -1041,6 +1041,7 @@ static void ath12k_update_11d(struct work_struct *work)
pdev = &ab->pdevs[i];
ar = pdev->ar;
+ memcpy(&ar->alpha2, &arg.alpha2, 2);
ret = ath12k_wmi_send_set_current_country_cmd(ar, &arg);
if (ret)
ath12k_warn(ar->ab,
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 3d4ab34d50b3..d24fbf84e3ee 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -688,6 +688,7 @@ struct ath12k {
u32 vdev_id_11d_scan;
struct completion completed_11d_scan;
enum ath12k_11d_state state_11d;
+ u8 alpha2[REG_ALPHA2_LEN];
bool regdom_set_by_user;
bool nlo_enabled;
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 0a71867d2540..f59a30f4c573 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -8927,6 +8927,14 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
ath12k_warn(ar->ab, "pdev %d successfully recovered\n",
ar->pdev->pdev_id);
+ if (ar->ab->hw_params->current_cc_support &&
+ ar->alpha2[0] != 0 && ar->alpha2[1] != 0) {
+ struct wmi_set_current_country_arg arg = {};
+
+ memcpy(&arg.alpha2, ar->alpha2, 2);
+ ath12k_wmi_send_set_current_country_cmd(ar, &arg);
+ }
+
if (ab->is_reset) {
recovery_count = atomic_inc_return(&ab->recovery_count);
diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c
index c7b0d66f4874..c3ebb0247e6f 100644
--- a/drivers/net/wireless/ath/ath12k/reg.c
+++ b/drivers/net/wireless/ath/ath12k/reg.c
@@ -85,6 +85,7 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
for_each_ar(ah, ar, i) {
if (ar->ab->hw_params->current_cc_support) {
memcpy(¤t_arg.alpha2, request->alpha2, 2);
+ memcpy(&ar->alpha2, ¤t_arg.alpha2, 2);
ret = ath12k_wmi_send_set_current_country_cmd(ar, ¤t_arg);
if (ret)
ath12k_warn(ar->ab,
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery
2024-10-17 3:09 [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
` (3 preceding siblings ...)
2024-10-17 3:09 ` [PATCH v6 4/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
@ 2024-10-17 18:55 ` Jeff Johnson
2024-11-20 16:50 ` Mihai Moldovan
2024-11-29 12:18 ` Mihai Moldovan
5 siblings, 1 reply; 19+ messages in thread
From: Jeff Johnson @ 2024-10-17 18:55 UTC (permalink / raw)
To: Kang Yang, ath12k; +Cc: linux-wireless
On 10/16/2024 8:09 PM, Kang Yang wrote:
> This patch-set mainly does four things:
> 1. Add handler to send WMI_SET_CURRENT_COUNTRY_CMDID to firmware.
> 2. Implement 11d scan offload, and report country code to firmware by
> WMI command WMI_SET_CURRENT_COUNTRY_CMDID.
> 3. Use WMI_SET_CURRENT_COUNTRY_CMDID to set country code for WCN7850.
> 4. Store country code, and update it to firmware after device recovery.
>
> With this patch-set, WCN7850 can do 11d offload scan and update country
> code to firmware successfully.
>
> Note: This patch-set is an old patch-set in public review written by
> Wen Gong. Just resend it for him.
> Link: https://patchwork.kernel.org/project/linux-wireless/cover/20230914090746.23560-1-quic_wgong@quicinc.com/
>
> v6: rebase on tag: ath/main(ath-202410161539).
> v5: rebase on tag: ath/main(ath-202410111606).
> v4: rebase on tag: ath-202410072115.
> v3:
> 1. use wiphy::mtx lock instead of adding a new lock(patch#2).
> 2. rename struct according to wmi naming convention(patch#1, #2).
> 3. update copyright in reg.h
> 4. modifiy patch#3, #4 due to struct name change.
> v2: change per Jeff.
> 1. change alpha2 length from 3 to 2.
> 2. change wmi_11d_new_cc_ev to wmi_11d_new_cc_event.
>
> Wen Gong (4):
> wifi: ath12k: add configure country code for WCN7850
> wifi: ath12k: add 11d scan offload support
> wifi: ath12k: use correct WMI command to set country code for WCN7850
> wifi: ath12k: store and send country code to firmware after recovery
>
> drivers/net/wireless/ath/ath12k/core.c | 34 ++++-
> drivers/net/wireless/ath/ath12k/core.h | 17 +++
> drivers/net/wireless/ath/ath12k/hw.c | 6 +
> drivers/net/wireless/ath/ath12k/hw.h | 1 +
> drivers/net/wireless/ath/ath12k/mac.c | 168 ++++++++++++++++++++++++-
> drivers/net/wireless/ath/ath12k/mac.h | 7 ++
> drivers/net/wireless/ath/ath12k/reg.c | 70 ++++++++---
> drivers/net/wireless/ath/ath12k/reg.h | 4 +-
> drivers/net/wireless/ath/ath12k/wmi.c | 158 ++++++++++++++++++++++-
> drivers/net/wireless/ath/ath12k/wmi.h | 38 ++++++
> 10 files changed, 481 insertions(+), 22 deletions(-)
>
>
> base-commit: fa934bf3e0a825ee09f035c6580af513187d59a2
This series looks ok to me, but it conflicts with the MLO branch so I'll defer
this until the MLO branch is merged.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery
2024-10-17 18:55 ` [PATCH v6 0/4] " Jeff Johnson
@ 2024-11-20 16:50 ` Mihai Moldovan
2024-11-21 11:03 ` Kalle Valo
0 siblings, 1 reply; 19+ messages in thread
From: Mihai Moldovan @ 2024-11-20 16:50 UTC (permalink / raw)
To: ath12k
[-- Attachment #1.1: Type: text/plain, Size: 539 bytes --]
* On 10/17/24 20:55, Jeff Johnson wrote:
> This series looks ok to me, but it conflicts with the MLO branch so I'll defer
> this until the MLO branch is merged.
I can understand prioritizing MLO, but would like to point out that without
these changes, AP mode is essentially broken/disabled hard on non-2.4 GHz bands
(and even the 2.4 GHz band is restricted to channels 1 to 11).
If you want to:
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Tested-by: Mihai Moldovan <ionic@ionic.de>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery
2024-11-20 16:50 ` Mihai Moldovan
@ 2024-11-21 11:03 ` Kalle Valo
2024-11-22 20:17 ` Mihai Moldovan
0 siblings, 1 reply; 19+ messages in thread
From: Kalle Valo @ 2024-11-21 11:03 UTC (permalink / raw)
To: Mihai Moldovan; +Cc: ath12k
Mihai Moldovan <ionic@ionic.de> writes:
> * On 10/17/24 20:55, Jeff Johnson wrote:
>> This series looks ok to me, but it conflicts with the MLO branch so I'll defer
>> this until the MLO branch is merged.
>
> I can understand prioritizing MLO, but would like to point out that
> without these changes, AP mode is essentially broken/disabled hard on
> non-2.4 GHz bands (and even the 2.4 GHz band is restricted to channels
> 1 to 11).
But this is not a regression, right? I mean, has it been always broken?
It is very unfortunate MLO is currently taking too much of our time but
we should get that done soon, I hope. But all help (review, testing etc)
is very much appreciated.
--
https://patchwork.kernel.org/project/linux-wireless/list/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery
2024-11-21 11:03 ` Kalle Valo
@ 2024-11-22 20:17 ` Mihai Moldovan
0 siblings, 0 replies; 19+ messages in thread
From: Mihai Moldovan @ 2024-11-22 20:17 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath12k
[-- Attachment #1.1: Type: text/plain, Size: 407 bytes --]
* On 11/21/24 12:03, Kalle Valo wrote:
> But this is not a regression, right? I mean, has it been always broken?
Yeah, true, to the best of my knowledge, running an AP never worked on a non-2.4
GHz band with ath12k since its inception, so it's not a regression.
Just wanted to point that out and offer my testing input that it works with this
patch set for the hardware I tested.
Mihai
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery
2024-10-17 3:09 [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
` (4 preceding siblings ...)
2024-10-17 18:55 ` [PATCH v6 0/4] " Jeff Johnson
@ 2024-11-29 12:18 ` Mihai Moldovan
2024-12-02 1:53 ` Kang Yang
5 siblings, 1 reply; 19+ messages in thread
From: Mihai Moldovan @ 2024-11-29 12:18 UTC (permalink / raw)
To: Kang Yang, ath12k
[-- Attachment #1.1: Type: text/plain, Size: 3469 bytes --]
* On 10/17/24 05:09, Kang Yang wrote:
> This patch-set mainly does four things:
> 1. Add handler to send WMI_SET_CURRENT_COUNTRY_CMDID to firmware.
> 2. Implement 11d scan offload, and report country code to firmware by
> WMI command WMI_SET_CURRENT_COUNTRY_CMDID.
> 3. Use WMI_SET_CURRENT_COUNTRY_CMDID to set country code for WCN7850.
> 4. Store country code, and update it to firmware after device recovery.
>
> With this patch-set, WCN7850 can do 11d offload scan and update country
> code to firmware successfully.
>
> Note: This patch-set is an old patch-set in public review written by
> Wen Gong. Just resend it for him.
> Link: https://patchwork.kernel.org/project/linux-wireless/cover/20230914090746.23560-1-quic_wgong@quicinc.com/
Have you tested this in AP mode or was testing limited to STA mode?
Even with this patch set, hostapd fails to start on a channel that is disabled
in the default regdomain, even if 11d is enabled and a CC specified, even after
a CC update is requested and CHANEL_LIST_UPDATE is being received.
---
1732881245.637059: wifibe: interface state UNINITIALIZED->COUNTRY_UPDATE
1732881245.637268: Previous country code na, new country code DEI
1732881245.637283: Continue interface setup after channel list update
1732881245.637291: ctrl_iface not configured!
1732881245.637318: RTM_NEWLINK: ifi_index=6 ifname=wifibe operstate=0 linkmode=0
ifi_family=0 ifi_flags=0x1043 ([UP][RUNNING])
1732881245.637371: RTM_NEWLINK: ifi_index=6 ifname=wifibe operstate=2 linkmode=0
ifi_family=0 ifi_flags=0x1003 ([UP])
1732881245.637404: RTM_NEWLINK: ifi_index=6 ifname=wifibe operstate=2 linkmode=0
master=5 ifi_family=0 ifi_flags=0x1003 ([UP])
1732881245.637434: RTM_NEWLINK: ifi_index=6 ifname=wifibe operstate=2 linkmode=0
master=5 ifi_family=0 ifi_flags=0x1003 ([UP])
1732881245.637464: RTM_NEWLINK: ifi_index=6 ifname=wifibe master=5 operstate=2
ifi_family=7 ifi_flags=0x1003 ([UP])
1732881245.637505: nl80211: Add ifindex 5 for bridge brvswitch
1732881245.637514: nl80211: Add own interface ifindex 5 (ifidx_reason 6)
1732881245.637521: nl80211: ifindex 5 already in the list
1732881245.637540: nl80211: Event message available
1732881245.637563: nl80211: Drv Event 36 (NL80211_CMD_REG_CHANGE) received for
wifibe
1732881245.637574: nl80211: Regulatory domain change
1732881245.637580: * initiator=1
1732881245.637590: * type=0
1732881245.637595: * alpha2=DE
1732881245.637609: wifibe: Event CHANNEL_LIST_CHANGED (27) received
1732881245.637619: Channel list updated - continue setup
1732881245.638475: nl80211: Regulatory information - country=na
1732881245.638499: nl80211: 2402-2472 @ 40 MHz 20 mBm
1732881245.638512: nl80211: 2457-2482 @ 20 MHz 20 mBm (no IR)
[...]
---
Interestingly, iw reg get shows the new CC/regdomain after hostapd terminates,
so I suspect a race condition:
---
phy#0 (self-managed)
country DE: DFS-ETSI
---
Starting hostapd again after it failed the first time around works, since the CC
+ regdomain are correctly updated by that time.
You recently re-submitted a patch set for ath11k by Wen Gong[0] that is supposed
to fix a race condition during reg updates and this smells like the same issue.
I'll try to port it to ath12k on top of this patch set to see if it fixes this
issue.
Mihai
[0] https://lore.kernel.org/ath11k/20241129070714.226-1-quic_kangyang@quicinc.com
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery
2024-11-29 12:18 ` Mihai Moldovan
@ 2024-12-02 1:53 ` Kang Yang
2024-12-02 8:47 ` Mihai Moldovan
0 siblings, 1 reply; 19+ messages in thread
From: Kang Yang @ 2024-12-02 1:53 UTC (permalink / raw)
To: Mihai Moldovan, ath12k
On 11/29/2024 8:18 PM, Mihai Moldovan wrote:
>
> Have you tested this in AP mode or was testing limited to STA mode?
>
Not yet.
> Even with this patch set, hostapd fails to start on a channel that is
> disabled in the default regdomain, even if 11d is enabled and a CC
> specified, even after a CC update is requested and CHANEL_LIST_UPDATE is
> being received.
>
What is the probability of failure?
> ---
> 1732881245.637059: wifibe: interface state UNINITIALIZED->COUNTRY_UPDATE
>
> 1732881245.637268: Previous country code na, new country code DEI
> 1732881245.637283: Continue interface setup after channel list update
> 1732881245.637291: ctrl_iface not configured!
> 1732881245.637318: RTM_NEWLINK: ifi_index=6 ifname=wifibe operstate=0
> linkmode=0 ifi_family=0 ifi_flags=0x1043 ([UP][RUNNING])
> 1732881245.637371: RTM_NEWLINK: ifi_index=6 ifname=wifibe operstate=2
> linkmode=0 ifi_family=0 ifi_flags=0x1003 ([UP])
> 1732881245.637404: RTM_NEWLINK: ifi_index=6 ifname=wifibe operstate=2
> linkmode=0 master=5 ifi_family=0 ifi_flags=0x1003 ([UP])
> 1732881245.637434: RTM_NEWLINK: ifi_index=6 ifname=wifibe operstate=2
> linkmode=0 master=5 ifi_family=0 ifi_flags=0x1003 ([UP])
> 1732881245.637464: RTM_NEWLINK: ifi_index=6 ifname=wifibe master=5
> operstate=2 ifi_family=7 ifi_flags=0x1003 ([UP])
> 1732881245.637505: nl80211: Add ifindex 5 for bridge brvswitch
> 1732881245.637514: nl80211: Add own interface ifindex 5 (ifidx_reason 6)
> 1732881245.637521: nl80211: ifindex 5 already in the list
> 1732881245.637540: nl80211: Event message available
> 1732881245.637563: nl80211: Drv Event 36 (NL80211_CMD_REG_CHANGE)
> received for wifibe
> 1732881245.637574: nl80211: Regulatory domain change
> 1732881245.637580: * initiator=1
> 1732881245.637590: * type=0
> 1732881245.637595: * alpha2=DE
> 1732881245.637609: wifibe: Event CHANNEL_LIST_CHANGED (27) received
>
> 1732881245.637619: Channel list updated - continue setup
>
> 1732881245.638475: nl80211: Regulatory information - country=na
> 1732881245.638499: nl80211: 2402-2472 @ 40 MHz 20 mBm
> 1732881245.638512: nl80211: 2457-2482 @ 20 MHz 20 mBm (no IR)
> [...]
> ---
>
> Interestingly, iw reg get shows the new CC/regdomain after hostapd
> terminates, so I suspect a race condition:
>
> ---
> phy#0 (self-managed)
> country DE: DFS-ETSI
> ---
>
> Starting hostapd again after it failed the first time around works,
> since the CC + regdomain are correctly updated by that time.
>
>
> You recently re-submitted a patch set for ath11k by Wen Gong[0] that is
> supposed to fix a race condition during reg updates and this smells like
> the same issue. I'll try to port it to ath12k on top of this patch set
> to see if it fixes this issue.
>
>
Thanks for trying, currently, i'm occupied by other tasks...
>
> Mihai
>
>
>
> [0] https://lore.kernel.org/ath11k/20241129070714.226-1-
> quic_kangyang@quicinc.com
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery
2024-12-02 1:53 ` Kang Yang
@ 2024-12-02 8:47 ` Mihai Moldovan
2024-12-09 21:47 ` [RFC] [PATCH] wifi: ath12k: wait for chan update in reg_notifier Mihai Moldovan
2024-12-11 4:32 ` [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
0 siblings, 2 replies; 19+ messages in thread
From: Mihai Moldovan @ 2024-12-02 8:47 UTC (permalink / raw)
To: Kang Yang, ath12k
[-- Attachment #1.1: Type: text/plain, Size: 2574 bytes --]
* On 12/2/24 02:53, Kang Yang wrote:
> On 11/29/2024 8:18 PM, Mihai Moldovan wrote:
>> Have you tested this in AP mode or was testing limited to STA mode?
>
> Not yet.
Okay, so a useful heads-up, I guess!
>> Even with this patch set, hostapd fails to start on a channel that is
>> disabled in the default regdomain, even if 11d is enabled and a CC
>> specified, even after a CC update is requested and CHANEL_LIST_UPDATE is
>> being received.
>>
>
> What is the probability of failure?
In my tests, 100 % reproducible, but I admit I haven't stress-tested it.
It always fails the first time hostapd is started if the default rules define
NO_IR on the channel you want to use (even if CC rules disagree) and can also
easily be reproduced by, e.g., using channel 100 with hostapd and setting CC for
instance to DE or US in the hostapd config file:
# Chinese regulatory does not allow operation on channels 96 to 128.
iw reg set CN; hostapd ... => fails
iw reg set DE; hostapd ... => works
Luckily it's really easy to reproduce.
hostapd is special in the sense that it's using netlink directly and this is
probably very fast.
I was never able to reproduce the issue with iw reg set CN; iw reg set DE; iw
list, but I don't find that surprising due to all the overhead and highly
different code path.
>> You recently re-submitted a patch set for ath11k by Wen Gong[0] that is
>> supposed to fix a race condition during reg updates and this smells like
>> the same issue. I'll try to port it to ath12k on top of this patch set
>> to see if it fixes this issue.
>>
>>
>
> Thanks for trying, currently, i'm occupied by other tasks...
All good.
If and when you try, another heads-up: ath12k is currently running into an rtln
deadlock quite often (but not always) when hostapd is stopped (or fails) because
that's also bringing the interface down.
Fortunately, Baochen Qiang ported the fix for this issue from ath11k to
ath12k[0], but it wasn't applied to ath-next or main yet, so you will likely see
a very irritating deadlock requiring a hard machine reset if you don't also use
his patch when testing.
His patch, apart from fixing the deadlock, also ports some parts of the ath11k
patch set I mentioned in my previous mail, but unfortunately doesn't fix the
chan list update race I'm seeing.
I'll dig further into it and hope to come up with something usable in the next
few days.
Mihai
[0] https://lore.kernel.org/ath12k/20240830023901.204746-1-quic_bqiang@quicinc.com/
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* [RFC] [PATCH] wifi: ath12k: wait for chan update in reg_notifier
2024-12-02 8:47 ` Mihai Moldovan
@ 2024-12-09 21:47 ` Mihai Moldovan
2024-12-09 22:00 ` Ionic
2024-12-10 23:19 ` [RFC] [PATCH v2] " Mihai Moldovan
2024-12-11 4:32 ` [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
1 sibling, 2 replies; 19+ messages in thread
From: Mihai Moldovan @ 2024-12-09 21:47 UTC (permalink / raw)
To: ath12k, Kang Yang
Currently, setting a new regdomain is asynchronous in ath12k, in the
sense that the reg_notifier function does not wait for the actual
regdomain change to complete, including handling the channel list
update.
This causes issues with user space programs like hostapd, which listen
on a netlink socket, set a new country code, see a reg change event and
assume that the reg change actually completed within the driver as well.
Unfortunately, this has almost never been the case in my testing, which
lead to failures when trying to use channels that are disallowed in the
old regdomain, but allowed in the new regdomain.
Easy reproducer:
iw reg set CN
hostapd hostapd.conf # should contain e.g., channel=100 and country_code=DE
=> fails to start
Be nice to user space and wait for ath12k_regd_update to complete prior
to exiting the reg_notifier, which is triggered by receiving the channel
list update event from the FW.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
---
drivers/net/wireless/ath/ath12k/core.c | 2 ++
drivers/net/wireless/ath/ath12k/core.h | 3 +++
drivers/net/wireless/ath/ath12k/mac.c | 3 +++
drivers/net/wireless/ath/ath12k/reg.c | 11 +++++++++++
4 files changed, 19 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 07c6cdd9fcd5..9a226484062f 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -1073,6 +1073,8 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
ieee80211_stop_queues(ah->hw);
+ complete(&ah->completed_regd_update);
+
for (j = 0; j < ah->num_radio; j++) {
ar = &ah->radio[j];
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 0be274f99c99..6507eee32056 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -360,6 +360,7 @@ struct ath12k_vif_iter {
#define ATH12K_RX_RATE_TABLE_NUM 320
#define ATH12K_SCAN_TIMEOUT_HZ (20 * HZ)
+#define ATH12K_REGD_UPDATE_TIMEOUT_HZ (60 * HZ)
struct ath12k_rx_peer_rate_stats {
u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1];
@@ -742,6 +743,8 @@ struct ath12k_hw {
DECLARE_BITMAP(free_ml_peer_id_map, ATH12K_MAX_MLO_PEERS);
+ struct completion completed_regd_update;
+
/* protected by wiphy_lock() */
struct list_head ml_peers;
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 4cbe8dbdcba9..b76135b4b164 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -10649,6 +10649,8 @@ static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
ieee80211_unregister_hw(hw);
+ reinit_completion(&ah->completed_regd_update);
+
for_each_ar(ah, ar, i)
ath12k_mac_cleanup_unregister(ar);
@@ -10861,6 +10863,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_PUNCT);
ath12k_reg_init(hw);
+ init_completion(&ah->completed_regd_update);
if (!is_raw_mode) {
hw->netdev_features = NETIF_F_HW_CSUM;
diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c
index 7d2d887c5dbe..046ad0eadf7e 100644
--- a/drivers/net/wireless/ath/ath12k/reg.c
+++ b/drivers/net/wireless/ath/ath12k/reg.c
@@ -52,6 +52,7 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
int ret, i;
+ unsigned long left = 0;
ath12k_dbg(ar->ab, ATH12K_DBG_REG,
"Regulatory Notification received for %s\n", wiphy_name(wiphy));
@@ -125,6 +126,15 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
ar->regdom_set_by_user = true;
}
+
+ left = wait_for_completion_timeout(&ah->completed_regd_update,
+ ATH12K_REGD_UPDATE_TIMEOUT_HZ);
+ if (!left) {
+ ath12k_dbg(ar->ab, ATH12K_DBG_REG,
+ "failed to receive regd update complete: timed out\n");
+ }
+ ath12k_dbg(ar->ab, ATH12K_DBG_REG,
+ "regd update wait left time %ld\n", left);
}
int ath12k_reg_update_chan_list(struct ath12k *ar, bool wait)
@@ -343,6 +353,7 @@ int ath12k_regd_update(struct ath12k *ar, bool init)
goto skip;
ah->regd_updated = true;
+ complete(&ah->completed_regd_update);
skip:
return 0;
err:
--
2.45.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] wifi: ath12k: wait for chan update in reg_notifier
2024-12-09 21:47 ` [RFC] [PATCH] wifi: ath12k: wait for chan update in reg_notifier Mihai Moldovan
@ 2024-12-09 22:00 ` Ionic
2024-12-11 2:18 ` Kang Yang
2024-12-10 23:19 ` [RFC] [PATCH v2] " Mihai Moldovan
1 sibling, 1 reply; 19+ messages in thread
From: Ionic @ 2024-12-09 22:00 UTC (permalink / raw)
To: ath12k, Kang Yang
* On 12/9/24 22:47, Mihai Moldovan wrote:
> Currently, setting a new regdomain is asynchronous in ath12k, in the
> [...]
Making the reg_notifier synchronous with the actual reg update fixes the issue.
In short, when setting a new reg domain, the reg notifier is called as the last
step by cfg80211 before sending a regdom change event over netlink, but since
the reg_notifier is not waiting for the hardware to apply the new country code
to the firmware and update things like the channel list, things can fail in user
space.
I implemented a regd_update completion in ah and added a wait call in
reg_notifier, as well as completing it in regd_update, with (re-)initializers in
mac_hw_register and mac_hw_unregister.
I'm not quite sure if ah is the correct place for that, but it felt like the
most appropriate. ar is too low-level (since multiple ar can share an ah IIRC)
and it should generally not be possible to set per-ar regdomains, although
per-phy regdomains are possible, but every phy should have an ah (I guess?). Not
sure how vdevs play into this.
Can you please test and review this? If it's already good, feel free to include
it in your series.
ath11k is suffering from the same issue - I just haven't noticed it before
because the default regdomain of the ath11k-based card I use is set to US, which
allows operations on channel 96 to 144. If I set CN first, I can easily
reproduce the same issue with ath11k, so I'll have to backport a good patch to
ath11k as well.
Mihai
^ permalink raw reply [flat|nested] 19+ messages in thread
* [RFC] [PATCH v2] wifi: ath12k: wait for chan update in reg_notifier
2024-12-09 21:47 ` [RFC] [PATCH] wifi: ath12k: wait for chan update in reg_notifier Mihai Moldovan
2024-12-09 22:00 ` Ionic
@ 2024-12-10 23:19 ` Mihai Moldovan
1 sibling, 0 replies; 19+ messages in thread
From: Mihai Moldovan @ 2024-12-10 23:19 UTC (permalink / raw)
To: ath12k, Kang Yang
Currently, setting a new regdomain is asynchronous in ath12k, in the
sense that the reg_notifier function does not wait for the actual
regdomain change to complete, including handling the channel list
update.
This causes issues with user space programs like hostapd, which listen
on a netlink socket, set a new country code, see a reg change event and
assume that the reg change actually completed within the driver as well.
Unfortunately, this has almost never been the case in my testing, which
lead to failures when trying to use channels that are disallowed in the
old regdomain, but allowed in the new regdomain.
Easy reproducer:
iw reg set CN
hostapd hostapd.conf # should contain e.g., channel=100 and country_code=DE
=> fails to start
Be nice to user space and wait for ath12k_regd_update to complete prior
to exiting the reg_notifier, which is triggered by receiving the channel
list update event from the FW.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
---
drivers/net/wireless/ath/ath12k/core.c | 2 ++
drivers/net/wireless/ath/ath12k/core.h | 3 +++
drivers/net/wireless/ath/ath12k/mac.c | 3 +++
drivers/net/wireless/ath/ath12k/reg.c | 13 +++++++++++++
4 files changed, 21 insertions(+)
v2:
- reinitialize completion in reg_notifier, otherwise the wait call
will always time out on subsequent regdom changes
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 07c6cdd9fcd5..9a226484062f 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -1073,6 +1073,8 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
ieee80211_stop_queues(ah->hw);
+ complete(&ah->completed_regd_update);
+
for (j = 0; j < ah->num_radio; j++) {
ar = &ah->radio[j];
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 0be274f99c99..6507eee32056 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -360,6 +360,7 @@ struct ath12k_vif_iter {
#define ATH12K_RX_RATE_TABLE_NUM 320
#define ATH12K_SCAN_TIMEOUT_HZ (20 * HZ)
+#define ATH12K_REGD_UPDATE_TIMEOUT_HZ (60 * HZ)
struct ath12k_rx_peer_rate_stats {
u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1];
@@ -742,6 +743,8 @@ struct ath12k_hw {
DECLARE_BITMAP(free_ml_peer_id_map, ATH12K_MAX_MLO_PEERS);
+ struct completion completed_regd_update;
+
/* protected by wiphy_lock() */
struct list_head ml_peers;
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 4cbe8dbdcba9..b76135b4b164 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -10649,6 +10649,8 @@ static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
ieee80211_unregister_hw(hw);
+ reinit_completion(&ah->completed_regd_update);
+
for_each_ar(ah, ar, i)
ath12k_mac_cleanup_unregister(ar);
@@ -10861,6 +10863,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_PUNCT);
ath12k_reg_init(hw);
+ init_completion(&ah->completed_regd_update);
if (!is_raw_mode) {
hw->netdev_features = NETIF_F_HW_CSUM;
diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c
index 7d2d887c5dbe..00588b53673d 100644
--- a/drivers/net/wireless/ath/ath12k/reg.c
+++ b/drivers/net/wireless/ath/ath12k/reg.c
@@ -52,6 +52,7 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
int ret, i;
+ unsigned long left = 0;
ath12k_dbg(ar->ab, ATH12K_DBG_REG,
"Regulatory Notification received for %s\n", wiphy_name(wiphy));
@@ -99,6 +100,8 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
/* Allow fresh updates to wiphy regd */
ah->regd_updated = false;
+ reinit_completion(&ah->completed_regd_update);
+
/* Send the reg change request to all the radios */
for_each_ar(ah, ar, i) {
if (ar->ab->hw_params->current_cc_support) {
@@ -125,6 +128,15 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
ar->regdom_set_by_user = true;
}
+
+ left = wait_for_completion_timeout(&ah->completed_regd_update,
+ ATH12K_REGD_UPDATE_TIMEOUT_HZ);
+ if (!left) {
+ ath12k_dbg(ar->ab, ATH12K_DBG_REG,
+ "failed to receive regd update complete: timed out\n");
+ }
+ ath12k_dbg(ar->ab, ATH12K_DBG_REG,
+ "regd update wait left time %ld\n", left);
}
int ath12k_reg_update_chan_list(struct ath12k *ar, bool wait)
@@ -343,6 +355,7 @@ int ath12k_regd_update(struct ath12k *ar, bool init)
goto skip;
ah->regd_updated = true;
+ complete(&ah->completed_regd_update);
skip:
return 0;
err:
--
2.45.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] wifi: ath12k: wait for chan update in reg_notifier
2024-12-09 22:00 ` Ionic
@ 2024-12-11 2:18 ` Kang Yang
2024-12-11 16:14 ` Mihai Moldovan
0 siblings, 1 reply; 19+ messages in thread
From: Kang Yang @ 2024-12-11 2:18 UTC (permalink / raw)
To: Ionic, ath12k
On 12/10/2024 6:00 AM, Ionic wrote:
> * On 12/9/24 22:47, Mihai Moldovan wrote:
>> Currently, setting a new regdomain is asynchronous in ath12k, in the
>> [...]
>
> Making the reg_notifier synchronous with the actual reg update fixes the
> issue.
>
> In short, when setting a new reg domain, the reg notifier is called as
> the last step by cfg80211 before sending a regdom change event over
> netlink, but since the reg_notifier is not waiting for the hardware to
> apply the new country code to the firmware and update things like the
> channel list, things can fail in user space.
>
>
> I implemented a regd_update completion in ah and added a wait call in
> reg_notifier, as well as completing it in regd_update, with
> (re-)initializers in mac_hw_register and mac_hw_unregister.
>
> I'm not quite sure if ah is the correct place for that, but it felt like
> the most appropriate.
I think this place is right.
> ar is too low-level (since multiple ar can share
> an ah IIRC) and it should generally not be possible to set per-ar
> regdomains, although per-phy regdomains are possible, but every phy
> should have an ah (I guess?).
If the "phy" you mentioned is one wifi chip, i think you are right.
> Not sure how vdevs play into this.
Each chip at least have one vdev.
>
>
> Can you please test and review this? If it's already good, feel free to
> include it in your series.
I will review and test your "RFC v2"
>
>
> ath11k is suffering from the same issue - I just haven't noticed it
> before because the default regdomain of the ath11k-based card I use is
> set to US, which allows operations on channel 96 to 144. If I set CN
> first, I can easily reproduce the same issue with ath11k, so I'll have
> to backport a good patch to ath11k as well.
>
>
>
> Mihai
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery
2024-12-02 8:47 ` Mihai Moldovan
2024-12-09 21:47 ` [RFC] [PATCH] wifi: ath12k: wait for chan update in reg_notifier Mihai Moldovan
@ 2024-12-11 4:32 ` Kang Yang
2024-12-11 16:22 ` Mihai Moldovan
1 sibling, 1 reply; 19+ messages in thread
From: Kang Yang @ 2024-12-11 4:32 UTC (permalink / raw)
To: Mihai Moldovan, ath12k
On 12/2/2024 4:47 PM, Mihai Moldovan wrote:
> * On 12/2/24 02:53, Kang Yang wrote:
>> On 11/29/2024 8:18 PM, Mihai Moldovan wrote:
>>> Have you tested this in AP mode or was testing limited to STA mode?
>>
>> Not yet.
>
> Okay, so a useful heads-up, I guess!
>
>
>>> Even with this patch set, hostapd fails to start on a channel that is
>>> disabled in the default regdomain, even if 11d is enabled and a CC
>>> specified, even after a CC update is requested and CHANEL_LIST_UPDATE is
>>> being received.
>>>
>>
>> What is the probability of failure?
>
> In my tests, 100 % reproducible, but I admit I haven't stress-tested it.
>
> It always fails the first time hostapd is started if the default rules
> define NO_IR on the channel you want to use (even if CC rules disagree)
> and can also easily be reproduced by, e.g., using channel 100 with
> hostapd and setting CC for instance to DE or US in the hostapd config file:
>
root@NUC8:/home/yk/Desktop/sigma-script# wls1: interface state
UNINITIALIZED->COUNTRY_UPDATE
Frequency 5500 (primary) not allowed for AP mode, flags: 0x100959 RADAR
Primary frequency not allowed
wls1: IEEE 802.11 Configured channel (100) or frequency (5500)
(secondary_channel=0) not found from the channel list of the current
mode (2) IEEE 802.11a
Don't know how you test with channel 100, it's a DFS channel.
Can you show me your whole hostapd.conf?
> # Chinese regulatory does not allow operation on channels 96 to 128.
> iw reg set CN; hostapd ... => fails
> iw reg set DE; hostapd ... => works
>
my steps:
rmmod ath12k
insmod ath12k
iw reg set CN
hostapd...
> Luckily it's really easy to reproduce.
>
>
> hostapd is special in the sense that it's using netlink directly and
> this is probably very fast.
>
> I was never able to reproduce the issue with iw reg set CN; iw reg set
> DE; iw list, but I don't find that surprising due to all the overhead
> and highly different code path.
>
>
>>> You recently re-submitted a patch set for ath11k by Wen Gong[0] that is
>>> supposed to fix a race condition during reg updates and this smells like
>>> the same issue. I'll try to port it to ath12k on top of this patch set
>>> to see if it fixes this issue.
>>>
>>>
>>
>> Thanks for trying, currently, i'm occupied by other tasks...
>
> All good.
>
> If and when you try, another heads-up: ath12k is currently running into
> an rtln deadlock quite often (but not always) when hostapd is stopped
> (or fails) because that's also bringing the interface down.
>
> Fortunately, Baochen Qiang ported the fix for this issue from ath11k to
> ath12k[0], but it wasn't applied to ath-next or main yet, so you will
> likely see a very irritating deadlock requiring a hard machine reset if
> you don't also use his patch when testing.
>
> His patch, apart from fixing the deadlock, also ports some parts of the
> ath11k patch set I mentioned in my previous mail, but unfortunately
> doesn't fix the chan list update race I'm seeing.
>
> I'll dig further into it and hope to come up with something usable in
> the next few days.
>
>
>
> Mihai
>
>
> [0] https://lore.kernel.org/ath12k/20240830023901.204746-1-
> quic_bqiang@quicinc.com/
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] wifi: ath12k: wait for chan update in reg_notifier
2024-12-11 2:18 ` Kang Yang
@ 2024-12-11 16:14 ` Mihai Moldovan
0 siblings, 0 replies; 19+ messages in thread
From: Mihai Moldovan @ 2024-12-11 16:14 UTC (permalink / raw)
To: Kang Yang, ath12k
[-- Attachment #1.1: Type: text/plain, Size: 293 bytes --]
* On 12/11/24 03:18, Kang Yang wrote:
> I will review and test your "RFC v2"
Don't test it yet.
I found out that it's broken when switching between regdoms (running into the
timeout) via:
iw reg set CN
iw reg set DE
...
Will have to fix that first. Wait for v3.
Mihai
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery
2024-12-11 4:32 ` [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
@ 2024-12-11 16:22 ` Mihai Moldovan
0 siblings, 0 replies; 19+ messages in thread
From: Mihai Moldovan @ 2024-12-11 16:22 UTC (permalink / raw)
To: Kang Yang, ath12k
[-- Attachment #1.1: Type: text/plain, Size: 4009 bytes --]
* On 12/11/24 05:32, Kang Yang wrote:
> root@NUC8:/home/yk/Desktop/sigma-script# wls1: interface state
> UNINITIALIZED->COUNTRY_UPDATE
> Frequency 5500 (primary) not allowed for AP mode, flags: 0x100959 RADAR
> Primary frequency not allowed
> wls1: IEEE 802.11 Configured channel (100) or frequency (5500)
> (secondary_channel=0) not found from the channel list of the current
> mode (2) IEEE 802.11a
>
> Don't know how you test with channel 100, it's a DFS channel.
> Can you show me your whole hostapd.conf?
Sure. DFS must be enabled of course - both in the kernel and in hostapd.
Complete hostapd.conf I'm testing with (80 MHz operation on channels 100+):
interface=wifibe
#bridge=brvswitch # Enabling that will likely fail for you out of the box.
driver=nl80211
logger_syslog=-1
logger_syslog_level=0
logger_stdout=-1
logger_stdout_level=2
ctrl_interface=/run/hostapd
ctrl_interface_group=0
ssid=WRTKA04
utf8_ssid=1
country_code=DE
country3=0x49
ieee80211d=1
ieee80211h=1
hw_mode=a
channel=100
acs_num_scans=100
acs_exclude_dfs=0
enable_background_radar=1
min_tx_power=0
beacon_int=100
dtim_period=2
max_num_sta=255
rts_threshold=65535
fragm_threshold=-1
preamble=1
macaddr_acl=1
accept_mac_file=/etc/hostapd/hostapd.accept
deny_mac_file=/etc/hostapd/hostapd.deny
auth_algs=1
ignore_broadcast_ssid=0
wmm_enabled=1
wmm_ac_bk_cwmin=4
wmm_ac_bk_cwmax=10
wmm_ac_bk_aifs=7
wmm_ac_bk_txop_limit=0
wmm_ac_bk_acm=0
wmm_ac_be_aifs=3
wmm_ac_be_cwmin=4
wmm_ac_be_cwmax=10
wmm_ac_be_txop_limit=0
wmm_ac_be_acm=0
wmm_ac_vi_aifs=2
wmm_ac_vi_cwmin=3
wmm_ac_vi_cwmax=4
wmm_ac_vi_txop_limit=94
wmm_ac_vi_acm=0
wmm_ac_vo_aifs=2
wmm_ac_vo_cwmin=2
wmm_ac_vo_cwmax=3
wmm_ac_vo_txop_limit=47
wmm_ac_vo_acm=0
ap_max_inactivity=7200
bss_max_idle=1
disassoc_low_ack=0
start_disabled=0
ieee80211n=1
disable_11n=0
ht_capab=[HT20][HT40+][HT40-][SHORT-GI-20][SHORT-GI-40][TX-STBC][RX-STBC1][LDCP][DSSS_CCK-40][MAX-AMSDU-7935]
require_ht=0
obss_interval=30
ht_vht_twt_responder=1
ieee80211ac=1
disable_11ac=0
vht_capab=[MAX-MPDU-11454][RXLDPC][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP3][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
require_vht=0
vht_oper_chwidth=1
vht_oper_centr_freq_seg0_idx=106
vht_oper_centr_freq_seg1_idx=0
ieee80211ax=1
require_he=0
disable_11ax=0
he_su_beamformer=1
he_su_beamformee=1
he_mu_beamformer=1
he_bss_color=39
he_twt_required=0
he_twt_responder=1
he_er_su_disable=0
he_oper_chwidth=1
he_oper_centr_freq_seg0_idx=106
he_oper_centr_freq_seg1_idx=0
he_6ghz_max_mpdu=2
he_6ghz_max_ampdu_len_exp=7
he_6ghz_rx_ant_pat=1
he_6ghz_tx_ant_pat=1
he_6ghz_reg_pwr_type=4
reg_def_cli_eirp_psd=0
reg_sub_cli_eirp_psd=1
unsol_bcast_probe_resp_interval=0
channel_usage=1
peer_to_peer_twt=1
ieee80211be=1
disable_11be=0
eht_su_beamformer=1
eht_su_beamformee=1
eht_mu_beamformer=0
eht_oper_chwidth=1
eht_oper_centr_freq_seg0_idx=106
eht_default_pe_duration=0
eht_bw320_offset=0
punct_bitmap=0
punct_acs_threshold=0
mld_ap=0
eapol_key_index_workaround=0
own_ip_addr=127.0.0.1
wpa=2
extended_key_id=0
wpa_passphrase=BREAKMEnottheactualpassphraseofc
wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256 SAE
wpa_pairwise=CCMP CCMP-256 GCMP GCMP-256
rsn_pairwise=CCMP CCMP-256 GCMP GCMP-256
ieee80211w=1
group_mgmt_cipher=AES-128-CMAC
beacon_prot=1
ocv=1
sae_require_mfp=1
fils_discovery_min_interval=20
fils_discovery_max_interval=8000
ssid_protection=1
ap_table_max_size=255
ap_table_expiration_time=3600
wps_cred_add_sae=1
multi_ap_profile=2
multi_ap_client_disallow=0
friendly_name=WPS 802.11be Access Point
manufacturer_url=http://www.ionic.de/
model_description=Wireless 802.11be Access Point
wps_rf_bands=a
tdls_prohibit=1
tdls_prohibit_chan_switch=1
mbo=0
mbo_cell_data_conn_pref=1
rssi_ignore_probe_request=0
> my steps:
> rmmod ath12k
> insmod ath12k
> iw reg set CN
> hostapd...
Yep, that should do the trick.
Mihai
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2024-12-11 16:22 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-17 3:09 [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
2024-10-17 3:09 ` [PATCH v6 1/4] wifi: ath12k: add configure country code for WCN7850 Kang Yang
2024-10-17 3:09 ` [PATCH v6 2/4] wifi: ath12k: add 11d scan offload support Kang Yang
2024-10-17 3:09 ` [PATCH v6 3/4] wifi: ath12k: use correct WMI command to set country code for WCN7850 Kang Yang
2024-10-17 3:09 ` [PATCH v6 4/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
2024-10-17 18:55 ` [PATCH v6 0/4] " Jeff Johnson
2024-11-20 16:50 ` Mihai Moldovan
2024-11-21 11:03 ` Kalle Valo
2024-11-22 20:17 ` Mihai Moldovan
2024-11-29 12:18 ` Mihai Moldovan
2024-12-02 1:53 ` Kang Yang
2024-12-02 8:47 ` Mihai Moldovan
2024-12-09 21:47 ` [RFC] [PATCH] wifi: ath12k: wait for chan update in reg_notifier Mihai Moldovan
2024-12-09 22:00 ` Ionic
2024-12-11 2:18 ` Kang Yang
2024-12-11 16:14 ` Mihai Moldovan
2024-12-10 23:19 ` [RFC] [PATCH v2] " Mihai Moldovan
2024-12-11 4:32 ` [PATCH v6 0/4] wifi: ath12k: store and send country code to firmware after recovery Kang Yang
2024-12-11 16:22 ` Mihai Moldovan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox