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