1 /* 2 * Copyright (c) 2017-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 * DOC: service_ready_util.c 20 * 21 * Public APIs implementation source file for accessing (ext)service ready 22 * data from psoc object 23 */ 24 #include "service_ready_util.h" 25 #include <wlan_reg_ucfg_api.h> 26 #include <target_type.h> 27 #include <qdf_module.h> 28 29 QDF_STATUS init_deinit_chainmask_table_alloc( 30 struct wlan_psoc_host_service_ext_param *ser_ext_par) 31 { 32 int i; 33 uint32_t alloc_size; 34 QDF_STATUS status = QDF_STATUS_SUCCESS; 35 36 if (ser_ext_par->num_chainmask_tables == 0) 37 return QDF_STATUS_E_NOSUPPORT; 38 39 for (i = 0; i < ser_ext_par->num_chainmask_tables; i++) { 40 if (ser_ext_par->chainmask_table[i].num_valid_chainmasks > 41 (UINT_MAX / sizeof( 42 struct wlan_psoc_host_chainmask_capabilities))) { 43 target_if_err("invalid valid chanmask num %d", 44 ser_ext_par->chainmask_table[i]. 45 num_valid_chainmasks); 46 status = QDF_STATUS_E_FAILURE; 47 break; 48 } 49 alloc_size = 50 (sizeof(struct wlan_psoc_host_chainmask_capabilities) * 51 ser_ext_par->chainmask_table[i].num_valid_chainmasks); 52 53 ser_ext_par->chainmask_table[i].cap_list = 54 qdf_mem_alloc_outline(NULL, alloc_size); 55 if (!ser_ext_par->chainmask_table[i].cap_list) { 56 init_deinit_chainmask_table_free(ser_ext_par); 57 status = QDF_STATUS_E_NOMEM; 58 break; 59 } 60 } 61 62 return status; 63 } 64 65 qdf_export_symbol(init_deinit_chainmask_table_alloc); 66 67 QDF_STATUS init_deinit_chainmask_table_free( 68 struct wlan_psoc_host_service_ext_param *ser_ext_par) 69 { 70 struct wlan_psoc_host_chainmask_table *table; 71 int i; 72 73 for (i = 0; i < ser_ext_par->num_chainmask_tables; i++) { 74 table = &(ser_ext_par->chainmask_table[i]); 75 if (table->cap_list) { 76 qdf_mem_free(table->cap_list); 77 table->cap_list = NULL; 78 } 79 } 80 81 return QDF_STATUS_SUCCESS; 82 } 83 84 qdf_export_symbol(init_deinit_chainmask_table_free); 85 86 int init_deinit_populate_service_bitmap(void *wmi_handle, uint8_t *event, 87 uint32_t *service_bitmap) 88 { 89 QDF_STATUS status; 90 91 status = wmi_save_service_bitmap(wmi_handle, event, service_bitmap); 92 if (QDF_IS_STATUS_ERROR(status)) { 93 target_if_err("failed to parse service bitmap"); 94 return qdf_status_to_os_return(status); 95 } 96 97 return 0; 98 } 99 100 int init_deinit_populate_fw_version_cmd(void *wmi_handle, uint8_t *event) 101 { 102 QDF_STATUS status; 103 104 status = wmi_unified_save_fw_version_cmd(wmi_handle, event); 105 if (QDF_IS_STATUS_ERROR(status)) 106 target_if_err("failed to save fw version"); 107 108 return 0; 109 } 110 111 int init_deinit_populate_target_cap(void *wmi_handle, uint8_t *event, 112 struct wlan_psoc_target_capability_info *cap) 113 { 114 QDF_STATUS status; 115 116 status = wmi_get_target_cap_from_service_ready(wmi_handle, event, cap); 117 if (QDF_IS_STATUS_ERROR(status)) { 118 target_if_err("failed to parse target cap"); 119 return qdf_status_to_os_return(status); 120 } 121 122 return 0; 123 } 124 125 int init_deinit_populate_service_ready_ext_param(void *handle, uint8_t *evt, 126 struct wlan_psoc_host_service_ext_param *param) 127 { 128 QDF_STATUS status; 129 130 status = wmi_extract_service_ready_ext(handle, evt, param); 131 if (QDF_IS_STATUS_ERROR(status)) { 132 target_if_err("failed to parse wmi service ready ext param"); 133 return qdf_status_to_os_return(status); 134 } 135 136 return 0; 137 } 138 139 int init_deinit_populate_chainmask_tables(void *handle, uint8_t *evt, 140 struct wlan_psoc_host_chainmask_table *param) 141 { 142 QDF_STATUS status; 143 144 status = wmi_extract_chainmask_tables(handle, evt, param); 145 if (QDF_IS_STATUS_ERROR(status)) { 146 target_if_err("failed to parse wmi service ready ext param"); 147 return qdf_status_to_os_return(status); 148 } 149 150 return 0; 151 } 152 153 int init_deinit_populate_mac_phy_capability(void *handle, uint8_t *evt, 154 struct wlan_psoc_host_hw_mode_caps *hw_cap, struct tgt_info *info) 155 { 156 QDF_STATUS status; 157 uint32_t hw_mode_id; 158 uint32_t phy_bit_map; 159 uint8_t mac_phy_id; 160 161 hw_mode_id = hw_cap->hw_mode_id; 162 phy_bit_map = hw_cap->phy_id_map; 163 target_if_debug("hw_mode_id %d phy_bit_map 0x%x", 164 hw_mode_id, phy_bit_map); 165 166 mac_phy_id = 0; 167 while (phy_bit_map) { 168 if (info->total_mac_phy_cnt >= PSOC_MAX_MAC_PHY_CAP) { 169 target_if_err("total mac phy exceeds max limit %d", 170 info->total_mac_phy_cnt); 171 return -EINVAL; 172 } 173 174 status = wmi_extract_mac_phy_cap_service_ready_ext(handle, 175 evt, hw_mode_id, mac_phy_id, 176 &(info->mac_phy_cap[info->total_mac_phy_cnt])); 177 if (QDF_IS_STATUS_ERROR(status)) { 178 target_if_err("failed to parse mac phy capability"); 179 return qdf_status_to_os_return(status); 180 } 181 info->mac_phy_cap[info->total_mac_phy_cnt].hw_mode_config_type 182 = hw_cap->hw_mode_config_type; 183 info->total_mac_phy_cnt++; 184 phy_bit_map &= (phy_bit_map - 1); 185 mac_phy_id++; 186 } 187 target_if_debug("total_mac_phy_cnt %d", info->total_mac_phy_cnt); 188 189 return 0; 190 } 191 192 static int get_hw_mode(void *handle, uint8_t *evt, uint8_t hw_idx, 193 struct wlan_psoc_host_hw_mode_caps *cap) 194 { 195 QDF_STATUS status; 196 197 status = wmi_extract_hw_mode_cap_service_ready_ext(handle, evt, 198 hw_idx, cap); 199 if (QDF_IS_STATUS_ERROR(status)) { 200 target_if_err("failed to parse hw mode capability"); 201 return qdf_status_to_os_return(status); 202 } 203 204 return 0; 205 } 206 207 static int get_sar_version(void *handle, uint8_t *evt, 208 struct wlan_psoc_host_service_ext_param *ext_param) 209 { 210 QDF_STATUS status; 211 212 status = wmi_extract_sar_cap_service_ready_ext(handle, evt, ext_param); 213 if (QDF_IS_STATUS_ERROR(status)) { 214 target_if_err("failed to parse sar capability"); 215 return qdf_status_to_os_return(status); 216 } 217 218 return 0; 219 } 220 221 static bool new_hw_mode_preferred(uint32_t current_hw_mode, 222 uint32_t new_hw_mode) 223 { 224 uint8_t hw_mode_id_precedence[WMI_HOST_HW_MODE_MAX + 1] = { 5, 1, 4, 225 3, 0, 2, 226 6 }; 227 228 if (current_hw_mode > WMI_HOST_HW_MODE_MAX || 229 new_hw_mode > WMI_HOST_HW_MODE_MAX) 230 return false; 231 232 /* Above precedence is defined by low to high, lower the value 233 * higher the precedence 234 */ 235 if (hw_mode_id_precedence[current_hw_mode] > 236 hw_mode_id_precedence[new_hw_mode]) 237 return true; 238 239 return false; 240 } 241 242 /** 243 * select_preferred_mode() - Select preferred hw mode based on current mode. 244 * @tgt_hdl: target_psoc_info object 245 * @hw_mode_caps: HW mode caps of new mode id that needs to checked for 246 * selection. 247 * @current_mode: Current mode. 248 * 249 * API to select preferred hw mode based on the current config. 250 * Based on host config for preferred mode, final mode selected as follows- 251 * 1) If preferred_mode == WMI_HOST_HW_MODE_DETECT, Then select mode from FW 252 * supported modes such that it is a super set of all modes FW advertises. 253 * For e.g., If FW supports DBS(2 radio) and DBS_SBS(3 radio)- Choose DBS_SBS 254 * 2) If preferred_mode == WMI_HOST_HW_MODE_MAX, Then do not select any mode 255 * from FW advertised modes. Host needs to maintain all modes supported in FW 256 * and can switch dynamically. 257 * 3) Else, A valid preferred_mode is set, Hence check if this is part of FW 258 * supported modes. If it is found, then use it to bring up the device. 259 * 260 * Return: selected_mode based on the above criteria. 261 */ 262 static uint32_t 263 select_preferred_hw_mode(struct target_psoc_info *tgt_hdl, 264 struct wlan_psoc_host_hw_mode_caps *hw_mode_caps, 265 uint32_t current_mode) 266 { 267 uint32_t preferred_mode, selected_mode = current_mode; 268 struct tgt_info *info; 269 270 info = &tgt_hdl->info; 271 preferred_mode = target_psoc_get_preferred_hw_mode(tgt_hdl); 272 if (preferred_mode == WMI_HOST_HW_MODE_DETECT) { 273 uint32_t new_mode = hw_mode_caps->hw_mode_id; 274 275 /* Choose hw_mode_id based on precedence */ 276 if (new_hw_mode_preferred(selected_mode, new_mode)) { 277 selected_mode = new_mode; 278 qdf_mem_copy(&info->hw_mode_cap, hw_mode_caps, 279 sizeof(info->hw_mode_cap)); 280 } 281 } else if ((preferred_mode != WMI_HOST_HW_MODE_MAX) && 282 (preferred_mode == hw_mode_caps->hw_mode_id)) { 283 selected_mode = preferred_mode; 284 qdf_mem_copy(&info->hw_mode_cap, hw_mode_caps, 285 sizeof(info->hw_mode_cap)); 286 } 287 288 return selected_mode; 289 } 290 291 int init_deinit_populate_hw_mode_capability(void *wmi_handle, 292 uint8_t *event, struct target_psoc_info *tgt_hdl) 293 { 294 QDF_STATUS status = QDF_STATUS_SUCCESS; 295 uint8_t hw_idx; 296 uint32_t num_hw_modes; 297 struct wlan_psoc_host_hw_mode_caps hw_mode_caps[PSOC_MAX_HW_MODE]; 298 uint32_t preferred_mode, selected_mode = WMI_HOST_HW_MODE_MAX; 299 struct tgt_info *info; 300 301 info = &tgt_hdl->info; 302 num_hw_modes = info->service_ext_param.num_hw_modes; 303 if (num_hw_modes > PSOC_MAX_HW_MODE) { 304 target_if_err("invalid num_hw_modes %d", num_hw_modes); 305 return -EINVAL; 306 } 307 target_if_debug("num_hw_modes %d", num_hw_modes); 308 309 qdf_mem_zero(&hw_mode_caps, sizeof(hw_mode_caps)); 310 info->hw_modes.num_modes = 0; 311 info->hw_mode_cap.hw_mode_id = WMI_HOST_HW_MODE_MAX; 312 313 preferred_mode = target_psoc_get_preferred_hw_mode(tgt_hdl); 314 for (hw_idx = 0; hw_idx < num_hw_modes; hw_idx++) { 315 status = get_hw_mode(wmi_handle, event, hw_idx, 316 &hw_mode_caps[hw_idx]); 317 if (status) 318 goto return_exit; 319 320 if (hw_idx < WMI_HOST_HW_MODE_MAX) { 321 info->hw_modes.hw_mode_ids[hw_idx] = 322 hw_mode_caps[hw_idx].hw_mode_id; 323 info->hw_modes.num_modes++; 324 } 325 326 status = init_deinit_populate_mac_phy_capability(wmi_handle, 327 event, &hw_mode_caps[hw_idx], info); 328 if (status) 329 goto return_exit; 330 331 selected_mode = select_preferred_hw_mode(tgt_hdl, 332 &hw_mode_caps[hw_idx], 333 selected_mode); 334 } 335 336 if (preferred_mode == WMI_HOST_HW_MODE_DETECT) { 337 target_if_info("Preferred mode is not set, use mode id %d\n", 338 selected_mode); 339 target_psoc_set_preferred_hw_mode(tgt_hdl, selected_mode); 340 } 341 342 status = get_sar_version(wmi_handle, event, &info->service_ext_param); 343 target_if_debug("sar version %d", info->service_ext_param.sar_version); 344 345 return_exit: 346 return qdf_status_to_os_return(status); 347 } 348 349 int init_deinit_populate_dbr_ring_cap(struct wlan_objmgr_psoc *psoc, 350 void *handle, uint8_t *event, struct tgt_info *info) 351 352 { 353 uint8_t cap_idx; 354 uint32_t num_dbr_ring_caps; 355 QDF_STATUS status = QDF_STATUS_SUCCESS; 356 357 num_dbr_ring_caps = info->service_ext_param.num_dbr_ring_caps; 358 359 target_if_debug("Num DMA Capabilities = %d", num_dbr_ring_caps); 360 361 if (!num_dbr_ring_caps) 362 return 0; 363 364 info->dbr_ring_cap = qdf_mem_malloc( 365 sizeof(struct wlan_psoc_host_dbr_ring_caps) * 366 num_dbr_ring_caps); 367 368 if (!info->dbr_ring_cap) 369 return -EINVAL; 370 371 for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) { 372 status = wmi_extract_dbr_ring_cap_service_ready_ext(handle, 373 event, cap_idx, 374 &(info->dbr_ring_cap[cap_idx])); 375 if (QDF_IS_STATUS_ERROR(status)) { 376 target_if_err("Extraction of DMA cap failed"); 377 goto free_and_return; 378 } 379 } 380 381 return 0; 382 383 free_and_return: 384 qdf_mem_free(info->dbr_ring_cap); 385 info->dbr_ring_cap = NULL; 386 387 return qdf_status_to_os_return(status); 388 } 389 390 int init_deinit_populate_spectral_bin_scale_params( 391 struct wlan_objmgr_psoc *psoc, void *handle, 392 uint8_t *event, struct tgt_info *info) 393 394 { 395 uint8_t param_idx; 396 uint32_t num_bin_scaling_params; 397 QDF_STATUS status = QDF_STATUS_SUCCESS; 398 399 num_bin_scaling_params = info->service_ext_param.num_bin_scaling_params; 400 401 if (!num_bin_scaling_params) 402 return 0; 403 404 info->scaling_params = qdf_mem_malloc( 405 sizeof(struct wlan_psoc_host_spectral_scaling_params) * 406 num_bin_scaling_params); 407 408 if (!info->scaling_params) { 409 target_if_err("Mem alloc for bin scaling params failed"); 410 return -EINVAL; 411 } 412 413 for (param_idx = 0; param_idx < num_bin_scaling_params; param_idx++) { 414 status = wmi_extract_spectral_scaling_params_service_ready_ext( 415 handle, 416 event, param_idx, 417 &info->scaling_params[param_idx]); 418 if (QDF_IS_STATUS_ERROR(status)) { 419 target_if_err("Extraction of scaling params failed"); 420 goto free_and_return; 421 } 422 } 423 424 return 0; 425 426 free_and_return: 427 qdf_mem_free(info->scaling_params); 428 info->scaling_params = NULL; 429 430 return qdf_status_to_os_return(status); 431 } 432 433 QDF_STATUS init_deinit_dbr_ring_cap_free( 434 struct target_psoc_info *tgt_psoc_info) 435 { 436 QDF_STATUS status = QDF_STATUS_SUCCESS; 437 438 if (tgt_psoc_info->info.dbr_ring_cap) { 439 qdf_mem_free(tgt_psoc_info->info.dbr_ring_cap); 440 tgt_psoc_info->info.dbr_ring_cap = NULL; 441 } 442 443 return status; 444 } 445 qdf_export_symbol(init_deinit_dbr_ring_cap_free); 446 447 QDF_STATUS init_deinit_spectral_scaling_params_free( 448 struct target_psoc_info *tgt_psoc_info) 449 { 450 QDF_STATUS status = QDF_STATUS_E_FAILURE; 451 452 if (tgt_psoc_info->info.scaling_params) { 453 qdf_mem_free(tgt_psoc_info->info.scaling_params); 454 tgt_psoc_info->info.scaling_params = NULL; 455 status = QDF_STATUS_SUCCESS; 456 } 457 458 return status; 459 } 460 461 qdf_export_symbol(init_deinit_spectral_scaling_params_free); 462 463 int init_deinit_populate_phy_reg_cap(struct wlan_objmgr_psoc *psoc, 464 void *handle, uint8_t *event, 465 struct tgt_info *info, bool service_ready) 466 { 467 uint8_t reg_idx; 468 uint32_t num_phy_reg_cap; 469 QDF_STATUS status = QDF_STATUS_SUCCESS; 470 struct wlan_psoc_hal_reg_capability cap; 471 struct wlan_psoc_host_hal_reg_capabilities_ext 472 reg_cap[PSOC_MAX_PHY_REG_CAP] = {{0} }; 473 474 if (service_ready) { 475 status = wmi_extract_hal_reg_cap(handle, event, &cap); 476 if (QDF_IS_STATUS_ERROR(status)) { 477 target_if_err("failed to parse hal reg cap"); 478 return qdf_status_to_os_return(status); 479 } 480 info->service_ext_param.num_phy = 1; 481 num_phy_reg_cap = 1; 482 reg_cap[0].phy_id = 0; 483 qdf_mem_copy(&(reg_cap[0].eeprom_reg_domain), &cap, 484 sizeof(struct wlan_psoc_hal_reg_capability)); 485 target_if_debug("FW wireless modes 0x%x", 486 reg_cap[0].wireless_modes); 487 } else { 488 num_phy_reg_cap = info->service_ext_param.num_phy; 489 if (num_phy_reg_cap > PSOC_MAX_PHY_REG_CAP) { 490 target_if_err("Invalid num_phy_reg_cap %d", 491 num_phy_reg_cap); 492 return -EINVAL; 493 } 494 target_if_debug("num_phy_reg_cap %d", num_phy_reg_cap); 495 496 for (reg_idx = 0; reg_idx < num_phy_reg_cap; reg_idx++) { 497 status = wmi_extract_reg_cap_service_ready_ext(handle, 498 event, reg_idx, &(reg_cap[reg_idx])); 499 if (QDF_IS_STATUS_ERROR(status)) { 500 target_if_err("failed to parse reg cap"); 501 return qdf_status_to_os_return(status); 502 } 503 } 504 } 505 506 status = ucfg_reg_set_hal_reg_cap(psoc, reg_cap, num_phy_reg_cap); 507 508 return qdf_status_to_os_return(status); 509 } 510 511 static bool init_deinit_regdmn_160mhz_support( 512 struct wlan_psoc_host_hal_reg_capabilities_ext *hal_cap) 513 { 514 return ((hal_cap->wireless_modes & 515 WMI_HOST_REGDMN_MODE_11AC_VHT160) != 0); 516 } 517 518 static bool init_deinit_regdmn_80p80mhz_support( 519 struct wlan_psoc_host_hal_reg_capabilities_ext *hal_cap) 520 { 521 return ((hal_cap->wireless_modes & 522 WMI_HOST_REGDMN_MODE_11AC_VHT80_80) != 0); 523 } 524 525 static bool init_deinit_vht_160mhz_is_supported(uint32_t vhtcap) 526 { 527 return ((vhtcap & WLAN_VHTCAP_SUP_CHAN_WIDTH_160) != 0); 528 } 529 530 static bool init_deinit_vht_80p80mhz_is_supported(uint32_t vhtcap) 531 { 532 return ((vhtcap & WLAN_VHTCAP_SUP_CHAN_WIDTH_80_160) != 0); 533 } 534 535 static bool init_deinit_vht_160mhz_shortgi_is_supported(uint32_t vhtcap) 536 { 537 return ((vhtcap & WLAN_VHTCAP_SHORTGI_160) != 0); 538 } 539 540 QDF_STATUS init_deinit_validate_160_80p80_fw_caps( 541 struct wlan_objmgr_psoc *psoc, 542 struct target_psoc_info *tgt_hdl) 543 { 544 bool wireless_mode_160mhz = false; 545 bool wireless_mode_80p80mhz = false; 546 bool vhtcap_160mhz = false; 547 bool vhtcap_80p80_160mhz = false; 548 bool vhtcap_160mhz_sgi = false; 549 bool valid = false; 550 struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap; 551 struct common_wmi_handle *wmi_handle; 552 553 if (!tgt_hdl) { 554 target_if_err( 555 "target_psoc_info is null in validate 160n80p80 cap check"); 556 return QDF_STATUS_E_INVAL; 557 } 558 559 wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl); 560 561 if ((tgt_hdl->info.target_type == TARGET_TYPE_QCA8074) || 562 (tgt_hdl->info.target_type == TARGET_TYPE_QCA8074V2) || 563 (tgt_hdl->info.target_type == TARGET_TYPE_QCA6018) || 564 (tgt_hdl->info.target_type == TARGET_TYPE_QCA6290)) { 565 /** 566 * Return true for now. This is not available in 567 * qca8074 fw yet 568 */ 569 return QDF_STATUS_SUCCESS; 570 } 571 572 reg_cap = ucfg_reg_get_hal_reg_cap(psoc); 573 if (reg_cap == NULL) { 574 target_if_err("reg cap is NULL"); 575 return QDF_STATUS_E_FAILURE; 576 } 577 578 /* NOTE: Host driver gets vht capability and supported channel 579 * width / channel frequency range from FW/HALPHY and obeys it. 580 * Host driver is unaware of any physical filters or any other 581 * hardware factors that can impact these capabilities. 582 * These need to be correctly determined by firmware. 583 */ 584 585 /*This table lists all valid and invalid combinations 586 * WMODE160 WMODE80_80 VHTCAP_160 VHTCAP_80+80_160 IsCombinationvalid? 587 * 0 0 0 0 YES 588 * 0 0 0 1 NO 589 * 0 0 1 0 NO 590 * 0 0 1 1 NO 591 * 0 1 0 0 NO 592 * 0 1 0 1 NO 593 * 0 1 1 0 NO 594 * 0 1 1 1 NO 595 * 1 0 0 0 NO 596 * 1 0 0 1 NO 597 * 1 0 1 0 YES 598 * 1 0 1 1 NO 599 * 1 1 0 0 NO 600 * 1 1 0 1 YES 601 * 1 1 1 0 NO 602 * 1 1 1 1 NO 603 */ 604 605 /* NOTE: Last row in above table is invalid because value corresponding 606 * to both VHTCAP_160 and VHTCAP_80+80_160 being set is reserved as per 607 * 802.11ac. Only one of them can be set at a time. 608 */ 609 610 wireless_mode_160mhz = init_deinit_regdmn_160mhz_support(reg_cap); 611 wireless_mode_80p80mhz = init_deinit_regdmn_80p80mhz_support(reg_cap); 612 vhtcap_160mhz = init_deinit_vht_160mhz_is_supported( 613 tgt_hdl->info.target_caps.vht_cap_info); 614 vhtcap_80p80_160mhz = init_deinit_vht_80p80mhz_is_supported( 615 tgt_hdl->info.target_caps.vht_cap_info); 616 vhtcap_160mhz_sgi = init_deinit_vht_160mhz_shortgi_is_supported( 617 tgt_hdl->info.target_caps.vht_cap_info); 618 619 if (!(wireless_mode_160mhz || wireless_mode_80p80mhz || 620 vhtcap_160mhz || vhtcap_80p80_160mhz)) { 621 valid = QDF_STATUS_SUCCESS; 622 } else if (wireless_mode_160mhz && !wireless_mode_80p80mhz && 623 vhtcap_160mhz && !vhtcap_80p80_160mhz) { 624 valid = QDF_STATUS_SUCCESS; 625 } else if (wireless_mode_160mhz && wireless_mode_80p80mhz && 626 !vhtcap_160mhz && vhtcap_160mhz_sgi) { 627 valid = QDF_STATUS_SUCCESS; 628 } 629 630 if (valid == QDF_STATUS_SUCCESS) { 631 /* 632 * Ensure short GI for 160 MHz is enabled 633 * only if 160/80+80 is supported. 634 */ 635 if (vhtcap_160mhz_sgi && 636 !(vhtcap_160mhz || vhtcap_80p80_160mhz)) { 637 valid = QDF_STATUS_E_FAILURE; 638 } 639 } 640 641 /* Invalid config specified by FW */ 642 if (valid != QDF_STATUS_SUCCESS) { 643 target_if_err("Invalid 160/80+80 MHz config specified by FW. Take care of it first"); 644 target_if_err("wireless_mode_160mhz: %d, wireless_mode_80p80mhz: %d", 645 wireless_mode_160mhz, wireless_mode_80p80mhz); 646 target_if_err("vhtcap_160mhz: %d, vhtcap_80p80_160mhz: %d,vhtcap_160mhz_sgi: %d", 647 vhtcap_160mhz, vhtcap_80p80_160mhz, 648 vhtcap_160mhz_sgi); 649 } 650 return valid; 651 } 652 653 void init_deinit_chainmask_config( 654 struct wlan_objmgr_psoc *psoc, 655 struct target_psoc_info *tgt_hdl) 656 { 657 tgt_hdl->info.wlan_res_cfg.tx_chain_mask = 658 ((1 << tgt_hdl->info.target_caps.num_rf_chains) - 1); 659 tgt_hdl->info.wlan_res_cfg.rx_chain_mask = 660 ((1 << tgt_hdl->info.target_caps.num_rf_chains) - 1); 661 } 662 663 QDF_STATUS init_deinit_is_service_ext_msg( 664 struct wlan_objmgr_psoc *psoc, 665 struct target_psoc_info *tgt_hdl) 666 { 667 struct common_wmi_handle *wmi_handle; 668 669 if (!tgt_hdl) { 670 target_if_err( 671 "psoc target_psoc_info is null in service ext msg"); 672 return QDF_STATUS_E_INVAL; 673 } 674 675 wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl); 676 677 if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) 678 return QDF_STATUS_SUCCESS; 679 else 680 return QDF_STATUS_E_FAILURE; 681 } 682 683 bool init_deinit_is_preferred_hw_mode_supported( 684 struct wlan_objmgr_psoc *psoc, 685 struct target_psoc_info *tgt_hdl) 686 { 687 uint16_t i; 688 struct tgt_info *info; 689 690 if (!tgt_hdl) { 691 target_if_err( 692 "psoc target_psoc_info is null in service ext msg"); 693 return FALSE; 694 } 695 696 info = &tgt_hdl->info; 697 698 if (info->preferred_hw_mode == WMI_HOST_HW_MODE_MAX) 699 return TRUE; 700 701 for (i = 0; i < target_psoc_get_total_mac_phy_cnt(tgt_hdl); i++) { 702 if (info->mac_phy_cap[i].hw_mode_id == info->preferred_hw_mode) 703 return TRUE; 704 } 705 706 return FALSE; 707 } 708 709 void init_deinit_wakeup_host_wait( 710 struct wlan_objmgr_psoc *psoc, 711 struct target_psoc_info *tgt_hdl) 712 { 713 if (!tgt_hdl) { 714 target_if_err("psoc target_psoc_info is null in target ready"); 715 return; 716 } 717 qdf_event_set(&tgt_hdl->info.event); 718 } 719