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