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