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