1 // SPDX-License-Identifier: BSD-3-Clause-Clear
3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
6 #include <linux/rtnetlink.h>
10 /* World regdom to be used in case default regd from fw is unavailable */
11 #define ATH12K_2GHZ_CH01_11 REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0)
12 #define ATH12K_5GHZ_5150_5350 REG_RULE(5150 - 10, 5350 + 10, 80, 0, 30,\
14 #define ATH12K_5GHZ_5725_5850 REG_RULE(5725 - 10, 5850 + 10, 80, 0, 30,\
17 #define ETSI_WEATHER_RADAR_BAND_LOW 5590
18 #define ETSI_WEATHER_RADAR_BAND_HIGH 5650
19 #define ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT 600000
21 static const struct ieee80211_regdomain ath12k_world_regd
= {
26 ATH12K_5GHZ_5150_5350
,
27 ATH12K_5GHZ_5725_5850
,
31 static bool ath12k_regdom_changes(struct ieee80211_hw
*hw
, char *alpha2
)
33 const struct ieee80211_regdomain
*regd
;
35 regd
= rcu_dereference_rtnl(hw
->wiphy
->regd
);
36 /* This can happen during wiphy registration where the previous
37 * user request is received before we update the regd received
43 return memcmp(regd
->alpha2
, alpha2
, 2) != 0;
47 ath12k_reg_notifier(struct wiphy
*wiphy
, struct regulatory_request
*request
)
49 struct ieee80211_hw
*hw
= wiphy_to_ieee80211_hw(wiphy
);
50 struct ath12k_wmi_init_country_arg arg
;
51 struct ath12k_hw
*ah
= ath12k_hw_to_ah(hw
);
52 struct ath12k
*ar
= ath12k_ah_to_ar(ah
, 0);
55 ath12k_dbg(ar
->ab
, ATH12K_DBG_REG
,
56 "Regulatory Notification received for %s\n", wiphy_name(wiphy
));
58 /* Currently supporting only General User Hints. Cell base user
59 * hints to be handled later.
60 * Hints from other sources like Core, Beacons are not expected for
61 * self managed wiphy's
63 if (!(request
->initiator
== NL80211_REGDOM_SET_BY_USER
&&
64 request
->user_reg_hint_type
== NL80211_USER_REG_HINT_USER
)) {
65 ath12k_warn(ar
->ab
, "Unexpected Regulatory event for this wiphy\n");
69 if (!IS_ENABLED(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS
)) {
70 ath12k_dbg(ar
->ab
, ATH12K_DBG_REG
,
71 "Country Setting is not allowed\n");
75 if (!ath12k_regdom_changes(hw
, request
->alpha2
)) {
76 ath12k_dbg(ar
->ab
, ATH12K_DBG_REG
, "Country is already set\n");
80 /* Set the country code to the firmware and wait for
81 * the WMI_REG_CHAN_LIST_CC EVENT for updating the
84 arg
.flags
= ALPHA_IS_SET
;
85 memcpy(&arg
.cc_info
.alpha2
, request
->alpha2
, 2);
86 arg
.cc_info
.alpha2
[2] = 0;
88 /* Allow fresh updates to wiphy regd */
89 ah
->regd_updated
= false;
91 /* Send the reg change request to all the radios */
92 for_each_ar(ah
, ar
, i
) {
93 ret
= ath12k_wmi_send_init_country_cmd(ar
, &arg
);
96 "INIT Country code set to fw failed : %d\n", ret
);
100 int ath12k_reg_update_chan_list(struct ath12k
*ar
)
102 struct ieee80211_supported_band
**bands
;
103 struct ath12k_wmi_scan_chan_list_arg
*arg
;
104 struct ieee80211_channel
*channel
;
105 struct ieee80211_hw
*hw
= ath12k_ar_to_hw(ar
);
106 struct ath12k_wmi_channel_arg
*ch
;
107 enum nl80211_band band
;
108 int num_channels
= 0;
111 bands
= hw
->wiphy
->bands
;
112 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
113 if (!(ar
->mac
.sbands
[band
].channels
&& bands
[band
]))
116 for (i
= 0; i
< bands
[band
]->n_channels
; i
++) {
117 if (bands
[band
]->channels
[i
].flags
&
118 IEEE80211_CHAN_DISABLED
)
125 if (WARN_ON(!num_channels
))
128 arg
= kzalloc(struct_size(arg
, channel
, num_channels
), GFP_KERNEL
);
133 arg
->pdev_id
= ar
->pdev
->pdev_id
;
134 arg
->nallchans
= num_channels
;
138 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
139 if (!(ar
->mac
.sbands
[band
].channels
&& bands
[band
]))
142 for (i
= 0; i
< bands
[band
]->n_channels
; i
++) {
143 channel
= &bands
[band
]->channels
[i
];
145 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
148 /* TODO: Set to true/false based on some condition? */
150 ch
->allow_vht
= true;
154 !!(channel
->flags
& IEEE80211_CHAN_RADAR
);
155 ch
->is_chan_passive
= !!(channel
->flags
&
156 IEEE80211_CHAN_NO_IR
);
157 ch
->is_chan_passive
|= ch
->dfs_set
;
158 ch
->mhz
= channel
->center_freq
;
159 ch
->cfreq1
= channel
->center_freq
;
161 ch
->maxpower
= channel
->max_power
* 2;
162 ch
->maxregpower
= channel
->max_reg_power
* 2;
163 ch
->antennamax
= channel
->max_antenna_gain
* 2;
165 /* TODO: Use appropriate phymodes */
166 if (channel
->band
== NL80211_BAND_2GHZ
)
167 ch
->phy_mode
= MODE_11G
;
169 ch
->phy_mode
= MODE_11A
;
171 if (channel
->band
== NL80211_BAND_6GHZ
&&
172 cfg80211_channel_is_psc(channel
))
173 ch
->psc_channel
= true;
175 ath12k_dbg(ar
->ab
, ATH12K_DBG_WMI
,
176 "mac channel [%d/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
178 ch
->mhz
, ch
->maxpower
, ch
->maxregpower
,
179 ch
->antennamax
, ch
->phy_mode
);
182 /* TODO: use quarrter/half rate, cfreq12, dfs_cfreq2
183 * set_agile, reg_class_idx
188 ret
= ath12k_wmi_send_scan_chan_list_cmd(ar
, arg
);
194 static void ath12k_copy_regd(struct ieee80211_regdomain
*regd_orig
,
195 struct ieee80211_regdomain
*regd_copy
)
199 /* The caller should have checked error conditions */
200 memcpy(regd_copy
, regd_orig
, sizeof(*regd_orig
));
202 for (i
= 0; i
< regd_orig
->n_reg_rules
; i
++)
203 memcpy(®d_copy
->reg_rules
[i
], ®d_orig
->reg_rules
[i
],
204 sizeof(struct ieee80211_reg_rule
));
207 int ath12k_regd_update(struct ath12k
*ar
, bool init
)
209 struct ath12k_hw
*ah
= ath12k_ar_to_ah(ar
);
210 struct ieee80211_hw
*hw
= ah
->hw
;
211 struct ieee80211_regdomain
*regd
, *regd_copy
= NULL
;
212 int ret
, regd_len
, pdev_id
;
213 struct ath12k_base
*ab
;
218 /* If one of the radios within ah has already updated the regd for
219 * the wiphy, then avoid setting regd again
221 if (ah
->regd_updated
)
224 /* firmware provides reg rules which are similar for 2 GHz and 5 GHz
225 * pdev but 6 GHz pdev has superset of all rules including rules for
226 * all bands, we prefer 6 GHz pdev's rules to be used for setup of
228 * If 6 GHz pdev was part of the ath12k_hw, wait for the 6 GHz pdev,
229 * else pick the first pdev which calls this function and use its
230 * regd to update global hw regd.
231 * The regd_updated flag set at the end will not allow any further
234 if (ah
->use_6ghz_regd
&& !ar
->supports_6ghz
)
237 pdev_id
= ar
->pdev_idx
;
239 spin_lock_bh(&ab
->base_lock
);
242 /* Apply the regd received during init through
243 * WMI_REG_CHAN_LIST_CC event. In case of failure to
244 * receive the regd, initialize with a default world
247 if (ab
->default_regd
[pdev_id
]) {
248 regd
= ab
->default_regd
[pdev_id
];
251 "failed to receive default regd during init\n");
252 regd
= (struct ieee80211_regdomain
*)&ath12k_world_regd
;
255 regd
= ab
->new_regd
[pdev_id
];
260 spin_unlock_bh(&ab
->base_lock
);
264 regd_len
= sizeof(*regd
) + (regd
->n_reg_rules
*
265 sizeof(struct ieee80211_reg_rule
));
267 regd_copy
= kzalloc(regd_len
, GFP_ATOMIC
);
269 ath12k_copy_regd(regd
, regd_copy
);
271 spin_unlock_bh(&ab
->base_lock
);
279 wiphy_lock(hw
->wiphy
);
280 ret
= regulatory_set_wiphy_regd_sync(hw
->wiphy
, regd_copy
);
281 wiphy_unlock(hw
->wiphy
);
289 if (ah
->state
!= ATH12K_HW_STATE_ON
)
292 ah
->regd_updated
= true;
293 /* Apply the new regd to all the radios, this is expected to be received only once
294 * since we check for ah->regd_updated and allow here only once.
296 for_each_ar(ah
, ar
, i
) {
298 ret
= ath12k_reg_update_chan_list(ar
);
305 ath12k_warn(ab
, "failed to perform regd update : %d\n", ret
);
309 static enum nl80211_dfs_regions
310 ath12k_map_fw_dfs_region(enum ath12k_dfs_region dfs_region
)
312 switch (dfs_region
) {
313 case ATH12K_DFS_REG_FCC
:
314 case ATH12K_DFS_REG_CN
:
315 return NL80211_DFS_FCC
;
316 case ATH12K_DFS_REG_ETSI
:
317 case ATH12K_DFS_REG_KR
:
318 return NL80211_DFS_ETSI
;
319 case ATH12K_DFS_REG_MKK
:
320 case ATH12K_DFS_REG_MKK_N
:
321 return NL80211_DFS_JP
;
323 return NL80211_DFS_UNSET
;
327 static u32
ath12k_map_fw_reg_flags(u16 reg_flags
)
331 if (reg_flags
& REGULATORY_CHAN_NO_IR
)
332 flags
= NL80211_RRF_NO_IR
;
334 if (reg_flags
& REGULATORY_CHAN_RADAR
)
335 flags
|= NL80211_RRF_DFS
;
337 if (reg_flags
& REGULATORY_CHAN_NO_OFDM
)
338 flags
|= NL80211_RRF_NO_OFDM
;
340 if (reg_flags
& REGULATORY_CHAN_INDOOR_ONLY
)
341 flags
|= NL80211_RRF_NO_OUTDOOR
;
343 if (reg_flags
& REGULATORY_CHAN_NO_HT40
)
344 flags
|= NL80211_RRF_NO_HT40
;
346 if (reg_flags
& REGULATORY_CHAN_NO_80MHZ
)
347 flags
|= NL80211_RRF_NO_80MHZ
;
349 if (reg_flags
& REGULATORY_CHAN_NO_160MHZ
)
350 flags
|= NL80211_RRF_NO_160MHZ
;
355 static u32
ath12k_map_fw_phy_flags(u32 phy_flags
)
359 if (phy_flags
& ATH12K_REG_PHY_BITMAP_NO11AX
)
360 flags
|= NL80211_RRF_NO_HE
;
362 if (phy_flags
& ATH12K_REG_PHY_BITMAP_NO11BE
)
363 flags
|= NL80211_RRF_NO_EHT
;
369 ath12k_reg_can_intersect(struct ieee80211_reg_rule
*rule1
,
370 struct ieee80211_reg_rule
*rule2
)
372 u32 start_freq1
, end_freq1
;
373 u32 start_freq2
, end_freq2
;
375 start_freq1
= rule1
->freq_range
.start_freq_khz
;
376 start_freq2
= rule2
->freq_range
.start_freq_khz
;
378 end_freq1
= rule1
->freq_range
.end_freq_khz
;
379 end_freq2
= rule2
->freq_range
.end_freq_khz
;
381 if ((start_freq1
>= start_freq2
&&
382 start_freq1
< end_freq2
) ||
383 (start_freq2
> start_freq1
&&
384 start_freq2
< end_freq1
))
387 /* TODO: Should we restrict intersection feasibility
388 * based on min bandwidth of the intersected region also,
389 * say the intersected rule should have a min bandwidth
396 static void ath12k_reg_intersect_rules(struct ieee80211_reg_rule
*rule1
,
397 struct ieee80211_reg_rule
*rule2
,
398 struct ieee80211_reg_rule
*new_rule
)
400 u32 start_freq1
, end_freq1
;
401 u32 start_freq2
, end_freq2
;
402 u32 freq_diff
, max_bw
;
404 start_freq1
= rule1
->freq_range
.start_freq_khz
;
405 start_freq2
= rule2
->freq_range
.start_freq_khz
;
407 end_freq1
= rule1
->freq_range
.end_freq_khz
;
408 end_freq2
= rule2
->freq_range
.end_freq_khz
;
410 new_rule
->freq_range
.start_freq_khz
= max_t(u32
, start_freq1
,
412 new_rule
->freq_range
.end_freq_khz
= min_t(u32
, end_freq1
, end_freq2
);
414 freq_diff
= new_rule
->freq_range
.end_freq_khz
-
415 new_rule
->freq_range
.start_freq_khz
;
416 max_bw
= min_t(u32
, rule1
->freq_range
.max_bandwidth_khz
,
417 rule2
->freq_range
.max_bandwidth_khz
);
418 new_rule
->freq_range
.max_bandwidth_khz
= min_t(u32
, max_bw
, freq_diff
);
420 new_rule
->power_rule
.max_antenna_gain
=
421 min_t(u32
, rule1
->power_rule
.max_antenna_gain
,
422 rule2
->power_rule
.max_antenna_gain
);
424 new_rule
->power_rule
.max_eirp
= min_t(u32
, rule1
->power_rule
.max_eirp
,
425 rule2
->power_rule
.max_eirp
);
427 /* Use the flags of both the rules */
428 new_rule
->flags
= rule1
->flags
| rule2
->flags
;
430 /* To be safe, lts use the max cac timeout of both rules */
431 new_rule
->dfs_cac_ms
= max_t(u32
, rule1
->dfs_cac_ms
,
435 static struct ieee80211_regdomain
*
436 ath12k_regd_intersect(struct ieee80211_regdomain
*default_regd
,
437 struct ieee80211_regdomain
*curr_regd
)
439 u8 num_old_regd_rules
, num_curr_regd_rules
, num_new_regd_rules
;
440 struct ieee80211_reg_rule
*old_rule
, *curr_rule
, *new_rule
;
441 struct ieee80211_regdomain
*new_regd
= NULL
;
444 num_old_regd_rules
= default_regd
->n_reg_rules
;
445 num_curr_regd_rules
= curr_regd
->n_reg_rules
;
446 num_new_regd_rules
= 0;
448 /* Find the number of intersecting rules to allocate new regd memory */
449 for (i
= 0; i
< num_old_regd_rules
; i
++) {
450 old_rule
= default_regd
->reg_rules
+ i
;
451 for (j
= 0; j
< num_curr_regd_rules
; j
++) {
452 curr_rule
= curr_regd
->reg_rules
+ j
;
454 if (ath12k_reg_can_intersect(old_rule
, curr_rule
))
455 num_new_regd_rules
++;
459 if (!num_new_regd_rules
)
462 new_regd
= kzalloc(sizeof(*new_regd
) + (num_new_regd_rules
*
463 sizeof(struct ieee80211_reg_rule
)),
469 /* We set the new country and dfs region directly and only trim
470 * the freq, power, antenna gain by intersecting with the
471 * default regdomain. Also MAX of the dfs cac timeout is selected.
473 new_regd
->n_reg_rules
= num_new_regd_rules
;
474 memcpy(new_regd
->alpha2
, curr_regd
->alpha2
, sizeof(new_regd
->alpha2
));
475 new_regd
->dfs_region
= curr_regd
->dfs_region
;
476 new_rule
= new_regd
->reg_rules
;
478 for (i
= 0, k
= 0; i
< num_old_regd_rules
; i
++) {
479 old_rule
= default_regd
->reg_rules
+ i
;
480 for (j
= 0; j
< num_curr_regd_rules
; j
++) {
481 curr_rule
= curr_regd
->reg_rules
+ j
;
483 if (ath12k_reg_can_intersect(old_rule
, curr_rule
))
484 ath12k_reg_intersect_rules(old_rule
, curr_rule
,
492 ath12k_reg_get_regdom_str(enum nl80211_dfs_regions dfs_region
)
494 switch (dfs_region
) {
495 case NL80211_DFS_FCC
:
497 case NL80211_DFS_ETSI
:
507 ath12k_reg_adjust_bw(u16 start_freq
, u16 end_freq
, u16 max_bw
)
511 bw
= end_freq
- start_freq
;
512 bw
= min_t(u16
, bw
, max_bw
);
514 if (bw
>= 80 && bw
< 160)
516 else if (bw
>= 40 && bw
< 80)
525 ath12k_reg_update_rule(struct ieee80211_reg_rule
*reg_rule
, u32 start_freq
,
526 u32 end_freq
, u32 bw
, u32 ant_gain
, u32 reg_pwr
,
529 reg_rule
->freq_range
.start_freq_khz
= MHZ_TO_KHZ(start_freq
);
530 reg_rule
->freq_range
.end_freq_khz
= MHZ_TO_KHZ(end_freq
);
531 reg_rule
->freq_range
.max_bandwidth_khz
= MHZ_TO_KHZ(bw
);
532 reg_rule
->power_rule
.max_antenna_gain
= DBI_TO_MBI(ant_gain
);
533 reg_rule
->power_rule
.max_eirp
= DBM_TO_MBM(reg_pwr
);
534 reg_rule
->flags
= reg_flags
;
538 ath12k_reg_update_weather_radar_band(struct ath12k_base
*ab
,
539 struct ieee80211_regdomain
*regd
,
540 struct ath12k_reg_rule
*reg_rule
,
541 u8
*rule_idx
, u32 flags
, u16 max_bw
)
549 bw
= ath12k_reg_adjust_bw(reg_rule
->start_freq
,
550 ETSI_WEATHER_RADAR_BAND_LOW
, max_bw
);
552 ath12k_reg_update_rule(regd
->reg_rules
+ i
, reg_rule
->start_freq
,
553 ETSI_WEATHER_RADAR_BAND_LOW
, bw
,
554 reg_rule
->ant_gain
, reg_rule
->reg_power
,
557 ath12k_dbg(ab
, ATH12K_DBG_REG
,
558 "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
559 i
+ 1, reg_rule
->start_freq
, ETSI_WEATHER_RADAR_BAND_LOW
,
560 bw
, reg_rule
->ant_gain
, reg_rule
->reg_power
,
561 regd
->reg_rules
[i
].dfs_cac_ms
,
564 if (reg_rule
->end_freq
> ETSI_WEATHER_RADAR_BAND_HIGH
)
565 end_freq
= ETSI_WEATHER_RADAR_BAND_HIGH
;
567 end_freq
= reg_rule
->end_freq
;
569 bw
= ath12k_reg_adjust_bw(ETSI_WEATHER_RADAR_BAND_LOW
, end_freq
,
574 ath12k_reg_update_rule(regd
->reg_rules
+ i
,
575 ETSI_WEATHER_RADAR_BAND_LOW
, end_freq
, bw
,
576 reg_rule
->ant_gain
, reg_rule
->reg_power
,
579 regd
->reg_rules
[i
].dfs_cac_ms
= ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT
;
581 ath12k_dbg(ab
, ATH12K_DBG_REG
,
582 "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
583 i
+ 1, ETSI_WEATHER_RADAR_BAND_LOW
, end_freq
,
584 bw
, reg_rule
->ant_gain
, reg_rule
->reg_power
,
585 regd
->reg_rules
[i
].dfs_cac_ms
,
588 if (end_freq
== reg_rule
->end_freq
) {
594 bw
= ath12k_reg_adjust_bw(ETSI_WEATHER_RADAR_BAND_HIGH
,
595 reg_rule
->end_freq
, max_bw
);
599 ath12k_reg_update_rule(regd
->reg_rules
+ i
, ETSI_WEATHER_RADAR_BAND_HIGH
,
600 reg_rule
->end_freq
, bw
,
601 reg_rule
->ant_gain
, reg_rule
->reg_power
,
604 ath12k_dbg(ab
, ATH12K_DBG_REG
,
605 "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
606 i
+ 1, ETSI_WEATHER_RADAR_BAND_HIGH
, reg_rule
->end_freq
,
607 bw
, reg_rule
->ant_gain
, reg_rule
->reg_power
,
608 regd
->reg_rules
[i
].dfs_cac_ms
,
614 struct ieee80211_regdomain
*
615 ath12k_reg_build_regd(struct ath12k_base
*ab
,
616 struct ath12k_reg_info
*reg_info
, bool intersect
)
618 struct ieee80211_regdomain
*tmp_regd
, *default_regd
, *new_regd
= NULL
;
619 struct ath12k_reg_rule
*reg_rule
;
620 u8 i
= 0, j
= 0, k
= 0;
626 num_rules
= reg_info
->num_5g_reg_rules
+ reg_info
->num_2g_reg_rules
;
628 /* FIXME: Currently taking reg rules for 6G only from Indoor AP mode list.
629 * This can be updated to choose the combination dynamically based on AP
630 * type and client type, after complete 6G regulatory support is added.
632 if (reg_info
->is_ext_reg_event
)
633 num_rules
+= reg_info
->num_6g_reg_rules_ap
[WMI_REG_INDOOR_AP
];
638 /* Add max additional rules to accommodate weather radar band */
639 if (reg_info
->dfs_region
== ATH12K_DFS_REG_ETSI
)
642 tmp_regd
= kzalloc(sizeof(*tmp_regd
) +
643 (num_rules
* sizeof(struct ieee80211_reg_rule
)),
648 memcpy(tmp_regd
->alpha2
, reg_info
->alpha2
, REG_ALPHA2_LEN
+ 1);
649 memcpy(alpha2
, reg_info
->alpha2
, REG_ALPHA2_LEN
+ 1);
651 tmp_regd
->dfs_region
= ath12k_map_fw_dfs_region(reg_info
->dfs_region
);
653 ath12k_dbg(ab
, ATH12K_DBG_REG
,
654 "\r\nCountry %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n",
655 alpha2
, ath12k_reg_get_regdom_str(tmp_regd
->dfs_region
),
656 reg_info
->dfs_region
, num_rules
);
657 /* Update reg_rules[] below. Firmware is expected to
658 * send these rules in order(2G rules first and then 5G)
660 for (; i
< num_rules
; i
++) {
661 if (reg_info
->num_2g_reg_rules
&&
662 (i
< reg_info
->num_2g_reg_rules
)) {
663 reg_rule
= reg_info
->reg_rules_2g_ptr
+ i
;
664 max_bw
= min_t(u16
, reg_rule
->max_bw
,
665 reg_info
->max_bw_2g
);
667 } else if (reg_info
->num_5g_reg_rules
&&
668 (j
< reg_info
->num_5g_reg_rules
)) {
669 reg_rule
= reg_info
->reg_rules_5g_ptr
+ j
++;
670 max_bw
= min_t(u16
, reg_rule
->max_bw
,
671 reg_info
->max_bw_5g
);
673 /* FW doesn't pass NL80211_RRF_AUTO_BW flag for
674 * BW Auto correction, we can enable this by default
675 * for all 5G rules here. The regulatory core performs
676 * BW correction if required and applies flags as
677 * per other BW rule flags we pass from here
679 flags
= NL80211_RRF_AUTO_BW
;
680 } else if (reg_info
->is_ext_reg_event
&&
681 reg_info
->num_6g_reg_rules_ap
[WMI_REG_INDOOR_AP
] &&
682 (k
< reg_info
->num_6g_reg_rules_ap
[WMI_REG_INDOOR_AP
])) {
683 reg_rule
= reg_info
->reg_rules_6g_ap_ptr
[WMI_REG_INDOOR_AP
] + k
++;
684 max_bw
= min_t(u16
, reg_rule
->max_bw
,
685 reg_info
->max_bw_6g_ap
[WMI_REG_INDOOR_AP
]);
686 flags
= NL80211_RRF_AUTO_BW
;
691 flags
|= ath12k_map_fw_reg_flags(reg_rule
->flags
);
692 flags
|= ath12k_map_fw_phy_flags(reg_info
->phybitmap
);
694 ath12k_reg_update_rule(tmp_regd
->reg_rules
+ i
,
695 reg_rule
->start_freq
,
696 reg_rule
->end_freq
, max_bw
,
697 reg_rule
->ant_gain
, reg_rule
->reg_power
,
700 /* Update dfs cac timeout if the dfs domain is ETSI and the
701 * new rule covers weather radar band.
702 * Default value of '0' corresponds to 60s timeout, so no
703 * need to update that for other rules.
705 if (flags
& NL80211_RRF_DFS
&&
706 reg_info
->dfs_region
== ATH12K_DFS_REG_ETSI
&&
707 (reg_rule
->end_freq
> ETSI_WEATHER_RADAR_BAND_LOW
&&
708 reg_rule
->start_freq
< ETSI_WEATHER_RADAR_BAND_HIGH
)){
709 ath12k_reg_update_weather_radar_band(ab
, tmp_regd
,
715 if (reg_info
->is_ext_reg_event
) {
716 ath12k_dbg(ab
, ATH12K_DBG_REG
, "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n",
717 i
+ 1, reg_rule
->start_freq
, reg_rule
->end_freq
,
718 max_bw
, reg_rule
->ant_gain
, reg_rule
->reg_power
,
719 tmp_regd
->reg_rules
[i
].dfs_cac_ms
,
720 flags
, reg_rule
->psd_flag
, reg_rule
->psd_eirp
);
722 ath12k_dbg(ab
, ATH12K_DBG_REG
,
723 "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
724 i
+ 1, reg_rule
->start_freq
, reg_rule
->end_freq
,
725 max_bw
, reg_rule
->ant_gain
, reg_rule
->reg_power
,
726 tmp_regd
->reg_rules
[i
].dfs_cac_ms
,
731 tmp_regd
->n_reg_rules
= i
;
734 default_regd
= ab
->default_regd
[reg_info
->phy_id
];
736 /* Get a new regd by intersecting the received regd with
739 new_regd
= ath12k_regd_intersect(default_regd
, tmp_regd
);
742 ath12k_warn(ab
, "Unable to create intersected regdomain\n");
753 void ath12k_regd_update_work(struct work_struct
*work
)
755 struct ath12k
*ar
= container_of(work
, struct ath12k
,
759 ret
= ath12k_regd_update(ar
, false);
761 /* Firmware has already moved to the new regd. We need
762 * to maintain channel consistency across FW, Host driver
763 * and userspace. Hence as a fallback mechanism we can set
764 * the prev or default country code to the firmware.
766 /* TODO: Implement Fallback Mechanism */
770 void ath12k_reg_init(struct ieee80211_hw
*hw
)
772 hw
->wiphy
->regulatory_flags
= REGULATORY_WIPHY_SELF_MANAGED
;
773 hw
->wiphy
->reg_notifier
= ath12k_reg_notifier
;
776 void ath12k_reg_free(struct ath12k_base
*ab
)
780 for (i
= 0; i
< ab
->hw_params
->max_radios
; i
++) {
781 kfree(ab
->default_regd
[i
]);
782 kfree(ab
->new_regd
[i
]);