1 /* 2 * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /** 20 * DOC: reg_build_chan_list.c 21 * This file defines the API to build master and current channel list. 22 */ 23 24 #include <wlan_cmn.h> 25 #include <reg_services_public_struct.h> 26 #include <wlan_objmgr_psoc_obj.h> 27 #include <wlan_objmgr_pdev_obj.h> 28 #include "reg_priv_objs.h" 29 #include "reg_utils.h" 30 #include "reg_callbacks.h" 31 #include "reg_services_common.h" 32 #include "reg_db.h" 33 #include "reg_db_parser.h" 34 #include "reg_offload_11d_scan.h" 35 #include <scheduler_api.h> 36 #include "reg_build_chan_list.h" 37 #include <qdf_platform.h> 38 39 #define MAX_PWR_FCC_CHAN_12 8 40 #define MAX_PWR_FCC_CHAN_13 2 41 #define CHAN_144_CENT_FREQ 5720 42 43 /** 44 * reg_fill_channel_info() - Populate TX power, antenna gain, channel state, 45 * channel flags, min and max bandwidth to master channel list. 46 * @chan_enum: Channel enum. 47 * @reg_rule: Pointer to regulatory rule which has tx power and antenna gain. 48 * @master_list: Pointer to master channel list. 49 * @min_bw: minimum bandwidth to be used for given channel. 50 */ 51 static void reg_fill_channel_info(enum channel_enum chan_enum, 52 struct cur_reg_rule *reg_rule, 53 struct regulatory_channel *master_list, 54 uint16_t min_bw) 55 { 56 master_list[chan_enum].chan_flags &= ~REGULATORY_CHAN_DISABLED; 57 58 master_list[chan_enum].tx_power = reg_rule->reg_power; 59 master_list[chan_enum].ant_gain = reg_rule->ant_gain; 60 master_list[chan_enum].state = CHANNEL_STATE_ENABLE; 61 62 if (reg_rule->flags & REGULATORY_CHAN_NO_IR) { 63 master_list[chan_enum].chan_flags |= REGULATORY_CHAN_NO_IR; 64 master_list[chan_enum].state = CHANNEL_STATE_DFS; 65 } 66 67 if (reg_rule->flags & REGULATORY_CHAN_RADAR) { 68 master_list[chan_enum].chan_flags |= REGULATORY_CHAN_RADAR; 69 master_list[chan_enum].state = CHANNEL_STATE_DFS; 70 } 71 72 if (reg_rule->flags & REGULATORY_CHAN_INDOOR_ONLY) 73 master_list[chan_enum].chan_flags |= 74 REGULATORY_CHAN_INDOOR_ONLY; 75 76 if (reg_rule->flags & REGULATORY_CHAN_NO_OFDM) 77 master_list[chan_enum].chan_flags |= REGULATORY_CHAN_NO_OFDM; 78 79 master_list[chan_enum].min_bw = min_bw; 80 if (master_list[chan_enum].max_bw == 20) 81 master_list[chan_enum].max_bw = reg_rule->max_bw; 82 } 83 84 /** 85 * reg_populate_band_channels() - For all the valid regdb channels in the master 86 * channel list, find the regulatory rules and call reg_fill_channel_info() to 87 * populate master channel list with txpower, antennagain, BW info, etc. 88 * @start_chan: Start channel enum. 89 * @end_chan: End channel enum. 90 * @rule_start_ptr: Pointer to regulatory rules. 91 * @num_reg_rules: Number of regulatory rules. 92 * @min_reg_bw: Minimum regulatory bandwidth. 93 * @mas_chan_list: Pointer to master channel list. 94 */ 95 static void reg_populate_band_channels(enum channel_enum start_chan, 96 enum channel_enum end_chan, 97 struct cur_reg_rule *rule_start_ptr, 98 uint32_t num_reg_rules, 99 uint16_t min_reg_bw, 100 struct regulatory_channel *mas_chan_list) 101 { 102 struct cur_reg_rule *found_rule_ptr; 103 struct cur_reg_rule *cur_rule_ptr; 104 struct regulatory_channel; 105 enum channel_enum chan_enum; 106 uint32_t rule_num, bw; 107 uint16_t max_bw; 108 uint16_t min_bw; 109 110 for (chan_enum = start_chan; chan_enum <= end_chan; chan_enum++) { 111 found_rule_ptr = NULL; 112 113 max_bw = QDF_MIN((uint16_t)20, channel_map[chan_enum].max_bw); 114 min_bw = QDF_MAX(min_reg_bw, channel_map[chan_enum].min_bw); 115 116 if (channel_map[chan_enum].chan_num == INVALID_CHANNEL_NUM) 117 continue; 118 119 for (bw = max_bw; bw >= min_bw; bw = bw / 2) { 120 for (rule_num = 0, cur_rule_ptr = rule_start_ptr; 121 rule_num < num_reg_rules; 122 cur_rule_ptr++, rule_num++) { 123 if ((cur_rule_ptr->start_freq <= 124 mas_chan_list[chan_enum].center_freq - 125 bw / 2) && 126 (cur_rule_ptr->end_freq >= 127 mas_chan_list[chan_enum].center_freq + 128 bw / 2) && (min_bw <= bw)) { 129 found_rule_ptr = cur_rule_ptr; 130 break; 131 } 132 } 133 134 if (found_rule_ptr) 135 break; 136 } 137 138 if (found_rule_ptr) { 139 mas_chan_list[chan_enum].max_bw = bw; 140 reg_fill_channel_info(chan_enum, found_rule_ptr, 141 mas_chan_list, min_bw); 142 /* Disable 2.4 Ghz channels that dont have 20 mhz bw */ 143 if (start_chan == MIN_24GHZ_CHANNEL && 144 mas_chan_list[chan_enum].max_bw < 20) { 145 mas_chan_list[chan_enum].chan_flags |= 146 REGULATORY_CHAN_DISABLED; 147 mas_chan_list[chan_enum].state = 148 REGULATORY_CHAN_DISABLED; 149 } 150 } 151 } 152 } 153 154 /** 155 * reg_update_max_bw_per_rule() - Update max bandwidth value for given regrules. 156 * @num_reg_rules: Number of regulatory rules. 157 * @reg_rule_start: Pointer to regulatory rules. 158 * @max_bw: Maximum bandwidth 159 */ 160 static void reg_update_max_bw_per_rule(uint32_t num_reg_rules, 161 struct cur_reg_rule *reg_rule_start, 162 uint16_t max_bw) 163 { 164 uint32_t count; 165 166 for (count = 0; count < num_reg_rules; count++) 167 reg_rule_start[count].max_bw = 168 min(reg_rule_start[count].max_bw, max_bw); 169 } 170 171 /** 172 * reg_do_auto_bw_correction() - Calculate and update the maximum bandwidth 173 * value. 174 * @num_reg_rules: Number of regulatory rules. 175 * @reg_rule_ptr: Pointer to regulatory rules. 176 * @max_bw: Maximum bandwidth 177 */ 178 static void reg_do_auto_bw_correction(uint32_t num_reg_rules, 179 struct cur_reg_rule *reg_rule_ptr, 180 uint16_t max_bw) 181 { 182 uint32_t count; 183 uint16_t new_bw; 184 185 for (count = 0; count < num_reg_rules - 1; count++) { 186 if ((reg_rule_ptr[count].end_freq == 187 reg_rule_ptr[count + 1].start_freq) && 188 ((reg_rule_ptr[count].max_bw + 189 reg_rule_ptr[count + 1].max_bw) <= max_bw)) { 190 new_bw = reg_rule_ptr[count].max_bw + 191 reg_rule_ptr[count + 1].max_bw; 192 reg_rule_ptr[count].max_bw = new_bw; 193 reg_rule_ptr[count + 1].max_bw = new_bw; 194 } 195 } 196 } 197 198 /** 199 * reg_modify_chan_list_for_dfs_channels() - disable the DFS channels if 200 * dfs_enable set to false. 201 * @chan_list: Pointer to regulatory channel list. 202 * @dfs_enabled: if false, then disable the DFS channels. 203 */ 204 static void reg_modify_chan_list_for_dfs_channels( 205 struct regulatory_channel *chan_list, bool dfs_enabled) 206 { 207 enum channel_enum chan_enum; 208 209 if (dfs_enabled) 210 return; 211 212 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 213 if (chan_list[chan_enum].state == CHANNEL_STATE_DFS) { 214 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 215 chan_list[chan_enum].chan_flags |= 216 REGULATORY_CHAN_DISABLED; 217 } 218 } 219 } 220 221 /** 222 * reg_modify_chan_list_for_indoor_channels() - Disable the indoor channels if 223 * indoor_chan_enabled flag is set to false. 224 * @pdev_priv_obj: Pointer to regulatory private pdev structure. 225 */ 226 static void reg_modify_chan_list_for_indoor_channels( 227 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 228 { 229 enum channel_enum chan_enum; 230 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list; 231 232 if (!pdev_priv_obj->indoor_chan_enabled) { 233 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 234 if (REGULATORY_CHAN_INDOOR_ONLY & 235 chan_list[chan_enum].chan_flags) { 236 chan_list[chan_enum].state = 237 CHANNEL_STATE_DFS; 238 chan_list[chan_enum].chan_flags |= 239 REGULATORY_CHAN_NO_IR; 240 } 241 } 242 } 243 244 if (pdev_priv_obj->force_ssc_disable_indoor_channel && 245 pdev_priv_obj->sap_state) { 246 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 247 if (REGULATORY_CHAN_INDOOR_ONLY & 248 chan_list[chan_enum].chan_flags) { 249 chan_list[chan_enum].state = 250 CHANNEL_STATE_DISABLE; 251 chan_list[chan_enum].chan_flags |= 252 REGULATORY_CHAN_DISABLED; 253 } 254 } 255 } 256 } 257 258 /** 259 * reg_modify_chan_list_for_band() - Based on the input band value, either 260 * disable 2GHz or 5GHz channels. 261 * @chan_list: Pointer to regulatory channel list. 262 * @band_val: Input band value. 263 */ 264 static void reg_modify_chan_list_for_band(struct regulatory_channel *chan_list, 265 enum band_info band_val) 266 { 267 enum channel_enum chan_enum; 268 269 if (band_val == BAND_2G) { 270 for (chan_enum = MIN_5GHZ_CHANNEL; 271 chan_enum <= MAX_5GHZ_CHANNEL; chan_enum++) { 272 chan_list[chan_enum].chan_flags |= 273 REGULATORY_CHAN_DISABLED; 274 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 275 } 276 } 277 278 if (band_val == BAND_5G) { 279 for (chan_enum = MIN_24GHZ_CHANNEL; 280 chan_enum <= MAX_24GHZ_CHANNEL; chan_enum++) { 281 chan_list[chan_enum].chan_flags |= 282 REGULATORY_CHAN_DISABLED; 283 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 284 } 285 } 286 } 287 288 /** 289 * reg_modify_chan_list_for_fcc_channel() - Set maximum FCC txpower for channel 290 * 12 and 13 if set_fcc_channel flag is set to true. 291 * @chan_list: Pointer to regulatory channel list. 292 * @set_fcc_channel: If this flag is set to true, then set the max FCC txpower 293 * for channel 12 and 13. 294 */ 295 static void reg_modify_chan_list_for_fcc_channel( 296 struct regulatory_channel *chan_list, bool set_fcc_channel) 297 { 298 enum channel_enum chan_enum; 299 300 if (!set_fcc_channel) 301 return; 302 303 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 304 if (chan_list[chan_enum].center_freq == CHAN_12_CENT_FREQ) 305 chan_list[chan_enum].tx_power = MAX_PWR_FCC_CHAN_12; 306 307 if (chan_list[chan_enum].center_freq == CHAN_13_CENT_FREQ) 308 chan_list[chan_enum].tx_power = MAX_PWR_FCC_CHAN_13; 309 } 310 } 311 312 /** 313 * reg_modify_chan_list_for_chan_144() - Disable channel 144 if en_chan_144 flag 314 * is set to false. 315 * @chan_list: Pointer to regulatory channel list. 316 * @en_chan_144: if false, then disable channel 144. 317 */ 318 static void reg_modify_chan_list_for_chan_144( 319 struct regulatory_channel *chan_list, bool en_chan_144) 320 { 321 enum channel_enum chan_enum; 322 323 if (en_chan_144) 324 return; 325 326 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 327 if (chan_list[chan_enum].center_freq == CHAN_144_CENT_FREQ) { 328 chan_list[chan_enum].chan_flags |= 329 REGULATORY_CHAN_DISABLED; 330 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 331 } 332 } 333 } 334 335 /** 336 * reg_modify_chan_list_for_nol_list() - Disable the channel if nol_chan flag is 337 * set. 338 * @chan_list: Pointer to regulatory channel list. 339 */ 340 static void reg_modify_chan_list_for_nol_list( 341 struct regulatory_channel *chan_list) 342 { 343 enum channel_enum chan_enum; 344 345 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 346 if (chan_list[chan_enum].nol_chan) { 347 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 348 chan_list[chan_enum].chan_flags |= 349 REGULATORY_CHAN_DISABLED; 350 } 351 } 352 } 353 354 /** 355 * reg_find_low_limit_chan_enum() - Find low limit 2G and 5G channel enums. 356 * @chan_list: Pointer to regulatory channel list. 357 * @low_freq: low limit frequency. 358 * @low_limit: pointer to output low limit enum. 359 * 360 * Return: None 361 */ 362 static void reg_find_low_limit_chan_enum( 363 struct regulatory_channel *chan_list, uint32_t low_freq, 364 uint32_t *low_limit) 365 { 366 enum channel_enum chan_enum; 367 uint16_t min_bw; 368 uint16_t max_bw; 369 uint32_t center_freq; 370 371 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 372 min_bw = chan_list[chan_enum].min_bw; 373 max_bw = chan_list[chan_enum].max_bw; 374 center_freq = chan_list[chan_enum].center_freq; 375 376 if ((center_freq - min_bw / 2) >= low_freq) { 377 if ((center_freq - max_bw / 2) < low_freq) { 378 if (max_bw <= 20) 379 max_bw = ((center_freq - low_freq) * 2); 380 if (max_bw < min_bw) 381 max_bw = min_bw; 382 chan_list[chan_enum].max_bw = max_bw; 383 } 384 *low_limit = chan_enum; 385 break; 386 } 387 } 388 } 389 390 /** 391 * reg_find_high_limit_chan_enum() - Find high limit 2G and 5G channel enums. 392 * @chan_list: Pointer to regulatory channel list. 393 * @high_freq: high limit frequency. 394 * @high_limit: pointer to output high limit enum. 395 * 396 * Return: None 397 */ 398 static void reg_find_high_limit_chan_enum( 399 struct regulatory_channel *chan_list, uint32_t high_freq, 400 uint32_t *high_limit) 401 { 402 enum channel_enum chan_enum; 403 uint16_t min_bw; 404 uint16_t max_bw; 405 uint32_t center_freq; 406 407 for (chan_enum = NUM_CHANNELS - 1; chan_enum >= 0; chan_enum--) { 408 min_bw = chan_list[chan_enum].min_bw; 409 max_bw = chan_list[chan_enum].max_bw; 410 center_freq = chan_list[chan_enum].center_freq; 411 412 if (center_freq + min_bw / 2 <= high_freq) { 413 if ((center_freq + max_bw / 2) > high_freq) { 414 if (max_bw <= 20) 415 max_bw = ((high_freq - 416 center_freq) * 2); 417 if (max_bw < min_bw) 418 max_bw = min_bw; 419 chan_list[chan_enum].max_bw = max_bw; 420 } 421 *high_limit = chan_enum; 422 break; 423 } 424 425 if (chan_enum == 0) 426 break; 427 } 428 } 429 430 /** 431 * reg_modify_chan_list_for_freq_range() - Modify channel list for the given low 432 * and high frequency range. 433 * @chan_list: Pointer to regulatory channel list. 434 * @low_freq_2g: Low frequency 2G. 435 * @high_freq_2g: High frequency 2G. 436 * @low_freq_5g: Low frequency 5G. 437 * @high_freq_5g: High frequency 5G. 438 * 439 * Return: None 440 */ 441 static void 442 reg_modify_chan_list_for_freq_range(struct regulatory_channel *chan_list, 443 uint32_t low_freq_2g, 444 uint32_t high_freq_2g, 445 uint32_t low_freq_5g, 446 uint32_t high_freq_5g) 447 { 448 uint32_t low_limit_2g = NUM_CHANNELS; 449 uint32_t high_limit_2g = NUM_CHANNELS; 450 uint32_t low_limit_5g = NUM_CHANNELS; 451 uint32_t high_limit_5g = NUM_CHANNELS; 452 enum channel_enum chan_enum; 453 bool chan_in_range; 454 455 reg_find_low_limit_chan_enum(chan_list, low_freq_2g, &low_limit_2g); 456 reg_find_low_limit_chan_enum(chan_list, low_freq_5g, &low_limit_5g); 457 reg_find_high_limit_chan_enum(chan_list, high_freq_2g, &high_limit_2g); 458 reg_find_high_limit_chan_enum(chan_list, high_freq_5g, &high_limit_5g); 459 460 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 461 chan_in_range = false; 462 if ((low_limit_2g <= chan_enum) && 463 (high_limit_2g >= chan_enum) && 464 (low_limit_2g != NUM_CHANNELS) && 465 (high_limit_2g != NUM_CHANNELS)) 466 chan_in_range = true; 467 468 if ((low_limit_5g <= chan_enum) && 469 (high_limit_5g >= chan_enum) && 470 (low_limit_5g != NUM_CHANNELS) && 471 (high_limit_5g != NUM_CHANNELS)) 472 chan_in_range = true; 473 474 if (!chan_in_range) { 475 chan_list[chan_enum].chan_flags |= 476 REGULATORY_CHAN_DISABLED; 477 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 478 } 479 } 480 } 481 482 void reg_init_pdev_mas_chan_list( 483 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 484 struct mas_chan_params *mas_chan_params) 485 { 486 qdf_mem_copy(pdev_priv_obj->mas_chan_list, 487 mas_chan_params->mas_chan_list, 488 NUM_CHANNELS * sizeof(struct regulatory_channel)); 489 490 pdev_priv_obj->dfs_region = mas_chan_params->dfs_region; 491 492 pdev_priv_obj->phybitmap = mas_chan_params->phybitmap; 493 494 pdev_priv_obj->reg_dmn_pair = mas_chan_params->reg_dmn_pair; 495 pdev_priv_obj->ctry_code = mas_chan_params->ctry_code; 496 497 pdev_priv_obj->def_region_domain = mas_chan_params->reg_dmn_pair; 498 pdev_priv_obj->def_country_code = mas_chan_params->ctry_code; 499 500 qdf_mem_copy(pdev_priv_obj->default_country, 501 mas_chan_params->default_country, REG_ALPHA2_LEN + 1); 502 503 qdf_mem_copy(pdev_priv_obj->current_country, 504 mas_chan_params->current_country, REG_ALPHA2_LEN + 1); 505 } 506 507 /** 508 * reg_modify_chan_list_for_cached_channels() - If num_cache_channels are 509 * non-zero, then disable the pdev channels which is given in 510 * cache_disable_chan_list. 511 * @pdev_priv_obj: Pointer to regulatory pdev private object. 512 */ 513 #ifdef DISABLE_CHANNEL_LIST 514 static void reg_modify_chan_list_for_cached_channels( 515 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 516 { 517 uint32_t i, j; 518 uint32_t num_cache_channels = pdev_priv_obj->num_cache_channels; 519 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list; 520 struct regulatory_channel *cache_chan_list = 521 pdev_priv_obj->cache_disable_chan_list; 522 523 if (!num_cache_channels) 524 return; 525 526 if (pdev_priv_obj->disable_cached_channels) { 527 for (i = 0; i < num_cache_channels; i++) 528 for (j = 0; j < NUM_CHANNELS; j++) 529 if (cache_chan_list[i].chan_num == 530 chan_list[j].chan_num) { 531 chan_list[j].state = 532 CHANNEL_STATE_DISABLE; 533 chan_list[j].chan_flags |= 534 REGULATORY_CHAN_DISABLED; 535 } 536 } 537 } 538 #else 539 static void reg_modify_chan_list_for_cached_channels( 540 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 541 { 542 } 543 #endif 544 545 void reg_compute_pdev_current_chan_list( 546 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 547 { 548 qdf_mem_copy(pdev_priv_obj->cur_chan_list, pdev_priv_obj->mas_chan_list, 549 NUM_CHANNELS * sizeof(struct regulatory_channel)); 550 551 reg_modify_chan_list_for_freq_range(pdev_priv_obj->cur_chan_list, 552 pdev_priv_obj->range_2g_low, 553 pdev_priv_obj->range_2g_high, 554 pdev_priv_obj->range_5g_low, 555 pdev_priv_obj->range_5g_high); 556 557 reg_modify_chan_list_for_band(pdev_priv_obj->cur_chan_list, 558 pdev_priv_obj->band_capability); 559 560 reg_modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list, 561 pdev_priv_obj->dfs_enabled); 562 563 reg_modify_chan_list_for_nol_list(pdev_priv_obj->cur_chan_list); 564 565 reg_modify_chan_list_for_indoor_channels(pdev_priv_obj); 566 567 reg_modify_chan_list_for_fcc_channel(pdev_priv_obj->cur_chan_list, 568 pdev_priv_obj->set_fcc_channel); 569 570 reg_modify_chan_list_for_chan_144(pdev_priv_obj->cur_chan_list, 571 pdev_priv_obj->en_chan_144); 572 573 reg_modify_chan_list_for_cached_channels(pdev_priv_obj); 574 } 575 576 void reg_reset_reg_rules(struct reg_rule_info *reg_rules) 577 { 578 qdf_mem_zero(reg_rules, sizeof(*reg_rules)); 579 } 580 581 void reg_save_reg_rules_to_pdev( 582 struct reg_rule_info *psoc_reg_rules, 583 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 584 { 585 uint32_t reg_rule_len; 586 struct reg_rule_info *pdev_reg_rules; 587 588 qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock); 589 590 pdev_reg_rules = &pdev_priv_obj->reg_rules; 591 reg_reset_reg_rules(pdev_reg_rules); 592 593 pdev_reg_rules->num_of_reg_rules = psoc_reg_rules->num_of_reg_rules; 594 if (!pdev_reg_rules->num_of_reg_rules) { 595 qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock); 596 reg_err("no reg rules in psoc"); 597 return; 598 } 599 600 reg_rule_len = pdev_reg_rules->num_of_reg_rules * 601 sizeof(struct cur_reg_rule); 602 qdf_mem_copy(pdev_reg_rules->reg_rules, psoc_reg_rules->reg_rules, 603 reg_rule_len); 604 605 qdf_mem_copy(pdev_reg_rules->alpha2, pdev_priv_obj->current_country, 606 REG_ALPHA2_LEN + 1); 607 pdev_reg_rules->dfs_region = pdev_priv_obj->dfs_region; 608 609 qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock); 610 } 611 612 void reg_propagate_mas_chan_list_to_pdev(struct wlan_objmgr_psoc *psoc, 613 void *object, void *arg) 614 { 615 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object; 616 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 617 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 618 enum direction *dir = arg; 619 uint32_t pdev_id; 620 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; 621 struct reg_rule_info *psoc_reg_rules; 622 623 psoc_priv_obj = (struct wlan_regulatory_psoc_priv_obj *) 624 wlan_objmgr_psoc_get_comp_private_obj( 625 psoc, WLAN_UMAC_COMP_REGULATORY); 626 627 if (!psoc_priv_obj) { 628 reg_err("psoc priv obj is NULL"); 629 return; 630 } 631 632 pdev_priv_obj = reg_get_pdev_obj(pdev); 633 634 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 635 reg_err("reg pdev priv obj is NULL"); 636 return; 637 } 638 639 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 640 reg_init_pdev_mas_chan_list( 641 pdev_priv_obj, 642 &psoc_priv_obj->mas_chan_params[pdev_id]); 643 psoc_reg_rules = &psoc_priv_obj->mas_chan_params[pdev_id].reg_rules; 644 reg_save_reg_rules_to_pdev(psoc_reg_rules, pdev_priv_obj); 645 reg_compute_pdev_current_chan_list(pdev_priv_obj); 646 647 reg_tx_ops = reg_get_psoc_tx_ops(psoc); 648 if (reg_tx_ops->fill_umac_legacy_chanlist) { 649 reg_tx_ops->fill_umac_legacy_chanlist( 650 pdev, pdev_priv_obj->cur_chan_list); 651 } else { 652 if (*dir == NORTHBOUND) 653 reg_send_scheduler_msg_nb(psoc, pdev); 654 else 655 reg_send_scheduler_msg_sb(psoc, pdev); 656 } 657 } 658 659 QDF_STATUS reg_process_master_chan_list( 660 struct cur_regulatory_info *regulat_info) 661 { 662 struct wlan_regulatory_psoc_priv_obj *soc_reg; 663 uint32_t num_2g_reg_rules, num_5g_reg_rules; 664 struct cur_reg_rule *reg_rule_2g, *reg_rule_5g; 665 uint16_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g; 666 struct regulatory_channel *mas_chan_list; 667 struct wlan_objmgr_psoc *psoc; 668 enum channel_enum chan_enum; 669 wlan_objmgr_ref_dbgid dbg_id; 670 enum direction dir; 671 uint8_t phy_id; 672 struct wlan_objmgr_pdev *pdev; 673 struct wlan_lmac_if_reg_tx_ops *tx_ops; 674 struct reg_rule_info *reg_rules; 675 QDF_STATUS status; 676 677 psoc = regulat_info->psoc; 678 soc_reg = reg_get_psoc_obj(psoc); 679 680 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) { 681 reg_err("psoc reg component is NULL"); 682 return QDF_STATUS_E_FAILURE; 683 } 684 685 tx_ops = reg_get_psoc_tx_ops(psoc); 686 phy_id = regulat_info->phy_id; 687 688 if (reg_ignore_default_country(soc_reg, regulat_info)) { 689 status = reg_set_curr_country(soc_reg, regulat_info, tx_ops); 690 if (QDF_IS_STATUS_SUCCESS(status)) { 691 reg_debug("WLAN restart - Ignore default CC for phy_id: %u", 692 phy_id); 693 return QDF_STATUS_SUCCESS; 694 } 695 } 696 697 reg_debug("process reg master chan list"); 698 699 if (soc_reg->offload_enabled) { 700 dbg_id = WLAN_REGULATORY_NB_ID; 701 dir = NORTHBOUND; 702 } else { 703 dbg_id = WLAN_REGULATORY_SB_ID; 704 dir = SOUTHBOUND; 705 } 706 707 if (regulat_info->status_code != REG_SET_CC_STATUS_PASS) { 708 reg_err("Setting country code failed, status code is %d", 709 regulat_info->status_code); 710 711 pdev = wlan_objmgr_get_pdev_by_id(psoc, phy_id, dbg_id); 712 if (!pdev) { 713 reg_err("pdev is NULL"); 714 return QDF_STATUS_E_FAILURE; 715 } 716 717 if (tx_ops->set_country_failed) 718 tx_ops->set_country_failed(pdev); 719 720 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 721 722 if (regulat_info->status_code != REG_CURRENT_ALPHA2_NOT_FOUND) 723 return QDF_STATUS_E_FAILURE; 724 725 soc_reg->new_user_ctry_pending[phy_id] = false; 726 soc_reg->new_11d_ctry_pending[phy_id] = false; 727 soc_reg->world_country_pending[phy_id] = true; 728 } 729 730 mas_chan_list = soc_reg->mas_chan_params[phy_id].mas_chan_list; 731 732 reg_init_channel_map(regulat_info->dfs_region); 733 734 for (chan_enum = 0; chan_enum < NUM_CHANNELS; 735 chan_enum++) { 736 mas_chan_list[chan_enum].chan_num = 737 channel_map[chan_enum].chan_num; 738 mas_chan_list[chan_enum].center_freq = 739 channel_map[chan_enum].center_freq; 740 mas_chan_list[chan_enum].chan_flags = 741 REGULATORY_CHAN_DISABLED; 742 mas_chan_list[chan_enum].state = 743 CHANNEL_STATE_DISABLE; 744 mas_chan_list[chan_enum].nol_chan = false; 745 } 746 747 soc_reg->num_phy = regulat_info->num_phy; 748 soc_reg->mas_chan_params[phy_id].phybitmap = 749 regulat_info->phybitmap; 750 soc_reg->mas_chan_params[phy_id].dfs_region = 751 regulat_info->dfs_region; 752 soc_reg->mas_chan_params[phy_id].ctry_code = 753 regulat_info->ctry_code; 754 soc_reg->mas_chan_params[phy_id].reg_dmn_pair = 755 regulat_info->reg_dmn_pair; 756 qdf_mem_copy(soc_reg->mas_chan_params[phy_id].current_country, 757 regulat_info->alpha2, 758 REG_ALPHA2_LEN + 1); 759 qdf_mem_copy(soc_reg->cur_country, 760 regulat_info->alpha2, 761 REG_ALPHA2_LEN + 1); 762 reg_debug("set cur_country %.2s", soc_reg->cur_country); 763 764 min_bw_2g = regulat_info->min_bw_2g; 765 max_bw_2g = regulat_info->max_bw_2g; 766 reg_rule_2g = regulat_info->reg_rules_2g_ptr; 767 num_2g_reg_rules = regulat_info->num_2g_reg_rules; 768 reg_update_max_bw_per_rule(num_2g_reg_rules, 769 reg_rule_2g, max_bw_2g); 770 771 min_bw_5g = regulat_info->min_bw_5g; 772 max_bw_5g = regulat_info->max_bw_5g; 773 reg_rule_5g = regulat_info->reg_rules_5g_ptr; 774 num_5g_reg_rules = regulat_info->num_5g_reg_rules; 775 reg_update_max_bw_per_rule(num_5g_reg_rules, 776 reg_rule_5g, max_bw_5g); 777 778 reg_rules = &soc_reg->mas_chan_params[phy_id].reg_rules; 779 reg_reset_reg_rules(reg_rules); 780 781 reg_rules->num_of_reg_rules = num_5g_reg_rules + num_2g_reg_rules; 782 if (reg_rules->num_of_reg_rules > MAX_REG_RULES) { 783 reg_err("number of reg rules exceeds limit"); 784 return QDF_STATUS_E_FAILURE; 785 } 786 787 if (reg_rules->num_of_reg_rules) { 788 if (num_2g_reg_rules) 789 qdf_mem_copy(reg_rules->reg_rules, 790 reg_rule_2g, num_2g_reg_rules * 791 sizeof(struct cur_reg_rule)); 792 if (num_5g_reg_rules) 793 qdf_mem_copy(reg_rules->reg_rules + 794 num_2g_reg_rules, reg_rule_5g, 795 num_5g_reg_rules * 796 sizeof(struct cur_reg_rule)); 797 } 798 799 if (num_5g_reg_rules != 0) 800 reg_do_auto_bw_correction(num_5g_reg_rules, 801 reg_rule_5g, max_bw_5g); 802 803 if (num_2g_reg_rules != 0) 804 reg_populate_band_channels(MIN_24GHZ_CHANNEL, MAX_24GHZ_CHANNEL, 805 reg_rule_2g, num_2g_reg_rules, 806 min_bw_2g, mas_chan_list); 807 808 if (num_5g_reg_rules != 0) 809 reg_populate_band_channels(MIN_5GHZ_CHANNEL, MAX_5GHZ_CHANNEL, 810 reg_rule_5g, num_5g_reg_rules, 811 min_bw_5g, mas_chan_list); 812 813 if (num_5g_reg_rules != 0) 814 reg_populate_band_channels(MIN_49GHZ_CHANNEL, 815 MAX_49GHZ_CHANNEL, 816 reg_rule_5g, num_5g_reg_rules, 817 min_bw_5g, mas_chan_list); 818 819 if (soc_reg->new_user_ctry_pending[phy_id]) { 820 soc_reg->new_user_ctry_pending[phy_id] = false; 821 soc_reg->cc_src = SOURCE_USERSPACE; 822 soc_reg->user_ctry_set = true; 823 reg_debug("new user country is set"); 824 reg_run_11d_state_machine(psoc); 825 } else if (soc_reg->new_init_ctry_pending[phy_id]) { 826 soc_reg->new_init_ctry_pending[phy_id] = false; 827 soc_reg->cc_src = SOURCE_USERSPACE; 828 reg_debug("new init country is set"); 829 } else if (soc_reg->new_11d_ctry_pending[phy_id]) { 830 soc_reg->new_11d_ctry_pending[phy_id] = false; 831 soc_reg->cc_src = SOURCE_11D; 832 soc_reg->user_ctry_set = false; 833 reg_run_11d_state_machine(psoc); 834 } else if (soc_reg->world_country_pending[phy_id]) { 835 soc_reg->world_country_pending[phy_id] = false; 836 soc_reg->cc_src = SOURCE_CORE; 837 soc_reg->user_ctry_set = false; 838 reg_run_11d_state_machine(psoc); 839 } else { 840 if (soc_reg->cc_src == SOURCE_UNKNOWN && 841 soc_reg->num_phy == phy_id + 1) 842 soc_reg->cc_src = SOURCE_DRIVER; 843 844 qdf_mem_copy(soc_reg->mas_chan_params[phy_id].default_country, 845 regulat_info->alpha2, 846 REG_ALPHA2_LEN + 1); 847 848 soc_reg->mas_chan_params[phy_id].def_country_code = 849 regulat_info->ctry_code; 850 soc_reg->mas_chan_params[phy_id].def_region_domain = 851 regulat_info->reg_dmn_pair; 852 853 if (soc_reg->cc_src == SOURCE_DRIVER) { 854 qdf_mem_copy(soc_reg->def_country, 855 regulat_info->alpha2, 856 REG_ALPHA2_LEN + 1); 857 858 soc_reg->def_country_code = regulat_info->ctry_code; 859 soc_reg->def_region_domain = 860 regulat_info->reg_dmn_pair; 861 862 if (reg_is_world_alpha2(regulat_info->alpha2)) { 863 soc_reg->cc_src = SOURCE_CORE; 864 reg_run_11d_state_machine(psoc); 865 } 866 } 867 } 868 869 pdev = wlan_objmgr_get_pdev_by_id(psoc, phy_id, dbg_id); 870 if (pdev) { 871 reg_propagate_mas_chan_list_to_pdev(psoc, pdev, &dir); 872 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 873 reg_reset_reg_rules(reg_rules); 874 } 875 876 return QDF_STATUS_SUCCESS; 877 } 878 879 QDF_STATUS reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev, 880 struct regulatory_channel *chan_list) 881 { 882 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 883 884 pdev_priv_obj = reg_get_pdev_obj(pdev); 885 886 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 887 reg_err("reg pdev private obj is NULL"); 888 return QDF_STATUS_E_FAILURE; 889 } 890 891 qdf_mem_copy(chan_list, pdev_priv_obj->cur_chan_list, 892 NUM_CHANNELS * sizeof(struct regulatory_channel)); 893 894 return QDF_STATUS_SUCCESS; 895 } 896