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