1cc75651cSSrinivas Pitla /* 2ff041723SPavankumar Nandeshwar * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 38380ebafSSrinivas Dasari * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. 4cc75651cSSrinivas Pitla * 5cc75651cSSrinivas Pitla * Permission to use, copy, modify, and/or distribute this software for 6cc75651cSSrinivas Pitla * any purpose with or without fee is hereby granted, provided that the 7cc75651cSSrinivas Pitla * above copyright notice and this permission notice appear in all 8cc75651cSSrinivas Pitla * copies. 9cc75651cSSrinivas Pitla * 10cc75651cSSrinivas Pitla * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11cc75651cSSrinivas Pitla * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12cc75651cSSrinivas Pitla * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13cc75651cSSrinivas Pitla * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14cc75651cSSrinivas Pitla * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15cc75651cSSrinivas Pitla * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16cc75651cSSrinivas Pitla * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17cc75651cSSrinivas Pitla * PERFORMANCE OF THIS SOFTWARE. 18cc75651cSSrinivas Pitla */ 19cc75651cSSrinivas Pitla /** 20cc75651cSSrinivas Pitla * DOC: service_ready_util.c 21cc75651cSSrinivas Pitla * 22cc75651cSSrinivas Pitla * Public APIs implementation source file for accessing (ext)service ready 23cc75651cSSrinivas Pitla * data from psoc object 24cc75651cSSrinivas Pitla */ 25cc75651cSSrinivas Pitla #include "service_ready_util.h" 26cc75651cSSrinivas Pitla #include <wlan_reg_ucfg_api.h> 27cc75651cSSrinivas Pitla #include <target_type.h> 28cc75651cSSrinivas Pitla #include <qdf_module.h> 29cc75651cSSrinivas Pitla 30cc75651cSSrinivas Pitla QDF_STATUS init_deinit_chainmask_table_alloc( 31cc75651cSSrinivas Pitla struct wlan_psoc_host_service_ext_param *ser_ext_par) 32cc75651cSSrinivas Pitla { 33cc75651cSSrinivas Pitla int i; 34cc75651cSSrinivas Pitla uint32_t alloc_size; 35c05f8e47SBala Venkatesh QDF_STATUS status = QDF_STATUS_SUCCESS; 36cc75651cSSrinivas Pitla 37c05f8e47SBala Venkatesh if (ser_ext_par->num_chainmask_tables == 0) 38c05f8e47SBala Venkatesh return QDF_STATUS_E_NOSUPPORT; 39c05f8e47SBala Venkatesh 40cc75651cSSrinivas Pitla for (i = 0; i < ser_ext_par->num_chainmask_tables; i++) { 41c05f8e47SBala Venkatesh if (ser_ext_par->chainmask_table[i].num_valid_chainmasks > 42c05f8e47SBala Venkatesh (UINT_MAX / sizeof( 43c05f8e47SBala Venkatesh struct wlan_psoc_host_chainmask_capabilities))) { 44c05f8e47SBala Venkatesh target_if_err("invalid valid chanmask num %d", 45c05f8e47SBala Venkatesh ser_ext_par->chainmask_table[i]. 46c05f8e47SBala Venkatesh num_valid_chainmasks); 47c05f8e47SBala Venkatesh status = QDF_STATUS_E_FAILURE; 48c05f8e47SBala Venkatesh break; 49c05f8e47SBala Venkatesh } 50cc75651cSSrinivas Pitla alloc_size = 51cc75651cSSrinivas Pitla (sizeof(struct wlan_psoc_host_chainmask_capabilities) * 52cc75651cSSrinivas Pitla ser_ext_par->chainmask_table[i].num_valid_chainmasks); 53cc75651cSSrinivas Pitla 54cc75651cSSrinivas Pitla ser_ext_par->chainmask_table[i].cap_list = 55b5b21cacSDustin Brown qdf_mem_malloc(alloc_size); 56cc75651cSSrinivas Pitla if (!ser_ext_par->chainmask_table[i].cap_list) { 57cc75651cSSrinivas Pitla init_deinit_chainmask_table_free(ser_ext_par); 58cc75651cSSrinivas Pitla status = QDF_STATUS_E_NOMEM; 59cc75651cSSrinivas Pitla break; 60cc75651cSSrinivas Pitla } 61cc75651cSSrinivas Pitla } 62cc75651cSSrinivas Pitla 63cc75651cSSrinivas Pitla return status; 64cc75651cSSrinivas Pitla } 65cc75651cSSrinivas Pitla 66cc75651cSSrinivas Pitla qdf_export_symbol(init_deinit_chainmask_table_alloc); 67cc75651cSSrinivas Pitla 68cc75651cSSrinivas Pitla QDF_STATUS init_deinit_chainmask_table_free( 69cc75651cSSrinivas Pitla struct wlan_psoc_host_service_ext_param *ser_ext_par) 70cc75651cSSrinivas Pitla { 71cc75651cSSrinivas Pitla struct wlan_psoc_host_chainmask_table *table; 72cc75651cSSrinivas Pitla int i; 73cc75651cSSrinivas Pitla 74cc75651cSSrinivas Pitla for (i = 0; i < ser_ext_par->num_chainmask_tables; i++) { 75cc75651cSSrinivas Pitla table = &(ser_ext_par->chainmask_table[i]); 76cc75651cSSrinivas Pitla if (table->cap_list) { 77cc75651cSSrinivas Pitla qdf_mem_free(table->cap_list); 78cc75651cSSrinivas Pitla table->cap_list = NULL; 79cc75651cSSrinivas Pitla } 80cc75651cSSrinivas Pitla } 81cc75651cSSrinivas Pitla 82cc75651cSSrinivas Pitla return QDF_STATUS_SUCCESS; 83cc75651cSSrinivas Pitla } 84cc75651cSSrinivas Pitla 85cc75651cSSrinivas Pitla qdf_export_symbol(init_deinit_chainmask_table_free); 86cc75651cSSrinivas Pitla 87453eea49SHimanshu Batra int init_deinit_populate_service_bitmap( 88453eea49SHimanshu Batra wmi_unified_t wmi_handle, uint8_t *event, 89cc75651cSSrinivas Pitla uint32_t *service_bitmap) 90cc75651cSSrinivas Pitla { 91cc75651cSSrinivas Pitla QDF_STATUS status; 92cc75651cSSrinivas Pitla 93cc75651cSSrinivas Pitla status = wmi_save_service_bitmap(wmi_handle, event, service_bitmap); 94cc75651cSSrinivas Pitla if (QDF_IS_STATUS_ERROR(status)) { 95cc75651cSSrinivas Pitla target_if_err("failed to parse service bitmap"); 96cc75651cSSrinivas Pitla return qdf_status_to_os_return(status); 97cc75651cSSrinivas Pitla } 98cc75651cSSrinivas Pitla 99cc75651cSSrinivas Pitla return 0; 100cc75651cSSrinivas Pitla } 101cc75651cSSrinivas Pitla 102c36e3543SAkshay Kosigi int init_deinit_populate_fw_version_cmd(wmi_unified_t wmi_handle, 103c36e3543SAkshay Kosigi uint8_t *event) 104cc75651cSSrinivas Pitla { 105cc75651cSSrinivas Pitla QDF_STATUS status; 106cc75651cSSrinivas Pitla 107cc75651cSSrinivas Pitla status = wmi_unified_save_fw_version_cmd(wmi_handle, event); 108cc75651cSSrinivas Pitla if (QDF_IS_STATUS_ERROR(status)) 109cc75651cSSrinivas Pitla target_if_err("failed to save fw version"); 110cc75651cSSrinivas Pitla 111cc75651cSSrinivas Pitla return 0; 112cc75651cSSrinivas Pitla } 113cc75651cSSrinivas Pitla 11429bc9919SHimanshu Batra int init_deinit_populate_target_cap( 11529bc9919SHimanshu Batra wmi_unified_t wmi_handle, uint8_t *event, 116cc75651cSSrinivas Pitla struct wlan_psoc_target_capability_info *cap) 117cc75651cSSrinivas Pitla { 118cc75651cSSrinivas Pitla QDF_STATUS status; 119cc75651cSSrinivas Pitla 120cc75651cSSrinivas Pitla status = wmi_get_target_cap_from_service_ready(wmi_handle, event, cap); 121cc75651cSSrinivas Pitla if (QDF_IS_STATUS_ERROR(status)) { 122cc75651cSSrinivas Pitla target_if_err("failed to parse target cap"); 123cc75651cSSrinivas Pitla return qdf_status_to_os_return(status); 124cc75651cSSrinivas Pitla } 125cc75651cSSrinivas Pitla 126cc75651cSSrinivas Pitla return 0; 127cc75651cSSrinivas Pitla } 128cc75651cSSrinivas Pitla 1296abe4bebSHimanshu Batra int init_deinit_populate_service_ready_ext_param( 1306abe4bebSHimanshu Batra wmi_unified_t handle, uint8_t *evt, 131cc75651cSSrinivas Pitla struct wlan_psoc_host_service_ext_param *param) 132cc75651cSSrinivas Pitla { 133cc75651cSSrinivas Pitla QDF_STATUS status; 134cc75651cSSrinivas Pitla 135cc75651cSSrinivas Pitla status = wmi_extract_service_ready_ext(handle, evt, param); 136cc75651cSSrinivas Pitla if (QDF_IS_STATUS_ERROR(status)) { 137cc75651cSSrinivas Pitla target_if_err("failed to parse wmi service ready ext param"); 138cc75651cSSrinivas Pitla return qdf_status_to_os_return(status); 139cc75651cSSrinivas Pitla } 140cc75651cSSrinivas Pitla 141cc75651cSSrinivas Pitla return 0; 142cc75651cSSrinivas Pitla } 143cc75651cSSrinivas Pitla 14465614566SSourav Mohapatra int init_deinit_populate_service_ready_ext2_param( 14565614566SSourav Mohapatra wmi_unified_t handle, uint8_t *evt, 14665614566SSourav Mohapatra struct tgt_info *info) 14765614566SSourav Mohapatra { 14865614566SSourav Mohapatra QDF_STATUS status; 14965614566SSourav Mohapatra 15065614566SSourav Mohapatra status = wmi_extract_service_ready_ext2(handle, evt, 15165614566SSourav Mohapatra &info->service_ext2_param); 15265614566SSourav Mohapatra if (QDF_IS_STATUS_ERROR(status)) { 15365614566SSourav Mohapatra target_if_err("failed to parse wmi service ready ext param"); 15465614566SSourav Mohapatra return qdf_status_to_os_return(status); 15565614566SSourav Mohapatra } 15665614566SSourav Mohapatra 15765614566SSourav Mohapatra return 0; 15865614566SSourav Mohapatra } 15965614566SSourav Mohapatra 160453eea49SHimanshu Batra int init_deinit_populate_chainmask_tables( 161453eea49SHimanshu Batra wmi_unified_t handle, uint8_t *evt, 162cc75651cSSrinivas Pitla struct wlan_psoc_host_chainmask_table *param) 163cc75651cSSrinivas Pitla { 164cc75651cSSrinivas Pitla QDF_STATUS status; 165cc75651cSSrinivas Pitla 166cc75651cSSrinivas Pitla status = wmi_extract_chainmask_tables(handle, evt, param); 167cc75651cSSrinivas Pitla if (QDF_IS_STATUS_ERROR(status)) { 168cc75651cSSrinivas Pitla target_if_err("failed to parse wmi service ready ext param"); 169cc75651cSSrinivas Pitla return qdf_status_to_os_return(status); 170cc75651cSSrinivas Pitla } 171cc75651cSSrinivas Pitla 172cc75651cSSrinivas Pitla return 0; 173cc75651cSSrinivas Pitla } 174cc75651cSSrinivas Pitla 1756abe4bebSHimanshu Batra int init_deinit_populate_mac_phy_capability( 1766abe4bebSHimanshu Batra wmi_unified_t handle, uint8_t *evt, 177cc75651cSSrinivas Pitla struct wlan_psoc_host_hw_mode_caps *hw_cap, struct tgt_info *info) 178cc75651cSSrinivas Pitla { 179cc75651cSSrinivas Pitla QDF_STATUS status; 180cc75651cSSrinivas Pitla uint32_t hw_mode_id; 181cc75651cSSrinivas Pitla uint32_t phy_bit_map; 182cc75651cSSrinivas Pitla uint8_t mac_phy_id; 183cc75651cSSrinivas Pitla 184cc75651cSSrinivas Pitla hw_mode_id = hw_cap->hw_mode_id; 185cc75651cSSrinivas Pitla phy_bit_map = hw_cap->phy_id_map; 1863fc809d6SDustin Brown target_if_debug("hw_mode_id %d phy_bit_map 0x%x", 187cc75651cSSrinivas Pitla hw_mode_id, phy_bit_map); 188cc75651cSSrinivas Pitla 189cc75651cSSrinivas Pitla mac_phy_id = 0; 190cc75651cSSrinivas Pitla while (phy_bit_map) { 191cc75651cSSrinivas Pitla if (info->total_mac_phy_cnt >= PSOC_MAX_MAC_PHY_CAP) { 192cc75651cSSrinivas Pitla target_if_err("total mac phy exceeds max limit %d", 193cc75651cSSrinivas Pitla info->total_mac_phy_cnt); 194cc75651cSSrinivas Pitla return -EINVAL; 195cc75651cSSrinivas Pitla } 196cc75651cSSrinivas Pitla 197cc75651cSSrinivas Pitla status = wmi_extract_mac_phy_cap_service_ready_ext(handle, 198cc75651cSSrinivas Pitla evt, hw_mode_id, mac_phy_id, 199cc75651cSSrinivas Pitla &(info->mac_phy_cap[info->total_mac_phy_cnt])); 200cc75651cSSrinivas Pitla if (QDF_IS_STATUS_ERROR(status)) { 201cc75651cSSrinivas Pitla target_if_err("failed to parse mac phy capability"); 202cc75651cSSrinivas Pitla return qdf_status_to_os_return(status); 203cc75651cSSrinivas Pitla } 204e460c52cSArunk Khandavalli info->mac_phy_cap[info->total_mac_phy_cnt].hw_mode_config_type 205e460c52cSArunk Khandavalli = hw_cap->hw_mode_config_type; 206cc75651cSSrinivas Pitla info->total_mac_phy_cnt++; 207cc75651cSSrinivas Pitla phy_bit_map &= (phy_bit_map - 1); 208cc75651cSSrinivas Pitla mac_phy_id++; 209cc75651cSSrinivas Pitla } 2103fc809d6SDustin Brown target_if_debug("total_mac_phy_cnt %d", info->total_mac_phy_cnt); 211cc75651cSSrinivas Pitla 212cc75651cSSrinivas Pitla return 0; 213cc75651cSSrinivas Pitla } 214cc75651cSSrinivas Pitla 2156abe4bebSHimanshu Batra static int get_hw_mode(wmi_unified_t handle, uint8_t *evt, uint8_t hw_idx, 216cc75651cSSrinivas Pitla struct wlan_psoc_host_hw_mode_caps *cap) 217cc75651cSSrinivas Pitla { 218cc75651cSSrinivas Pitla QDF_STATUS status; 219cc75651cSSrinivas Pitla 220cc75651cSSrinivas Pitla status = wmi_extract_hw_mode_cap_service_ready_ext(handle, evt, 221cc75651cSSrinivas Pitla hw_idx, cap); 222cc75651cSSrinivas Pitla if (QDF_IS_STATUS_ERROR(status)) { 223cc75651cSSrinivas Pitla target_if_err("failed to parse hw mode capability"); 224cc75651cSSrinivas Pitla return qdf_status_to_os_return(status); 225cc75651cSSrinivas Pitla } 226cc75651cSSrinivas Pitla 227cc75651cSSrinivas Pitla return 0; 228cc75651cSSrinivas Pitla } 229cc75651cSSrinivas Pitla 2306abe4bebSHimanshu Batra static int get_sar_version(wmi_unified_t handle, uint8_t *evt, 231762ad5dbSKabilan Kannan struct wlan_psoc_host_service_ext_param *ext_param) 232762ad5dbSKabilan Kannan { 233762ad5dbSKabilan Kannan QDF_STATUS status; 234762ad5dbSKabilan Kannan 235762ad5dbSKabilan Kannan status = wmi_extract_sar_cap_service_ready_ext(handle, evt, ext_param); 236762ad5dbSKabilan Kannan if (QDF_IS_STATUS_ERROR(status)) { 237762ad5dbSKabilan Kannan target_if_err("failed to parse sar capability"); 238762ad5dbSKabilan Kannan return qdf_status_to_os_return(status); 239762ad5dbSKabilan Kannan } 240762ad5dbSKabilan Kannan 241762ad5dbSKabilan Kannan return 0; 242762ad5dbSKabilan Kannan } 243762ad5dbSKabilan Kannan 244c0d01021SKiran Venkatappa static bool new_hw_mode_preferred(uint32_t current_hw_mode, 245c0d01021SKiran Venkatappa uint32_t new_hw_mode) 246c0d01021SKiran Venkatappa { 247c6ca8572SNandha Kishore Easwaran uint8_t hw_mode_id_precedence[WMI_HOST_HW_MODE_MAX + 1] = { 6, 2, 5, 248c6ca8572SNandha Kishore Easwaran 4, 1, 3, 249*0ae969c9SAniruddha Mishra 7, 0, 8, 250*0ae969c9SAniruddha Mishra 9, 10, 11}; 251c0d01021SKiran Venkatappa 252c0d01021SKiran Venkatappa if (current_hw_mode > WMI_HOST_HW_MODE_MAX || 253c0d01021SKiran Venkatappa new_hw_mode > WMI_HOST_HW_MODE_MAX) 254c0d01021SKiran Venkatappa return false; 255c0d01021SKiran Venkatappa 256c0d01021SKiran Venkatappa /* Above precedence is defined by low to high, lower the value 257c0d01021SKiran Venkatappa * higher the precedence 258c0d01021SKiran Venkatappa */ 259c0d01021SKiran Venkatappa if (hw_mode_id_precedence[current_hw_mode] > 260c0d01021SKiran Venkatappa hw_mode_id_precedence[new_hw_mode]) 261c0d01021SKiran Venkatappa return true; 262c0d01021SKiran Venkatappa 263c0d01021SKiran Venkatappa return false; 264c0d01021SKiran Venkatappa } 265c0d01021SKiran Venkatappa 266c0d01021SKiran Venkatappa /** 267045d6e4eSJeff Johnson * select_preferred_hw_mode() - Select preferred hw mode based on current mode. 268c0d01021SKiran Venkatappa * @tgt_hdl: target_psoc_info object 269c0d01021SKiran Venkatappa * @hw_mode_caps: HW mode caps of new mode id that needs to checked for 270c0d01021SKiran Venkatappa * selection. 271c0d01021SKiran Venkatappa * @current_mode: Current mode. 272c0d01021SKiran Venkatappa * 273c0d01021SKiran Venkatappa * API to select preferred hw mode based on the current config. 274c0d01021SKiran Venkatappa * Based on host config for preferred mode, final mode selected as follows- 275c0d01021SKiran Venkatappa * 1) If preferred_mode == WMI_HOST_HW_MODE_DETECT, Then select mode from FW 276c0d01021SKiran Venkatappa * supported modes such that it is a super set of all modes FW advertises. 277c0d01021SKiran Venkatappa * For e.g., If FW supports DBS(2 radio) and DBS_SBS(3 radio)- Choose DBS_SBS 278c0d01021SKiran Venkatappa * 2) If preferred_mode == WMI_HOST_HW_MODE_MAX, Then do not select any mode 279c0d01021SKiran Venkatappa * from FW advertised modes. Host needs to maintain all modes supported in FW 280c0d01021SKiran Venkatappa * and can switch dynamically. 281c0d01021SKiran Venkatappa * 3) Else, A valid preferred_mode is set, Hence check if this is part of FW 282c0d01021SKiran Venkatappa * supported modes. If it is found, then use it to bring up the device. 283c0d01021SKiran Venkatappa * 284c0d01021SKiran Venkatappa * Return: selected_mode based on the above criteria. 285c0d01021SKiran Venkatappa */ 286c0d01021SKiran Venkatappa static uint32_t 287c0d01021SKiran Venkatappa select_preferred_hw_mode(struct target_psoc_info *tgt_hdl, 288c0d01021SKiran Venkatappa struct wlan_psoc_host_hw_mode_caps *hw_mode_caps, 289c0d01021SKiran Venkatappa uint32_t current_mode) 290c0d01021SKiran Venkatappa { 291c0d01021SKiran Venkatappa uint32_t preferred_mode, selected_mode = current_mode; 292c0d01021SKiran Venkatappa struct tgt_info *info; 293c0d01021SKiran Venkatappa 294c0d01021SKiran Venkatappa info = &tgt_hdl->info; 295c0d01021SKiran Venkatappa preferred_mode = target_psoc_get_preferred_hw_mode(tgt_hdl); 296c0d01021SKiran Venkatappa if (preferred_mode == WMI_HOST_HW_MODE_DETECT) { 297c0d01021SKiran Venkatappa uint32_t new_mode = hw_mode_caps->hw_mode_id; 298c0d01021SKiran Venkatappa 299c0d01021SKiran Venkatappa /* Choose hw_mode_id based on precedence */ 300c0d01021SKiran Venkatappa if (new_hw_mode_preferred(selected_mode, new_mode)) { 301c0d01021SKiran Venkatappa selected_mode = new_mode; 302c0d01021SKiran Venkatappa qdf_mem_copy(&info->hw_mode_cap, hw_mode_caps, 303c0d01021SKiran Venkatappa sizeof(info->hw_mode_cap)); 304c0d01021SKiran Venkatappa } 305c0d01021SKiran Venkatappa } else if ((preferred_mode != WMI_HOST_HW_MODE_MAX) && 306c0d01021SKiran Venkatappa (preferred_mode == hw_mode_caps->hw_mode_id)) { 307c0d01021SKiran Venkatappa selected_mode = preferred_mode; 308c0d01021SKiran Venkatappa qdf_mem_copy(&info->hw_mode_cap, hw_mode_caps, 309c0d01021SKiran Venkatappa sizeof(info->hw_mode_cap)); 310c0d01021SKiran Venkatappa } 311c0d01021SKiran Venkatappa 312c0d01021SKiran Venkatappa return selected_mode; 313c0d01021SKiran Venkatappa } 314c0d01021SKiran Venkatappa 31513b4322eSRachit Kankane #ifdef FEATURE_NO_DBS_INTRABAND_MCC_SUPPORT 31613b4322eSRachit Kankane static void init_deinit_change_def_hw_mode(struct target_psoc_info *tgt_hdl, 31713b4322eSRachit Kankane struct wmi_unified *wmi_handle) 31813b4322eSRachit Kankane { 31913b4322eSRachit Kankane struct tgt_info *info = &tgt_hdl->info; 32013b4322eSRachit Kankane 32113b4322eSRachit Kankane if ((info->hw_modes.num_modes == 1) && 32213b4322eSRachit Kankane (info->hw_modes.hw_mode_ids[0] == WMI_HOST_HW_MODE_DBS) && 32313b4322eSRachit Kankane !wmi_service_enabled(wmi_handle, 32413b4322eSRachit Kankane wmi_service_dual_band_simultaneous_support)) 32513b4322eSRachit Kankane target_psoc_set_preferred_hw_mode(tgt_hdl, 32613b4322eSRachit Kankane WMI_HOST_HW_MODE_DETECT); 32713b4322eSRachit Kankane } 32813b4322eSRachit Kankane #else 32913b4322eSRachit Kankane static void init_deinit_change_def_hw_mode(struct target_psoc_info *tgt_hdl, 33013b4322eSRachit Kankane struct wmi_unified *wmi_handle) 33113b4322eSRachit Kankane { 33213b4322eSRachit Kankane } 33313b4322eSRachit Kankane #endif 33413b4322eSRachit Kankane 3356abe4bebSHimanshu Batra int init_deinit_populate_hw_mode_capability( 3366abe4bebSHimanshu Batra wmi_unified_t wmi_handle, uint8_t *event, 3376abe4bebSHimanshu Batra struct target_psoc_info *tgt_hdl) 338cc75651cSSrinivas Pitla { 339cc75651cSSrinivas Pitla QDF_STATUS status = QDF_STATUS_SUCCESS; 340cc75651cSSrinivas Pitla uint8_t hw_idx; 341cc75651cSSrinivas Pitla uint32_t num_hw_modes; 342cc75651cSSrinivas Pitla struct wlan_psoc_host_hw_mode_caps hw_mode_caps[PSOC_MAX_HW_MODE]; 343c0d01021SKiran Venkatappa uint32_t preferred_mode, selected_mode = WMI_HOST_HW_MODE_MAX; 344cc75651cSSrinivas Pitla struct tgt_info *info; 345cc75651cSSrinivas Pitla 346cc75651cSSrinivas Pitla info = &tgt_hdl->info; 347cc75651cSSrinivas Pitla num_hw_modes = info->service_ext_param.num_hw_modes; 348cc75651cSSrinivas Pitla if (num_hw_modes > PSOC_MAX_HW_MODE) { 349cc75651cSSrinivas Pitla target_if_err("invalid num_hw_modes %d", num_hw_modes); 350cc75651cSSrinivas Pitla return -EINVAL; 351cc75651cSSrinivas Pitla } 3523fc809d6SDustin Brown target_if_debug("num_hw_modes %d", num_hw_modes); 353cc75651cSSrinivas Pitla 354cc75651cSSrinivas Pitla qdf_mem_zero(&hw_mode_caps, sizeof(hw_mode_caps)); 355c0d01021SKiran Venkatappa info->hw_modes.num_modes = 0; 356c0d01021SKiran Venkatappa info->hw_mode_cap.hw_mode_id = WMI_HOST_HW_MODE_MAX; 357cc75651cSSrinivas Pitla 358cc75651cSSrinivas Pitla for (hw_idx = 0; hw_idx < num_hw_modes; hw_idx++) { 359cc75651cSSrinivas Pitla status = get_hw_mode(wmi_handle, event, hw_idx, 360cc75651cSSrinivas Pitla &hw_mode_caps[hw_idx]); 361cc75651cSSrinivas Pitla if (status) 362cc75651cSSrinivas Pitla goto return_exit; 363cc75651cSSrinivas Pitla 364c0d01021SKiran Venkatappa if (hw_idx < WMI_HOST_HW_MODE_MAX) { 365c0d01021SKiran Venkatappa info->hw_modes.hw_mode_ids[hw_idx] = 366c0d01021SKiran Venkatappa hw_mode_caps[hw_idx].hw_mode_id; 367a76f88adSShashikala Prabhu info->hw_modes.phy_bit_map[hw_idx] = 368a76f88adSShashikala Prabhu hw_mode_caps[hw_idx].phy_id_map; 369c0d01021SKiran Venkatappa info->hw_modes.num_modes++; 370c0d01021SKiran Venkatappa } 371cc75651cSSrinivas Pitla 372cc75651cSSrinivas Pitla status = init_deinit_populate_mac_phy_capability(wmi_handle, 373cc75651cSSrinivas Pitla event, &hw_mode_caps[hw_idx], info); 374cc75651cSSrinivas Pitla if (status) 375cc75651cSSrinivas Pitla goto return_exit; 376cc75651cSSrinivas Pitla 37713b4322eSRachit Kankane if (num_hw_modes == 1) 37813b4322eSRachit Kankane init_deinit_change_def_hw_mode(tgt_hdl, wmi_handle); 37913b4322eSRachit Kankane 380c0d01021SKiran Venkatappa selected_mode = select_preferred_hw_mode(tgt_hdl, 381c0d01021SKiran Venkatappa &hw_mode_caps[hw_idx], 382c0d01021SKiran Venkatappa selected_mode); 383cc75651cSSrinivas Pitla } 384c0d01021SKiran Venkatappa 38513b4322eSRachit Kankane preferred_mode = target_psoc_get_preferred_hw_mode(tgt_hdl); 386c0d01021SKiran Venkatappa if (preferred_mode == WMI_HOST_HW_MODE_DETECT) { 387c0d01021SKiran Venkatappa target_if_info("Preferred mode is not set, use mode id %d\n", 388c0d01021SKiran Venkatappa selected_mode); 389c0d01021SKiran Venkatappa target_psoc_set_preferred_hw_mode(tgt_hdl, selected_mode); 3904d124bfbSRachit Kankane 3914d124bfbSRachit Kankane /* Change default DBS hw mode as per selected one */ 3924d124bfbSRachit Kankane info->target_caps.default_dbs_hw_mode_index = selected_mode; 393cc75651cSSrinivas Pitla } 394c0d01021SKiran Venkatappa 395762ad5dbSKabilan Kannan status = get_sar_version(wmi_handle, event, &info->service_ext_param); 3963fc809d6SDustin Brown target_if_debug("sar version %d", info->service_ext_param.sar_version); 397cc75651cSSrinivas Pitla 398cc75651cSSrinivas Pitla return_exit: 399cc75651cSSrinivas Pitla return qdf_status_to_os_return(status); 400cc75651cSSrinivas Pitla } 401cc75651cSSrinivas Pitla 402cc75651cSSrinivas Pitla int init_deinit_populate_dbr_ring_cap(struct wlan_objmgr_psoc *psoc, 403453eea49SHimanshu Batra wmi_unified_t handle, uint8_t *event, 404453eea49SHimanshu Batra struct tgt_info *info) 405cc75651cSSrinivas Pitla 406cc75651cSSrinivas Pitla { 407cc75651cSSrinivas Pitla uint8_t cap_idx; 408cc75651cSSrinivas Pitla uint32_t num_dbr_ring_caps; 409cc75651cSSrinivas Pitla QDF_STATUS status = QDF_STATUS_SUCCESS; 410cc75651cSSrinivas Pitla 411cc75651cSSrinivas Pitla num_dbr_ring_caps = info->service_ext_param.num_dbr_ring_caps; 4123fc809d6SDustin Brown target_if_debug("Num DMA Capabilities = %d", num_dbr_ring_caps); 413cc75651cSSrinivas Pitla 414cc75651cSSrinivas Pitla if (!num_dbr_ring_caps) 415cc75651cSSrinivas Pitla return 0; 416cc75651cSSrinivas Pitla 417cc75651cSSrinivas Pitla info->dbr_ring_cap = qdf_mem_malloc( 418cc75651cSSrinivas Pitla sizeof(struct wlan_psoc_host_dbr_ring_caps) * 419cc75651cSSrinivas Pitla num_dbr_ring_caps); 420cc75651cSSrinivas Pitla 4210c5bdd7eSMadhvapathi Sriram if (!info->dbr_ring_cap) 422cc75651cSSrinivas Pitla return -EINVAL; 423cc75651cSSrinivas Pitla 424cc75651cSSrinivas Pitla for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) { 425cc75651cSSrinivas Pitla status = wmi_extract_dbr_ring_cap_service_ready_ext(handle, 426cc75651cSSrinivas Pitla event, cap_idx, 427cc75651cSSrinivas Pitla &(info->dbr_ring_cap[cap_idx])); 428cc75651cSSrinivas Pitla if (QDF_IS_STATUS_ERROR(status)) { 429cc75651cSSrinivas Pitla target_if_err("Extraction of DMA cap failed"); 430cc75651cSSrinivas Pitla goto free_and_return; 431cc75651cSSrinivas Pitla } 432cc75651cSSrinivas Pitla } 433cc75651cSSrinivas Pitla 434cc75651cSSrinivas Pitla return 0; 435cc75651cSSrinivas Pitla 436cc75651cSSrinivas Pitla free_and_return: 437cc75651cSSrinivas Pitla qdf_mem_free(info->dbr_ring_cap); 438cc75651cSSrinivas Pitla info->dbr_ring_cap = NULL; 439cc75651cSSrinivas Pitla 440cc75651cSSrinivas Pitla return qdf_status_to_os_return(status); 441cc75651cSSrinivas Pitla } 442cc75651cSSrinivas Pitla 443285561b9SDebasis Das int init_deinit_populate_dbr_ring_cap_ext2(struct wlan_objmgr_psoc *psoc, 444285561b9SDebasis Das wmi_unified_t handle, uint8_t *event, 445285561b9SDebasis Das struct tgt_info *info) 446285561b9SDebasis Das 447285561b9SDebasis Das { 448285561b9SDebasis Das uint8_t cap_idx; 449285561b9SDebasis Das uint32_t num_dbr_ring_caps; 450285561b9SDebasis Das QDF_STATUS status = QDF_STATUS_SUCCESS; 451285561b9SDebasis Das struct wlan_psoc_host_dbr_ring_caps *param; 452285561b9SDebasis Das 453285561b9SDebasis Das /* 454285561b9SDebasis Das * If FW had already sent this info as part of EXT event, 455285561b9SDebasis Das * we need to discard the same and use the info from EXT2. 456285561b9SDebasis Das */ 457285561b9SDebasis Das if (info->service_ext_param.num_dbr_ring_caps) { 458285561b9SDebasis Das target_if_debug("dbr_ring_caps already populated"); 459285561b9SDebasis Das info->service_ext_param.num_dbr_ring_caps = 0; 460285561b9SDebasis Das qdf_mem_free(info->dbr_ring_cap); 461285561b9SDebasis Das info->dbr_ring_cap = NULL; 462285561b9SDebasis Das } 463285561b9SDebasis Das 464285561b9SDebasis Das num_dbr_ring_caps = info->service_ext2_param.num_dbr_ring_caps; 465285561b9SDebasis Das target_if_debug("Num DMA Capabilities = %d", num_dbr_ring_caps); 466285561b9SDebasis Das 467285561b9SDebasis Das if (!num_dbr_ring_caps) 468285561b9SDebasis Das return 0; 469285561b9SDebasis Das 470285561b9SDebasis Das info->dbr_ring_cap = qdf_mem_malloc( 471285561b9SDebasis Das sizeof(struct wlan_psoc_host_dbr_ring_caps) * 472285561b9SDebasis Das num_dbr_ring_caps); 473285561b9SDebasis Das 474285561b9SDebasis Das if (!info->dbr_ring_cap) 475285561b9SDebasis Das return -EINVAL; 476285561b9SDebasis Das 477285561b9SDebasis Das for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) { 478285561b9SDebasis Das param = &info->dbr_ring_cap[cap_idx]; 479285561b9SDebasis Das status = wmi_extract_dbr_ring_cap_service_ready_ext2(handle, 480285561b9SDebasis Das event, 481285561b9SDebasis Das cap_idx, 482285561b9SDebasis Das param); 483285561b9SDebasis Das if (QDF_IS_STATUS_ERROR(status)) { 484285561b9SDebasis Das target_if_err("Extraction of DMA cap failed"); 485285561b9SDebasis Das goto free_and_return; 486285561b9SDebasis Das } 487285561b9SDebasis Das } 488285561b9SDebasis Das 489285561b9SDebasis Das return 0; 490285561b9SDebasis Das 491285561b9SDebasis Das free_and_return: 492285561b9SDebasis Das qdf_mem_free(info->dbr_ring_cap); 493285561b9SDebasis Das info->dbr_ring_cap = NULL; 494285561b9SDebasis Das 495285561b9SDebasis Das return qdf_status_to_os_return(status); 496285561b9SDebasis Das } 497ac0ddecbSEdayilliam Jayadev int init_deinit_populate_spectral_bin_scale_params( 498453eea49SHimanshu Batra struct wlan_objmgr_psoc *psoc, wmi_unified_t handle, 499ac0ddecbSEdayilliam Jayadev uint8_t *event, struct tgt_info *info) 500ac0ddecbSEdayilliam Jayadev 501ac0ddecbSEdayilliam Jayadev { 502ac0ddecbSEdayilliam Jayadev uint8_t param_idx; 503ac0ddecbSEdayilliam Jayadev uint32_t num_bin_scaling_params; 504ac0ddecbSEdayilliam Jayadev QDF_STATUS status = QDF_STATUS_SUCCESS; 505ac0ddecbSEdayilliam Jayadev 506ac0ddecbSEdayilliam Jayadev num_bin_scaling_params = info->service_ext_param.num_bin_scaling_params; 507ac0ddecbSEdayilliam Jayadev 508ac0ddecbSEdayilliam Jayadev if (!num_bin_scaling_params) 509ac0ddecbSEdayilliam Jayadev return 0; 510ac0ddecbSEdayilliam Jayadev 511ac0ddecbSEdayilliam Jayadev info->scaling_params = qdf_mem_malloc( 512ac0ddecbSEdayilliam Jayadev sizeof(struct wlan_psoc_host_spectral_scaling_params) * 513ac0ddecbSEdayilliam Jayadev num_bin_scaling_params); 514ac0ddecbSEdayilliam Jayadev 515ac0ddecbSEdayilliam Jayadev if (!info->scaling_params) { 516ac0ddecbSEdayilliam Jayadev target_if_err("Mem alloc for bin scaling params failed"); 517ac0ddecbSEdayilliam Jayadev return -EINVAL; 518ac0ddecbSEdayilliam Jayadev } 519ac0ddecbSEdayilliam Jayadev 520ac0ddecbSEdayilliam Jayadev for (param_idx = 0; param_idx < num_bin_scaling_params; param_idx++) { 521ac0ddecbSEdayilliam Jayadev status = wmi_extract_spectral_scaling_params_service_ready_ext( 522ac0ddecbSEdayilliam Jayadev handle, 523ac0ddecbSEdayilliam Jayadev event, param_idx, 524ac0ddecbSEdayilliam Jayadev &info->scaling_params[param_idx]); 525ac0ddecbSEdayilliam Jayadev if (QDF_IS_STATUS_ERROR(status)) { 526ac0ddecbSEdayilliam Jayadev target_if_err("Extraction of scaling params failed"); 527ac0ddecbSEdayilliam Jayadev goto free_and_return; 528ac0ddecbSEdayilliam Jayadev } 529ac0ddecbSEdayilliam Jayadev } 530ac0ddecbSEdayilliam Jayadev 531ac0ddecbSEdayilliam Jayadev return 0; 532ac0ddecbSEdayilliam Jayadev 533ac0ddecbSEdayilliam Jayadev free_and_return: 534ac0ddecbSEdayilliam Jayadev qdf_mem_free(info->scaling_params); 535ac0ddecbSEdayilliam Jayadev info->scaling_params = NULL; 536ac0ddecbSEdayilliam Jayadev 537ac0ddecbSEdayilliam Jayadev return qdf_status_to_os_return(status); 538ac0ddecbSEdayilliam Jayadev } 539ac0ddecbSEdayilliam Jayadev 54043c413bcSJyoti Kumari #ifdef WLAN_SUPPORT_TWT 54143c413bcSJyoti Kumari int init_deinit_populate_twt_cap_ext2(struct wlan_objmgr_psoc *psoc, 54243c413bcSJyoti Kumari wmi_unified_t handle, uint8_t *event, 54343c413bcSJyoti Kumari struct tgt_info *info) 54443c413bcSJyoti Kumari { 54543c413bcSJyoti Kumari struct wmi_twt_cap_bitmap_params param; 54643c413bcSJyoti Kumari struct target_psoc_info *psoc_info; 54743c413bcSJyoti Kumari QDF_STATUS status = QDF_STATUS_SUCCESS; 54843c413bcSJyoti Kumari 54943c413bcSJyoti Kumari status = wmi_extract_twt_cap_service_ready_ext2(handle, event, 55043c413bcSJyoti Kumari ¶m); 55143c413bcSJyoti Kumari if (QDF_IS_STATUS_ERROR(status)) { 55243c413bcSJyoti Kumari target_if_err("Extraction of twt capability failed"); 55343c413bcSJyoti Kumari goto exit; 55443c413bcSJyoti Kumari } 55543c413bcSJyoti Kumari 55643c413bcSJyoti Kumari psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 55743c413bcSJyoti Kumari 55843c413bcSJyoti Kumari target_psoc_set_twt_ack_cap(psoc_info, param.twt_ack_support_cap); 55943c413bcSJyoti Kumari 56043c413bcSJyoti Kumari exit: 56143c413bcSJyoti Kumari return qdf_status_to_os_return(status); 56243c413bcSJyoti Kumari } 56343c413bcSJyoti Kumari #endif 56443c413bcSJyoti Kumari 5656828824cSShwetha G K #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 5666828824cSShwetha G K int init_deinit_populate_rcc_aoa_cap_ext2(struct wlan_objmgr_psoc *psoc, 5676828824cSShwetha G K wmi_unified_t handle, 5686828824cSShwetha G K uint8_t *event, 5696828824cSShwetha G K struct tgt_info *info) 5706828824cSShwetha G K { 5716828824cSShwetha G K QDF_STATUS status = QDF_STATUS_E_FAILURE; 5726828824cSShwetha G K 5736828824cSShwetha G K info->aoa_caps = qdf_mem_malloc( 5746828824cSShwetha G K sizeof(struct wlan_psoc_host_rcc_enh_aoa_caps_ext2)); 5756828824cSShwetha G K 5766828824cSShwetha G K if (!info->aoa_caps) { 5776828824cSShwetha G K target_if_err("Mem alloc for aoa cap failed"); 5786828824cSShwetha G K return -EINVAL; 5796828824cSShwetha G K } 5806828824cSShwetha G K 5816828824cSShwetha G K status = wmi_extract_aoa_caps_service_ready_ext2( 5826828824cSShwetha G K handle, event, 5836828824cSShwetha G K info->aoa_caps); 5846828824cSShwetha G K 5856828824cSShwetha G K if (QDF_IS_STATUS_ERROR(status)) { 5866828824cSShwetha G K target_if_err("Extraction of aoa caps failed"); 5876828824cSShwetha G K goto free_and_return; 5886828824cSShwetha G K } 5896828824cSShwetha G K 5906828824cSShwetha G K return 0; 5916828824cSShwetha G K 5926828824cSShwetha G K free_and_return: 5936828824cSShwetha G K qdf_mem_free(info->aoa_caps); 5946828824cSShwetha G K info->aoa_caps = NULL; 5956828824cSShwetha G K 5966828824cSShwetha G K return qdf_status_to_os_return(status); 5976828824cSShwetha G K } 5986828824cSShwetha G K 5996828824cSShwetha G K QDF_STATUS init_deinit_rcc_aoa_cap_ext2_free( 6006828824cSShwetha G K struct target_psoc_info *tgt_psoc_info) 6016828824cSShwetha G K { 6026828824cSShwetha G K qdf_mem_free(tgt_psoc_info->info.aoa_caps); 6036828824cSShwetha G K tgt_psoc_info->info.aoa_caps = NULL; 6046828824cSShwetha G K 6056828824cSShwetha G K return QDF_STATUS_SUCCESS; 6066828824cSShwetha G K } 6076828824cSShwetha G K #else 6086828824cSShwetha G K int init_deinit_populate_rcc_aoa_cap_ext2(struct wlan_objmgr_psoc *psoc, 6096828824cSShwetha G K wmi_unified_t handle, 6106828824cSShwetha G K uint8_t *event, 6116828824cSShwetha G K struct tgt_info *info) 6126828824cSShwetha G K { 6136828824cSShwetha G K return 0; 6146828824cSShwetha G K } 6156828824cSShwetha G K 6166828824cSShwetha G K QDF_STATUS init_deinit_rcc_aoa_cap_ext2_free( 6176828824cSShwetha G K struct target_psoc_info *tgt_psoc_info) 6186828824cSShwetha G K { 6196828824cSShwetha G K return QDF_STATUS_SUCCESS; 6206828824cSShwetha G K } 6216828824cSShwetha G K #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 6226828824cSShwetha G K 6236828824cSShwetha G K qdf_export_symbol(init_deinit_rcc_aoa_cap_ext2_free); 6246828824cSShwetha G K 6258d1f8d1bSUtkarsh Bhatnagar int init_deinit_populate_dbs_or_sbs_cap_ext2(struct wlan_objmgr_psoc *psoc, 6268d1f8d1bSUtkarsh Bhatnagar wmi_unified_t handle, 6278d1f8d1bSUtkarsh Bhatnagar uint8_t *event, 6288d1f8d1bSUtkarsh Bhatnagar struct tgt_info *info) 6298d1f8d1bSUtkarsh Bhatnagar { 6308d1f8d1bSUtkarsh Bhatnagar uint32_t sbs_lower_band_end_freq; 6318d1f8d1bSUtkarsh Bhatnagar struct target_psoc_info *psoc_info; 6328d1f8d1bSUtkarsh Bhatnagar QDF_STATUS status = QDF_STATUS_SUCCESS; 6338d1f8d1bSUtkarsh Bhatnagar 6348d1f8d1bSUtkarsh Bhatnagar status = wmi_extract_dbs_or_sbs_cap_service_ready_ext2(handle, event, 6358d1f8d1bSUtkarsh Bhatnagar &sbs_lower_band_end_freq); 6368d1f8d1bSUtkarsh Bhatnagar if (QDF_IS_STATUS_ERROR(status)) { 6378d1f8d1bSUtkarsh Bhatnagar target_if_err("Extraction of twt capability failed"); 6388d1f8d1bSUtkarsh Bhatnagar goto exit; 6398d1f8d1bSUtkarsh Bhatnagar } 6408d1f8d1bSUtkarsh Bhatnagar psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 6418d1f8d1bSUtkarsh Bhatnagar target_psoc_set_sbs_lower_band_end(psoc_info, sbs_lower_band_end_freq); 6428d1f8d1bSUtkarsh Bhatnagar 6438d1f8d1bSUtkarsh Bhatnagar exit: 6448d1f8d1bSUtkarsh Bhatnagar return qdf_status_to_os_return(status); 6458d1f8d1bSUtkarsh Bhatnagar } 6468d1f8d1bSUtkarsh Bhatnagar 6478380ebafSSrinivas Dasari int init_deinit_populate_sap_coex_capability(struct wlan_objmgr_psoc *psoc, 6488380ebafSSrinivas Dasari wmi_unified_t handle, 6498380ebafSSrinivas Dasari uint8_t *event) 6508380ebafSSrinivas Dasari { 6518380ebafSSrinivas Dasari struct wmi_host_coex_fix_chan_cap sap_coex_fixed_chan_cap; 6528380ebafSSrinivas Dasari struct target_psoc_info *psoc_info; 6538380ebafSSrinivas Dasari QDF_STATUS status; 6548380ebafSSrinivas Dasari 6558380ebafSSrinivas Dasari qdf_mem_zero(&sap_coex_fixed_chan_cap, 6568380ebafSSrinivas Dasari sizeof(struct wmi_host_coex_fix_chan_cap)); 6578380ebafSSrinivas Dasari 6588380ebafSSrinivas Dasari status = wmi_extract_sap_coex_cap_service_ready_ext2(handle, event, 6598380ebafSSrinivas Dasari &sap_coex_fixed_chan_cap); 6608380ebafSSrinivas Dasari if (QDF_IS_STATUS_ERROR(status)) { 6618380ebafSSrinivas Dasari target_if_err("Extraction of sap_coex_chan_pref cap failed"); 6628380ebafSSrinivas Dasari goto exit; 6638380ebafSSrinivas Dasari } 6648380ebafSSrinivas Dasari psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 6658380ebafSSrinivas Dasari target_psoc_set_sap_coex_fixed_chan_cap(psoc_info, 6668380ebafSSrinivas Dasari !!sap_coex_fixed_chan_cap.fix_chan_priority); 6678380ebafSSrinivas Dasari exit: 6688380ebafSSrinivas Dasari return qdf_status_to_os_return(status); 6698380ebafSSrinivas Dasari } 6708d1f8d1bSUtkarsh Bhatnagar 671f8d1f8acSjingxiang ge int init_deinit_populate_aux_dev_cap_ext2(struct wlan_objmgr_psoc *psoc, 672f8d1f8acSjingxiang ge wmi_unified_t handle, uint8_t *event, 673f8d1f8acSjingxiang ge struct tgt_info *info) 674f8d1f8acSjingxiang ge 675f8d1f8acSjingxiang ge { 676f8d1f8acSjingxiang ge uint8_t cap_idx; 677f8d1f8acSjingxiang ge uint32_t num_aux_dev_caps; 678f8d1f8acSjingxiang ge QDF_STATUS status = QDF_STATUS_SUCCESS; 679f8d1f8acSjingxiang ge struct wlan_psoc_host_aux_dev_caps *param; 680f8d1f8acSjingxiang ge 681f8d1f8acSjingxiang ge num_aux_dev_caps = info->service_ext2_param.num_aux_dev_caps; 682f8d1f8acSjingxiang ge target_if_info("num_aux_dev_caps = %d", num_aux_dev_caps); 683f8d1f8acSjingxiang ge 684f8d1f8acSjingxiang ge if (!num_aux_dev_caps) 685f8d1f8acSjingxiang ge return 0; 686f8d1f8acSjingxiang ge 687f8d1f8acSjingxiang ge info->aux_dev_caps = 688f8d1f8acSjingxiang ge qdf_mem_malloc(sizeof(struct wlan_psoc_host_aux_dev_caps) * 689f8d1f8acSjingxiang ge num_aux_dev_caps); 690f8d1f8acSjingxiang ge 691f8d1f8acSjingxiang ge if (!info->aux_dev_caps) 692f8d1f8acSjingxiang ge return -EINVAL; 693f8d1f8acSjingxiang ge 694f8d1f8acSjingxiang ge for (cap_idx = 0; cap_idx < num_aux_dev_caps; cap_idx++) { 695f8d1f8acSjingxiang ge param = &info->aux_dev_caps[cap_idx]; 696f8d1f8acSjingxiang ge status = wmi_extract_aux_dev_cap_service_ready_ext2(handle, 697f8d1f8acSjingxiang ge event, 698f8d1f8acSjingxiang ge cap_idx, 699f8d1f8acSjingxiang ge param); 700f8d1f8acSjingxiang ge if (QDF_IS_STATUS_ERROR(status)) { 701f8d1f8acSjingxiang ge target_if_err("Extraction of aux dev cap failed"); 702f8d1f8acSjingxiang ge goto free_and_return; 703f8d1f8acSjingxiang ge } 704f8d1f8acSjingxiang ge } 705f8d1f8acSjingxiang ge 706f8d1f8acSjingxiang ge return 0; 707f8d1f8acSjingxiang ge 708f8d1f8acSjingxiang ge free_and_return: 709f8d1f8acSjingxiang ge qdf_mem_free(info->aux_dev_caps); 710f8d1f8acSjingxiang ge info->aux_dev_caps = NULL; 711f8d1f8acSjingxiang ge /* Set to 0 in case some code later rely on that */ 712f8d1f8acSjingxiang ge info->service_ext2_param.num_aux_dev_caps = 0; 713f8d1f8acSjingxiang ge 714f8d1f8acSjingxiang ge return qdf_status_to_os_return(status); 715f8d1f8acSjingxiang ge } 716f8d1f8acSjingxiang ge 71777f3c438SSathish Kumar QDF_STATUS init_deinit_dbr_ring_cap_free( 71877f3c438SSathish Kumar struct target_psoc_info *tgt_psoc_info) 71977f3c438SSathish Kumar { 72077f3c438SSathish Kumar QDF_STATUS status = QDF_STATUS_SUCCESS; 72177f3c438SSathish Kumar 72277f3c438SSathish Kumar if (tgt_psoc_info->info.dbr_ring_cap) { 72377f3c438SSathish Kumar qdf_mem_free(tgt_psoc_info->info.dbr_ring_cap); 72477f3c438SSathish Kumar tgt_psoc_info->info.dbr_ring_cap = NULL; 72577f3c438SSathish Kumar } 72677f3c438SSathish Kumar 72777f3c438SSathish Kumar return status; 72877f3c438SSathish Kumar } 72977f3c438SSathish Kumar qdf_export_symbol(init_deinit_dbr_ring_cap_free); 73077f3c438SSathish Kumar 731ac0ddecbSEdayilliam Jayadev QDF_STATUS init_deinit_spectral_scaling_params_free( 732ac0ddecbSEdayilliam Jayadev struct target_psoc_info *tgt_psoc_info) 733ac0ddecbSEdayilliam Jayadev { 734ac0ddecbSEdayilliam Jayadev QDF_STATUS status = QDF_STATUS_E_FAILURE; 735ac0ddecbSEdayilliam Jayadev 736ac0ddecbSEdayilliam Jayadev if (tgt_psoc_info->info.scaling_params) { 737ac0ddecbSEdayilliam Jayadev qdf_mem_free(tgt_psoc_info->info.scaling_params); 738ac0ddecbSEdayilliam Jayadev tgt_psoc_info->info.scaling_params = NULL; 739ac0ddecbSEdayilliam Jayadev status = QDF_STATUS_SUCCESS; 740ac0ddecbSEdayilliam Jayadev } 741ac0ddecbSEdayilliam Jayadev 742ac0ddecbSEdayilliam Jayadev return status; 743ac0ddecbSEdayilliam Jayadev } 744ac0ddecbSEdayilliam Jayadev 745ac0ddecbSEdayilliam Jayadev qdf_export_symbol(init_deinit_spectral_scaling_params_free); 746ac0ddecbSEdayilliam Jayadev 747f8d1f8acSjingxiang ge QDF_STATUS init_deinit_aux_dev_cap_free( 748f8d1f8acSjingxiang ge struct target_psoc_info *tgt_psoc_info) 749f8d1f8acSjingxiang ge { 750f8d1f8acSjingxiang ge QDF_STATUS status = QDF_STATUS_SUCCESS; 751f8d1f8acSjingxiang ge 752f8d1f8acSjingxiang ge if (tgt_psoc_info->info.aux_dev_caps) { 753f8d1f8acSjingxiang ge qdf_mem_free(tgt_psoc_info->info.aux_dev_caps); 754f8d1f8acSjingxiang ge tgt_psoc_info->info.aux_dev_caps = NULL; 755f8d1f8acSjingxiang ge } 756f8d1f8acSjingxiang ge 757f8d1f8acSjingxiang ge return status; 758f8d1f8acSjingxiang ge } 759f8d1f8acSjingxiang ge 76091005b0bSGyanranjan Hazarika #ifdef DBS_SBS_BAND_LIMITATION_WAR 76191005b0bSGyanranjan Hazarika #define phy0 0 76291005b0bSGyanranjan Hazarika #define phy2 2 76391005b0bSGyanranjan Hazarika #define NUM_RF_MODES 2 /* (DBS + DBS_SBS) */ 76491005b0bSGyanranjan Hazarika /** 76591005b0bSGyanranjan Hazarika * init_deinit_update_phy_reg_cap() - Update the low/high frequency for phy0. 76691005b0bSGyanranjan Hazarika * @psoc: PSOC common object 76791005b0bSGyanranjan Hazarika * @info: FW or lower layer related info 768045d6e4eSJeff Johnson * @reg_cap: Reg caps per PHY 76991005b0bSGyanranjan Hazarika * 77091005b0bSGyanranjan Hazarika * For the DBS_SBS capable board, update the low or high frequency 77191005b0bSGyanranjan Hazarika * for phy0 by leveraging the frequency populated for phy2 77291005b0bSGyanranjan Hazarika * depending on whether it is mapped to upper or lower 5G band by 77391005b0bSGyanranjan Hazarika * FW/HAL-PHY. 77491005b0bSGyanranjan Hazarika */ 77591005b0bSGyanranjan Hazarika static void init_deinit_update_phy_reg_cap(struct wlan_objmgr_psoc *psoc, 77691005b0bSGyanranjan Hazarika struct tgt_info *info, 77791005b0bSGyanranjan Hazarika struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap) 77891005b0bSGyanranjan Hazarika { 77991005b0bSGyanranjan Hazarika struct target_psoc_info *tgt_hdl; 78091005b0bSGyanranjan Hazarika enum wmi_host_hw_mode_config_type mode; 78184f2effdSShashikala Prabhu uint32_t num_hw_modes; 78284f2effdSShashikala Prabhu uint8_t idx; 78391005b0bSGyanranjan Hazarika 78491005b0bSGyanranjan Hazarika tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle( 78591005b0bSGyanranjan Hazarika psoc); 78691005b0bSGyanranjan Hazarika if (!tgt_hdl) { 78791005b0bSGyanranjan Hazarika target_if_err("target_psoc_info is null in service ready ev"); 78891005b0bSGyanranjan Hazarika return; 78991005b0bSGyanranjan Hazarika } 79091005b0bSGyanranjan Hazarika 79191005b0bSGyanranjan Hazarika mode = target_psoc_get_preferred_hw_mode(tgt_hdl); 79291005b0bSGyanranjan Hazarika 79384f2effdSShashikala Prabhu num_hw_modes = info->hw_modes.num_modes; 79491005b0bSGyanranjan Hazarika 79584f2effdSShashikala Prabhu if ((mode != WMI_HOST_HW_MODE_DBS) || (num_hw_modes < NUM_RF_MODES)) 79684f2effdSShashikala Prabhu return; 79784f2effdSShashikala Prabhu 79884f2effdSShashikala Prabhu for (idx = 0; idx < num_hw_modes; idx++) 79984f2effdSShashikala Prabhu if (info->hw_modes.hw_mode_ids[idx] == 80084f2effdSShashikala Prabhu WMI_HOST_HW_MODE_DBS_SBS) { 80184f2effdSShashikala Prabhu if (reg_cap[phy0].low_5ghz_chan > 80284f2effdSShashikala Prabhu reg_cap[phy2].low_5ghz_chan) 80384f2effdSShashikala Prabhu reg_cap[phy0].low_5ghz_chan = 80484f2effdSShashikala Prabhu reg_cap[phy2].low_5ghz_chan; 80584f2effdSShashikala Prabhu else if (reg_cap[phy0].high_5ghz_chan < 80684f2effdSShashikala Prabhu reg_cap[phy2].high_5ghz_chan) 80784f2effdSShashikala Prabhu reg_cap[phy0].high_5ghz_chan = 80884f2effdSShashikala Prabhu reg_cap[phy2].high_5ghz_chan; 80984f2effdSShashikala Prabhu break; 81084f2effdSShashikala Prabhu } 81191005b0bSGyanranjan Hazarika } 81291005b0bSGyanranjan Hazarika #else 81391005b0bSGyanranjan Hazarika static void init_deinit_update_phy_reg_cap(struct wlan_objmgr_psoc *psoc, 81491005b0bSGyanranjan Hazarika struct tgt_info *info, 81591005b0bSGyanranjan Hazarika struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap) 81691005b0bSGyanranjan Hazarika { 81791005b0bSGyanranjan Hazarika } 81891005b0bSGyanranjan Hazarika #endif 81991005b0bSGyanranjan Hazarika 820ca3471eeSPriyadarshnee Srinivasan /** 821ca3471eeSPriyadarshnee Srinivasan * init_deinit_fill_host_reg_cap() - Fill the host regulatory cap 822ca3471eeSPriyadarshnee Srinivasan * with target hal reg capabilities. 823ca3471eeSPriyadarshnee Srinivasan * @cap: Pointer to wlan_psoc_hal_reg_capability where FW capabilities 824ca3471eeSPriyadarshnee Srinivasan * are extracted. 825ca3471eeSPriyadarshnee Srinivasan * @reg_cap: Pointer to wlan_psoc_host_hal_reg_capabilities_ext, host reg 826ca3471eeSPriyadarshnee Srinivasan * capabilities to be filled. 827ca3471eeSPriyadarshnee Srinivasan * 828ca3471eeSPriyadarshnee Srinivasan * Return - None 829ca3471eeSPriyadarshnee Srinivasan */ 830ca3471eeSPriyadarshnee Srinivasan static void 831ca3471eeSPriyadarshnee Srinivasan init_deinit_fill_host_reg_cap(struct wlan_psoc_hal_reg_capability *cap, 832ca3471eeSPriyadarshnee Srinivasan struct wlan_psoc_host_hal_reg_capabilities_ext 833ca3471eeSPriyadarshnee Srinivasan *reg_cap) 834ca3471eeSPriyadarshnee Srinivasan { 835ca3471eeSPriyadarshnee Srinivasan reg_cap->phy_id = 0; 836ca3471eeSPriyadarshnee Srinivasan reg_cap->eeprom_reg_domain = cap->eeprom_rd; 837ca3471eeSPriyadarshnee Srinivasan reg_cap->eeprom_reg_domain_ext = cap->eeprom_rd_ext; 838ca3471eeSPriyadarshnee Srinivasan reg_cap->regcap1 = cap->regcap1; 839ca3471eeSPriyadarshnee Srinivasan reg_cap->regcap2 = cap->regcap2; 840ca3471eeSPriyadarshnee Srinivasan reg_cap->wireless_modes = (uint64_t)cap->wireless_modes; 841ca3471eeSPriyadarshnee Srinivasan reg_cap->low_2ghz_chan = cap->low_2ghz_chan; 842ca3471eeSPriyadarshnee Srinivasan reg_cap->high_2ghz_chan = cap->high_2ghz_chan; 843ca3471eeSPriyadarshnee Srinivasan reg_cap->low_5ghz_chan = cap->low_5ghz_chan; 844ca3471eeSPriyadarshnee Srinivasan reg_cap->high_5ghz_chan = cap->high_5ghz_chan; 845ca3471eeSPriyadarshnee Srinivasan } 846ca3471eeSPriyadarshnee Srinivasan 847b9322f12SManoj Ekbote static void 848b9322f12SManoj Ekbote init_deinit_populate_tgt_ext_param(struct tgt_info *info, 849b9322f12SManoj Ekbote struct wlan_psoc_host_hal_reg_capabilities_ext *cap) 850b9322f12SManoj Ekbote { 851b9322f12SManoj Ekbote struct wlan_psoc_host_service_ext_param *ext_param; 852b9322f12SManoj Ekbote 853b9322f12SManoj Ekbote ext_param = &info->service_ext_param; 854b9322f12SManoj Ekbote ext_param->wireless_modes = cap->wireless_modes; 855b9322f12SManoj Ekbote ext_param->low_2ghz_chan = cap->low_2ghz_chan; 856b9322f12SManoj Ekbote ext_param->high_2ghz_chan = cap->high_2ghz_chan; 857b9322f12SManoj Ekbote ext_param->low_5ghz_chan = cap->low_5ghz_chan; 858b9322f12SManoj Ekbote ext_param->high_5ghz_chan = cap->high_5ghz_chan; 859b9322f12SManoj Ekbote } 860b9322f12SManoj Ekbote 861b9322f12SManoj Ekbote static void 862b9322f12SManoj Ekbote init_deinit_populate_tgt_ext2_param(struct tgt_info *info, 863b9322f12SManoj Ekbote struct wlan_psoc_host_hal_reg_capabilities_ext2 *cap) 864b9322f12SManoj Ekbote { 865b9322f12SManoj Ekbote struct wlan_psoc_host_service_ext2_param *ext2_param; 866b9322f12SManoj Ekbote 867b9322f12SManoj Ekbote ext2_param = &info->service_ext2_param; 868b9322f12SManoj Ekbote ext2_param->wireless_modes_ext = cap->wireless_modes_ext; 869b9322f12SManoj Ekbote ext2_param->low_2ghz_chan_ext = cap->low_2ghz_chan_ext; 870b9322f12SManoj Ekbote ext2_param->high_2ghz_chan_ext = cap->high_2ghz_chan_ext; 871b9322f12SManoj Ekbote ext2_param->low_5ghz_chan_ext = cap->low_5ghz_chan_ext; 872b9322f12SManoj Ekbote ext2_param->high_5ghz_chan_ext = cap->high_5ghz_chan_ext; 873b9322f12SManoj Ekbote } 874b9322f12SManoj Ekbote 875cc75651cSSrinivas Pitla int init_deinit_populate_phy_reg_cap(struct wlan_objmgr_psoc *psoc, 87629bc9919SHimanshu Batra wmi_unified_t handle, uint8_t *event, 87729bc9919SHimanshu Batra struct tgt_info *info, 87829bc9919SHimanshu Batra bool service_ready) 879cc75651cSSrinivas Pitla { 880cc75651cSSrinivas Pitla uint8_t reg_idx; 881cc75651cSSrinivas Pitla uint32_t num_phy_reg_cap; 882cc75651cSSrinivas Pitla QDF_STATUS status = QDF_STATUS_SUCCESS; 883cc75651cSSrinivas Pitla struct wlan_psoc_hal_reg_capability cap; 884cc75651cSSrinivas Pitla struct wlan_psoc_host_hal_reg_capabilities_ext 8855539b45bSTushnim Bhattacharyya reg_cap[PSOC_MAX_PHY_REG_CAP] = {{0} }; 886cc75651cSSrinivas Pitla 887cc75651cSSrinivas Pitla if (service_ready) { 888cc75651cSSrinivas Pitla status = wmi_extract_hal_reg_cap(handle, event, &cap); 889cc75651cSSrinivas Pitla if (QDF_IS_STATUS_ERROR(status)) { 890cc75651cSSrinivas Pitla target_if_err("failed to parse hal reg cap"); 891cc75651cSSrinivas Pitla return qdf_status_to_os_return(status); 892cc75651cSSrinivas Pitla } 893cc75651cSSrinivas Pitla info->service_ext_param.num_phy = 1; 894cc75651cSSrinivas Pitla num_phy_reg_cap = 1; 895ca3471eeSPriyadarshnee Srinivasan init_deinit_fill_host_reg_cap(&cap, ®_cap[0]); 896b9322f12SManoj Ekbote init_deinit_populate_tgt_ext_param(info, ®_cap[0]); 897ca3471eeSPriyadarshnee Srinivasan target_if_debug("FW wireless modes 0x%llx", 898cc75651cSSrinivas Pitla reg_cap[0].wireless_modes); 899cc75651cSSrinivas Pitla } else { 900cc75651cSSrinivas Pitla num_phy_reg_cap = info->service_ext_param.num_phy; 901cc75651cSSrinivas Pitla if (num_phy_reg_cap > PSOC_MAX_PHY_REG_CAP) { 902cc75651cSSrinivas Pitla target_if_err("Invalid num_phy_reg_cap %d", 903cc75651cSSrinivas Pitla num_phy_reg_cap); 904cc75651cSSrinivas Pitla return -EINVAL; 905cc75651cSSrinivas Pitla } 9063fc809d6SDustin Brown target_if_debug("num_phy_reg_cap %d", num_phy_reg_cap); 907cc75651cSSrinivas Pitla 908cc75651cSSrinivas Pitla for (reg_idx = 0; reg_idx < num_phy_reg_cap; reg_idx++) { 909cc75651cSSrinivas Pitla status = wmi_extract_reg_cap_service_ready_ext(handle, 910cc75651cSSrinivas Pitla event, reg_idx, &(reg_cap[reg_idx])); 911cc75651cSSrinivas Pitla if (QDF_IS_STATUS_ERROR(status)) { 912cc75651cSSrinivas Pitla target_if_err("failed to parse reg cap"); 913cc75651cSSrinivas Pitla return qdf_status_to_os_return(status); 914cc75651cSSrinivas Pitla } 915cc75651cSSrinivas Pitla } 916cc75651cSSrinivas Pitla } 917cc75651cSSrinivas Pitla 91891005b0bSGyanranjan Hazarika init_deinit_update_phy_reg_cap(psoc, info, reg_cap); 919cc75651cSSrinivas Pitla status = ucfg_reg_set_hal_reg_cap(psoc, reg_cap, num_phy_reg_cap); 920cc75651cSSrinivas Pitla 921cc75651cSSrinivas Pitla return qdf_status_to_os_return(status); 922cc75651cSSrinivas Pitla } 923cc75651cSSrinivas Pitla 924a76f88adSShashikala Prabhu int init_deinit_populate_mac_phy_cap_ext2(wmi_unified_t wmi_handle, 925a76f88adSShashikala Prabhu uint8_t *event, 926a76f88adSShashikala Prabhu struct tgt_info *info) 927a76f88adSShashikala Prabhu { 928a76f88adSShashikala Prabhu uint32_t num_hw_modes; 929a76f88adSShashikala Prabhu uint8_t hw_idx; 930a76f88adSShashikala Prabhu uint32_t hw_mode_id; 931a76f88adSShashikala Prabhu uint32_t phy_bit_map; 932a76f88adSShashikala Prabhu uint8_t phy_id; 933a76f88adSShashikala Prabhu uint8_t mac_phy_count = 0; 934a76f88adSShashikala Prabhu QDF_STATUS status = QDF_STATUS_SUCCESS; 935a76f88adSShashikala Prabhu struct wlan_psoc_host_mac_phy_caps *mac_phy_cap; 93611f4850bSVenkateswara Swamy Bandaru struct wlan_psoc_host_mac_phy_caps_ext2 *mac_phy_caps_ext2; 937a76f88adSShashikala Prabhu 938a76f88adSShashikala Prabhu if (!event) 939a76f88adSShashikala Prabhu return -EINVAL; 940a76f88adSShashikala Prabhu 941a76f88adSShashikala Prabhu num_hw_modes = info->hw_modes.num_modes; 942a76f88adSShashikala Prabhu 943a76f88adSShashikala Prabhu for (hw_idx = 0; hw_idx < num_hw_modes; hw_idx++) { 944a76f88adSShashikala Prabhu hw_mode_id = info->hw_modes.hw_mode_ids[hw_idx]; 945a76f88adSShashikala Prabhu phy_bit_map = info->hw_modes.phy_bit_map[hw_idx]; 946a76f88adSShashikala Prabhu 947a76f88adSShashikala Prabhu phy_id = info->mac_phy_cap[mac_phy_count].phy_id; 948a76f88adSShashikala Prabhu while (phy_bit_map) { 949a76f88adSShashikala Prabhu if (mac_phy_count >= info->total_mac_phy_cnt) { 950a76f88adSShashikala Prabhu target_if_err("total MAC PHY count exceeds max limit %d, mac_phy_count = %d", 951a76f88adSShashikala Prabhu info->total_mac_phy_cnt, 952a76f88adSShashikala Prabhu mac_phy_count); 953a76f88adSShashikala Prabhu return -EINVAL; 954a76f88adSShashikala Prabhu } 955a76f88adSShashikala Prabhu 956a76f88adSShashikala Prabhu mac_phy_cap = &info->mac_phy_cap[mac_phy_count]; 95711f4850bSVenkateswara Swamy Bandaru mac_phy_caps_ext2 = 95811f4850bSVenkateswara Swamy Bandaru &info->mac_phy_caps_ext2[mac_phy_count]; 959a76f88adSShashikala Prabhu status = wmi_extract_mac_phy_cap_service_ready_ext2( 960a76f88adSShashikala Prabhu wmi_handle, event, hw_mode_id, phy_id, 961a76f88adSShashikala Prabhu mac_phy_cap->phy_idx, 96211f4850bSVenkateswara Swamy Bandaru mac_phy_caps_ext2); 963a76f88adSShashikala Prabhu 964a76f88adSShashikala Prabhu if (QDF_IS_STATUS_ERROR(status)) { 965a76f88adSShashikala Prabhu target_if_err("failed to parse mac phy capability ext2"); 966a76f88adSShashikala Prabhu return qdf_status_to_os_return(status); 967a76f88adSShashikala Prabhu } 968a76f88adSShashikala Prabhu 969a76f88adSShashikala Prabhu mac_phy_cap->reg_cap_ext.wireless_modes |= 970a76f88adSShashikala Prabhu mac_phy_caps_ext2[phy_id].wireless_modes_ext; 971a76f88adSShashikala Prabhu 972a76f88adSShashikala Prabhu mac_phy_count++; 973a76f88adSShashikala Prabhu phy_bit_map &= (phy_bit_map - 1); 974a76f88adSShashikala Prabhu phy_id++; 975a76f88adSShashikala Prabhu } 976a76f88adSShashikala Prabhu } 977a76f88adSShashikala Prabhu 978a76f88adSShashikala Prabhu return 0; 979a76f88adSShashikala Prabhu } 980a76f88adSShashikala Prabhu 981a76f88adSShashikala Prabhu int init_deinit_populate_hal_reg_cap_ext2(wmi_unified_t wmi_handle, 982a76f88adSShashikala Prabhu uint8_t *event, 983a76f88adSShashikala Prabhu struct tgt_info *info) 984a76f88adSShashikala Prabhu { 985a76f88adSShashikala Prabhu struct wlan_psoc_host_hal_reg_capabilities_ext2 986a76f88adSShashikala Prabhu reg_cap[PSOC_MAX_PHY_REG_CAP] = {{0} }; 987a76f88adSShashikala Prabhu struct wlan_objmgr_psoc *psoc; 988a76f88adSShashikala Prabhu uint32_t num_phy_reg_cap; 989a76f88adSShashikala Prabhu uint8_t reg_idx; 990a76f88adSShashikala Prabhu QDF_STATUS status = QDF_STATUS_SUCCESS; 991a76f88adSShashikala Prabhu 992a76f88adSShashikala Prabhu if (!event) { 993a76f88adSShashikala Prabhu target_if_err("event buffer is null"); 994a76f88adSShashikala Prabhu return -EINVAL; 995a76f88adSShashikala Prabhu } 996a76f88adSShashikala Prabhu 997a76f88adSShashikala Prabhu psoc = target_if_get_psoc_from_scn_hdl(wmi_handle->scn_handle); 998a76f88adSShashikala Prabhu if (!psoc) { 999a76f88adSShashikala Prabhu target_if_err("psoc is null"); 1000a76f88adSShashikala Prabhu return -EINVAL; 1001a76f88adSShashikala Prabhu } 1002a76f88adSShashikala Prabhu 1003a76f88adSShashikala Prabhu num_phy_reg_cap = info->service_ext_param.num_phy; 1004a76f88adSShashikala Prabhu if (num_phy_reg_cap > PSOC_MAX_PHY_REG_CAP) { 1005a76f88adSShashikala Prabhu target_if_err("Invalid num_phy_reg_cap %d", num_phy_reg_cap); 1006a76f88adSShashikala Prabhu return -EINVAL; 1007a76f88adSShashikala Prabhu } 1008a76f88adSShashikala Prabhu 1009a76f88adSShashikala Prabhu for (reg_idx = 0; reg_idx < num_phy_reg_cap; reg_idx++) { 1010a76f88adSShashikala Prabhu status = wmi_extract_hal_reg_cap_ext2( 1011a76f88adSShashikala Prabhu wmi_handle, event, reg_idx, ®_cap[reg_idx]); 1012a76f88adSShashikala Prabhu if (QDF_IS_STATUS_ERROR(status)) { 1013a76f88adSShashikala Prabhu target_if_err("failed to parse hal reg cap ext2"); 1014a76f88adSShashikala Prabhu return qdf_status_to_os_return(status); 1015a76f88adSShashikala Prabhu } 1016a76f88adSShashikala Prabhu 1017b9322f12SManoj Ekbote init_deinit_populate_tgt_ext2_param(info, ®_cap[reg_idx]); 1018b9322f12SManoj Ekbote status = ucfg_reg_update_hal_cap_wireless_modes(psoc, 1019b9322f12SManoj Ekbote reg_cap[reg_idx].wireless_modes_ext, 1020a76f88adSShashikala Prabhu reg_idx); 1021a76f88adSShashikala Prabhu if (QDF_IS_STATUS_ERROR(status)) { 1022a76f88adSShashikala Prabhu target_if_err("Failed to update hal reg cap"); 1023a76f88adSShashikala Prabhu return qdf_status_to_os_return(status); 1024a76f88adSShashikala Prabhu } 1025a76f88adSShashikala Prabhu } 1026a76f88adSShashikala Prabhu 1027a76f88adSShashikala Prabhu return 0; 1028a76f88adSShashikala Prabhu } 1029a76f88adSShashikala Prabhu 1030e0f284b0SEdayilliam Jayadev int init_deinit_populate_scan_radio_cap_ext2(wmi_unified_t wmi_handle, 1031e0f284b0SEdayilliam Jayadev uint8_t *event, 1032e0f284b0SEdayilliam Jayadev struct tgt_info *info) 1033e0f284b0SEdayilliam Jayadev { 1034e0f284b0SEdayilliam Jayadev struct wlan_psoc_host_scan_radio_caps *param; 1035e0f284b0SEdayilliam Jayadev uint32_t num_scan_radio_caps; 1036e0f284b0SEdayilliam Jayadev uint8_t cap_idx; 1037e0f284b0SEdayilliam Jayadev QDF_STATUS status; 1038e0f284b0SEdayilliam Jayadev 1039e0f284b0SEdayilliam Jayadev if (!event) { 1040e0f284b0SEdayilliam Jayadev target_if_err("Invalid event buffer"); 1041e0f284b0SEdayilliam Jayadev return -EINVAL; 1042e0f284b0SEdayilliam Jayadev } 1043e0f284b0SEdayilliam Jayadev 1044e0f284b0SEdayilliam Jayadev num_scan_radio_caps = info->service_ext2_param.num_scan_radio_caps; 1045e0f284b0SEdayilliam Jayadev target_if_debug("num scan radio capabilities = %d", 1046e0f284b0SEdayilliam Jayadev num_scan_radio_caps); 1047e0f284b0SEdayilliam Jayadev 1048e0f284b0SEdayilliam Jayadev if (!num_scan_radio_caps) 1049e0f284b0SEdayilliam Jayadev return 0; 1050e0f284b0SEdayilliam Jayadev 1051e0f284b0SEdayilliam Jayadev info->scan_radio_caps = qdf_mem_malloc( 1052e0f284b0SEdayilliam Jayadev sizeof(struct wlan_psoc_host_scan_radio_caps) * 1053e0f284b0SEdayilliam Jayadev num_scan_radio_caps); 1054e0f284b0SEdayilliam Jayadev 1055e0f284b0SEdayilliam Jayadev if (!info->scan_radio_caps) { 1056e0f284b0SEdayilliam Jayadev target_if_err("Failed to allocate memory for scan radio caps"); 1057e0f284b0SEdayilliam Jayadev return -EINVAL; 1058e0f284b0SEdayilliam Jayadev } 1059e0f284b0SEdayilliam Jayadev 1060e0f284b0SEdayilliam Jayadev for (cap_idx = 0; cap_idx < num_scan_radio_caps; cap_idx++) { 1061e0f284b0SEdayilliam Jayadev param = &info->scan_radio_caps[cap_idx]; 1062e0f284b0SEdayilliam Jayadev status = wmi_extract_scan_radio_cap_service_ready_ext2( 1063e0f284b0SEdayilliam Jayadev wmi_handle, event, cap_idx, param); 1064e0f284b0SEdayilliam Jayadev if (QDF_IS_STATUS_ERROR(status)) { 1065e0f284b0SEdayilliam Jayadev target_if_err("Extraction of scan radio cap failed"); 1066e0f284b0SEdayilliam Jayadev goto free_and_return; 1067e0f284b0SEdayilliam Jayadev } 1068e0f284b0SEdayilliam Jayadev } 1069e0f284b0SEdayilliam Jayadev 1070e0f284b0SEdayilliam Jayadev return 0; 1071e0f284b0SEdayilliam Jayadev 1072e0f284b0SEdayilliam Jayadev free_and_return: 1073e0f284b0SEdayilliam Jayadev qdf_mem_free(info->scan_radio_caps); 1074e0f284b0SEdayilliam Jayadev info->scan_radio_caps = NULL; 1075e0f284b0SEdayilliam Jayadev 1076e0f284b0SEdayilliam Jayadev return qdf_status_to_os_return(status); 1077e0f284b0SEdayilliam Jayadev } 1078e0f284b0SEdayilliam Jayadev 1079e0f284b0SEdayilliam Jayadev QDF_STATUS init_deinit_scan_radio_cap_free( 1080e0f284b0SEdayilliam Jayadev struct target_psoc_info *tgt_psoc_info) 1081e0f284b0SEdayilliam Jayadev { 1082e0f284b0SEdayilliam Jayadev qdf_mem_free(tgt_psoc_info->info.scan_radio_caps); 1083e0f284b0SEdayilliam Jayadev tgt_psoc_info->info.scan_radio_caps = NULL; 1084e0f284b0SEdayilliam Jayadev 1085e0f284b0SEdayilliam Jayadev return QDF_STATUS_SUCCESS; 1086e0f284b0SEdayilliam Jayadev } 1087e0f284b0SEdayilliam Jayadev 1088e0f284b0SEdayilliam Jayadev qdf_export_symbol(init_deinit_scan_radio_cap_free); 1089e0f284b0SEdayilliam Jayadev 1090a3697f6bSJinwei Chen int init_deinit_populate_msdu_idx_qtype_map_ext2(wmi_unified_t wmi_handle, 1091a3697f6bSJinwei Chen uint8_t *event, 1092a3697f6bSJinwei Chen struct tgt_info *info) 1093a3697f6bSJinwei Chen { 1094a3697f6bSJinwei Chen uint8_t *msdu_qtype; 1095a3697f6bSJinwei Chen uint32_t num_msdu_idx_qtype_map; 1096a3697f6bSJinwei Chen uint8_t msdu_idx; 1097a3697f6bSJinwei Chen QDF_STATUS status; 1098a3697f6bSJinwei Chen 1099a3697f6bSJinwei Chen if (!event) { 1100a3697f6bSJinwei Chen target_if_err("Invalid event buffer"); 1101a3697f6bSJinwei Chen return -EINVAL; 1102a3697f6bSJinwei Chen } 1103a3697f6bSJinwei Chen 1104a3697f6bSJinwei Chen num_msdu_idx_qtype_map = 1105a3697f6bSJinwei Chen info->service_ext2_param.num_msdu_idx_qtype_map; 1106a3697f6bSJinwei Chen target_if_debug("num msdu_idx to qtype map = %d", 1107a3697f6bSJinwei Chen num_msdu_idx_qtype_map); 1108a3697f6bSJinwei Chen 1109a3697f6bSJinwei Chen if (!num_msdu_idx_qtype_map) 1110a3697f6bSJinwei Chen return 0; 1111a3697f6bSJinwei Chen 1112a3697f6bSJinwei Chen info->msdu_idx_qtype_map = qdf_mem_malloc(sizeof(uint8_t) * 1113a3697f6bSJinwei Chen num_msdu_idx_qtype_map); 1114a3697f6bSJinwei Chen 1115a3697f6bSJinwei Chen if (!info->msdu_idx_qtype_map) { 1116a3697f6bSJinwei Chen target_if_err("Failed to allocate memory for msdu idx qtype map"); 1117a3697f6bSJinwei Chen return -EINVAL; 1118a3697f6bSJinwei Chen } 1119a3697f6bSJinwei Chen 1120a3697f6bSJinwei Chen for (msdu_idx = 0; msdu_idx < num_msdu_idx_qtype_map; msdu_idx++) { 1121a3697f6bSJinwei Chen msdu_qtype = &info->msdu_idx_qtype_map[msdu_idx]; 1122a3697f6bSJinwei Chen status = wmi_extract_msdu_idx_qtype_map_service_ready_ext2( 1123a3697f6bSJinwei Chen wmi_handle, event, msdu_idx, msdu_qtype); 1124a3697f6bSJinwei Chen if (QDF_IS_STATUS_ERROR(status)) { 1125a3697f6bSJinwei Chen target_if_err("Extraction of msdu idx qtype map failed"); 1126a3697f6bSJinwei Chen goto free_and_return; 1127a3697f6bSJinwei Chen } 1128a3697f6bSJinwei Chen } 1129a3697f6bSJinwei Chen 1130a3697f6bSJinwei Chen return 0; 1131a3697f6bSJinwei Chen 1132a3697f6bSJinwei Chen free_and_return: 1133a3697f6bSJinwei Chen qdf_mem_free(info->msdu_idx_qtype_map); 1134a3697f6bSJinwei Chen info->msdu_idx_qtype_map = NULL; 1135a3697f6bSJinwei Chen 1136a3697f6bSJinwei Chen return qdf_status_to_os_return(status); 1137a3697f6bSJinwei Chen } 1138a3697f6bSJinwei Chen 1139a3697f6bSJinwei Chen QDF_STATUS init_deinit_msdu_idx_qtype_map_free( 1140a3697f6bSJinwei Chen struct target_psoc_info *tgt_psoc_info) 1141a3697f6bSJinwei Chen { 1142a3697f6bSJinwei Chen qdf_mem_free(tgt_psoc_info->info.msdu_idx_qtype_map); 1143a3697f6bSJinwei Chen tgt_psoc_info->info.msdu_idx_qtype_map = NULL; 1144a3697f6bSJinwei Chen 1145a3697f6bSJinwei Chen return QDF_STATUS_SUCCESS; 1146a3697f6bSJinwei Chen } 1147a3697f6bSJinwei Chen 1148a3697f6bSJinwei Chen qdf_export_symbol(init_deinit_msdu_idx_qtype_map_free); 1149a3697f6bSJinwei Chen 1150cc75651cSSrinivas Pitla static bool init_deinit_regdmn_160mhz_support( 1151cc75651cSSrinivas Pitla struct wlan_psoc_host_hal_reg_capabilities_ext *hal_cap) 1152cc75651cSSrinivas Pitla { 1153cc75651cSSrinivas Pitla return ((hal_cap->wireless_modes & 115429817dceSShiva Krishna Pittala HOST_REGDMN_MODE_11AC_VHT160) != 0); 1155cc75651cSSrinivas Pitla } 1156cc75651cSSrinivas Pitla 1157cc75651cSSrinivas Pitla static bool init_deinit_regdmn_80p80mhz_support( 1158cc75651cSSrinivas Pitla struct wlan_psoc_host_hal_reg_capabilities_ext *hal_cap) 1159cc75651cSSrinivas Pitla { 1160cc75651cSSrinivas Pitla return ((hal_cap->wireless_modes & 116129817dceSShiva Krishna Pittala HOST_REGDMN_MODE_11AC_VHT80_80) != 0); 1162cc75651cSSrinivas Pitla } 1163cc75651cSSrinivas Pitla 1164cc75651cSSrinivas Pitla static bool init_deinit_vht_160mhz_is_supported(uint32_t vhtcap) 1165cc75651cSSrinivas Pitla { 1166cc75651cSSrinivas Pitla return ((vhtcap & WLAN_VHTCAP_SUP_CHAN_WIDTH_160) != 0); 1167cc75651cSSrinivas Pitla } 1168cc75651cSSrinivas Pitla 1169cc75651cSSrinivas Pitla static bool init_deinit_vht_80p80mhz_is_supported(uint32_t vhtcap) 1170cc75651cSSrinivas Pitla { 1171cc75651cSSrinivas Pitla return ((vhtcap & WLAN_VHTCAP_SUP_CHAN_WIDTH_80_160) != 0); 1172cc75651cSSrinivas Pitla } 1173cc75651cSSrinivas Pitla 1174cc75651cSSrinivas Pitla static bool init_deinit_vht_160mhz_shortgi_is_supported(uint32_t vhtcap) 1175cc75651cSSrinivas Pitla { 1176cc75651cSSrinivas Pitla return ((vhtcap & WLAN_VHTCAP_SHORTGI_160) != 0); 1177cc75651cSSrinivas Pitla } 1178cc75651cSSrinivas Pitla 1179cc75651cSSrinivas Pitla QDF_STATUS init_deinit_validate_160_80p80_fw_caps( 1180cc75651cSSrinivas Pitla struct wlan_objmgr_psoc *psoc, 1181cc75651cSSrinivas Pitla struct target_psoc_info *tgt_hdl) 1182cc75651cSSrinivas Pitla { 1183cc75651cSSrinivas Pitla bool wireless_mode_160mhz = false; 1184cc75651cSSrinivas Pitla bool wireless_mode_80p80mhz = false; 1185cc75651cSSrinivas Pitla bool vhtcap_160mhz = false; 1186cc75651cSSrinivas Pitla bool vhtcap_80p80_160mhz = false; 1187cc75651cSSrinivas Pitla bool vhtcap_160mhz_sgi = false; 1188cc75651cSSrinivas Pitla bool valid = false; 1189cc75651cSSrinivas Pitla struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap; 1190dc8e095fSAkshay Kosigi struct wmi_unified *wmi_handle; 1191cc75651cSSrinivas Pitla 1192cc75651cSSrinivas Pitla if (!tgt_hdl) { 1193cc75651cSSrinivas Pitla target_if_err( 1194cc75651cSSrinivas Pitla "target_psoc_info is null in validate 160n80p80 cap check"); 1195cc75651cSSrinivas Pitla return QDF_STATUS_E_INVAL; 1196cc75651cSSrinivas Pitla } 1197cc75651cSSrinivas Pitla 1198cc75651cSSrinivas Pitla wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl); 1199cc75651cSSrinivas Pitla 1200cc75651cSSrinivas Pitla if ((tgt_hdl->info.target_type == TARGET_TYPE_QCA8074) || 12014dd4a622SVenkateswara Swamy Bandaru (tgt_hdl->info.target_type == TARGET_TYPE_QCA8074V2) || 1202ff041723SPavankumar Nandeshwar (tgt_hdl->info.target_type == TARGET_TYPE_QCN6122) || 1203a7323442SKannan Saravanan (tgt_hdl->info.target_type == TARGET_TYPE_QCN9160) || 1204e11f459aSKannan Saravanan (tgt_hdl->info.target_type == TARGET_TYPE_QCA6290) || 1205e11f459aSKannan Saravanan (tgt_hdl->info.target_type == TARGET_TYPE_QCN6432)) { 1206cc75651cSSrinivas Pitla /** 1207cc75651cSSrinivas Pitla * Return true for now. This is not available in 1208cc75651cSSrinivas Pitla * qca8074 fw yet 1209cc75651cSSrinivas Pitla */ 1210cc75651cSSrinivas Pitla return QDF_STATUS_SUCCESS; 1211cc75651cSSrinivas Pitla } 1212cc75651cSSrinivas Pitla 1213cc75651cSSrinivas Pitla reg_cap = ucfg_reg_get_hal_reg_cap(psoc); 1214eee26f7bSJeff Johnson if (!reg_cap) { 1215cc75651cSSrinivas Pitla target_if_err("reg cap is NULL"); 1216cc75651cSSrinivas Pitla return QDF_STATUS_E_FAILURE; 1217cc75651cSSrinivas Pitla } 1218cc75651cSSrinivas Pitla 1219cc75651cSSrinivas Pitla /* NOTE: Host driver gets vht capability and supported channel 1220cc75651cSSrinivas Pitla * width / channel frequency range from FW/HALPHY and obeys it. 1221cc75651cSSrinivas Pitla * Host driver is unaware of any physical filters or any other 1222cc75651cSSrinivas Pitla * hardware factors that can impact these capabilities. 1223cc75651cSSrinivas Pitla * These need to be correctly determined by firmware. 1224cc75651cSSrinivas Pitla */ 1225cc75651cSSrinivas Pitla 1226cc75651cSSrinivas Pitla /*This table lists all valid and invalid combinations 1227cc75651cSSrinivas Pitla * WMODE160 WMODE80_80 VHTCAP_160 VHTCAP_80+80_160 IsCombinationvalid? 1228cc75651cSSrinivas Pitla * 0 0 0 0 YES 1229cc75651cSSrinivas Pitla * 0 0 0 1 NO 1230cc75651cSSrinivas Pitla * 0 0 1 0 NO 1231cc75651cSSrinivas Pitla * 0 0 1 1 NO 1232cc75651cSSrinivas Pitla * 0 1 0 0 NO 1233cc75651cSSrinivas Pitla * 0 1 0 1 NO 1234cc75651cSSrinivas Pitla * 0 1 1 0 NO 1235cc75651cSSrinivas Pitla * 0 1 1 1 NO 1236cc75651cSSrinivas Pitla * 1 0 0 0 NO 1237cc75651cSSrinivas Pitla * 1 0 0 1 NO 1238cc75651cSSrinivas Pitla * 1 0 1 0 YES 1239cc75651cSSrinivas Pitla * 1 0 1 1 NO 1240cc75651cSSrinivas Pitla * 1 1 0 0 NO 1241cc75651cSSrinivas Pitla * 1 1 0 1 YES 1242cc75651cSSrinivas Pitla * 1 1 1 0 NO 1243cc75651cSSrinivas Pitla * 1 1 1 1 NO 1244cc75651cSSrinivas Pitla */ 1245cc75651cSSrinivas Pitla 1246cc75651cSSrinivas Pitla /* NOTE: Last row in above table is invalid because value corresponding 1247cc75651cSSrinivas Pitla * to both VHTCAP_160 and VHTCAP_80+80_160 being set is reserved as per 1248cc75651cSSrinivas Pitla * 802.11ac. Only one of them can be set at a time. 1249cc75651cSSrinivas Pitla */ 1250cc75651cSSrinivas Pitla 1251cc75651cSSrinivas Pitla wireless_mode_160mhz = init_deinit_regdmn_160mhz_support(reg_cap); 1252cc75651cSSrinivas Pitla wireless_mode_80p80mhz = init_deinit_regdmn_80p80mhz_support(reg_cap); 1253cc75651cSSrinivas Pitla vhtcap_160mhz = init_deinit_vht_160mhz_is_supported( 1254cc75651cSSrinivas Pitla tgt_hdl->info.target_caps.vht_cap_info); 1255cc75651cSSrinivas Pitla vhtcap_80p80_160mhz = init_deinit_vht_80p80mhz_is_supported( 1256cc75651cSSrinivas Pitla tgt_hdl->info.target_caps.vht_cap_info); 1257cc75651cSSrinivas Pitla vhtcap_160mhz_sgi = init_deinit_vht_160mhz_shortgi_is_supported( 1258cc75651cSSrinivas Pitla tgt_hdl->info.target_caps.vht_cap_info); 1259cc75651cSSrinivas Pitla 1260cc75651cSSrinivas Pitla if (!(wireless_mode_160mhz || wireless_mode_80p80mhz || 1261cc75651cSSrinivas Pitla vhtcap_160mhz || vhtcap_80p80_160mhz)) { 1262cc75651cSSrinivas Pitla valid = QDF_STATUS_SUCCESS; 1263cc75651cSSrinivas Pitla } else if (wireless_mode_160mhz && !wireless_mode_80p80mhz && 1264cc75651cSSrinivas Pitla vhtcap_160mhz && !vhtcap_80p80_160mhz) { 1265cc75651cSSrinivas Pitla valid = QDF_STATUS_SUCCESS; 1266cc75651cSSrinivas Pitla } else if (wireless_mode_160mhz && wireless_mode_80p80mhz && 1267cc75651cSSrinivas Pitla !vhtcap_160mhz && vhtcap_160mhz_sgi) { 1268cc75651cSSrinivas Pitla valid = QDF_STATUS_SUCCESS; 1269cc75651cSSrinivas Pitla } 1270cc75651cSSrinivas Pitla 1271cc75651cSSrinivas Pitla if (valid == QDF_STATUS_SUCCESS) { 1272cc75651cSSrinivas Pitla /* 1273cc75651cSSrinivas Pitla * Ensure short GI for 160 MHz is enabled 1274cc75651cSSrinivas Pitla * only if 160/80+80 is supported. 1275cc75651cSSrinivas Pitla */ 1276cc75651cSSrinivas Pitla if (vhtcap_160mhz_sgi && 1277cc75651cSSrinivas Pitla !(vhtcap_160mhz || vhtcap_80p80_160mhz)) { 1278cc75651cSSrinivas Pitla valid = QDF_STATUS_E_FAILURE; 1279cc75651cSSrinivas Pitla } 1280cc75651cSSrinivas Pitla } 1281cc75651cSSrinivas Pitla 1282cc75651cSSrinivas Pitla /* Invalid config specified by FW */ 1283cc75651cSSrinivas Pitla if (valid != QDF_STATUS_SUCCESS) { 1284cc75651cSSrinivas Pitla target_if_err("Invalid 160/80+80 MHz config specified by FW. Take care of it first"); 1285cc75651cSSrinivas Pitla target_if_err("wireless_mode_160mhz: %d, wireless_mode_80p80mhz: %d", 1286cc75651cSSrinivas Pitla wireless_mode_160mhz, wireless_mode_80p80mhz); 1287cc75651cSSrinivas Pitla target_if_err("vhtcap_160mhz: %d, vhtcap_80p80_160mhz: %d,vhtcap_160mhz_sgi: %d", 1288cc75651cSSrinivas Pitla vhtcap_160mhz, vhtcap_80p80_160mhz, 1289cc75651cSSrinivas Pitla vhtcap_160mhz_sgi); 1290cc75651cSSrinivas Pitla } 1291cc75651cSSrinivas Pitla return valid; 1292cc75651cSSrinivas Pitla } 1293cc75651cSSrinivas Pitla 1294cc75651cSSrinivas Pitla void init_deinit_chainmask_config( 1295cc75651cSSrinivas Pitla struct wlan_objmgr_psoc *psoc, 1296cc75651cSSrinivas Pitla struct target_psoc_info *tgt_hdl) 1297cc75651cSSrinivas Pitla { 1298cc75651cSSrinivas Pitla tgt_hdl->info.wlan_res_cfg.tx_chain_mask = 1299cc75651cSSrinivas Pitla ((1 << tgt_hdl->info.target_caps.num_rf_chains) - 1); 1300cc75651cSSrinivas Pitla tgt_hdl->info.wlan_res_cfg.rx_chain_mask = 1301cc75651cSSrinivas Pitla ((1 << tgt_hdl->info.target_caps.num_rf_chains) - 1); 1302cc75651cSSrinivas Pitla } 1303cc75651cSSrinivas Pitla 1304cc75651cSSrinivas Pitla QDF_STATUS init_deinit_is_service_ext_msg( 1305cc75651cSSrinivas Pitla struct wlan_objmgr_psoc *psoc, 1306cc75651cSSrinivas Pitla struct target_psoc_info *tgt_hdl) 1307cc75651cSSrinivas Pitla { 1308dc8e095fSAkshay Kosigi struct wmi_unified *wmi_handle; 1309cc75651cSSrinivas Pitla 1310cc75651cSSrinivas Pitla if (!tgt_hdl) { 1311cc75651cSSrinivas Pitla target_if_err( 1312cc75651cSSrinivas Pitla "psoc target_psoc_info is null in service ext msg"); 1313cc75651cSSrinivas Pitla return QDF_STATUS_E_INVAL; 1314cc75651cSSrinivas Pitla } 1315cc75651cSSrinivas Pitla 1316cc75651cSSrinivas Pitla wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl); 1317cc75651cSSrinivas Pitla 1318cc75651cSSrinivas Pitla if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) 1319cc75651cSSrinivas Pitla return QDF_STATUS_SUCCESS; 1320cc75651cSSrinivas Pitla else 1321cc75651cSSrinivas Pitla return QDF_STATUS_E_FAILURE; 1322cc75651cSSrinivas Pitla } 1323cc75651cSSrinivas Pitla 1324cc75651cSSrinivas Pitla bool init_deinit_is_preferred_hw_mode_supported( 1325cc75651cSSrinivas Pitla struct wlan_objmgr_psoc *psoc, 1326cc75651cSSrinivas Pitla struct target_psoc_info *tgt_hdl) 1327cc75651cSSrinivas Pitla { 1328cc75651cSSrinivas Pitla uint16_t i; 1329cc75651cSSrinivas Pitla struct tgt_info *info; 1330cc75651cSSrinivas Pitla 1331cc75651cSSrinivas Pitla if (!tgt_hdl) { 1332cc75651cSSrinivas Pitla target_if_err( 1333cc75651cSSrinivas Pitla "psoc target_psoc_info is null in service ext msg"); 1334cc75651cSSrinivas Pitla return FALSE; 1335cc75651cSSrinivas Pitla } 1336cc75651cSSrinivas Pitla 1337cc75651cSSrinivas Pitla info = &tgt_hdl->info; 1338cc75651cSSrinivas Pitla 13398bb56ebeSNandha Kishore Easwaran if (info->preferred_hw_mode == WMI_HOST_HW_MODE_MAX) 13408bb56ebeSNandha Kishore Easwaran return TRUE; 13418bb56ebeSNandha Kishore Easwaran 13428e0ae994SGyanranjan Hazarika if (wlan_psoc_nif_feat_cap_get(psoc, WLAN_SOC_F_DYNAMIC_HW_MODE)) { 13438e0ae994SGyanranjan Hazarika if (!wlan_psoc_nif_fw_ext_cap_get(psoc, 13448e0ae994SGyanranjan Hazarika WLAN_SOC_CEXT_DYNAMIC_HW_MODE)) { 13458e0ae994SGyanranjan Hazarika target_if_err( 13468e0ae994SGyanranjan Hazarika "WMI service bit for DYNAMIC HW mode is not set!"); 13478e0ae994SGyanranjan Hazarika return FALSE; 13488e0ae994SGyanranjan Hazarika } 13498e0ae994SGyanranjan Hazarika } 13508e0ae994SGyanranjan Hazarika 1351cc75651cSSrinivas Pitla for (i = 0; i < target_psoc_get_total_mac_phy_cnt(tgt_hdl); i++) { 1352cc75651cSSrinivas Pitla if (info->mac_phy_cap[i].hw_mode_id == info->preferred_hw_mode) 1353cc75651cSSrinivas Pitla return TRUE; 1354cc75651cSSrinivas Pitla } 1355cc75651cSSrinivas Pitla 1356cc75651cSSrinivas Pitla return FALSE; 1357cc75651cSSrinivas Pitla } 1358cc75651cSSrinivas Pitla 1359cc75651cSSrinivas Pitla void init_deinit_wakeup_host_wait( 1360cc75651cSSrinivas Pitla struct wlan_objmgr_psoc *psoc, 1361cc75651cSSrinivas Pitla struct target_psoc_info *tgt_hdl) 1362cc75651cSSrinivas Pitla { 1363cc75651cSSrinivas Pitla if (!tgt_hdl) { 1364cc75651cSSrinivas Pitla target_if_err("psoc target_psoc_info is null in target ready"); 1365cc75651cSSrinivas Pitla return; 1366cc75651cSSrinivas Pitla } 1367d898ceddSSrinivas Pitla qdf_event_set(&tgt_hdl->info.event); 1368cc75651cSSrinivas Pitla } 1369