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