1 /* 2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: reg_build_chan_list.c 22 * This file defines the API to build master and current channel list. 23 */ 24 25 #include <wlan_cmn.h> 26 #include <reg_services_public_struct.h> 27 #include <wlan_objmgr_psoc_obj.h> 28 #include <wlan_objmgr_pdev_obj.h> 29 #include "reg_priv_objs.h" 30 #include "reg_utils.h" 31 #include "reg_callbacks.h" 32 #include "reg_services_common.h" 33 #include "reg_db.h" 34 #include "reg_db_parser.h" 35 #include "reg_offload_11d_scan.h" 36 #include <scheduler_api.h> 37 #include "reg_build_chan_list.h" 38 #include <qdf_platform.h> 39 #include <wlan_reg_services_api.h> 40 41 #define MAX_PWR_FCC_CHAN_12 8 42 #define MAX_PWR_FCC_CHAN_13 2 43 #define CHAN_144_CENT_FREQ 5720 44 45 /** 46 * reg_init_chan() - Initialize the channel list from the channel_map global 47 * list 48 * @dst_list: list to initialize 49 * @beg_enum: starting point in list(inclusive) 50 * @end_enum: ending point in list(inclusive) 51 * @dst_idx_adj: offset between channel_map and dst_list 52 * @soc_reg: soc private object for regulatory 53 * 54 * Return: none 55 */ 56 static void reg_init_chan(struct regulatory_channel *dst_list, 57 enum channel_enum beg_enum, 58 enum channel_enum end_enum, uint8_t dst_idx_adj, 59 struct wlan_regulatory_psoc_priv_obj *soc_reg) 60 { 61 enum channel_enum chan_enum; 62 uint8_t dst_idx; 63 64 for (chan_enum = beg_enum; chan_enum <= end_enum; chan_enum++) { 65 dst_idx = chan_enum - dst_idx_adj; 66 67 dst_list[dst_idx].chan_num = channel_map[chan_enum].chan_num; 68 dst_list[dst_idx].center_freq = 69 channel_map[chan_enum].center_freq; 70 dst_list[dst_idx].chan_flags = REGULATORY_CHAN_DISABLED; 71 dst_list[dst_idx].state = CHANNEL_STATE_DISABLE; 72 if (!soc_reg->retain_nol_across_regdmn_update) 73 dst_list[dst_idx].nol_chan = false; 74 } 75 } 76 77 static inline bool 78 reg_nol_and_history_not_set(struct regulatory_channel *chan) 79 { 80 return ((!chan->nol_chan) && (!chan->nol_history)); 81 } 82 83 bool reg_is_chan_disabled_and_not_nol(struct regulatory_channel *chan) 84 { 85 return (!reg_is_state_allowed(chan->state) && 86 (chan->chan_flags & REGULATORY_CHAN_DISABLED) && 87 reg_nol_and_history_not_set(chan)); 88 } 89 #ifdef CONFIG_BAND_6GHZ 90 static void reg_fill_psd_info(enum channel_enum chan_enum, 91 struct cur_reg_rule *reg_rule, 92 struct regulatory_channel *master_list) 93 { 94 master_list[chan_enum].psd_flag = reg_rule->psd_flag; 95 96 master_list[chan_enum].psd_eirp = reg_rule->psd_eirp; 97 } 98 99 /** 100 * reg_init_6ghz_master_chan() - Init 6 GHz channel list 101 * @dst_list: pointer to 6 GHz channel list 102 * @soc_reg: pointer to regulatory psoc private object. 103 * 104 * Return: None 105 */ 106 static void 107 reg_init_6ghz_master_chan(struct regulatory_channel *dst_list, 108 struct wlan_regulatory_psoc_priv_obj *soc_reg) 109 { 110 reg_init_chan(dst_list, MIN_6GHZ_CHANNEL, MAX_6GHZ_CHANNEL, 111 MIN_6GHZ_CHANNEL, soc_reg); 112 } 113 #else 114 static inline void reg_fill_psd_info(enum channel_enum chan_enum, 115 struct cur_reg_rule *reg_rule, 116 struct regulatory_channel *master_list) 117 { 118 } 119 120 static inline void 121 reg_init_6ghz_master_chan(struct regulatory_channel *dst_list, 122 struct wlan_regulatory_psoc_priv_obj *soc_reg) 123 { 124 } 125 #endif 126 127 /** 128 * reg_fill_channel_info() - Populate TX power, antenna gain, channel state, 129 * channel flags, min and max bandwidth to master channel list. 130 * @chan_enum: Channel enum. 131 * @reg_rule: Pointer to regulatory rule which has tx power and antenna gain. 132 * @master_list: Pointer to master channel list. 133 * @min_bw: minimum bandwidth to be used for given channel. 134 */ 135 static void reg_fill_channel_info(enum channel_enum chan_enum, 136 struct cur_reg_rule *reg_rule, 137 struct regulatory_channel *master_list, 138 uint16_t min_bw) 139 { 140 master_list[chan_enum].chan_flags &= ~REGULATORY_CHAN_DISABLED; 141 142 reg_fill_psd_info(chan_enum, reg_rule, master_list); 143 master_list[chan_enum].tx_power = reg_rule->reg_power; 144 master_list[chan_enum].ant_gain = reg_rule->ant_gain; 145 master_list[chan_enum].state = CHANNEL_STATE_ENABLE; 146 147 if (reg_rule->flags & REGULATORY_CHAN_NO_IR) { 148 master_list[chan_enum].chan_flags |= REGULATORY_CHAN_NO_IR; 149 master_list[chan_enum].state = CHANNEL_STATE_DFS; 150 } 151 152 if (reg_rule->flags & REGULATORY_CHAN_RADAR) { 153 master_list[chan_enum].chan_flags |= REGULATORY_CHAN_RADAR; 154 master_list[chan_enum].state = CHANNEL_STATE_DFS; 155 } 156 157 if (reg_rule->flags & REGULATORY_CHAN_INDOOR_ONLY) 158 master_list[chan_enum].chan_flags |= 159 REGULATORY_CHAN_INDOOR_ONLY; 160 161 if (reg_rule->flags & REGULATORY_CHAN_NO_OFDM) 162 master_list[chan_enum].chan_flags |= REGULATORY_CHAN_NO_OFDM; 163 164 master_list[chan_enum].min_bw = min_bw; 165 if (master_list[chan_enum].max_bw == 20) 166 master_list[chan_enum].max_bw = reg_rule->max_bw; 167 } 168 169 #ifdef CONFIG_BAND_6GHZ 170 /** 171 * reg_dis_chan_state_and_flags() - Disable the input channel state 172 * and chan_flags 173 * @state: Channel state 174 * @chan_flags: Channel flags 175 * 176 * Return: void 177 */ 178 static void reg_dis_chan_state_and_flags(enum channel_state *state, 179 uint32_t *chan_flags) 180 { 181 *state = CHANNEL_STATE_DISABLE; 182 *chan_flags |= REGULATORY_CHAN_DISABLED; 183 } 184 185 /** 186 * reg_populate_band_channels_ext_for_6g() - For all the valid regdb channels in 187 * the master channel list, find the regulatory rules and call 188 * reg_fill_channel_info() to populate master channel list with txpower, 189 * antennagain, BW info, etc. 190 * @start_idx: Start channel range in list 191 * @end_idx: End channel range in list 192 * @rule_start_ptr: Pointer to regulatory rules 193 * @num_reg_rules: Number of regulatory rules 194 * @min_reg_bw: Minimum regulatory bandwidth 195 * @mas_chan_list: Pointer to master channel list 196 */ 197 static void reg_populate_band_channels_ext_for_6g(uint16_t start_idx, 198 uint16_t end_idx, 199 struct cur_reg_rule *rule_start_ptr, 200 uint32_t num_reg_rules, 201 uint16_t min_reg_bw, 202 struct regulatory_channel *mas_chan_list) 203 { 204 struct cur_reg_rule *found_rule_ptr; 205 struct cur_reg_rule *cur_rule_ptr; 206 struct regulatory_channel; 207 uint32_t rule_num, bw; 208 uint16_t i, min_bw, max_bw; 209 210 for (i = start_idx; i <= end_idx; i++) { 211 found_rule_ptr = NULL; 212 213 max_bw = QDF_MIN((uint16_t)20, 214 channel_map[MIN_6GHZ_CHANNEL + i].max_bw); 215 min_bw = QDF_MAX(min_reg_bw, 216 channel_map[MIN_6GHZ_CHANNEL + i].min_bw); 217 218 if (channel_map[MIN_6GHZ_CHANNEL + i].chan_num == 219 INVALID_CHANNEL_NUM) 220 continue; 221 222 for (bw = max_bw; bw >= min_bw; bw = bw / 2) { 223 for (rule_num = 0, cur_rule_ptr = rule_start_ptr; 224 rule_num < num_reg_rules; 225 cur_rule_ptr++, rule_num++) { 226 if ((cur_rule_ptr->start_freq <= 227 mas_chan_list[i].center_freq - 228 bw / 2) && 229 (cur_rule_ptr->end_freq >= 230 mas_chan_list[i].center_freq + 231 bw / 2) && (min_bw <= bw)) { 232 found_rule_ptr = cur_rule_ptr; 233 break; 234 } 235 } 236 237 if (found_rule_ptr) 238 break; 239 } 240 241 if (found_rule_ptr) { 242 mas_chan_list[i].max_bw = bw; 243 reg_fill_channel_info(i, found_rule_ptr, 244 mas_chan_list, min_bw); 245 } 246 } 247 } 248 #else 249 static inline void 250 reg_populate_band_channels_ext_for_6g(enum channel_enum start_chan, 251 enum channel_enum end_chan, 252 struct cur_reg_rule *rule_start_ptr, 253 uint32_t num_reg_rules, 254 uint16_t min_reg_bw, 255 struct regulatory_channel *mas_chan_list) 256 { 257 } 258 #endif 259 260 /** 261 * reg_populate_band_channels() - For all the valid regdb channels in the master 262 * channel list, find the regulatory rules and call reg_fill_channel_info() to 263 * populate master channel list with txpower, antennagain, BW info, etc. 264 * @start_chan: Start channel enum. 265 * @end_chan: End channel enum. 266 * @rule_start_ptr: Pointer to regulatory rules. 267 * @num_reg_rules: Number of regulatory rules. 268 * @min_reg_bw: Minimum regulatory bandwidth. 269 * @mas_chan_list: Pointer to master channel list. 270 */ 271 static void reg_populate_band_channels(enum channel_enum start_chan, 272 enum channel_enum end_chan, 273 struct cur_reg_rule *rule_start_ptr, 274 uint32_t num_reg_rules, 275 uint16_t min_reg_bw, 276 struct regulatory_channel *mas_chan_list) 277 { 278 struct cur_reg_rule *found_rule_ptr; 279 struct cur_reg_rule *cur_rule_ptr; 280 struct regulatory_channel; 281 enum channel_enum chan_enum; 282 uint32_t rule_num, bw; 283 uint16_t max_bw; 284 uint16_t min_bw; 285 286 for (chan_enum = start_chan; chan_enum <= end_chan; chan_enum++) { 287 found_rule_ptr = NULL; 288 289 max_bw = QDF_MIN((uint16_t)20, channel_map[chan_enum].max_bw); 290 min_bw = QDF_MAX(min_reg_bw, channel_map[chan_enum].min_bw); 291 292 if (channel_map[chan_enum].chan_num == INVALID_CHANNEL_NUM) 293 continue; 294 295 for (bw = max_bw; bw >= min_bw; bw = bw / 2) { 296 for (rule_num = 0, cur_rule_ptr = rule_start_ptr; 297 rule_num < num_reg_rules; 298 cur_rule_ptr++, rule_num++) { 299 if ((cur_rule_ptr->start_freq <= 300 mas_chan_list[chan_enum].center_freq - 301 bw / 2) && 302 (cur_rule_ptr->end_freq >= 303 mas_chan_list[chan_enum].center_freq + 304 bw / 2) && (min_bw <= bw)) { 305 found_rule_ptr = cur_rule_ptr; 306 break; 307 } 308 } 309 310 if (found_rule_ptr) 311 break; 312 } 313 314 if (found_rule_ptr) { 315 mas_chan_list[chan_enum].max_bw = bw; 316 reg_fill_channel_info(chan_enum, found_rule_ptr, 317 mas_chan_list, min_bw); 318 /* Disable 2.4 Ghz channels that dont have 20 mhz bw */ 319 if (start_chan == MIN_24GHZ_CHANNEL && 320 mas_chan_list[chan_enum].max_bw < 20) { 321 mas_chan_list[chan_enum].chan_flags |= 322 REGULATORY_CHAN_DISABLED; 323 mas_chan_list[chan_enum].state = 324 CHANNEL_STATE_DISABLE; 325 } 326 } 327 } 328 } 329 330 /** 331 * reg_update_max_bw_per_rule() - Update max bandwidth value for given regrules. 332 * @num_reg_rules: Number of regulatory rules. 333 * @reg_rule_start: Pointer to regulatory rules. 334 * @max_bw: Maximum bandwidth 335 */ 336 static void reg_update_max_bw_per_rule(uint32_t num_reg_rules, 337 struct cur_reg_rule *reg_rule_start, 338 uint16_t max_bw) 339 { 340 uint32_t count; 341 342 for (count = 0; count < num_reg_rules; count++) 343 reg_rule_start[count].max_bw = 344 min(reg_rule_start[count].max_bw, max_bw); 345 } 346 347 #ifdef CONFIG_REG_CLIENT 348 /** 349 * reg_bw_floor() - Calculate floor of a given bandwidth. Find the nearest 350 * bandwidth, from the set = {5, 10, 20, 40, 80, 160, 320}, which is less 351 * than or equal to the given bandwidth. Any input bandwidth less than 5MHz 352 * is converted to 0. 353 * @in_bw: A positive bandwidth value 354 * 355 * Return: The floor of the given bandwidth. 356 */ 357 static uint16_t reg_bw_floor(uint16_t in_bw) 358 { 359 static const uint16_t chwidth_array[] = {5, 10, 20, 40, 80, 160, 320}; 360 int16_t i; 361 362 for (i = QDF_ARRAY_SIZE(chwidth_array) - 1; i >= 0; i--) { 363 if (in_bw >= chwidth_array[i]) 364 return chwidth_array[i]; 365 } 366 return 0; 367 } 368 369 /** 370 * reg_find_enhanced_bw() - Given two adjacent reg rules, it first finds the 371 * coalesced bandwidth limited by the country/regulatory domain bandwidth. Then 372 * it finds the nearest discrete bandwidth from the discrete 373 * set = {5, 10, 20, 40, 80, 160, 320} of bandwidths. 374 * @reg_rule_ptr: Pointer to reg rule 375 * @cur_idx: Current index to be considered 376 * @max_reg_bw: Maximum bandwidth of the country/regulatory domain 377 * 378 * Return: Return enhanced bandwidth of the coalesced band 379 */ 380 static uint16_t reg_find_enhanced_bw(struct cur_reg_rule *reg_rule_ptr, 381 uint32_t cur_idx, 382 uint16_t max_reg_bw) 383 { 384 uint16_t cur_rule_diff_freq; 385 uint16_t next_rule_diff_freq; 386 uint16_t new_bw; 387 uint16_t enhanced_bw; 388 389 cur_rule_diff_freq = reg_rule_ptr[cur_idx].end_freq - 390 reg_rule_ptr[cur_idx].start_freq; 391 next_rule_diff_freq = reg_rule_ptr[cur_idx + 1].end_freq - 392 reg_rule_ptr[cur_idx + 1].start_freq; 393 394 new_bw = QDF_MIN(max_reg_bw, cur_rule_diff_freq + next_rule_diff_freq); 395 enhanced_bw = reg_bw_floor(new_bw); 396 397 return enhanced_bw; 398 } 399 400 /** 401 * reg_do_auto_bw_correction() - Calculate and update the maximum bandwidth 402 * value. 403 * @num_reg_rules: Number of regulatory rules. 404 * @reg_rule_ptr: Pointer to regulatory rules. 405 * @max_bw: Maximum bandwidth 406 */ 407 static void reg_do_auto_bw_correction(uint32_t num_reg_rules, 408 struct cur_reg_rule *reg_rule_ptr, 409 uint16_t max_bw) 410 { 411 uint32_t count; 412 uint16_t enhanced_bw; 413 414 for (count = 0; count < num_reg_rules - 1; count++) { 415 if (reg_rule_ptr[count].end_freq == 416 reg_rule_ptr[count + 1].start_freq) { 417 enhanced_bw = reg_find_enhanced_bw(reg_rule_ptr, 418 count, 419 max_bw); 420 reg_rule_ptr[count].max_bw = enhanced_bw; 421 reg_rule_ptr[count + 1].max_bw = enhanced_bw; 422 } 423 } 424 } 425 #else 426 /** 427 * reg_do_auto_bw_correction() - Calculate and update the maximum bandwidth 428 * value. 429 * @num_reg_rules: Number of regulatory rules. 430 * @reg_rule_ptr: Pointer to regulatory rules. 431 * @max_bw: Maximum bandwidth 432 */ 433 static void reg_do_auto_bw_correction(uint32_t num_reg_rules, 434 struct cur_reg_rule *reg_rule_ptr, 435 uint16_t max_bw) 436 { 437 uint32_t count; 438 uint16_t new_bw; 439 440 for (count = 0; count < num_reg_rules - 1; count++) { 441 if (reg_rule_ptr[count].end_freq == 442 reg_rule_ptr[count + 1].start_freq) { 443 new_bw = QDF_MIN(max_bw, reg_rule_ptr[count].max_bw + 444 reg_rule_ptr[count + 1].max_bw); 445 reg_rule_ptr[count].max_bw = new_bw; 446 reg_rule_ptr[count + 1].max_bw = new_bw; 447 } 448 } 449 } 450 #endif 451 452 /** 453 * reg_modify_chan_list_for_dfs_channels() - disable the DFS channels if 454 * dfs_enable set to false. 455 * @chan_list: Pointer to regulatory channel list. 456 * @dfs_enabled: if false, then disable the DFS channels. 457 */ 458 static void reg_modify_chan_list_for_dfs_channels( 459 struct regulatory_channel *chan_list, bool dfs_enabled) 460 { 461 enum channel_enum chan_enum; 462 463 if (dfs_enabled) 464 return; 465 466 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 467 if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_RADAR) { 468 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 469 chan_list[chan_enum].chan_flags |= 470 REGULATORY_CHAN_DISABLED; 471 } 472 } 473 } 474 475 #if defined(CONFIG_BAND_6GHZ) && defined(CONFIG_REG_CLIENT) 476 /** 477 * reg_is_lpi_cli_supp_pwr_mode() - Check if the input supported power mode is a 478 * client LPI power mode 479 * 480 * @supp_pwr_mode: 6G supported power mode 481 * 482 * Return: bool 483 */ 484 static bool 485 reg_is_lpi_cli_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode) 486 { 487 return ((supp_pwr_mode == REG_CLI_DEF_LPI) || 488 (supp_pwr_mode == REG_CLI_SUB_LPI)); 489 } 490 491 /** 492 * reg_modify_super_chan_list_for_indoor_channels() - Disable the indoor 493 * channels in super channel list if indoor_chan_enabled flag is set to false. 494 * 495 * @pdev_priv_obj: Pointer to regulatory private pdev structure. 496 * @chn_idx: Channel index for which indoor channel needs to be disabled in 497 * super channel list. 498 * pwr_mode: Input power mode 499 * 500 * Return: None 501 */ 502 static void reg_modify_super_chan_list_for_indoor_channels( 503 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 504 uint16_t chn_idx, 505 enum supported_6g_pwr_types pwr_mode) 506 { 507 struct super_chan_info *super_chan_list; 508 509 if (!reg_is_lpi_cli_supp_pwr_mode(pwr_mode)) 510 return; 511 512 super_chan_list = pdev_priv_obj->super_chan_list; 513 514 if (!pdev_priv_obj->indoor_chan_enabled) { 515 if (!reg_is_chan_disabled( 516 super_chan_list[chn_idx].chan_flags_arr[pwr_mode], 517 super_chan_list[chn_idx].state_arr[pwr_mode])) { 518 super_chan_list[chn_idx].chan_flags_arr[pwr_mode] |= 519 REGULATORY_CHAN_NO_IR; 520 super_chan_list[chn_idx].state_arr[pwr_mode] = 521 CHANNEL_STATE_DFS; 522 } 523 } 524 525 if (pdev_priv_obj->force_ssc_disable_indoor_channel && 526 pdev_priv_obj->sap_state) { 527 if (!reg_is_chan_disabled( 528 super_chan_list[chn_idx].chan_flags_arr[pwr_mode], 529 super_chan_list[chn_idx].state_arr[pwr_mode])) { 530 super_chan_list[chn_idx].chan_flags_arr[pwr_mode] |= 531 REGULATORY_CHAN_NO_IR; 532 super_chan_list[chn_idx].state_arr[pwr_mode] = 533 CHANNEL_STATE_DISABLE; 534 } 535 } 536 } 537 538 static void 539 reg_dis_6g_chan_in_super_chan_list(struct wlan_objmgr_pdev *pdev, 540 struct super_chan_info *chan_info, 541 enum supported_6g_pwr_types pwr_type) 542 { 543 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 544 uint32_t band_bitmap; 545 546 if (!pdev) { 547 reg_debug("pdev is NULL"); 548 return; 549 } 550 551 if (!chan_info) { 552 reg_debug("chan_info is NULL"); 553 return; 554 } 555 556 pdev_priv_obj = reg_get_pdev_obj(pdev); 557 band_bitmap = pdev_priv_obj->band_capability; 558 559 if (!(band_bitmap & BIT(REG_BAND_6G))) 560 reg_dis_chan_state_and_flags( 561 &chan_info->state_arr[pwr_type], 562 &chan_info->chan_flags_arr[pwr_type]); 563 } 564 #else 565 static inline bool 566 reg_is_lpi_cli_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode) 567 { 568 return false; 569 } 570 571 static inline void 572 reg_modify_super_chan_list_for_indoor_channels( 573 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 574 uint16_t chn_idx, 575 enum supported_6g_pwr_types pwr_mode) 576 { 577 } 578 579 static inline void 580 reg_dis_6g_chan_in_super_chan_list(struct wlan_objmgr_pdev *pdev, 581 struct super_chan_info *chan_info, 582 enum supported_6g_pwr_types pwr_type) 583 { 584 } 585 #endif /* CONFIG_BAND_6GHZ && CONFIG_REG_CLIENT */ 586 587 /** 588 * reg_modify_chan_list_for_indoor_channels() - Disable the indoor channels if 589 * indoor_chan_enabled flag is set to false. 590 * @pdev_priv_obj: Pointer to regulatory private pdev structure. 591 */ 592 #ifdef CONFIG_REG_CLIENT 593 static void reg_modify_chan_list_for_indoor_channels( 594 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 595 { 596 enum channel_enum chan_enum; 597 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list; 598 599 if (!pdev_priv_obj->indoor_chan_enabled) { 600 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 601 if (!(REGULATORY_CHAN_DISABLED & 602 chan_list[chan_enum].chan_flags) && 603 (REGULATORY_CHAN_INDOOR_ONLY & 604 chan_list[chan_enum].chan_flags)) { 605 chan_list[chan_enum].state = 606 CHANNEL_STATE_DFS; 607 chan_list[chan_enum].chan_flags |= 608 REGULATORY_CHAN_NO_IR; 609 } 610 } 611 } 612 if (pdev_priv_obj->force_ssc_disable_indoor_channel && 613 pdev_priv_obj->sap_state) { 614 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 615 if (!(REGULATORY_CHAN_DISABLED & 616 chan_list[chan_enum].chan_flags) && 617 (REGULATORY_CHAN_INDOOR_ONLY & 618 chan_list[chan_enum].chan_flags)) { 619 chan_list[chan_enum].state = 620 CHANNEL_STATE_DISABLE; 621 chan_list[chan_enum].chan_flags |= 622 REGULATORY_CHAN_DISABLED; 623 } 624 } 625 } 626 } 627 628 /** 629 *reg_modify_chan_list_for_indoor_concurrency() - Enable/Disable the indoor 630 *channels for SAP operation based on the indoor concurrency list 631 * 632 * @pdev_priv_obj: Pointer to regulatory private pdev structure. 633 */ 634 static void reg_modify_chan_list_for_indoor_concurrency( 635 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 636 { 637 struct indoor_concurrency_list *indoor_list = NULL; 638 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list; 639 enum channel_enum chan, min_enum, max_enum; 640 uint8_t i; 641 642 if (pdev_priv_obj->indoor_chan_enabled || 643 !pdev_priv_obj->sta_sap_scc_on_indoor_channel) 644 return; 645 646 indoor_list = pdev_priv_obj->indoor_list; 647 648 if (!indoor_list) 649 return; 650 651 for (i = 0; i < MAX_INDOOR_LIST_SIZE; i++, indoor_list++) { 652 if (indoor_list->freq == 0 && 653 indoor_list->vdev_id == INVALID_VDEV_ID) 654 continue; 655 656 if (!indoor_list->chan_range) { 657 min_enum = 658 reg_get_chan_enum_for_freq(indoor_list->freq); 659 max_enum = min_enum; 660 } else { 661 min_enum = 662 reg_get_chan_enum_for_freq( 663 indoor_list->chan_range->start_freq); 664 max_enum = 665 reg_get_chan_enum_for_freq( 666 indoor_list->chan_range->end_freq); 667 } 668 669 if (min_enum == NUM_CHANNELS || max_enum == NUM_CHANNELS) 670 continue; 671 672 for (chan = min_enum; chan <= max_enum; chan++) { 673 if (chan_list[chan].chan_flags & REGULATORY_CHAN_INDOOR_ONLY && 674 !(chan_list[chan].chan_flags & REGULATORY_CHAN_DISABLED)) { 675 chan_list[chan].chan_flags &= ~REGULATORY_CHAN_NO_IR; 676 } 677 } 678 } 679 } 680 681 #else 682 static void reg_modify_chan_list_for_indoor_channels( 683 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 684 { 685 } 686 687 static void reg_modify_chan_list_for_indoor_concurrency( 688 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 689 { 690 } 691 #endif 692 693 #ifdef CONFIG_BAND_6GHZ 694 static void reg_modify_chan_list_for_band_6G( 695 struct regulatory_channel *chan_list) 696 { 697 enum channel_enum chan_enum; 698 699 reg_debug("disabling 6G"); 700 for (chan_enum = MIN_6GHZ_CHANNEL; 701 chan_enum <= MAX_6GHZ_CHANNEL; chan_enum++) { 702 chan_list[chan_enum].chan_flags |= 703 REGULATORY_CHAN_DISABLED; 704 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 705 } 706 } 707 #else 708 static inline void reg_modify_chan_list_for_band_6G( 709 struct regulatory_channel *chan_list) 710 { 711 } 712 #endif 713 714 /** 715 * reg_modify_chan_list_for_band() - Based on the input band bitmap, either 716 * disable 2GHz, 5GHz, or 6GHz channels. 717 * @chan_list: Pointer to regulatory channel list. 718 * @band_bitmap: Input bitmap of reg_wifi_band values. 719 */ 720 static void reg_modify_chan_list_for_band(struct regulatory_channel *chan_list, 721 uint32_t band_bitmap) 722 { 723 enum channel_enum chan_enum; 724 725 if (!band_bitmap) 726 return; 727 728 if (!(band_bitmap & BIT(REG_BAND_5G))) { 729 reg_debug("disabling 5G"); 730 for (chan_enum = MIN_5GHZ_CHANNEL; 731 chan_enum <= MAX_5GHZ_CHANNEL; chan_enum++) { 732 chan_list[chan_enum].chan_flags |= 733 REGULATORY_CHAN_DISABLED; 734 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 735 } 736 } 737 738 if (!(band_bitmap & BIT(REG_BAND_2G))) { 739 reg_debug("disabling 2G"); 740 for (chan_enum = MIN_24GHZ_CHANNEL; 741 chan_enum <= MAX_24GHZ_CHANNEL; chan_enum++) { 742 chan_list[chan_enum].chan_flags |= 743 REGULATORY_CHAN_DISABLED; 744 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 745 } 746 } 747 748 if (!(band_bitmap & BIT(REG_BAND_6G))) 749 reg_modify_chan_list_for_band_6G(chan_list); 750 751 } 752 753 #ifdef CONFIG_REG_CLIENT 754 /** 755 * reg_get_tx_power_for_fcc_channel() - Set FCC txpower received from firmware 756 * @chan_list: Regulatory channel to be updated 757 * @fcc_rule: Pointer to current fcc rule array 758 * 759 * Return: true if regulatory channel is present in current fcc rules array 760 */ 761 static bool reg_get_tx_power_for_fcc_channel( 762 struct regulatory_channel *chan_list, 763 struct cur_fcc_rule *fcc_rule) 764 { 765 int index = 0; 766 767 if (!chan_list || !fcc_rule) 768 return false; 769 770 for (index = 0; index < MAX_NUM_FCC_RULES; index++) { 771 if (chan_list->center_freq == fcc_rule[index].center_freq) { 772 chan_list->tx_power = fcc_rule[index].tx_power; 773 return true; 774 } 775 } 776 777 return false; 778 } 779 780 /** 781 * reg_modify_chan_list_for_fcc_channel() - Set maximum FCC txpower for channel 782 * 12 and 13 if set_fcc_channel flag is set to true. 783 * @pdev_priv_obj: Pointer to pdev private object. 784 */ 785 static void reg_modify_chan_list_for_fcc_channel( 786 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 787 { 788 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list; 789 struct cur_fcc_rule *fcc_rules = pdev_priv_obj->fcc_rules_ptr; 790 791 if (!pdev_priv_obj->set_fcc_channel) 792 return; 793 794 if (!chan_list || !fcc_rules) 795 return; 796 797 if (!reg_get_tx_power_for_fcc_channel( 798 &chan_list[CHAN_ENUM_2467], fcc_rules)) { 799 chan_list[CHAN_ENUM_2467].tx_power = MAX_PWR_FCC_CHAN_12; 800 reg_debug("Channel 12 not found from BDF"); 801 } 802 if (!reg_get_tx_power_for_fcc_channel( 803 &chan_list[CHAN_ENUM_2472], fcc_rules)) { 804 chan_list[CHAN_ENUM_2472].tx_power = MAX_PWR_FCC_CHAN_13; 805 reg_debug("Channel 13 not found from BDF"); 806 } 807 reg_debug("Channel 12 tx_power = %d, 13 tx_power = %d", 808 chan_list[CHAN_ENUM_2467].tx_power, 809 chan_list[CHAN_ENUM_2472].tx_power); 810 } 811 #else 812 static inline void reg_modify_chan_list_for_fcc_channel( 813 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 814 { 815 } 816 #endif 817 818 /** 819 * reg_modify_chan_list_for_chan_144() - Disable channel 144 if en_chan_144 flag 820 * is set to false. 821 * @chan_list: Pointer to regulatory channel list. 822 * @en_chan_144: if false, then disable channel 144. 823 */ 824 static void reg_modify_chan_list_for_chan_144( 825 struct regulatory_channel *chan_list, bool en_chan_144) 826 { 827 enum channel_enum chan_enum; 828 829 if (en_chan_144) 830 return; 831 832 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 833 if (chan_list[chan_enum].center_freq == CHAN_144_CENT_FREQ) { 834 chan_list[chan_enum].chan_flags |= 835 REGULATORY_CHAN_DISABLED; 836 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 837 } 838 } 839 } 840 841 /** 842 * reg_modify_chan_list_for_nol_list() - Disable the channel if nol_chan flag is 843 * set. 844 * @chan_list: Pointer to regulatory channel list. 845 */ 846 static void reg_modify_chan_list_for_nol_list( 847 struct regulatory_channel *chan_list) 848 { 849 enum channel_enum chan_enum; 850 851 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 852 if (chan_list[chan_enum].nol_chan) { 853 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 854 chan_list[chan_enum].chan_flags |= 855 REGULATORY_CHAN_DISABLED; 856 } 857 } 858 } 859 860 #ifdef CONFIG_REG_CLIENT 861 /** 862 * reg_modify_chan_list_for_static_puncture() - Disable the channel if 863 * static_puncture is set. 864 * @chan_list: Pointer to regulatory channel list. 865 */ 866 static void 867 reg_modify_chan_list_for_static_puncture(struct regulatory_channel *chan_list) 868 { 869 enum channel_enum chan_enum; 870 871 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 872 if (chan_list[chan_enum].is_static_punctured) { 873 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 874 chan_list[chan_enum].chan_flags |= 875 REGULATORY_CHAN_DISABLED; 876 } 877 } 878 } 879 #else 880 static void 881 reg_modify_chan_list_for_static_puncture(struct regulatory_channel *chan_list) 882 { 883 } 884 #endif 885 886 /** 887 * reg_find_low_limit_chan_enum() - Find low limit 2G and 5G channel enums. 888 * @chan_list: Pointer to regulatory channel list. 889 * @low_freq: low limit frequency. 890 * @low_limit: pointer to output low limit enum. 891 * 892 * Return: None 893 */ 894 static void reg_find_low_limit_chan_enum( 895 struct regulatory_channel *chan_list, qdf_freq_t low_freq, 896 uint32_t *low_limit) 897 { 898 enum channel_enum chan_enum; 899 uint16_t min_bw; 900 uint16_t max_bw; 901 qdf_freq_t center_freq; 902 903 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 904 min_bw = chan_list[chan_enum].min_bw; 905 max_bw = chan_list[chan_enum].max_bw; 906 center_freq = chan_list[chan_enum].center_freq; 907 908 if ((center_freq - min_bw / 2) >= low_freq) { 909 if ((center_freq - max_bw / 2) < low_freq) { 910 if (max_bw <= 20) 911 max_bw = ((center_freq - low_freq) * 2); 912 if (max_bw < min_bw) 913 max_bw = min_bw; 914 chan_list[chan_enum].max_bw = max_bw; 915 } 916 *low_limit = chan_enum; 917 break; 918 } 919 } 920 } 921 922 /** 923 * reg_find_high_limit_chan_enum() - Find high limit 2G and 5G channel enums. 924 * @chan_list: Pointer to regulatory channel list. 925 * @high_freq: high limit frequency. 926 * @high_limit: pointer to output high limit enum. 927 * 928 * Return: None 929 */ 930 static void reg_find_high_limit_chan_enum( 931 struct regulatory_channel *chan_list, 932 qdf_freq_t high_freq, 933 uint32_t *high_limit) 934 { 935 enum channel_enum chan_enum; 936 uint16_t min_bw; 937 uint16_t max_bw; 938 qdf_freq_t center_freq; 939 940 for (chan_enum = NUM_CHANNELS - 1; chan_enum >= 0; chan_enum--) { 941 min_bw = chan_list[chan_enum].min_bw; 942 max_bw = chan_list[chan_enum].max_bw; 943 center_freq = chan_list[chan_enum].center_freq; 944 945 if (center_freq + min_bw / 2 <= high_freq) { 946 if ((center_freq + max_bw / 2) > high_freq) { 947 if (max_bw <= 20) 948 max_bw = ((high_freq - 949 center_freq) * 2); 950 if (max_bw < min_bw) 951 max_bw = min_bw; 952 chan_list[chan_enum].max_bw = max_bw; 953 } 954 *high_limit = chan_enum; 955 break; 956 } 957 958 if (chan_enum == 0) 959 break; 960 } 961 } 962 963 #ifdef CONFIG_AFC_SUPPORT 964 /** 965 * reg_modify_chan_list_for_outdoor() - Set the channel flag for the 966 * enabled SP channels as REGULATORY_CHAN_AFC_NOT_DONE. 967 * @pdev_priv_obj: Regulatory pdev private object. 968 * 969 * Return: void 970 */ 971 static void 972 reg_modify_chan_list_for_outdoor(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 973 { 974 struct regulatory_channel *sp_chan_list; 975 int i; 976 977 sp_chan_list = pdev_priv_obj->mas_chan_list_6g_ap[REG_STANDARD_POWER_AP]; 978 if (pdev_priv_obj->reg_afc_dev_deployment_type != AFC_DEPLOYMENT_OUTDOOR) 979 return; 980 981 if (pdev_priv_obj->is_6g_afc_power_event_received) 982 return; 983 984 if (!pdev_priv_obj->is_6g_channel_list_populated) 985 return; 986 987 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) { 988 if (sp_chan_list[i].state == CHANNEL_STATE_ENABLE) 989 sp_chan_list[i].chan_flags |= REGULATORY_CHAN_AFC_NOT_DONE; 990 } 991 } 992 #else 993 static inline void 994 reg_modify_chan_list_for_outdoor(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 995 { 996 } 997 #endif 998 999 /** 1000 * reg_modify_chan_list_for_freq_range() - Modify channel list for the given low 1001 * and high frequency range. 1002 * @chan_list: Pointer to regulatory channel list. 1003 * @low_freq_2g: Low frequency 2G. 1004 * @high_freq_2g: High frequency 2G. 1005 * @low_freq_5g: Low frequency 5G. 1006 * @high_freq_5g: High frequency 5G. 1007 * 1008 * Return: None 1009 */ 1010 static void 1011 reg_modify_chan_list_for_freq_range(struct regulatory_channel *chan_list, 1012 qdf_freq_t low_freq_2g, 1013 qdf_freq_t high_freq_2g, 1014 qdf_freq_t low_freq_5g, 1015 qdf_freq_t high_freq_5g) 1016 { 1017 uint32_t low_limit_2g = NUM_CHANNELS; 1018 uint32_t high_limit_2g = NUM_CHANNELS; 1019 uint32_t low_limit_5g = NUM_CHANNELS; 1020 uint32_t high_limit_5g = NUM_CHANNELS; 1021 enum channel_enum chan_enum; 1022 bool chan_in_range; 1023 1024 reg_find_low_limit_chan_enum(chan_list, low_freq_2g, &low_limit_2g); 1025 reg_find_low_limit_chan_enum(chan_list, low_freq_5g, &low_limit_5g); 1026 reg_find_high_limit_chan_enum(chan_list, high_freq_2g, &high_limit_2g); 1027 reg_find_high_limit_chan_enum(chan_list, high_freq_5g, &high_limit_5g); 1028 1029 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 1030 chan_in_range = false; 1031 if ((low_limit_2g <= chan_enum) && 1032 (high_limit_2g >= chan_enum) && 1033 (low_limit_2g != NUM_CHANNELS) && 1034 (high_limit_2g != NUM_CHANNELS)) 1035 chan_in_range = true; 1036 1037 if ((low_limit_5g <= chan_enum) && 1038 (high_limit_5g >= chan_enum) && 1039 (low_limit_5g != NUM_CHANNELS) && 1040 (high_limit_5g != NUM_CHANNELS)) 1041 chan_in_range = true; 1042 1043 if (!chan_in_range) { 1044 chan_list[chan_enum].chan_flags |= 1045 REGULATORY_CHAN_DISABLED; 1046 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 1047 } 1048 } 1049 } 1050 1051 #ifdef CONFIG_BAND_6GHZ 1052 /** 1053 * reg_propagate_6g_mas_channel_list() - Copy master chan list from PSOC to PDEV 1054 * @pdev_priv_obj: Pointer to pdev 1055 * @mas_chan_params: Master channel parameters 1056 * 1057 * Return: None 1058 */ 1059 static void reg_propagate_6g_mas_channel_list( 1060 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 1061 struct mas_chan_params *mas_chan_params) 1062 { 1063 uint8_t i, j; 1064 struct regulatory_channel *src_6g_chan, *dst_6g_chan; 1065 uint32_t size_of_6g_chan_list = 1066 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel); 1067 1068 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 1069 qdf_mem_copy(pdev_priv_obj->mas_chan_list_6g_ap[i], 1070 mas_chan_params->mas_chan_list_6g_ap[i], 1071 size_of_6g_chan_list); 1072 1073 for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) { 1074 dst_6g_chan = 1075 pdev_priv_obj->mas_chan_list_6g_client[i][j]; 1076 src_6g_chan = 1077 mas_chan_params->mas_chan_list_6g_client[i][j]; 1078 qdf_mem_copy(dst_6g_chan, src_6g_chan, 1079 size_of_6g_chan_list); 1080 } 1081 } 1082 1083 pdev_priv_obj->reg_cur_6g_client_mobility_type = 1084 mas_chan_params->client_type; 1085 pdev_priv_obj->reg_target_client_type = 1086 mas_chan_params->client_type; 1087 pdev_priv_obj->reg_rnr_tpe_usable = mas_chan_params->rnr_tpe_usable; 1088 pdev_priv_obj->reg_unspecified_ap_usable = 1089 mas_chan_params->unspecified_ap_usable; 1090 pdev_priv_obj->is_6g_channel_list_populated = 1091 mas_chan_params->is_6g_channel_list_populated; 1092 pdev_priv_obj->reg_6g_superid = 1093 mas_chan_params->reg_6g_superid; 1094 pdev_priv_obj->reg_6g_thresh_priority_freq = 1095 mas_chan_params->reg_6g_thresh_priority_freq; 1096 reg_set_ap_pwr_type(pdev_priv_obj); 1097 } 1098 1099 #ifdef CONFIG_AFC_SUPPORT 1100 void reg_set_ap_pwr_type(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 1101 { 1102 uint8_t *num_rules = pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules; 1103 1104 if (pdev_priv_obj->reg_afc_dev_deployment_type == 1105 AFC_DEPLOYMENT_OUTDOOR) { 1106 if (num_rules[REG_VERY_LOW_POWER_AP]) 1107 pdev_priv_obj->reg_cur_6g_ap_pwr_type = 1108 REG_VERY_LOW_POWER_AP; 1109 else 1110 pdev_priv_obj->reg_cur_6g_ap_pwr_type = 1111 REG_STANDARD_POWER_AP; 1112 } else { 1113 if (num_rules[REG_INDOOR_AP]) 1114 pdev_priv_obj->reg_cur_6g_ap_pwr_type = 1115 REG_INDOOR_AP; 1116 else if (num_rules[REG_VERY_LOW_POWER_AP]) 1117 pdev_priv_obj->reg_cur_6g_ap_pwr_type = 1118 REG_VERY_LOW_POWER_AP; 1119 else 1120 pdev_priv_obj->reg_cur_6g_ap_pwr_type = 1121 REG_INDOOR_AP; 1122 } 1123 } 1124 #else 1125 void reg_set_ap_pwr_type(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 1126 { 1127 pdev_priv_obj->reg_cur_6g_ap_pwr_type = REG_INDOOR_AP; 1128 } 1129 #endif /* CONFIG_AFC_SUPPORT */ 1130 #else 1131 static inline void reg_propagate_6g_mas_channel_list( 1132 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 1133 struct mas_chan_params *mas_chan_params) 1134 { 1135 } 1136 #endif /* CONFIG_BAND_6GHZ */ 1137 1138 void reg_init_pdev_mas_chan_list( 1139 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 1140 struct mas_chan_params *mas_chan_params) 1141 { 1142 qdf_mem_copy(pdev_priv_obj->mas_chan_list, 1143 mas_chan_params->mas_chan_list, 1144 NUM_CHANNELS * sizeof(struct regulatory_channel)); 1145 1146 reg_propagate_6g_mas_channel_list(pdev_priv_obj, mas_chan_params); 1147 1148 pdev_priv_obj->dfs_region = mas_chan_params->dfs_region; 1149 1150 pdev_priv_obj->phybitmap = mas_chan_params->phybitmap; 1151 1152 pdev_priv_obj->reg_dmn_pair = mas_chan_params->reg_dmn_pair; 1153 pdev_priv_obj->ctry_code = mas_chan_params->ctry_code; 1154 1155 pdev_priv_obj->def_region_domain = mas_chan_params->reg_dmn_pair; 1156 pdev_priv_obj->def_country_code = mas_chan_params->ctry_code; 1157 qdf_mem_copy(pdev_priv_obj->default_country, 1158 mas_chan_params->default_country, REG_ALPHA2_LEN + 1); 1159 1160 qdf_mem_copy(pdev_priv_obj->current_country, 1161 mas_chan_params->current_country, REG_ALPHA2_LEN + 1); 1162 } 1163 1164 /** 1165 * reg_modify_chan_list_for_cached_channels() - If num_cache_channels are 1166 * non-zero, then disable the pdev channels which is given in 1167 * cache_disable_chan_list. 1168 * @pdev_priv_obj: Pointer to regulatory pdev private object. 1169 */ 1170 #ifdef DISABLE_CHANNEL_LIST 1171 static void reg_modify_chan_list_for_cached_channels( 1172 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 1173 { 1174 uint32_t i, j; 1175 uint32_t num_cache_channels = pdev_priv_obj->num_cache_channels; 1176 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list; 1177 struct regulatory_channel *cache_chan_list = 1178 pdev_priv_obj->cache_disable_chan_list; 1179 1180 if (!num_cache_channels) 1181 return; 1182 1183 if (pdev_priv_obj->disable_cached_channels) { 1184 for (i = 0; i < num_cache_channels; i++) 1185 for (j = 0; j < NUM_CHANNELS; j++) 1186 if (cache_chan_list[i].center_freq == 1187 chan_list[j].center_freq) { 1188 chan_list[j].state = 1189 CHANNEL_STATE_DISABLE; 1190 chan_list[j].chan_flags |= 1191 REGULATORY_CHAN_DISABLED; 1192 } 1193 } 1194 } 1195 #else 1196 static void reg_modify_chan_list_for_cached_channels( 1197 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 1198 { 1199 } 1200 #endif 1201 1202 #ifdef CONFIG_REG_CLIENT 1203 /** 1204 * reg_modify_chan_list_for_srd_channels() - Modify SRD channels in ETSI13 1205 * @pdev: Pointer to pdev object 1206 * @chan_list: Current channel list 1207 * 1208 * This function converts SRD channels to passive in ETSI13 regulatory domain 1209 * when enable_srd_chan_in_master_mode is not set. 1210 */ 1211 static void 1212 reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev, 1213 struct regulatory_channel *chan_list) 1214 { 1215 enum channel_enum chan_enum; 1216 1217 if (!reg_is_etsi13_regdmn(pdev)) 1218 return; 1219 1220 if (reg_is_etsi13_srd_chan_allowed_master_mode(pdev)) 1221 return; 1222 1223 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 1224 if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_DISABLED) 1225 continue; 1226 1227 if (reg_is_etsi13_srd_chan_for_freq( 1228 pdev, 1229 chan_list[chan_enum].center_freq)) { 1230 chan_list[chan_enum].state = 1231 CHANNEL_STATE_DFS; 1232 chan_list[chan_enum].chan_flags |= 1233 REGULATORY_CHAN_NO_IR; 1234 } 1235 } 1236 } 1237 #else 1238 static inline void 1239 reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev, 1240 struct regulatory_channel *chan_list) 1241 { 1242 } 1243 #endif 1244 1245 #ifdef CONFIG_REG_CLIENT 1246 1247 /** 1248 * reg_is_disabling_5dot9_needed() - Checks if 5.9GHz channels should 1249 * be disabled. 1250 * @psoc: Pointer to psoc object 1251 * 1252 * This function checks only if F/W has enabled the BDF bit for 5.9GHz 1253 * channels for AP target and both the BDF bit as well as if offload is 1254 * enabled for STA target. 1255 */ 1256 static inline bool 1257 reg_is_disabling_5dot9_needed(struct wlan_objmgr_psoc *psoc) 1258 { 1259 return (!reg_is_5dot9_ghz_supported(psoc) || 1260 !reg_is_regdb_offloaded(psoc)); 1261 } 1262 #else 1263 static inline bool 1264 reg_is_disabling_5dot9_needed(struct wlan_objmgr_psoc *psoc) 1265 { 1266 return (!reg_is_5dot9_ghz_supported(psoc)); 1267 } 1268 #endif 1269 1270 /** 1271 * reg_modify_chan_list_for_5dot9_ghz_channels() - Modify 5.9 GHz channels 1272 * in FCC 1273 * @pdev: Pointer to pdev object 1274 * @chan_list: Current channel list 1275 * 1276 * This function disables 5.9 GHz channels if service bit 1277 * wmi_service_5dot9_ghz_support is not set or the reg db is not offloaded 1278 * to FW. If service bit is set but ini enable_5dot9_ghz_chan_in_master_mode 1279 * is not set, it converts these channels to passive in FCC regulatory domain. 1280 * If both service bit and ini are set, the channels remain enabled. 1281 */ 1282 static void 1283 reg_modify_chan_list_for_5dot9_ghz_channels(struct wlan_objmgr_pdev *pdev, 1284 struct regulatory_channel 1285 *chan_list) 1286 { 1287 enum channel_enum chan_enum; 1288 struct wlan_objmgr_psoc *psoc; 1289 1290 psoc = wlan_pdev_get_psoc(pdev); 1291 1292 if (!reg_is_fcc_regdmn(pdev)) 1293 return; 1294 1295 if (reg_is_disabling_5dot9_needed(psoc)) { 1296 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 1297 if (reg_is_5dot9_ghz_freq(pdev, chan_list[chan_enum]. 1298 center_freq)) { 1299 chan_list[chan_enum].state = 1300 CHANNEL_STATE_DISABLE; 1301 chan_list[chan_enum].chan_flags = 1302 REGULATORY_CHAN_DISABLED; 1303 } 1304 } 1305 return; 1306 } 1307 1308 if (reg_is_5dot9_ghz_chan_allowed_master_mode(pdev)) 1309 return; 1310 1311 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 1312 if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_DISABLED) 1313 continue; 1314 1315 if (reg_is_5dot9_ghz_freq(pdev, 1316 chan_list[chan_enum].center_freq)) { 1317 chan_list[chan_enum].state = 1318 CHANNEL_STATE_DFS; 1319 chan_list[chan_enum].chan_flags |= 1320 REGULATORY_CHAN_NO_IR; 1321 } 1322 } 1323 } 1324 1325 #if defined(CONFIG_BAND_6GHZ) 1326 /** 1327 * reg_modify_chan_list_for_6g_edge_channels() - Modify 6 GHz edge channels 1328 * 1329 * @pdev: Pointer to pdev object 1330 * @chan_list: Current channel list 1331 * 1332 * This function disables lower 6G edge channel (5935MHz) if service bit 1333 * wmi_service_lower_6g_edge_ch_supp is not set. If service bit is set 1334 * the channels remain enabled. It disables upper 6G edge channel (7115MHz) 1335 * if the service bit wmi_service_disable_upper_6g_edge_ch_supp is set, it 1336 * is enabled by default. 1337 * 1338 */ 1339 static void 1340 reg_modify_chan_list_for_6g_edge_channels(struct wlan_objmgr_pdev *pdev, 1341 struct regulatory_channel 1342 *chan_list) 1343 { 1344 struct wlan_objmgr_psoc *psoc; 1345 1346 psoc = wlan_pdev_get_psoc(pdev); 1347 1348 if (!reg_is_lower_6g_edge_ch_supp(psoc)) { 1349 chan_list[CHAN_ENUM_5935].state = CHANNEL_STATE_DISABLE; 1350 chan_list[CHAN_ENUM_5935].chan_flags |= 1351 REGULATORY_CHAN_DISABLED; 1352 } 1353 1354 if (reg_is_upper_6g_edge_ch_disabled(psoc)) { 1355 chan_list[CHAN_ENUM_7115].state = CHANNEL_STATE_DISABLE; 1356 chan_list[CHAN_ENUM_7115].chan_flags |= 1357 REGULATORY_CHAN_DISABLED; 1358 } 1359 } 1360 #else 1361 static inline void 1362 reg_modify_chan_list_for_6g_edge_channels(struct wlan_objmgr_pdev *pdev, 1363 struct regulatory_channel 1364 *chan_list) 1365 { 1366 } 1367 #endif 1368 1369 #ifdef DISABLE_UNII_SHARED_BANDS 1370 /** 1371 * reg_is_reg_unii_band_1_set() - Check UNII bitmap 1372 * @unii_bitmap: 5G UNII band bitmap 1373 * 1374 * This function checks the input bitmap to disable UNII-1 band channels. 1375 * 1376 * Return: Return true if UNII-1 channels need to be disabled, 1377 * else return false. 1378 */ 1379 static bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap) 1380 { 1381 return !!(unii_bitmap & BIT(REG_UNII_BAND_1)); 1382 } 1383 1384 /** 1385 * reg_is_reg_unii_band_2a_set() - Check UNII bitmap 1386 * @unii_bitmap: 5G UNII band bitmap 1387 * 1388 * This function checks the input bitmap to disable UNII-2A band channels. 1389 * 1390 * Return: Return true if UNII-2A channels need to be disabled, 1391 * else return false. 1392 */ 1393 static bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap) 1394 { 1395 return !!(unii_bitmap & BIT(REG_UNII_BAND_2A)); 1396 } 1397 1398 /** 1399 * reg_is_5g_enum() - Check if channel enum is a 5G channel enum 1400 * @chan_enum: channel enum 1401 * 1402 * Return: Return true if the input channel enum is 5G, else return false. 1403 */ 1404 static bool reg_is_5g_enum(enum channel_enum chan_enum) 1405 { 1406 return (chan_enum >= MIN_5GHZ_CHANNEL && chan_enum <= MAX_5GHZ_CHANNEL); 1407 } 1408 1409 /** 1410 * reg_remove_unii_chan_from_chan_list() - Remove UNII band channels 1411 * @chan_list: Pointer to current channel list 1412 * @start_enum: starting enum value 1413 * @end_enum: ending enum value 1414 * 1415 * Remove channels in a unii band based in on the input start_enum and end_enum. 1416 * Disable the state and flags. Set disable_coex flag to true. 1417 * 1418 * return: void. 1419 */ 1420 static void 1421 reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list, 1422 enum channel_enum start_enum, 1423 enum channel_enum end_enum) 1424 { 1425 enum channel_enum chan_enum; 1426 1427 if (!(reg_is_5g_enum(start_enum) && reg_is_5g_enum(end_enum))) { 1428 reg_err_rl("start_enum or end_enum is invalid"); 1429 return; 1430 } 1431 1432 for (chan_enum = start_enum; chan_enum <= end_enum; chan_enum++) { 1433 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 1434 chan_list[chan_enum].chan_flags |= REGULATORY_CHAN_DISABLED; 1435 } 1436 } 1437 1438 /** 1439 * reg_modify_disable_chan_list_for_unii1_and_unii2a() - Disable UNII-1 and 1440 * UNII2A band 1441 * @pdev_priv_obj: Pointer to pdev private object 1442 * 1443 * This function disables the UNII-1 and UNII-2A band channels 1444 * based on input unii_5g_bitmap. 1445 * 1446 * Return: void. 1447 */ 1448 static void 1449 reg_modify_disable_chan_list_for_unii1_and_unii2a( 1450 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 1451 { 1452 uint8_t unii_bitmap = pdev_priv_obj->unii_5g_bitmap; 1453 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list; 1454 1455 if (reg_is_reg_unii_band_1_set(unii_bitmap)) { 1456 reg_remove_unii_chan_from_chan_list(chan_list, 1457 MIN_UNII_1_BAND_CHANNEL, 1458 MAX_UNII_1_BAND_CHANNEL); 1459 } 1460 1461 if (reg_is_reg_unii_band_2a_set(unii_bitmap)) { 1462 reg_remove_unii_chan_from_chan_list(chan_list, 1463 MIN_UNII_2A_BAND_CHANNEL, 1464 MAX_UNII_2A_BAND_CHANNEL); 1465 } 1466 } 1467 #else 1468 static inline bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap) 1469 { 1470 return false; 1471 } 1472 1473 static inline bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap) 1474 { 1475 return false; 1476 } 1477 1478 static inline bool reg_is_5g_enum(enum channel_enum chan_enum) 1479 { 1480 return false; 1481 } 1482 1483 static inline void 1484 reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list, 1485 enum channel_enum start_enum, 1486 enum channel_enum end_enum) 1487 { 1488 } 1489 1490 static inline void 1491 reg_modify_disable_chan_list_for_unii1_and_unii2a( 1492 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 1493 { 1494 } 1495 #endif 1496 1497 #ifdef CONFIG_BAND_6GHZ 1498 #ifdef CONFIG_REG_CLIENT 1499 1500 #ifdef CONFIG_AFC_SUPPORT 1501 /** 1502 * reg_append_mas_chan_list_for_6g_sp() - Append SP channels to the master 1503 * channel list 1504 * @pdev_priv_obj: Pointer to pdev private object 1505 * 1506 * This function appends SP channels to the master channel list 1507 * 1508 * Return: void. 1509 */ 1510 static void 1511 reg_append_mas_chan_list_for_6g_sp(struct wlan_regulatory_pdev_priv_obj 1512 *pdev_priv_obj) 1513 { 1514 struct regulatory_channel *master_chan_list_6g_client_sp; 1515 1516 master_chan_list_6g_client_sp = pdev_priv_obj->afc_chan_list; 1517 1518 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL], 1519 master_chan_list_6g_client_sp, 1520 NUM_6GHZ_CHANNELS * 1521 sizeof(struct regulatory_channel)); 1522 } 1523 #else 1524 static inline void 1525 reg_append_mas_chan_list_for_6g_sp(struct wlan_regulatory_pdev_priv_obj 1526 *pdev_priv_obj) 1527 { 1528 } 1529 #endif 1530 1531 /** 1532 * reg_append_mas_chan_list_for_6g_lpi() - Append LPI channels to the master 1533 * channel list 1534 * @pdev_priv_obj: Pointer to pdev private object 1535 * 1536 * This function appends LPI channels to the master channel list 1537 * 1538 * Return: void. 1539 */ 1540 static void 1541 reg_append_mas_chan_list_for_6g_lpi(struct wlan_regulatory_pdev_priv_obj 1542 *pdev_priv_obj) 1543 { 1544 struct regulatory_channel *master_chan_list_6g_client_lpi; 1545 uint8_t i, j; 1546 1547 if (!pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_INDOOR_AP]) { 1548 reg_debug("No LPI reg rules"); 1549 return; 1550 } 1551 1552 master_chan_list_6g_client_lpi = 1553 pdev_priv_obj->mas_chan_list_6g_client[REG_INDOOR_AP] 1554 [pdev_priv_obj->reg_cur_6g_client_mobility_type]; 1555 1556 for (i = MIN_6GHZ_CHANNEL, j = 0; 1557 i <= MAX_6GHZ_CHANNEL && j < NUM_6GHZ_CHANNELS; i++, j++) { 1558 if ((pdev_priv_obj->mas_chan_list[i].state == 1559 CHANNEL_STATE_DISABLE) || 1560 (pdev_priv_obj->mas_chan_list[i].chan_flags & 1561 REGULATORY_CHAN_DISABLED)) { 1562 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[i], 1563 &master_chan_list_6g_client_lpi[j], 1564 sizeof(struct regulatory_channel)); 1565 } 1566 } 1567 } 1568 1569 /** 1570 * reg_append_mas_chan_list_for_6g_VLP() - Append VLP channels to the master 1571 * channel list 1572 * @pdev_priv_obj: Pointer to pdev private object 1573 * 1574 * This function appends VLP channels to the master channel list 1575 * 1576 * Return: void. 1577 */ 1578 static void 1579 reg_append_mas_chan_list_for_6g_vlp(struct wlan_regulatory_pdev_priv_obj 1580 *pdev_priv_obj) 1581 { 1582 struct regulatory_channel *master_chan_list_6g_client_vlp; 1583 uint8_t i, j; 1584 1585 if (!pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_VERY_LOW_POWER_AP]) { 1586 reg_debug("No VLP reg rules"); 1587 return; 1588 } 1589 1590 master_chan_list_6g_client_vlp = 1591 pdev_priv_obj->mas_chan_list_6g_client[REG_VERY_LOW_POWER_AP] 1592 [pdev_priv_obj->reg_cur_6g_client_mobility_type]; 1593 1594 for (i = MIN_6GHZ_CHANNEL, j = 0; 1595 i <= MAX_6GHZ_CHANNEL && j < NUM_6GHZ_CHANNELS; i++, j++) { 1596 if ((pdev_priv_obj->mas_chan_list[i].state == 1597 CHANNEL_STATE_DISABLE) || 1598 (pdev_priv_obj->mas_chan_list[i].chan_flags & 1599 REGULATORY_CHAN_DISABLED)) { 1600 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[i], 1601 &master_chan_list_6g_client_vlp[j], 1602 sizeof(struct regulatory_channel)); 1603 } 1604 } 1605 } 1606 1607 static void 1608 reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj 1609 *pdev_priv_obj) 1610 { 1611 if (pdev_priv_obj->reg_cur_6g_ap_pwr_type >= REG_CURRENT_MAX_AP_TYPE || 1612 pdev_priv_obj->reg_cur_6g_client_mobility_type >= 1613 REG_MAX_CLIENT_TYPE) { 1614 reg_debug("invalid 6G AP or client power type"); 1615 return; 1616 } 1617 1618 /* Client should be able to scan all types of APs, so prepare the 1619 * client list which has all the enabled channels, first priority is 1620 * given to AFC power type and then second priority is decided based on 1621 * gindoor_channel_support ini value 1622 */ 1623 reg_append_mas_chan_list_for_6g_sp(pdev_priv_obj); 1624 1625 if (pdev_priv_obj->indoor_chan_enabled) { 1626 reg_append_mas_chan_list_for_6g_lpi(pdev_priv_obj); 1627 reg_append_mas_chan_list_for_6g_vlp(pdev_priv_obj); 1628 } else { 1629 reg_append_mas_chan_list_for_6g_vlp(pdev_priv_obj); 1630 reg_append_mas_chan_list_for_6g_lpi(pdev_priv_obj); 1631 } 1632 } 1633 1634 /** 1635 * reg_dump_valid_6ghz_channel_list() - Function to print valid 6 GHz channel 1636 * list state and attribute. 1637 * @chan: Pointer to array of 6 GHz channel list 1638 * 1639 * Return: None 1640 */ 1641 static void 1642 reg_dump_valid_6ghz_channel_list(struct regulatory_channel *chan) 1643 { 1644 #define MAX_CHAN_LOG_ONE_LINE 18 1645 uint32_t buf_size = MAX_CHAN_LOG_ONE_LINE * 24 + 1; 1646 uint8_t *buf; 1647 uint32_t i, len = 0, count = 0; 1648 1649 buf = qdf_mem_malloc(buf_size); 1650 if (!buf) 1651 return; 1652 1653 for (i = MIN_6GHZ_CHANNEL; i <= MAX_6GHZ_CHANNEL; i++, chan++) { 1654 if (chan->state == CHANNEL_STATE_DISABLE) 1655 continue; 1656 len += qdf_scnprintf(buf + len, buf_size - len, 1657 "%d:%d:%d:%d:%d:%x ", 1658 chan->center_freq, chan->state, 1659 chan->psd_flag, chan->tx_power, 1660 (int16_t)chan->psd_eirp, 1661 chan->chan_flags); 1662 count++; 1663 if (count >= MAX_CHAN_LOG_ONE_LINE) { 1664 reg_nofl_debug("%s", buf); 1665 count = 0; 1666 len = 0; 1667 } 1668 } 1669 1670 if (len) 1671 reg_nofl_debug("%s", buf); 1672 1673 qdf_mem_free(buf); 1674 } 1675 1676 /** 1677 * reg_dump_valid_6ghz_cur_chan_list() - API to dump pdev current/secondary 1678 * channel list state 1679 * @pdev_priv_obj: pointer to pdev private object 1680 * 1681 * Return: None 1682 */ 1683 static void 1684 reg_dump_valid_6ghz_cur_chan_list(struct wlan_regulatory_pdev_priv_obj 1685 *pdev_priv_obj) 1686 { 1687 reg_debug("sta freq:state:ispsd:pwr:psd:flags(hex):"); 1688 reg_dump_valid_6ghz_channel_list( 1689 &pdev_priv_obj->cur_chan_list[MIN_6GHZ_CHANNEL]); 1690 reg_debug("sap freq:state:ispsd:pwr:psd:flags(hex):"); 1691 reg_dump_valid_6ghz_channel_list( 1692 &pdev_priv_obj->secondary_cur_chan_list[MIN_6GHZ_CHANNEL]); 1693 } 1694 1695 #ifdef CONFIG_AFC_SUPPORT 1696 /** 1697 * reg_populate_afc_secondary_cur_chan_list() - Function to populate AFC 1698 * channel list to secondary current channel list 1699 * @pdev_priv_obj: Pointer to pdev regulatory private object 1700 * @chan_list: Pointer to array of 6 GHz channel list 1701 * 1702 * Return: None 1703 */ 1704 static void reg_populate_afc_secondary_cur_chan_list( 1705 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 1706 struct regulatory_channel *chan_list) 1707 { 1708 uint32_t i; 1709 struct regulatory_channel *afc_chan_list; 1710 struct regulatory_channel *sp_chan_list; 1711 1712 if (!pdev_priv_obj->is_6g_afc_power_event_received) 1713 return; 1714 1715 afc_chan_list = pdev_priv_obj->afc_chan_list; 1716 sp_chan_list = pdev_priv_obj-> 1717 mas_chan_list_6g_ap[REG_STANDARD_POWER_AP]; 1718 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) { 1719 if (afc_chan_list[i].state == CHANNEL_STATE_DISABLE && 1720 sp_chan_list[i].state == CHANNEL_STATE_ENABLE) { 1721 chan_list[i].state = CHANNEL_STATE_DISABLE; 1722 chan_list[i].chan_flags |= REGULATORY_CHAN_DISABLED; 1723 } else if (afc_chan_list[i].state == CHANNEL_STATE_ENABLE) { 1724 qdf_mem_copy(&chan_list[i], 1725 &afc_chan_list[i], 1726 sizeof(chan_list[i])); 1727 chan_list[i].chan_flags |= REGULATORY_CHAN_AFC; 1728 } 1729 } 1730 } 1731 #else 1732 static inline void reg_populate_afc_secondary_cur_chan_list( 1733 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 1734 struct regulatory_channel *chan_list) 1735 { 1736 } 1737 #endif 1738 1739 static void 1740 reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj 1741 *pdev_priv_obj) 1742 { 1743 struct wlan_objmgr_psoc *psoc; 1744 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; 1745 struct wlan_regulatory_psoc_priv_obj *soc_reg; 1746 struct regulatory_channel *chan_list; 1747 uint32_t len_6ghz; 1748 1749 psoc = wlan_pdev_get_psoc(pdev_priv_obj->pdev_ptr); 1750 if (!psoc) { 1751 reg_err("psoc is NULL"); 1752 return; 1753 } 1754 1755 soc_reg = reg_get_psoc_obj(psoc); 1756 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) { 1757 reg_err("psoc reg component is NULL"); 1758 return; 1759 } 1760 1761 reg_tx_ops = reg_get_psoc_tx_ops(psoc); 1762 if (!reg_tx_ops) { 1763 reg_err("reg_tx_ops null"); 1764 return; 1765 } 1766 1767 if (!reg_tx_ops->register_master_ext_handler || 1768 !wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_EXT_EVENT_SUPPORTED)) { 1769 qdf_mem_copy(pdev_priv_obj->secondary_cur_chan_list, 1770 pdev_priv_obj->cur_chan_list, 1771 (NUM_CHANNELS) * 1772 sizeof(struct regulatory_channel)); 1773 return; 1774 } 1775 1776 len_6ghz = NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel); 1777 chan_list = qdf_mem_malloc(len_6ghz); 1778 if (!chan_list) 1779 return; 1780 1781 if (pdev_priv_obj->indoor_chan_enabled && 1782 pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_INDOOR_AP]) { 1783 qdf_mem_copy(chan_list, 1784 pdev_priv_obj->mas_chan_list_6g_ap[REG_INDOOR_AP], 1785 len_6ghz); 1786 /* has flag REGULATORY_CHAN_INDOOR_ONLY */ 1787 } else if (pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules 1788 [REG_VERY_LOW_POWER_AP]) { 1789 qdf_mem_copy(chan_list, 1790 pdev_priv_obj->mas_chan_list_6g_ap 1791 [REG_VERY_LOW_POWER_AP], 1792 len_6ghz); 1793 } else { 1794 reg_init_6ghz_master_chan(chan_list, soc_reg); 1795 } 1796 1797 reg_populate_afc_secondary_cur_chan_list(pdev_priv_obj, chan_list); 1798 1799 qdf_mem_copy(pdev_priv_obj->secondary_cur_chan_list, 1800 pdev_priv_obj->cur_chan_list, 1801 (NUM_CHANNELS - NUM_6GHZ_CHANNELS) * 1802 sizeof(struct regulatory_channel)); 1803 qdf_mem_copy(&pdev_priv_obj->secondary_cur_chan_list[MIN_6GHZ_CHANNEL], 1804 chan_list, 1805 len_6ghz); 1806 qdf_mem_free(chan_list); 1807 reg_dump_valid_6ghz_cur_chan_list(pdev_priv_obj); 1808 } 1809 #else /* CONFIG_REG_CLIENT */ 1810 1811 /** 1812 * reg_copy_ap_chan_list_to_mas_chan_list() - Copy the 6G ap channel list to 1813 * the MIN_6GHZ_CHANNEL index of the mas_chan_list based on the AP power type 1814 * In case of standard power type, if the afc channel list is available from 1815 * the afc server, use afc channel list (intersected with SP power list) 1816 * for the copy instead of using the standard power list directly. 1817 * @pdev_priv_obj: pointer to pdev_priv_obj. 1818 * @ap_pwr_type: 6G AP power type 1819 * 1820 * Return type: void. 1821 */ 1822 #ifdef CONFIG_AFC_SUPPORT 1823 static void 1824 reg_copy_ap_chan_list_to_mas_chan_list(struct wlan_regulatory_pdev_priv_obj 1825 *pdev_priv_obj, 1826 enum reg_6g_ap_type ap_pwr_type) 1827 { 1828 if (ap_pwr_type == REG_STANDARD_POWER_AP && 1829 pdev_priv_obj->is_6g_afc_power_event_received) { 1830 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL], 1831 pdev_priv_obj->afc_chan_list, 1832 NUM_6GHZ_CHANNELS * 1833 sizeof(struct regulatory_channel)); 1834 } else { 1835 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL], 1836 pdev_priv_obj->mas_chan_list_6g_ap[ap_pwr_type], 1837 NUM_6GHZ_CHANNELS * 1838 sizeof(struct regulatory_channel)); 1839 } 1840 } 1841 #else 1842 static void 1843 reg_copy_ap_chan_list_to_mas_chan_list(struct wlan_regulatory_pdev_priv_obj 1844 *pdev_priv_obj, 1845 enum reg_6g_ap_type ap_pwr_type) 1846 { 1847 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL], 1848 pdev_priv_obj->mas_chan_list_6g_ap[ap_pwr_type], 1849 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel)); 1850 } 1851 #endif 1852 static void 1853 reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj 1854 *pdev_priv_obj) 1855 { 1856 enum reg_6g_ap_type ap_pwr_type = pdev_priv_obj->reg_cur_6g_ap_pwr_type; 1857 1858 if (ap_pwr_type >= REG_CURRENT_MAX_AP_TYPE) { 1859 reg_debug("invalid 6G AP power type"); 1860 return; 1861 } 1862 1863 reg_copy_ap_chan_list_to_mas_chan_list(pdev_priv_obj, ap_pwr_type); 1864 } 1865 1866 static inline void 1867 reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj 1868 *pdev_priv_obj) 1869 { 1870 } 1871 #endif /* CONFIG_REG_CLIENT */ 1872 1873 #ifdef CONFIG_AFC_SUPPORT 1874 /* reg_intersect_6g_afc_chan_list() - Do intersection of tx_powers of AFC master 1875 * channel list and SP channel list and store the power in the AFC channel list. 1876 * @pdev_priv_obj: pointer to pdev_priv_obj. 1877 * 1878 * Return type: void. 1879 */ 1880 static void 1881 reg_intersect_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj 1882 *pdev_priv_obj) 1883 { 1884 struct regulatory_channel *afc_chan_list; 1885 struct regulatory_channel *afc_mas_chan_list; 1886 struct regulatory_channel *sp_chan_list; 1887 uint8_t i; 1888 1889 afc_chan_list = pdev_priv_obj->afc_chan_list; 1890 afc_mas_chan_list = pdev_priv_obj->mas_chan_list_6g_afc; 1891 sp_chan_list = 1892 pdev_priv_obj->mas_chan_list_6g_ap[REG_STANDARD_POWER_AP]; 1893 1894 qdf_mem_copy(afc_chan_list, afc_mas_chan_list, 1895 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel)); 1896 1897 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) { 1898 if ((afc_chan_list[i].state != CHANNEL_STATE_DISABLE) && 1899 !(afc_chan_list[i].chan_flags & 1900 REGULATORY_CHAN_DISABLED)) { 1901 afc_chan_list[i].tx_power = 1902 QDF_MIN(sp_chan_list[i].tx_power, 1903 afc_mas_chan_list[i].tx_power); 1904 afc_chan_list[i].psd_eirp = 1905 QDF_MIN((int16_t)sp_chan_list[i].psd_eirp, 1906 (int16_t)afc_mas_chan_list[i].psd_eirp); 1907 afc_chan_list[i].chan_flags &= 1908 ~REGULATORY_CHAN_AFC_NOT_DONE; 1909 } else if ((pdev_priv_obj->reg_afc_dev_deployment_type == 1910 AFC_DEPLOYMENT_OUTDOOR) && 1911 (sp_chan_list[i].chan_flags & 1912 REGULATORY_CHAN_AFC_NOT_DONE)) { 1913 /* This is for the SP channels supported by 1914 * regulatory list that are not supported by AFC i.e. 1915 * SP channel list - AFC Channel list. 1916 */ 1917 afc_chan_list[i].tx_power = sp_chan_list[i].tx_power; 1918 afc_chan_list[i].psd_eirp = sp_chan_list[i].psd_eirp; 1919 afc_chan_list[i].chan_flags &= ~REGULATORY_CHAN_DISABLED; 1920 afc_chan_list[i].chan_flags |= REGULATORY_CHAN_AFC_NOT_DONE; 1921 afc_chan_list[i].state = CHANNEL_STATE_ENABLE; 1922 } 1923 } 1924 } 1925 1926 /* reg_modify_6g_afc_chan_list() - Modify the AFC channel list if the AFC WMI 1927 * power event is received from the target 1928 * @pdev_priv_obj: pointer to pdev_priv_obj. 1929 * 1930 * Return type: void. 1931 */ 1932 static void 1933 reg_modify_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 1934 { 1935 if (pdev_priv_obj->is_6g_afc_power_event_received) 1936 reg_intersect_6g_afc_chan_list(pdev_priv_obj); 1937 } 1938 #else 1939 static inline void 1940 reg_modify_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 1941 { 1942 } 1943 #endif 1944 1945 static void reg_copy_6g_cur_mas_chan_list_to_cmn( 1946 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 1947 { 1948 if (pdev_priv_obj->is_6g_channel_list_populated) 1949 reg_append_mas_chan_list_for_6g(pdev_priv_obj); 1950 } 1951 #else /* CONFIG_BAND_6GHZ */ 1952 static inline void 1953 reg_copy_6g_cur_mas_chan_list_to_cmn( 1954 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 1955 { 1956 } 1957 1958 static inline void 1959 reg_append_mas_chan_list_for_6g( 1960 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 1961 { 1962 } 1963 1964 #ifdef CONFIG_REG_CLIENT 1965 static void 1966 reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj 1967 *pdev_priv_obj) 1968 { 1969 qdf_mem_copy(pdev_priv_obj->secondary_cur_chan_list, 1970 pdev_priv_obj->cur_chan_list, 1971 NUM_CHANNELS * sizeof(struct regulatory_channel)); 1972 } 1973 #else /* CONFIG_REG_CLIENT */ 1974 static inline void 1975 reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj 1976 *pdev_priv_obj) 1977 { 1978 } 1979 #endif /* CONFIG_REG_CLIENT */ 1980 static inline void 1981 reg_modify_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 1982 { 1983 } 1984 #endif /* CONFIG_BAND_6GHZ */ 1985 1986 #if defined(CONFIG_BAND_6GHZ) && defined(CONFIG_REG_CLIENT) 1987 /** 1988 * reg_modify_sec_chan_list_for_6g_edge_chan() - Modify 6 GHz edge channels 1989 * for SAP (for MCC use case) 1990 * 1991 * @pdev_priv_obj: pointer to pdev_priv_obj. 1992 * 1993 * This is a wrapper function that calls the API 1994 * reg_modify_chan_list_for_6g_edge_channels() by passing secondary channel 1995 * list (used by beaconing entities like SAP). This API enables/disables 6GHz 1996 * edge channels ch2 (5935 MHz) and ch233 (7115 MHz) based on service bits. 1997 * 1998 */ 1999 static void 2000 reg_modify_sec_chan_list_for_6g_edge_chan(struct wlan_regulatory_pdev_priv_obj 2001 *pdev_priv_obj) 2002 { 2003 reg_modify_chan_list_for_6g_edge_channels(pdev_priv_obj->pdev_ptr, 2004 pdev_priv_obj-> 2005 secondary_cur_chan_list); 2006 } 2007 #else 2008 static inline void 2009 reg_modify_sec_chan_list_for_6g_edge_chan(struct wlan_regulatory_pdev_priv_obj 2010 *pdev_priv_obj) 2011 { 2012 } 2013 #endif 2014 2015 #ifdef FEATURE_WLAN_CH_AVOID_EXT 2016 struct chan_5g_center_freq center_5g[MAX_5G_CHAN_NUM] = { 2017 /*36*/ 2018 {5180, 5190, 5210, 5250}, 2019 /*40*/ 2020 {5200, 5190, 5210, 5250}, 2021 /*44*/ 2022 {5220, 5230, 5210, 5250}, 2023 /*48*/ 2024 {5240, 5230, 5210, 5250}, 2025 2026 /*52*/ 2027 {5260, 5270, 5290, 5250}, 2028 /*56*/ 2029 {5280, 5270, 5290, 5250}, 2030 /*60*/ 2031 {5300, 5310, 5290, 5250}, 2032 /*64*/ 2033 {5320, 5310, 5290, 5250}, 2034 2035 /*100*/ 2036 {5500, 5510, 5530, 5570}, 2037 /*104*/ 2038 {5520, 5510, 5530, 5570}, 2039 /*108*/ 2040 {5540, 5550, 5530, 5570}, 2041 /*112*/ 2042 {5560, 5550, 5530, 5570}, 2043 2044 /*116*/ 2045 {5580, 5590, 5610, 5570}, 2046 /*120*/ 2047 {5600, 5590, 5610, 5570}, 2048 /*124*/ 2049 {5620, 5630, 5610, 5570}, 2050 /*128*/ 2051 {5640, 5630, 5610, 5570}, 2052 2053 /*132*/ 2054 {5660, 5670, 5690, INVALID_CENTER_FREQ}, 2055 /*136*/ 2056 {5680, 5670, 5690, INVALID_CENTER_FREQ}, 2057 /*140*/ 2058 {5700, 5710, 5690, INVALID_CENTER_FREQ}, 2059 /*144*/ 2060 {5720, 5710, 5690, INVALID_CENTER_FREQ}, 2061 2062 /*149*/ 2063 {5745, 5755, 5775, 5815}, 2064 /*153*/ 2065 {5765, 5755, 5775, 5815}, 2066 /*157*/ 2067 {5785, 5795, 5775, 5815}, 2068 /*161*/ 2069 {5805, 5795, 5775, 5815}, 2070 2071 /*165*/ 2072 {5825, 5835, 5855, 5815}, 2073 /*169*/ 2074 {5845, 5835, 5855, 5815}, 2075 /*173*/ 2076 {5865, 5875, 5855, 5815}, 2077 /*177*/ 2078 {5885, 5875, 5855, 5815}, 2079 }; 2080 2081 /** 2082 * reg_modify_5g_maxbw() - Update the max bandwidth for 5G channel 2083 * @chan: Pointer to current channel 2084 * @avoid_freq: current avoid frequency range 2085 * 2086 * This function updates the max bandwidth for the 5G channels if 2087 * it has overlap with avoid frequency range. For example, if the 2088 * avoid frequency range is []5755-5775], and current channel is 149 with 2089 * max bandwidth 80Mhz by default, then has to change the max bandwidth 2090 * to 20Mhz, since both 40Mhz [5735-5775] and 80M [5735-5815] has 2091 * overlap with avoid frequency [5755-5775]. 2092 * 2093 * Return: void. 2094 */ 2095 static void 2096 reg_modify_5g_maxbw(struct regulatory_channel *chan, 2097 struct ch_avoid_freq_type *avoid_freq) 2098 { 2099 int i; 2100 qdf_freq_t start = 0; 2101 qdf_freq_t end = 0; 2102 qdf_freq_t cur; 2103 bool found = false; 2104 2105 for (i = 0; i < MAX_5G_CHAN_NUM; i++) { 2106 cur = center_5g[i].center_freq_20; 2107 if (chan->center_freq == cur) { 2108 while (!found) { 2109 uint16_t h_bw; 2110 2111 if (chan->max_bw < 20 || 2112 chan->max_bw > 160) 2113 break; 2114 2115 switch (chan->max_bw) { 2116 case 160: 2117 cur = center_5g[i].center_freq_160; 2118 if (!cur) { 2119 chan->max_bw = chan->max_bw / 2; 2120 break; 2121 } 2122 start = cur - HALF_160MHZ_BW; 2123 end = cur + HALF_160MHZ_BW; 2124 break; 2125 case 80: 2126 cur = center_5g[i].center_freq_80; 2127 start = cur - HALF_80MHZ_BW; 2128 end = cur + HALF_80MHZ_BW; 2129 break; 2130 case 40: 2131 cur = center_5g[i].center_freq_40; 2132 start = cur - HALF_40MHZ_BW; 2133 end = cur + HALF_40MHZ_BW; 2134 break; 2135 case 20: 2136 cur = center_5g[i].center_freq_20; 2137 start = cur - HALF_20MHZ_BW; 2138 end = cur + HALF_20MHZ_BW; 2139 break; 2140 default: 2141 break; 2142 } 2143 2144 if (avoid_freq->end_freq <= end && 2145 avoid_freq->start_freq >= start) { 2146 /* avoid freq inside */ 2147 h_bw = chan->max_bw / 2; 2148 chan->max_bw = min(chan->max_bw, h_bw); 2149 continue; 2150 } else if ((avoid_freq->start_freq > start && 2151 avoid_freq->start_freq < end) || 2152 (avoid_freq->end_freq > start && 2153 avoid_freq->end_freq < end)) { 2154 /* avoid freq part overlap */ 2155 h_bw = chan->max_bw / 2; 2156 chan->max_bw = min(chan->max_bw, h_bw); 2157 continue; 2158 } else if (avoid_freq->start_freq >= end || 2159 avoid_freq->end_freq <= start) { 2160 /* beyond the range freq */ 2161 found = true; 2162 } 2163 } 2164 } 2165 } 2166 } 2167 2168 /** 2169 * reg_modify_chan_list_for_avoid_chan_ext() - Update the state and bandwidth 2170 * for each channel in the current channel list. 2171 * @pdev_priv_obj: Pointer to wlan regulatory pdev private object. 2172 * 2173 * This function update the state and bandwidth for each channel in the current 2174 * channel list if it is affected by avoid frequency list. 2175 * For 2.4G/5G, all the center frequency of specific channel in the 2176 * avoid_chan_ext_list (avoid frequency list) will be disabled. 2177 * For example, avoid frequency list include [2412,2417,2422], 2178 * then channel 1, 2 and 3 will be disabled. Same logic apply for 5g. 2179 * For 5G, if the max bandwidth of the channel affected by avoid frequency 2180 * range then need to reduce the bandwidth or finally disabled. 2181 * For other bands, to-do in future if need. 2182 * 2183 * Return: void. 2184 */ 2185 static void 2186 reg_modify_chan_list_for_avoid_chan_ext(struct wlan_regulatory_pdev_priv_obj 2187 *pdev_priv_obj) 2188 { 2189 uint32_t i, j, k; 2190 struct wlan_objmgr_psoc *psoc; 2191 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 2192 uint32_t num_avoid_channels; 2193 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list; 2194 struct regulatory_channel *sec_chan_list; 2195 uint16_t *avoid_chan_ext_list; 2196 uint32_t num_avoid_freq; 2197 struct ch_avoid_freq_type *avoid_freq_ext, *avoid_freq_ext_t; 2198 2199 sec_chan_list = pdev_priv_obj->secondary_cur_chan_list; 2200 2201 avoid_chan_ext_list = pdev_priv_obj->avoid_chan_ext_list.chan_freq_list; 2202 num_avoid_channels = pdev_priv_obj->avoid_chan_ext_list.chan_cnt; 2203 2204 psoc = wlan_pdev_get_psoc(pdev_priv_obj->pdev_ptr); 2205 if (!psoc) 2206 return; 2207 2208 if (!reg_check_coex_unsafe_chan_reg_disable(psoc)) { 2209 reg_debug("Don't disable reg channels for Coex unsafe channels"); 2210 return; 2211 } 2212 2213 psoc_priv_obj = reg_get_psoc_obj(psoc); 2214 if (!psoc_priv_obj) 2215 return; 2216 2217 if (!num_avoid_channels || !psoc_priv_obj->ch_avoid_ext_ind) 2218 return; 2219 2220 num_avoid_freq = psoc_priv_obj->avoid_freq_ext_list.ch_avoid_range_cnt; 2221 avoid_freq_ext = psoc_priv_obj->avoid_freq_ext_list.avoid_freq_range; 2222 2223 for (i = 0; i < num_avoid_channels; i++) 2224 for (j = 0; j < NUM_CHANNELS; j++) { 2225 qdf_freq_t c_freq, avoid_tmp = avoid_chan_ext_list[i]; 2226 2227 if (chan_list[j].state == CHANNEL_STATE_DISABLE) 2228 goto second_chan_handle; 2229 2230 /* For 2.4G, just only disable the channel if center 2231 * frequecy is in avoid_chan_ext_list. 2232 * For 5G, customer ask for bandwidth reduction if 2233 * it affect by the nearby channel that in the 2234 * avoid_chan_ext_list. 2235 * For example, if block out frequency range is 2236 * [5755-5775], then except for channel 153 need 2237 * to be disabled, and 149 has to change max 80Mhz 2238 * to 20Mhz, since 149 only has [5735-5755] available. 2239 * channel 157/161 [5775-5815] has to change max 80 2240 * to 40. 2241 * For 6G: to-do in future. 2242 */ 2243 c_freq = chan_list[j].center_freq; 2244 if (avoid_tmp == c_freq) { 2245 chan_list[j].state = CHANNEL_STATE_DISABLE; 2246 chan_list[j].chan_flags |= 2247 REGULATORY_CHAN_DISABLED; 2248 } else if (reg_is_5ghz_ch_freq(c_freq)) { 2249 for (k = 0; k < num_avoid_freq; k++) { 2250 qdf_freq_t s_freq, e_freq; 2251 2252 avoid_freq_ext_t = &avoid_freq_ext[k]; 2253 s_freq = avoid_freq_ext_t->start_freq; 2254 e_freq = avoid_freq_ext_t->end_freq; 2255 2256 /* need to cover [5170-5190] case*/ 2257 if ((!reg_is_5ghz_ch_freq(s_freq) && 2258 ((s_freq + HALF_20MHZ_BW) < 2259 reg_min_5ghz_chan_freq())) || 2260 (!reg_is_5ghz_ch_freq(e_freq) && 2261 ((e_freq - HALF_20MHZ_BW) > 2262 reg_max_5ghz_chan_freq()))) 2263 continue; 2264 2265 /* if current center freq is in the 2266 * avoid rang, then skip it, it will be 2267 * handled in the branch (avoid_tmp 2268 * == c_freq) 2269 */ 2270 if ((c_freq > s_freq && 2271 c_freq < e_freq)) 2272 continue; 2273 2274 reg_modify_5g_maxbw(&chan_list[j], 2275 avoid_freq_ext_t); 2276 2277 if (chan_list[j].max_bw < 2278 HALF_40MHZ_BW) { 2279 chan_list[j].state = 2280 CHANNEL_STATE_DISABLE; 2281 chan_list[j].chan_flags |= 2282 REGULATORY_CHAN_DISABLED; 2283 break; 2284 } 2285 } 2286 } 2287 second_chan_handle: 2288 2289 if (sec_chan_list[j].state == 2290 CHANNEL_STATE_DISABLE) 2291 continue; 2292 2293 c_freq = sec_chan_list[j].center_freq; 2294 if (avoid_tmp == c_freq) { 2295 sec_chan_list[j].state = CHANNEL_STATE_DISABLE; 2296 sec_chan_list[j].chan_flags |= 2297 REGULATORY_CHAN_DISABLED; 2298 } else if (reg_is_5ghz_ch_freq(c_freq)) { 2299 for (k = 0; k < num_avoid_freq; k++) { 2300 qdf_freq_t s_freq, e_freq; 2301 2302 avoid_freq_ext_t = &avoid_freq_ext[k]; 2303 s_freq = avoid_freq_ext_t->start_freq; 2304 e_freq = avoid_freq_ext_t->end_freq; 2305 2306 /* need to cover [5170-5190] case*/ 2307 if ((!reg_is_5ghz_ch_freq(s_freq) && 2308 ((s_freq + HALF_20MHZ_BW) < 2309 reg_min_5ghz_chan_freq())) || 2310 (!reg_is_5ghz_ch_freq(e_freq) && 2311 ((e_freq - HALF_20MHZ_BW) > 2312 reg_max_5ghz_chan_freq()))) 2313 continue; 2314 2315 /* if current center freq is in the 2316 * avoid rang, then skip it, it will be 2317 * handled in the branch (avoid_tmp 2318 * == c_freq) 2319 */ 2320 if ((c_freq > s_freq && 2321 c_freq < e_freq)) 2322 continue; 2323 2324 reg_modify_5g_maxbw(&sec_chan_list[j], 2325 avoid_freq_ext_t); 2326 2327 if (sec_chan_list[j].max_bw < 2328 HALF_40MHZ_BW) { 2329 sec_chan_list[j].state = 2330 CHANNEL_STATE_DISABLE; 2331 sec_chan_list[j].chan_flags |= 2332 REGULATORY_CHAN_DISABLED; 2333 break; 2334 } 2335 } 2336 } 2337 } 2338 } 2339 #else 2340 static inline void 2341 reg_modify_chan_list_for_avoid_chan_ext(struct wlan_regulatory_pdev_priv_obj 2342 *pdev_priv_obj) 2343 { 2344 } 2345 #endif 2346 2347 #ifdef CONFIG_BAND_6GHZ 2348 /** 2349 * reg_init_super_chan_entry() - Initialize the super channel list entry 2350 * for an input channel index by disabling the state and chan flags. 2351 * @pdev_priv_obj: Pointer to pdev_priv_obj 2352 * 2353 * Return: void 2354 */ 2355 static void reg_init_super_chan_entry( 2356 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 2357 uint8_t chan_idx) 2358 { 2359 enum supported_6g_pwr_types pwr_type; 2360 struct super_chan_info *chan_info; 2361 2362 chan_info = &pdev_priv_obj->super_chan_list[chan_idx]; 2363 2364 for (pwr_type = REG_CURRENT_PWR_MODE; pwr_type <= REG_CLI_SUB_VLP; 2365 pwr_type++) 2366 reg_dis_chan_state_and_flags(&chan_info->state_arr[pwr_type], 2367 &chan_info->chan_flags_arr 2368 [pwr_type]); 2369 } 2370 2371 /** 2372 * reg_init_pdev_super_chan_list() - Initialize the super channel list. 2373 * @pdev_priv_obj: Pointer to pdev_priv_obj 2374 * 2375 * Return: void 2376 */ 2377 static void reg_init_pdev_super_chan_list( 2378 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 2379 { 2380 uint8_t i; 2381 2382 qdf_mem_zero(pdev_priv_obj->super_chan_list, NUM_6GHZ_CHANNELS * 2383 sizeof(struct super_chan_info)); 2384 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) 2385 reg_init_super_chan_entry(pdev_priv_obj, i); 2386 } 2387 2388 /** 2389 * reg_is_edge_chan_disable_needed() - Check if the 6G edge channels are 2390 * disabled 2391 * @psoc: Pointer to psoc 2392 * @chan_idx: Channel index 2393 * 2394 * Return: bool 2395 */ 2396 static bool reg_is_edge_chan_disable_needed(struct wlan_objmgr_psoc *psoc, 2397 uint16_t chan_idx) 2398 { 2399 bool is_lower_edge_disable = 2400 ((chan_idx == (CHAN_ENUM_5935 - MIN_6GHZ_CHANNEL)) && 2401 !reg_is_lower_6g_edge_ch_supp(psoc)); 2402 bool is_upper_edge_disable = 2403 ((chan_idx == (CHAN_ENUM_7115 - MIN_6GHZ_CHANNEL)) && 2404 reg_is_upper_6g_edge_ch_disabled(psoc)); 2405 2406 return is_lower_edge_disable || is_upper_edge_disable; 2407 } 2408 2409 #ifdef CONFIG_AFC_SUPPORT 2410 /** 2411 * reg_set_flag_afc_not_done() - Set channel flag REGULATORY_CHAN_AFC_NOT_DONE 2412 * @chan_flags: Channel flags 2413 * @is_set: boolean to set/unset the flag 2414 * 2415 * Return: void 2416 */ 2417 static inline void 2418 reg_set_flag_afc_not_done(uint32_t *chan_flags, bool is_set) 2419 { 2420 if (is_set) 2421 *chan_flags |= REGULATORY_CHAN_AFC_NOT_DONE; 2422 else 2423 *chan_flags &= ~REGULATORY_CHAN_AFC_NOT_DONE; 2424 } 2425 2426 #else 2427 static inline void 2428 reg_set_flag_afc_not_done(uint32_t *chan_flags, bool is_set) 2429 { 2430 } 2431 #endif 2432 2433 /** 2434 * reg_dis_6g_edge_chan_in_enh_chan() - Disable the 6g edge 2435 * channels in the super channel list 2436 * @pdev: Pointer to pdev 2437 * @chan_info: Pointer to chan_info 2438 * @chan_idx: Channel index 2439 * @pwr_type: 6G power type bitmap 2440 * 2441 * Return: void 2442 */ 2443 static void 2444 reg_dis_6g_edge_chan_in_enh_chan(struct wlan_objmgr_pdev *pdev, 2445 struct super_chan_info *chan_info, 2446 uint16_t chan_idx, 2447 enum supported_6g_pwr_types pwr_type) 2448 { 2449 struct wlan_objmgr_psoc *psoc; 2450 2451 if (!pdev) { 2452 reg_debug("pdev is NULL"); 2453 return; 2454 } 2455 2456 if (!chan_info) { 2457 reg_debug("chan_info is NULL"); 2458 return; 2459 } 2460 2461 if (reg_is_supp_pwr_mode_invalid(pwr_type)) { 2462 reg_debug("pwr_type invalid"); 2463 return; 2464 } 2465 2466 if (chan_idx >= NUM_6GHZ_CHANNELS) { 2467 reg_debug("chan_idx is out bounds"); 2468 return; 2469 } 2470 2471 psoc = wlan_pdev_get_psoc(pdev); 2472 if (!psoc) { 2473 reg_debug("psoc is NULL"); 2474 return; 2475 } 2476 2477 if (reg_is_edge_chan_disable_needed(psoc, chan_idx)) 2478 reg_dis_chan_state_and_flags(&chan_info->state_arr[pwr_type], 2479 &chan_info->chan_flags_arr 2480 [pwr_type]); 2481 } 2482 2483 /** 2484 * copy_enh_chan_info_from_reg_chan() - Copy the mas_chan_list entry to the 2485 * super channel list entry 2486 * @chan_info: Pointer to chan_info 2487 * @pwr_type: 6G power type bitmap 2488 * @reg_chan: Pointer to reg_chan 2489 * 2490 * Return: void 2491 */ 2492 static void 2493 copy_enh_chan_info_from_reg_chan(struct super_chan_info *chan_info, 2494 enum supported_6g_pwr_types pwr_type, 2495 struct regulatory_channel *reg_chan) 2496 { 2497 if (!chan_info) { 2498 reg_debug("chan_info is NULL"); 2499 return; 2500 } 2501 2502 if (reg_is_supp_pwr_mode_invalid(pwr_type)) { 2503 reg_debug("pwr_type invalid"); 2504 return; 2505 } 2506 2507 if (!reg_chan) { 2508 reg_debug("reg_chan is NULL"); 2509 return; 2510 } 2511 2512 chan_info->reg_chan_pwr[pwr_type].psd_flag = reg_chan->psd_flag; 2513 chan_info->reg_chan_pwr[pwr_type].psd_eirp = reg_chan->psd_eirp; 2514 chan_info->reg_chan_pwr[pwr_type].tx_power = reg_chan->tx_power; 2515 chan_info->chan_flags_arr[pwr_type] = reg_chan->chan_flags; 2516 chan_info->state_arr[pwr_type] = reg_chan->state; 2517 chan_info->min_bw[pwr_type] = reg_chan->min_bw; 2518 chan_info->max_bw[pwr_type] = reg_chan->max_bw; 2519 } 2520 2521 const struct ap_cli_pwr_mode_info reg_pwr_enum_2_ap_cli_pwrmode[] = { 2522 [REG_AP_LPI] = {true, REG_INVALID_CLIENT_TYPE, REG_INDOOR_AP}, 2523 [REG_AP_SP] = {true, REG_INVALID_CLIENT_TYPE, 2524 REG_STANDARD_POWER_AP}, 2525 [REG_AP_VLP] = {true, REG_INVALID_CLIENT_TYPE, 2526 REG_VERY_LOW_POWER_AP}, 2527 [REG_CLI_DEF_LPI] = {false, REG_DEFAULT_CLIENT, REG_INDOOR_AP}, 2528 [REG_CLI_DEF_SP] = {false, REG_DEFAULT_CLIENT, REG_STANDARD_POWER_AP}, 2529 [REG_CLI_DEF_VLP] = {false, REG_DEFAULT_CLIENT, REG_VERY_LOW_POWER_AP}, 2530 [REG_CLI_SUB_LPI] = {false, REG_SUBORDINATE_CLIENT, REG_INDOOR_AP}, 2531 [REG_CLI_SUB_SP] = {false, REG_SUBORDINATE_CLIENT, 2532 REG_STANDARD_POWER_AP}, 2533 [REG_CLI_SUB_VLP] = {false, REG_SUBORDINATE_CLIENT, 2534 REG_VERY_LOW_POWER_AP}, 2535 }; 2536 2537 enum reg_6g_ap_type 2538 reg_convert_supported_6g_pwr_type_to_ap_pwr_type(enum supported_6g_pwr_types 2539 in_6g_pwr_type) 2540 { 2541 if (reg_is_supp_pwr_mode_invalid(in_6g_pwr_type)) 2542 return REG_MAX_AP_TYPE; 2543 2544 return reg_pwr_enum_2_ap_cli_pwrmode[in_6g_pwr_type].ap_pwr_mode; 2545 } 2546 2547 struct regulatory_channel *reg_get_reg_maschan_lst_frm_6g_pwr_mode( 2548 enum supported_6g_pwr_types supp_pwr_mode, 2549 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 2550 uint16_t chan_idx) 2551 { 2552 struct regulatory_channel *mas_chan_list = NULL; 2553 bool is_ap_chan_lst; 2554 enum reg_6g_ap_type ap_pwr_mode; /* LPI, SP or VLP */ 2555 2556 if (reg_is_supp_pwr_mode_invalid(supp_pwr_mode)) { 2557 reg_debug("Unsupported 6G AP power type"); 2558 return mas_chan_list; 2559 } 2560 2561 is_ap_chan_lst = 2562 reg_pwr_enum_2_ap_cli_pwrmode[supp_pwr_mode].is_mode_ap; 2563 ap_pwr_mode = reg_pwr_enum_2_ap_cli_pwrmode[supp_pwr_mode].ap_pwr_mode; 2564 2565 if (ap_pwr_mode > REG_MAX_SUPP_AP_TYPE) { 2566 reg_debug("Unsupported 6G AP power type"); 2567 return mas_chan_list; 2568 } 2569 2570 if (is_ap_chan_lst) { 2571 mas_chan_list = 2572 &pdev_priv_obj->mas_chan_list_6g_ap[ap_pwr_mode][chan_idx]; 2573 } else { 2574 enum reg_6g_client_type cli_type; 2575 2576 cli_type = 2577 reg_pwr_enum_2_ap_cli_pwrmode[supp_pwr_mode].cli_type; 2578 if (cli_type >= REG_MAX_CLIENT_TYPE) { 2579 reg_debug("Unsupported 6G client power type"); 2580 return mas_chan_list; 2581 } 2582 2583 mas_chan_list = 2584 &pdev_priv_obj->mas_chan_list_6g_client[ap_pwr_mode][cli_type] 2585 [chan_idx]; 2586 } 2587 2588 return mas_chan_list; 2589 } 2590 2591 /** 2592 * reg_disable_out_of_range_chan_entry() - Disable the input channel if it is 2593 * out of the range of the 6G radio and return true, else return false 2594 * @reg_chan: Pointer to reg_chan 2595 * @pdev_priv_obj: Pointer to pdev_priv_obj 2596 * 2597 * Return: bool 2598 */ 2599 static bool reg_is_chan_out_of_chip_range( 2600 struct regulatory_channel *reg_chan, 2601 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 2602 { 2603 return ((reg_chan->center_freq < pdev_priv_obj->range_5g_low) || 2604 (reg_chan->center_freq > pdev_priv_obj->range_5g_high)); 2605 } 2606 2607 /** 2608 * reg_accumulate_pwr_type() - Accumulate the power type in the super channel 2609 * list entry for a given input channel index. 2610 * @supp_pwr_mode: 6G supported power mode 2611 * @super_chan_list: Pointer to super channel list 2612 * @chn_idx: Channel index 2613 * 2614 * Return: void 2615 */ 2616 static void reg_accumulate_pwr_type( 2617 enum supported_6g_pwr_types supp_pwr_mode, 2618 struct super_chan_info *super_chan_list, 2619 uint16_t chn_idx) 2620 { 2621 if (reg_is_supp_pwr_mode_invalid(supp_pwr_mode)) 2622 return; 2623 2624 super_chan_list[chn_idx].power_types |= BIT(supp_pwr_mode); 2625 } 2626 2627 /** 2628 * reg_is_sp_supp_pwr_mode() - Check if the input supported power mode is a 2629 * SP power mode 2630 * @supp_pwr_mode: 6G supported power mode 2631 * 2632 * Return: bool 2633 */ 2634 static bool 2635 reg_is_sp_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode) 2636 { 2637 return ((supp_pwr_mode == REG_AP_SP) || 2638 (supp_pwr_mode == REG_CLI_DEF_SP) || 2639 (supp_pwr_mode == REG_CLI_SUB_SP)); 2640 } 2641 2642 /** 2643 * reg_fill_best_pwr_mode() - Fill the best power mode 2644 * @pdev_priv_obj: Pointer to pdev_priv_obj 2645 * @super_chan_list: Pointer to super_chan_list 2646 * @chn_idx: Channel index 2647 * @supp_pwr_mode: Supported power mode 2648 * @mas_chan_list_power: EIRP of the channel in the mas_chan_list 2649 * @max_eirp_pwr: Maximum EIRP 2650 * 2651 * Return: void 2652 */ 2653 #ifdef CONFIG_REG_CLIENT 2654 static void 2655 reg_fill_best_pwr_mode(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 2656 struct super_chan_info *super_chan_list, 2657 uint8_t chn_idx, 2658 enum supported_6g_pwr_types supp_pwr_mode, 2659 uint8_t mas_chan_list_power, 2660 uint8_t *max_eirp_pwr) 2661 { 2662 enum reg_6g_client_type curr_6g_client_type; 2663 enum reg_6g_client_type client_type = 2664 reg_pwr_enum_2_ap_cli_pwrmode[supp_pwr_mode].cli_type; 2665 2666 reg_get_cur_6g_client_type(pdev_priv_obj->pdev_ptr, 2667 &curr_6g_client_type); 2668 if (client_type != curr_6g_client_type) 2669 return; 2670 2671 if (reg_is_sp_supp_pwr_mode(supp_pwr_mode) && 2672 !wlan_reg_is_afc_power_event_received(pdev_priv_obj->pdev_ptr)) 2673 return; 2674 2675 if (*max_eirp_pwr == 0) { 2676 *max_eirp_pwr = mas_chan_list_power; 2677 super_chan_list[chn_idx].best_power_mode = supp_pwr_mode; 2678 return; 2679 } else if (pdev_priv_obj->indoor_chan_enabled && 2680 (mas_chan_list_power > *max_eirp_pwr)) { 2681 *max_eirp_pwr = mas_chan_list_power; 2682 super_chan_list[chn_idx].best_power_mode = supp_pwr_mode; 2683 return; 2684 } 2685 2686 if (reg_is_lpi_cli_supp_pwr_mode( 2687 super_chan_list[chn_idx].best_power_mode) && 2688 !reg_is_lpi_cli_supp_pwr_mode(supp_pwr_mode)) { 2689 *max_eirp_pwr = mas_chan_list_power; 2690 super_chan_list[chn_idx].best_power_mode = supp_pwr_mode; 2691 return; 2692 } else if (!reg_is_lpi_cli_supp_pwr_mode(super_chan_list[chn_idx]. 2693 best_power_mode) && 2694 reg_is_lpi_cli_supp_pwr_mode(supp_pwr_mode)) { 2695 return; 2696 } else if (mas_chan_list_power > *max_eirp_pwr) { 2697 *max_eirp_pwr = mas_chan_list_power; 2698 super_chan_list[chn_idx].best_power_mode = supp_pwr_mode; 2699 } 2700 } 2701 #else 2702 static void 2703 reg_fill_best_pwr_mode(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 2704 struct super_chan_info *super_chan_list, 2705 uint8_t chn_idx, 2706 enum supported_6g_pwr_types supp_pwr_mode, 2707 uint8_t mas_chan_list_power, 2708 uint8_t *max_eirp_pwr) 2709 { 2710 if (mas_chan_list_power > *max_eirp_pwr) { 2711 *max_eirp_pwr = mas_chan_list_power; 2712 super_chan_list[chn_idx].best_power_mode = supp_pwr_mode; 2713 } 2714 } 2715 #endif 2716 2717 #ifdef CONFIG_AFC_SUPPORT 2718 /** 2719 * reg_assign_afc_chan_entry_to_mas_chan() - Assign the AFC channel list entry 2720 * to the mas_chan 2721 * @pdev_priv_obj: Pointer to pdev_priv_obj 2722 * @mas_chan: Pointer to address of mas_chan 2723 * @chn_idx: Channel index 2724 * 2725 * Return: void 2726 */ 2727 static void 2728 reg_assign_afc_chan_entry_to_mas_chan( 2729 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 2730 struct regulatory_channel **mas_chan, 2731 uint8_t chn_idx) 2732 { 2733 *mas_chan = &pdev_priv_obj->afc_chan_list[chn_idx]; 2734 } 2735 2736 /** 2737 * reg_is_deployment_outdoor() - Check if device deployment type is outdoor 2738 * @pdev_priv_obj: Pointer to pdev_priv_obj 2739 * 2740 * Return: True if deployment is outdoor, else false 2741 */ 2742 static bool 2743 reg_is_deployment_outdoor(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 2744 { 2745 return pdev_priv_obj->reg_afc_dev_deployment_type == 2746 AFC_DEPLOYMENT_OUTDOOR; 2747 } 2748 #else 2749 static inline void 2750 reg_assign_afc_chan_entry_to_mas_chan( 2751 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 2752 struct regulatory_channel **mas_chan, 2753 uint8_t chn_idx) 2754 { 2755 } 2756 2757 static inline bool 2758 reg_is_deployment_outdoor(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 2759 { 2760 return false; 2761 } 2762 #endif 2763 2764 /** 2765 * reg_update_sup_ch_entry_for_mode() - Construct the super channel list entry 2766 * for a mode 2767 * @pdev_priv_obj: Pointer to pdev_priv_obj 2768 * @supp_pwr_mode: Supported power mode 2769 * @chn_idx: Channel index 2770 * 2771 * Return: void 2772 */ 2773 static void reg_update_sup_ch_entry_for_mode( 2774 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 2775 enum supported_6g_pwr_types supp_pwr_mode, 2776 uint16_t chn_idx, 2777 uint8_t *max_eirp_pwr) 2778 { 2779 struct super_chan_info *super_chan_list; 2780 struct wlan_objmgr_pdev *pdev = pdev_priv_obj->pdev_ptr; 2781 struct regulatory_channel *mas_chan; 2782 struct regulatory_channel temp_reg_chan; 2783 2784 mas_chan = reg_get_reg_maschan_lst_frm_6g_pwr_mode(supp_pwr_mode, 2785 pdev_priv_obj, 2786 chn_idx); 2787 if (!mas_chan) 2788 return; 2789 2790 /* 2791 * If AFC is invalid, copy from Regulatory SP channel list. 2792 * If AFC is valid, copy from AFC response channel list. 2793 */ 2794 if (reg_is_sp_supp_pwr_mode(supp_pwr_mode)) { 2795 if (wlan_reg_is_afc_power_event_received(pdev)) 2796 reg_assign_afc_chan_entry_to_mas_chan(pdev_priv_obj, 2797 &mas_chan, 2798 chn_idx); 2799 /* In INDOOR mode, before AFC response is received, the SP 2800 * channels should be totally disabled. Therefore, return from 2801 * here so that super channel entry remain disabled 2802 */ 2803 else if (!reg_is_deployment_outdoor(pdev_priv_obj)) 2804 return; 2805 } 2806 2807 if (!mas_chan) 2808 return; 2809 2810 qdf_mem_copy(&temp_reg_chan, mas_chan, 2811 sizeof(struct regulatory_channel)); 2812 /* 2813 * Intersect the hardware frequency range with the 2814 * 6GHz channels. 2815 * If a channel is out of chip range, disable it. 2816 */ 2817 if (reg_is_chan_out_of_chip_range(&temp_reg_chan, pdev_priv_obj)) { 2818 reg_dis_chan_state_and_flags(&temp_reg_chan.state, 2819 &temp_reg_chan.chan_flags); 2820 } 2821 2822 super_chan_list = pdev_priv_obj->super_chan_list; 2823 copy_enh_chan_info_from_reg_chan(&super_chan_list[chn_idx], 2824 supp_pwr_mode, 2825 &temp_reg_chan); 2826 if (reg_is_chan_disabled_and_not_nol(&temp_reg_chan)) 2827 return; 2828 2829 reg_modify_super_chan_list_for_indoor_channels(pdev_priv_obj, chn_idx, 2830 supp_pwr_mode); 2831 2832 reg_dis_6g_chan_in_super_chan_list(pdev, &super_chan_list[chn_idx], 2833 supp_pwr_mode); 2834 2835 reg_dis_6g_edge_chan_in_enh_chan(pdev, &super_chan_list[chn_idx], 2836 chn_idx, supp_pwr_mode); 2837 reg_fill_best_pwr_mode(pdev_priv_obj, super_chan_list, chn_idx, 2838 supp_pwr_mode, temp_reg_chan.tx_power, 2839 max_eirp_pwr); 2840 reg_accumulate_pwr_type(supp_pwr_mode, super_chan_list, chn_idx); 2841 } 2842 2843 /** 2844 * reg_update_super_chan_entry() - Construct the super channel list entry for an 2845 * input channel index 2846 * @pdev_priv_obj: Pointer to pdev_priv_obj 2847 * @chn_idx: Channel index 2848 * 2849 * Return: void 2850 */ 2851 static void 2852 reg_update_super_chan_entry(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 2853 uint16_t chn_idx) 2854 { 2855 enum supported_6g_pwr_types supp_pwr_mode; 2856 uint8_t max_eirp_pwr = 0; 2857 2858 for (supp_pwr_mode = REG_AP_LPI; supp_pwr_mode <= REG_CLI_SUB_VLP; 2859 supp_pwr_mode++) { 2860 reg_update_sup_ch_entry_for_mode(pdev_priv_obj, supp_pwr_mode, 2861 chn_idx, &max_eirp_pwr); 2862 } 2863 } 2864 2865 /** 2866 * reg_compute_super_chan_list() - Construct the super channel list 2867 * @pdev_priv_obj: Pointer to pdev_priv_obj 2868 * 2869 * Return: void 2870 */ 2871 static void 2872 reg_compute_super_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 2873 { 2874 uint8_t i; 2875 2876 if (!pdev_priv_obj->is_6g_channel_list_populated) 2877 return; 2878 2879 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) 2880 reg_update_super_chan_entry(pdev_priv_obj, i); 2881 } 2882 #else /* CONFIG_BAND_6GHZ */ 2883 static void reg_init_pdev_super_chan_list( 2884 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 2885 { 2886 } 2887 2888 static inline void 2889 reg_compute_super_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 2890 { 2891 } 2892 #endif /* CONFIG_BAND_6GHZ */ 2893 2894 void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj 2895 *pdev_priv_obj) 2896 { 2897 reg_modify_6g_afc_chan_list(pdev_priv_obj); 2898 2899 reg_copy_6g_cur_mas_chan_list_to_cmn(pdev_priv_obj); 2900 2901 reg_compute_super_chan_list(pdev_priv_obj); 2902 2903 qdf_mem_copy(pdev_priv_obj->cur_chan_list, pdev_priv_obj->mas_chan_list, 2904 NUM_CHANNELS * sizeof(struct regulatory_channel)); 2905 2906 reg_modify_chan_list_for_freq_range(pdev_priv_obj->cur_chan_list, 2907 pdev_priv_obj->range_2g_low, 2908 pdev_priv_obj->range_2g_high, 2909 pdev_priv_obj->range_5g_low, 2910 pdev_priv_obj->range_5g_high); 2911 2912 reg_modify_chan_list_for_band(pdev_priv_obj->cur_chan_list, 2913 pdev_priv_obj->band_capability); 2914 2915 reg_modify_disable_chan_list_for_unii1_and_unii2a(pdev_priv_obj); 2916 2917 reg_modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list, 2918 pdev_priv_obj->dfs_enabled); 2919 2920 reg_modify_chan_list_for_nol_list(pdev_priv_obj->cur_chan_list); 2921 reg_modify_chan_list_for_static_puncture(pdev_priv_obj->cur_chan_list); 2922 2923 reg_modify_chan_list_for_indoor_channels(pdev_priv_obj); 2924 2925 reg_modify_chan_list_for_indoor_concurrency(pdev_priv_obj); 2926 2927 reg_modify_chan_list_for_fcc_channel(pdev_priv_obj); 2928 2929 reg_modify_chan_list_for_chan_144(pdev_priv_obj->cur_chan_list, 2930 pdev_priv_obj->en_chan_144); 2931 2932 reg_modify_chan_list_for_cached_channels(pdev_priv_obj); 2933 2934 reg_modify_chan_list_for_srd_channels(pdev_priv_obj->pdev_ptr, 2935 pdev_priv_obj->cur_chan_list); 2936 2937 reg_modify_chan_list_for_5dot9_ghz_channels(pdev_priv_obj->pdev_ptr, 2938 pdev_priv_obj-> 2939 cur_chan_list); 2940 2941 reg_modify_chan_list_for_max_chwidth_for_pwrmode( 2942 pdev_priv_obj->pdev_ptr, 2943 pdev_priv_obj->cur_chan_list, 2944 REG_CURRENT_PWR_MODE); 2945 2946 reg_modify_chan_list_for_6g_edge_channels(pdev_priv_obj->pdev_ptr, 2947 pdev_priv_obj-> 2948 cur_chan_list); 2949 2950 reg_populate_secondary_cur_chan_list(pdev_priv_obj); 2951 2952 reg_modify_chan_list_for_avoid_chan_ext(pdev_priv_obj); 2953 2954 reg_modify_sec_chan_list_for_6g_edge_chan(pdev_priv_obj); 2955 } 2956 2957 void reg_reset_reg_rules(struct reg_rule_info *reg_rules) 2958 { 2959 qdf_mem_zero(reg_rules, sizeof(*reg_rules)); 2960 } 2961 2962 #ifdef CONFIG_REG_CLIENT 2963 /** 2964 * reg_get_num_reg_rules() - Get number of reg rules. 2965 * @psoc_reg_rules: pointer to psoc reg rules 2966 * @pdev_priv_obj: pointer to pdev priv object 2967 * 2968 * Return: int 2969 */ 2970 static int reg_get_num_reg_rules( 2971 struct reg_rule_info *psoc_reg_rules, 2972 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 2973 { 2974 struct reg_rule_info *pdev_reg_rules; 2975 2976 pdev_reg_rules = &pdev_priv_obj->reg_rules; 2977 return pdev_reg_rules->num_of_reg_rules; 2978 } 2979 #else 2980 /** 2981 * reg_get_num_reg_rules() - Get number of reg rules. 2982 * @psoc_reg_rules: pointer to psoc reg rules 2983 * @pdev_priv_obj: pointer to pdev priv object 2984 * 2985 * Return: int. 2986 */ 2987 static int reg_get_num_reg_rules( 2988 struct reg_rule_info *psoc_reg_rules, 2989 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 2990 { 2991 enum reg_6g_ap_type cur_6g_ap_pwr_type; 2992 struct reg_rule_info *pdev_reg_rules; 2993 2994 cur_6g_ap_pwr_type = pdev_priv_obj->reg_cur_6g_ap_pwr_type; 2995 pdev_reg_rules = &pdev_priv_obj->reg_rules; 2996 2997 return (pdev_reg_rules->num_of_reg_rules + 2998 psoc_reg_rules->num_of_6g_ap_reg_rules[cur_6g_ap_pwr_type]); 2999 } 3000 #endif 3001 3002 #ifdef CONFIG_BAND_6GHZ 3003 #ifdef CONFIG_REG_CLIENT 3004 /** 3005 * reg_append_6g_reg_rules_in_pdev() - Append the 6G reg rules to the reg rules 3006 * list in pdev so that all currently used reg rules are in one common list 3007 * @pdev_priv_obj: Pointer to pdev private object 3008 * 3009 * Return: void 3010 */ 3011 static void reg_append_6g_reg_rules_in_pdev( 3012 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 3013 { 3014 struct reg_rule_info *pdev_reg_rules; 3015 enum reg_6g_ap_type cur_pwr_type = REG_INDOOR_AP; 3016 uint8_t num_reg_rules; 3017 3018 pdev_reg_rules = &pdev_priv_obj->reg_rules; 3019 3020 num_reg_rules = pdev_reg_rules->num_of_reg_rules; 3021 pdev_reg_rules->num_of_reg_rules += 3022 pdev_reg_rules->num_of_6g_client_reg_rules[cur_pwr_type]; 3023 3024 qdf_mem_copy(&pdev_reg_rules->reg_rules[num_reg_rules], 3025 pdev_reg_rules->reg_rules_6g_client[cur_pwr_type], 3026 pdev_reg_rules->num_of_6g_client_reg_rules[cur_pwr_type] * 3027 sizeof(struct cur_reg_rule)); 3028 } 3029 #else /* CONFIG_REG_CLIENT */ 3030 /** 3031 * reg_append_6g_reg_rules_in_pdev() - Append 6 GHz reg rules to reg rules list 3032 * @pdev_priv_obj: Pointer to pdev private object 3033 * 3034 * Append 6 GHz reg rules to the reg rules list in pdev so that all currently 3035 * used reg rules are in one common list. 3036 * 3037 * Return: void 3038 */ 3039 static void reg_append_6g_reg_rules_in_pdev( 3040 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 3041 { 3042 struct reg_rule_info *pdev_reg_rules; 3043 enum reg_6g_ap_type cur_pwr_type; 3044 uint8_t num_reg_rules; 3045 3046 cur_pwr_type = pdev_priv_obj->reg_cur_6g_ap_pwr_type; 3047 pdev_reg_rules = &pdev_priv_obj->reg_rules; 3048 3049 num_reg_rules = pdev_reg_rules->num_of_reg_rules; 3050 pdev_reg_rules->num_of_reg_rules += 3051 pdev_reg_rules->num_of_6g_ap_reg_rules[cur_pwr_type]; 3052 3053 qdf_mem_copy(&pdev_reg_rules->reg_rules[num_reg_rules], 3054 pdev_reg_rules->reg_rules_6g_ap[cur_pwr_type], 3055 pdev_reg_rules->num_of_6g_ap_reg_rules[cur_pwr_type] * 3056 sizeof(struct cur_reg_rule)); 3057 } 3058 #endif /* CONFIG_REG_CLIENT */ 3059 3060 /** 3061 * reg_copy_6g_reg_rules() - Copy the 6GHz reg rules from PSOC to PDEV 3062 * @pdev_reg_rules: Pointer to pdev reg rules 3063 * @psoc_reg_rules: Pointer to psoc reg rules 3064 * 3065 * Return: void 3066 */ 3067 static void reg_copy_6g_reg_rules(struct reg_rule_info *pdev_reg_rules, 3068 struct reg_rule_info *psoc_reg_rules) 3069 { 3070 uint32_t reg_rule_len_6g_ap, reg_rule_len_6g_client; 3071 uint8_t i; 3072 3073 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 3074 pdev_reg_rules->num_of_6g_ap_reg_rules[i] = 3075 psoc_reg_rules->num_of_6g_ap_reg_rules[i]; 3076 reg_rule_len_6g_ap = psoc_reg_rules->num_of_6g_ap_reg_rules[i] * 3077 sizeof(struct cur_reg_rule); 3078 qdf_mem_copy(pdev_reg_rules->reg_rules_6g_ap[i], 3079 psoc_reg_rules->reg_rules_6g_ap[i], 3080 reg_rule_len_6g_ap); 3081 3082 pdev_reg_rules->num_of_6g_client_reg_rules[i] = 3083 psoc_reg_rules->num_of_6g_client_reg_rules[i]; 3084 reg_rule_len_6g_client = 3085 psoc_reg_rules->num_of_6g_client_reg_rules[i] * 3086 sizeof(struct cur_reg_rule); 3087 qdf_mem_copy(pdev_reg_rules->reg_rules_6g_client[i], 3088 psoc_reg_rules->reg_rules_6g_client[i], 3089 reg_rule_len_6g_client); 3090 } 3091 } 3092 #else /* CONFIG_BAND_6GHZ */ 3093 static inline void reg_copy_6g_reg_rules(struct reg_rule_info *pdev_reg_rules, 3094 struct reg_rule_info *psoc_reg_rules) 3095 { 3096 } 3097 3098 static inline void 3099 reg_append_6g_reg_rules_in_pdev( 3100 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 3101 { 3102 } 3103 #endif /* CONFIG_BAND_6GHZ */ 3104 3105 void reg_save_reg_rules_to_pdev(struct reg_rule_info *psoc_reg_rules, 3106 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 3107 { 3108 uint32_t reg_rule_len; 3109 struct reg_rule_info *pdev_reg_rules; 3110 3111 qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock); 3112 3113 pdev_reg_rules = &pdev_priv_obj->reg_rules; 3114 reg_reset_reg_rules(pdev_reg_rules); 3115 3116 pdev_reg_rules->num_of_reg_rules = psoc_reg_rules->num_of_reg_rules; 3117 3118 if (!reg_get_num_reg_rules(psoc_reg_rules, pdev_priv_obj)) { 3119 qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock); 3120 reg_err("no reg rules in psoc"); 3121 return; 3122 } 3123 3124 reg_rule_len = pdev_reg_rules->num_of_reg_rules * 3125 sizeof(struct cur_reg_rule); 3126 qdf_mem_copy(pdev_reg_rules->reg_rules, psoc_reg_rules->reg_rules, 3127 reg_rule_len); 3128 3129 reg_copy_6g_reg_rules(pdev_reg_rules, psoc_reg_rules); 3130 reg_append_6g_reg_rules_in_pdev(pdev_priv_obj); 3131 3132 qdf_mem_copy(pdev_reg_rules->alpha2, pdev_priv_obj->current_country, 3133 REG_ALPHA2_LEN + 1); 3134 pdev_reg_rules->dfs_region = pdev_priv_obj->dfs_region; 3135 3136 qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock); 3137 } 3138 3139 #ifdef CONFIG_REG_CLIENT 3140 /** 3141 * reg_set_pdev_fcc_rules - Set pdev fcc rules array 3142 * @psoc_priv_obj - PSOC private object pointer 3143 * @pdev_priv_obj - PDEV private object pointer 3144 * 3145 */ 3146 3147 static void reg_set_pdev_fcc_rules( 3148 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj, 3149 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 3150 { 3151 if (!psoc_priv_obj) { 3152 reg_err("psoc priv obj is NULL"); 3153 return; 3154 } 3155 3156 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 3157 reg_err("reg pdev priv obj is NULL"); 3158 return; 3159 } 3160 3161 qdf_mem_copy(pdev_priv_obj->fcc_rules_ptr, 3162 psoc_priv_obj->fcc_rules_ptr, 3163 sizeof(struct cur_fcc_rule) * MAX_NUM_FCC_RULES); 3164 } 3165 #else 3166 static inline void reg_set_pdev_fcc_rules( 3167 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj, 3168 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 3169 { 3170 } 3171 #endif 3172 3173 void reg_propagate_mas_chan_list_to_pdev(struct wlan_objmgr_psoc *psoc, 3174 void *object, void *arg) 3175 { 3176 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object; 3177 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 3178 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 3179 enum direction *dir = arg; 3180 uint8_t pdev_id; 3181 uint8_t phy_id; 3182 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; 3183 struct reg_rule_info *psoc_reg_rules; 3184 3185 psoc_priv_obj = (struct wlan_regulatory_psoc_priv_obj *) 3186 wlan_objmgr_psoc_get_comp_private_obj( 3187 psoc, WLAN_UMAC_COMP_REGULATORY); 3188 3189 if (!psoc_priv_obj) { 3190 reg_err("psoc priv obj is NULL"); 3191 return; 3192 } 3193 3194 pdev_priv_obj = reg_get_pdev_obj(pdev); 3195 3196 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 3197 reg_err("reg pdev priv obj is NULL"); 3198 return; 3199 } 3200 3201 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 3202 3203 reg_tx_ops = reg_get_psoc_tx_ops(psoc); 3204 if (reg_tx_ops->get_phy_id_from_pdev_id) 3205 reg_tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id); 3206 else 3207 phy_id = pdev_id; 3208 3209 reg_set_pdev_fcc_rules(psoc_priv_obj, pdev_priv_obj); 3210 reg_init_pdev_mas_chan_list( 3211 pdev_priv_obj, 3212 &psoc_priv_obj->mas_chan_params[phy_id]); 3213 psoc_reg_rules = &psoc_priv_obj->mas_chan_params[phy_id].reg_rules; 3214 reg_save_reg_rules_to_pdev(psoc_reg_rules, pdev_priv_obj); 3215 reg_set_ap_pwr_type(pdev_priv_obj); 3216 reg_init_pdev_super_chan_list(pdev_priv_obj); 3217 pdev_priv_obj->chan_list_recvd = 3218 psoc_priv_obj->chan_list_recvd[phy_id]; 3219 3220 reg_init_indoor_channel_list(pdev); 3221 reg_compute_indoor_list_on_cc_change(psoc, pdev); 3222 3223 reg_update_max_phymode_chwidth_for_pdev(pdev); 3224 reg_update_channel_ranges(pdev); 3225 reg_modify_chan_list_for_outdoor(pdev_priv_obj); 3226 reg_compute_pdev_current_chan_list(pdev_priv_obj); 3227 3228 if (reg_tx_ops->fill_umac_legacy_chanlist) { 3229 reg_tx_ops->fill_umac_legacy_chanlist( 3230 pdev, pdev_priv_obj->cur_chan_list); 3231 } else { 3232 if (*dir == NORTHBOUND) 3233 reg_send_scheduler_msg_nb(psoc, pdev); 3234 else 3235 reg_send_scheduler_msg_sb(psoc, pdev); 3236 } 3237 } 3238 3239 /** 3240 * reg_populate_49g_band_channels() - For all the valid 4.9GHz regdb channels 3241 * in the master channel list, find the regulatory rules and call 3242 * reg_fill_channel_info() to populate master channel list with txpower, 3243 * antennagain, BW info, etc. 3244 * @reg_rule_5g: Pointer to regulatory rule. 3245 * @num_5g_reg_rules: Number of regulatory rules. 3246 * @min_bw_5g: Minimum regulatory bandwidth. 3247 * @mas_chan_list: Pointer to the master channel list. 3248 */ 3249 #ifdef CONFIG_49GHZ_CHAN 3250 static void 3251 reg_populate_49g_band_channels(struct cur_reg_rule *reg_rule_5g, 3252 uint32_t num_5g_reg_rules, 3253 uint16_t min_bw_5g, 3254 struct regulatory_channel *mas_chan_list) 3255 { 3256 reg_populate_band_channels(MIN_49GHZ_CHANNEL, 3257 MAX_49GHZ_CHANNEL, 3258 reg_rule_5g, 3259 num_5g_reg_rules, 3260 min_bw_5g, 3261 mas_chan_list); 3262 } 3263 #else 3264 static void 3265 reg_populate_49g_band_channels(struct cur_reg_rule *reg_rule_5g, 3266 uint32_t num_5g_reg_rules, 3267 uint16_t min_bw_5g, 3268 struct regulatory_channel *mas_chan_list) 3269 { 3270 } 3271 #endif /* CONFIG_49GHZ_CHAN */ 3272 3273 #ifdef CONFIG_BAND_6GHZ 3274 /** 3275 * reg_populate_6g_band_channels() - For all the valid 6GHz regdb channels 3276 * in the master channel list, find the regulatory rules and call 3277 * reg_fill_channel_info() to populate master channel list with txpower, 3278 * antennagain, BW info, etc. 3279 * @reg_rule_5g: Pointer to regulatory rule. 3280 * @num_5g_reg_rules: Number of regulatory rules. 3281 * @min_bw_5g: Minimum regulatory bandwidth. 3282 * @mas_chan_list: Pointer to the master channel list. 3283 */ 3284 static void 3285 reg_populate_6g_band_channels(struct cur_reg_rule *reg_rule_5g, 3286 uint32_t num_5g_reg_rules, 3287 uint16_t min_bw_5g, 3288 struct regulatory_channel *mas_chan_list) 3289 { 3290 reg_populate_band_channels(MIN_6GHZ_CHANNEL, 3291 MAX_6GHZ_CHANNEL, 3292 reg_rule_5g, 3293 num_5g_reg_rules, 3294 min_bw_5g, 3295 mas_chan_list); 3296 } 3297 3298 void 3299 reg_copy_from_super_chan_info_to_reg_channel(struct regulatory_channel *chan, 3300 const struct super_chan_info sc_entry, 3301 enum supported_6g_pwr_types 3302 in_6g_pwr_mode) 3303 { 3304 if (in_6g_pwr_mode == REG_BEST_PWR_MODE) 3305 in_6g_pwr_mode = sc_entry.best_power_mode; 3306 3307 if (reg_is_supp_pwr_mode_invalid(in_6g_pwr_mode)) 3308 return; 3309 3310 chan->state = sc_entry.state_arr[in_6g_pwr_mode]; 3311 chan->chan_flags = sc_entry.chan_flags_arr[in_6g_pwr_mode]; 3312 chan->tx_power = sc_entry.reg_chan_pwr[in_6g_pwr_mode].tx_power; 3313 chan->min_bw = sc_entry.min_bw[in_6g_pwr_mode]; 3314 chan->max_bw = sc_entry.max_bw[in_6g_pwr_mode]; 3315 chan->psd_flag = sc_entry.reg_chan_pwr[in_6g_pwr_mode].psd_flag; 3316 chan->psd_eirp = sc_entry.reg_chan_pwr[in_6g_pwr_mode].psd_eirp; 3317 } 3318 3319 static QDF_STATUS 3320 reg_get_6g_pwrmode_chan_list(struct wlan_regulatory_pdev_priv_obj 3321 *pdev_priv_obj, 3322 struct regulatory_channel *chan_list, 3323 enum supported_6g_pwr_types in_6g_pwr_mode) 3324 { 3325 uint8_t i; 3326 3327 /* 3328 * If 6GHz channel list is present, populate it with desired 3329 * power type 3330 */ 3331 if (!pdev_priv_obj->is_6g_channel_list_populated) { 3332 reg_debug("6G channel list is empty"); 3333 return QDF_STATUS_SUCCESS; 3334 } 3335 3336 /* Copy the regulatory_channel fields from super_chan_info */ 3337 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) 3338 reg_copy_from_super_chan_info_to_reg_channel( 3339 &chan_list[i + MIN_6GHZ_CHANNEL], 3340 pdev_priv_obj->super_chan_list[i], 3341 in_6g_pwr_mode); 3342 3343 return QDF_STATUS_SUCCESS; 3344 } 3345 #else 3346 static void 3347 reg_populate_6g_band_channels(struct cur_reg_rule *reg_rule_5g, 3348 uint32_t num_5g_reg_rules, 3349 uint16_t min_bw_5g, 3350 struct regulatory_channel *mas_chan_list) 3351 { 3352 } 3353 3354 static inline QDF_STATUS 3355 reg_get_6g_pwrmode_chan_list(struct wlan_regulatory_pdev_priv_obj 3356 *pdev_priv_obj, 3357 struct regulatory_channel *chan_list, 3358 enum supported_6g_pwr_types in_6g_pwr_mode) 3359 { 3360 return QDF_STATUS_E_INVAL; 3361 } 3362 #endif /* CONFIG_BAND_6GHZ */ 3363 3364 QDF_STATUS reg_get_pwrmode_chan_list(struct wlan_objmgr_pdev *pdev, 3365 struct regulatory_channel *chan_list, 3366 enum supported_6g_pwr_types in_6g_pwr_mode) 3367 { 3368 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 3369 3370 if (!pdev) { 3371 reg_err_rl("invalid pdev"); 3372 return QDF_STATUS_E_INVAL; 3373 } 3374 3375 if (!chan_list) { 3376 reg_err_rl("invalid chanlist"); 3377 return QDF_STATUS_E_INVAL; 3378 } 3379 3380 pdev_priv_obj = reg_get_pdev_obj(pdev); 3381 3382 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 3383 reg_err_rl("reg pdev priv obj is NULL"); 3384 return QDF_STATUS_E_INVAL; 3385 } 3386 3387 /* Get the current channel list */ 3388 qdf_mem_copy(chan_list, pdev_priv_obj->cur_chan_list, 3389 NUM_CHANNELS * sizeof(struct regulatory_channel)); 3390 3391 if (in_6g_pwr_mode == REG_CURRENT_PWR_MODE) 3392 return QDF_STATUS_SUCCESS; 3393 3394 return reg_get_6g_pwrmode_chan_list(pdev_priv_obj, chan_list, 3395 in_6g_pwr_mode); 3396 } 3397 3398 #ifdef CONFIG_REG_CLIENT 3399 /** 3400 * reg_send_ctl_info() - Send CTL info to firmware when regdb is not offloaded 3401 * @soc_reg: soc private object for regulatory 3402 * @regulatory_info: regulatory info 3403 * @tx_ops: send operations for regulatory component 3404 * 3405 * Return: QDF_STATUS 3406 */ 3407 static QDF_STATUS 3408 reg_send_ctl_info(struct wlan_regulatory_psoc_priv_obj *soc_reg, 3409 struct cur_regulatory_info *regulatory_info, 3410 struct wlan_lmac_if_reg_tx_ops *tx_ops) 3411 { 3412 struct wlan_objmgr_psoc *psoc = regulatory_info->psoc; 3413 struct reg_ctl_params params = {0}; 3414 QDF_STATUS status; 3415 uint16_t regd_index; 3416 uint32_t index_2g, index_5g; 3417 3418 if (soc_reg->offload_enabled) 3419 return QDF_STATUS_SUCCESS; 3420 3421 if (!tx_ops || !tx_ops->send_ctl_info) { 3422 reg_err("No regulatory tx_ops"); 3423 return QDF_STATUS_E_FAULT; 3424 } 3425 3426 status = reg_get_rdpair_from_regdmn_id(regulatory_info->reg_dmn_pair, 3427 ®d_index); 3428 if (QDF_IS_STATUS_ERROR(status)) { 3429 reg_err("Failed to get regdomain index for regdomain pair: %x", 3430 regulatory_info->reg_dmn_pair); 3431 return status; 3432 } 3433 3434 index_2g = g_reg_dmn_pairs[regd_index].dmn_id_2g; 3435 index_5g = g_reg_dmn_pairs[regd_index].dmn_id_5g; 3436 params.ctl_2g = regdomains_2g[index_2g].ctl_val; 3437 params.ctl_5g = regdomains_5g[index_5g].ctl_val; 3438 params.regd_2g = reg_2g_sub_dmn_code[index_2g]; 3439 params.regd_5g = reg_5g_sub_dmn_code[index_5g]; 3440 3441 if (reg_is_world_ctry_code(regulatory_info->reg_dmn_pair)) 3442 params.regd = regulatory_info->reg_dmn_pair; 3443 else 3444 params.regd = regulatory_info->ctry_code | COUNTRY_ERD_FLAG; 3445 3446 reg_debug("regdomain pair = %u, regdomain index = %u", 3447 regulatory_info->reg_dmn_pair, regd_index); 3448 reg_debug("index_2g = %u, index_5g = %u, ctl_2g = %x, ctl_5g = %x", 3449 index_2g, index_5g, params.ctl_2g, params.ctl_5g); 3450 reg_debug("regd_2g = %x, regd_5g = %x, regd = %x", 3451 params.regd_2g, params.regd_5g, params.regd); 3452 3453 status = tx_ops->send_ctl_info(psoc, ¶ms); 3454 if (QDF_IS_STATUS_ERROR(status)) 3455 reg_err("Failed to send CTL info to firmware"); 3456 3457 return status; 3458 } 3459 #else 3460 static QDF_STATUS 3461 reg_send_ctl_info(struct wlan_regulatory_psoc_priv_obj *soc_reg, 3462 struct cur_regulatory_info *regulatory_info, 3463 struct wlan_lmac_if_reg_tx_ops *tx_ops) 3464 { 3465 return QDF_STATUS_SUCCESS; 3466 } 3467 #endif 3468 3469 /** 3470 * reg_soc_vars_reset_on_failure() - Reset the PSOC private object variables 3471 * when there is a failure 3472 * @status_code: status code of CC setting event 3473 * @soc_reg: soc private object for regulatory 3474 * @tx_ops: send operations for regulatory component 3475 * @psoc: pointer to PSOC object 3476 * @dbg_id: object manager reference debug ID 3477 * @phy_id: physical ID 3478 * 3479 * Return: QDF_STATUS 3480 */ 3481 static QDF_STATUS 3482 reg_soc_vars_reset_on_failure(enum cc_setting_code status_code, 3483 struct wlan_regulatory_psoc_priv_obj *soc_reg, 3484 struct wlan_lmac_if_reg_tx_ops *tx_ops, 3485 struct wlan_objmgr_psoc *psoc, 3486 wlan_objmgr_ref_dbgid dbg_id, 3487 uint8_t phy_id) 3488 { 3489 struct wlan_objmgr_pdev *pdev; 3490 3491 if (status_code != REG_SET_CC_STATUS_PASS) { 3492 reg_err("Set country code failed, status code %d", 3493 status_code); 3494 3495 pdev = wlan_objmgr_get_pdev_by_id(psoc, phy_id, dbg_id); 3496 if (!pdev) { 3497 reg_err("pdev is NULL"); 3498 return QDF_STATUS_E_FAILURE; 3499 } 3500 3501 if (tx_ops->set_country_failed) 3502 tx_ops->set_country_failed(pdev); 3503 3504 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 3505 3506 if (status_code != REG_CURRENT_ALPHA2_NOT_FOUND) 3507 return QDF_STATUS_E_FAILURE; 3508 3509 soc_reg->new_user_ctry_pending[phy_id] = false; 3510 soc_reg->new_11d_ctry_pending[phy_id] = false; 3511 soc_reg->world_country_pending[phy_id] = true; 3512 } 3513 3514 return QDF_STATUS_SUCCESS; 3515 } 3516 3517 static void reg_init_legacy_master_chan(struct regulatory_channel *dst_list, 3518 struct wlan_regulatory_psoc_priv_obj *soc_reg) 3519 { 3520 reg_init_chan(dst_list, 0, NUM_CHANNELS - 1, 0, soc_reg); 3521 } 3522 3523 #ifdef CONFIG_REG_CLIENT 3524 /** 3525 * reg_set_psoc_fcc_rules - Set PSOC fcc rules array 3526 * @soc_reg - PSOC private object pointer 3527 * @regulat_info - Regulatory info pointer 3528 * 3529 * Return - QDF_STATUS 3530 */ 3531 static QDF_STATUS reg_set_psoc_fcc_rules( 3532 struct wlan_regulatory_psoc_priv_obj *soc_reg, 3533 struct cur_regulatory_info *regulat_info) 3534 { 3535 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) { 3536 reg_err("psoc reg component is NULL"); 3537 return QDF_STATUS_E_FAILURE; 3538 } 3539 3540 if (regulat_info->num_fcc_rules) 3541 qdf_mem_copy(soc_reg->fcc_rules_ptr, 3542 regulat_info->fcc_rules_ptr, 3543 sizeof(struct cur_fcc_rule) * 3544 regulat_info->num_fcc_rules); 3545 3546 return QDF_STATUS_SUCCESS; 3547 } 3548 #else 3549 static inline QDF_STATUS reg_set_psoc_fcc_rules( 3550 struct wlan_regulatory_psoc_priv_obj *soc_reg, 3551 struct cur_regulatory_info *regulat_info) 3552 { 3553 return QDF_STATUS_SUCCESS; 3554 } 3555 #endif 3556 3557 #ifdef CONFIG_BAND_6GHZ 3558 static void reg_init_2g_5g_master_chan(struct regulatory_channel *dst_list, 3559 struct wlan_regulatory_psoc_priv_obj *soc_reg) 3560 { 3561 reg_init_chan(dst_list, 0, MAX_5GHZ_CHANNEL, 0, soc_reg); 3562 } 3563 3564 /** 3565 * reg_store_regulatory_ext_info_to_socpriv() - Copy ext info from regulatory 3566 * to regulatory PSOC private obj 3567 * @soc_reg: soc private object for regulatory 3568 * @regulat_info: regulatory info from CC event 3569 * @phy_id: physical ID 3570 * 3571 * Return: none 3572 */ 3573 static void reg_store_regulatory_ext_info_to_socpriv( 3574 struct wlan_regulatory_psoc_priv_obj *soc_reg, 3575 struct cur_regulatory_info *regulat_info, 3576 uint8_t phy_id) 3577 { 3578 uint32_t i; 3579 3580 soc_reg->num_phy = regulat_info->num_phy; 3581 soc_reg->mas_chan_params[phy_id].phybitmap = regulat_info->phybitmap; 3582 soc_reg->mas_chan_params[phy_id].dfs_region = regulat_info->dfs_region; 3583 soc_reg->mas_chan_params[phy_id].ctry_code = regulat_info->ctry_code; 3584 soc_reg->mas_chan_params[phy_id].reg_dmn_pair = 3585 regulat_info->reg_dmn_pair; 3586 soc_reg->mas_chan_params[phy_id].reg_6g_superid = 3587 regulat_info->domain_code_6g_super_id; 3588 soc_reg->mas_chan_params[phy_id].max_bw_5g = regulat_info->max_bw_5g; 3589 qdf_mem_copy(soc_reg->mas_chan_params[phy_id].current_country, 3590 regulat_info->alpha2, 3591 REG_ALPHA2_LEN + 1); 3592 qdf_mem_copy(soc_reg->cur_country, 3593 regulat_info->alpha2, 3594 REG_ALPHA2_LEN + 1); 3595 reg_debug("set cur_country %.2s", soc_reg->cur_country); 3596 3597 soc_reg->mas_chan_params[phy_id].ap_pwr_type = REG_INDOOR_AP; 3598 soc_reg->mas_chan_params[phy_id].client_type = 3599 regulat_info->client_type; 3600 soc_reg->mas_chan_params[phy_id].rnr_tpe_usable = 3601 regulat_info->rnr_tpe_usable; 3602 soc_reg->mas_chan_params[phy_id].unspecified_ap_usable = 3603 regulat_info->unspecified_ap_usable; 3604 soc_reg->mas_chan_params[phy_id].reg_6g_thresh_priority_freq = 3605 regulat_info->reg_6g_thresh_priority_freq; 3606 3607 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 3608 soc_reg->domain_code_6g_ap[i] = 3609 regulat_info->domain_code_6g_ap[i]; 3610 3611 soc_reg->mas_chan_params[phy_id]. 3612 is_6g_channel_list_populated = true; 3613 3614 qdf_mem_copy(soc_reg->domain_code_6g_client[i], 3615 regulat_info->domain_code_6g_client[i], 3616 REG_MAX_CLIENT_TYPE * sizeof(uint8_t)); 3617 } 3618 } 3619 3620 #ifdef WLAN_FEATURE_11BE 3621 static bool 3622 reg_is_bonded_ch_subset_of_regrule(struct cur_reg_rule *cur_rule_ptr, 3623 const struct bonded_channel_freq 3624 *bonded_ch_ptr) 3625 { 3626 if (bonded_ch_ptr->start_freq >= cur_rule_ptr->start_freq && 3627 bonded_ch_ptr->end_freq <= cur_rule_ptr->end_freq) 3628 return true; 3629 3630 return false; 3631 } 3632 #endif 3633 3634 /** 3635 * reg_is_5g_240chan_in_rule() - Determine if the given reg rule supports 3636 * 5g 240MHZ chan [100 - 144] and the BW of the rule is greater than 160MHZ. 3637 * @cur_rule_ptr: Pointer to struct cur_reg_rule 3638 * @bonded_ch_ptr: Pointer to const struct bonded_channel_freq 3639 * 3640 * Return -True if 240 chan rule is found, false otherwise. 3641 */ 3642 #ifdef WLAN_FEATURE_11BE 3643 static bool 3644 reg_is_5g_240chan_in_rule(struct cur_reg_rule *cur_rule_ptr, 3645 const struct bonded_channel_freq *bonded_ch_ptr) 3646 { 3647 if (!bonded_ch_ptr) 3648 return false; 3649 3650 if (reg_is_bonded_ch_subset_of_regrule(cur_rule_ptr, bonded_ch_ptr) && 3651 cur_rule_ptr->max_bw > BW_160_MHZ) 3652 return true; 3653 3654 return false; 3655 } 3656 #endif 3657 3658 /** 3659 * reg_is_chip_cc_11be_cap() - Determine if country supports a max BW 3660 * greater than 160MHZ and if chip is 11BE capable. 3661 * @psoc: Pointer to struct wlan_objmgr_psoc 3662 * @phy_id: Phy-id 3663 * @max_cc_bw: Maximum 5g BW supported by the country 3664 * 3665 * Return - True if cc_max is greater than 160MHZ and chip is 11BE cap, 3666 * false otherwise. 3667 */ 3668 #ifdef WLAN_FEATURE_11BE 3669 static bool reg_is_chip_cc_11be_cap(struct wlan_objmgr_psoc *psoc, 3670 uint16_t phy_id, 3671 uint16_t max_cc_bw) 3672 { 3673 struct wlan_lmac_if_reg_tx_ops *tx_ops; 3674 3675 tx_ops = reg_get_psoc_tx_ops(psoc); 3676 if (!tx_ops) 3677 return false; 3678 3679 if (max_cc_bw > BW_160_MHZ && tx_ops->is_chip_11be(psoc, phy_id)) 3680 return true; 3681 3682 return false; 3683 } 3684 #endif 3685 3686 /** 3687 * reg_modify_max_bw_for_240mhz_5g_chans() - Manually update the bandwidh 3688 * of the 240MHz channels in 5GHz band [IEEE channels 100 - 144 support 240MHz 3689 * bandwidth using puncturing; 240MHz = 320MHz - 80Mhz(punctured)]. 3690 * The max bandwidth for these channels should be 320MHz. 3691 * 3692 * Modify reg rule BW of 100 - 144 channels to 320 if 3693 * a) Chip supports 11BE 3694 * b) Country supports 320MHZ BW. 3695 * c) Reg rule BW advertised by FW is 240MHZ. 3696 * d) Channel is between 5500 and 5720. 3697 * 3698 * @regulat_info: Pointer to struct cur_regulatory_info 3699 * @reg_rule_5g: Pointer to struct cur_reg_rule 3700 */ 3701 #ifdef WLAN_FEATURE_11BE 3702 static void 3703 reg_modify_max_bw_for_240mhz_5g_chans(struct cur_regulatory_info *regulat_info, 3704 struct cur_reg_rule *reg_rule_5g) 3705 3706 { 3707 #define FREQ_5500_MHZ 5500 3708 3709 uint16_t num_5g_reg_rules = regulat_info->num_5g_reg_rules; 3710 uint16_t rule_num; 3711 struct cur_reg_rule *cur_rule_ptr; 3712 const struct bonded_channel_freq *bonded_ch_ptr; 3713 3714 bonded_ch_ptr = reg_get_bonded_chan_entry(FREQ_5500_MHZ, 3715 CH_WIDTH_320MHZ, 0); 3716 if (!reg_is_chip_cc_11be_cap(regulat_info->psoc, 3717 regulat_info->phy_id, 3718 regulat_info->max_bw_5g)) 3719 return; 3720 3721 for (rule_num = 0, cur_rule_ptr = reg_rule_5g; 3722 rule_num < num_5g_reg_rules; cur_rule_ptr++, rule_num++) { 3723 if (reg_is_5g_240chan_in_rule(cur_rule_ptr, bonded_ch_ptr)) { 3724 cur_rule_ptr->max_bw = BW_320_MHZ; 3725 break; 3726 } 3727 } 3728 } 3729 #else 3730 static void 3731 reg_modify_max_bw_for_240mhz_5g_chans(struct cur_regulatory_info *regulat_info, 3732 struct cur_reg_rule *reg_rule_5g) 3733 { 3734 } 3735 #endif 3736 3737 /** 3738 * reg_is_pwrmode_not_required - Check if given power mode is needed. 3739 * @soc_reg: soc private object for regulatory 3740 * @pwr_type: input AP power type 3741 * 3742 * Return: True if deployemnt is outdoor and power type is LPI, else false. 3743 */ 3744 #if !defined(CONFIG_REG_CLIENT) && defined(CONFIG_AFC_SUPPORT) 3745 static bool reg_is_pwrmode_not_required( 3746 struct wlan_regulatory_psoc_priv_obj *soc_reg, 3747 enum reg_6g_ap_type pwr_type) 3748 { 3749 /* 3750 * In outdoor deployment, LPI(AP INDDOR and CLI INDOOR) 3751 * rules are not needed. 3752 */ 3753 return ((soc_reg->reg_afc_dev_type == AFC_DEPLOYMENT_OUTDOOR) && 3754 (pwr_type == REG_INDOOR_AP)); 3755 } 3756 #else 3757 static bool reg_is_pwrmode_not_required( 3758 struct wlan_regulatory_psoc_priv_obj *soc_reg, 3759 enum reg_6g_ap_type pwr_mode) 3760 { 3761 return false; 3762 } 3763 #endif 3764 3765 /** 3766 * reg_fill_master_channels() - Fill the master channel lists based on the 3767 * regulatory rules 3768 * @regulat_info: regulatory info 3769 * @reg_rules: regulatory rules 3770 * @client_mobility_type: client mobility type 3771 * @mas_chan_list_2g_5g: master chan list to fill with 2GHz and 5GHz channels 3772 * @mas_chan_list_6g_ap: master AP chan list to fill with 6GHz channels 3773 * @mas_chan_list_6g_client: master client chan list to fill with 6GHz channels 3774 * @soc_reg: soc private object for regulatory 3775 * 3776 * Return: QDF_STATUS 3777 */ 3778 static QDF_STATUS 3779 reg_fill_master_channels(struct cur_regulatory_info *regulat_info, 3780 struct reg_rule_info *reg_rules, 3781 enum reg_6g_client_type client_mobility_type, 3782 struct regulatory_channel *mas_chan_list_2g_5g, 3783 struct regulatory_channel *mas_chan_list_6g_ap[REG_CURRENT_MAX_AP_TYPE], 3784 struct regulatory_channel *mas_chan_list_6g_client 3785 [REG_CURRENT_MAX_AP_TYPE][REG_MAX_CLIENT_TYPE], 3786 struct wlan_regulatory_psoc_priv_obj *soc_reg) 3787 { 3788 uint32_t i, j, k, curr_reg_rule_location; 3789 uint32_t num_2g_reg_rules, num_5g_reg_rules; 3790 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 3791 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 3792 struct cur_reg_rule *reg_rule_2g, *reg_rule_5g, 3793 *reg_rule_6g_ap[REG_CURRENT_MAX_AP_TYPE], 3794 **reg_rule_6g_client[REG_CURRENT_MAX_AP_TYPE]; 3795 uint32_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g, 3796 min_bw_6g_ap[REG_CURRENT_MAX_AP_TYPE], 3797 max_bw_6g_ap[REG_CURRENT_MAX_AP_TYPE], 3798 *min_bw_6g_client[REG_CURRENT_MAX_AP_TYPE], 3799 *max_bw_6g_client[REG_CURRENT_MAX_AP_TYPE]; 3800 3801 min_bw_2g = regulat_info->min_bw_2g; 3802 max_bw_2g = regulat_info->max_bw_2g; 3803 reg_rule_2g = regulat_info->reg_rules_2g_ptr; 3804 num_2g_reg_rules = regulat_info->num_2g_reg_rules; 3805 reg_update_max_bw_per_rule(num_2g_reg_rules, reg_rule_2g, max_bw_2g); 3806 3807 min_bw_5g = regulat_info->min_bw_5g; 3808 max_bw_5g = regulat_info->max_bw_5g; 3809 reg_rule_5g = regulat_info->reg_rules_5g_ptr; 3810 num_5g_reg_rules = regulat_info->num_5g_reg_rules; 3811 reg_update_max_bw_per_rule(num_5g_reg_rules, reg_rule_5g, max_bw_5g); 3812 3813 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 3814 min_bw_6g_ap[i] = regulat_info->min_bw_6g_ap[i]; 3815 max_bw_6g_ap[i] = regulat_info->max_bw_6g_ap[i]; 3816 reg_rule_6g_ap[i] = regulat_info->reg_rules_6g_ap_ptr[i]; 3817 num_6g_reg_rules_ap[i] = regulat_info->num_6g_reg_rules_ap[i]; 3818 reg_update_max_bw_per_rule(num_6g_reg_rules_ap[i], 3819 reg_rule_6g_ap[i], max_bw_6g_ap[i]); 3820 } 3821 3822 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 3823 min_bw_6g_client[j] = regulat_info->min_bw_6g_client[j]; 3824 max_bw_6g_client[j] = regulat_info->max_bw_6g_client[j]; 3825 reg_rule_6g_client[j] = 3826 regulat_info->reg_rules_6g_client_ptr[j]; 3827 num_6g_reg_rules_client[j] = 3828 regulat_info->num_6g_reg_rules_client[j]; 3829 for (k = 0; k < REG_MAX_CLIENT_TYPE; k++) { 3830 reg_update_max_bw_per_rule( 3831 num_6g_reg_rules_client[j][k], 3832 reg_rule_6g_client[j][k], 3833 max_bw_6g_client[j][k]); 3834 } 3835 } 3836 3837 reg_reset_reg_rules(reg_rules); 3838 3839 reg_rules->num_of_reg_rules = num_5g_reg_rules + num_2g_reg_rules; 3840 3841 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 3842 reg_rules->num_of_6g_ap_reg_rules[i] = num_6g_reg_rules_ap[i]; 3843 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 3844 reg_err("number of reg rules for 6g ap exceeds limit"); 3845 return QDF_STATUS_E_FAILURE; 3846 } 3847 3848 reg_rules->num_of_6g_client_reg_rules[i] = 3849 num_6g_reg_rules_client[i][client_mobility_type]; 3850 for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) { 3851 if (num_6g_reg_rules_client[i][j] > MAX_6G_REG_RULES) { 3852 reg_err("number of reg rules for 6g client exceeds limit"); 3853 return QDF_STATUS_E_FAILURE; 3854 } 3855 } 3856 } 3857 3858 if (reg_rules->num_of_reg_rules > MAX_REG_RULES) { 3859 reg_err("number of reg rules exceeds limit"); 3860 return QDF_STATUS_E_FAILURE; 3861 } 3862 3863 if (reg_rules->num_of_reg_rules) { 3864 if (num_2g_reg_rules) 3865 qdf_mem_copy(reg_rules->reg_rules, 3866 reg_rule_2g, num_2g_reg_rules * 3867 sizeof(struct cur_reg_rule)); 3868 curr_reg_rule_location = num_2g_reg_rules; 3869 if (num_5g_reg_rules) { 3870 qdf_mem_copy(reg_rules->reg_rules + 3871 curr_reg_rule_location, reg_rule_5g, 3872 num_5g_reg_rules * 3873 sizeof(struct cur_reg_rule)); 3874 reg_modify_max_bw_for_240mhz_5g_chans(regulat_info, 3875 reg_rule_5g); 3876 } 3877 } 3878 3879 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 3880 if (num_6g_reg_rules_ap[i]) 3881 qdf_mem_copy(reg_rules->reg_rules_6g_ap[i], 3882 reg_rule_6g_ap[i], 3883 num_6g_reg_rules_ap[i] * 3884 sizeof(struct cur_reg_rule)); 3885 3886 if (num_6g_reg_rules_client[i][client_mobility_type]) 3887 qdf_mem_copy(reg_rules->reg_rules_6g_client[i], 3888 reg_rule_6g_client[i][client_mobility_type], 3889 num_6g_reg_rules_client[i] 3890 [client_mobility_type] * 3891 sizeof(struct cur_reg_rule)); 3892 } 3893 3894 3895 if (num_5g_reg_rules) 3896 reg_do_auto_bw_correction(num_5g_reg_rules, 3897 reg_rule_5g, max_bw_5g); 3898 3899 if (num_2g_reg_rules) 3900 reg_populate_band_channels(MIN_24GHZ_CHANNEL, MAX_24GHZ_CHANNEL, 3901 reg_rule_2g, num_2g_reg_rules, 3902 min_bw_2g, mas_chan_list_2g_5g); 3903 3904 if (num_5g_reg_rules) { 3905 reg_populate_band_channels(MIN_5GHZ_CHANNEL, MAX_5GHZ_CHANNEL, 3906 reg_rule_5g, num_5g_reg_rules, 3907 min_bw_5g, mas_chan_list_2g_5g); 3908 reg_populate_49g_band_channels(reg_rule_5g, 3909 num_5g_reg_rules, 3910 min_bw_5g, 3911 mas_chan_list_2g_5g); 3912 } 3913 3914 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 3915 if (reg_is_pwrmode_not_required(soc_reg, i)) 3916 continue; 3917 3918 if (num_6g_reg_rules_ap[i]) 3919 reg_populate_band_channels_ext_for_6g(0, 3920 NUM_6GHZ_CHANNELS - 1, 3921 reg_rule_6g_ap[i], 3922 num_6g_reg_rules_ap[i], 3923 min_bw_6g_ap[i], 3924 mas_chan_list_6g_ap[i]); 3925 3926 for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) { 3927 if (num_6g_reg_rules_client[i][j]) 3928 reg_populate_band_channels_ext_for_6g(0, 3929 NUM_6GHZ_CHANNELS - 1, 3930 reg_rule_6g_client[i][j], 3931 num_6g_reg_rules_client[i][j], 3932 min_bw_6g_client[i][j], 3933 mas_chan_list_6g_client[i][j]); 3934 } 3935 } 3936 3937 return QDF_STATUS_SUCCESS; 3938 } 3939 3940 /** 3941 * reg_set_socpriv_vars() - Set the regulatory PSOC variables based on 3942 * pending country status 3943 * @soc_reg: regulatory PSOC private object 3944 * @regulat_info: regulatory info 3945 * @psoc: pointer to PSOC object 3946 * @phy_id: physical ID 3947 * 3948 * Return: none 3949 */ 3950 static void reg_set_socpriv_vars(struct wlan_regulatory_psoc_priv_obj *soc_reg, 3951 struct cur_regulatory_info *regulat_info, 3952 struct wlan_objmgr_psoc *psoc, 3953 uint8_t phy_id) 3954 { 3955 soc_reg->chan_list_recvd[phy_id] = true; 3956 3957 if (soc_reg->new_user_ctry_pending[phy_id]) { 3958 soc_reg->new_user_ctry_pending[phy_id] = false; 3959 soc_reg->cc_src = SOURCE_USERSPACE; 3960 soc_reg->user_ctry_set = true; 3961 reg_debug("new user country is set"); 3962 reg_run_11d_state_machine(psoc); 3963 } else if (soc_reg->new_init_ctry_pending[phy_id]) { 3964 soc_reg->new_init_ctry_pending[phy_id] = false; 3965 soc_reg->cc_src = SOURCE_USERSPACE; 3966 reg_debug("new init country is set"); 3967 } else if (soc_reg->new_11d_ctry_pending[phy_id]) { 3968 soc_reg->new_11d_ctry_pending[phy_id] = false; 3969 soc_reg->cc_src = SOURCE_11D; 3970 soc_reg->user_ctry_set = false; 3971 reg_run_11d_state_machine(psoc); 3972 } else if (soc_reg->world_country_pending[phy_id]) { 3973 soc_reg->world_country_pending[phy_id] = false; 3974 soc_reg->cc_src = SOURCE_CORE; 3975 soc_reg->user_ctry_set = false; 3976 reg_run_11d_state_machine(psoc); 3977 } else { 3978 if (soc_reg->cc_src == SOURCE_UNKNOWN && 3979 soc_reg->num_phy == phy_id + 1) 3980 soc_reg->cc_src = SOURCE_DRIVER; 3981 3982 qdf_mem_copy(soc_reg->mas_chan_params[phy_id].default_country, 3983 regulat_info->alpha2, 3984 REG_ALPHA2_LEN + 1); 3985 3986 soc_reg->mas_chan_params[phy_id].def_country_code = 3987 regulat_info->ctry_code; 3988 soc_reg->mas_chan_params[phy_id].def_region_domain = 3989 regulat_info->reg_dmn_pair; 3990 3991 if (soc_reg->cc_src == SOURCE_DRIVER) { 3992 qdf_mem_copy(soc_reg->def_country, 3993 regulat_info->alpha2, 3994 REG_ALPHA2_LEN + 1); 3995 3996 soc_reg->def_country_code = regulat_info->ctry_code; 3997 soc_reg->def_region_domain = 3998 regulat_info->reg_dmn_pair; 3999 4000 if (reg_is_world_alpha2(regulat_info->alpha2)) { 4001 soc_reg->cc_src = SOURCE_CORE; 4002 reg_run_11d_state_machine(psoc); 4003 } 4004 } 4005 } 4006 } 4007 4008 QDF_STATUS reg_process_master_chan_list_ext( 4009 struct cur_regulatory_info *regulat_info) 4010 { 4011 struct wlan_regulatory_psoc_priv_obj *soc_reg; 4012 uint32_t i, j; 4013 struct regulatory_channel *mas_chan_list_2g_5g, 4014 *mas_chan_list_6g_ap[REG_CURRENT_MAX_AP_TYPE], 4015 *mas_chan_list_6g_client[REG_CURRENT_MAX_AP_TYPE] 4016 [REG_MAX_CLIENT_TYPE]; 4017 struct wlan_objmgr_psoc *psoc; 4018 wlan_objmgr_ref_dbgid dbg_id; 4019 enum direction dir; 4020 uint8_t phy_id; 4021 uint8_t pdev_id; 4022 struct wlan_objmgr_pdev *pdev; 4023 struct wlan_lmac_if_reg_tx_ops *tx_ops; 4024 QDF_STATUS status; 4025 struct mas_chan_params *this_mchan_params; 4026 4027 psoc = regulat_info->psoc; 4028 soc_reg = reg_get_psoc_obj(psoc); 4029 4030 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) { 4031 reg_err("psoc reg component is NULL"); 4032 return QDF_STATUS_E_FAILURE; 4033 } 4034 4035 tx_ops = reg_get_psoc_tx_ops(psoc); 4036 phy_id = regulat_info->phy_id; 4037 4038 if (tx_ops->get_pdev_id_from_phy_id) 4039 tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id); 4040 else 4041 pdev_id = phy_id; 4042 4043 if (reg_ignore_default_country(soc_reg, regulat_info)) { 4044 status = reg_set_curr_country(soc_reg, regulat_info, tx_ops); 4045 if (QDF_IS_STATUS_SUCCESS(status)) { 4046 reg_debug("WLAN restart - Ignore default CC for phy_id: %u", 4047 phy_id); 4048 return QDF_STATUS_SUCCESS; 4049 } 4050 } 4051 4052 reg_debug("process reg master chan extended list"); 4053 4054 if (soc_reg->offload_enabled) { 4055 dbg_id = WLAN_REGULATORY_NB_ID; 4056 dir = NORTHBOUND; 4057 } else { 4058 dbg_id = WLAN_REGULATORY_SB_ID; 4059 dir = SOUTHBOUND; 4060 } 4061 4062 status = reg_soc_vars_reset_on_failure(regulat_info->status_code, 4063 soc_reg, tx_ops, psoc, dbg_id, 4064 phy_id); 4065 4066 if (!QDF_IS_STATUS_SUCCESS(status)) 4067 return status; 4068 4069 this_mchan_params = &soc_reg->mas_chan_params[phy_id]; 4070 mas_chan_list_2g_5g = this_mchan_params->mas_chan_list; 4071 4072 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 4073 mas_chan_list_6g_ap[i] = 4074 this_mchan_params->mas_chan_list_6g_ap[i]; 4075 4076 for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) 4077 mas_chan_list_6g_client[i][j] = 4078 this_mchan_params->mas_chan_list_6g_client[i][j]; 4079 } 4080 4081 reg_init_channel_map(regulat_info->dfs_region); 4082 4083 reg_init_2g_5g_master_chan(mas_chan_list_2g_5g, soc_reg); 4084 4085 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 4086 reg_init_6ghz_master_chan(mas_chan_list_6g_ap[i], soc_reg); 4087 for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) 4088 reg_init_6ghz_master_chan(mas_chan_list_6g_client[i][j], 4089 soc_reg); 4090 } 4091 4092 reg_store_regulatory_ext_info_to_socpriv(soc_reg, regulat_info, phy_id); 4093 4094 status = reg_fill_master_channels(regulat_info, 4095 &this_mchan_params->reg_rules, 4096 this_mchan_params->client_type, 4097 mas_chan_list_2g_5g, 4098 mas_chan_list_6g_ap, 4099 mas_chan_list_6g_client, 4100 soc_reg); 4101 if (!QDF_IS_STATUS_SUCCESS(status)) 4102 return status; 4103 4104 status = reg_send_ctl_info(soc_reg, regulat_info, tx_ops); 4105 if (!QDF_IS_STATUS_SUCCESS(status)) 4106 return status; 4107 4108 reg_set_socpriv_vars(soc_reg, regulat_info, psoc, phy_id); 4109 4110 status = reg_set_psoc_fcc_rules(soc_reg, regulat_info); 4111 if (!QDF_IS_STATUS_SUCCESS(status)) 4112 return status; 4113 4114 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id); 4115 if (pdev) { 4116 reg_propagate_mas_chan_list_to_pdev(psoc, pdev, &dir); 4117 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 4118 } 4119 4120 return QDF_STATUS_SUCCESS; 4121 } 4122 4123 QDF_STATUS reg_get_6g_ap_master_chan_list(struct wlan_objmgr_pdev *pdev, 4124 enum reg_6g_ap_type ap_pwr_type, 4125 struct regulatory_channel *chan_list) 4126 { 4127 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 4128 struct regulatory_channel *master_chan_list_6g; 4129 4130 pdev_priv_obj = reg_get_pdev_obj(pdev); 4131 4132 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 4133 reg_err("reg pdev private obj is NULL"); 4134 return QDF_STATUS_E_FAILURE; 4135 } 4136 4137 if (ap_pwr_type >= REG_CURRENT_MAX_AP_TYPE) 4138 return QDF_STATUS_E_FAILURE; 4139 4140 master_chan_list_6g = pdev_priv_obj->mas_chan_list_6g_ap[ap_pwr_type]; 4141 qdf_mem_copy(chan_list, master_chan_list_6g, 4142 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel)); 4143 4144 return QDF_STATUS_SUCCESS; 4145 } 4146 4147 #ifdef CONFIG_AFC_SUPPORT 4148 static void reg_disable_afc_mas_chan_list_channels( 4149 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 4150 { 4151 struct regulatory_channel *afc_mas_chan_list; 4152 enum channel_enum chan_idx; 4153 4154 QDF_TRACE(QDF_MODULE_ID_AFC, QDF_TRACE_LEVEL_DEBUG, 4155 "Processing AFC Switch to LPI event"); 4156 4157 afc_mas_chan_list = pdev_priv_obj->mas_chan_list_6g_afc; 4158 4159 for (chan_idx = 0; chan_idx < NUM_6GHZ_CHANNELS; chan_idx++) { 4160 if (afc_mas_chan_list[chan_idx].state == CHANNEL_STATE_ENABLE) { 4161 if (pdev_priv_obj->reg_afc_dev_deployment_type == 4162 AFC_DEPLOYMENT_OUTDOOR) { 4163 afc_mas_chan_list[chan_idx].chan_flags |= 4164 REGULATORY_CHAN_AFC_NOT_DONE; 4165 } else { 4166 afc_mas_chan_list[chan_idx].state = 4167 CHANNEL_STATE_DISABLE; 4168 afc_mas_chan_list[chan_idx].chan_flags |= 4169 REGULATORY_CHAN_DISABLED; 4170 afc_mas_chan_list[chan_idx].psd_eirp = 0; 4171 afc_mas_chan_list[chan_idx].tx_power = 0; 4172 } 4173 } 4174 } 4175 4176 qdf_mem_zero(pdev_priv_obj->afc_chan_list, 4177 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel)); 4178 } 4179 4180 static void reg_free_expiry_afc_info(struct afc_regulatory_info *afc_info) 4181 { 4182 qdf_mem_free(afc_info->expiry_info); 4183 } 4184 4185 /** 4186 * reg_disable_sp_entries_in_supr_chan_entry() - Disable the SP entries in the 4187 * super channel list 4188 * @chan_info: Pointer to chan_info 4189 * @reg_afc_dev_type: AFC device deployment type 4190 * 4191 * Return: void 4192 */ 4193 static void reg_disable_sp_entries_in_supr_chan_entry( 4194 struct super_chan_info *chan_info, 4195 enum reg_afc_dev_deploy_type reg_afc_dev_type) 4196 { 4197 uint8_t j; 4198 static enum supported_6g_pwr_types list_of_sp_lists[] = { 4199 REG_AP_SP, 4200 REG_CLI_DEF_SP, 4201 REG_CLI_SUB_SP 4202 }; 4203 uint8_t num_sp_lists = QDF_ARRAY_SIZE(list_of_sp_lists); 4204 4205 for (j = 0; j < num_sp_lists; j++) { 4206 enum supported_6g_pwr_types idx = list_of_sp_lists[j]; 4207 4208 if (reg_is_supp_pwr_mode_invalid(idx)) 4209 continue; 4210 4211 if (chan_info->state_arr[idx] == CHANNEL_STATE_DISABLE) 4212 continue; 4213 4214 if (reg_afc_dev_type == AFC_DEPLOYMENT_OUTDOOR) 4215 reg_set_flag_afc_not_done( 4216 &chan_info->chan_flags_arr[idx], 4217 true); 4218 else 4219 reg_dis_chan_state_and_flags( 4220 &chan_info->state_arr[idx], 4221 &chan_info->chan_flags_arr[idx]); 4222 } 4223 } 4224 4225 /** 4226 * reg_disable_sp_channels_in_super_chan_list() - Disable the SP channels in 4227 * the super channel list 4228 * @pdev_priv_obj: Pointer to pdev_priv_obj 4229 * 4230 * Return: void 4231 */ 4232 static void 4233 reg_disable_sp_channels_in_super_chan_list( 4234 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 4235 { 4236 uint8_t i; 4237 struct super_chan_info *super_chan_list; 4238 4239 super_chan_list = pdev_priv_obj->super_chan_list; 4240 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) { 4241 struct super_chan_info *chan_info = 4242 &super_chan_list[i]; 4243 reg_disable_sp_entries_in_supr_chan_entry( 4244 chan_info, 4245 pdev_priv_obj->reg_afc_dev_deployment_type); 4246 } 4247 } 4248 4249 #if defined(CONFIG_AFC_SUPPORT) && defined(CONFIG_REG_CLIENT) 4250 /** 4251 * reg_client_afc_populate_channels() - Function to populate channels and 4252 * invoke callbacks to notify the channel list change. 4253 * @psoc: Pointer to PSOC object 4254 * @pdev: Pointer to PDEV object 4255 * 4256 * Return: None 4257 */ 4258 static void 4259 reg_client_afc_populate_channels(struct wlan_objmgr_psoc *psoc, 4260 struct wlan_objmgr_pdev *pdev) 4261 { 4262 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 4263 4264 pdev_priv_obj = reg_get_pdev_obj(pdev); 4265 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 4266 reg_alert("pdev reg component is NULL"); 4267 return; 4268 } 4269 reg_compute_pdev_current_chan_list(pdev_priv_obj); 4270 reg_send_scheduler_msg_nb(psoc, pdev); 4271 } 4272 #else 4273 static inline void 4274 reg_client_afc_populate_channels(struct wlan_objmgr_psoc *psoc, 4275 struct wlan_objmgr_pdev *pdev) 4276 { 4277 } 4278 #endif 4279 4280 /** 4281 * reg_process_afc_expiry_event() - Process the afc expiry event and get the 4282 * afc request id 4283 * @afc_info: Pointer to afc info 4284 * 4285 * Return: QDF_STATUS 4286 */ 4287 static QDF_STATUS 4288 reg_process_afc_expiry_event(struct afc_regulatory_info *afc_info) 4289 { 4290 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 4291 uint8_t phy_id; 4292 uint8_t pdev_id; 4293 struct wlan_objmgr_psoc *psoc; 4294 struct wlan_regulatory_psoc_priv_obj *soc_reg; 4295 struct wlan_objmgr_pdev *pdev; 4296 struct wlan_lmac_if_reg_tx_ops *tx_ops; 4297 wlan_objmgr_ref_dbgid dbg_id; 4298 4299 psoc = afc_info->psoc; 4300 soc_reg = reg_get_psoc_obj(psoc); 4301 4302 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) { 4303 reg_err("psoc reg component is NULL"); 4304 return QDF_STATUS_E_FAILURE; 4305 } 4306 4307 phy_id = afc_info->phy_id; 4308 tx_ops = reg_get_psoc_tx_ops(psoc); 4309 4310 if (soc_reg->offload_enabled) 4311 dbg_id = WLAN_REGULATORY_NB_ID; 4312 else 4313 dbg_id = WLAN_REGULATORY_SB_ID; 4314 4315 if (tx_ops->get_pdev_id_from_phy_id) 4316 tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id); 4317 else 4318 pdev_id = phy_id; 4319 4320 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id); 4321 4322 if (!pdev) { 4323 reg_err("pdev is NULL"); 4324 return QDF_STATUS_E_FAILURE; 4325 } 4326 4327 pdev_priv_obj = reg_get_pdev_obj(pdev); 4328 4329 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 4330 reg_err("reg pdev priv obj is NULL"); 4331 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 4332 return QDF_STATUS_E_FAILURE; 4333 } 4334 4335 reg_debug("AFC event subtype: %d", 4336 afc_info->expiry_info->event_subtype); 4337 switch (afc_info->expiry_info->event_subtype) { 4338 case REG_AFC_EXPIRY_EVENT_START: 4339 case REG_AFC_EXPIRY_EVENT_RENEW: 4340 pdev_priv_obj->afc_request_id = 4341 afc_info->expiry_info->request_id; 4342 pdev_priv_obj->is_6g_afc_expiry_event_received = true; 4343 reg_afc_start(pdev, pdev_priv_obj->afc_request_id); 4344 break; 4345 case REG_AFC_EXPIRY_EVENT_SWITCH_TO_LPI: 4346 case REG_AFC_EXPIRY_EVENT_STOP_TX: 4347 pdev_priv_obj->is_6g_afc_power_event_received = false; 4348 reg_disable_afc_mas_chan_list_channels(pdev_priv_obj); 4349 reg_disable_sp_channels_in_super_chan_list(pdev_priv_obj); 4350 reg_client_afc_populate_channels(psoc, pdev); 4351 if (tx_ops->trigger_acs_for_afc) 4352 tx_ops->trigger_acs_for_afc(pdev); 4353 break; 4354 default: 4355 reg_err_rl("Invalid event subtype"); 4356 }; 4357 4358 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 4359 reg_free_expiry_afc_info(afc_info); 4360 4361 return QDF_STATUS_SUCCESS; 4362 } 4363 4364 /** 4365 * reg_fill_min_max_bw_for_afc_list() - Fill min and max bw in afc list from 4366 * from the SP AFC list 4367 * @pdev_priv_obj: Pointer to pdev_priv_obj 4368 * @afc_chan_list: Pointer to afc_chan_list 4369 * 4370 * Return: void 4371 */ 4372 static void 4373 reg_fill_min_max_bw_for_afc_list( 4374 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 4375 struct regulatory_channel *afc_chan_list) 4376 { 4377 uint8_t chan_idx; 4378 4379 for (chan_idx = 0; chan_idx < NUM_6GHZ_CHANNELS; chan_idx++) { 4380 afc_chan_list[chan_idx].min_bw = MIN_AFC_BW; 4381 afc_chan_list[chan_idx].max_bw = MAX_AFC_BW; 4382 } 4383 } 4384 4385 /** 4386 * reg_fill_subchan_centers() - Fill the subchannels for the given cfi. 4387 * @nchans: Number of sub-channels 4388 * @cfi: Center frequency index 4389 * @subchannels: Array of subchannels to be filled 4390 * 4391 * eg: subchannels[0] = cfi - 6 : The second left hand channel is 4392 * 4 MHz to the left of the previous channel. 4393 * subchannels[1] = cfi - 2 : The first left hand channel is 2 MHz 4394 * to the left of the CFI. 4395 * subchannels[2] = cfi + 2 : The first right hand channel is 2 MHz 4396 * to the right of the center (or CFI) as the distance between 4397 * two IEEE channels is 4 MHz. 4398 * subchannels[3] = cfi + 6 : The second right hand channel is 4 MHz to the 4399 * right the of previous channel 4400 * 4401 * Return: void 4402 */ 4403 static void 4404 reg_fill_subchan_centers(uint8_t nchans, uint8_t cfi, uint8_t *subchannels) 4405 { 4406 uint8_t last_idx = nchans - 1; 4407 uint8_t offset = HALF_IEEE_CH_SEP; 4408 uint8_t i; 4409 4410 if (nchans == 1) { 4411 subchannels[0] = cfi; 4412 return; 4413 } 4414 4415 for (i = nchans / 2; i < nchans; i++) { 4416 subchannels[i] = cfi + offset; 4417 subchannels[last_idx - i] = cfi - offset; 4418 offset += IEEE_20MHZ_CH_SEP; 4419 } 4420 } 4421 4422 /** 4423 * reg_get_subchannels_for_opclass() - Get the list of subchannels based on the 4424 * the channel frequency index and opclass. 4425 * @cfi: Channel frequency index 4426 * @opclass: Operating class 4427 * @subchannels: Pointer to list of subchannels 4428 * 4429 * Return: void 4430 */ 4431 uint8_t reg_get_subchannels_for_opclass(uint8_t cfi, 4432 uint8_t opclass, 4433 uint8_t *subchannels) 4434 { 4435 uint8_t nchans; 4436 4437 switch (opclass) { 4438 case 131: 4439 case 136: 4440 nchans = 1; 4441 break; 4442 case 132: 4443 nchans = 2; 4444 break; 4445 case 133: 4446 nchans = 4; 4447 break; 4448 case 134: 4449 nchans = 8; 4450 break; 4451 case 137: 4452 nchans = 16; 4453 break; 4454 4455 default: 4456 nchans = 0; 4457 break; 4458 } 4459 4460 reg_fill_subchan_centers(nchans, cfi, subchannels); 4461 4462 return nchans; 4463 } 4464 4465 /** 4466 * reg_search_afc_power_info_for_freq() - Search the chan_eirp object for the 4467 * eirp power for a given frequency 4468 * @pdev: Pointer to pdev 4469 * @power_info: Pointer to power_info 4470 * @freq: Channel frequency 4471 * @eirp_power: Pointer to eirp_power 4472 * 4473 * Return: QDF_STATUS 4474 */ 4475 static QDF_STATUS 4476 reg_search_afc_power_info_for_freq( 4477 struct wlan_objmgr_pdev *pdev, 4478 struct reg_fw_afc_power_event *power_info, 4479 qdf_freq_t freq, 4480 uint16_t *eirp_power) 4481 { 4482 uint8_t i; 4483 4484 if (!power_info->num_chan_objs) { 4485 reg_err("num chan objs cannot be zero"); 4486 return QDF_STATUS_E_FAILURE; 4487 } 4488 4489 *eirp_power = 0; 4490 for (i = 0; i < power_info->num_chan_objs; i++) { 4491 uint8_t j; 4492 struct afc_chan_obj *chan_obj = &power_info->afc_chan_info[i]; 4493 4494 if (!chan_obj->num_chans) { 4495 reg_err("num chans cannot be zero"); 4496 return QDF_STATUS_E_FAILURE; 4497 } 4498 4499 for (j = 0; j < chan_obj->num_chans; j++) { 4500 uint8_t k; 4501 struct chan_eirp_obj *eirp_obj = 4502 &chan_obj->chan_eirp_info[j]; 4503 uint8_t opclass = chan_obj->global_opclass; 4504 uint8_t subchannels[REG_MAX_20M_SUB_CH]; 4505 uint8_t nchans; 4506 4507 nchans = 4508 reg_get_subchannels_for_opclass(eirp_obj->cfi, 4509 opclass, subchannels); 4510 4511 for (k = 0; k < nchans; k++) { 4512 if (reg_chan_band_to_freq(pdev, 4513 subchannels[k], 4514 BIT(REG_BAND_6G)) == 4515 freq) { 4516 *eirp_power = eirp_obj->eirp_power; 4517 return QDF_STATUS_SUCCESS; 4518 } 4519 } 4520 } 4521 } 4522 4523 return QDF_STATUS_E_FAILURE; 4524 } 4525 4526 /** 4527 * reg_process_cfi_chan_list() - Fill eirp power and state in the cfi chan list 4528 * @pdev: Pointer to pdev 4529 * @cfi_chan_list: Pointer to cfi_chan_list 4530 * @power_info: Pointer to power_info 4531 * 4532 * Return: QDF_STATUS 4533 */ 4534 static QDF_STATUS reg_process_cfi_chan_list( 4535 struct wlan_objmgr_pdev *pdev, 4536 struct regulatory_channel *cfi_chan_list, 4537 struct reg_fw_afc_power_event *power_info) 4538 4539 { 4540 uint8_t chan_idx; 4541 uint16_t eirp_power; 4542 QDF_STATUS status = QDF_STATUS_SUCCESS; 4543 4544 for (chan_idx = 0; chan_idx < NUM_6GHZ_CHANNELS; chan_idx++) { 4545 status = 4546 reg_search_afc_power_info_for_freq(pdev, 4547 power_info, 4548 cfi_chan_list[chan_idx]. 4549 center_freq, 4550 &eirp_power); 4551 /* 4552 * The eirp_power is divided by 100 because the target 4553 * sends the EIRP in the units of 0.01 dbm. 4554 */ 4555 if (QDF_IS_STATUS_SUCCESS(status)) { 4556 cfi_chan_list[chan_idx].tx_power = eirp_power / 100; 4557 cfi_chan_list[chan_idx].state = CHANNEL_STATE_ENABLE; 4558 cfi_chan_list[chan_idx].chan_flags &= 4559 ~REGULATORY_CHAN_DISABLED; 4560 } 4561 } 4562 4563 return status; 4564 } 4565 4566 /** 4567 * reg_find_low_limit_chan_enum_for_6g() - Find 6G channel enum for a given 6G 4568 * lower edge frequency in the input channel list 4569 * @chan_list: Pointer to regulatory channel list. 4570 * @low_freq: Channel frequency. 4571 * @channel_enum: pointer to output channel enum. 4572 * 4573 * Return: None 4574 */ 4575 static void reg_find_low_limit_chan_enum_for_6g( 4576 struct regulatory_channel *chan_list, qdf_freq_t low_freq, 4577 enum channel_enum *channel_enum) 4578 { 4579 enum channel_enum chan_enum; 4580 uint16_t min_bw, max_bw, left_edge_of_min_band, left_edge_of_max_band; 4581 qdf_freq_t center_freq; 4582 4583 *channel_enum = 0; 4584 for (chan_enum = 0; chan_enum < NUM_6GHZ_CHANNELS; chan_enum++) { 4585 min_bw = chan_list[chan_enum].min_bw; 4586 max_bw = chan_list[chan_enum].max_bw; 4587 center_freq = chan_list[chan_enum].center_freq; 4588 left_edge_of_min_band = center_freq - min_bw / 2; 4589 4590 if ((left_edge_of_min_band) >= low_freq) { 4591 left_edge_of_max_band = center_freq - max_bw / 2; 4592 if (left_edge_of_max_band < low_freq) { 4593 if (max_bw <= 20) 4594 max_bw = ((center_freq - low_freq) * 2); 4595 if (max_bw < min_bw) 4596 max_bw = min_bw; 4597 chan_list[chan_enum].max_bw = max_bw; 4598 } 4599 *channel_enum = chan_enum; 4600 break; 4601 } 4602 } 4603 } 4604 4605 /** 4606 * reg_find_high_limit_chan_enum_for_6g() - Find 6G channel enum for a given 4607 * 6G higher edge frequency in the input channel list 4608 * @chan_list: Pointer to regulatory channel list. 4609 * @freq: Channel frequency. 4610 * @channel_enum: pointer to output channel enum. 4611 * 4612 * Return: None 4613 */ 4614 static void reg_find_high_limit_chan_enum_for_6g( 4615 struct regulatory_channel *chan_list, 4616 qdf_freq_t high_freq, 4617 enum channel_enum *channel_enum) 4618 { 4619 enum channel_enum chan_enum; 4620 uint16_t min_bw, max_bw, right_edge_of_min_band, right_edge_of_max_band; 4621 qdf_freq_t center_freq; 4622 4623 *channel_enum = 0; 4624 for (chan_enum = NUM_6GHZ_CHANNELS - 1; chan_enum >= 0; chan_enum--) { 4625 min_bw = chan_list[chan_enum].min_bw; 4626 max_bw = chan_list[chan_enum].max_bw; 4627 center_freq = chan_list[chan_enum].center_freq; 4628 right_edge_of_min_band = center_freq + min_bw / 2; 4629 4630 if (right_edge_of_min_band <= high_freq) { 4631 right_edge_of_max_band = center_freq + max_bw / 2; 4632 if (right_edge_of_max_band > high_freq) { 4633 if (max_bw <= 20) 4634 max_bw = ((high_freq - 4635 center_freq) * 2); 4636 if (max_bw < min_bw) 4637 max_bw = min_bw; 4638 chan_list[chan_enum].max_bw = max_bw; 4639 } 4640 *channel_enum = chan_enum; 4641 break; 4642 } 4643 4644 if (chan_enum == 0) 4645 break; 4646 } 4647 } 4648 4649 /** 4650 * reg_fill_max_psd_in_afc_chan_list() - Fill max_psd in the afc master chan 4651 * list 4652 * @pdev_priv_obj: Pointer to pdev_priv_obj 4653 * @afc_chan_list: Pointer to afc_chan_list 4654 * @power_info: Pointer to power_info 4655 * 4656 * Return: QDF_STATUS 4657 */ 4658 static QDF_STATUS reg_fill_max_psd_in_afc_chan_list( 4659 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 4660 struct regulatory_channel *afc_chan_list, 4661 struct reg_fw_afc_power_event *power_info) 4662 { 4663 uint8_t i; 4664 struct regulatory_channel *sp_chan_list; 4665 struct regulatory_channel *cfi_chan_list; 4666 4667 if (!power_info) { 4668 reg_err("power_info is NULL"); 4669 return QDF_STATUS_E_FAILURE; 4670 } 4671 4672 if (!power_info->num_freq_objs) { 4673 reg_err("num freq objs cannot be zero"); 4674 return QDF_STATUS_E_FAILURE; 4675 } 4676 4677 cfi_chan_list = qdf_mem_malloc(sizeof(struct regulatory_channel) * 4678 NUM_6GHZ_CHANNELS); 4679 4680 if (!cfi_chan_list) 4681 return QDF_STATUS_E_NOMEM; 4682 4683 qdf_mem_copy(cfi_chan_list, afc_chan_list, 4684 sizeof(struct regulatory_channel) * NUM_6GHZ_CHANNELS); 4685 sp_chan_list = 4686 pdev_priv_obj->mas_chan_list_6g_ap[REG_STANDARD_POWER_AP]; 4687 4688 reg_process_cfi_chan_list(pdev_priv_obj->pdev_ptr, cfi_chan_list, 4689 power_info); 4690 4691 for (i = 0; i < power_info->num_freq_objs; i++) { 4692 struct afc_freq_obj *freq_obj = &power_info->afc_freq_info[i]; 4693 enum channel_enum low_limit_enum, high_limit_enum; 4694 uint8_t j; 4695 4696 reg_find_low_limit_chan_enum_for_6g(afc_chan_list, 4697 freq_obj->low_freq, 4698 &low_limit_enum); 4699 reg_find_high_limit_chan_enum_for_6g(afc_chan_list, 4700 freq_obj->high_freq, 4701 &high_limit_enum); 4702 for (j = low_limit_enum; j <= high_limit_enum; j++) { 4703 if ((sp_chan_list[j].state == CHANNEL_STATE_ENABLE) && 4704 (cfi_chan_list[j].state == CHANNEL_STATE_ENABLE)) { 4705 afc_chan_list[j].state = CHANNEL_STATE_ENABLE; 4706 afc_chan_list[j].chan_flags &= 4707 ~REGULATORY_CHAN_DISABLED; 4708 /* 4709 * The max_psd is divided by 100 because the 4710 * target sends the PSD in the units of 4711 * 0.01 dbm/MHz. 4712 */ 4713 afc_chan_list[j].psd_eirp = 4714 freq_obj->max_psd / 100; 4715 afc_chan_list[j].psd_flag = true; 4716 afc_chan_list[j].tx_power = 4717 cfi_chan_list[j].tx_power; 4718 } 4719 } 4720 } 4721 4722 qdf_mem_free(cfi_chan_list); 4723 4724 return QDF_STATUS_SUCCESS; 4725 } 4726 4727 /** 4728 * reg_is_afc_mas_chan_list_valid() - Check if the AFC master channel list 4729 * is non-empty 4730 * @afc_mas_chan_list: Pointer to afc_mas_chan_list. 4731 * 4732 * Return: True, if atleast one channel has the state "CHANNEL_STATE_ENABLE", 4733 * else false. 4734 */ 4735 static bool 4736 reg_is_afc_mas_chan_list_valid(struct regulatory_channel *afc_mas_chan_list) 4737 { 4738 uint8_t i; 4739 4740 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) 4741 if (afc_mas_chan_list[i].state == CHANNEL_STATE_ENABLE) 4742 return true; 4743 4744 return false; 4745 } 4746 4747 /** 4748 * reg_process_afc_power_event() - Process the afc event and compute the 6G AFC 4749 * channel list based on the frequency range and channel frequency indice set. 4750 * @afc_info: Pointer to afc info 4751 * 4752 * Return: QDF_STATUS 4753 */ 4754 static QDF_STATUS 4755 reg_process_afc_power_event(struct afc_regulatory_info *afc_info) 4756 { 4757 struct wlan_objmgr_psoc *psoc; 4758 uint8_t phy_id; 4759 uint8_t pdev_id; 4760 wlan_objmgr_ref_dbgid dbg_id; 4761 struct wlan_objmgr_pdev *pdev; 4762 struct mas_chan_params *this_mchan_params; 4763 struct wlan_lmac_if_reg_tx_ops *tx_ops; 4764 struct regulatory_channel *afc_mas_chan_list; 4765 struct wlan_regulatory_psoc_priv_obj *soc_reg; 4766 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 4767 uint32_t size_of_6g_chan_list = 4768 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel); 4769 QDF_STATUS status; 4770 4771 QDF_TRACE(QDF_MODULE_ID_AFC, QDF_TRACE_LEVEL_DEBUG, 4772 "Processing AFC Power event"); 4773 4774 if (afc_info->power_info->fw_status_code != 4775 REG_FW_AFC_POWER_EVENT_SUCCESS) { 4776 reg_err_rl("AFC Power event failure status code %d", 4777 afc_info->power_info->fw_status_code); 4778 return QDF_STATUS_E_FAILURE; 4779 } 4780 4781 psoc = afc_info->psoc; 4782 soc_reg = reg_get_psoc_obj(psoc); 4783 4784 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) { 4785 reg_err("psoc reg component is NULL"); 4786 return QDF_STATUS_E_FAILURE; 4787 } 4788 4789 tx_ops = reg_get_psoc_tx_ops(psoc); 4790 phy_id = afc_info->phy_id; 4791 4792 if (tx_ops->get_pdev_id_from_phy_id) 4793 tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id); 4794 else 4795 pdev_id = phy_id; 4796 4797 if (soc_reg->offload_enabled) 4798 dbg_id = WLAN_REGULATORY_NB_ID; 4799 else 4800 dbg_id = WLAN_REGULATORY_SB_ID; 4801 4802 reg_debug("process reg afc master chan list"); 4803 this_mchan_params = &soc_reg->mas_chan_params[phy_id]; 4804 afc_mas_chan_list = this_mchan_params->mas_chan_list_6g_afc; 4805 qdf_mem_zero(afc_mas_chan_list, 4806 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel)); 4807 reg_init_6ghz_master_chan(afc_mas_chan_list, soc_reg); 4808 soc_reg->mas_chan_params[phy_id].is_6g_afc_power_event_received = true; 4809 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id); 4810 4811 if (!pdev) { 4812 reg_err("pdev is NULL"); 4813 return QDF_STATUS_E_FAILURE; 4814 } 4815 4816 pdev_priv_obj = reg_get_pdev_obj(pdev); 4817 4818 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 4819 reg_err("reg pdev priv obj is NULL"); 4820 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 4821 return QDF_STATUS_E_FAILURE; 4822 } 4823 4824 reg_init_pdev_super_chan_list(pdev_priv_obj); 4825 reg_init_6ghz_master_chan(pdev_priv_obj->afc_chan_list, soc_reg); 4826 /* Free the old power_info event if it was allocated */ 4827 if (pdev_priv_obj->power_info) 4828 reg_free_afc_pwr_info(pdev_priv_obj); 4829 4830 pdev_priv_obj->power_info = afc_info->power_info; 4831 reg_fill_min_max_bw_for_afc_list(pdev_priv_obj, 4832 afc_mas_chan_list); 4833 status = reg_fill_max_psd_in_afc_chan_list(pdev_priv_obj, 4834 afc_mas_chan_list, 4835 afc_info->power_info); 4836 if (QDF_IS_STATUS_ERROR(status)) { 4837 reg_err("Error in filling max_psd in AFC chan list"); 4838 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 4839 return status; 4840 } 4841 4842 qdf_mem_copy(pdev_priv_obj->mas_chan_list_6g_afc, 4843 afc_mas_chan_list, 4844 size_of_6g_chan_list); 4845 pdev_priv_obj->is_6g_afc_power_event_received = 4846 soc_reg->mas_chan_params[phy_id].is_6g_afc_power_event_received; 4847 4848 reg_modify_6g_afc_chan_list(pdev_priv_obj); 4849 reg_compute_super_chan_list(pdev_priv_obj); 4850 reg_client_afc_populate_channels(psoc, pdev); 4851 4852 if (tx_ops->trigger_acs_for_afc && 4853 !wlan_reg_is_noaction_on_afc_pwr_evt(pdev) && 4854 reg_is_afc_mas_chan_list_valid(pdev_priv_obj->mas_chan_list_6g_afc)) 4855 tx_ops->trigger_acs_for_afc(pdev); 4856 4857 reg_send_afc_power_event(pdev, afc_info->power_info); 4858 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 4859 4860 return QDF_STATUS_SUCCESS; 4861 } 4862 4863 /** 4864 * reg_process_afc_event() - Process the afc event received from the target. 4865 * @afc_info: Pointer to afc_info 4866 * 4867 * Return: QDF_STATUS 4868 */ 4869 QDF_STATUS 4870 reg_process_afc_event(struct afc_regulatory_info *afc_info) 4871 { 4872 switch (afc_info->event_type) { 4873 case REG_AFC_EVENT_POWER_INFO: 4874 return reg_process_afc_power_event(afc_info); 4875 case REG_AFC_EVENT_TIMER_EXPIRY: 4876 return reg_process_afc_expiry_event(afc_info); 4877 default: 4878 reg_err_rl("Invalid event type"); 4879 return QDF_STATUS_E_FAILURE; 4880 } 4881 } 4882 #endif /* CONFIG_AFC_SUPPORT */ 4883 #ifdef CONFIG_REG_CLIENT 4884 const char *reg_get_power_string(enum reg_6g_ap_type power_type) 4885 { 4886 switch (power_type) { 4887 case REG_INDOOR_AP: 4888 return "LP"; 4889 case REG_STANDARD_POWER_AP: 4890 return "SP"; 4891 case REG_VERY_LOW_POWER_AP: 4892 return "VLP"; 4893 default: 4894 return "INVALID"; 4895 } 4896 } 4897 #endif 4898 #endif /* CONFIG_BAND_6GHZ */ 4899 4900 QDF_STATUS reg_process_master_chan_list( 4901 struct cur_regulatory_info *regulat_info) 4902 { 4903 struct wlan_regulatory_psoc_priv_obj *soc_reg; 4904 uint32_t num_2g_reg_rules, num_5g_reg_rules; 4905 struct cur_reg_rule *reg_rule_2g, *reg_rule_5g; 4906 uint16_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g; 4907 struct regulatory_channel *mas_chan_list; 4908 struct wlan_objmgr_psoc *psoc; 4909 wlan_objmgr_ref_dbgid dbg_id; 4910 enum direction dir; 4911 uint8_t phy_id; 4912 uint8_t pdev_id; 4913 struct wlan_objmgr_pdev *pdev; 4914 struct wlan_lmac_if_reg_tx_ops *tx_ops; 4915 struct reg_rule_info *reg_rules; 4916 QDF_STATUS status; 4917 4918 psoc = regulat_info->psoc; 4919 soc_reg = reg_get_psoc_obj(psoc); 4920 4921 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) { 4922 reg_err("psoc reg component is NULL"); 4923 return QDF_STATUS_E_FAILURE; 4924 } 4925 4926 tx_ops = reg_get_psoc_tx_ops(psoc); 4927 phy_id = regulat_info->phy_id; 4928 4929 if (tx_ops->get_pdev_id_from_phy_id) 4930 tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id); 4931 else 4932 pdev_id = phy_id; 4933 4934 if (reg_ignore_default_country(soc_reg, regulat_info)) { 4935 status = reg_set_curr_country(soc_reg, regulat_info, tx_ops); 4936 if (QDF_IS_STATUS_SUCCESS(status)) { 4937 reg_debug("WLAN restart - Ignore default CC for phy_id: %u", 4938 phy_id); 4939 return QDF_STATUS_SUCCESS; 4940 } 4941 } 4942 4943 reg_debug("process reg master chan list"); 4944 4945 if (soc_reg->offload_enabled) { 4946 dbg_id = WLAN_REGULATORY_NB_ID; 4947 dir = NORTHBOUND; 4948 } else { 4949 dbg_id = WLAN_REGULATORY_SB_ID; 4950 dir = SOUTHBOUND; 4951 } 4952 4953 status = reg_soc_vars_reset_on_failure(regulat_info->status_code, 4954 soc_reg, tx_ops, psoc, dbg_id, 4955 phy_id); 4956 4957 if (!QDF_IS_STATUS_SUCCESS(status)) 4958 return status; 4959 4960 mas_chan_list = soc_reg->mas_chan_params[phy_id].mas_chan_list; 4961 4962 reg_init_channel_map(regulat_info->dfs_region); 4963 4964 reg_init_legacy_master_chan(mas_chan_list, soc_reg); 4965 4966 soc_reg->num_phy = regulat_info->num_phy; 4967 soc_reg->mas_chan_params[phy_id].phybitmap = 4968 regulat_info->phybitmap; 4969 soc_reg->mas_chan_params[phy_id].dfs_region = 4970 regulat_info->dfs_region; 4971 soc_reg->mas_chan_params[phy_id].ctry_code = 4972 regulat_info->ctry_code; 4973 soc_reg->mas_chan_params[phy_id].reg_dmn_pair = 4974 regulat_info->reg_dmn_pair; 4975 qdf_mem_copy(soc_reg->mas_chan_params[phy_id].current_country, 4976 regulat_info->alpha2, 4977 REG_ALPHA2_LEN + 1); 4978 qdf_mem_copy(soc_reg->cur_country, 4979 regulat_info->alpha2, 4980 REG_ALPHA2_LEN + 1); 4981 reg_debug("set cur_country %.2s", soc_reg->cur_country); 4982 4983 min_bw_2g = regulat_info->min_bw_2g; 4984 max_bw_2g = regulat_info->max_bw_2g; 4985 reg_rule_2g = regulat_info->reg_rules_2g_ptr; 4986 num_2g_reg_rules = regulat_info->num_2g_reg_rules; 4987 reg_update_max_bw_per_rule(num_2g_reg_rules, 4988 reg_rule_2g, max_bw_2g); 4989 4990 min_bw_5g = regulat_info->min_bw_5g; 4991 max_bw_5g = regulat_info->max_bw_5g; 4992 reg_rule_5g = regulat_info->reg_rules_5g_ptr; 4993 num_5g_reg_rules = regulat_info->num_5g_reg_rules; 4994 reg_update_max_bw_per_rule(num_5g_reg_rules, 4995 reg_rule_5g, max_bw_5g); 4996 soc_reg->mas_chan_params[phy_id].max_bw_5g = regulat_info->max_bw_5g; 4997 reg_rules = &soc_reg->mas_chan_params[phy_id].reg_rules; 4998 reg_reset_reg_rules(reg_rules); 4999 5000 reg_rules->num_of_reg_rules = num_5g_reg_rules + num_2g_reg_rules; 5001 if (reg_rules->num_of_reg_rules > MAX_REG_RULES) { 5002 reg_err("number of reg rules exceeds limit"); 5003 return QDF_STATUS_E_FAILURE; 5004 } 5005 5006 if (reg_rules->num_of_reg_rules) { 5007 if (num_2g_reg_rules) 5008 qdf_mem_copy(reg_rules->reg_rules, 5009 reg_rule_2g, num_2g_reg_rules * 5010 sizeof(struct cur_reg_rule)); 5011 if (num_5g_reg_rules) 5012 qdf_mem_copy(reg_rules->reg_rules + 5013 num_2g_reg_rules, reg_rule_5g, 5014 num_5g_reg_rules * 5015 sizeof(struct cur_reg_rule)); 5016 } 5017 5018 if (num_5g_reg_rules != 0) 5019 reg_do_auto_bw_correction(num_5g_reg_rules, 5020 reg_rule_5g, max_bw_5g); 5021 5022 if (num_2g_reg_rules != 0) 5023 reg_populate_band_channels(MIN_24GHZ_CHANNEL, MAX_24GHZ_CHANNEL, 5024 reg_rule_2g, num_2g_reg_rules, 5025 min_bw_2g, mas_chan_list); 5026 5027 if (num_5g_reg_rules != 0) { 5028 reg_populate_band_channels(MIN_5GHZ_CHANNEL, MAX_5GHZ_CHANNEL, 5029 reg_rule_5g, num_5g_reg_rules, 5030 min_bw_5g, mas_chan_list); 5031 reg_populate_49g_band_channels(reg_rule_5g, 5032 num_5g_reg_rules, 5033 min_bw_5g, 5034 mas_chan_list); 5035 reg_populate_6g_band_channels(reg_rule_5g, 5036 num_5g_reg_rules, 5037 min_bw_5g, 5038 mas_chan_list); 5039 } 5040 5041 soc_reg->chan_list_recvd[phy_id] = true; 5042 status = reg_send_ctl_info(soc_reg, regulat_info, tx_ops); 5043 if (!QDF_IS_STATUS_SUCCESS(status)) 5044 return status; 5045 5046 if (soc_reg->new_user_ctry_pending[phy_id]) { 5047 soc_reg->new_user_ctry_pending[phy_id] = false; 5048 soc_reg->cc_src = SOURCE_USERSPACE; 5049 soc_reg->user_ctry_set = true; 5050 reg_debug("new user country is set"); 5051 reg_run_11d_state_machine(psoc); 5052 } else if (soc_reg->new_init_ctry_pending[phy_id]) { 5053 soc_reg->new_init_ctry_pending[phy_id] = false; 5054 soc_reg->cc_src = SOURCE_USERSPACE; 5055 reg_debug("new init country is set"); 5056 } else if (soc_reg->new_11d_ctry_pending[phy_id]) { 5057 soc_reg->new_11d_ctry_pending[phy_id] = false; 5058 soc_reg->cc_src = SOURCE_11D; 5059 soc_reg->user_ctry_set = false; 5060 reg_run_11d_state_machine(psoc); 5061 } else if (soc_reg->world_country_pending[phy_id]) { 5062 soc_reg->world_country_pending[phy_id] = false; 5063 soc_reg->cc_src = SOURCE_CORE; 5064 soc_reg->user_ctry_set = false; 5065 reg_run_11d_state_machine(psoc); 5066 } else { 5067 if (soc_reg->cc_src == SOURCE_UNKNOWN && 5068 soc_reg->num_phy == phy_id + 1) 5069 soc_reg->cc_src = SOURCE_DRIVER; 5070 5071 qdf_mem_copy(soc_reg->mas_chan_params[phy_id].default_country, 5072 regulat_info->alpha2, 5073 REG_ALPHA2_LEN + 1); 5074 5075 soc_reg->mas_chan_params[phy_id].def_country_code = 5076 regulat_info->ctry_code; 5077 soc_reg->mas_chan_params[phy_id].def_region_domain = 5078 regulat_info->reg_dmn_pair; 5079 5080 if (soc_reg->cc_src == SOURCE_DRIVER) { 5081 qdf_mem_copy(soc_reg->def_country, 5082 regulat_info->alpha2, 5083 REG_ALPHA2_LEN + 1); 5084 5085 soc_reg->def_country_code = regulat_info->ctry_code; 5086 soc_reg->def_region_domain = 5087 regulat_info->reg_dmn_pair; 5088 5089 if (reg_is_world_alpha2(regulat_info->alpha2)) { 5090 soc_reg->cc_src = SOURCE_CORE; 5091 reg_run_11d_state_machine(psoc); 5092 } 5093 } 5094 } 5095 5096 status = reg_set_psoc_fcc_rules(soc_reg, regulat_info); 5097 if (!QDF_IS_STATUS_SUCCESS(status)) 5098 return status; 5099 5100 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id); 5101 if (pdev) { 5102 reg_propagate_mas_chan_list_to_pdev(psoc, pdev, &dir); 5103 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 5104 } 5105 5106 return QDF_STATUS_SUCCESS; 5107 } 5108 5109 QDF_STATUS reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev, 5110 struct regulatory_channel *chan_list) 5111 { 5112 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 5113 5114 pdev_priv_obj = reg_get_pdev_obj(pdev); 5115 5116 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 5117 reg_err("reg pdev private obj is NULL"); 5118 return QDF_STATUS_E_FAILURE; 5119 } 5120 5121 qdf_mem_copy(chan_list, pdev_priv_obj->cur_chan_list, 5122 NUM_CHANNELS * sizeof(struct regulatory_channel)); 5123 5124 return QDF_STATUS_SUCCESS; 5125 } 5126 5127 #ifdef CONFIG_REG_CLIENT 5128 QDF_STATUS 5129 reg_get_secondary_current_chan_list(struct wlan_objmgr_pdev *pdev, 5130 struct regulatory_channel *chan_list) 5131 { 5132 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 5133 5134 pdev_priv_obj = reg_get_pdev_obj(pdev); 5135 5136 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 5137 reg_err("reg pdev private obj is NULL"); 5138 return QDF_STATUS_E_FAILURE; 5139 } 5140 5141 qdf_mem_copy(chan_list, pdev_priv_obj->secondary_cur_chan_list, 5142 NUM_CHANNELS * sizeof(struct regulatory_channel)); 5143 5144 return QDF_STATUS_SUCCESS; 5145 } 5146 #endif 5147 5148 #if defined(CONFIG_AFC_SUPPORT) && defined(CONFIG_BAND_6GHZ) 5149 QDF_STATUS reg_get_6g_afc_chan_list(struct wlan_objmgr_pdev *pdev, 5150 struct regulatory_channel *chan_list) 5151 { 5152 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 5153 struct regulatory_channel *afc_chan_list; 5154 5155 pdev_priv_obj = reg_get_pdev_obj(pdev); 5156 5157 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 5158 reg_err("reg pdev private obj is NULL"); 5159 return QDF_STATUS_E_FAILURE; 5160 } 5161 5162 afc_chan_list = pdev_priv_obj->afc_chan_list; 5163 qdf_mem_copy(chan_list, afc_chan_list, 5164 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel)); 5165 5166 return QDF_STATUS_SUCCESS; 5167 } 5168 5169 QDF_STATUS 5170 reg_get_6g_afc_mas_chan_list(struct wlan_objmgr_pdev *pdev, 5171 struct regulatory_channel *chan_list) 5172 { 5173 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 5174 5175 pdev_priv_obj = reg_get_pdev_obj(pdev); 5176 5177 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 5178 reg_err("reg pdev private obj is NULL"); 5179 return QDF_STATUS_E_FAILURE; 5180 } 5181 5182 qdf_mem_copy(chan_list, pdev_priv_obj->mas_chan_list_6g_afc, 5183 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel)); 5184 5185 return QDF_STATUS_SUCCESS; 5186 } 5187 #endif 5188 5189 #ifdef CONFIG_BAND_6GHZ 5190 /** 5191 * struct bw_10log10_pair - The bandwidth and 10*log10(bandwidth) pair. 5192 * ten_l_len = trunc(10*log10(bw)). 'trunc' is truncation function. 5193 * @bw: The input bandwidth 5194 * @ten_l_ten: Integer value of 10 times the Logarithm (to the base-10) of the 5195 * input bandwidth(@bw). 5196 */ 5197 struct bw_10log10_pair { 5198 uint16_t bw; 5199 int16_t ten_l_ten; 5200 }; 5201 5202 /* The array of bandwidth to trunc(10log10(bandwidth)) mapping */ 5203 static const struct bw_10log10_pair bw_to_10log10_map[] = { 5204 { 20, 13}, /* 10* 1.30102 = 13.0102 */ 5205 { 40, 16}, /* 10* 1.60205 = 16.0205 */ 5206 { 80, 19}, /* 10* 1.90308 = 19.0308 */ 5207 {160, 22}, /* 10* 2.20411 = 22.0411 */ 5208 #ifdef WLAN_FEATURE_11BE 5209 {320, 25}, /* 10* 2.50514 = 25.0514 */ 5210 { 60, 18}, /* 10* 1.77815 = 17.7815 */ 5211 {140, 21}, /* 10* 2.14612 = 21.4612 */ 5212 {120, 21}, /* 10* 2.07918 = 20.7918 */ 5213 {200, 23}, /* 10* 2.30102 = 23.0102 */ 5214 {240, 24}, /* 10* 2.38021 = 23.8021 */ 5215 {280, 24}, /* 10* 2.44715 = 24.4715 */ 5216 #endif 5217 }; 5218 5219 QDF_STATUS reg_psd_2_eirp(struct wlan_objmgr_pdev *pdev, 5220 int16_t psd, 5221 uint16_t ch_bw, 5222 int16_t *eirp) 5223 { 5224 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 5225 int16_t ten_log10_bw; 5226 uint8_t i; 5227 uint8_t num_bws; 5228 5229 pdev_priv_obj = reg_get_pdev_obj(pdev); 5230 5231 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 5232 reg_err("reg pdev private obj is NULL"); 5233 return QDF_STATUS_E_FAILURE; 5234 } 5235 5236 /* EIRP = PSD + (10 * log10(CH_BW)) */ 5237 num_bws = QDF_ARRAY_SIZE(bw_to_10log10_map); 5238 for (i = 0; i < num_bws; i++) { 5239 if (ch_bw == bw_to_10log10_map[i].bw) { 5240 ten_log10_bw = bw_to_10log10_map[i].ten_l_ten; 5241 *eirp = psd + ten_log10_bw; 5242 return QDF_STATUS_SUCCESS; 5243 } 5244 } 5245 reg_err("Invalid input bandwidth %hd", ch_bw); 5246 return QDF_STATUS_E_FAILURE; 5247 } 5248 5249 QDF_STATUS reg_eirp_2_psd(struct wlan_objmgr_pdev *pdev, 5250 uint16_t ch_bw, 5251 int16_t eirp, 5252 int16_t *psd) 5253 { 5254 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 5255 int16_t ten_log10_bw; 5256 uint8_t i; 5257 uint8_t num_bws; 5258 5259 pdev_priv_obj = reg_get_pdev_obj(pdev); 5260 5261 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 5262 reg_err("reg pdev private obj is NULL"); 5263 return QDF_STATUS_E_FAILURE; 5264 } 5265 5266 /* EIRP = PSD + (10 * log10(CH_BW)) */ 5267 num_bws = QDF_ARRAY_SIZE(bw_to_10log10_map); 5268 for (i = 0; i < num_bws; i++) { 5269 if (ch_bw == bw_to_10log10_map[i].bw) { 5270 ten_log10_bw = bw_to_10log10_map[i].ten_l_ten; 5271 *psd = eirp - ten_log10_bw; 5272 return QDF_STATUS_SUCCESS; 5273 } 5274 } 5275 reg_err("Invalid input bandwidth %hd", ch_bw); 5276 return QDF_STATUS_E_FAILURE; 5277 } 5278 #endif 5279