1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * 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: target_if_reg.c 22 * This file contains regulatory target interfaces. 23 */ 24 25 #include <wmi_unified_api.h> 26 #include <reg_services_public_struct.h> 27 #include <wlan_reg_tgt_api.h> 28 #include <target_if.h> 29 #include <target_if_reg.h> 30 #include <wmi_unified_reg_api.h> 31 #include <qdf_platform.h> 32 #include <target_if_reg_11d.h> 33 #include <target_if_reg_lte.h> 34 #include <wlan_reg_ucfg_api.h> 35 36 /** 37 * get_chan_list_cc_event_id() - Get chan_list_cc event i 38 * 39 * Return: Event id 40 */ 41 static inline uint32_t get_chan_list_cc_event_id(void) 42 { 43 return wmi_reg_chan_list_cc_event_id; 44 } 45 46 /** 47 * tgt_if_regulatory_is_regdb_offloaded() - Check if regdb is offloaded 48 * @psoc: Pointer to psoc 49 * 50 * Return: true if regdb if offloaded, else false 51 */ 52 static bool tgt_if_regulatory_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc) 53 { 54 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 55 56 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 57 58 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 59 if (!reg_rx_ops) { 60 target_if_err("reg_rx_ops is NULL"); 61 return false; 62 } 63 64 if (!wmi_handle) 65 return false; 66 67 if (reg_rx_ops->reg_ignore_fw_reg_offload_ind && 68 reg_rx_ops->reg_ignore_fw_reg_offload_ind(psoc)) { 69 target_if_debug("User disabled regulatory offload from ini"); 70 return 0; 71 } 72 73 return wmi_service_enabled(wmi_handle, wmi_service_regulatory_db); 74 } 75 76 /** 77 * tgt_if_regulatory_is_6ghz_supported() - Check if 6ghz is supported 78 * @psoc: Pointer to psoc 79 * 80 * Return: true if regdb if offloaded, else false 81 */ 82 static bool tgt_if_regulatory_is_6ghz_supported(struct wlan_objmgr_psoc *psoc) 83 { 84 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 85 86 if (!wmi_handle) 87 return false; 88 89 return wmi_service_enabled(wmi_handle, wmi_service_6ghz_support); 90 } 91 92 /** 93 * tgt_if_regulatory_is_5dot9_ghz_supported() - Check if 5.9ghz is supported 94 * @psoc: Pointer to psoc 95 * 96 * Return: true if regdb if offloaded, else false 97 */ 98 static bool 99 tgt_if_regulatory_is_5dot9_ghz_supported(struct wlan_objmgr_psoc *psoc) 100 { 101 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 102 103 if (!wmi_handle) 104 return false; 105 106 return wmi_service_enabled(wmi_handle, wmi_service_5dot9_ghz_support); 107 } 108 109 /** 110 * tgt_if_regulatory_is_there_serv_ready_extn() - Check for service ready 111 * extension 112 * @psoc: Pointer to psoc object 113 * 114 * Return: true if service ready extension is present, else false. 115 */ 116 static bool tgt_if_regulatory_is_there_serv_ready_extn( 117 struct wlan_objmgr_psoc *psoc) 118 { 119 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 120 121 if (!wmi_handle) 122 return false; 123 124 return wmi_service_enabled(wmi_handle, wmi_service_ext_msg); 125 } 126 127 /** 128 * target_if_regulatory_get_rx_ops() - Get regdb rx ops 129 * @psoc: Pointer to psoc object 130 * 131 * Return: Reg rx_ops 132 */ 133 struct wlan_lmac_if_reg_rx_ops * 134 target_if_regulatory_get_rx_ops(struct wlan_objmgr_psoc *psoc) 135 { 136 struct wlan_lmac_if_rx_ops *rx_ops; 137 138 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 139 if (!rx_ops) { 140 target_if_err("rx_ops is NULL"); 141 return NULL; 142 } 143 144 return &rx_ops->reg_rx_ops; 145 } 146 147 struct wlan_lmac_if_reg_tx_ops * 148 target_if_regulatory_get_tx_ops(struct wlan_objmgr_psoc *psoc) 149 { 150 struct wlan_lmac_if_tx_ops *tx_ops; 151 152 tx_ops = wlan_psoc_get_lmac_if_txops(psoc); 153 if (!tx_ops) { 154 target_if_err("tx_ops is NULL"); 155 return NULL; 156 } 157 158 return &tx_ops->reg_ops; 159 } 160 161 QDF_STATUS target_if_reg_set_offloaded_info(struct wlan_objmgr_psoc *psoc) 162 { 163 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 164 165 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 166 if (!reg_rx_ops) { 167 target_if_err("reg_rx_ops is NULL"); 168 return QDF_STATUS_E_FAILURE; 169 } 170 171 if (reg_rx_ops->reg_set_regdb_offloaded) 172 reg_rx_ops->reg_set_regdb_offloaded( 173 psoc, 174 tgt_if_regulatory_is_regdb_offloaded(psoc)); 175 176 if (reg_rx_ops->reg_set_11d_offloaded) 177 reg_rx_ops->reg_set_11d_offloaded( 178 psoc, tgt_if_regulatory_is_11d_offloaded(psoc)); 179 180 return QDF_STATUS_SUCCESS; 181 } 182 183 QDF_STATUS target_if_reg_set_6ghz_info(struct wlan_objmgr_psoc *psoc) 184 { 185 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 186 187 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 188 if (!reg_rx_ops) { 189 target_if_err("reg_rx_ops is NULL"); 190 return QDF_STATUS_E_FAILURE; 191 } 192 193 if (reg_rx_ops->reg_set_6ghz_supported) 194 reg_rx_ops->reg_set_6ghz_supported( 195 psoc, 196 tgt_if_regulatory_is_6ghz_supported(psoc)); 197 198 return QDF_STATUS_SUCCESS; 199 } 200 201 QDF_STATUS target_if_reg_set_5dot9_ghz_info(struct wlan_objmgr_psoc *psoc) 202 { 203 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 204 205 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 206 if (!reg_rx_ops) { 207 target_if_err("reg_rx_ops is NULL"); 208 return QDF_STATUS_E_FAILURE; 209 } 210 211 if (reg_rx_ops->reg_set_5dot9_ghz_supported) 212 reg_rx_ops->reg_set_5dot9_ghz_supported( 213 psoc, 214 tgt_if_regulatory_is_5dot9_ghz_supported(psoc)); 215 216 return QDF_STATUS_SUCCESS; 217 } 218 219 bool 220 target_if_reg_is_reg_cc_ext_event_host_supported(struct wlan_objmgr_psoc *psoc) 221 { 222 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; 223 bool reg_ext_cc_supp = false; 224 225 reg_tx_ops = target_if_regulatory_get_tx_ops(psoc); 226 if (!reg_tx_ops) { 227 target_if_err("reg_tx_ops is NULL"); 228 return reg_ext_cc_supp; 229 } 230 231 if (reg_tx_ops->register_master_ext_handler) 232 reg_ext_cc_supp = true; 233 234 return reg_ext_cc_supp; 235 } 236 237 /** 238 * tgt_reg_chan_list_update_handler() - Channel list update handler 239 * @handle: scn handle 240 * @event_buf: pointer to event buffer 241 * @len: buffer length 242 * 243 * Return: 0 on success 244 */ 245 static int tgt_reg_chan_list_update_handler(ol_scn_t handle, uint8_t *event_buf, 246 uint32_t len) 247 { 248 struct wlan_objmgr_psoc *psoc; 249 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 250 struct cur_regulatory_info *reg_info; 251 QDF_STATUS status; 252 struct wmi_unified *wmi_handle; 253 int ret_val = 0; 254 255 TARGET_IF_ENTER(); 256 257 psoc = target_if_get_psoc_from_scn_hdl(handle); 258 if (!psoc) { 259 target_if_err("psoc ptr is NULL"); 260 return -EINVAL; 261 } 262 263 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 264 if (!reg_rx_ops) { 265 target_if_err("reg_rx_ops is NULL"); 266 return -EINVAL; 267 } 268 269 if (!reg_rx_ops->master_list_handler) { 270 target_if_err("master_list_handler is NULL"); 271 return -EINVAL; 272 } 273 274 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 275 if (!wmi_handle) { 276 target_if_err("invalid wmi handle"); 277 return -EINVAL; 278 } 279 280 reg_info = qdf_mem_malloc(sizeof(*reg_info)); 281 if (!reg_info) 282 return -ENOMEM; 283 284 if (wmi_extract_reg_chan_list_update_event(wmi_handle, 285 event_buf, reg_info, len) 286 != QDF_STATUS_SUCCESS) { 287 target_if_err("Extraction of channel list event failed"); 288 ret_val = -EFAULT; 289 goto clean; 290 } 291 292 if (reg_info->phy_id >= PSOC_MAX_PHY_REG_CAP) { 293 target_if_err_rl("phy_id %d is out of bounds", 294 reg_info->phy_id); 295 ret_val = -EFAULT; 296 goto clean; 297 } 298 299 reg_info->psoc = psoc; 300 301 status = reg_rx_ops->master_list_handler(reg_info); 302 if (status != QDF_STATUS_SUCCESS) { 303 target_if_err("Failed to process master channel list handler"); 304 ret_val = -EFAULT; 305 } 306 307 clean: 308 qdf_mem_free(reg_info->reg_rules_2g_ptr); 309 qdf_mem_free(reg_info->reg_rules_5g_ptr); 310 qdf_mem_free(reg_info); 311 312 TARGET_IF_EXIT(); 313 314 return ret_val; 315 } 316 317 /** 318 * tgt_if_regulatory_register_master_list_handler() - Register master channel 319 * list 320 * @psoc: Pointer to psoc 321 * @arg: Pointer to argument list 322 * 323 * Return: QDF_STATUS 324 */ 325 static QDF_STATUS tgt_if_regulatory_register_master_list_handler( 326 struct wlan_objmgr_psoc *psoc, void *arg) 327 { 328 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 329 330 if (!wmi_handle) 331 return QDF_STATUS_E_FAILURE; 332 333 return wmi_unified_register_event_handler( 334 wmi_handle, wmi_reg_chan_list_cc_event_id, 335 tgt_reg_chan_list_update_handler, WMI_RX_WORK_CTX); 336 } 337 338 /** 339 * tgt_if_regulatory_unregister_master_list_handler() - Unregister master 340 * channel list 341 * @psoc: Pointer to psoc 342 * @arg: Pointer to argument list 343 * 344 * Return: QDF_STATUS 345 */ 346 static QDF_STATUS tgt_if_regulatory_unregister_master_list_handler( 347 struct wlan_objmgr_psoc *psoc, void *arg) 348 { 349 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 350 351 if (!wmi_handle) 352 return QDF_STATUS_E_FAILURE; 353 354 return wmi_unified_unregister_event_handler( 355 wmi_handle, wmi_reg_chan_list_cc_event_id); 356 } 357 358 #ifdef CONFIG_BAND_6GHZ 359 /** 360 * tgt_reg_chan_list_ext_update_handler() - Extended channel list update handler 361 * @handle: scn handle 362 * @event_buf: pointer to event buffer 363 * @len: buffer length 364 * 365 * Return: 0 on success 366 */ 367 static int tgt_reg_chan_list_ext_update_handler(ol_scn_t handle, 368 uint8_t *event_buf, 369 uint32_t len) 370 { 371 struct wlan_objmgr_psoc *psoc; 372 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 373 struct cur_regulatory_info *reg_info; 374 QDF_STATUS status; 375 struct wmi_unified *wmi_handle; 376 int ret_val = 0; 377 uint32_t i; 378 379 TARGET_IF_ENTER(); 380 381 psoc = target_if_get_psoc_from_scn_hdl(handle); 382 if (!psoc) { 383 target_if_err("psoc ptr is NULL"); 384 return -EINVAL; 385 } 386 387 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 388 if (!reg_rx_ops) { 389 target_if_err("reg_rx_ops is NULL"); 390 return -EINVAL; 391 } 392 393 if (!reg_rx_ops->master_list_ext_handler) { 394 target_if_err("master_list_ext_handler is NULL"); 395 return -EINVAL; 396 } 397 398 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 399 if (!wmi_handle) { 400 target_if_err("invalid wmi handle"); 401 return -EINVAL; 402 } 403 404 reg_info = qdf_mem_malloc(sizeof(*reg_info)); 405 if (!reg_info) 406 return -ENOMEM; 407 408 status = wmi_extract_reg_chan_list_ext_update_event(wmi_handle, 409 event_buf, 410 reg_info, len); 411 if (!QDF_IS_STATUS_SUCCESS(status)) { 412 target_if_err("Extraction of ext channel list event failed"); 413 ret_val = -EFAULT; 414 goto clean; 415 } 416 417 if (reg_info->phy_id >= PSOC_MAX_PHY_REG_CAP) { 418 target_if_err_rl("phy_id %d is out of bounds", 419 reg_info->phy_id); 420 ret_val = -EFAULT; 421 goto clean; 422 } 423 424 reg_info->psoc = psoc; 425 426 status = reg_rx_ops->master_list_ext_handler(reg_info); 427 if (!QDF_IS_STATUS_SUCCESS(status)) { 428 target_if_err("Failed to process master ext channel list handler"); 429 ret_val = -EFAULT; 430 } 431 432 clean: 433 qdf_mem_free(reg_info->reg_rules_2g_ptr); 434 qdf_mem_free(reg_info->reg_rules_5g_ptr); 435 436 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 437 qdf_mem_free(reg_info->reg_rules_6g_ap_ptr[i]); 438 qdf_mem_free(reg_info-> 439 reg_rules_6g_client_ptr[i][REG_DEFAULT_CLIENT]); 440 qdf_mem_free(reg_info-> 441 reg_rules_6g_client_ptr[i][REG_SUBORDINATE_CLIENT]); 442 } 443 444 qdf_mem_free(reg_info); 445 446 TARGET_IF_EXIT(); 447 448 return ret_val; 449 } 450 451 /** 452 * tgt_if_regulatory_register_master_list_ext_handler() - Register extended 453 * master channel list event handler 454 * @psoc: Pointer to psoc 455 * @arg: Pointer to argument list 456 * 457 * Return: QDF_STATUS 458 */ 459 static QDF_STATUS tgt_if_regulatory_register_master_list_ext_handler( 460 struct wlan_objmgr_psoc *psoc, void *arg) 461 { 462 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 463 464 if (!wmi_handle) 465 return QDF_STATUS_E_FAILURE; 466 467 return wmi_unified_register_event_handler( 468 wmi_handle, wmi_reg_chan_list_cc_ext_event_id, 469 tgt_reg_chan_list_ext_update_handler, WMI_RX_WORK_CTX); 470 } 471 472 /** 473 * tgt_if_regulatory_unregister_master_list_ext_handler() - Unregister extended 474 * master channel list event handler 475 * @psoc: Pointer to psoc 476 * @arg: Pointer to argument list 477 * 478 * Return: QDF_STATUS 479 */ 480 static QDF_STATUS tgt_if_regulatory_unregister_master_list_ext_handler( 481 struct wlan_objmgr_psoc *psoc, void *arg) 482 { 483 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 484 485 if (!wmi_handle) 486 return QDF_STATUS_E_FAILURE; 487 488 return wmi_unified_unregister_event_handler( 489 wmi_handle, wmi_reg_chan_list_cc_ext_event_id); 490 } 491 492 #ifdef CONFIG_AFC_SUPPORT 493 /** 494 * tgt_afc_event_handler() - Handler for AFC Event 495 * @handle: scn handle 496 * @event_buf: pointer to event buffer 497 * @len: buffer length 498 * 499 * Return: 0 on success 500 */ 501 static int 502 tgt_afc_event_handler(ol_scn_t handle, uint8_t *event_buf, uint32_t len) 503 { 504 struct wlan_objmgr_psoc *psoc; 505 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 506 struct afc_regulatory_info *afc_info; 507 QDF_STATUS status; 508 struct wmi_unified *wmi_handle; 509 int ret_val = 0; 510 511 TARGET_IF_ENTER(); 512 513 psoc = target_if_get_psoc_from_scn_hdl(handle); 514 if (!psoc) { 515 target_if_err("psoc ptr is NULL"); 516 return -EINVAL; 517 } 518 519 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 520 if (!reg_rx_ops) { 521 target_if_err("reg_rx_ops is NULL"); 522 return -EINVAL; 523 } 524 525 if (!reg_rx_ops->afc_event_handler) { 526 target_if_err("afc_event_handler is NULL"); 527 return -EINVAL; 528 } 529 530 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 531 if (!wmi_handle) { 532 target_if_err("invalid wmi handle"); 533 return -EINVAL; 534 } 535 536 afc_info = qdf_mem_malloc(sizeof(*afc_info)); 537 if (!afc_info) 538 return -ENOMEM; 539 540 status = wmi_extract_afc_event(wmi_handle, event_buf, afc_info, len); 541 if (!QDF_IS_STATUS_SUCCESS(status)) { 542 target_if_err("Extraction of AFC event failed"); 543 ret_val = -EFAULT; 544 goto clean; 545 } 546 547 if (afc_info->phy_id >= PSOC_MAX_PHY_REG_CAP) { 548 target_if_err_rl("phy_id %d is out of bounds", 549 afc_info->phy_id); 550 ret_val = -EFAULT; 551 goto clean; 552 } 553 554 afc_info->psoc = psoc; 555 556 status = reg_rx_ops->afc_event_handler(afc_info); 557 if (!QDF_IS_STATUS_SUCCESS(status)) { 558 target_if_err("Failed to process AFC event handler"); 559 ret_val = -EFAULT; 560 goto clean; 561 } 562 563 clean: 564 qdf_mem_free(afc_info); 565 TARGET_IF_EXIT(); 566 567 return ret_val; 568 } 569 570 /** 571 * tgt_if_regulatory_register_afc_event_handler() - Register AFC event 572 * handler 573 * @psoc: Pointer to psoc 574 * @arg: Pointer to argument list 575 * 576 * Return: QDF_STATUS 577 */ 578 static QDF_STATUS tgt_if_regulatory_register_afc_event_handler( 579 struct wlan_objmgr_psoc *psoc, void *arg) 580 { 581 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 582 583 if (!wmi_handle) 584 return QDF_STATUS_E_FAILURE; 585 586 return wmi_unified_register_event_handler( 587 wmi_handle, wmi_afc_event_id, 588 tgt_afc_event_handler, WMI_RX_WORK_CTX); 589 } 590 591 /** 592 * tgt_if_regulatory_unregister_afc_event_handler() - Unregister AFC event 593 * handler 594 * @psoc: Pointer to psoc 595 * @arg: Pointer to argument list 596 * 597 * Return: QDF_STATUS 598 */ 599 static QDF_STATUS 600 tgt_if_regulatory_unregister_afc_event_handler(struct wlan_objmgr_psoc *psoc, 601 void *arg) 602 { 603 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 604 605 if (!wmi_handle) 606 return QDF_STATUS_E_FAILURE; 607 608 return wmi_unified_unregister_event_handler( 609 wmi_handle, wmi_afc_event_id); 610 } 611 #endif 612 #endif 613 614 /** 615 * tgt_if_regulatory_set_country_code() - Set country code 616 * @psoc: Pointer to psoc 617 * @arg: Pointer to argument list 618 * 619 * Return: QDF_STATUS 620 */ 621 static QDF_STATUS tgt_if_regulatory_set_country_code( 622 struct wlan_objmgr_psoc *psoc, void *arg) 623 { 624 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 625 626 if (!wmi_handle) 627 return QDF_STATUS_E_FAILURE; 628 629 return wmi_unified_set_country_cmd_send(wmi_handle, arg); 630 } 631 632 /** 633 * tgt_if_regulatory_set_user_country_code() - Set user country code 634 * @psoc: Pointer to psoc 635 * @pdev_id: Pdev id 636 * @rd: Pointer to regdomain structure 637 * 638 * Return: QDF_STATUS 639 */ 640 static QDF_STATUS tgt_if_regulatory_set_user_country_code( 641 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, struct cc_regdmn_s *rd) 642 { 643 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 644 645 if (!wmi_handle) 646 return QDF_STATUS_E_FAILURE; 647 648 if (wmi_unified_set_user_country_code_cmd_send( 649 wmi_handle, pdev_id, rd) != QDF_STATUS_SUCCESS 650 ) { 651 target_if_err("Set user country code failed"); 652 return QDF_STATUS_E_FAILURE; 653 } 654 655 return QDF_STATUS_SUCCESS; 656 } 657 658 QDF_STATUS tgt_if_regulatory_modify_freq_range(struct wlan_objmgr_psoc *psoc) 659 { 660 struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap; 661 662 reg_cap = ucfg_reg_get_hal_reg_cap(psoc); 663 if (!reg_cap) { 664 target_if_err("reg cap is NULL"); 665 return QDF_STATUS_E_FAILURE; 666 } 667 668 if (!(reg_cap->wireless_modes & WMI_HOST_REGDMN_MODE_11A)) { 669 reg_cap->low_5ghz_chan = 0; 670 reg_cap->high_5ghz_chan = 0; 671 } 672 673 if (!(reg_cap->wireless_modes & 674 (WMI_HOST_REGDMN_MODE_11B | WMI_HOST_REGDMN_MODE_PUREG))) { 675 reg_cap->low_2ghz_chan = 0; 676 reg_cap->high_2ghz_chan = 0; 677 } 678 679 target_if_debug("phy_id = %d - low_2ghz_chan = %d high_2ghz_chan = %d low_5ghz_chan = %d high_5ghz_chan = %d", 680 reg_cap->phy_id, 681 reg_cap->low_2ghz_chan, 682 reg_cap->high_2ghz_chan, 683 reg_cap->low_5ghz_chan, 684 reg_cap->high_5ghz_chan); 685 686 return QDF_STATUS_SUCCESS; 687 } 688 689 #ifdef CONFIG_REG_CLIENT 690 /** 691 * tgt_if_regulatory_send_ctl_info() - Send CTL info to firmware 692 * @psoc: Pointer to psoc 693 * @params: Pointer to reg control params 694 * 695 * Return: QDF_STATUS 696 */ 697 static QDF_STATUS 698 tgt_if_regulatory_send_ctl_info(struct wlan_objmgr_psoc *psoc, 699 struct reg_ctl_params *params) 700 { 701 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 702 703 if (!wmi_handle) 704 return QDF_STATUS_E_FAILURE; 705 706 return wmi_unified_send_regdomain_info_to_fw_cmd(wmi_handle, 707 params->regd, 708 params->regd_2g, 709 params->regd_5g, 710 params->ctl_2g, 711 params->ctl_5g); 712 } 713 #else 714 static QDF_STATUS 715 tgt_if_regulatory_send_ctl_info(struct wlan_objmgr_psoc *psoc, 716 struct reg_ctl_params *params) 717 { 718 return QDF_STATUS_SUCCESS; 719 } 720 #endif 721 722 /** 723 * tgt_if_regulatory_get_phy_id_from_pdev_id() - Get phy_id from pdev_id 724 * @psoc: Pointer to psoc 725 * @pdev_id: Pdev id 726 * @phy_id: phy_id 727 * 728 * Return: QDF_STATUS 729 */ 730 static QDF_STATUS tgt_if_regulatory_get_phy_id_from_pdev_id( 731 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *phy_id) 732 { 733 struct target_psoc_info *tgt_if_handle = psoc->tgt_if_handle; 734 uint8_t ret; 735 736 if (pdev_id >= WLAN_UMAC_MAX_PDEVS) { 737 target_if_err("pdev_id is greater than WLAN_UMAC_MAX_PDEVS"); 738 return QDF_STATUS_E_FAILURE; 739 } 740 741 /* By default pdev_id and phy_id have one to one mapping */ 742 *phy_id = pdev_id; 743 744 if (!(tgt_if_handle && 745 tgt_if_handle->info.is_pdevid_to_phyid_map)) 746 return QDF_STATUS_SUCCESS; 747 748 ret = tgt_if_handle->info.pdev_id_to_phy_id_map[pdev_id]; 749 750 if (ret < PSOC_MAX_PHY_REG_CAP) { 751 *phy_id = ret; 752 } else { 753 target_if_err("phy_id is greater than PSOC_MAX_PHY_REG_CAP"); 754 return QDF_STATUS_E_FAILURE; 755 } 756 757 return QDF_STATUS_SUCCESS; 758 } 759 760 /** 761 * tgt_if_regulatory_get_pdev_id_from_phy_id() - Get pdev_id for phy_id 762 * @psoc: Pointer to psoc 763 * @phy_id: Phy id 764 * @pdev_id: Pdev id 765 * 766 * Return: QDF_STATUS 767 */ 768 static QDF_STATUS tgt_if_regulatory_get_pdev_id_from_phy_id( 769 struct wlan_objmgr_psoc *psoc, uint8_t phy_id, uint8_t *pdev_id) 770 { 771 struct target_psoc_info *tgt_if_handle = psoc->tgt_if_handle; 772 uint8_t i; 773 774 if (phy_id >= PSOC_MAX_PHY_REG_CAP) { 775 target_if_err("phy_id is greater than PSOC_MAX_PHY_REG_CAP"); 776 return QDF_STATUS_E_FAILURE; 777 } 778 779 /* By default pdev_id and phy_id have one to one mapping */ 780 *pdev_id = phy_id; 781 782 if (!(tgt_if_handle && 783 tgt_if_handle->info.is_pdevid_to_phyid_map)) 784 return QDF_STATUS_SUCCESS; 785 786 for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) { 787 if (tgt_if_handle->info.pdev_id_to_phy_id_map[i] == phy_id) 788 break; 789 } 790 791 if (i < WLAN_UMAC_MAX_PDEVS) { 792 *pdev_id = i; 793 } else { 794 target_if_err("pdev_id is greater than WLAN_UMAC_MAX_PDEVS"); 795 return QDF_STATUS_E_FAILURE; 796 } 797 798 return QDF_STATUS_SUCCESS; 799 } 800 801 #ifdef CONFIG_BAND_6GHZ 802 static void target_if_register_master_ext_handler( 803 struct wlan_lmac_if_reg_tx_ops *reg_ops) 804 { 805 reg_ops->register_master_ext_handler = 806 tgt_if_regulatory_register_master_list_ext_handler; 807 808 reg_ops->unregister_master_ext_handler = 809 tgt_if_regulatory_unregister_master_list_ext_handler; 810 } 811 812 #ifdef CONFIG_AFC_SUPPORT 813 static void target_if_register_afc_event_handler( 814 struct wlan_lmac_if_reg_tx_ops *reg_ops) 815 { 816 reg_ops->register_afc_event_handler = 817 tgt_if_regulatory_register_afc_event_handler; 818 819 reg_ops->unregister_afc_event_handler = 820 tgt_if_regulatory_unregister_afc_event_handler; 821 } 822 823 static void target_if_register_acs_trigger_for_afc 824 (struct wlan_lmac_if_reg_tx_ops *reg_ops) 825 { 826 reg_ops->trigger_acs_for_afc = NULL; 827 } 828 #else 829 static void target_if_register_afc_event_handler( 830 struct wlan_lmac_if_reg_tx_ops *reg_ops) 831 { 832 } 833 834 static void target_if_register_acs_trigger_for_afc 835 (struct wlan_lmac_if_reg_tx_ops *reg_ops) 836 { 837 } 838 #endif 839 #else 840 static inline void 841 target_if_register_master_ext_handler(struct wlan_lmac_if_reg_tx_ops *reg_ops) 842 { 843 } 844 845 static void target_if_register_afc_event_handler( 846 struct wlan_lmac_if_reg_tx_ops *reg_ops) 847 { 848 } 849 850 static void target_if_register_acs_trigger_for_afc 851 (struct wlan_lmac_if_reg_tx_ops *reg_ops) 852 { 853 } 854 #endif 855 856 static QDF_STATUS 857 tgt_if_regulatory_set_tpc_power(struct wlan_objmgr_psoc *psoc, 858 uint8_t vdev_id, 859 struct reg_tpc_power_info *param) 860 { 861 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 862 863 if (!wmi_handle) 864 return QDF_STATUS_E_FAILURE; 865 866 return wmi_unified_send_set_tpc_power_cmd(wmi_handle, vdev_id, param); 867 } 868 869 #ifdef CONFIG_AFC_SUPPORT 870 /** 871 * tgt_if_regulatory_send_afc_cmd() - Send AFC command to the FW 872 * 873 * @psoc: Pointer to psoc 874 * @pdev_id: Pdev id 875 * @param: Pointer to hold AFC indication. 876 * 877 * Return: QDF_STATUS_SUCCESS if WMI_AFC_CMD is sent, else QDF_STATUS_E_FAILURE 878 */ 879 static QDF_STATUS 880 tgt_if_regulatory_send_afc_cmd(struct wlan_objmgr_psoc *psoc, 881 uint8_t pdev_id, 882 struct reg_afc_resp_rx_ind_info *param) 883 { 884 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 885 886 if (!wmi_handle) 887 return QDF_STATUS_E_FAILURE; 888 889 return wmi_unified_send_afc_cmd(wmi_handle, pdev_id, param); 890 } 891 892 static void 893 tgt_if_register_afc_callback(struct wlan_lmac_if_reg_tx_ops *reg_ops) 894 { 895 reg_ops->send_afc_ind = tgt_if_regulatory_send_afc_cmd; 896 } 897 #else 898 static void 899 tgt_if_register_afc_callback(struct wlan_lmac_if_reg_tx_ops *reg_ops) 900 { 901 } 902 #endif 903 904 /** 905 * tgt_if_regulatory_is_ext_tpc_supported() - Check if FW supports new 906 * WMI command for TPC power 907 * 908 * @psoc: Pointer to psoc 909 * 910 * Return: true if FW supports new WMI command for TPC, else false 911 */ 912 static bool 913 tgt_if_regulatory_is_ext_tpc_supported(struct wlan_objmgr_psoc *psoc) 914 { 915 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 916 917 if (!wmi_handle) 918 return false; 919 920 return wmi_service_enabled(wmi_handle, 921 wmi_service_ext_tpc_reg_support); 922 } 923 924 QDF_STATUS target_if_regulatory_set_ext_tpc(struct wlan_objmgr_psoc *psoc) 925 { 926 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 927 928 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 929 if (!reg_rx_ops) { 930 target_if_err("reg_rx_ops is NULL"); 931 return QDF_STATUS_E_FAILURE; 932 } 933 934 if (reg_rx_ops->reg_set_ext_tpc_supported) 935 reg_rx_ops->reg_set_ext_tpc_supported( 936 psoc, 937 tgt_if_regulatory_is_ext_tpc_supported(psoc)); 938 939 return QDF_STATUS_SUCCESS; 940 } 941 942 #if defined(CONFIG_BAND_6GHZ) 943 /** 944 * tgt_if_regulatory_is_lower_6g_edge_ch_supp() - Check if lower 6ghz 945 * edge channel (5935MHz) is supported 946 * @psoc: Pointer to psoc 947 * 948 * Return: true if channel is supported, else false 949 */ 950 static bool 951 tgt_if_regulatory_is_lower_6g_edge_ch_supp(struct wlan_objmgr_psoc *psoc) 952 { 953 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 954 955 if (!wmi_handle) 956 return false; 957 958 return wmi_service_enabled(wmi_handle, 959 wmi_service_lower_6g_edge_ch_supp); 960 } 961 962 /** 963 * tgt_if_regulatory_is_upper_6g_edge_ch_disabled() - Check if upper 964 * 6ghz edge channel (7115MHz) is disabled 965 * @psoc: Pointer to psoc 966 * 967 * Return: true if channel is disabled, else false 968 */ 969 static bool 970 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(struct wlan_objmgr_psoc *psoc) 971 { 972 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 973 974 if (!wmi_handle) 975 return false; 976 977 return wmi_service_enabled(wmi_handle, 978 wmi_service_disable_upper_6g_edge_ch_supp); 979 } 980 981 QDF_STATUS 982 target_if_reg_set_lower_6g_edge_ch_info(struct wlan_objmgr_psoc *psoc) 983 { 984 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 985 986 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 987 if (!reg_rx_ops) { 988 target_if_err("reg_rx_ops is NULL"); 989 return QDF_STATUS_E_FAILURE; 990 } 991 992 if (reg_rx_ops->reg_set_lower_6g_edge_ch_supp) 993 reg_rx_ops->reg_set_lower_6g_edge_ch_supp( 994 psoc, 995 tgt_if_regulatory_is_lower_6g_edge_ch_supp(psoc)); 996 997 return QDF_STATUS_SUCCESS; 998 } 999 1000 QDF_STATUS 1001 target_if_reg_set_disable_upper_6g_edge_ch_info(struct wlan_objmgr_psoc *psoc) 1002 { 1003 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 1004 1005 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 1006 if (!reg_rx_ops) { 1007 target_if_err("reg_rx_ops is NULL"); 1008 return QDF_STATUS_E_FAILURE; 1009 } 1010 1011 if (reg_rx_ops->reg_set_disable_upper_6g_edge_ch_supp) 1012 reg_rx_ops->reg_set_disable_upper_6g_edge_ch_supp( 1013 psoc, 1014 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(psoc)); 1015 1016 return QDF_STATUS_SUCCESS; 1017 } 1018 #else 1019 static inline bool 1020 tgt_if_regulatory_is_lower_6g_edge_ch_supp(struct wlan_objmgr_psoc *psoc) 1021 { 1022 return false; 1023 } 1024 1025 static inline bool 1026 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(struct wlan_objmgr_psoc *psoc) 1027 { 1028 return false; 1029 } 1030 #endif 1031 1032 QDF_STATUS target_if_register_regulatory_tx_ops( 1033 struct wlan_lmac_if_tx_ops *tx_ops) 1034 { 1035 struct wlan_lmac_if_reg_tx_ops *reg_ops = &tx_ops->reg_ops; 1036 1037 reg_ops->register_master_handler = 1038 tgt_if_regulatory_register_master_list_handler; 1039 1040 reg_ops->unregister_master_handler = 1041 tgt_if_regulatory_unregister_master_list_handler; 1042 1043 target_if_register_master_ext_handler(reg_ops); 1044 1045 target_if_register_afc_event_handler(reg_ops); 1046 1047 reg_ops->set_country_code = tgt_if_regulatory_set_country_code; 1048 1049 reg_ops->fill_umac_legacy_chanlist = NULL; 1050 1051 reg_ops->set_country_failed = NULL; 1052 1053 target_if_register_acs_trigger_for_afc(reg_ops); 1054 1055 reg_ops->register_11d_new_cc_handler = 1056 tgt_if_regulatory_register_11d_new_cc_handler; 1057 1058 reg_ops->unregister_11d_new_cc_handler = 1059 tgt_if_regulatory_unregister_11d_new_cc_handler; 1060 1061 reg_ops->start_11d_scan = tgt_if_regulatory_start_11d_scan; 1062 1063 reg_ops->stop_11d_scan = tgt_if_regulatory_stop_11d_scan; 1064 1065 reg_ops->is_there_serv_ready_extn = 1066 tgt_if_regulatory_is_there_serv_ready_extn; 1067 1068 reg_ops->set_user_country_code = 1069 tgt_if_regulatory_set_user_country_code; 1070 1071 reg_ops->register_ch_avoid_event_handler = 1072 tgt_if_regulatory_register_ch_avoid_event_handler; 1073 1074 reg_ops->unregister_ch_avoid_event_handler = 1075 tgt_if_regulatory_unregister_ch_avoid_event_handler; 1076 1077 reg_ops->send_ctl_info = tgt_if_regulatory_send_ctl_info; 1078 1079 reg_ops->get_phy_id_from_pdev_id = 1080 tgt_if_regulatory_get_phy_id_from_pdev_id; 1081 1082 reg_ops->get_pdev_id_from_phy_id = 1083 tgt_if_regulatory_get_pdev_id_from_phy_id; 1084 1085 reg_ops->set_tpc_power = tgt_if_regulatory_set_tpc_power; 1086 1087 tgt_if_register_afc_callback(reg_ops); 1088 1089 return QDF_STATUS_SUCCESS; 1090 } 1091