]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: store reg info for later use
authorBaochen Qiang <quic_bqiang@quicinc.com>
Fri, 18 Apr 2025 02:55:39 +0000 (10:55 +0800)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Fri, 16 May 2025 19:38:53 +0000 (12:38 -0700)
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 <quic_bqiang@quicinc.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250418-ath12k-6g-lp-vlp-v1-6-c869c86cad60@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/core.h
drivers/net/wireless/ath/ath12k/reg.c
drivers/net/wireless/ath/ath12k/wmi.c

index fff3d1f81d5d7a5b3ea94905abcb72b872deaf09..695fab249eba182b90c4b23076b0e713a701f6bd 100644 (file)
@@ -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;
index e3ad475328526cf6e9e5e312c7953f661a1e5e8d..dbd7d956dd52ad91cf1c0bae0a243afd3bd26a61 100644 (file)
@@ -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]);
index 42e275762563f84f4891ffd1be8e33917f1192d2..80b8cad5bc78ca0cf27383e594ea6f48887a1910 100644 (file)
@@ -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) {