1 // SPDX-License-Identifier: BSD-3-Clause-Clear
3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
8 /* World regdom to be used in case default regd from fw is unavailable */
9 #define ATH11K_2GHZ_CH01_11 REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0)
10 #define ATH11K_5GHZ_5150_5350 REG_RULE(5150 - 10, 5350 + 10, 80, 0, 30,\
12 #define ATH11K_5GHZ_5725_5850 REG_RULE(5725 - 10, 5850 + 10, 80, 0, 30,\
15 #define ETSI_WEATHER_RADAR_BAND_LOW 5590
16 #define ETSI_WEATHER_RADAR_BAND_HIGH 5650
17 #define ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT 600000
19 static const struct ieee80211_regdomain ath11k_world_regd
= {
24 ATH11K_5GHZ_5150_5350
,
25 ATH11K_5GHZ_5725_5850
,
29 static bool ath11k_regdom_changes(struct ath11k
*ar
, char *alpha2
)
31 const struct ieee80211_regdomain
*regd
;
33 regd
= rcu_dereference_rtnl(ar
->hw
->wiphy
->regd
);
34 /* This can happen during wiphy registration where the previous
35 * user request is received before we update the regd received
41 return memcmp(regd
->alpha2
, alpha2
, 2) != 0;
45 ath11k_reg_notifier(struct wiphy
*wiphy
, struct regulatory_request
*request
)
47 struct ieee80211_hw
*hw
= wiphy_to_ieee80211_hw(wiphy
);
48 struct wmi_init_country_params init_country_param
;
49 struct ath11k
*ar
= hw
->priv
;
52 ath11k_dbg(ar
->ab
, ATH11K_DBG_REG
,
53 "Regulatory Notification received for %s\n", wiphy_name(wiphy
));
55 /* Currently supporting only General User Hints. Cell base user
56 * hints to be handled later.
57 * Hints from other sources like Core, Beacons are not expected for
58 * self managed wiphy's
60 if (!(request
->initiator
== NL80211_REGDOM_SET_BY_USER
&&
61 request
->user_reg_hint_type
== NL80211_USER_REG_HINT_USER
)) {
62 ath11k_warn(ar
->ab
, "Unexpected Regulatory event for this wiphy\n");
66 if (!IS_ENABLED(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS
)) {
67 ath11k_dbg(ar
->ab
, ATH11K_DBG_REG
,
68 "Country Setting is not allowed\n");
72 if (!ath11k_regdom_changes(ar
, request
->alpha2
)) {
73 ath11k_dbg(ar
->ab
, ATH11K_DBG_REG
, "Country is already set\n");
77 /* Set the country code to the firmware and wait for
78 * the WMI_REG_CHAN_LIST_CC EVENT for updating the
81 init_country_param
.flags
= ALPHA_IS_SET
;
82 memcpy(&init_country_param
.cc_info
.alpha2
, request
->alpha2
, 2);
83 init_country_param
.cc_info
.alpha2
[2] = 0;
85 ret
= ath11k_wmi_send_init_country_cmd(ar
, init_country_param
);
88 "INIT Country code set to fw failed : %d\n", ret
);
91 int ath11k_reg_update_chan_list(struct ath11k
*ar
)
93 struct ieee80211_supported_band
**bands
;
94 struct scan_chan_list_params
*params
;
95 struct ieee80211_channel
*channel
;
96 struct ieee80211_hw
*hw
= ar
->hw
;
97 struct channel_param
*ch
;
98 enum nl80211_band band
;
103 bands
= hw
->wiphy
->bands
;
104 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
108 for (i
= 0; i
< bands
[band
]->n_channels
; i
++) {
109 if (bands
[band
]->channels
[i
].flags
&
110 IEEE80211_CHAN_DISABLED
)
117 if (WARN_ON(!num_channels
))
120 params_len
= sizeof(struct scan_chan_list_params
) +
121 num_channels
* sizeof(struct channel_param
);
122 params
= kzalloc(params_len
, GFP_KERNEL
);
127 params
->pdev_id
= ar
->pdev
->pdev_id
;
128 params
->nallchans
= num_channels
;
130 ch
= params
->ch_param
;
132 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
136 for (i
= 0; i
< bands
[band
]->n_channels
; i
++) {
137 channel
= &bands
[band
]->channels
[i
];
139 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
142 /* TODO: Set to true/false based on some condition? */
144 ch
->allow_vht
= true;
148 !!(channel
->flags
& IEEE80211_CHAN_RADAR
);
149 ch
->is_chan_passive
= !!(channel
->flags
&
150 IEEE80211_CHAN_NO_IR
);
151 ch
->is_chan_passive
|= ch
->dfs_set
;
152 ch
->mhz
= channel
->center_freq
;
153 ch
->cfreq1
= channel
->center_freq
;
155 ch
->maxpower
= channel
->max_power
* 2;
156 ch
->maxregpower
= channel
->max_reg_power
* 2;
157 ch
->antennamax
= channel
->max_antenna_gain
* 2;
159 /* TODO: Use appropriate phymodes */
160 if (channel
->band
== NL80211_BAND_2GHZ
)
161 ch
->phy_mode
= MODE_11G
;
163 ch
->phy_mode
= MODE_11A
;
165 if (channel
->band
== NL80211_BAND_6GHZ
&&
166 cfg80211_channel_is_psc(channel
))
167 ch
->psc_channel
= true;
169 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
170 "mac channel [%d/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
171 i
, params
->nallchans
,
172 ch
->mhz
, ch
->maxpower
, ch
->maxregpower
,
173 ch
->antennamax
, ch
->phy_mode
);
176 /* TODO: use quarrter/half rate, cfreq12, dfs_cfreq2
177 * set_agile, reg_class_idx
182 ret
= ath11k_wmi_send_scan_chan_list_cmd(ar
, params
);
188 static void ath11k_copy_regd(struct ieee80211_regdomain
*regd_orig
,
189 struct ieee80211_regdomain
*regd_copy
)
193 /* The caller should have checked error conditions */
194 memcpy(regd_copy
, regd_orig
, sizeof(*regd_orig
));
196 for (i
= 0; i
< regd_orig
->n_reg_rules
; i
++)
197 memcpy(®d_copy
->reg_rules
[i
], ®d_orig
->reg_rules
[i
],
198 sizeof(struct ieee80211_reg_rule
));
201 int ath11k_regd_update(struct ath11k
*ar
, bool init
)
203 struct ieee80211_regdomain
*regd
, *regd_copy
= NULL
;
204 int ret
, regd_len
, pdev_id
;
205 struct ath11k_base
*ab
;
208 pdev_id
= ar
->pdev_idx
;
210 spin_lock_bh(&ab
->base_lock
);
213 /* Apply the regd received during init through
214 * WMI_REG_CHAN_LIST_CC event. In case of failure to
215 * receive the regd, initialize with a default world
218 if (ab
->default_regd
[pdev_id
]) {
219 regd
= ab
->default_regd
[pdev_id
];
222 "failed to receive default regd during init\n");
223 regd
= (struct ieee80211_regdomain
*)&ath11k_world_regd
;
226 regd
= ab
->new_regd
[pdev_id
];
231 spin_unlock_bh(&ab
->base_lock
);
235 regd_len
= sizeof(*regd
) + (regd
->n_reg_rules
*
236 sizeof(struct ieee80211_reg_rule
));
238 regd_copy
= kzalloc(regd_len
, GFP_ATOMIC
);
240 ath11k_copy_regd(regd
, regd_copy
);
242 spin_unlock_bh(&ab
->base_lock
);
250 ret
= regulatory_set_wiphy_regd_sync_rtnl(ar
->hw
->wiphy
, regd_copy
);
258 if (ar
->state
== ATH11K_STATE_ON
) {
259 ret
= ath11k_reg_update_chan_list(ar
);
266 ath11k_warn(ab
, "failed to perform regd update : %d\n", ret
);
270 static enum nl80211_dfs_regions
271 ath11k_map_fw_dfs_region(enum ath11k_dfs_region dfs_region
)
273 switch (dfs_region
) {
274 case ATH11K_DFS_REG_FCC
:
275 case ATH11K_DFS_REG_CN
:
276 return NL80211_DFS_FCC
;
277 case ATH11K_DFS_REG_ETSI
:
278 case ATH11K_DFS_REG_KR
:
279 return NL80211_DFS_ETSI
;
280 case ATH11K_DFS_REG_MKK
:
281 case ATH11K_DFS_REG_MKK_N
:
282 return NL80211_DFS_JP
;
284 return NL80211_DFS_UNSET
;
288 static u32
ath11k_map_fw_reg_flags(u16 reg_flags
)
292 if (reg_flags
& REGULATORY_CHAN_NO_IR
)
293 flags
= NL80211_RRF_NO_IR
;
295 if (reg_flags
& REGULATORY_CHAN_RADAR
)
296 flags
|= NL80211_RRF_DFS
;
298 if (reg_flags
& REGULATORY_CHAN_NO_OFDM
)
299 flags
|= NL80211_RRF_NO_OFDM
;
301 if (reg_flags
& REGULATORY_CHAN_INDOOR_ONLY
)
302 flags
|= NL80211_RRF_NO_OUTDOOR
;
304 if (reg_flags
& REGULATORY_CHAN_NO_HT40
)
305 flags
|= NL80211_RRF_NO_HT40
;
307 if (reg_flags
& REGULATORY_CHAN_NO_80MHZ
)
308 flags
|= NL80211_RRF_NO_80MHZ
;
310 if (reg_flags
& REGULATORY_CHAN_NO_160MHZ
)
311 flags
|= NL80211_RRF_NO_160MHZ
;
317 ath11k_reg_can_intersect(struct ieee80211_reg_rule
*rule1
,
318 struct ieee80211_reg_rule
*rule2
)
320 u32 start_freq1
, end_freq1
;
321 u32 start_freq2
, end_freq2
;
323 start_freq1
= rule1
->freq_range
.start_freq_khz
;
324 start_freq2
= rule2
->freq_range
.start_freq_khz
;
326 end_freq1
= rule1
->freq_range
.end_freq_khz
;
327 end_freq2
= rule2
->freq_range
.end_freq_khz
;
329 if ((start_freq1
>= start_freq2
&&
330 start_freq1
< end_freq2
) ||
331 (start_freq2
> start_freq1
&&
332 start_freq2
< end_freq1
))
335 /* TODO: Should we restrict intersection feasibility
336 * based on min bandwidth of the intersected region also,
337 * say the intersected rule should have a min bandwidth
344 static void ath11k_reg_intersect_rules(struct ieee80211_reg_rule
*rule1
,
345 struct ieee80211_reg_rule
*rule2
,
346 struct ieee80211_reg_rule
*new_rule
)
348 u32 start_freq1
, end_freq1
;
349 u32 start_freq2
, end_freq2
;
350 u32 freq_diff
, max_bw
;
352 start_freq1
= rule1
->freq_range
.start_freq_khz
;
353 start_freq2
= rule2
->freq_range
.start_freq_khz
;
355 end_freq1
= rule1
->freq_range
.end_freq_khz
;
356 end_freq2
= rule2
->freq_range
.end_freq_khz
;
358 new_rule
->freq_range
.start_freq_khz
= max_t(u32
, start_freq1
,
360 new_rule
->freq_range
.end_freq_khz
= min_t(u32
, end_freq1
, end_freq2
);
362 freq_diff
= new_rule
->freq_range
.end_freq_khz
-
363 new_rule
->freq_range
.start_freq_khz
;
364 max_bw
= min_t(u32
, rule1
->freq_range
.max_bandwidth_khz
,
365 rule2
->freq_range
.max_bandwidth_khz
);
366 new_rule
->freq_range
.max_bandwidth_khz
= min_t(u32
, max_bw
, freq_diff
);
368 new_rule
->power_rule
.max_antenna_gain
=
369 min_t(u32
, rule1
->power_rule
.max_antenna_gain
,
370 rule2
->power_rule
.max_antenna_gain
);
372 new_rule
->power_rule
.max_eirp
= min_t(u32
, rule1
->power_rule
.max_eirp
,
373 rule2
->power_rule
.max_eirp
);
375 /* Use the flags of both the rules */
376 new_rule
->flags
= rule1
->flags
| rule2
->flags
;
378 /* To be safe, lts use the max cac timeout of both rules */
379 new_rule
->dfs_cac_ms
= max_t(u32
, rule1
->dfs_cac_ms
,
383 static struct ieee80211_regdomain
*
384 ath11k_regd_intersect(struct ieee80211_regdomain
*default_regd
,
385 struct ieee80211_regdomain
*curr_regd
)
387 u8 num_old_regd_rules
, num_curr_regd_rules
, num_new_regd_rules
;
388 struct ieee80211_reg_rule
*old_rule
, *curr_rule
, *new_rule
;
389 struct ieee80211_regdomain
*new_regd
= NULL
;
392 num_old_regd_rules
= default_regd
->n_reg_rules
;
393 num_curr_regd_rules
= curr_regd
->n_reg_rules
;
394 num_new_regd_rules
= 0;
396 /* Find the number of intersecting rules to allocate new regd memory */
397 for (i
= 0; i
< num_old_regd_rules
; i
++) {
398 old_rule
= default_regd
->reg_rules
+ i
;
399 for (j
= 0; j
< num_curr_regd_rules
; j
++) {
400 curr_rule
= curr_regd
->reg_rules
+ j
;
402 if (ath11k_reg_can_intersect(old_rule
, curr_rule
))
403 num_new_regd_rules
++;
407 if (!num_new_regd_rules
)
410 new_regd
= kzalloc(sizeof(*new_regd
) + (num_new_regd_rules
*
411 sizeof(struct ieee80211_reg_rule
)),
417 /* We set the new country and dfs region directly and only trim
418 * the freq, power, antenna gain by intersecting with the
419 * default regdomain. Also MAX of the dfs cac timeout is selected.
421 new_regd
->n_reg_rules
= num_new_regd_rules
;
422 memcpy(new_regd
->alpha2
, curr_regd
->alpha2
, sizeof(new_regd
->alpha2
));
423 new_regd
->dfs_region
= curr_regd
->dfs_region
;
424 new_rule
= new_regd
->reg_rules
;
426 for (i
= 0, k
= 0; i
< num_old_regd_rules
; i
++) {
427 old_rule
= default_regd
->reg_rules
+ i
;
428 for (j
= 0; j
< num_curr_regd_rules
; j
++) {
429 curr_rule
= curr_regd
->reg_rules
+ j
;
431 if (ath11k_reg_can_intersect(old_rule
, curr_rule
))
432 ath11k_reg_intersect_rules(old_rule
, curr_rule
,
440 ath11k_reg_get_regdom_str(enum nl80211_dfs_regions dfs_region
)
442 switch (dfs_region
) {
443 case NL80211_DFS_FCC
:
445 case NL80211_DFS_ETSI
:
455 ath11k_reg_adjust_bw(u16 start_freq
, u16 end_freq
, u16 max_bw
)
459 bw
= end_freq
- start_freq
;
460 bw
= min_t(u16
, bw
, max_bw
);
462 if (bw
>= 80 && bw
< 160)
464 else if (bw
>= 40 && bw
< 80)
473 ath11k_reg_update_rule(struct ieee80211_reg_rule
*reg_rule
, u32 start_freq
,
474 u32 end_freq
, u32 bw
, u32 ant_gain
, u32 reg_pwr
,
477 reg_rule
->freq_range
.start_freq_khz
= MHZ_TO_KHZ(start_freq
);
478 reg_rule
->freq_range
.end_freq_khz
= MHZ_TO_KHZ(end_freq
);
479 reg_rule
->freq_range
.max_bandwidth_khz
= MHZ_TO_KHZ(bw
);
480 reg_rule
->power_rule
.max_antenna_gain
= DBI_TO_MBI(ant_gain
);
481 reg_rule
->power_rule
.max_eirp
= DBM_TO_MBM(reg_pwr
);
482 reg_rule
->flags
= reg_flags
;
486 ath11k_reg_update_weather_radar_band(struct ath11k_base
*ab
,
487 struct ieee80211_regdomain
*regd
,
488 struct cur_reg_rule
*reg_rule
,
489 u8
*rule_idx
, u32 flags
, u16 max_bw
)
497 bw
= ath11k_reg_adjust_bw(reg_rule
->start_freq
,
498 ETSI_WEATHER_RADAR_BAND_LOW
, max_bw
);
500 ath11k_reg_update_rule(regd
->reg_rules
+ i
, reg_rule
->start_freq
,
501 ETSI_WEATHER_RADAR_BAND_LOW
, bw
,
502 reg_rule
->ant_gain
, reg_rule
->reg_power
,
505 ath11k_dbg(ab
, ATH11K_DBG_REG
,
506 "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
507 i
+ 1, reg_rule
->start_freq
, ETSI_WEATHER_RADAR_BAND_LOW
,
508 bw
, reg_rule
->ant_gain
, reg_rule
->reg_power
,
509 regd
->reg_rules
[i
].dfs_cac_ms
,
512 if (reg_rule
->end_freq
> ETSI_WEATHER_RADAR_BAND_HIGH
)
513 end_freq
= ETSI_WEATHER_RADAR_BAND_HIGH
;
515 end_freq
= reg_rule
->end_freq
;
517 bw
= ath11k_reg_adjust_bw(ETSI_WEATHER_RADAR_BAND_LOW
, end_freq
,
522 ath11k_reg_update_rule(regd
->reg_rules
+ i
,
523 ETSI_WEATHER_RADAR_BAND_LOW
, end_freq
, bw
,
524 reg_rule
->ant_gain
, reg_rule
->reg_power
,
527 regd
->reg_rules
[i
].dfs_cac_ms
= ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT
;
529 ath11k_dbg(ab
, ATH11K_DBG_REG
,
530 "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
531 i
+ 1, ETSI_WEATHER_RADAR_BAND_LOW
, end_freq
,
532 bw
, reg_rule
->ant_gain
, reg_rule
->reg_power
,
533 regd
->reg_rules
[i
].dfs_cac_ms
,
536 if (end_freq
== reg_rule
->end_freq
) {
542 bw
= ath11k_reg_adjust_bw(ETSI_WEATHER_RADAR_BAND_HIGH
,
543 reg_rule
->end_freq
, max_bw
);
547 ath11k_reg_update_rule(regd
->reg_rules
+ i
, ETSI_WEATHER_RADAR_BAND_HIGH
,
548 reg_rule
->end_freq
, bw
,
549 reg_rule
->ant_gain
, reg_rule
->reg_power
,
552 ath11k_dbg(ab
, ATH11K_DBG_REG
,
553 "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
554 i
+ 1, ETSI_WEATHER_RADAR_BAND_HIGH
, reg_rule
->end_freq
,
555 bw
, reg_rule
->ant_gain
, reg_rule
->reg_power
,
556 regd
->reg_rules
[i
].dfs_cac_ms
,
562 struct ieee80211_regdomain
*
563 ath11k_reg_build_regd(struct ath11k_base
*ab
,
564 struct cur_regulatory_info
*reg_info
, bool intersect
)
566 struct ieee80211_regdomain
*tmp_regd
, *default_regd
, *new_regd
= NULL
;
567 struct cur_reg_rule
*reg_rule
;
574 num_rules
= reg_info
->num_5g_reg_rules
+ reg_info
->num_2g_reg_rules
;
579 /* Add max additional rules to accommodate weather radar band */
580 if (reg_info
->dfs_region
== ATH11K_DFS_REG_ETSI
)
583 tmp_regd
= kzalloc(sizeof(*tmp_regd
) +
584 (num_rules
* sizeof(struct ieee80211_reg_rule
)),
589 memcpy(tmp_regd
->alpha2
, reg_info
->alpha2
, REG_ALPHA2_LEN
+ 1);
590 memcpy(alpha2
, reg_info
->alpha2
, REG_ALPHA2_LEN
+ 1);
592 tmp_regd
->dfs_region
= ath11k_map_fw_dfs_region(reg_info
->dfs_region
);
594 ath11k_dbg(ab
, ATH11K_DBG_REG
,
595 "\r\nCountry %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n",
596 alpha2
, ath11k_reg_get_regdom_str(tmp_regd
->dfs_region
),
597 reg_info
->dfs_region
, num_rules
);
598 /* Update reg_rules[] below. Firmware is expected to
599 * send these rules in order(2G rules first and then 5G)
601 for (; i
< num_rules
; i
++) {
602 if (reg_info
->num_2g_reg_rules
&&
603 (i
< reg_info
->num_2g_reg_rules
)) {
604 reg_rule
= reg_info
->reg_rules_2g_ptr
+ i
;
605 max_bw
= min_t(u16
, reg_rule
->max_bw
,
606 reg_info
->max_bw_2g
);
608 } else if (reg_info
->num_5g_reg_rules
&&
609 (j
< reg_info
->num_5g_reg_rules
)) {
610 reg_rule
= reg_info
->reg_rules_5g_ptr
+ j
++;
611 max_bw
= min_t(u16
, reg_rule
->max_bw
,
612 reg_info
->max_bw_5g
);
614 /* FW doesn't pass NL80211_RRF_AUTO_BW flag for
615 * BW Auto correction, we can enable this by default
616 * for all 5G rules here. The regulatory core performs
617 * BW correction if required and applies flags as
618 * per other BW rule flags we pass from here
620 flags
= NL80211_RRF_AUTO_BW
;
625 flags
|= ath11k_map_fw_reg_flags(reg_rule
->flags
);
627 ath11k_reg_update_rule(tmp_regd
->reg_rules
+ i
,
628 reg_rule
->start_freq
,
629 reg_rule
->end_freq
, max_bw
,
630 reg_rule
->ant_gain
, reg_rule
->reg_power
,
633 /* Update dfs cac timeout if the dfs domain is ETSI and the
634 * new rule covers weather radar band.
635 * Default value of '0' corresponds to 60s timeout, so no
636 * need to update that for other rules.
638 if (flags
& NL80211_RRF_DFS
&&
639 reg_info
->dfs_region
== ATH11K_DFS_REG_ETSI
&&
640 (reg_rule
->end_freq
> ETSI_WEATHER_RADAR_BAND_LOW
&&
641 reg_rule
->start_freq
< ETSI_WEATHER_RADAR_BAND_HIGH
)){
642 ath11k_reg_update_weather_radar_band(ab
, tmp_regd
,
648 ath11k_dbg(ab
, ATH11K_DBG_REG
,
649 "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
650 i
+ 1, reg_rule
->start_freq
, reg_rule
->end_freq
,
651 max_bw
, reg_rule
->ant_gain
, reg_rule
->reg_power
,
652 tmp_regd
->reg_rules
[i
].dfs_cac_ms
,
656 tmp_regd
->n_reg_rules
= i
;
659 default_regd
= ab
->default_regd
[reg_info
->phy_id
];
661 /* Get a new regd by intersecting the received regd with
664 new_regd
= ath11k_regd_intersect(default_regd
, tmp_regd
);
667 ath11k_warn(ab
, "Unable to create intersected regdomain\n");
678 void ath11k_regd_update_work(struct work_struct
*work
)
680 struct ath11k
*ar
= container_of(work
, struct ath11k
,
684 ret
= ath11k_regd_update(ar
, false);
686 /* Firmware has already moved to the new regd. We need
687 * to maintain channel consistency across FW, Host driver
688 * and userspace. Hence as a fallback mechanism we can set
689 * the prev or default country code to the firmware.
691 /* TODO: Implement Fallback Mechanism */
695 void ath11k_reg_init(struct ath11k
*ar
)
697 ar
->hw
->wiphy
->regulatory_flags
= REGULATORY_WIPHY_SELF_MANAGED
;
698 ar
->hw
->wiphy
->reg_notifier
= ath11k_reg_notifier
;
701 void ath11k_reg_free(struct ath11k_base
*ab
)
705 for (i
= 0; i
< ab
->hw_params
.max_radios
; i
++) {
706 kfree(ab
->default_regd
[i
]);
707 kfree(ab
->new_regd
[i
]);