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