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_utils.c 21 * This file defines the APIs to set and get the regulatory variables. 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_db.h" 32 #include "reg_db_parser.h" 33 #include "reg_host_11d.h" 34 #include <scheduler_api.h> 35 #include <wlan_reg_services_api.h> 36 #include <qdf_platform.h> 37 #include "reg_services_common.h" 38 #include "reg_build_chan_list.h" 39 40 #define DEFAULT_WORLD_REGDMN 0x60 41 42 #define IS_VALID_PSOC_REG_OBJ(psoc_priv_obj) (psoc_priv_obj) 43 #define IS_VALID_PDEV_REG_OBJ(pdev_priv_obj) (pdev_priv_obj) 44 45 #ifdef CONFIG_CHAN_NUM_API 46 bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint8_t ch) 47 { 48 enum channel_enum ch_idx; 49 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 50 51 ch_idx = reg_get_chan_enum(ch); 52 53 if (ch_idx == INVALID_CHANNEL) 54 return false; 55 56 pdev_priv_obj = reg_get_pdev_obj(pdev); 57 58 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 59 reg_err("pdev reg obj is NULL"); 60 return false; 61 } 62 63 if (pdev_priv_obj->cur_chan_list[ch_idx].chan_flags & 64 REGULATORY_CHAN_RADAR) 65 return true; 66 67 return false; 68 } 69 #endif /* CONFIG_CHAN_NUM_API */ 70 71 #ifdef CONFIG_CHAN_FREQ_API 72 bool reg_chan_has_dfs_attribute_for_freq(struct wlan_objmgr_pdev *pdev, 73 qdf_freq_t freq) 74 { 75 enum channel_enum ch_idx; 76 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 77 78 ch_idx = reg_get_chan_enum_for_freq(freq); 79 80 if (ch_idx == INVALID_CHANNEL) 81 return false; 82 83 pdev_priv_obj = reg_get_pdev_obj(pdev); 84 85 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 86 reg_err("pdev reg obj is NULL"); 87 return false; 88 } 89 90 if (pdev_priv_obj->cur_chan_list[ch_idx].chan_flags & 91 REGULATORY_CHAN_RADAR) 92 return true; 93 94 return false; 95 } 96 #endif /* CONFIG_CHAN_FREQ_API */ 97 98 bool reg_is_world_ctry_code(uint16_t ctry_code) 99 { 100 if ((ctry_code & 0xFFF0) == DEFAULT_WORLD_REGDMN) 101 return true; 102 103 return false; 104 } 105 106 QDF_STATUS reg_read_current_country(struct wlan_objmgr_psoc *psoc, 107 uint8_t *country_code) 108 { 109 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 110 111 if (!country_code) { 112 reg_err("country_code is NULL"); 113 return QDF_STATUS_E_INVAL; 114 } 115 116 psoc_reg = reg_get_psoc_obj(psoc); 117 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 118 reg_err("psoc reg component is NULL"); 119 return QDF_STATUS_E_INVAL; 120 } 121 122 qdf_mem_copy(country_code, psoc_reg->cur_country, REG_ALPHA2_LEN + 1); 123 124 return QDF_STATUS_SUCCESS; 125 } 126 127 /** 128 * reg_set_default_country() - Read the default country for the regdomain 129 * @country: country code. 130 * 131 * Return: QDF_STATUS 132 */ 133 QDF_STATUS reg_set_default_country(struct wlan_objmgr_psoc *psoc, 134 uint8_t *country) 135 { 136 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 137 138 if (!country) { 139 reg_err("country is NULL"); 140 return QDF_STATUS_E_INVAL; 141 } 142 143 psoc_reg = reg_get_psoc_obj(psoc); 144 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 145 reg_err("psoc reg component is NULL"); 146 return QDF_STATUS_E_INVAL; 147 } 148 149 reg_info("setting default_country: %s", country); 150 151 qdf_mem_copy(psoc_reg->def_country, country, REG_ALPHA2_LEN + 1); 152 153 return QDF_STATUS_SUCCESS; 154 } 155 156 bool reg_is_world_alpha2(uint8_t *alpha2) 157 { 158 if ((alpha2[0] == '0') && (alpha2[1] == '0')) 159 return true; 160 161 return false; 162 } 163 164 bool reg_is_us_alpha2(uint8_t *alpha2) 165 { 166 if ((alpha2[0] == 'U') && (alpha2[1] == 'S')) 167 return true; 168 169 return false; 170 } 171 172 QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev, 173 uint8_t *country) 174 { 175 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 176 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 177 struct wlan_lmac_if_reg_tx_ops *tx_ops; 178 struct set_country cc; 179 struct wlan_objmgr_psoc *psoc; 180 struct cc_regdmn_s rd; 181 uint8_t pdev_id; 182 183 if (!pdev) { 184 reg_err("pdev is NULL"); 185 return QDF_STATUS_E_INVAL; 186 } 187 188 if (!country) { 189 reg_err("country code is NULL"); 190 return QDF_STATUS_E_INVAL; 191 } 192 193 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 194 195 psoc = wlan_pdev_get_psoc(pdev); 196 197 psoc_reg = reg_get_psoc_obj(psoc); 198 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 199 reg_err("psoc reg component is NULL"); 200 return QDF_STATUS_E_INVAL; 201 } 202 203 if (!qdf_mem_cmp(psoc_reg->cur_country, country, REG_ALPHA2_LEN)) { 204 reg_err("country is not different"); 205 return QDF_STATUS_SUCCESS; 206 } 207 208 reg_debug("programming new country: %s to firmware", country); 209 210 qdf_mem_copy(cc.country, country, REG_ALPHA2_LEN + 1); 211 cc.pdev_id = pdev_id; 212 213 if (!psoc_reg->offload_enabled && !reg_is_world_alpha2(country)) { 214 QDF_STATUS status; 215 216 status = reg_is_country_code_valid(country); 217 if (!QDF_IS_STATUS_SUCCESS(status)) { 218 reg_err("Unable to set country code: %s\n", country); 219 reg_err("Restoring to world domain"); 220 qdf_mem_copy(cc.country, REG_WORLD_ALPHA2, 221 REG_ALPHA2_LEN + 1); 222 } 223 } 224 225 226 if (reg_is_world_alpha2(cc.country)) 227 psoc_reg->world_country_pending[pdev_id] = true; 228 else 229 psoc_reg->new_user_ctry_pending[pdev_id] = true; 230 231 if (psoc_reg->offload_enabled) { 232 tx_ops = reg_get_psoc_tx_ops(psoc); 233 if (tx_ops->set_country_code) { 234 tx_ops->set_country_code(psoc, &cc); 235 } else { 236 reg_err("country set fw handler not present"); 237 psoc_reg->new_user_ctry_pending[pdev_id] = false; 238 return QDF_STATUS_E_FAULT; 239 } 240 } else { 241 if (reg_is_world_alpha2(cc.country)) { 242 pdev_priv_obj = reg_get_pdev_obj(pdev); 243 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 244 reg_err("reg component pdev priv is NULL"); 245 psoc_reg->world_country_pending[pdev_id] = 246 false; 247 return QDF_STATUS_E_INVAL; 248 } 249 if (reg_is_world_ctry_code( 250 pdev_priv_obj->def_region_domain)) 251 rd.cc.regdmn_id = 252 pdev_priv_obj->def_region_domain; 253 else 254 rd.cc.regdmn_id = DEFAULT_WORLD_REGDMN; 255 rd.flags = REGDMN_IS_SET; 256 } else { 257 qdf_mem_copy(rd.cc.alpha, cc.country, 258 REG_ALPHA2_LEN + 1); 259 rd.flags = ALPHA_IS_SET; 260 } 261 262 reg_program_chan_list(pdev, &rd); 263 } 264 265 return QDF_STATUS_SUCCESS; 266 } 267 268 QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc) 269 { 270 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 271 272 psoc_reg = reg_get_psoc_obj(psoc); 273 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 274 reg_err("psoc reg component is NULL"); 275 return QDF_STATUS_E_INVAL; 276 } 277 278 reg_info("re-setting user country to default"); 279 qdf_mem_copy(psoc_reg->cur_country, 280 psoc_reg->def_country, 281 REG_ALPHA2_LEN + 1); 282 reg_debug("set cur_country %.2s", psoc_reg->cur_country); 283 284 return QDF_STATUS_SUCCESS; 285 } 286 287 QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, 288 const uint8_t *country_alpha2, 289 enum country_src source) 290 { 291 if (!reg_domain_ptr) { 292 reg_err("Invalid reg domain pointer"); 293 return QDF_STATUS_E_FAULT; 294 } 295 296 *reg_domain_ptr = 0; 297 298 if (!country_alpha2) { 299 reg_err("Country code array is NULL"); 300 return QDF_STATUS_E_FAULT; 301 } 302 303 return QDF_STATUS_SUCCESS; 304 } 305 306 #ifdef CONFIG_CHAN_NUM_API 307 bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, 308 uint8_t chan) 309 { 310 enum channel_state ch_state; 311 312 ch_state = reg_get_channel_state(pdev, chan); 313 314 return (ch_state == CHANNEL_STATE_DFS) || 315 (ch_state == CHANNEL_STATE_DISABLE); 316 } 317 #endif /* CONFIG_CHAN_NUM_API */ 318 319 #ifdef CONFIG_CHAN_FREQ_API 320 bool reg_is_passive_or_disable_for_freq(struct wlan_objmgr_pdev *pdev, 321 qdf_freq_t freq) 322 { 323 enum channel_state chan_state; 324 325 chan_state = reg_get_channel_state_for_freq(pdev, freq); 326 327 return (chan_state == CHANNEL_STATE_DFS) || 328 (chan_state == CHANNEL_STATE_DISABLE); 329 } 330 #endif /* CONFIG_CHAN_FREQ_API */ 331 332 #ifdef WLAN_FEATURE_DSRC 333 #ifdef CONFIG_CHAN_FREQ_API 334 bool reg_is_dsrc_freq(qdf_freq_t freq) 335 { 336 if (!REG_IS_5GHZ_FREQ(freq)) 337 return false; 338 339 if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ)) 340 return false; 341 342 return true; 343 } 344 #endif /*CONFIG_CHAN_FREQ_API*/ 345 346 #ifdef CONFIG_CHAN_NUM_API 347 bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint8_t chan) 348 { 349 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 350 qdf_freq_t freq = 0; 351 352 pdev_priv_obj = reg_get_pdev_obj(pdev); 353 354 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 355 reg_err("reg pdev priv obj is NULL"); 356 return false; 357 } 358 359 if (!REG_IS_5GHZ_CH(chan)) 360 return false; 361 362 freq = reg_chan_to_freq(pdev, chan); 363 364 if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ)) 365 return false; 366 367 return true; 368 } 369 #endif /* CONFIG_CHAN_NUM_API */ 370 371 #else 372 373 bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev) 374 { 375 struct cur_regdmn_info cur_reg_dmn; 376 QDF_STATUS status; 377 378 status = reg_get_curr_regdomain(pdev, &cur_reg_dmn); 379 if (status != QDF_STATUS_SUCCESS) { 380 reg_err_rl("Failed to get reg domain"); 381 return false; 382 } 383 384 return reg_etsi13_regdmn(cur_reg_dmn.dmn_id_5g); 385 } 386 387 #ifdef CONFIG_CHAN_FREQ_API 388 bool reg_is_etsi13_srd_chan_for_freq(struct wlan_objmgr_pdev *pdev, 389 uint16_t freq) 390 { 391 if (!REG_IS_5GHZ_FREQ(freq)) 392 return false; 393 394 if (!(freq >= REG_ETSI13_SRD_START_FREQ && 395 freq <= REG_ETSI13_SRD_END_FREQ)) 396 return false; 397 398 return reg_is_etsi13_regdmn(pdev); 399 } 400 #endif /* CONFIG_CHAN_FREQ_API */ 401 402 #ifdef CONFIG_CHAN_NUM_API 403 bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint8_t chan) 404 { 405 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 406 qdf_freq_t freq = 0; 407 408 pdev_priv_obj = reg_get_pdev_obj(pdev); 409 410 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 411 reg_err("reg pdev priv obj is NULL"); 412 return false; 413 } 414 415 if (!REG_IS_5GHZ_CH(chan)) 416 return false; 417 418 freq = reg_chan_to_freq(pdev, chan); 419 420 if (!(freq >= REG_ETSI13_SRD_START_FREQ && 421 freq <= REG_ETSI13_SRD_END_FREQ)) 422 return false; 423 424 return reg_is_etsi13_regdmn(pdev); 425 } 426 #endif /* CONFIG_CHAN_NUM_API */ 427 428 bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev) 429 { 430 struct wlan_objmgr_psoc *psoc; 431 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 432 433 if (!pdev) { 434 reg_alert("pdev is NULL"); 435 return true; 436 } 437 psoc = wlan_pdev_get_psoc(pdev); 438 439 psoc_priv_obj = reg_get_psoc_obj(psoc); 440 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 441 reg_alert("psoc reg component is NULL"); 442 return true; 443 } 444 445 return psoc_priv_obj->enable_srd_chan_in_master_mode && 446 reg_is_etsi13_regdmn(pdev); 447 } 448 #endif 449 450 QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, 451 enum band_info band) 452 { 453 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 454 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 455 struct wlan_objmgr_psoc *psoc; 456 QDF_STATUS status; 457 458 pdev_priv_obj = reg_get_pdev_obj(pdev); 459 460 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 461 reg_err("pdev reg component is NULL"); 462 return QDF_STATUS_E_INVAL; 463 } 464 465 if (pdev_priv_obj->band_capability == band) { 466 reg_info("band is already set to %d", band); 467 return QDF_STATUS_SUCCESS; 468 } 469 470 psoc = wlan_pdev_get_psoc(pdev); 471 if (!psoc) { 472 reg_err("psoc is NULL"); 473 return QDF_STATUS_E_INVAL; 474 } 475 476 psoc_priv_obj = reg_get_psoc_obj(psoc); 477 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 478 reg_err("psoc reg component is NULL"); 479 return QDF_STATUS_E_INVAL; 480 } 481 482 reg_info("setting band_info: %d", band); 483 pdev_priv_obj->band_capability = band; 484 485 reg_compute_pdev_current_chan_list(pdev_priv_obj); 486 487 status = reg_send_scheduler_msg_sb(psoc, pdev); 488 489 return status; 490 } 491 492 QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev, 493 enum band_info *band) 494 { 495 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 496 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 497 struct wlan_objmgr_psoc *psoc; 498 499 pdev_priv_obj = reg_get_pdev_obj(pdev); 500 501 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 502 reg_err("pdev reg component is NULL"); 503 return QDF_STATUS_E_INVAL; 504 } 505 506 psoc = wlan_pdev_get_psoc(pdev); 507 if (!psoc) { 508 reg_err("psoc is NULL"); 509 return QDF_STATUS_E_INVAL; 510 } 511 512 psoc_priv_obj = reg_get_psoc_obj(psoc); 513 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 514 reg_err("psoc reg component is NULL"); 515 return QDF_STATUS_E_INVAL; 516 } 517 518 reg_debug("getting band_info: %d", pdev_priv_obj->band_capability); 519 *band = pdev_priv_obj->band_capability; 520 521 return QDF_STATUS_SUCCESS; 522 } 523 524 #ifdef DISABLE_CHANNEL_LIST 525 QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) 526 { 527 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 528 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 529 struct wlan_objmgr_psoc *psoc; 530 QDF_STATUS status; 531 532 pdev_priv_obj = reg_get_pdev_obj(pdev); 533 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 534 reg_err("pdev reg component is NULL"); 535 return QDF_STATUS_E_INVAL; 536 } 537 538 psoc = wlan_pdev_get_psoc(pdev); 539 if (!psoc) { 540 reg_err("psoc is NULL"); 541 return QDF_STATUS_E_INVAL; 542 } 543 544 psoc_priv_obj = reg_get_psoc_obj(psoc); 545 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 546 reg_err("psoc reg component is NULL"); 547 return QDF_STATUS_E_INVAL; 548 } 549 550 pdev_priv_obj->disable_cached_channels = false; 551 reg_compute_pdev_current_chan_list(pdev_priv_obj); 552 status = reg_send_scheduler_msg_sb(psoc, pdev); 553 return status; 554 } 555 556 #ifdef CONFIG_CHAN_FREQ_API 557 QDF_STATUS reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev, 558 uint32_t *channel_list, 559 uint32_t num_channels) 560 { 561 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 562 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 563 struct wlan_objmgr_psoc *psoc; 564 uint16_t i, j; 565 566 pdev_priv_obj = reg_get_pdev_obj(pdev); 567 568 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 569 reg_err("pdev reg component is NULL"); 570 return QDF_STATUS_E_INVAL; 571 } 572 573 psoc = wlan_pdev_get_psoc(pdev); 574 if (!psoc) { 575 reg_err("psoc is NULL"); 576 return QDF_STATUS_E_INVAL; 577 } 578 579 psoc_priv_obj = reg_get_psoc_obj(psoc); 580 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 581 reg_err("psoc reg component is NULL"); 582 return QDF_STATUS_E_INVAL; 583 } 584 if (pdev_priv_obj->num_cache_channels > 0) { 585 pdev_priv_obj->num_cache_channels = 0; 586 qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list, 587 sizeof(pdev_priv_obj->cache_disable_chan_list)); 588 } 589 590 for (i = 0; i < num_channels; i++) { 591 for (j = 0; j < NUM_CHANNELS; j++) { 592 if (channel_list[i] == pdev_priv_obj-> 593 cur_chan_list[j].center_freq) { 594 pdev_priv_obj-> 595 cache_disable_chan_list[i].center_freq = 596 channel_list[i]; 597 pdev_priv_obj-> 598 cache_disable_chan_list[i].state = 599 pdev_priv_obj->cur_chan_list[j].state; 600 pdev_priv_obj-> 601 cache_disable_chan_list[i].chan_flags = 602 pdev_priv_obj-> 603 cur_chan_list[j].chan_flags; 604 } 605 } 606 } 607 pdev_priv_obj->num_cache_channels = num_channels; 608 609 return QDF_STATUS_SUCCESS; 610 } 611 #endif /* CONFIG_CHAN_FREQ_API */ 612 613 #ifdef CONFIG_CHAN_NUM_API 614 QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, 615 uint32_t *channel_list, 616 uint32_t num_channels) 617 { 618 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 619 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 620 struct wlan_objmgr_psoc *psoc; 621 uint8_t i, j; 622 623 pdev_priv_obj = reg_get_pdev_obj(pdev); 624 625 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 626 reg_err("pdev reg component is NULL"); 627 return QDF_STATUS_E_INVAL; 628 } 629 630 psoc = wlan_pdev_get_psoc(pdev); 631 if (!psoc) { 632 reg_err("psoc is NULL"); 633 return QDF_STATUS_E_INVAL; 634 } 635 636 psoc_priv_obj = reg_get_psoc_obj(psoc); 637 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 638 reg_err("psoc reg component is NULL"); 639 return QDF_STATUS_E_INVAL; 640 } 641 if (pdev_priv_obj->num_cache_channels > 0) { 642 pdev_priv_obj->num_cache_channels = 0; 643 qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list, 644 sizeof(pdev_priv_obj->cache_disable_chan_list)); 645 } 646 647 for (i = 0; i < num_channels; i++) { 648 for (j = 0; j < NUM_CHANNELS; j++) { 649 if (channel_list[i] == pdev_priv_obj-> 650 cur_chan_list[j].chan_num) { 651 pdev_priv_obj-> 652 cache_disable_chan_list[i].chan_num = 653 channel_list[i]; 654 pdev_priv_obj-> 655 cache_disable_chan_list[i].state = 656 pdev_priv_obj->cur_chan_list[j].state; 657 pdev_priv_obj-> 658 cache_disable_chan_list[i].chan_flags = 659 pdev_priv_obj-> 660 cur_chan_list[j].chan_flags; 661 } 662 } 663 } 664 pdev_priv_obj->num_cache_channels = num_channels; 665 666 return QDF_STATUS_SUCCESS; 667 } 668 #endif /* CONFIG_CHAN_NUM_API */ 669 void set_disable_channel_state( 670 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 671 { 672 pdev_priv_obj->disable_cached_channels = pdev_priv_obj->sap_state; 673 } 674 #endif 675 676 #ifdef CONFIG_REG_CLIENT 677 678 QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev, 679 bool fcc_constraint) 680 { 681 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 682 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 683 struct wlan_objmgr_psoc *psoc; 684 QDF_STATUS status; 685 686 pdev_priv_obj = reg_get_pdev_obj(pdev); 687 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 688 reg_err("pdev reg component is NULL"); 689 return QDF_STATUS_E_INVAL; 690 } 691 692 if (pdev_priv_obj->set_fcc_channel == fcc_constraint) { 693 reg_info("fcc_constraint is already set to %d", fcc_constraint); 694 return QDF_STATUS_SUCCESS; 695 } 696 697 reg_info("setting set_fcc_channel: %d", fcc_constraint); 698 pdev_priv_obj->set_fcc_channel = fcc_constraint; 699 700 psoc = wlan_pdev_get_psoc(pdev); 701 if (!psoc) { 702 reg_err("psoc is NULL"); 703 return QDF_STATUS_E_INVAL; 704 } 705 706 psoc_priv_obj = reg_get_psoc_obj(psoc); 707 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 708 reg_err("psoc reg component is NULL"); 709 return QDF_STATUS_E_INVAL; 710 } 711 712 reg_compute_pdev_current_chan_list(pdev_priv_obj); 713 714 status = reg_send_scheduler_msg_sb(psoc, pdev); 715 716 return status; 717 } 718 719 bool reg_get_fcc_constraint(struct wlan_objmgr_pdev *pdev, uint32_t freq) 720 { 721 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 722 723 pdev_priv_obj = reg_get_pdev_obj(pdev); 724 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 725 reg_err("pdev reg component is NULL"); 726 return false; 727 } 728 729 if (freq != CHAN_12_CENT_FREQ && freq != CHAN_13_CENT_FREQ) 730 return false; 731 732 if (!pdev_priv_obj->set_fcc_channel) 733 return false; 734 735 return true; 736 } 737 738 #endif /* CONFIG_REG_CLIENT */ 739 740 /** 741 * reg_change_pdev_for_config() - Update user configuration in pdev private obj. 742 * @psoc: Pointer to global psoc structure. 743 * @object: Pointer to global pdev structure. 744 * @arg: Pointer to argument list. 745 */ 746 static void reg_change_pdev_for_config(struct wlan_objmgr_psoc *psoc, 747 void *object, void *arg) 748 { 749 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object; 750 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 751 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 752 753 psoc_priv_obj = reg_get_psoc_obj(psoc); 754 if (!psoc_priv_obj) { 755 reg_err("psoc priv obj is NULL"); 756 return; 757 } 758 759 pdev_priv_obj = reg_get_pdev_obj(pdev); 760 761 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 762 reg_err("reg pdev private obj is NULL"); 763 return; 764 } 765 766 pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled; 767 pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled; 768 pdev_priv_obj->force_ssc_disable_indoor_channel = 769 psoc_priv_obj->force_ssc_disable_indoor_channel; 770 pdev_priv_obj->band_capability = psoc_priv_obj->band_capability; 771 772 reg_compute_pdev_current_chan_list(pdev_priv_obj); 773 774 reg_send_scheduler_msg_sb(psoc, pdev); 775 } 776 777 QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc, 778 struct reg_config_vars config_vars) 779 { 780 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 781 QDF_STATUS status; 782 783 psoc_priv_obj = reg_get_psoc_obj(psoc); 784 if (!psoc_priv_obj) { 785 reg_err("psoc priv obj is NULL"); 786 return QDF_STATUS_E_FAILURE; 787 } 788 789 psoc_priv_obj->enable_11d_supp_original = 790 config_vars.enable_11d_support; 791 psoc_priv_obj->scan_11d_interval = config_vars.scan_11d_interval; 792 psoc_priv_obj->user_ctry_priority = config_vars.userspace_ctry_priority; 793 psoc_priv_obj->dfs_enabled = config_vars.dfs_enabled; 794 psoc_priv_obj->indoor_chan_enabled = config_vars.indoor_chan_enabled; 795 psoc_priv_obj->force_ssc_disable_indoor_channel = 796 config_vars.force_ssc_disable_indoor_channel; 797 psoc_priv_obj->band_capability = config_vars.band_capability; 798 psoc_priv_obj->restart_beaconing = config_vars.restart_beaconing; 799 psoc_priv_obj->enable_srd_chan_in_master_mode = 800 config_vars.enable_srd_chan_in_master_mode; 801 psoc_priv_obj->enable_11d_in_world_mode = 802 config_vars.enable_11d_in_world_mode; 803 804 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); 805 if (QDF_IS_STATUS_ERROR(status)) { 806 reg_err("error taking psoc ref cnt"); 807 return status; 808 } 809 status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, 810 reg_change_pdev_for_config, 811 NULL, 1, WLAN_REGULATORY_SB_ID); 812 wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID); 813 814 return status; 815 } 816 817 #ifdef CONFIG_CHAN_FREQ_API 818 bool reg_is_disable_for_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq) 819 { 820 enum channel_state ch_state; 821 822 ch_state = reg_get_channel_state_for_freq(pdev, freq); 823 824 return ch_state == CHANNEL_STATE_DISABLE; 825 } 826 #endif /* CONFIG_CHAN_FREQ_API */ 827 828 #ifdef CONFIG_CHAN_NUM_API 829 bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint8_t chan) 830 { 831 enum channel_state ch_state; 832 833 ch_state = reg_get_channel_state(pdev, chan); 834 835 return ch_state == CHANNEL_STATE_DISABLE; 836 } 837 #endif /* CONFIG_CHAN_NUM_API */ 838 839 bool reg_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc) 840 { 841 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 842 843 psoc_priv_obj = reg_get_psoc_obj(psoc); 844 if (!psoc_priv_obj) { 845 reg_err("reg psoc private obj is NULL"); 846 return false; 847 } 848 849 return psoc_priv_obj->offload_enabled; 850 } 851 852 void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc, 853 struct regulatory_channel *reg_channels, 854 uint8_t *alpha2, 855 enum dfs_reg dfs_region) 856 { 857 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 858 QDF_STATUS status; 859 uint32_t count; 860 enum direction dir; 861 uint32_t pdev_cnt; 862 863 psoc_priv_obj = reg_get_psoc_obj(psoc); 864 if (!psoc_priv_obj) { 865 reg_err("reg psoc private obj is NULL"); 866 return; 867 } 868 869 qdf_mem_copy(psoc_priv_obj->cur_country, alpha2, 870 REG_ALPHA2_LEN); 871 reg_debug("set cur_country %.2s", psoc_priv_obj->cur_country); 872 for (count = 0; count < NUM_CHANNELS; count++) { 873 reg_channels[count].chan_num = channel_map[count].chan_num; 874 reg_channels[count].center_freq = 875 channel_map[count].center_freq; 876 reg_channels[count].nol_chan = false; 877 } 878 879 for (pdev_cnt = 0; pdev_cnt < PSOC_MAX_PHY_REG_CAP; pdev_cnt++) { 880 qdf_mem_copy(psoc_priv_obj->mas_chan_params[pdev_cnt]. 881 mas_chan_list, reg_channels, 882 NUM_CHANNELS * sizeof(struct regulatory_channel)); 883 884 psoc_priv_obj->mas_chan_params[pdev_cnt].dfs_region = 885 dfs_region; 886 } 887 888 dir = SOUTHBOUND; 889 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); 890 if (QDF_IS_STATUS_ERROR(status)) { 891 reg_err("error taking psoc ref cnt"); 892 return; 893 } 894 status = wlan_objmgr_iterate_obj_list( 895 psoc, WLAN_PDEV_OP, reg_propagate_mas_chan_list_to_pdev, 896 &dir, 1, WLAN_REGULATORY_SB_ID); 897 wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID); 898 } 899 900 enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc, 901 uint8_t *alpha2) 902 { 903 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 904 905 psoc_priv_obj = reg_get_psoc_obj(psoc); 906 if (!psoc_priv_obj) { 907 reg_err("reg psoc private obj is NULL"); 908 return SOURCE_UNKNOWN; 909 } 910 911 qdf_mem_copy(alpha2, psoc_priv_obj->cur_country, REG_ALPHA2_LEN + 1); 912 913 return psoc_priv_obj->cc_src; 914 } 915 916 QDF_STATUS reg_get_regd_rules(struct wlan_objmgr_pdev *pdev, 917 struct reg_rule_info *reg_rules) 918 { 919 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 920 921 if (!pdev) { 922 reg_err("pdev is NULL"); 923 return QDF_STATUS_E_FAILURE; 924 } 925 926 pdev_priv_obj = reg_get_pdev_obj(pdev); 927 if (!pdev_priv_obj) { 928 reg_err("pdev priv obj is NULL"); 929 return QDF_STATUS_E_FAILURE; 930 } 931 932 qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock); 933 qdf_mem_copy(reg_rules, &pdev_priv_obj->reg_rules, 934 sizeof(struct reg_rule_info)); 935 qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock); 936 937 return QDF_STATUS_SUCCESS; 938 } 939 940 void reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj 941 *soc_reg) 942 { 943 uint8_t ctr; 944 945 if (!soc_reg->offload_enabled) 946 return; 947 948 for (ctr = 0; ctr < PSOC_MAX_PHY_REG_CAP; ctr++) { 949 soc_reg->new_user_ctry_pending[ctr] = false; 950 soc_reg->new_init_ctry_pending[ctr] = false; 951 soc_reg->new_11d_ctry_pending[ctr] = false; 952 soc_reg->world_country_pending[ctr] = false; 953 } 954 } 955 956 QDF_STATUS reg_set_curr_country(struct wlan_regulatory_psoc_priv_obj *soc_reg, 957 struct cur_regulatory_info *regulat_info, 958 struct wlan_lmac_if_reg_tx_ops *tx_ops) 959 { 960 struct wlan_objmgr_psoc *psoc = regulat_info->psoc; 961 uint8_t pdev_id; 962 uint8_t phy_num; 963 struct set_country country_code; 964 QDF_STATUS status; 965 966 /* 967 * During SSR/WLAN restart ignore master channel list 968 * for all events and in the last event handling if 969 * current country and default country is different, send the last 970 * configured (soc_reg->cur_country) country. 971 */ 972 if ((regulat_info->num_phy != regulat_info->phy_id + 1) || 973 (!qdf_mem_cmp(soc_reg->cur_country, regulat_info->alpha2, 974 REG_ALPHA2_LEN))) 975 return QDF_STATUS_SUCCESS; 976 977 /* 978 * Need firmware to send channel list event 979 * for all phys. Therefore set pdev_id to 0xFF 980 */ 981 pdev_id = 0xFF; 982 for (phy_num = 0; phy_num < regulat_info->num_phy; phy_num++) { 983 if (soc_reg->cc_src == SOURCE_USERSPACE) 984 soc_reg->new_user_ctry_pending[phy_num] = true; 985 else if (soc_reg->cc_src == SOURCE_11D) 986 soc_reg->new_11d_ctry_pending[phy_num] = true; 987 else 988 soc_reg->world_country_pending[phy_num] = true; 989 } 990 991 qdf_mem_zero(&country_code, sizeof(country_code)); 992 qdf_mem_copy(country_code.country, soc_reg->cur_country, 993 sizeof(soc_reg->cur_country)); 994 country_code.pdev_id = pdev_id; 995 996 if (!tx_ops || !tx_ops->set_country_code) { 997 reg_err("No regulatory tx_ops for set_country_code"); 998 status = QDF_STATUS_E_FAULT; 999 goto error; 1000 } 1001 1002 status = tx_ops->set_country_code(psoc, &country_code); 1003 if (QDF_IS_STATUS_ERROR(status)) { 1004 reg_err("Failed to send country code to firmware"); 1005 goto error; 1006 } 1007 1008 reg_debug("Target CC: %.2s, Restore to Previous CC: %.2s", 1009 regulat_info->alpha2, soc_reg->cur_country); 1010 1011 return status; 1012 1013 error: 1014 reg_reset_ctry_pending_hints(soc_reg); 1015 1016 return status; 1017 } 1018 1019 bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg, 1020 struct cur_regulatory_info *regulat_info) 1021 { 1022 uint8_t phy_num; 1023 1024 if (!soc_reg->offload_enabled) 1025 return false; 1026 1027 if (soc_reg->cc_src == SOURCE_UNKNOWN) 1028 return false; 1029 1030 phy_num = regulat_info->phy_id; 1031 if (soc_reg->new_user_ctry_pending[phy_num] || 1032 soc_reg->new_init_ctry_pending[phy_num] || 1033 soc_reg->new_11d_ctry_pending[phy_num] || 1034 soc_reg->world_country_pending[phy_num]) 1035 return false; 1036 1037 return true; 1038 } 1039