e165c09dc47885d51c0fab281836b9c02e28dfba
[librecmc/librecmc.git] /
1 From 91fa00fa69224aae5afb720c5e68b22e4c4f7333 Mon Sep 17 00:00:00 2001
2 From: Aditya Kumar Singh <quic_adisi@quicinc.com>
3 Date: Wed, 1 Mar 2023 16:20:59 +0200
4 Subject: [PATCH] wifi: ath11k: add support to parse new WMI event for 6 GHz
5
6 In order to support different power levels of 6 GHz AP and client,
7 new WMI event for regulatory - WMI_REG_CHAN_LIST_CC_EXT_EVENTID is
8 added in firmware. This event provides new parameters required for
9 6 GHz regulatory rules.
10
11 Add support for parsing 2.4 GHz, 5 GHz and 6 GHz reg rules and other
12 parameters from WMI_REG_CHAN_LIST_CC_EXT_EVENTID.
13
14 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
15 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
16 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1
17
18 Signed-off-by: Lavanya Suresh <quic_lavaks@quicinc.com>
19 Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
20 Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
21 Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
22 Link: https://lore.kernel.org/r/20230110121024.14051-3-quic_adisi@quicinc.com
23 ---
24  drivers/net/wireless/ath/ath11k/reg.c |  37 ++-
25  drivers/net/wireless/ath/ath11k/wmi.c | 418 +++++++++++++++++++++++++-
26  drivers/net/wireless/ath/ath11k/wmi.h | 163 +++++++++-
27  3 files changed, 584 insertions(+), 34 deletions(-)
28
29 --- a/drivers/net/wireless/ath/ath11k/reg.c
30 +++ b/drivers/net/wireless/ath/ath11k/reg.c
31 @@ -613,7 +613,7 @@ ath11k_reg_build_regd(struct ath11k_base
32  {
33         struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL;
34         struct cur_reg_rule *reg_rule;
35 -       u8 i = 0, j = 0;
36 +       u8 i = 0, j = 0, k = 0;
37         u8 num_rules;
38         u16 max_bw;
39         u32 flags;
40 @@ -621,6 +621,12 @@ ath11k_reg_build_regd(struct ath11k_base
41  
42         num_rules = reg_info->num_5ghz_reg_rules + reg_info->num_2ghz_reg_rules;
43  
44 +       /* FIXME: Currently taking reg rules for 6 GHz only from Indoor AP mode list.
45 +        * This can be updated after complete 6 GHz regulatory support is added.
46 +        */
47 +       if (reg_info->is_ext_reg_event)
48 +               num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP];
49 +
50         if (!num_rules)
51                 goto ret;
52  
53 @@ -666,6 +672,14 @@ ath11k_reg_build_regd(struct ath11k_base
54                          * per other BW rule flags we pass from here
55                          */
56                         flags = NL80211_RRF_AUTO_BW;
57 +               } else if (reg_info->is_ext_reg_event &&
58 +                          reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] &&
59 +                          (k < reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP])) {
60 +                       reg_rule = reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP] +
61 +                                  k++;
62 +                       max_bw = min_t(u16, reg_rule->max_bw,
63 +                                      reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP]);
64 +                       flags = NL80211_RRF_AUTO_BW;
65                 } else {
66                         break;
67                 }
68 @@ -693,12 +707,21 @@ ath11k_reg_build_regd(struct ath11k_base
69                         continue;
70                 }
71  
72 -               ath11k_dbg(ab, ATH11K_DBG_REG,
73 -                          "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
74 -                          i + 1, reg_rule->start_freq, reg_rule->end_freq,
75 -                          max_bw, reg_rule->ant_gain, reg_rule->reg_power,
76 -                          tmp_regd->reg_rules[i].dfs_cac_ms,
77 -                          flags);
78 +               if (reg_info->is_ext_reg_event) {
79 +                       ath11k_dbg(ab, ATH11K_DBG_REG,
80 +                                  "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n",
81 +                                  i + 1, reg_rule->start_freq, reg_rule->end_freq,
82 +                                  max_bw, reg_rule->ant_gain, reg_rule->reg_power,
83 +                                  tmp_regd->reg_rules[i].dfs_cac_ms, flags,
84 +                                  reg_rule->psd_flag, reg_rule->psd_eirp);
85 +               } else {
86 +                       ath11k_dbg(ab, ATH11K_DBG_REG,
87 +                                  "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
88 +                                  i + 1, reg_rule->start_freq, reg_rule->end_freq,
89 +                                  max_bw, reg_rule->ant_gain, reg_rule->reg_power,
90 +                                  tmp_regd->reg_rules[i].dfs_cac_ms,
91 +                                  flags);
92 +               }
93         }
94  
95         tmp_regd->n_reg_rules = i;
96 --- a/drivers/net/wireless/ath/ath11k/wmi.c
97 +++ b/drivers/net/wireless/ath/ath11k/wmi.c
98 @@ -105,6 +105,8 @@ static const struct wmi_tlv_policy wmi_t
99                 = { .min_len = sizeof(struct wmi_vdev_stopped_event) },
100         [WMI_TAG_REG_CHAN_LIST_CC_EVENT]
101                 = { .min_len = sizeof(struct wmi_reg_chan_list_cc_event) },
102 +       [WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT]
103 +               = { .min_len = sizeof(struct wmi_reg_chan_list_cc_ext_event) },
104         [WMI_TAG_MGMT_RX_HDR]
105                 = { .min_len = sizeof(struct wmi_mgmt_rx_hdr) },
106         [WMI_TAG_MGMT_TX_COMPL_EVENT]
107 @@ -3974,6 +3976,10 @@ ath11k_wmi_copy_resource_config(struct w
108         wmi_cfg->sched_params = tg_cfg->sched_params;
109         wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count;
110         wmi_cfg->twt_ap_sta_count = tg_cfg->twt_ap_sta_count;
111 +       wmi_cfg->host_service_flags &=
112 +               ~(1 << WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT);
113 +       wmi_cfg->host_service_flags |= (tg_cfg->is_reg_cc_ext_event_supported <<
114 +                                       WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT);
115  }
116  
117  static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
118 @@ -4192,6 +4198,10 @@ int ath11k_wmi_cmd_init(struct ath11k_ba
119  
120         ab->hw_params.hw_ops->wmi_init_config(ab, &config);
121  
122 +       if (test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT,
123 +                    ab->wmi_ab.svc_map))
124 +               config.is_reg_cc_ext_event_supported = 1;
125 +
126         memcpy(&wmi_sc->wlan_resource_config, &config, sizeof(config));
127  
128         init_param.res_cfg = &wmi_sc->wlan_resource_config;
129 @@ -4995,18 +5005,11 @@ static int ath11k_pull_reg_chan_list_upd
130         reg_info->phy_id = chan_list_event_hdr->phy_id;
131         reg_info->ctry_code = chan_list_event_hdr->country_id;
132         reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code;
133 -       if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS)
134 -               reg_info->status_code = REG_SET_CC_STATUS_PASS;
135 -       else if (chan_list_event_hdr->status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND)
136 -               reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND;
137 -       else if (chan_list_event_hdr->status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND)
138 -               reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND;
139 -       else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED)
140 -               reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED;
141 -       else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY)
142 -               reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY;
143 -       else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_FAIL)
144 -               reg_info->status_code = REG_SET_CC_STATUS_FAIL;
145 +
146 +       reg_info->status_code =
147 +               ath11k_wmi_cc_setting_code_to_reg(chan_list_event_hdr->status_code);
148 +
149 +       reg_info->is_ext_reg_event = false;
150  
151         reg_info->min_bw_2ghz = chan_list_event_hdr->min_bw_2ghz;
152         reg_info->max_bw_2ghz = chan_list_event_hdr->max_bw_2ghz;
153 @@ -5060,6 +5063,372 @@ static int ath11k_pull_reg_chan_list_upd
154         return 0;
155  }
156  
157 +static struct cur_reg_rule
158 +*create_ext_reg_rules_from_wmi(u32 num_reg_rules,
159 +                              struct wmi_regulatory_ext_rule *wmi_reg_rule)
160 +{
161 +       struct cur_reg_rule *reg_rule_ptr;
162 +       u32 count;
163 +
164 +       reg_rule_ptr =  kcalloc(num_reg_rules, sizeof(*reg_rule_ptr), GFP_ATOMIC);
165 +
166 +       if (!reg_rule_ptr)
167 +               return NULL;
168 +
169 +       for (count = 0; count < num_reg_rules; count++) {
170 +               reg_rule_ptr[count].start_freq =
171 +                       u32_get_bits(wmi_reg_rule[count].freq_info,
172 +                                    REG_RULE_START_FREQ);
173 +               reg_rule_ptr[count].end_freq =
174 +                       u32_get_bits(wmi_reg_rule[count].freq_info,
175 +                                    REG_RULE_END_FREQ);
176 +               reg_rule_ptr[count].max_bw =
177 +                       u32_get_bits(wmi_reg_rule[count].bw_pwr_info,
178 +                                    REG_RULE_MAX_BW);
179 +               reg_rule_ptr[count].reg_power =
180 +                       u32_get_bits(wmi_reg_rule[count].bw_pwr_info,
181 +                                    REG_RULE_REG_PWR);
182 +               reg_rule_ptr[count].ant_gain =
183 +                       u32_get_bits(wmi_reg_rule[count].bw_pwr_info,
184 +                                    REG_RULE_ANT_GAIN);
185 +               reg_rule_ptr[count].flags =
186 +                       u32_get_bits(wmi_reg_rule[count].flag_info,
187 +                                    REG_RULE_FLAGS);
188 +               reg_rule_ptr[count].psd_flag =
189 +                       u32_get_bits(wmi_reg_rule[count].psd_power_info,
190 +                                    REG_RULE_PSD_INFO);
191 +               reg_rule_ptr[count].psd_eirp =
192 +                       u32_get_bits(wmi_reg_rule[count].psd_power_info,
193 +                                    REG_RULE_PSD_EIRP);
194 +       }
195 +
196 +       return reg_rule_ptr;
197 +}
198 +
199 +static u8
200 +ath11k_invalid_5ghz_reg_ext_rules_from_wmi(u32 num_reg_rules,
201 +                                          const struct wmi_regulatory_ext_rule *rule)
202 +{
203 +       u8 num_invalid_5ghz_rules = 0;
204 +       u32 count, start_freq;
205 +
206 +       for (count = 0; count < num_reg_rules; count++) {
207 +               start_freq = u32_get_bits(rule[count].freq_info,
208 +                                         REG_RULE_START_FREQ);
209 +
210 +               if (start_freq >= ATH11K_MIN_6G_FREQ)
211 +                       num_invalid_5ghz_rules++;
212 +       }
213 +
214 +       return num_invalid_5ghz_rules;
215 +}
216 +
217 +static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab,
218 +                                                  struct sk_buff *skb,
219 +                                                  struct cur_regulatory_info *reg_info)
220 +{
221 +       const void **tb;
222 +       const struct wmi_reg_chan_list_cc_ext_event *ext_chan_list_event_hdr;
223 +       struct wmi_regulatory_ext_rule *ext_wmi_reg_rule;
224 +       u32 num_2ghz_reg_rules, num_5ghz_reg_rules;
225 +       u32 num_6ghz_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE];
226 +       u32 num_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
227 +       u32 total_reg_rules = 0;
228 +       int ret, i, j, num_invalid_5ghz_ext_rules = 0;
229 +
230 +       ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory ext channel list\n");
231 +
232 +       tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
233 +       if (IS_ERR(tb)) {
234 +               ret = PTR_ERR(tb);
235 +               ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
236 +               return ret;
237 +       }
238 +
239 +       ext_chan_list_event_hdr = tb[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT];
240 +       if (!ext_chan_list_event_hdr) {
241 +               ath11k_warn(ab, "failed to fetch reg chan list ext update ev\n");
242 +               kfree(tb);
243 +               return -EPROTO;
244 +       }
245 +
246 +       reg_info->num_2ghz_reg_rules =
247 +                       ext_chan_list_event_hdr->num_2ghz_reg_rules;
248 +       reg_info->num_5ghz_reg_rules =
249 +                       ext_chan_list_event_hdr->num_5ghz_reg_rules;
250 +       reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] =
251 +                       ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_lpi;
252 +       reg_info->num_6ghz_rules_ap[WMI_REG_STANDARD_POWER_AP] =
253 +                       ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_sp;
254 +       reg_info->num_6ghz_rules_ap[WMI_REG_VERY_LOW_POWER_AP] =
255 +                       ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_vlp;
256 +
257 +       for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
258 +               reg_info->num_6ghz_rules_client[WMI_REG_INDOOR_AP][i] =
259 +                       ext_chan_list_event_hdr->num_6ghz_reg_rules_client_lpi[i];
260 +               reg_info->num_6ghz_rules_client[WMI_REG_STANDARD_POWER_AP][i] =
261 +                       ext_chan_list_event_hdr->num_6ghz_reg_rules_client_sp[i];
262 +               reg_info->num_6ghz_rules_client[WMI_REG_VERY_LOW_POWER_AP][i] =
263 +                       ext_chan_list_event_hdr->num_6ghz_reg_rules_client_vlp[i];
264 +       }
265 +
266 +       num_2ghz_reg_rules = reg_info->num_2ghz_reg_rules;
267 +       num_5ghz_reg_rules = reg_info->num_5ghz_reg_rules;
268 +
269 +       total_reg_rules += num_2ghz_reg_rules;
270 +       total_reg_rules += num_5ghz_reg_rules;
271 +
272 +       if ((num_2ghz_reg_rules > MAX_REG_RULES) ||
273 +           (num_5ghz_reg_rules > MAX_REG_RULES)) {
274 +               ath11k_warn(ab, "Num reg rules for 2.4 GHz/5 GHz exceeds max limit (num_2ghz_reg_rules: %d num_5ghz_reg_rules: %d max_rules: %d)\n",
275 +                           num_2ghz_reg_rules, num_5ghz_reg_rules, MAX_REG_RULES);
276 +               kfree(tb);
277 +               return -EINVAL;
278 +       }
279 +
280 +       for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) {
281 +               num_6ghz_reg_rules_ap[i] = reg_info->num_6ghz_rules_ap[i];
282 +
283 +               if (num_6ghz_reg_rules_ap[i] > MAX_6GHZ_REG_RULES) {
284 +                       ath11k_warn(ab, "Num 6 GHz reg rules for AP mode(%d) exceeds max limit (num_6ghz_reg_rules_ap: %d, max_rules: %d)\n",
285 +                                   i, num_6ghz_reg_rules_ap[i], MAX_6GHZ_REG_RULES);
286 +                       kfree(tb);
287 +                       return -EINVAL;
288 +               }
289 +
290 +               total_reg_rules += num_6ghz_reg_rules_ap[i];
291 +       }
292 +
293 +       for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
294 +               num_6ghz_client[WMI_REG_INDOOR_AP][i] =
295 +                       reg_info->num_6ghz_rules_client[WMI_REG_INDOOR_AP][i];
296 +               total_reg_rules += num_6ghz_client[WMI_REG_INDOOR_AP][i];
297 +
298 +               num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] =
299 +                       reg_info->num_6ghz_rules_client[WMI_REG_STANDARD_POWER_AP][i];
300 +               total_reg_rules += num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i];
301 +
302 +               num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] =
303 +                       reg_info->num_6ghz_rules_client[WMI_REG_VERY_LOW_POWER_AP][i];
304 +               total_reg_rules += num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i];
305 +
306 +               if ((num_6ghz_client[WMI_REG_INDOOR_AP][i] > MAX_6GHZ_REG_RULES) ||
307 +                   (num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] >
308 +                                                            MAX_6GHZ_REG_RULES) ||
309 +                   (num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] >
310 +                                                            MAX_6GHZ_REG_RULES)) {
311 +                       ath11k_warn(ab,
312 +                                   "Num 6 GHz client reg rules exceeds max limit, for client(type: %d)\n",
313 +                                   i);
314 +                       kfree(tb);
315 +                       return -EINVAL;
316 +               }
317 +       }
318 +
319 +       if (!total_reg_rules) {
320 +               ath11k_warn(ab, "No reg rules available\n");
321 +               kfree(tb);
322 +               return -EINVAL;
323 +       }
324 +
325 +       memcpy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2,
326 +              REG_ALPHA2_LEN);
327 +
328 +       reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region;
329 +       reg_info->phybitmap = ext_chan_list_event_hdr->phybitmap;
330 +       reg_info->num_phy = ext_chan_list_event_hdr->num_phy;
331 +       reg_info->phy_id = ext_chan_list_event_hdr->phy_id;
332 +       reg_info->ctry_code = ext_chan_list_event_hdr->country_id;
333 +       reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code;
334 +
335 +       reg_info->status_code =
336 +               ath11k_wmi_cc_setting_code_to_reg(ext_chan_list_event_hdr->status_code);
337 +
338 +       reg_info->is_ext_reg_event = true;
339 +
340 +       reg_info->min_bw_2ghz = ext_chan_list_event_hdr->min_bw_2ghz;
341 +       reg_info->max_bw_2ghz = ext_chan_list_event_hdr->max_bw_2ghz;
342 +       reg_info->min_bw_5ghz = ext_chan_list_event_hdr->min_bw_5ghz;
343 +       reg_info->max_bw_5ghz = ext_chan_list_event_hdr->max_bw_5ghz;
344 +
345 +       reg_info->min_bw_6ghz_ap[WMI_REG_INDOOR_AP] =
346 +                       ext_chan_list_event_hdr->min_bw_6ghz_ap_lpi;
347 +       reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP] =
348 +                        ext_chan_list_event_hdr->max_bw_6ghz_ap_lpi;
349 +       reg_info->min_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] =
350 +                       ext_chan_list_event_hdr->min_bw_6ghz_ap_sp;
351 +       reg_info->max_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] =
352 +                       ext_chan_list_event_hdr->max_bw_6ghz_ap_sp;
353 +       reg_info->min_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] =
354 +                       ext_chan_list_event_hdr->min_bw_6ghz_ap_vlp;
355 +       reg_info->max_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] =
356 +                       ext_chan_list_event_hdr->max_bw_6ghz_ap_vlp;
357 +
358 +       for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
359 +               reg_info->min_bw_6ghz_client[WMI_REG_INDOOR_AP][i] =
360 +                               ext_chan_list_event_hdr->min_bw_6ghz_client_lpi[i];
361 +               reg_info->max_bw_6ghz_client[WMI_REG_INDOOR_AP][i] =
362 +                               ext_chan_list_event_hdr->max_bw_6ghz_client_lpi[i];
363 +               reg_info->min_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] =
364 +                               ext_chan_list_event_hdr->min_bw_6ghz_client_sp[i];
365 +               reg_info->max_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] =
366 +                               ext_chan_list_event_hdr->max_bw_6ghz_client_sp[i];
367 +               reg_info->min_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] =
368 +                               ext_chan_list_event_hdr->min_bw_6ghz_client_vlp[i];
369 +               reg_info->max_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] =
370 +                               ext_chan_list_event_hdr->max_bw_6ghz_client_vlp[i];
371 +       }
372 +
373 +       ath11k_dbg(ab, ATH11K_DBG_WMI,
374 +                  "%s:cc_ext %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d",
375 +                  __func__, reg_info->alpha2, reg_info->dfs_region,
376 +                  reg_info->min_bw_2ghz, reg_info->max_bw_2ghz,
377 +                  reg_info->min_bw_5ghz, reg_info->max_bw_5ghz);
378 +
379 +       ath11k_dbg(ab, ATH11K_DBG_WMI,
380 +                  "num_2ghz_reg_rules %d num_5ghz_reg_rules %d",
381 +                  num_2ghz_reg_rules, num_5ghz_reg_rules);
382 +
383 +       ath11k_dbg(ab, ATH11K_DBG_WMI,
384 +                  "num_6ghz_reg_rules_ap_lpi: %d num_6ghz_reg_rules_ap_sp: %d num_6ghz_reg_rules_ap_vlp: %d",
385 +                  num_6ghz_reg_rules_ap[WMI_REG_INDOOR_AP],
386 +                  num_6ghz_reg_rules_ap[WMI_REG_STANDARD_POWER_AP],
387 +                  num_6ghz_reg_rules_ap[WMI_REG_VERY_LOW_POWER_AP]);
388 +
389 +       j = WMI_REG_DEFAULT_CLIENT;
390 +       ath11k_dbg(ab, ATH11K_DBG_WMI,
391 +                  "6 GHz Regular client: num_6ghz_reg_rules_lpi: %d num_6ghz_reg_rules_sp: %d num_6ghz_reg_rules_vlp: %d",
392 +                  num_6ghz_client[WMI_REG_INDOOR_AP][j],
393 +                  num_6ghz_client[WMI_REG_STANDARD_POWER_AP][j],
394 +                  num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][j]);
395 +
396 +       j = WMI_REG_SUBORDINATE_CLIENT;
397 +       ath11k_dbg(ab, ATH11K_DBG_WMI,
398 +                  "6 GHz Subordinate client: num_6ghz_reg_rules_lpi: %d num_6ghz_reg_rules_sp: %d num_6ghz_reg_rules_vlp: %d",
399 +                  num_6ghz_client[WMI_REG_INDOOR_AP][j],
400 +                  num_6ghz_client[WMI_REG_STANDARD_POWER_AP][j],
401 +                  num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][j]);
402 +
403 +       ext_wmi_reg_rule =
404 +               (struct wmi_regulatory_ext_rule *)((u8 *)ext_chan_list_event_hdr
405 +                                                  + sizeof(*ext_chan_list_event_hdr)
406 +                                                  + sizeof(struct wmi_tlv));
407 +       if (num_2ghz_reg_rules) {
408 +               reg_info->reg_rules_2ghz_ptr =
409 +                       create_ext_reg_rules_from_wmi(num_2ghz_reg_rules,
410 +                                                     ext_wmi_reg_rule);
411 +
412 +               if (!reg_info->reg_rules_2ghz_ptr) {
413 +                       kfree(tb);
414 +                       ath11k_warn(ab, "Unable to Allocate memory for 2 GHz rules\n");
415 +                       return -ENOMEM;
416 +               }
417 +       }
418 +
419 +       ext_wmi_reg_rule += num_2ghz_reg_rules;
420 +
421 +       /* Firmware might include 6 GHz reg rule in 5 GHz rule list
422 +        * for few countries along with separate 6 GHz rule.
423 +        * Having same 6 GHz reg rule in 5 GHz and 6 GHz rules list
424 +        * causes intersect check to be true, and same rules will be
425 +        * shown multiple times in iw cmd.
426 +        * Hence, avoid parsing 6 GHz rule from 5 GHz reg rule list
427 +        */
428 +       num_invalid_5ghz_ext_rules =
429 +               ath11k_invalid_5ghz_reg_ext_rules_from_wmi(num_5ghz_reg_rules,
430 +                                                          ext_wmi_reg_rule);
431 +
432 +       if (num_invalid_5ghz_ext_rules) {
433 +               ath11k_dbg(ab, ATH11K_DBG_WMI,
434 +                          "CC: %s 5 GHz reg rules number %d from fw, %d number of invalid 5 GHz rules",
435 +                          reg_info->alpha2, reg_info->num_5ghz_reg_rules,
436 +                          num_invalid_5ghz_ext_rules);
437 +
438 +               num_5ghz_reg_rules = num_5ghz_reg_rules - num_invalid_5ghz_ext_rules;
439 +               reg_info->num_5ghz_reg_rules = num_5ghz_reg_rules;
440 +       }
441 +
442 +       if (num_5ghz_reg_rules) {
443 +               reg_info->reg_rules_5ghz_ptr =
444 +                       create_ext_reg_rules_from_wmi(num_5ghz_reg_rules,
445 +                                                     ext_wmi_reg_rule);
446 +
447 +               if (!reg_info->reg_rules_5ghz_ptr) {
448 +                       kfree(tb);
449 +                       ath11k_warn(ab, "Unable to Allocate memory for 5 GHz rules\n");
450 +                       return -ENOMEM;
451 +               }
452 +       }
453 +
454 +       /* We have adjusted the number of 5 GHz reg rules above. But still those
455 +        * many rules needs to be adjusted in ext_wmi_reg_rule.
456 +        *
457 +        * NOTE: num_invalid_5ghz_ext_rules will be 0 for rest other cases.
458 +        */
459 +       ext_wmi_reg_rule += (num_5ghz_reg_rules + num_invalid_5ghz_ext_rules);
460 +
461 +       for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) {
462 +               reg_info->reg_rules_6ghz_ap_ptr[i] =
463 +                       create_ext_reg_rules_from_wmi(num_6ghz_reg_rules_ap[i],
464 +                                                     ext_wmi_reg_rule);
465 +
466 +               if (!reg_info->reg_rules_6ghz_ap_ptr[i]) {
467 +                       kfree(tb);
468 +                       ath11k_warn(ab, "Unable to Allocate memory for 6 GHz AP rules\n");
469 +                       return -ENOMEM;
470 +               }
471 +
472 +               ext_wmi_reg_rule += num_6ghz_reg_rules_ap[i];
473 +       }
474 +
475 +       for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++) {
476 +               for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
477 +                       reg_info->reg_rules_6ghz_client_ptr[j][i] =
478 +                               create_ext_reg_rules_from_wmi(num_6ghz_client[j][i],
479 +                                                             ext_wmi_reg_rule);
480 +
481 +                       if (!reg_info->reg_rules_6ghz_client_ptr[j][i]) {
482 +                               kfree(tb);
483 +                               ath11k_warn(ab, "Unable to Allocate memory for 6 GHz client rules\n");
484 +                               return -ENOMEM;
485 +                       }
486 +
487 +                       ext_wmi_reg_rule += num_6ghz_client[j][i];
488 +               }
489 +       }
490 +
491 +       reg_info->client_type = ext_chan_list_event_hdr->client_type;
492 +       reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable;
493 +       reg_info->unspecified_ap_usable =
494 +                       ext_chan_list_event_hdr->unspecified_ap_usable;
495 +       reg_info->domain_code_6ghz_ap[WMI_REG_INDOOR_AP] =
496 +                       ext_chan_list_event_hdr->domain_code_6ghz_ap_lpi;
497 +       reg_info->domain_code_6ghz_ap[WMI_REG_STANDARD_POWER_AP] =
498 +                       ext_chan_list_event_hdr->domain_code_6ghz_ap_sp;
499 +       reg_info->domain_code_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] =
500 +                       ext_chan_list_event_hdr->domain_code_6ghz_ap_vlp;
501 +
502 +       for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
503 +               reg_info->domain_code_6ghz_client[WMI_REG_INDOOR_AP][i] =
504 +                               ext_chan_list_event_hdr->domain_code_6ghz_client_lpi[i];
505 +               reg_info->domain_code_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] =
506 +                               ext_chan_list_event_hdr->domain_code_6ghz_client_sp[i];
507 +               reg_info->domain_code_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] =
508 +                               ext_chan_list_event_hdr->domain_code_6ghz_client_vlp[i];
509 +       }
510 +
511 +       reg_info->domain_code_6ghz_super_id =
512 +                       ext_chan_list_event_hdr->domain_code_6ghz_super_id;
513 +
514 +       ath11k_dbg(ab, ATH11K_DBG_WMI, "6 GHz client_type: %d domain_code_6ghz_super_id: %d",
515 +                  reg_info->client_type, reg_info->domain_code_6ghz_super_id);
516 +
517 +       ath11k_dbg(ab, ATH11K_DBG_WMI, "processed regulatory ext channel list\n");
518 +
519 +       kfree(tb);
520 +       return 0;
521 +}
522 +
523  static int ath11k_pull_peer_del_resp_ev(struct ath11k_base *ab, struct sk_buff *skb,
524                                         struct wmi_peer_delete_resp_event *peer_del_resp)
525  {
526 @@ -6507,12 +6876,14 @@ static bool ath11k_reg_is_world_alpha(ch
527         return false;
528  }
529  
530 -static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *skb)
531 +static int ath11k_reg_chan_list_event(struct ath11k_base *ab,
532 +                                     struct sk_buff *skb,
533 +                                     enum wmi_reg_chan_list_cmd_type id)
534  {
535         struct cur_regulatory_info *reg_info = NULL;
536         struct ieee80211_regdomain *regd = NULL;
537         bool intersect = false;
538 -       int ret = 0, pdev_idx;
539 +       int ret = 0, pdev_idx, i, j;
540         struct ath11k *ar;
541  
542         reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC);
543 @@ -6521,7 +6892,11 @@ static int ath11k_reg_chan_list_event(st
544                 goto fallback;
545         }
546  
547 -       ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info);
548 +       if (id == WMI_REG_CHAN_LIST_CC_ID)
549 +               ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info);
550 +       else
551 +               ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, reg_info);
552 +
553         if (ret) {
554                 ath11k_warn(ab, "failed to extract regulatory info from received event\n");
555                 goto fallback;
556 @@ -6623,6 +6998,14 @@ mem_free:
557         if (reg_info) {
558                 kfree(reg_info->reg_rules_2ghz_ptr);
559                 kfree(reg_info->reg_rules_5ghz_ptr);
560 +               if (reg_info->is_ext_reg_event) {
561 +                       for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++)
562 +                               kfree(reg_info->reg_rules_6ghz_ap_ptr[i]);
563 +
564 +                       for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++)
565 +                               for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++)
566 +                                       kfree(reg_info->reg_rules_6ghz_client_ptr[j][i]);
567 +               }
568                 kfree(reg_info);
569         }
570         return ret;
571 @@ -8054,7 +8437,10 @@ static void ath11k_wmi_tlv_op_rx(struct
572                 ath11k_service_ready_ext2_event(ab, skb);
573                 break;
574         case WMI_REG_CHAN_LIST_CC_EVENTID:
575 -               ath11k_reg_chan_list_event(ab, skb);
576 +               ath11k_reg_chan_list_event(ab, skb, WMI_REG_CHAN_LIST_CC_ID);
577 +               break;
578 +       case WMI_REG_CHAN_LIST_CC_EXT_EVENTID:
579 +               ath11k_reg_chan_list_event(ab, skb, WMI_REG_CHAN_LIST_CC_EXT_ID);
580                 break;
581         case WMI_READY_EVENTID:
582                 ath11k_ready_event(ab, skb);
583 --- a/drivers/net/wireless/ath/ath11k/wmi.h
584 +++ b/drivers/net/wireless/ath/ath11k/wmi.h
585 @@ -797,6 +797,7 @@ enum wmi_tlv_event_id {
586         WMI_RMC_NEW_LEADER_EVENTID = WMI_TLV_CMD(WMI_GRP_RMC),
587         WMI_REG_CHAN_LIST_CC_EVENTID = WMI_TLV_CMD(WMI_GRP_REGULATORY),
588         WMI_11D_NEW_COUNTRY_EVENTID,
589 +       WMI_REG_CHAN_LIST_CC_EXT_EVENTID,
590         WMI_NDI_CAP_RSP_EVENTID = WMI_TLV_CMD(WMI_GRP_PROTOTYPE),
591         WMI_NDP_INITIATOR_RSP_EVENTID,
592         WMI_NDP_RESPONDER_RSP_EVENTID,
593 @@ -1865,6 +1866,8 @@ enum wmi_tlv_tag {
594         WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD,
595         WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD,
596         WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD,
597 +       WMI_TAG_REGULATORY_RULE_EXT_STRUCT = 0x3A9,
598 +       WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT,
599         WMI_TAG_PDEV_SET_BIOS_SAR_TABLE_CMD = 0x3D8,
600         WMI_TAG_PDEV_SET_BIOS_GEO_TABLE_CMD,
601         WMI_TAG_MAX
602 @@ -2097,6 +2100,7 @@ enum wmi_tlv_service {
603  
604         /* The second 128 bits */
605         WMI_MAX_EXT_SERVICE = 256,
606 +       WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281,
607         WMI_TLV_SERVICE_BIOS_SAR_SUPPORT = 326,
608  
609         /* The third 128 bits */
610 @@ -2313,6 +2317,8 @@ struct wmi_init_cmd {
611  #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
612  #define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18)
613  
614 +#define WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT 4
615 +
616  struct wmi_resource_config {
617         u32 tlv_header;
618         u32 num_vdevs;
619 @@ -2372,6 +2378,15 @@ struct wmi_resource_config {
620         u32 sched_params;
621         u32 twt_ap_pdev_count;
622         u32 twt_ap_sta_count;
623 +       u32 max_nlo_ssids;
624 +       u32 num_pkt_filters;
625 +       u32 num_max_sta_vdevs;
626 +       u32 max_bssid_indicator;
627 +       u32 ul_resp_config;
628 +       u32 msdu_flow_override_config0;
629 +       u32 msdu_flow_override_config1;
630 +       u32 flags2;
631 +       u32 host_service_flags;
632  } __packed;
633  
634  struct wmi_service_ready_event {
635 @@ -2854,6 +2869,8 @@ struct rx_reorder_queue_remove_params {
636  #define REG_RULE_MAX_BW                                0x0000ffff
637  #define REG_RULE_REG_PWR                       0x00ff0000
638  #define REG_RULE_ANT_GAIN                      0xff000000
639 +#define REG_RULE_PSD_INFO                      BIT(0)
640 +#define REG_RULE_PSD_EIRP                      0xff0000
641  
642  #define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0)
643  #define WMI_VDEV_PARAM_TXBF_MU_TX_BFEE BIT(1)
644 @@ -4049,6 +4066,7 @@ struct wmi_he_rate_set {
645  
646  #define MAX_REG_RULES 10
647  #define REG_ALPHA2_LEN 2
648 +#define MAX_6GHZ_REG_RULES 5
649  
650  enum wmi_start_event_param {
651         WMI_VDEV_START_RESP_EVENT = 0,
652 @@ -4079,16 +4097,6 @@ enum wmi_vdev_start_resp_status_code {
653         WMI_VDEV_START_RESPONSE_INVALID_REGDOMAIN = 4,
654  };
655  
656 -;
657 -enum cc_setting_code {
658 -       REG_SET_CC_STATUS_PASS = 0,
659 -       REG_CURRENT_ALPHA2_NOT_FOUND = 1,
660 -       REG_INIT_ALPHA2_NOT_FOUND = 2,
661 -       REG_SET_CC_CHANGE_NOT_ALLOWED = 3,
662 -       REG_SET_CC_STATUS_NO_MEMORY = 4,
663 -       REG_SET_CC_STATUS_FAIL = 5,
664 -};
665 -
666  /* Regaulatory Rule Flags Passed by FW */
667  #define REGULATORY_CHAN_DISABLED     BIT(0)
668  #define REGULATORY_CHAN_NO_IR        BIT(1)
669 @@ -4102,13 +4110,72 @@ enum cc_setting_code {
670  #define REGULATORY_CHAN_NO_20MHZ     BIT(11)
671  #define REGULATORY_CHAN_NO_10MHZ     BIT(12)
672  
673 -enum {
674 +enum wmi_reg_chan_list_cmd_type {
675 +       WMI_REG_CHAN_LIST_CC_ID = 0,
676 +       WMI_REG_CHAN_LIST_CC_EXT_ID = 1,
677 +};
678 +
679 +enum wmi_reg_cc_setting_code {
680         WMI_REG_SET_CC_STATUS_PASS = 0,
681         WMI_REG_CURRENT_ALPHA2_NOT_FOUND = 1,
682         WMI_REG_INIT_ALPHA2_NOT_FOUND = 2,
683         WMI_REG_SET_CC_CHANGE_NOT_ALLOWED = 3,
684         WMI_REG_SET_CC_STATUS_NO_MEMORY = 4,
685         WMI_REG_SET_CC_STATUS_FAIL = 5,
686 +
687 +       /* add new setting code above, update in
688 +        * @enum cc_setting_code as well.
689 +        * Also handle it in ath11k_wmi_cc_setting_code_to_reg()
690 +        */
691 +};
692 +
693 +enum cc_setting_code {
694 +       REG_SET_CC_STATUS_PASS = 0,
695 +       REG_CURRENT_ALPHA2_NOT_FOUND = 1,
696 +       REG_INIT_ALPHA2_NOT_FOUND = 2,
697 +       REG_SET_CC_CHANGE_NOT_ALLOWED = 3,
698 +       REG_SET_CC_STATUS_NO_MEMORY = 4,
699 +       REG_SET_CC_STATUS_FAIL = 5,
700 +
701 +       /* add new setting code above, update in
702 +        * @enum wmi_reg_cc_setting_code as well.
703 +        */
704 +};
705 +
706 +static inline enum cc_setting_code
707 +ath11k_wmi_cc_setting_code_to_reg(enum wmi_reg_cc_setting_code status_code)
708 +{
709 +       switch (status_code) {
710 +       case WMI_REG_SET_CC_STATUS_PASS:
711 +               return REG_SET_CC_STATUS_PASS;
712 +       case WMI_REG_CURRENT_ALPHA2_NOT_FOUND:
713 +               return REG_CURRENT_ALPHA2_NOT_FOUND;
714 +       case WMI_REG_INIT_ALPHA2_NOT_FOUND:
715 +               return REG_INIT_ALPHA2_NOT_FOUND;
716 +       case WMI_REG_SET_CC_CHANGE_NOT_ALLOWED:
717 +               return REG_SET_CC_CHANGE_NOT_ALLOWED;
718 +       case WMI_REG_SET_CC_STATUS_NO_MEMORY:
719 +               return REG_SET_CC_STATUS_NO_MEMORY;
720 +       case WMI_REG_SET_CC_STATUS_FAIL:
721 +               return REG_SET_CC_STATUS_FAIL;
722 +       }
723 +
724 +       return REG_SET_CC_STATUS_FAIL;
725 +}
726 +
727 +enum wmi_reg_6ghz_ap_type {
728 +       WMI_REG_INDOOR_AP = 0,
729 +       WMI_REG_STANDARD_POWER_AP = 1,
730 +       WMI_REG_VERY_LOW_POWER_AP = 2,
731 +
732 +       WMI_REG_CURRENT_MAX_AP_TYPE,
733 +       WMI_REG_MAX_AP_TYPE = 7,
734 +};
735 +
736 +enum wmi_reg_6ghz_client_type {
737 +       WMI_REG_DEFAULT_CLIENT = 0,
738 +       WMI_REG_SUBORDINATE_CLIENT = 1,
739 +       WMI_REG_MAX_CLIENT_TYPE = 2,
740  };
741  
742  struct cur_reg_rule {
743 @@ -4118,6 +4185,8 @@ struct cur_reg_rule {
744         u8 reg_power;
745         u8 ant_gain;
746         u16 flags;
747 +       bool psd_flag;
748 +       s8 psd_eirp;
749  };
750  
751  struct cur_regulatory_info {
752 @@ -4137,6 +4206,22 @@ struct cur_regulatory_info {
753         u32 num_5ghz_reg_rules;
754         struct cur_reg_rule *reg_rules_2ghz_ptr;
755         struct cur_reg_rule *reg_rules_5ghz_ptr;
756 +       bool is_ext_reg_event;
757 +       enum wmi_reg_6ghz_client_type client_type;
758 +       bool rnr_tpe_usable;
759 +       bool unspecified_ap_usable;
760 +       u8 domain_code_6ghz_ap[WMI_REG_CURRENT_MAX_AP_TYPE];
761 +       u8 domain_code_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
762 +       u32 domain_code_6ghz_super_id;
763 +       u32 min_bw_6ghz_ap[WMI_REG_CURRENT_MAX_AP_TYPE];
764 +       u32 max_bw_6ghz_ap[WMI_REG_CURRENT_MAX_AP_TYPE];
765 +       u32 min_bw_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
766 +       u32 max_bw_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
767 +       u32 num_6ghz_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE];
768 +       u32 num_6ghz_rules_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
769 +       struct cur_reg_rule *reg_rules_6ghz_ap_ptr[WMI_REG_CURRENT_MAX_AP_TYPE];
770 +       struct cur_reg_rule *reg_rules_6ghz_client_ptr
771 +               [WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
772  };
773  
774  struct wmi_reg_chan_list_cc_event {
775 @@ -4163,6 +4248,61 @@ struct wmi_regulatory_rule_struct {
776         u32  flag_info;
777  };
778  
779 +#define WMI_REG_CLIENT_MAX 4
780 +
781 +struct wmi_reg_chan_list_cc_ext_event {
782 +       u32 status_code;
783 +       u32 phy_id;
784 +       u32 alpha2;
785 +       u32 num_phy;
786 +       u32 country_id;
787 +       u32 domain_code;
788 +       u32 dfs_region;
789 +       u32 phybitmap;
790 +       u32 min_bw_2ghz;
791 +       u32 max_bw_2ghz;
792 +       u32 min_bw_5ghz;
793 +       u32 max_bw_5ghz;
794 +       u32 num_2ghz_reg_rules;
795 +       u32 num_5ghz_reg_rules;
796 +       u32 client_type;
797 +       u32 rnr_tpe_usable;
798 +       u32 unspecified_ap_usable;
799 +       u32 domain_code_6ghz_ap_lpi;
800 +       u32 domain_code_6ghz_ap_sp;
801 +       u32 domain_code_6ghz_ap_vlp;
802 +       u32 domain_code_6ghz_client_lpi[WMI_REG_CLIENT_MAX];
803 +       u32 domain_code_6ghz_client_sp[WMI_REG_CLIENT_MAX];
804 +       u32 domain_code_6ghz_client_vlp[WMI_REG_CLIENT_MAX];
805 +       u32 domain_code_6ghz_super_id;
806 +       u32 min_bw_6ghz_ap_sp;
807 +       u32 max_bw_6ghz_ap_sp;
808 +       u32 min_bw_6ghz_ap_lpi;
809 +       u32 max_bw_6ghz_ap_lpi;
810 +       u32 min_bw_6ghz_ap_vlp;
811 +       u32 max_bw_6ghz_ap_vlp;
812 +       u32 min_bw_6ghz_client_sp[WMI_REG_CLIENT_MAX];
813 +       u32 max_bw_6ghz_client_sp[WMI_REG_CLIENT_MAX];
814 +       u32 min_bw_6ghz_client_lpi[WMI_REG_CLIENT_MAX];
815 +       u32 max_bw_6ghz_client_lpi[WMI_REG_CLIENT_MAX];
816 +       u32 min_bw_6ghz_client_vlp[WMI_REG_CLIENT_MAX];
817 +       u32 max_bw_6ghz_client_vlp[WMI_REG_CLIENT_MAX];
818 +       u32 num_6ghz_reg_rules_ap_sp;
819 +       u32 num_6ghz_reg_rules_ap_lpi;
820 +       u32 num_6ghz_reg_rules_ap_vlp;
821 +       u32 num_6ghz_reg_rules_client_sp[WMI_REG_CLIENT_MAX];
822 +       u32 num_6ghz_reg_rules_client_lpi[WMI_REG_CLIENT_MAX];
823 +       u32 num_6ghz_reg_rules_client_vlp[WMI_REG_CLIENT_MAX];
824 +} __packed;
825 +
826 +struct wmi_regulatory_ext_rule {
827 +       u32 tlv_header;
828 +       u32 freq_info;
829 +       u32 bw_pwr_info;
830 +       u32 flag_info;
831 +       u32 psd_power_info;
832 +} __packed;
833 +
834  struct wmi_vdev_delete_resp_event {
835         u32 vdev_id;
836  } __packed;
837 @@ -5358,6 +5498,7 @@ struct target_resource_config {
838         u32 sched_params;
839         u32 twt_ap_pdev_count;
840         u32 twt_ap_sta_count;
841 +       u8 is_reg_cc_ext_event_supported;
842  };
843  
844  enum wmi_debug_log_param {