From: Baochen Qiang Date: Fri, 18 Apr 2025 02:55:39 +0000 (+0800) Subject: wifi: ath12k: store reg info for later use X-Git-Tag: v6.16-rc1~132^2~46^2~1^2~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eaa027a1d83f87c83f0b4138ca2427875a21b446;p=thirdparty%2Flinux.git wifi: ath12k: store reg info for later use Currently we only build regdomain when channel list event is received. That event is received when driver boots or when a new country code is sent to firmware. At either time we may have no information about interface mode or AP's power type, consequently WMI_REG_INDOOR_AP is selected. In upcoming patches we will rebuild regdomain once those information is available. For that purpose reg info has to be stored/refreshed each time a new channel list event is received. The stored reg info would be freed in ath12k_reg_free() when it is not needed. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20250418-ath12k-6g-lp-vlp-v1-6-c869c86cad60@quicinc.com Signed-off-by: Jeff Johnson --- diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index fff3d1f81d5d7..695fab249eba1 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1066,6 +1066,8 @@ struct ath12k_base { */ struct ieee80211_regdomain *new_regd[MAX_RADIOS]; + struct ath12k_reg_info *reg_info[MAX_RADIOS]; + /* Current DFS Regulatory */ enum ath12k_dfs_region dfs_region; struct ath12k_soc_dp_stats soc_stats; diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c index e3ad475328526..dbd7d956dd52a 100644 --- a/drivers/net/wireless/ath/ath12k/reg.c +++ b/drivers/net/wireless/ath/ath12k/reg.c @@ -1040,6 +1040,12 @@ void ath12k_reg_free(struct ath12k_base *ab) int i; mutex_lock(&ab->core_lock); + for (i = 0; i < MAX_RADIOS; i++) { + ath12k_reg_reset_reg_info(ab->reg_info[i]); + kfree(ab->reg_info[i]); + ab->reg_info[i] = NULL; + } + for (i = 0; i < ab->hw_params->max_radios; i++) { kfree(ab->default_regd[i]); kfree(ab->new_regd[i]); diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 42e275762563f..80b8cad5bc78c 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -6118,6 +6118,7 @@ static void ath12k_wmi_htc_tx_complete(struct ath12k_base *ab, static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *skb) { struct ath12k_reg_info *reg_info; + u8 pdev_idx; int ret; reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); @@ -6147,6 +6148,17 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk goto mem_free; } + /* free old reg_info if it exist */ + pdev_idx = reg_info->phy_id; + if (ab->reg_info[pdev_idx]) { + ath12k_reg_reset_reg_info(ab->reg_info[pdev_idx]); + kfree(ab->reg_info[pdev_idx]); + } + /* reg_info is valid, we store it for later use + * even below regd build failed + */ + ab->reg_info[pdev_idx] = reg_info; + ret = ath12k_reg_handle_chan_list(ab, reg_info, WMI_VDEV_TYPE_UNSPEC, IEEE80211_REG_UNSET_AP); if (ret) {