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