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