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