1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include "wmi_unified_api.h" 21 #include "wmi.h" 22 #include "wmi_version.h" 23 #include "wmi_unified_priv.h" 24 #include "wmi_version_allowlist.h" 25 #include "wifi_pos_public_struct.h" 26 #include <qdf_module.h> 27 #include <wlan_defs.h> 28 #include <wlan_cmn.h> 29 #include <htc_services.h> 30 #ifdef FEATURE_WLAN_APF 31 #include "wmi_unified_apf_tlv.h" 32 #endif 33 #ifdef WLAN_FEATURE_ACTION_OUI 34 #include "wmi_unified_action_oui_tlv.h" 35 #endif 36 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 37 #include "wlan_pmo_hw_filter_public_struct.h" 38 #endif 39 #include <wlan_utility.h> 40 #ifdef WLAN_SUPPORT_GREEN_AP 41 #include "wlan_green_ap_api.h" 42 #endif 43 44 #include "wmi_unified_twt_api.h" 45 #include "wmi_unified_wds_api.h" 46 47 #ifdef WLAN_POLICY_MGR_ENABLE 48 #include "wlan_policy_mgr_public_struct.h" 49 #endif 50 51 #ifdef WMI_SMART_ANT_SUPPORT 52 #include "wmi_unified_smart_ant_api.h" 53 #endif 54 55 #ifdef WMI_DBR_SUPPORT 56 #include "wmi_unified_dbr_api.h" 57 #endif 58 59 #ifdef WMI_ATF_SUPPORT 60 #include "wmi_unified_atf_api.h" 61 #endif 62 63 #ifdef WMI_AP_SUPPORT 64 #include "wmi_unified_ap_api.h" 65 #endif 66 67 #include <wmi_unified_vdev_api.h> 68 #include <wmi_unified_vdev_tlv.h> 69 #include <wmi_unified_11be_tlv.h> 70 71 #ifdef FEATURE_SET 72 #include "wlan_mlme_public_struct.h" 73 #endif 74 75 /* 76 * If FW supports WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 77 * then channel_list may fill the upper 12 bits with channel flags, 78 * while using only the lower 20 bits for channel frequency. 79 * If FW doesn't support WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 80 * then channel_list only holds the frequency value. 81 */ 82 #define CHAN_LIST_FLAG_MASK_POS 20 83 #define TARGET_SET_FREQ_IN_CHAN_LIST_TLV(buf, freq) \ 84 ((buf) |= ((freq) & WMI_SCAN_CHANNEL_FREQ_MASK)) 85 #define TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(buf, flags) \ 86 ((buf) |= ((flags) << CHAN_LIST_FLAG_MASK_POS)) 87 88 /* HTC service ids for WMI for multi-radio */ 89 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 90 WMI_CONTROL_SVC_WMAC1, 91 WMI_CONTROL_SVC_WMAC2}; 92 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 93 uint32_t service_id); 94 95 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 96 /*Populate peer_param array whose index as host id and 97 *value as target id 98 */ 99 static const uint32_t peer_param_tlv[] = { 100 [WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE, 101 [WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU, 102 [WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE, 103 [WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH, 104 [WMI_HOST_PEER_NSS] = WMI_PEER_NSS, 105 [WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR, 106 [WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP, 107 [WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS, 108 [WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] = 109 WMI_PEER_CRIT_PROTO_HINT_ENABLED, 110 [WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR, 111 [WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S, 112 [WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] = 113 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, 114 [WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE, 115 [WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR, 116 [WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE, 117 [WMI_HOST_PEER_SET_MU_ALLOWLIST] = WMI_PEER_SET_MU_ALLOWLIST, 118 [WMI_HOST_PEER_SET_MAX_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE, 119 [WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE, 120 [WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING, 121 [WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160, 122 [WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80, 123 [WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] = 124 WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL, 125 [WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] = 126 WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL, 127 [WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] = 128 WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE, 129 [WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE, 130 [WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE, 131 [WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT, 132 [WMI_HOST_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP] = 133 WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP, 134 [WMI_HOST_PEER_FT_ROAMING_PEER_UPDATE] = 135 WMI_PEER_FT_ROAMING_PEER_UPDATE, 136 [WMI_HOST_PEER_PARAM_DMS_SUPPORT] = WMI_PEER_PARAM_DMS_SUPPORT, 137 [WMI_HOST_PEER_PARAM_UL_OFDMA_RTD] = WMI_PEER_PARAM_UL_OFDMA_RTD, 138 }; 139 140 #define PARAM_MAP(name, NAME) [wmi_ ## name] = WMI_ ##NAME 141 142 /* Populate pdev_param whose index is host param and value is target */ 143 static const uint32_t pdev_param_tlv[] = { 144 PARAM_MAP(pdev_param_tx_chain_mask, PDEV_PARAM_TX_CHAIN_MASK), 145 PARAM_MAP(pdev_param_rx_chain_mask, PDEV_PARAM_RX_CHAIN_MASK), 146 PARAM_MAP(pdev_param_txpower_limit2g, PDEV_PARAM_TXPOWER_LIMIT2G), 147 PARAM_MAP(pdev_param_txpower_limit5g, PDEV_PARAM_TXPOWER_LIMIT5G), 148 PARAM_MAP(pdev_param_txpower_scale, PDEV_PARAM_TXPOWER_SCALE), 149 PARAM_MAP(pdev_param_beacon_gen_mode, PDEV_PARAM_BEACON_GEN_MODE), 150 PARAM_MAP(pdev_param_beacon_tx_mode, PDEV_PARAM_BEACON_TX_MODE), 151 PARAM_MAP(pdev_param_resmgr_offchan_mode, 152 PDEV_PARAM_RESMGR_OFFCHAN_MODE), 153 PARAM_MAP(pdev_param_protection_mode, PDEV_PARAM_PROTECTION_MODE), 154 PARAM_MAP(pdev_param_dynamic_bw, PDEV_PARAM_DYNAMIC_BW), 155 PARAM_MAP(pdev_param_non_agg_sw_retry_th, 156 PDEV_PARAM_NON_AGG_SW_RETRY_TH), 157 PARAM_MAP(pdev_param_agg_sw_retry_th, PDEV_PARAM_AGG_SW_RETRY_TH), 158 PARAM_MAP(pdev_param_sta_kickout_th, PDEV_PARAM_STA_KICKOUT_TH), 159 PARAM_MAP(pdev_param_ac_aggrsize_scaling, 160 PDEV_PARAM_AC_AGGRSIZE_SCALING), 161 PARAM_MAP(pdev_param_ltr_enable, PDEV_PARAM_LTR_ENABLE), 162 PARAM_MAP(pdev_param_ltr_ac_latency_be, 163 PDEV_PARAM_LTR_AC_LATENCY_BE), 164 PARAM_MAP(pdev_param_ltr_ac_latency_bk, PDEV_PARAM_LTR_AC_LATENCY_BK), 165 PARAM_MAP(pdev_param_ltr_ac_latency_vi, PDEV_PARAM_LTR_AC_LATENCY_VI), 166 PARAM_MAP(pdev_param_ltr_ac_latency_vo, PDEV_PARAM_LTR_AC_LATENCY_VO), 167 PARAM_MAP(pdev_param_ltr_ac_latency_timeout, 168 PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT), 169 PARAM_MAP(pdev_param_ltr_sleep_override, PDEV_PARAM_LTR_SLEEP_OVERRIDE), 170 PARAM_MAP(pdev_param_ltr_rx_override, PDEV_PARAM_LTR_RX_OVERRIDE), 171 PARAM_MAP(pdev_param_ltr_tx_activity_timeout, 172 PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT), 173 PARAM_MAP(pdev_param_l1ss_enable, PDEV_PARAM_L1SS_ENABLE), 174 PARAM_MAP(pdev_param_dsleep_enable, PDEV_PARAM_DSLEEP_ENABLE), 175 PARAM_MAP(pdev_param_pcielp_txbuf_flush, PDEV_PARAM_PCIELP_TXBUF_FLUSH), 176 PARAM_MAP(pdev_param_pcielp_txbuf_watermark, 177 PDEV_PARAM_PCIELP_TXBUF_WATERMARK), 178 PARAM_MAP(pdev_param_pcielp_txbuf_tmo_en, 179 PDEV_PARAM_PCIELP_TXBUF_TMO_EN), 180 PARAM_MAP(pdev_param_pcielp_txbuf_tmo_value, 181 PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE), 182 PARAM_MAP(pdev_param_pdev_stats_update_period, 183 PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD), 184 PARAM_MAP(pdev_param_vdev_stats_update_period, 185 PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD), 186 PARAM_MAP(pdev_param_peer_stats_update_period, 187 PDEV_PARAM_PEER_STATS_UPDATE_PERIOD), 188 PARAM_MAP(pdev_param_bcnflt_stats_update_period, 189 PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD), 190 PARAM_MAP(pdev_param_pmf_qos, PDEV_PARAM_PMF_QOS), 191 PARAM_MAP(pdev_param_arp_ac_override, PDEV_PARAM_ARP_AC_OVERRIDE), 192 PARAM_MAP(pdev_param_dcs, PDEV_PARAM_DCS), 193 PARAM_MAP(pdev_param_ani_enable, PDEV_PARAM_ANI_ENABLE), 194 PARAM_MAP(pdev_param_ani_poll_period, PDEV_PARAM_ANI_POLL_PERIOD), 195 PARAM_MAP(pdev_param_ani_listen_period, PDEV_PARAM_ANI_LISTEN_PERIOD), 196 PARAM_MAP(pdev_param_ani_ofdm_level, PDEV_PARAM_ANI_OFDM_LEVEL), 197 PARAM_MAP(pdev_param_ani_cck_level, PDEV_PARAM_ANI_CCK_LEVEL), 198 PARAM_MAP(pdev_param_dyntxchain, PDEV_PARAM_DYNTXCHAIN), 199 PARAM_MAP(pdev_param_proxy_sta, PDEV_PARAM_PROXY_STA), 200 PARAM_MAP(pdev_param_idle_ps_config, PDEV_PARAM_IDLE_PS_CONFIG), 201 PARAM_MAP(pdev_param_power_gating_sleep, PDEV_PARAM_POWER_GATING_SLEEP), 202 PARAM_MAP(pdev_param_rfkill_enable, PDEV_PARAM_RFKILL_ENABLE), 203 PARAM_MAP(pdev_param_burst_dur, PDEV_PARAM_BURST_DUR), 204 PARAM_MAP(pdev_param_burst_enable, PDEV_PARAM_BURST_ENABLE), 205 PARAM_MAP(pdev_param_hw_rfkill_config, PDEV_PARAM_HW_RFKILL_CONFIG), 206 PARAM_MAP(pdev_param_low_power_rf_enable, 207 PDEV_PARAM_LOW_POWER_RF_ENABLE), 208 PARAM_MAP(pdev_param_l1ss_track, PDEV_PARAM_L1SS_TRACK), 209 PARAM_MAP(pdev_param_hyst_en, PDEV_PARAM_HYST_EN), 210 PARAM_MAP(pdev_param_power_collapse_enable, 211 PDEV_PARAM_POWER_COLLAPSE_ENABLE), 212 PARAM_MAP(pdev_param_led_sys_state, PDEV_PARAM_LED_SYS_STATE), 213 PARAM_MAP(pdev_param_led_enable, PDEV_PARAM_LED_ENABLE), 214 PARAM_MAP(pdev_param_audio_over_wlan_latency, 215 PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY), 216 PARAM_MAP(pdev_param_audio_over_wlan_enable, 217 PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE), 218 PARAM_MAP(pdev_param_whal_mib_stats_update_enable, 219 PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE), 220 PARAM_MAP(pdev_param_vdev_rate_stats_update_period, 221 PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD), 222 PARAM_MAP(pdev_param_cts_cbw, PDEV_PARAM_CTS_CBW), 223 PARAM_MAP(pdev_param_wnts_config, PDEV_PARAM_WNTS_CONFIG), 224 PARAM_MAP(pdev_param_adaptive_early_rx_enable, 225 PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE), 226 PARAM_MAP(pdev_param_adaptive_early_rx_min_sleep_slop, 227 PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP), 228 PARAM_MAP(pdev_param_adaptive_early_rx_inc_dec_step, 229 PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP), 230 PARAM_MAP(pdev_param_early_rx_fix_sleep_slop, 231 PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP), 232 PARAM_MAP(pdev_param_bmiss_based_adaptive_bto_enable, 233 PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE), 234 PARAM_MAP(pdev_param_bmiss_bto_min_bcn_timeout, 235 PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT), 236 PARAM_MAP(pdev_param_bmiss_bto_inc_dec_step, 237 PDEV_PARAM_BMISS_BTO_INC_DEC_STEP), 238 PARAM_MAP(pdev_param_bto_fix_bcn_timeout, 239 PDEV_PARAM_BTO_FIX_BCN_TIMEOUT), 240 PARAM_MAP(pdev_param_ce_based_adaptive_bto_enable, 241 PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE), 242 PARAM_MAP(pdev_param_ce_bto_combo_ce_value, 243 PDEV_PARAM_CE_BTO_COMBO_CE_VALUE), 244 PARAM_MAP(pdev_param_tx_chain_mask_2g, PDEV_PARAM_TX_CHAIN_MASK_2G), 245 PARAM_MAP(pdev_param_rx_chain_mask_2g, PDEV_PARAM_RX_CHAIN_MASK_2G), 246 PARAM_MAP(pdev_param_tx_chain_mask_5g, PDEV_PARAM_TX_CHAIN_MASK_5G), 247 PARAM_MAP(pdev_param_rx_chain_mask_5g, PDEV_PARAM_RX_CHAIN_MASK_5G), 248 PARAM_MAP(pdev_param_tx_chain_mask_cck, PDEV_PARAM_TX_CHAIN_MASK_CCK), 249 PARAM_MAP(pdev_param_tx_chain_mask_1ss, PDEV_PARAM_TX_CHAIN_MASK_1SS), 250 PARAM_MAP(pdev_param_soft_tx_chain_mask, PDEV_PARAM_TX_CHAIN_MASK), 251 PARAM_MAP(pdev_param_rx_filter, PDEV_PARAM_RX_FILTER), 252 PARAM_MAP(pdev_set_mcast_to_ucast_tid, PDEV_SET_MCAST_TO_UCAST_TID), 253 PARAM_MAP(pdev_param_mgmt_retry_limit, PDEV_PARAM_MGMT_RETRY_LIMIT), 254 PARAM_MAP(pdev_param_aggr_burst, PDEV_PARAM_AGGR_BURST), 255 PARAM_MAP(pdev_peer_sta_ps_statechg_enable, 256 PDEV_PEER_STA_PS_STATECHG_ENABLE), 257 PARAM_MAP(pdev_param_proxy_sta_mode, PDEV_PARAM_PROXY_STA_MODE), 258 PARAM_MAP(pdev_param_mu_group_policy, PDEV_PARAM_MU_GROUP_POLICY), 259 PARAM_MAP(pdev_param_noise_detection, PDEV_PARAM_NOISE_DETECTION), 260 PARAM_MAP(pdev_param_noise_threshold, PDEV_PARAM_NOISE_THRESHOLD), 261 PARAM_MAP(pdev_param_dpd_enable, PDEV_PARAM_DPD_ENABLE), 262 PARAM_MAP(pdev_param_set_mcast_bcast_echo, 263 PDEV_PARAM_SET_MCAST_BCAST_ECHO), 264 PARAM_MAP(pdev_param_atf_strict_sch, PDEV_PARAM_ATF_STRICT_SCH), 265 PARAM_MAP(pdev_param_atf_sched_duration, PDEV_PARAM_ATF_SCHED_DURATION), 266 PARAM_MAP(pdev_param_ant_plzn, PDEV_PARAM_ANT_PLZN), 267 PARAM_MAP(pdev_param_sensitivity_level, PDEV_PARAM_SENSITIVITY_LEVEL), 268 PARAM_MAP(pdev_param_signed_txpower_2g, PDEV_PARAM_SIGNED_TXPOWER_2G), 269 PARAM_MAP(pdev_param_signed_txpower_5g, PDEV_PARAM_SIGNED_TXPOWER_5G), 270 PARAM_MAP(pdev_param_enable_per_tid_amsdu, 271 PDEV_PARAM_ENABLE_PER_TID_AMSDU), 272 PARAM_MAP(pdev_param_enable_per_tid_ampdu, 273 PDEV_PARAM_ENABLE_PER_TID_AMPDU), 274 PARAM_MAP(pdev_param_cca_threshold, PDEV_PARAM_CCA_THRESHOLD), 275 PARAM_MAP(pdev_param_rts_fixed_rate, PDEV_PARAM_RTS_FIXED_RATE), 276 PARAM_MAP(pdev_param_cal_period, UNAVAILABLE_PARAM), 277 PARAM_MAP(pdev_param_pdev_reset, PDEV_PARAM_PDEV_RESET), 278 PARAM_MAP(pdev_param_wapi_mbssid_offset, PDEV_PARAM_WAPI_MBSSID_OFFSET), 279 PARAM_MAP(pdev_param_arp_srcaddr, PDEV_PARAM_ARP_DBG_SRCADDR), 280 PARAM_MAP(pdev_param_arp_dstaddr, PDEV_PARAM_ARP_DBG_DSTADDR), 281 PARAM_MAP(pdev_param_txpower_decr_db, PDEV_PARAM_TXPOWER_DECR_DB), 282 PARAM_MAP(pdev_param_rx_batchmode, UNAVAILABLE_PARAM), 283 PARAM_MAP(pdev_param_packet_aggr_delay, UNAVAILABLE_PARAM), 284 PARAM_MAP(pdev_param_atf_obss_noise_sch, PDEV_PARAM_ATF_OBSS_NOISE_SCH), 285 PARAM_MAP(pdev_param_atf_obss_noise_scaling_factor, 286 PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR), 287 PARAM_MAP(pdev_param_cust_txpower_scale, PDEV_PARAM_CUST_TXPOWER_SCALE), 288 PARAM_MAP(pdev_param_atf_dynamic_enable, PDEV_PARAM_ATF_DYNAMIC_ENABLE), 289 PARAM_MAP(pdev_param_atf_ssid_group_policy, UNAVAILABLE_PARAM), 290 PARAM_MAP(pdev_param_igmpmld_override, PDEV_PARAM_IGMPMLD_AC_OVERRIDE), 291 PARAM_MAP(pdev_param_igmpmld_tid, PDEV_PARAM_IGMPMLD_AC_OVERRIDE), 292 PARAM_MAP(pdev_param_antenna_gain, PDEV_PARAM_ANTENNA_GAIN), 293 PARAM_MAP(pdev_param_block_interbss, PDEV_PARAM_BLOCK_INTERBSS), 294 PARAM_MAP(pdev_param_set_disable_reset_cmdid, 295 PDEV_PARAM_SET_DISABLE_RESET_CMDID), 296 PARAM_MAP(pdev_param_set_msdu_ttl_cmdid, PDEV_PARAM_SET_MSDU_TTL_CMDID), 297 PARAM_MAP(pdev_param_txbf_sound_period_cmdid, 298 PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID), 299 PARAM_MAP(pdev_param_set_burst_mode_cmdid, 300 PDEV_PARAM_SET_BURST_MODE_CMDID), 301 PARAM_MAP(pdev_param_en_stats, PDEV_PARAM_EN_STATS), 302 PARAM_MAP(pdev_param_mesh_mcast_enable, PDEV_PARAM_MESH_MCAST_ENABLE), 303 PARAM_MAP(pdev_param_set_promisc_mode_cmdid, 304 PDEV_PARAM_SET_PROMISC_MODE_CMDID), 305 PARAM_MAP(pdev_param_set_ppdu_duration_cmdid, 306 PDEV_PARAM_SET_PPDU_DURATION_CMDID), 307 PARAM_MAP(pdev_param_remove_mcast2ucast_buffer, 308 PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER), 309 PARAM_MAP(pdev_param_set_mcast2ucast_buffer, 310 PDEV_PARAM_SET_MCAST2UCAST_BUFFER), 311 PARAM_MAP(pdev_param_set_mcast2ucast_mode, 312 PDEV_PARAM_SET_MCAST2UCAST_MODE), 313 PARAM_MAP(pdev_param_smart_antenna_default_antenna, 314 PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA), 315 PARAM_MAP(pdev_param_fast_channel_reset, 316 PDEV_PARAM_FAST_CHANNEL_RESET), 317 PARAM_MAP(pdev_param_rx_decap_mode, PDEV_PARAM_RX_DECAP_MODE), 318 PARAM_MAP(pdev_param_tx_ack_timeout, PDEV_PARAM_ACK_TIMEOUT), 319 PARAM_MAP(pdev_param_cck_tx_enable, PDEV_PARAM_CCK_TX_ENABLE), 320 PARAM_MAP(pdev_param_antenna_gain_half_db, 321 PDEV_PARAM_ANTENNA_GAIN_HALF_DB), 322 PARAM_MAP(pdev_param_esp_indication_period, 323 PDEV_PARAM_ESP_INDICATION_PERIOD), 324 PARAM_MAP(pdev_param_esp_ba_window, PDEV_PARAM_ESP_BA_WINDOW), 325 PARAM_MAP(pdev_param_esp_airtime_fraction, 326 PDEV_PARAM_ESP_AIRTIME_FRACTION), 327 PARAM_MAP(pdev_param_esp_ppdu_duration, PDEV_PARAM_ESP_PPDU_DURATION), 328 PARAM_MAP(pdev_param_ru26_allowed, PDEV_PARAM_UL_RU26_ALLOWED), 329 PARAM_MAP(pdev_param_use_nol, PDEV_PARAM_USE_NOL), 330 PARAM_MAP(pdev_param_ul_trig_int, PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL), 331 PARAM_MAP(pdev_param_sub_channel_marking, 332 PDEV_PARAM_SUB_CHANNEL_MARKING), 333 PARAM_MAP(pdev_param_ul_ppdu_duration, PDEV_PARAM_SET_UL_PPDU_DURATION), 334 PARAM_MAP(pdev_param_equal_ru_allocation_enable, 335 PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE), 336 PARAM_MAP(pdev_param_per_peer_prd_cfr_enable, 337 PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE), 338 PARAM_MAP(pdev_param_nav_override_config, 339 PDEV_PARAM_NAV_OVERRIDE_CONFIG), 340 PARAM_MAP(pdev_param_set_mgmt_ttl, PDEV_PARAM_SET_MGMT_TTL), 341 PARAM_MAP(pdev_param_set_prb_rsp_ttl, 342 PDEV_PARAM_SET_PROBE_RESP_TTL), 343 PARAM_MAP(pdev_param_set_mu_ppdu_duration, 344 PDEV_PARAM_SET_MU_PPDU_DURATION), 345 PARAM_MAP(pdev_param_set_tbtt_ctrl, 346 PDEV_PARAM_SET_TBTT_CTRL), 347 PARAM_MAP(pdev_param_set_cmd_obss_pd_threshold, 348 PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 349 PARAM_MAP(pdev_param_set_cmd_obss_pd_per_ac, 350 PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC), 351 PARAM_MAP(pdev_param_set_cong_ctrl_max_msdus, 352 PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS), 353 PARAM_MAP(pdev_param_enable_fw_dynamic_he_edca, 354 PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA), 355 PARAM_MAP(pdev_param_enable_srp, PDEV_PARAM_ENABLE_SRP), 356 PARAM_MAP(pdev_param_enable_sr_prohibit, PDEV_PARAM_ENABLE_SR_PROHIBIT), 357 PARAM_MAP(pdev_param_sr_trigger_margin, PDEV_PARAM_SR_TRIGGER_MARGIN), 358 PARAM_MAP(pdev_param_pream_punct_bw, PDEV_PARAM_SET_PREAM_PUNCT_BW), 359 PARAM_MAP(pdev_param_enable_mbssid_ctrl_frame, 360 PDEV_PARAM_ENABLE_MBSSID_CTRL_FRAME), 361 PARAM_MAP(pdev_param_set_mesh_params, PDEV_PARAM_SET_MESH_PARAMS), 362 PARAM_MAP(pdev_param_mpd_userpd_ssr, PDEV_PARAM_MPD_USERPD_SSR), 363 PARAM_MAP(pdev_param_low_latency_mode, 364 PDEV_PARAM_LOW_LATENCY_SCHED_MODE), 365 PARAM_MAP(pdev_param_scan_radio_tx_on_dfs, 366 PDEV_PARAM_SCAN_RADIO_TX_ON_DFS), 367 PARAM_MAP(pdev_param_en_probe_all_bw, 368 PDEV_PARAM_EN_PROBE_ALL_BW), 369 PARAM_MAP(pdev_param_obss_min_duration_check_for_sr, 370 PDEV_PARAM_OBSS_MIN_DURATION_CHECK_FOR_SR), 371 PARAM_MAP(pdev_param_truncate_sr, PDEV_PARAM_TRUNCATE_SR), 372 PARAM_MAP(pdev_param_ctrl_frame_obss_pd_threshold, 373 PDEV_PARAM_CTRL_FRAME_OBSS_PD_THRESHOLD), 374 PARAM_MAP(pdev_param_rate_upper_cap, PDEV_PARAM_RATE_UPPER_CAP), 375 PARAM_MAP(pdev_param_set_disabled_sched_modes, 376 PDEV_PARAM_SET_DISABLED_SCHED_MODES), 377 PARAM_MAP(pdev_param_rate_retry_mcs_drop, 378 PDEV_PARAM_SET_RATE_DROP_DOWN_RETRY_THRESH), 379 PARAM_MAP(pdev_param_mcs_probe_intvl, 380 PDEV_PARAM_MIN_MAX_MCS_PROBE_INTERVAL), 381 PARAM_MAP(pdev_param_nss_probe_intvl, 382 PDEV_PARAM_MIN_MAX_NSS_PROBE_INTERVAL), 383 PARAM_MAP(pdev_param_dtim_synth, PDEV_PARAM_DTIM_SYNTH), 384 PARAM_MAP(pdev_param_1ch_dtim_optimized_chain_selection, 385 PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION), 386 PARAM_MAP(pdev_param_tx_sch_delay, PDEV_PARAM_TX_SCH_DELAY), 387 PARAM_MAP(pdev_param_en_update_scram_seed, 388 PDEV_PARAM_EN_UPDATE_SCRAM_SEED), 389 PARAM_MAP(pdev_param_secondary_retry_enable, 390 PDEV_PARAM_SECONDARY_RETRY_ENABLE), 391 PARAM_MAP(pdev_param_set_sap_xlna_bypass, 392 PDEV_PARAM_SET_SAP_XLNA_BYPASS), 393 PARAM_MAP(pdev_param_set_dfs_chan_ageout_time, 394 PDEV_PARAM_SET_DFS_CHAN_AGEOUT_TIME), 395 PARAM_MAP(pdev_param_pdev_stats_tx_xretry_ext, 396 PDEV_PARAM_PDEV_STATS_TX_XRETRY_EXT), 397 PARAM_MAP(pdev_param_smart_chainmask_scheme, 398 PDEV_PARAM_SMART_CHAINMASK_SCHEME), 399 PARAM_MAP(pdev_param_alternative_chainmask_scheme, 400 PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME), 401 PARAM_MAP(pdev_param_enable_rts_sifs_bursting, 402 PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING), 403 PARAM_MAP(pdev_param_max_mpdus_in_ampdu, PDEV_PARAM_MAX_MPDUS_IN_AMPDU), 404 PARAM_MAP(pdev_param_set_iot_pattern, PDEV_PARAM_SET_IOT_PATTERN), 405 PARAM_MAP(pdev_param_mwscoex_scc_chavd_delay, 406 PDEV_PARAM_MWSCOEX_SCC_CHAVD_DELAY), 407 PARAM_MAP(pdev_param_mwscoex_pcc_chavd_delay, 408 PDEV_PARAM_MWSCOEX_PCC_CHAVD_DELAY), 409 PARAM_MAP(pdev_param_mwscoex_set_5gnr_pwr_limit, 410 PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT), 411 PARAM_MAP(pdev_param_mwscoex_4g_allow_quick_ftdm, 412 PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM), 413 PARAM_MAP(pdev_param_fast_pwr_transition, 414 PDEV_PARAM_FAST_PWR_TRANSITION), 415 PARAM_MAP(pdev_auto_detect_power_failure, 416 PDEV_AUTO_DETECT_POWER_FAILURE), 417 PARAM_MAP(pdev_param_gcmp_support_enable, 418 PDEV_PARAM_GCMP_SUPPORT_ENABLE), 419 PARAM_MAP(pdev_param_abg_mode_tx_chain_num, 420 PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM), 421 PARAM_MAP(pdev_param_peer_stats_info_enable, 422 PDEV_PARAM_PEER_STATS_INFO_ENABLE), 423 PARAM_MAP(pdev_param_enable_cck_txfir_override, 424 PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE), 425 PARAM_MAP(pdev_param_twt_ac_config, PDEV_PARAM_TWT_AC_CONFIG), 426 PARAM_MAP(pdev_param_pcie_hw_ilp, PDEV_PARAM_PCIE_HW_ILP), 427 PARAM_MAP(pdev_param_disable_hw_assist, PDEV_PARAM_DISABLE_HW_ASSIST), 428 PARAM_MAP(pdev_param_ant_div_usrcfg, PDEV_PARAM_ANT_DIV_USRCFG), 429 PARAM_MAP(pdev_param_ctrl_retry_limit, PDEV_PARAM_CTRL_RETRY_LIMIT), 430 PARAM_MAP(pdev_param_propagation_delay, PDEV_PARAM_PROPAGATION_DELAY), 431 PARAM_MAP(pdev_param_ena_ant_div, PDEV_PARAM_ENA_ANT_DIV), 432 PARAM_MAP(pdev_param_force_chain_ant, PDEV_PARAM_FORCE_CHAIN_ANT), 433 PARAM_MAP(pdev_param_ant_div_selftest, PDEV_PARAM_ANT_DIV_SELFTEST), 434 PARAM_MAP(pdev_param_ant_div_selftest_intvl, 435 PDEV_PARAM_ANT_DIV_SELFTEST_INTVL), 436 PARAM_MAP(pdev_param_1ch_dtim_optimized_chain_selection, 437 PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION), 438 PARAM_MAP(pdev_param_data_stall_detect_enable, 439 PDEV_PARAM_DATA_STALL_DETECT_ENABLE), 440 PARAM_MAP(pdev_param_max_mpdus_in_ampdu, 441 PDEV_PARAM_MAX_MPDUS_IN_AMPDU), 442 PARAM_MAP(pdev_param_stats_observation_period, 443 PDEV_PARAM_STATS_OBSERVATION_PERIOD), 444 PARAM_MAP(pdev_param_cts2self_for_p2p_go_config, 445 PDEV_PARAM_CTS2SELF_FOR_P2P_GO_CONFIG), 446 PARAM_MAP(pdev_param_txpower_reason_sar, PDEV_PARAM_TXPOWER_REASON_SAR), 447 PARAM_MAP(pdev_param_default_6ghz_rate, PDEV_PARAM_DEFAULT_6GHZ_RATE), 448 PARAM_MAP(pdev_param_scan_blanking_mode, 449 PDEV_PARAM_SET_SCAN_BLANKING_MODE), 450 PARAM_MAP(pdev_param_set_conc_low_latency_mode, 451 PDEV_PARAM_SET_CONC_LOW_LATENCY_MODE), 452 PARAM_MAP(pdev_param_rtt_11az_rsid_range, 453 PDEV_PARAM_RTT_11AZ_RSID_RANGE), 454 PARAM_MAP(pdev_param_pcie_config, PDEV_PARAM_PCIE_CONFIG), 455 PARAM_MAP(pdev_param_probe_resp_retry_limit, 456 PDEV_PARAM_PROBE_RESP_RETRY_LIMIT), 457 PARAM_MAP(pdev_param_cts_timeout, PDEV_PARAM_CTS_TIMEOUT), 458 PARAM_MAP(pdev_param_slot_time, PDEV_PARAM_SLOT_TIME), 459 PARAM_MAP(pdev_param_atf_vo_dedicated_time, 460 PDEV_PARAM_ATF_VO_DEDICATED_TIME), 461 PARAM_MAP(pdev_param_atf_vi_dedicated_time, 462 PDEV_PARAM_ATF_VI_DEDICATED_TIME), 463 PARAM_MAP(pdev_param_ul_ofdma_rtd, PDEV_PARAM_UL_OFDMA_RTD), 464 PARAM_MAP(pdev_param_tid_mapping_3link_mlo, 465 PDEV_PARAM_TID_MAPPING_3LINK_MLO), 466 }; 467 468 /* Populate vdev_param array whose index is host param, value is target param */ 469 static const uint32_t vdev_param_tlv[] = { 470 PARAM_MAP(vdev_param_rts_threshold, VDEV_PARAM_RTS_THRESHOLD), 471 PARAM_MAP(vdev_param_fragmentation_threshold, 472 VDEV_PARAM_FRAGMENTATION_THRESHOLD), 473 PARAM_MAP(vdev_param_beacon_interval, VDEV_PARAM_BEACON_INTERVAL), 474 PARAM_MAP(vdev_param_listen_interval, VDEV_PARAM_LISTEN_INTERVAL), 475 PARAM_MAP(vdev_param_multicast_rate, VDEV_PARAM_MULTICAST_RATE), 476 PARAM_MAP(vdev_param_mgmt_tx_rate, VDEV_PARAM_MGMT_TX_RATE), 477 PARAM_MAP(vdev_param_slot_time, VDEV_PARAM_SLOT_TIME), 478 PARAM_MAP(vdev_param_preamble, VDEV_PARAM_PREAMBLE), 479 PARAM_MAP(vdev_param_swba_time, VDEV_PARAM_SWBA_TIME), 480 PARAM_MAP(vdev_stats_update_period, VDEV_STATS_UPDATE_PERIOD), 481 PARAM_MAP(vdev_pwrsave_ageout_time, VDEV_PWRSAVE_AGEOUT_TIME), 482 PARAM_MAP(vdev_host_swba_interval, VDEV_HOST_SWBA_INTERVAL), 483 PARAM_MAP(vdev_param_dtim_period, VDEV_PARAM_DTIM_PERIOD), 484 PARAM_MAP(vdev_oc_scheduler_air_time_limit, 485 VDEV_OC_SCHEDULER_AIR_TIME_LIMIT), 486 PARAM_MAP(vdev_param_wds, VDEV_PARAM_WDS), 487 PARAM_MAP(vdev_param_atim_window, VDEV_PARAM_ATIM_WINDOW), 488 PARAM_MAP(vdev_param_bmiss_count_max, VDEV_PARAM_BMISS_COUNT_MAX), 489 PARAM_MAP(vdev_param_bmiss_first_bcnt, VDEV_PARAM_BMISS_FIRST_BCNT), 490 PARAM_MAP(vdev_param_bmiss_final_bcnt, VDEV_PARAM_BMISS_FINAL_BCNT), 491 PARAM_MAP(vdev_param_feature_wmm, VDEV_PARAM_FEATURE_WMM), 492 PARAM_MAP(vdev_param_chwidth, VDEV_PARAM_CHWIDTH), 493 PARAM_MAP(vdev_param_chextoffset, VDEV_PARAM_CHEXTOFFSET), 494 PARAM_MAP(vdev_param_disable_htprotection, 495 VDEV_PARAM_DISABLE_HTPROTECTION), 496 PARAM_MAP(vdev_param_sta_quickkickout, VDEV_PARAM_STA_QUICKKICKOUT), 497 PARAM_MAP(vdev_param_mgmt_rate, VDEV_PARAM_MGMT_RATE), 498 PARAM_MAP(vdev_param_protection_mode, VDEV_PARAM_PROTECTION_MODE), 499 PARAM_MAP(vdev_param_fixed_rate, VDEV_PARAM_FIXED_RATE), 500 PARAM_MAP(vdev_param_sgi, VDEV_PARAM_SGI), 501 PARAM_MAP(vdev_param_ldpc, VDEV_PARAM_LDPC), 502 PARAM_MAP(vdev_param_tx_stbc, VDEV_PARAM_TX_STBC), 503 PARAM_MAP(vdev_param_rx_stbc, VDEV_PARAM_RX_STBC), 504 PARAM_MAP(vdev_param_intra_bss_fwd, VDEV_PARAM_INTRA_BSS_FWD), 505 PARAM_MAP(vdev_param_def_keyid, VDEV_PARAM_DEF_KEYID), 506 PARAM_MAP(vdev_param_nss, VDEV_PARAM_NSS), 507 PARAM_MAP(vdev_param_bcast_data_rate, VDEV_PARAM_BCAST_DATA_RATE), 508 PARAM_MAP(vdev_param_mcast_data_rate, VDEV_PARAM_MCAST_DATA_RATE), 509 PARAM_MAP(vdev_param_mcast_indicate, VDEV_PARAM_MCAST_INDICATE), 510 PARAM_MAP(vdev_param_dhcp_indicate, VDEV_PARAM_DHCP_INDICATE), 511 PARAM_MAP(vdev_param_unknown_dest_indicate, 512 VDEV_PARAM_UNKNOWN_DEST_INDICATE), 513 PARAM_MAP(vdev_param_ap_keepalive_min_idle_inactive_time_secs, 514 VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS), 515 PARAM_MAP(vdev_param_ap_keepalive_max_idle_inactive_time_secs, 516 VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS), 517 PARAM_MAP(vdev_param_ap_keepalive_max_unresponsive_time_secs, 518 VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS), 519 PARAM_MAP(vdev_param_ap_enable_nawds, VDEV_PARAM_AP_ENABLE_NAWDS), 520 PARAM_MAP(vdev_param_enable_rtscts, VDEV_PARAM_ENABLE_RTSCTS), 521 PARAM_MAP(vdev_param_txbf, VDEV_PARAM_TXBF), 522 PARAM_MAP(vdev_param_packet_powersave, VDEV_PARAM_PACKET_POWERSAVE), 523 PARAM_MAP(vdev_param_drop_unencry, VDEV_PARAM_DROP_UNENCRY), 524 PARAM_MAP(vdev_param_tx_encap_type, VDEV_PARAM_TX_ENCAP_TYPE), 525 PARAM_MAP(vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs, 526 VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS), 527 PARAM_MAP(vdev_param_early_rx_adjust_enable, 528 VDEV_PARAM_EARLY_RX_ADJUST_ENABLE), 529 PARAM_MAP(vdev_param_early_rx_tgt_bmiss_num, 530 VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM), 531 PARAM_MAP(vdev_param_early_rx_bmiss_sample_cycle, 532 VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE), 533 PARAM_MAP(vdev_param_early_rx_slop_step, VDEV_PARAM_EARLY_RX_SLOP_STEP), 534 PARAM_MAP(vdev_param_early_rx_init_slop, VDEV_PARAM_EARLY_RX_INIT_SLOP), 535 PARAM_MAP(vdev_param_early_rx_adjust_pause, 536 VDEV_PARAM_EARLY_RX_ADJUST_PAUSE), 537 PARAM_MAP(vdev_param_tx_pwrlimit, VDEV_PARAM_TX_PWRLIMIT), 538 PARAM_MAP(vdev_param_snr_num_for_cal, VDEV_PARAM_SNR_NUM_FOR_CAL), 539 PARAM_MAP(vdev_param_roam_fw_offload, VDEV_PARAM_ROAM_FW_OFFLOAD), 540 PARAM_MAP(vdev_param_enable_rmc, VDEV_PARAM_ENABLE_RMC), 541 PARAM_MAP(vdev_param_ibss_max_bcn_lost_ms, 542 VDEV_PARAM_IBSS_MAX_BCN_LOST_MS), 543 PARAM_MAP(vdev_param_max_rate, VDEV_PARAM_MAX_RATE), 544 PARAM_MAP(vdev_param_early_rx_drift_sample, 545 VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE), 546 PARAM_MAP(vdev_param_set_ibss_tx_fail_cnt_thr, 547 VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR), 548 PARAM_MAP(vdev_param_ebt_resync_timeout, 549 VDEV_PARAM_EBT_RESYNC_TIMEOUT), 550 PARAM_MAP(vdev_param_aggr_trig_event_enable, 551 VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE), 552 PARAM_MAP(vdev_param_is_ibss_power_save_allowed, 553 VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED), 554 PARAM_MAP(vdev_param_is_power_collapse_allowed, 555 VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED), 556 PARAM_MAP(vdev_param_is_awake_on_txrx_enabled, 557 VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED), 558 PARAM_MAP(vdev_param_inactivity_cnt, VDEV_PARAM_INACTIVITY_CNT), 559 PARAM_MAP(vdev_param_txsp_end_inactivity_time_ms, 560 VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS), 561 PARAM_MAP(vdev_param_dtim_policy, VDEV_PARAM_DTIM_POLICY), 562 PARAM_MAP(vdev_param_ibss_ps_warmup_time_secs, 563 VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS), 564 PARAM_MAP(vdev_param_ibss_ps_1rx_chain_in_atim_window_enable, 565 VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE), 566 PARAM_MAP(vdev_param_rx_leak_window, VDEV_PARAM_RX_LEAK_WINDOW), 567 PARAM_MAP(vdev_param_stats_avg_factor, 568 VDEV_PARAM_STATS_AVG_FACTOR), 569 PARAM_MAP(vdev_param_disconnect_th, VDEV_PARAM_DISCONNECT_TH), 570 PARAM_MAP(vdev_param_rtscts_rate, VDEV_PARAM_RTSCTS_RATE), 571 PARAM_MAP(vdev_param_mcc_rtscts_protection_enable, 572 VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE), 573 PARAM_MAP(vdev_param_mcc_broadcast_probe_enable, 574 VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE), 575 PARAM_MAP(vdev_param_mgmt_tx_power, VDEV_PARAM_MGMT_TX_POWER), 576 PARAM_MAP(vdev_param_beacon_rate, VDEV_PARAM_BEACON_RATE), 577 PARAM_MAP(vdev_param_rx_decap_type, VDEV_PARAM_RX_DECAP_TYPE), 578 PARAM_MAP(vdev_param_he_dcm_enable, VDEV_PARAM_HE_DCM), 579 PARAM_MAP(vdev_param_he_range_ext_enable, VDEV_PARAM_HE_RANGE_EXT), 580 PARAM_MAP(vdev_param_he_bss_color, VDEV_PARAM_BSS_COLOR), 581 PARAM_MAP(vdev_param_set_hemu_mode, VDEV_PARAM_SET_HEMU_MODE), 582 PARAM_MAP(vdev_param_set_he_sounding_mode, 583 VDEV_PARAM_SET_HE_SOUNDING_MODE), 584 PARAM_MAP(vdev_param_set_heop, VDEV_PARAM_HEOPS_0_31), 585 PARAM_MAP(vdev_param_set_ehtop, VDEV_PARAM_EHTOPS_0_31), 586 PARAM_MAP(vdev_param_set_eht_mu_mode, VDEV_PARAM_SET_EHT_MU_MODE), 587 PARAM_MAP(vdev_param_set_eht_puncturing_mode, 588 VDEV_PARAM_SET_EHT_PUNCTURING_MODE), 589 PARAM_MAP(vdev_param_set_eht_ltf, VDEV_PARAM_EHT_LTF), 590 PARAM_MAP(vdev_param_set_ul_eht_ltf, VDEV_PARAM_UL_EHT_LTF), 591 PARAM_MAP(vdev_param_set_eht_dcm, VDEV_PARAM_EHT_DCM), 592 PARAM_MAP(vdev_param_set_eht_range_ext, VDEV_PARAM_EHT_RANGE_EXT), 593 PARAM_MAP(vdev_param_set_non_data_eht_range_ext, 594 VDEV_PARAM_NON_DATA_EHT_RANGE_EXT), 595 PARAM_MAP(vdev_param_sensor_ap, VDEV_PARAM_SENSOR_AP), 596 PARAM_MAP(vdev_param_dtim_enable_cts, VDEV_PARAM_DTIM_ENABLE_CTS), 597 PARAM_MAP(vdev_param_atf_ssid_sched_policy, 598 VDEV_PARAM_ATF_SSID_SCHED_POLICY), 599 PARAM_MAP(vdev_param_disable_dyn_bw_rts, VDEV_PARAM_DISABLE_DYN_BW_RTS), 600 PARAM_MAP(vdev_param_mcast2ucast_set, VDEV_PARAM_MCAST2UCAST_SET), 601 PARAM_MAP(vdev_param_rc_num_retries, VDEV_PARAM_RC_NUM_RETRIES), 602 PARAM_MAP(vdev_param_cabq_maxdur, VDEV_PARAM_CABQ_MAXDUR), 603 PARAM_MAP(vdev_param_mfptest_set, VDEV_PARAM_MFPTEST_SET), 604 PARAM_MAP(vdev_param_rts_fixed_rate, VDEV_PARAM_RTS_FIXED_RATE), 605 PARAM_MAP(vdev_param_vht_sgimask, VDEV_PARAM_VHT_SGIMASK), 606 PARAM_MAP(vdev_param_vht80_ratemask, VDEV_PARAM_VHT80_RATEMASK), 607 PARAM_MAP(vdev_param_proxy_sta, VDEV_PARAM_PROXY_STA), 608 PARAM_MAP(vdev_param_bw_nss_ratemask, VDEV_PARAM_BW_NSS_RATEMASK), 609 PARAM_MAP(vdev_param_set_he_ltf, VDEV_PARAM_HE_LTF), 610 PARAM_MAP(vdev_param_disable_cabq, VDEV_PARAM_DISABLE_CABQ), 611 PARAM_MAP(vdev_param_rate_dropdown_bmap, VDEV_PARAM_RATE_DROPDOWN_BMAP), 612 PARAM_MAP(vdev_param_set_ba_mode, VDEV_PARAM_BA_MODE), 613 PARAM_MAP(vdev_param_capabilities, VDEV_PARAM_CAPABILITIES), 614 PARAM_MAP(vdev_param_autorate_misc_cfg, VDEV_PARAM_AUTORATE_MISC_CFG), 615 PARAM_MAP(vdev_param_ul_shortgi, VDEV_PARAM_UL_GI), 616 PARAM_MAP(vdev_param_ul_he_ltf, VDEV_PARAM_UL_HE_LTF), 617 PARAM_MAP(vdev_param_ul_nss, VDEV_PARAM_UL_NSS), 618 PARAM_MAP(vdev_param_ul_ppdu_bw, VDEV_PARAM_UL_PPDU_BW), 619 PARAM_MAP(vdev_param_ul_ldpc, VDEV_PARAM_UL_LDPC), 620 PARAM_MAP(vdev_param_ul_stbc, VDEV_PARAM_UL_STBC), 621 PARAM_MAP(vdev_param_ul_fixed_rate, VDEV_PARAM_UL_FIXED_RATE), 622 PARAM_MAP(vdev_param_rawmode_open_war, VDEV_PARAM_RAW_IS_ENCRYPTED), 623 PARAM_MAP(vdev_param_max_mtu_size, VDEV_PARAM_MAX_MTU_SIZE), 624 PARAM_MAP(vdev_param_mcast_rc_stale_period, 625 VDEV_PARAM_MCAST_RC_STALE_PERIOD), 626 PARAM_MAP(vdev_param_enable_multi_group_key, 627 VDEV_PARAM_ENABLE_MULTI_GROUP_KEY), 628 PARAM_MAP(vdev_param_max_group_keys, VDEV_PARAM_NUM_GROUP_KEYS), 629 PARAM_MAP(vdev_param_enable_mcast_rc, VDEV_PARAM_ENABLE_MCAST_RC), 630 PARAM_MAP(vdev_param_6ghz_params, VDEV_PARAM_6GHZ_PARAMS), 631 PARAM_MAP(vdev_param_enable_disable_roam_reason_vsie, 632 VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE), 633 PARAM_MAP(vdev_param_set_cmd_obss_pd_threshold, 634 VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 635 PARAM_MAP(vdev_param_set_cmd_obss_pd_per_ac, 636 VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC), 637 PARAM_MAP(vdev_param_enable_srp, VDEV_PARAM_ENABLE_SRP), 638 PARAM_MAP(vdev_param_nan_config_features, 639 VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES), 640 PARAM_MAP(vdev_param_enable_disable_rtt_responder_role, 641 VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE), 642 PARAM_MAP(vdev_param_enable_disable_rtt_initiator_role, 643 VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_ROLE), 644 PARAM_MAP(vdev_param_mcast_steer, VDEV_PARAM_MCAST_STEERING), 645 PARAM_MAP(vdev_param_set_normal_latency_flags_config, 646 VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION), 647 PARAM_MAP(vdev_param_set_xr_latency_flags_config, 648 VDEV_PARAM_XR_LATENCY_FLAGS_CONFIGURATION), 649 PARAM_MAP(vdev_param_set_low_latency_flags_config, 650 VDEV_PARAM_LOW_LATENCY_FLAGS_CONFIGURATION), 651 PARAM_MAP(vdev_param_set_ultra_low_latency_flags_config, 652 VDEV_PARAM_ULTRA_LOW_LATENCY_FLAGS_CONFIGURATION), 653 PARAM_MAP(vdev_param_set_normal_latency_ul_dl_config, 654 VDEV_PARAM_NORMAL_LATENCY_UL_DL_CONFIGURATION), 655 PARAM_MAP(vdev_param_set_xr_latency_ul_dl_config, 656 VDEV_PARAM_XR_LATENCY_UL_DL_CONFIGURATION), 657 PARAM_MAP(vdev_param_set_low_latency_ul_dl_config, 658 VDEV_PARAM_LOW_LATENCY_UL_DL_CONFIGURATION), 659 PARAM_MAP(vdev_param_set_ultra_low_latency_ul_dl_config, 660 VDEV_PARAM_ULTRA_LOW_LATENCY_UL_DL_CONFIGURATION), 661 PARAM_MAP(vdev_param_set_default_ll_config, 662 VDEV_PARAM_DEFAULT_LATENCY_LEVEL_CONFIGURATION), 663 PARAM_MAP(vdev_param_set_multi_client_ll_feature_config, 664 VDEV_PARAM_MULTI_CLIENT_LL_FEATURE_CONFIGURATION), 665 PARAM_MAP(vdev_param_set_traffic_config, 666 VDEV_PARAM_VDEV_TRAFFIC_CONFIG), 667 PARAM_MAP(vdev_param_he_range_ext, VDEV_PARAM_HE_RANGE_EXT), 668 PARAM_MAP(vdev_param_non_data_he_range_ext, 669 VDEV_PARAM_NON_DATA_HE_RANGE_EXT), 670 PARAM_MAP(vdev_param_ndp_inactivity_timeout, 671 VDEV_PARAM_NDP_INACTIVITY_TIMEOUT), 672 PARAM_MAP(vdev_param_ndp_keepalive_timeout, 673 VDEV_PARAM_NDP_KEEPALIVE_TIMEOUT), 674 PARAM_MAP(vdev_param_final_bmiss_time_sec, 675 VDEV_PARAM_FINAL_BMISS_TIME_SEC), 676 PARAM_MAP(vdev_param_final_bmiss_time_wow_sec, 677 VDEV_PARAM_FINAL_BMISS_TIME_WOW_SEC), 678 PARAM_MAP(vdev_param_ap_keepalive_max_idle_inactive_secs, 679 VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS), 680 PARAM_MAP(vdev_param_per_band_mgmt_tx_rate, 681 VDEV_PARAM_PER_BAND_MGMT_TX_RATE), 682 PARAM_MAP(vdev_param_max_li_of_moddtim, 683 VDEV_PARAM_MAX_LI_OF_MODDTIM), 684 PARAM_MAP(vdev_param_moddtim_cnt, VDEV_PARAM_MODDTIM_CNT), 685 PARAM_MAP(vdev_param_max_li_of_moddtim_ms, 686 VDEV_PARAM_MAX_LI_OF_MODDTIM_MS), 687 PARAM_MAP(vdev_param_dyndtim_cnt, VDEV_PARAM_DYNDTIM_CNT), 688 PARAM_MAP(vdev_param_wmm_txop_enable, VDEV_PARAM_WMM_TXOP_ENABLE), 689 PARAM_MAP(vdev_param_enable_bcast_probe_response, 690 VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE), 691 PARAM_MAP(vdev_param_fils_max_channel_guard_time, 692 VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME), 693 PARAM_MAP(vdev_param_probe_delay, VDEV_PARAM_PROBE_DELAY), 694 PARAM_MAP(vdev_param_repeat_probe_time, VDEV_PARAM_REPEAT_PROBE_TIME), 695 PARAM_MAP(vdev_param_enable_disable_oce_features, 696 VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES), 697 PARAM_MAP(vdev_param_enable_disable_nan_config_features, 698 VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES), 699 PARAM_MAP(vdev_param_rsn_capability, VDEV_PARAM_RSN_CAPABILITY), 700 PARAM_MAP(vdev_param_smps_intolerant, VDEV_PARAM_SMPS_INTOLERANT), 701 PARAM_MAP(vdev_param_abg_mode_tx_chain_num, 702 VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM), 703 PARAM_MAP(vdev_param_nth_beacon_to_host, VDEV_PARAM_NTH_BEACON_TO_HOST), 704 PARAM_MAP(vdev_param_prohibit_data_mgmt, VDEV_PARAM_PROHIBIT_DATA_MGMT), 705 PARAM_MAP(vdev_param_skip_roam_eapol_4way_handshake, 706 VDEV_PARAM_SKIP_ROAM_EAPOL_4WAY_HANDSHAKE), 707 PARAM_MAP(vdev_param_skip_sae_roam_4way_handshake, 708 VDEV_PARAM_SKIP_SAE_ROAM_4WAY_HANDSHAKE), 709 PARAM_MAP(vdev_param_roam_11kv_ctrl, VDEV_PARAM_ROAM_11KV_CTRL), 710 PARAM_MAP(vdev_param_disable_noa_p2p_go, VDEV_PARAM_DISABLE_NOA_P2P_GO), 711 PARAM_MAP(vdev_param_packet_capture_mode, 712 VDEV_PARAM_PACKET_CAPTURE_MODE), 713 PARAM_MAP(vdev_param_smart_monitor_config, 714 VDEV_PARAM_SMART_MONITOR_CONFIG), 715 PARAM_MAP(vdev_param_force_dtim_cnt, VDEV_PARAM_FORCE_DTIM_CNT), 716 PARAM_MAP(vdev_param_sho_config, VDEV_PARAM_SHO_CONFIG), 717 PARAM_MAP(vdev_param_gtx_enable, VDEV_PARAM_GTX_ENABLE), 718 PARAM_MAP(vdev_param_mu_edca_fw_update_en, 719 VDEV_PARAM_MU_EDCA_FW_UPDATE_EN), 720 PARAM_MAP(vdev_param_enable_disable_rtt_initiator_random_mac, 721 VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC), 722 PARAM_MAP(vdev_param_allow_nan_initial_discovery_of_mp0_cluster, 723 VDEV_PARAM_ALLOW_NAN_INITIAL_DISCOVERY_OF_MP0_CLUSTER), 724 PARAM_MAP(vdev_param_txpower_scale_decr_db, 725 VDEV_PARAM_TXPOWER_SCALE_DECR_DB), 726 PARAM_MAP(vdev_param_txpower_scale, VDEV_PARAM_TXPOWER_SCALE), 727 PARAM_MAP(vdev_param_agg_sw_retry_th, VDEV_PARAM_AGG_SW_RETRY_TH), 728 PARAM_MAP(vdev_param_obsspd, VDEV_PARAM_OBSSPD), 729 PARAM_MAP(vdev_param_amsdu_aggregation_size_optimization, 730 VDEV_PARAM_AMSDU_AGGREGATION_SIZE_OPTIMIZATION), 731 PARAM_MAP(vdev_param_non_agg_sw_retry_th, 732 VDEV_PARAM_NON_AGG_SW_RETRY_TH), 733 PARAM_MAP(vdev_param_set_cmd_obss_pd_threshold, 734 VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 735 PARAM_MAP(vdev_param_set_profile, 736 VDEV_PARAM_SET_PROFILE), 737 PARAM_MAP(vdev_param_set_disabled_modes, 738 VDEV_PARAM_SET_DISABLED_SCHED_MODES), 739 PARAM_MAP(vdev_param_set_sap_ps_with_twt, 740 VDEV_PARAM_SET_SAP_PS_WITH_TWT), 741 PARAM_MAP(vdev_param_rtt_11az_tb_max_session_expiry, 742 VDEV_PARAM_RTT_11AZ_TB_MAX_SESSION_EXPIRY), 743 PARAM_MAP(vdev_param_wifi_standard_version, 744 VDEV_PARAM_WIFI_STANDARD_VERSION), 745 PARAM_MAP(vdev_param_rtt_11az_ntb_max_time_bw_meas, 746 VDEV_PARAM_RTT_11AZ_NTB_MAX_TIME_BW_MEAS), 747 PARAM_MAP(vdev_param_rtt_11az_ntb_min_time_bw_meas, 748 VDEV_PARAM_RTT_11AZ_NTB_MIN_TIME_BW_MEAS), 749 PARAM_MAP(vdev_param_11az_security_config, 750 VDEV_PARAM_11AZ_SECURITY_CONFIG), 751 PARAM_MAP(vdev_param_mlo_max_recom_active_links, 752 VDEV_PARAM_MLO_MAX_RECOM_ACTIVE_LINKS), 753 }; 754 #endif 755 756 #ifndef WMI_PKTLOG_EVENT_CBF 757 #define WMI_PKTLOG_EVENT_CBF 0x100 758 #endif 759 760 /* 761 * Populate the pktlog event tlv array, where 762 * the values are the FW WMI events, which host 763 * uses to communicate with FW for pktlog 764 */ 765 766 static const uint32_t pktlog_event_tlv[] = { 767 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 768 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 769 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 770 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 771 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 772 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 773 WMI_PKTLOG_EVENT_SMART_ANTENNA, 774 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 775 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 776 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 777 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 778 [WMI_HOST_PKTLOG_EVENT_CBF_BIT] = WMI_PKTLOG_EVENT_CBF, 779 #ifdef BE_PKTLOG_SUPPORT 780 [WMI_HOST_PKTLOG_EVENT_HYBRID_TX_BIT] = WMI_PKTLOG_EVENT_HYBRID_TX, 781 #endif 782 }; 783 784 /** 785 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 786 * host to target defines. 787 * @wmi_handle: pointer to wmi_handle 788 * @pdev_id: host pdev_id to be converted. 789 * Return: target pdev_id after conversion. 790 */ 791 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 792 uint32_t pdev_id) 793 { 794 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 795 if (!wmi_handle->soc->is_pdev_is_map_enable) { 796 switch (pdev_id) { 797 case WMI_HOST_PDEV_ID_0: 798 return WMI_PDEV_ID_1ST; 799 case WMI_HOST_PDEV_ID_1: 800 return WMI_PDEV_ID_2ND; 801 case WMI_HOST_PDEV_ID_2: 802 return WMI_PDEV_ID_3RD; 803 } 804 } else { 805 return wmi_handle->cmd_pdev_id_map[pdev_id]; 806 } 807 } else { 808 return WMI_PDEV_ID_SOC; 809 } 810 811 QDF_ASSERT(0); 812 813 return WMI_PDEV_ID_SOC; 814 } 815 816 /** 817 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 818 * target to host defines. 819 * @wmi_handle: pointer to wmi_handle 820 * @pdev_id: target pdev_id to be converted. 821 * Return: host pdev_id after conversion. 822 */ 823 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 824 uint32_t pdev_id) 825 { 826 827 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 828 if (!wmi_handle->soc->is_pdev_is_map_enable) { 829 switch (pdev_id) { 830 case WMI_PDEV_ID_1ST: 831 return WMI_HOST_PDEV_ID_0; 832 case WMI_PDEV_ID_2ND: 833 return WMI_HOST_PDEV_ID_1; 834 case WMI_PDEV_ID_3RD: 835 return WMI_HOST_PDEV_ID_2; 836 } 837 } else { 838 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 839 } 840 } else if (pdev_id == WMI_PDEV_ID_SOC) { 841 return WMI_HOST_PDEV_ID_SOC; 842 } else { 843 wmi_err("Invalid pdev_id"); 844 } 845 846 return WMI_HOST_PDEV_ID_INVALID; 847 } 848 849 /** 850 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 851 * host to target defines. 852 * @wmi_handle: pointer to wmi_handle 853 * @phy_id: host pdev_id to be converted. 854 * Return: target phy_id after conversion. 855 */ 856 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 857 uint32_t phy_id) 858 { 859 if (!wmi_handle->soc->is_phy_id_map_enable || 860 phy_id >= WMI_MAX_RADIOS) { 861 return phy_id; 862 } 863 864 return wmi_handle->cmd_phy_id_map[phy_id]; 865 } 866 867 /** 868 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 869 * target to host defines. 870 * @wmi_handle: pointer to wmi_handle 871 * @phy_id: target phy_id to be converted. 872 * Return: host phy_id after conversion. 873 */ 874 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 875 uint32_t phy_id) 876 { 877 if (!wmi_handle->soc->is_phy_id_map_enable || 878 phy_id >= WMI_MAX_RADIOS) { 879 return phy_id; 880 } 881 882 return wmi_handle->evt_phy_id_map[phy_id]; 883 } 884 885 /** 886 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 887 * @wmi_handle: WMI handle 888 * @pdev_id_map: pointer to mapping table 889 * @size: number of entries in @pdev_id_map 890 * 891 * Return: None. 892 */ 893 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 894 uint32_t *pdev_id_map, 895 uint8_t size) 896 { 897 int i = 0; 898 899 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 900 for (i = 0; i < size; i++) { 901 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 902 wmi_handle->evt_pdev_id_map[i] = 903 WMI_HOST_PDEV_ID_INVALID; 904 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 905 wmi_handle->evt_phy_id_map[i] = 906 WMI_HOST_PDEV_ID_INVALID; 907 } 908 909 for (i = 0; i < size; i++) { 910 if (wmi_handle->cmd_pdev_id_map[i] != 911 WMI_HOST_PDEV_ID_INVALID) { 912 wmi_handle->evt_pdev_id_map 913 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 914 } 915 if (wmi_handle->cmd_phy_id_map[i] != 916 WMI_HOST_PDEV_ID_INVALID) { 917 wmi_handle->evt_phy_id_map 918 [wmi_handle->cmd_phy_id_map[i]] = i; 919 } 920 } 921 wmi_handle->soc->is_pdev_is_map_enable = true; 922 wmi_handle->soc->is_phy_id_map_enable = true; 923 } else { 924 wmi_handle->soc->is_pdev_is_map_enable = false; 925 wmi_handle->soc->is_phy_id_map_enable = false; 926 } 927 928 wmi_handle->ops->convert_pdev_id_host_to_target = 929 convert_host_pdev_id_to_target_pdev_id; 930 wmi_handle->ops->convert_pdev_id_target_to_host = 931 convert_target_pdev_id_to_host_pdev_id; 932 933 /* phy_id convert function assignments */ 934 wmi_handle->ops->convert_phy_id_host_to_target = 935 convert_host_phy_id_to_target_phy_id; 936 wmi_handle->ops->convert_phy_id_target_to_host = 937 convert_target_phy_id_to_host_phy_id; 938 } 939 940 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 941 * buffer. 942 * @wmi_handle: pointer to wmi_handle 943 * @cmd: pointer target vdev create command buffer 944 * @param: pointer host params for vdev create 945 * 946 * Return: None 947 */ 948 static inline void copy_vdev_create_pdev_id( 949 struct wmi_unified *wmi_handle, 950 wmi_vdev_create_cmd_fixed_param * cmd, 951 struct vdev_create_params *param) 952 { 953 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 954 wmi_handle, 955 param->pdev_id); 956 } 957 958 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 959 { 960 uint16_t mtrace_message_id; 961 962 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 963 (QDF_WMI_MTRACE_GRP_ID(message_id) << 964 QDF_WMI_MTRACE_CMD_NUM_BITS); 965 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 966 mtrace_message_id, vdev_id, data); 967 } 968 qdf_export_symbol(wmi_mtrace); 969 970 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 971 wmi_buf_t buf, 972 uint32_t buflen, uint32_t cmd_id, 973 bool is_qmi_send_support) 974 { 975 if (!is_qmi_send_support) 976 goto send_over_wmi; 977 978 if (!wmi_is_qmi_stats_enabled(wmi_handle)) 979 goto send_over_wmi; 980 981 if (wmi_is_target_suspended(wmi_handle)) { 982 if (QDF_IS_STATUS_SUCCESS( 983 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 984 buflen, cmd_id))) 985 return QDF_STATUS_SUCCESS; 986 } 987 988 send_over_wmi: 989 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 990 991 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 992 } 993 994 /** 995 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 996 * @wmi_handle: wmi handle 997 * @param: pointer to hold vdev create parameter 998 * @macaddr: vdev mac address 999 * 1000 * Return: QDF_STATUS_SUCCESS for success or error code 1001 */ 1002 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 1003 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 1004 struct vdev_create_params *param) 1005 { 1006 wmi_vdev_create_cmd_fixed_param *cmd; 1007 wmi_buf_t buf; 1008 int32_t len = sizeof(*cmd); 1009 QDF_STATUS ret; 1010 int num_bands = 2; 1011 uint8_t *buf_ptr; 1012 wmi_vdev_txrx_streams *txrx_streams; 1013 1014 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 1015 len += vdev_create_mlo_params_size(param); 1016 1017 buf = wmi_buf_alloc(wmi_handle, len); 1018 if (!buf) 1019 return QDF_STATUS_E_NOMEM; 1020 1021 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 1022 WMITLV_SET_HDR(&cmd->tlv_header, 1023 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 1024 WMITLV_GET_STRUCT_TLVLEN 1025 (wmi_vdev_create_cmd_fixed_param)); 1026 cmd->vdev_id = param->vdev_id; 1027 cmd->vdev_type = param->type; 1028 cmd->vdev_subtype = param->subtype; 1029 cmd->flags = param->mbssid_flags; 1030 cmd->flags |= (param->special_vdev_mode ? VDEV_FLAGS_SCAN_MODE_VAP : 0); 1031 cmd->vdevid_trans = param->vdevid_trans; 1032 cmd->num_cfg_txrx_streams = num_bands; 1033 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 1034 cmd->vdev_stats_id_valid = param->vdev_stats_id_valid; 1035 cmd->vdev_stats_id = param->vdev_stats_id; 1036 #endif 1037 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 1038 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 1039 wmi_debug("ID = %d[pdev:%d] VAP Addr = "QDF_MAC_ADDR_FMT, 1040 param->vdev_id, cmd->pdev_id, 1041 QDF_MAC_ADDR_REF(macaddr)); 1042 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 1043 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1044 (num_bands * sizeof(wmi_vdev_txrx_streams))); 1045 buf_ptr += WMI_TLV_HDR_SIZE; 1046 1047 wmi_debug("type %d, subtype %d, nss_2g %d, nss_5g %d", 1048 param->type, param->subtype, 1049 param->nss_2g, param->nss_5g); 1050 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 1051 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 1052 txrx_streams->supported_tx_streams = param->nss_2g; 1053 txrx_streams->supported_rx_streams = param->nss_2g; 1054 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1055 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1056 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1057 1058 txrx_streams++; 1059 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 1060 txrx_streams->supported_tx_streams = param->nss_5g; 1061 txrx_streams->supported_rx_streams = param->nss_5g; 1062 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1063 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1064 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1065 1066 buf_ptr += (num_bands * sizeof(wmi_vdev_txrx_streams)); 1067 buf_ptr = vdev_create_add_mlo_params(buf_ptr, param); 1068 1069 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 1070 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 1071 if (QDF_IS_STATUS_ERROR(ret)) { 1072 wmi_err("Failed to send WMI_VDEV_CREATE_CMDID"); 1073 wmi_buf_free(buf); 1074 } 1075 1076 return ret; 1077 } 1078 1079 /** 1080 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 1081 * @wmi_handle: wmi handle 1082 * @if_id: vdev id 1083 * 1084 * Return: QDF_STATUS_SUCCESS for success or error code 1085 */ 1086 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 1087 uint8_t if_id) 1088 { 1089 wmi_vdev_delete_cmd_fixed_param *cmd; 1090 wmi_buf_t buf; 1091 QDF_STATUS ret; 1092 1093 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1094 if (!buf) 1095 return QDF_STATUS_E_NOMEM; 1096 1097 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 1098 WMITLV_SET_HDR(&cmd->tlv_header, 1099 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 1100 WMITLV_GET_STRUCT_TLVLEN 1101 (wmi_vdev_delete_cmd_fixed_param)); 1102 cmd->vdev_id = if_id; 1103 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 1104 ret = wmi_unified_cmd_send(wmi_handle, buf, 1105 sizeof(wmi_vdev_delete_cmd_fixed_param), 1106 WMI_VDEV_DELETE_CMDID); 1107 if (QDF_IS_STATUS_ERROR(ret)) { 1108 wmi_err("Failed to send WMI_VDEV_DELETE_CMDID"); 1109 wmi_buf_free(buf); 1110 } 1111 wmi_debug("vdev id = %d", if_id); 1112 1113 return ret; 1114 } 1115 1116 /** 1117 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 1118 * @wmi_handle: wmi handle 1119 * @vdev_id: vdev id 1120 * @user_cfg: user configured nss chain params 1121 * 1122 * Return: QDF_STATUS_SUCCESS for success or error code 1123 */ 1124 static QDF_STATUS 1125 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 1126 uint8_t vdev_id, 1127 struct vdev_nss_chains *user_cfg) 1128 { 1129 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 1130 wmi_buf_t buf; 1131 QDF_STATUS ret; 1132 1133 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1134 if (!buf) 1135 return QDF_STATUS_E_NOMEM; 1136 1137 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 1138 WMITLV_SET_HDR(&cmd->tlv_header, 1139 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 1140 WMITLV_GET_STRUCT_TLVLEN 1141 (wmi_vdev_chainmask_config_cmd_fixed_param)); 1142 cmd->vdev_id = vdev_id; 1143 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 1144 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 1145 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 1146 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 1147 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 1148 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 1149 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 1150 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 1151 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 1152 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 1153 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 1154 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 1155 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 1156 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 1157 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 1158 1159 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 1160 ret = wmi_unified_cmd_send(wmi_handle, buf, 1161 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 1162 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 1163 if (QDF_IS_STATUS_ERROR(ret)) { 1164 wmi_err("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 1165 wmi_buf_free(buf); 1166 } 1167 wmi_debug("vdev_id %d", vdev_id); 1168 1169 return ret; 1170 } 1171 1172 /** 1173 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 1174 * @wmi: wmi handle 1175 * @vdev_id: vdev id 1176 * 1177 * Return: QDF_STATUS_SUCCESS for success or error code 1178 */ 1179 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 1180 uint8_t vdev_id) 1181 { 1182 wmi_vdev_stop_cmd_fixed_param *cmd; 1183 wmi_buf_t buf; 1184 int32_t len = sizeof(*cmd); 1185 1186 buf = wmi_buf_alloc(wmi, len); 1187 if (!buf) 1188 return QDF_STATUS_E_NOMEM; 1189 1190 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 1191 WMITLV_SET_HDR(&cmd->tlv_header, 1192 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 1193 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 1194 cmd->vdev_id = vdev_id; 1195 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 1196 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 1197 wmi_err("Failed to send vdev stop command"); 1198 wmi_buf_free(buf); 1199 return QDF_STATUS_E_FAILURE; 1200 } 1201 wmi_debug("vdev id = %d", vdev_id); 1202 1203 return 0; 1204 } 1205 1206 /** 1207 * send_vdev_down_cmd_tlv() - send vdev down command to fw 1208 * @wmi: wmi handle 1209 * @vdev_id: vdev id 1210 * 1211 * Return: QDF_STATUS_SUCCESS for success or error code 1212 */ 1213 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 1214 { 1215 wmi_vdev_down_cmd_fixed_param *cmd; 1216 wmi_buf_t buf; 1217 int32_t len = sizeof(*cmd); 1218 1219 buf = wmi_buf_alloc(wmi, len); 1220 if (!buf) 1221 return QDF_STATUS_E_NOMEM; 1222 1223 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 1224 WMITLV_SET_HDR(&cmd->tlv_header, 1225 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 1226 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 1227 cmd->vdev_id = vdev_id; 1228 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 1229 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 1230 wmi_err("Failed to send vdev down"); 1231 wmi_buf_free(buf); 1232 return QDF_STATUS_E_FAILURE; 1233 } 1234 wmi_debug("vdev_id %d", vdev_id); 1235 1236 return 0; 1237 } 1238 1239 static inline void copy_channel_info( 1240 wmi_vdev_start_request_cmd_fixed_param * cmd, 1241 wmi_channel *chan, 1242 struct vdev_start_params *req) 1243 { 1244 chan->mhz = req->channel.mhz; 1245 1246 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 1247 1248 chan->band_center_freq1 = req->channel.cfreq1; 1249 chan->band_center_freq2 = req->channel.cfreq2; 1250 1251 if (req->channel.half_rate) 1252 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 1253 else if (req->channel.quarter_rate) 1254 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 1255 1256 if (req->channel.dfs_set) { 1257 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 1258 cmd->disable_hw_ack = req->disable_hw_ack; 1259 } 1260 1261 if (req->channel.dfs_set_cfreq2) 1262 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 1263 1264 if (req->channel.is_stadfs_en) 1265 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_STA_DFS); 1266 1267 /* According to firmware both reg power and max tx power 1268 * on set channel power is used and set it to max reg 1269 * power from regulatory. 1270 */ 1271 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 1272 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 1273 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 1274 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 1275 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 1276 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 1277 1278 } 1279 1280 /** 1281 * vdev_start_cmd_fill_11be() - 11be information filling in vdev_start 1282 * @cmd: wmi cmd 1283 * @req: vdev start params 1284 * 1285 * Return: QDF status 1286 */ 1287 #ifdef WLAN_FEATURE_11BE 1288 static void 1289 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1290 struct vdev_start_params *req) 1291 { 1292 cmd->eht_ops = req->eht_ops; 1293 cmd->puncture_20mhz_bitmap = ~req->channel.puncture_bitmap; 1294 wmi_info("EHT ops: %x puncture_bitmap %x wmi cmd puncture bitmap %x", 1295 req->eht_ops, req->channel.puncture_bitmap, 1296 cmd->puncture_20mhz_bitmap); 1297 } 1298 #else 1299 static void 1300 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1301 struct vdev_start_params *req) 1302 { 1303 } 1304 #endif 1305 1306 /** 1307 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1308 * @wmi_handle: wmi handle 1309 * @req: vdev start params 1310 * 1311 * Return: QDF status 1312 */ 1313 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1314 struct vdev_start_params *req) 1315 { 1316 wmi_vdev_start_request_cmd_fixed_param *cmd; 1317 wmi_buf_t buf; 1318 wmi_channel *chan; 1319 int32_t len, ret; 1320 uint8_t *buf_ptr; 1321 1322 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1323 if (!req->is_restart) 1324 len += vdev_start_mlo_params_size(req); 1325 buf = wmi_buf_alloc(wmi_handle, len); 1326 if (!buf) 1327 return QDF_STATUS_E_NOMEM; 1328 1329 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1330 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1331 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1332 WMITLV_SET_HDR(&cmd->tlv_header, 1333 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1334 WMITLV_GET_STRUCT_TLVLEN 1335 (wmi_vdev_start_request_cmd_fixed_param)); 1336 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1337 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1338 cmd->vdev_id = req->vdev_id; 1339 1340 /* Fill channel info */ 1341 copy_channel_info(cmd, chan, req); 1342 cmd->beacon_interval = req->beacon_interval; 1343 cmd->dtim_period = req->dtim_period; 1344 1345 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1346 if (req->bcn_tx_rate_code) 1347 wmi_enable_bcn_ratecode(&cmd->flags); 1348 1349 if (!req->is_restart) { 1350 if (req->pmf_enabled) 1351 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1352 1353 cmd->mbss_capability_flags = req->mbssid_flags; 1354 cmd->vdevid_trans = req->vdevid_trans; 1355 cmd->mbssid_multi_group_flag = req->mbssid_multi_group_flag; 1356 cmd->mbssid_multi_group_id = req->mbssid_multi_group_id; 1357 } 1358 1359 /* Copy the SSID */ 1360 if (req->ssid.length) { 1361 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1362 cmd->ssid.ssid_len = req->ssid.length; 1363 else 1364 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1365 qdf_mem_copy(cmd->ssid.ssid, req->ssid.ssid, 1366 cmd->ssid.ssid_len); 1367 } 1368 1369 if (req->hidden_ssid) 1370 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1371 1372 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1373 cmd->num_noa_descriptors = req->num_noa_descriptors; 1374 cmd->preferred_rx_streams = req->preferred_rx_streams; 1375 cmd->preferred_tx_streams = req->preferred_tx_streams; 1376 cmd->cac_duration_ms = req->cac_duration_ms; 1377 cmd->regdomain = req->regdomain; 1378 cmd->he_ops = req->he_ops; 1379 1380 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1381 sizeof(wmi_channel)); 1382 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1383 cmd->num_noa_descriptors * 1384 sizeof(wmi_p2p_noa_descriptor)); 1385 if (!req->is_restart) { 1386 buf_ptr += WMI_TLV_HDR_SIZE + 1387 (cmd->num_noa_descriptors * sizeof(wmi_p2p_noa_descriptor)); 1388 1389 buf_ptr = vdev_start_add_mlo_params(buf_ptr, req); 1390 buf_ptr = vdev_start_add_ml_partner_links(buf_ptr, req); 1391 } 1392 wmi_info("vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1393 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1394 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1395 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1396 "req->dis_hw_ack: %d ", req->vdev_id, 1397 chan->mhz, req->channel.phy_mode, chan->info, 1398 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1399 chan->band_center_freq1, chan->band_center_freq2, 1400 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1401 req->preferred_tx_streams, req->preferred_rx_streams, 1402 req->ldpc_rx_enabled, req->cac_duration_ms, 1403 req->regdomain, req->he_ops, 1404 req->disable_hw_ack); 1405 1406 vdev_start_cmd_fill_11be(cmd, req); 1407 1408 if (req->is_restart) { 1409 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1410 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1411 WMI_VDEV_RESTART_REQUEST_CMDID); 1412 } else { 1413 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1414 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1415 WMI_VDEV_START_REQUEST_CMDID); 1416 } 1417 if (ret) { 1418 wmi_err("Failed to send vdev start command"); 1419 wmi_buf_free(buf); 1420 return QDF_STATUS_E_FAILURE; 1421 } 1422 1423 return QDF_STATUS_SUCCESS; 1424 } 1425 1426 /** 1427 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1428 * @wmi: wmi handle 1429 * @peer_addr: peer mac address 1430 * @param: pointer to hold peer flush tid parameter 1431 * 1432 * Return: QDF_STATUS_SUCCESS for success or error code 1433 */ 1434 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1435 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1436 struct peer_flush_params *param) 1437 { 1438 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1439 wmi_buf_t buf; 1440 int32_t len = sizeof(*cmd); 1441 1442 buf = wmi_buf_alloc(wmi, len); 1443 if (!buf) 1444 return QDF_STATUS_E_NOMEM; 1445 1446 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1447 WMITLV_SET_HDR(&cmd->tlv_header, 1448 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1449 WMITLV_GET_STRUCT_TLVLEN 1450 (wmi_peer_flush_tids_cmd_fixed_param)); 1451 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1452 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1453 cmd->vdev_id = param->vdev_id; 1454 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d and peer bitmap %d", 1455 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id, 1456 param->peer_tid_bitmap); 1457 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1458 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1459 wmi_err("Failed to send flush tid command"); 1460 wmi_buf_free(buf); 1461 return QDF_STATUS_E_FAILURE; 1462 } 1463 1464 return 0; 1465 } 1466 1467 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 1468 /** 1469 * map_to_wmi_flush_policy() - Map flush policy to firmware defined values 1470 * @policy: The target i/f flush policy value 1471 * 1472 * Return: WMI layer flush policy 1473 */ 1474 static wmi_peer_flush_policy 1475 map_to_wmi_flush_policy(enum peer_txq_flush_policy policy) 1476 { 1477 switch (policy) { 1478 case PEER_TXQ_FLUSH_POLICY_NONE: 1479 return WMI_NO_FLUSH; 1480 case PEER_TXQ_FLUSH_POLICY_TWT_SP_END: 1481 return WMI_TWT_FLUSH; 1482 default: 1483 return WMI_MAX_FLUSH_POLICY; 1484 } 1485 } 1486 1487 /** 1488 * send_peer_txq_flush_config_cmd_tlv() - Send peer TID queue flush config 1489 * @wmi: wmi handle 1490 * @param: Peer txq flush configuration 1491 * 1492 * Return: QDF_STATUS_SUCCESS for success or error code 1493 */ 1494 static QDF_STATUS 1495 send_peer_txq_flush_config_cmd_tlv(wmi_unified_t wmi, 1496 struct peer_txq_flush_config_params *param) 1497 { 1498 wmi_peer_flush_policy_cmd_fixed_param *cmd; 1499 wmi_buf_t buf; 1500 int32_t len = sizeof(*cmd); 1501 1502 buf = wmi_buf_alloc(wmi, len); 1503 if (!buf) 1504 return QDF_STATUS_E_NOMEM; 1505 1506 cmd = (wmi_peer_flush_policy_cmd_fixed_param *)wmi_buf_data(buf); 1507 1508 WMITLV_SET_HDR(&cmd->tlv_header, 1509 WMITLV_TAG_STRUC_wmi_peer_flush_policy_cmd_fixed_param, 1510 WMITLV_GET_STRUCT_TLVLEN 1511 (wmi_peer_flush_policy_cmd_fixed_param)); 1512 1513 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer, &cmd->peer_macaddr); 1514 cmd->peer_tid_bitmap = param->tid_mask; 1515 cmd->vdev_id = param->vdev_id; 1516 cmd->flush_policy = map_to_wmi_flush_policy(param->policy); 1517 if (cmd->flush_policy == WMI_MAX_FLUSH_POLICY) { 1518 wmi_buf_free(buf); 1519 wmi_err("Invalid policy"); 1520 return QDF_STATUS_E_INVAL; 1521 } 1522 wmi_debug("peer_addr " QDF_MAC_ADDR_FMT "vdev %d tid %x policy %d", 1523 QDF_MAC_ADDR_REF(param->peer), param->vdev_id, 1524 param->tid_mask, param->policy); 1525 wmi_mtrace(WMI_PEER_FLUSH_POLICY_CMDID, cmd->vdev_id, 0); 1526 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_POLICY_CMDID)) { 1527 wmi_err("Failed to send flush policy command"); 1528 wmi_buf_free(buf); 1529 return QDF_STATUS_E_FAILURE; 1530 } 1531 1532 return QDF_STATUS_SUCCESS; 1533 } 1534 #endif 1535 /** 1536 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1537 * @wmi: wmi handle 1538 * @peer_addr: peer mac addr 1539 * @param: peer delete parameters 1540 * 1541 * Return: QDF_STATUS_SUCCESS for success or error code 1542 */ 1543 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1544 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1545 struct peer_delete_cmd_params *param) 1546 { 1547 wmi_peer_delete_cmd_fixed_param *cmd; 1548 wmi_buf_t buf; 1549 int32_t len = sizeof(*cmd); 1550 uint8_t *buf_ptr; 1551 1552 len += peer_delete_mlo_params_size(param); 1553 buf = wmi_buf_alloc(wmi, len); 1554 if (!buf) 1555 return QDF_STATUS_E_NOMEM; 1556 1557 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1558 cmd = (wmi_peer_delete_cmd_fixed_param *)buf_ptr; 1559 WMITLV_SET_HDR(&cmd->tlv_header, 1560 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1561 WMITLV_GET_STRUCT_TLVLEN 1562 (wmi_peer_delete_cmd_fixed_param)); 1563 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1564 cmd->vdev_id = param->vdev_id; 1565 buf_ptr = (uint8_t *)(((uintptr_t) cmd) + sizeof(*cmd)); 1566 buf_ptr = peer_delete_add_mlo_params(buf_ptr, param); 1567 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1568 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id); 1569 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1570 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1571 wmi_err("Failed to send peer delete command"); 1572 wmi_buf_free(buf); 1573 return QDF_STATUS_E_FAILURE; 1574 } 1575 return 0; 1576 } 1577 1578 static void 1579 wmi_get_converted_peer_bitmap(uint32_t src_peer_bitmap, uint32_t *dst_bitmap) 1580 { 1581 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_SELF)) 1582 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1583 WMI_PEER_TYPE_DEFAULT); 1584 1585 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_AP)) 1586 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1587 WMI_PEER_TYPE_BSS); 1588 1589 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_TDLS)) 1590 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1591 WMI_PEER_TYPE_TDLS); 1592 1593 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_NDP)) 1594 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1595 WMI_PEER_TYPE_NAN_DATA); 1596 1597 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_RTT_PASN)) 1598 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1599 WMI_PEER_TYPE_PASN); 1600 } 1601 1602 /** 1603 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1604 * @wmi: wmi handle 1605 * @param: pointer to hold peer delete all parameter 1606 * 1607 * Return: QDF_STATUS_SUCCESS for success or error code 1608 */ 1609 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1610 wmi_unified_t wmi, 1611 struct peer_delete_all_params *param) 1612 { 1613 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1614 wmi_buf_t buf; 1615 int32_t len = sizeof(*cmd); 1616 1617 buf = wmi_buf_alloc(wmi, len); 1618 if (!buf) 1619 return QDF_STATUS_E_NOMEM; 1620 1621 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1622 WMITLV_SET_HDR( 1623 &cmd->tlv_header, 1624 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1625 WMITLV_GET_STRUCT_TLVLEN 1626 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1627 cmd->vdev_id = param->vdev_id; 1628 wmi_get_converted_peer_bitmap(param->peer_type_bitmap, 1629 cmd->peer_type_bitmap); 1630 1631 wmi_debug("vdev_id %d peer_type_bitmap:%d", cmd->vdev_id, 1632 param->peer_type_bitmap); 1633 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1634 if (wmi_unified_cmd_send(wmi, buf, len, 1635 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1636 wmi_err("Failed to send peer del all command"); 1637 wmi_buf_free(buf); 1638 return QDF_STATUS_E_FAILURE; 1639 } 1640 1641 return QDF_STATUS_SUCCESS; 1642 } 1643 1644 /** 1645 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1646 * to target id. 1647 * @peer_param_id: host param id. 1648 * 1649 * Return: Target param id. 1650 */ 1651 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1652 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1653 uint32_t peer_param_id) 1654 { 1655 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1656 return peer_param_tlv[peer_param_id]; 1657 return WMI_UNAVAILABLE_PARAM; 1658 } 1659 #else 1660 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1661 uint32_t peer_param_id) 1662 { 1663 return peer_param_id; 1664 } 1665 #endif 1666 1667 /** 1668 * wmi_host_chan_bw_to_target_chan_bw - convert wmi_host_channel_width to 1669 * wmi_channel_width 1670 * @bw: wmi_host_channel_width channel width 1671 * 1672 * Return: wmi_channel_width 1673 */ 1674 static wmi_channel_width wmi_host_chan_bw_to_target_chan_bw( 1675 wmi_host_channel_width bw) 1676 { 1677 wmi_channel_width target_bw = WMI_CHAN_WIDTH_20; 1678 1679 switch (bw) { 1680 case WMI_HOST_CHAN_WIDTH_20: 1681 target_bw = WMI_CHAN_WIDTH_20; 1682 break; 1683 case WMI_HOST_CHAN_WIDTH_40: 1684 target_bw = WMI_CHAN_WIDTH_40; 1685 break; 1686 case WMI_HOST_CHAN_WIDTH_80: 1687 target_bw = WMI_CHAN_WIDTH_80; 1688 break; 1689 case WMI_HOST_CHAN_WIDTH_160: 1690 target_bw = WMI_CHAN_WIDTH_160; 1691 break; 1692 case WMI_HOST_CHAN_WIDTH_80P80: 1693 target_bw = WMI_CHAN_WIDTH_80P80; 1694 break; 1695 case WMI_HOST_CHAN_WIDTH_5: 1696 target_bw = WMI_CHAN_WIDTH_5; 1697 break; 1698 case WMI_HOST_CHAN_WIDTH_10: 1699 target_bw = WMI_CHAN_WIDTH_10; 1700 break; 1701 case WMI_HOST_CHAN_WIDTH_165: 1702 target_bw = WMI_CHAN_WIDTH_165; 1703 break; 1704 case WMI_HOST_CHAN_WIDTH_160P160: 1705 target_bw = WMI_CHAN_WIDTH_160P160; 1706 break; 1707 case WMI_HOST_CHAN_WIDTH_320: 1708 target_bw = WMI_CHAN_WIDTH_320; 1709 break; 1710 default: 1711 break; 1712 } 1713 1714 return target_bw; 1715 } 1716 1717 /** 1718 * convert_host_peer_param_value_to_target_value_tlv() - convert host peer 1719 * param value to target 1720 * @param_id: target param id 1721 * @param_value: host param value 1722 * 1723 * Return: target param value 1724 */ 1725 static uint32_t convert_host_peer_param_value_to_target_value_tlv( 1726 uint32_t param_id, uint32_t param_value) 1727 { 1728 uint32_t fw_param_value = 0; 1729 wmi_host_channel_width bw; 1730 uint16_t punc; 1731 1732 switch (param_id) { 1733 case WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP: 1734 bw = QDF_GET_BITS(param_value, 0, 8); 1735 punc = QDF_GET_BITS(param_value, 8, 16); 1736 QDF_SET_BITS(fw_param_value, 0, 8, 1737 wmi_host_chan_bw_to_target_chan_bw(bw)); 1738 QDF_SET_BITS(fw_param_value, 8, 16, ~punc); 1739 break; 1740 default: 1741 fw_param_value = param_value; 1742 break; 1743 } 1744 1745 return fw_param_value; 1746 } 1747 1748 #ifdef WLAN_SUPPORT_PPEDS 1749 /** 1750 * peer_ppe_ds_param_send_tlv() - Set peer PPE DS config 1751 * @wmi: wmi handle 1752 * @param: pointer to hold PPE DS config 1753 * 1754 * Return: QDF_STATUS_SUCCESS for success or error code 1755 */ 1756 static QDF_STATUS peer_ppe_ds_param_send_tlv(wmi_unified_t wmi, 1757 struct peer_ppe_ds_param *param) 1758 { 1759 wmi_peer_config_ppe_ds_cmd_fixed_param *cmd; 1760 wmi_buf_t buf; 1761 int32_t err; 1762 uint32_t len = sizeof(wmi_peer_config_ppe_ds_cmd_fixed_param); 1763 1764 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1765 if (!buf) 1766 return QDF_STATUS_E_NOMEM; 1767 1768 cmd = (wmi_peer_config_ppe_ds_cmd_fixed_param *)wmi_buf_data(buf); 1769 WMITLV_SET_HDR(&cmd->tlv_header, 1770 WMITLV_TAG_STRUC_wmi_peer_config_ppe_ds_cmd_fixed_param, 1771 WMITLV_GET_STRUCT_TLVLEN 1772 (wmi_peer_config_ppe_ds_cmd_fixed_param)); 1773 1774 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1775 1776 if (param->ppe_routing_enabled) 1777 cmd->ppe_routing_enable = param->use_ppe ? 1778 WMI_AST_USE_PPE_ENABLED : WMI_AST_USE_PPE_DISABLED; 1779 else 1780 cmd->ppe_routing_enable = WMI_PPE_ROUTING_DISABLED; 1781 1782 cmd->service_code = param->service_code; 1783 cmd->priority_valid = param->priority_valid; 1784 cmd->src_info = param->src_info; 1785 cmd->vdev_id = param->vdev_id; 1786 1787 wmi_debug("vdev_id %d peer_mac: QDF_MAC_ADDR_FMT\n" 1788 "ppe_routing_enable: %u service_code: %u\n" 1789 "priority_valid:%d src_info:%u", 1790 param->vdev_id, 1791 QDF_MAC_ADDR_REF(param->peer_macaddr), 1792 param->ppe_routing_enabled, 1793 param->service_code, 1794 param->priority_valid, 1795 param->src_info); 1796 1797 wmi_mtrace(WMI_PEER_CONFIG_PPE_DS_CMDID, cmd->vdev_id, 0); 1798 err = wmi_unified_cmd_send(wmi, buf, 1799 len, 1800 WMI_PEER_CONFIG_PPE_DS_CMDID); 1801 if (err) { 1802 wmi_err("Failed to send ppeds config cmd"); 1803 wmi_buf_free(buf); 1804 return QDF_STATUS_E_FAILURE; 1805 } 1806 1807 return 0; 1808 } 1809 #endif /* WLAN_SUPPORT_PPEDS */ 1810 1811 /** 1812 * send_peer_param_cmd_tlv() - set peer parameter in fw 1813 * @wmi: wmi handle 1814 * @peer_addr: peer mac address 1815 * @param: pointer to hold peer set parameter 1816 * 1817 * Return: QDF_STATUS_SUCCESS for success or error code 1818 */ 1819 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1820 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1821 struct peer_set_params *param) 1822 { 1823 wmi_peer_set_param_cmd_fixed_param *cmd; 1824 wmi_buf_t buf; 1825 int32_t err; 1826 uint32_t param_id; 1827 uint32_t param_value; 1828 1829 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1830 if (param_id == WMI_UNAVAILABLE_PARAM) { 1831 wmi_err("Unavailable param %d", param->param_id); 1832 return QDF_STATUS_E_NOSUPPORT; 1833 } 1834 param_value = convert_host_peer_param_value_to_target_value_tlv( 1835 param_id, param->param_value); 1836 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1837 if (!buf) 1838 return QDF_STATUS_E_NOMEM; 1839 1840 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1841 WMITLV_SET_HDR(&cmd->tlv_header, 1842 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1843 WMITLV_GET_STRUCT_TLVLEN 1844 (wmi_peer_set_param_cmd_fixed_param)); 1845 cmd->vdev_id = param->vdev_id; 1846 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1847 cmd->param_id = param_id; 1848 cmd->param_value = param_value; 1849 1850 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1851 cmd->vdev_id, 1852 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1853 cmd->param_value); 1854 1855 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1856 err = wmi_unified_cmd_send(wmi, buf, 1857 sizeof(wmi_peer_set_param_cmd_fixed_param), 1858 WMI_PEER_SET_PARAM_CMDID); 1859 if (err) { 1860 wmi_err("Failed to send set_param cmd"); 1861 wmi_buf_free(buf); 1862 return QDF_STATUS_E_FAILURE; 1863 } 1864 1865 return 0; 1866 } 1867 1868 /** 1869 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1870 * @wmi: wmi handle 1871 * @bssid: bssid 1872 * @params: pointer to hold vdev up parameter 1873 * 1874 * Return: QDF_STATUS_SUCCESS for success or error code 1875 */ 1876 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1877 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1878 struct vdev_up_params *params) 1879 { 1880 wmi_vdev_up_cmd_fixed_param *cmd; 1881 wmi_buf_t buf; 1882 int32_t len = sizeof(*cmd); 1883 1884 wmi_debug("VDEV_UP"); 1885 wmi_debug("vdev_id %d aid %d profile idx %d count %d bssid " 1886 QDF_MAC_ADDR_FMT " trans bssid " QDF_MAC_ADDR_FMT, 1887 params->vdev_id, params->assoc_id, 1888 params->profile_idx, params->profile_num, 1889 QDF_MAC_ADDR_REF(bssid), QDF_MAC_ADDR_REF(params->trans_bssid)); 1890 buf = wmi_buf_alloc(wmi, len); 1891 if (!buf) 1892 return QDF_STATUS_E_NOMEM; 1893 1894 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1895 WMITLV_SET_HDR(&cmd->tlv_header, 1896 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1897 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1898 cmd->vdev_id = params->vdev_id; 1899 cmd->vdev_assoc_id = params->assoc_id; 1900 cmd->profile_idx = params->profile_idx; 1901 cmd->profile_num = params->profile_num; 1902 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1903 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1904 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1905 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1906 wmi_err("Failed to send vdev up command"); 1907 wmi_buf_free(buf); 1908 return QDF_STATUS_E_FAILURE; 1909 } 1910 1911 return 0; 1912 } 1913 1914 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1915 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1916 { 1917 /* Host sets the peer_type as 0 for the peer create command sent to FW 1918 * other than PASN and BRIDGE peer create command. 1919 */ 1920 if (peer_type == WLAN_PEER_RTT_PASN) 1921 return WMI_PEER_TYPE_PASN; 1922 1923 if (peer_type == WLAN_PEER_MLO_BRIDGE) 1924 return WMI_PEER_TYPE_BRIDGE; 1925 1926 return peer_type; 1927 } 1928 #else 1929 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1930 { 1931 return peer_type; 1932 } 1933 #endif 1934 /** 1935 * send_peer_create_cmd_tlv() - send peer create command to fw 1936 * @wmi: wmi handle 1937 * @param: peer create parameters 1938 * 1939 * Return: QDF_STATUS_SUCCESS for success or error code 1940 */ 1941 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1942 struct peer_create_params *param) 1943 { 1944 wmi_peer_create_cmd_fixed_param *cmd; 1945 wmi_buf_t buf; 1946 uint8_t *buf_ptr; 1947 int32_t len = sizeof(*cmd); 1948 1949 len += peer_create_mlo_params_size(param); 1950 buf = wmi_buf_alloc(wmi, len); 1951 if (!buf) 1952 return QDF_STATUS_E_NOMEM; 1953 1954 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1955 WMITLV_SET_HDR(&cmd->tlv_header, 1956 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1957 WMITLV_GET_STRUCT_TLVLEN 1958 (wmi_peer_create_cmd_fixed_param)); 1959 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1960 cmd->peer_type = convert_peer_type_host_to_target(param->peer_type); 1961 cmd->vdev_id = param->vdev_id; 1962 1963 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1964 buf_ptr += sizeof(*cmd); 1965 buf_ptr = peer_create_add_mlo_params(buf_ptr, param); 1966 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1967 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1968 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1969 wmi_buf_free(buf); 1970 return QDF_STATUS_E_FAILURE; 1971 } 1972 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1973 QDF_MAC_ADDR_REF(param->peer_addr), 1974 param->vdev_id); 1975 1976 return 0; 1977 } 1978 1979 /** 1980 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1981 * command to fw 1982 * @wmi: wmi handle 1983 * @param: Rx reorder queue setup parameters 1984 * 1985 * Return: QDF_STATUS_SUCCESS for success or error code 1986 */ 1987 static 1988 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1989 struct rx_reorder_queue_setup_params *param) 1990 { 1991 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1992 wmi_buf_t buf; 1993 int32_t len = sizeof(*cmd); 1994 1995 buf = wmi_buf_alloc(wmi, len); 1996 if (!buf) 1997 return QDF_STATUS_E_NOMEM; 1998 1999 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 2000 WMITLV_SET_HDR(&cmd->tlv_header, 2001 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 2002 WMITLV_GET_STRUCT_TLVLEN 2003 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 2004 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 2005 cmd->vdev_id = param->vdev_id; 2006 cmd->tid = param->tid; 2007 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 2008 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 2009 cmd->queue_no = param->queue_no; 2010 cmd->ba_window_size_valid = param->ba_window_size_valid; 2011 cmd->ba_window_size = param->ba_window_size; 2012 2013 2014 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 2015 if (wmi_unified_cmd_send(wmi, buf, len, 2016 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 2017 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 2018 wmi_buf_free(buf); 2019 return QDF_STATUS_E_FAILURE; 2020 } 2021 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 2022 QDF_MAC_ADDR_REF(param->peer_macaddr), 2023 param->vdev_id, param->tid); 2024 2025 return QDF_STATUS_SUCCESS; 2026 } 2027 2028 /** 2029 * send_peer_multi_rx_reorder_queue_setup_cmd_tlv() - Send multi rx reorder 2030 * setup cmd to fw. 2031 * @wmi: wmi handle 2032 * @param: Multi rx reorder queue setup parameters 2033 * 2034 * Return: QDF_STATUS_SUCCESS for success or error code 2035 */ 2036 static 2037 QDF_STATUS send_peer_multi_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 2038 struct multi_rx_reorder_queue_setup_params *param) 2039 { 2040 wmi_peer_multiple_reorder_queue_setup_cmd_fixed_param *cmd; 2041 wmi_buf_t buf; 2042 uint8_t *buf_ptr; 2043 wmi_peer_per_reorder_q_setup_params_t *q_params; 2044 struct rx_reorder_queue_params_list *param_ptr; 2045 int tid; 2046 int32_t len; 2047 2048 len = sizeof(wmi_peer_multiple_reorder_queue_setup_cmd_fixed_param) + 2049 WMI_TLV_HDR_SIZE + 2050 sizeof(wmi_peer_per_reorder_q_setup_params_t) * param->tid_num; 2051 2052 buf = wmi_buf_alloc(wmi, len); 2053 if (!buf) 2054 return QDF_STATUS_E_NOMEM; 2055 2056 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2057 cmd = (wmi_peer_multiple_reorder_queue_setup_cmd_fixed_param *) 2058 wmi_buf_data(buf); 2059 2060 WMITLV_SET_HDR(&cmd->tlv_header, 2061 WMITLV_TAG_STRUC_wmi_peer_multiple_reorder_queue_setup_cmd_fixed_param, 2062 WMITLV_GET_STRUCT_TLVLEN 2063 (wmi_peer_multiple_reorder_queue_setup_cmd_fixed_param)); 2064 2065 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 2066 cmd->vdev_id = param->vdev_id; 2067 2068 buf_ptr += 2069 sizeof(wmi_peer_multiple_reorder_queue_setup_cmd_fixed_param); 2070 2071 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2072 sizeof(wmi_peer_per_reorder_q_setup_params_t) * 2073 param->tid_num); 2074 2075 q_params = (wmi_peer_per_reorder_q_setup_params_t *)(buf_ptr + 2076 WMI_TLV_HDR_SIZE); 2077 2078 for (tid = 0; tid < WMI_MAX_TIDS; tid++) { 2079 if (!(BIT(tid) & param->tid_bitmap)) 2080 continue; 2081 2082 WMITLV_SET_HDR(q_params, 2083 WMITLV_TAG_STRUC_wmi_peer_per_reorder_q_setup_params_t, 2084 WMITLV_GET_STRUCT_TLVLEN( 2085 wmi_peer_per_reorder_q_setup_params_t)); 2086 2087 param_ptr = ¶m->queue_params_list[tid]; 2088 q_params->tid = tid; 2089 q_params->queue_ptr_lo = param_ptr->hw_qdesc_paddr & 0xffffffff; 2090 q_params->queue_ptr_hi = 2091 (uint64_t)param_ptr->hw_qdesc_paddr >> 32; 2092 q_params->queue_no = param_ptr->queue_no; 2093 q_params->ba_window_size_valid = 2094 param_ptr->ba_window_size_valid; 2095 q_params->ba_window_size = param_ptr->ba_window_size; 2096 q_params++; 2097 } 2098 2099 wmi_mtrace(WMI_PEER_MULTIPLE_REORDER_QUEUE_SETUP_CMDID, 2100 cmd->vdev_id, 0); 2101 if (wmi_unified_cmd_send(wmi, buf, len, 2102 WMI_PEER_MULTIPLE_REORDER_QUEUE_SETUP_CMDID)) { 2103 wmi_err("Send WMI_PEER_MULTILE_REORDER_QUEUE_SETUP_CMDID fail"); 2104 wmi_buf_free(buf); 2105 return QDF_STATUS_E_FAILURE; 2106 } 2107 2108 wmi_debug("peer_mac "QDF_MAC_ADDR_FMT" vdev_id %d, bitmap 0x%x, num %d", 2109 QDF_MAC_ADDR_REF(param->peer_macaddr), 2110 param->vdev_id, param->tid_bitmap, param->tid_num); 2111 2112 return QDF_STATUS_SUCCESS; 2113 } 2114 2115 /** 2116 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 2117 * command to fw 2118 * @wmi: wmi handle 2119 * @param: Rx reorder queue remove parameters 2120 * 2121 * Return: QDF_STATUS_SUCCESS for success or error code 2122 */ 2123 static 2124 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 2125 struct rx_reorder_queue_remove_params *param) 2126 { 2127 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 2128 wmi_buf_t buf; 2129 int32_t len = sizeof(*cmd); 2130 2131 buf = wmi_buf_alloc(wmi, len); 2132 if (!buf) 2133 return QDF_STATUS_E_NOMEM; 2134 2135 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 2136 wmi_buf_data(buf); 2137 WMITLV_SET_HDR(&cmd->tlv_header, 2138 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 2139 WMITLV_GET_STRUCT_TLVLEN 2140 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 2141 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 2142 cmd->vdev_id = param->vdev_id; 2143 cmd->tid_mask = param->peer_tid_bitmap; 2144 2145 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 2146 if (wmi_unified_cmd_send(wmi, buf, len, 2147 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 2148 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 2149 wmi_buf_free(buf); 2150 return QDF_STATUS_E_FAILURE; 2151 } 2152 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 2153 QDF_MAC_ADDR_REF(param->peer_macaddr), 2154 param->vdev_id, param->peer_tid_bitmap); 2155 2156 return QDF_STATUS_SUCCESS; 2157 } 2158 2159 #ifdef WLAN_SUPPORT_GREEN_AP 2160 /** 2161 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 2162 * @wmi_handle: wmi handle 2163 * @value: value 2164 * @pdev_id: pdev id to have radio context 2165 * 2166 * Return: QDF_STATUS_SUCCESS for success or error code 2167 */ 2168 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 2169 uint32_t value, uint8_t pdev_id) 2170 { 2171 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 2172 wmi_buf_t buf; 2173 int32_t len = sizeof(*cmd); 2174 2175 wmi_debug("Set Green AP PS val %d", value); 2176 2177 buf = wmi_buf_alloc(wmi_handle, len); 2178 if (!buf) 2179 return QDF_STATUS_E_NOMEM; 2180 2181 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 2182 WMITLV_SET_HDR(&cmd->tlv_header, 2183 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 2184 WMITLV_GET_STRUCT_TLVLEN 2185 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 2186 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2187 wmi_handle, 2188 pdev_id); 2189 cmd->enable = value; 2190 2191 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 2192 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2193 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 2194 wmi_err("Set Green AP PS param Failed val %d", value); 2195 wmi_buf_free(buf); 2196 return QDF_STATUS_E_FAILURE; 2197 } 2198 2199 return 0; 2200 } 2201 #endif 2202 2203 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 2204 static QDF_STATUS send_green_ap_ll_ps_cmd_tlv(wmi_unified_t wmi_handle, 2205 struct green_ap_ll_ps_cmd_param *green_ap_ll_ps_params) 2206 { 2207 uint32_t len; 2208 wmi_buf_t buf; 2209 wmi_xgap_enable_cmd_fixed_param *cmd; 2210 2211 len = sizeof(*cmd); 2212 2213 wmi_debug("Green AP low latency PS: bcn interval: %u state: %u cookie: %u", 2214 green_ap_ll_ps_params->bcn_interval, 2215 green_ap_ll_ps_params->state, 2216 green_ap_ll_ps_params->cookie); 2217 2218 buf = wmi_buf_alloc(wmi_handle, len); 2219 if (!buf) 2220 return QDF_STATUS_E_NOMEM; 2221 2222 cmd = (wmi_xgap_enable_cmd_fixed_param *)wmi_buf_data(buf); 2223 WMITLV_SET_HDR(&cmd->tlv_header, 2224 WMITLV_TAG_STRUC_wmi_xgap_enable_cmd_fixed_param, 2225 WMITLV_GET_STRUCT_TLVLEN 2226 (wmi_xgap_enable_cmd_fixed_param)); 2227 2228 cmd->beacon_interval = green_ap_ll_ps_params->bcn_interval; 2229 cmd->sap_lp_flag = green_ap_ll_ps_params->state; 2230 cmd->dialog_token = green_ap_ll_ps_params->cookie; 2231 2232 wmi_mtrace(WMI_XGAP_ENABLE_CMDID, NO_SESSION, 0); 2233 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2234 WMI_XGAP_ENABLE_CMDID)) { 2235 wmi_err("Green AP Low latency PS cmd Failed"); 2236 wmi_buf_free(buf); 2237 return QDF_STATUS_E_FAILURE; 2238 } 2239 2240 return QDF_STATUS_SUCCESS; 2241 } 2242 #endif 2243 2244 /** 2245 * send_pdev_utf_cmd_tlv() - send utf command to fw 2246 * @wmi_handle: wmi handle 2247 * @param: pointer to pdev_utf_params 2248 * @mac_id: mac id to have radio context 2249 * 2250 * Return: QDF_STATUS_SUCCESS for success or error code 2251 */ 2252 static QDF_STATUS 2253 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 2254 struct pdev_utf_params *param, 2255 uint8_t mac_id) 2256 { 2257 wmi_buf_t buf; 2258 uint8_t *cmd; 2259 /* if param->len is 0 no data is sent, return error */ 2260 QDF_STATUS ret = QDF_STATUS_E_INVAL; 2261 static uint8_t msgref = 1; 2262 uint8_t segNumber = 0, segInfo, numSegments; 2263 uint16_t chunk_len, total_bytes; 2264 uint8_t *bufpos; 2265 struct seg_hdr_info segHdrInfo; 2266 wmi_pdev_utf_cmd_fixed_param *utf_cmd; 2267 uint16_t len; 2268 bool is_pdev_id_over_utf; 2269 2270 bufpos = param->utf_payload; 2271 total_bytes = param->len; 2272 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 2273 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 2274 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 2275 2276 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 2277 numSegments++; 2278 2279 while (param->len) { 2280 if (param->len > MAX_WMI_UTF_LEN) 2281 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 2282 else 2283 chunk_len = param->len; 2284 2285 is_pdev_id_over_utf = is_service_enabled_tlv(wmi_handle, 2286 WMI_SERVICE_PDEV_PARAM_IN_UTF_WMI); 2287 if (is_pdev_id_over_utf) 2288 len = chunk_len + sizeof(segHdrInfo) + 2289 WMI_TLV_HDR_SIZE + sizeof(*utf_cmd); 2290 else 2291 len = chunk_len + sizeof(segHdrInfo) + WMI_TLV_HDR_SIZE; 2292 2293 buf = wmi_buf_alloc(wmi_handle, len); 2294 if (!buf) 2295 return QDF_STATUS_E_NOMEM; 2296 2297 cmd = (uint8_t *) wmi_buf_data(buf); 2298 2299 segHdrInfo.len = total_bytes; 2300 segHdrInfo.msgref = msgref; 2301 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 2302 segHdrInfo.segmentInfo = segInfo; 2303 segHdrInfo.pad = 0; 2304 2305 wmi_debug("segHdrInfo.len = %u, segHdrInfo.msgref = %u, segHdrInfo.segmentInfo = %u", 2306 segHdrInfo.len, segHdrInfo.msgref, 2307 segHdrInfo.segmentInfo); 2308 2309 wmi_debug("total_bytes %u segNumber %u totalSegments %u chunk len %u", 2310 total_bytes, segNumber, numSegments, chunk_len); 2311 2312 segNumber++; 2313 2314 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 2315 (chunk_len + sizeof(segHdrInfo))); 2316 cmd += WMI_TLV_HDR_SIZE; 2317 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 words */ 2318 cmd += sizeof(segHdrInfo); 2319 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(cmd, 2320 bufpos, chunk_len); 2321 2322 if (is_pdev_id_over_utf) { 2323 cmd += chunk_len; 2324 utf_cmd = (wmi_pdev_utf_cmd_fixed_param *)cmd; 2325 WMITLV_SET_HDR(&utf_cmd->tlv_header, 2326 WMITLV_TAG_STRUC_wmi_pdev_utf_cmd_fixed_param, 2327 WMITLV_GET_STRUCT_TLVLEN( 2328 wmi_pdev_utf_cmd_fixed_param)); 2329 2330 if (wmi_handle->ops->convert_host_pdev_id_to_target) 2331 utf_cmd->pdev_id = 2332 wmi_handle->ops->convert_host_pdev_id_to_target( 2333 wmi_handle, mac_id); 2334 2335 wmi_debug("pdev_id %u", utf_cmd->pdev_id); 2336 } 2337 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 2338 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2339 WMI_PDEV_UTF_CMDID); 2340 2341 if (QDF_IS_STATUS_ERROR(ret)) { 2342 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 2343 wmi_buf_free(buf); 2344 break; 2345 } 2346 2347 param->len -= chunk_len; 2348 bufpos += chunk_len; 2349 } 2350 2351 msgref++; 2352 2353 return ret; 2354 } 2355 2356 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2357 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2358 { 2359 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 2360 return pdev_param_tlv[host_param]; 2361 return WMI_UNAVAILABLE_PARAM; 2362 } 2363 2364 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2365 { 2366 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2367 return vdev_param_tlv[host_param]; 2368 return WMI_UNAVAILABLE_PARAM; 2369 } 2370 #else 2371 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2372 { 2373 return host_param; 2374 } 2375 2376 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2377 { 2378 return host_param; 2379 } 2380 #endif /* end of ENABLE_HOST_TO_TARGET_CONVERSION */ 2381 2382 /** 2383 * send_pdev_param_cmd_tlv() - set pdev parameters 2384 * @wmi_handle: wmi handle 2385 * @param: pointer to pdev parameter 2386 * @mac_id: radio context 2387 * 2388 * Return: QDF_STATUS_SUCCESS for success or error code 2389 */ 2390 static QDF_STATUS 2391 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2392 struct pdev_params *param, 2393 uint8_t mac_id) 2394 { 2395 QDF_STATUS ret; 2396 wmi_pdev_set_param_cmd_fixed_param *cmd; 2397 wmi_buf_t buf; 2398 uint16_t len = sizeof(*cmd); 2399 uint32_t pdev_param; 2400 2401 pdev_param = convert_host_pdev_param_tlv(param->param_id); 2402 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 2403 wmi_err("Unavailable param %d", param->param_id); 2404 return QDF_STATUS_E_INVAL; 2405 } 2406 2407 buf = wmi_buf_alloc(wmi_handle, len); 2408 if (!buf) 2409 return QDF_STATUS_E_NOMEM; 2410 2411 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2412 WMITLV_SET_HDR(&cmd->tlv_header, 2413 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 2414 WMITLV_GET_STRUCT_TLVLEN 2415 (wmi_pdev_set_param_cmd_fixed_param)); 2416 if (param->is_host_pdev_id) 2417 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 2418 wmi_handle, 2419 mac_id); 2420 else 2421 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2422 wmi_handle, 2423 mac_id); 2424 cmd->param_id = pdev_param; 2425 cmd->param_value = param->param_value; 2426 wmi_nofl_debug("Set pdev %d param 0x%x to %u", cmd->pdev_id, 2427 cmd->param_id, cmd->param_value); 2428 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 2429 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2430 WMI_PDEV_SET_PARAM_CMDID); 2431 if (QDF_IS_STATUS_ERROR(ret)) { 2432 wmi_buf_free(buf); 2433 } 2434 return ret; 2435 } 2436 2437 /** 2438 * send_multi_param_cmd_using_pdev_set_param_tlv() - set pdev parameters 2439 * @wmi_handle: wmi handle 2440 * @params: pointer to hold set_multiple_pdev_vdev_param info 2441 * 2442 * Return: QDF_STATUS_SUCCESS for success or error code 2443 */ 2444 static QDF_STATUS 2445 send_multi_param_cmd_using_pdev_set_param_tlv(wmi_unified_t wmi_handle, 2446 struct set_multiple_pdev_vdev_param *params) 2447 { 2448 uint8_t index; 2449 struct pdev_params pdevparam; 2450 uint8_t n_params = params->n_params; 2451 2452 pdevparam.is_host_pdev_id = params->is_host_pdev_id; 2453 for (index = 0; index < n_params; index++) { 2454 pdevparam.param_id = params->params[index].param_id; 2455 pdevparam.param_value = params->params[index].param_value; 2456 if (QDF_IS_STATUS_ERROR(send_pdev_param_cmd_tlv(wmi_handle, 2457 &pdevparam, 2458 params->dev_id))) { 2459 wmi_err("failed to send pdev setparam:%d", 2460 pdevparam.param_id); 2461 return QDF_STATUS_E_FAILURE; 2462 } 2463 } 2464 return QDF_STATUS_SUCCESS; 2465 } 2466 2467 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2468 2469 /** 2470 * convert_host_pdev_vdev_param_id_to_target()- convert host params to target params 2471 * @params: pointer to point set_multiple_pdev_vdev_param info 2472 * 2473 * Return: returns QDF_STATUS 2474 */ 2475 static QDF_STATUS 2476 convert_host_pdev_vdev_param_id_to_target(struct set_multiple_pdev_vdev_param *params) 2477 { 2478 uint8_t index; 2479 uint32_t dev_paramid; 2480 uint8_t num = params->n_params; 2481 2482 if (params->param_type == MLME_PDEV_SETPARAM) { 2483 for (index = 0; index < num; index++) { 2484 dev_paramid = convert_host_pdev_param_tlv(params->params[index].param_id); 2485 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2486 wmi_err("pdev param %d not available", 2487 params->params[index].param_id); 2488 return QDF_STATUS_E_INVAL; 2489 } 2490 params->params[index].param_id = dev_paramid; 2491 } 2492 } else if (params->param_type == MLME_VDEV_SETPARAM) { 2493 for (index = 0; index < num; index++) { 2494 dev_paramid = convert_host_vdev_param_tlv(params->params[index].param_id); 2495 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2496 wmi_err("vdev param %d not available", 2497 params->params[index].param_id); 2498 return QDF_STATUS_E_INVAL; 2499 } 2500 params->params[index].param_id = dev_paramid; 2501 } 2502 } else { 2503 wmi_err("invalid param type"); 2504 return QDF_STATUS_E_INVAL; 2505 } 2506 return QDF_STATUS_SUCCESS; 2507 } 2508 2509 /** 2510 * send_multi_pdev_vdev_set_param_cmd_tlv()-set pdev/vdev params 2511 * @wmi_handle: wmi handle 2512 * @params: pointer to hold set_multiple_pdev_vdev_param info 2513 * 2514 * Return: returns QDF_STATUS 2515 */ 2516 static QDF_STATUS 2517 send_multi_pdev_vdev_set_param_cmd_tlv( 2518 wmi_unified_t wmi_handle, 2519 struct set_multiple_pdev_vdev_param *params) 2520 { 2521 uint8_t *buf_ptr; 2522 QDF_STATUS ret; 2523 wmi_buf_t buf; 2524 wmi_set_param_info *setparam; 2525 wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *cmd; 2526 uint8_t num = params->n_params; 2527 uint16_t len; 2528 uint8_t index = 0; 2529 const char *dev_string[] = {"pdev", "vdev"}; 2530 2531 if (convert_host_pdev_vdev_param_id_to_target(params)) 2532 return QDF_STATUS_E_INVAL; 2533 2534 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + (num * sizeof(*setparam)); 2535 buf = wmi_buf_alloc(wmi_handle, len); 2536 if (!buf) 2537 return QDF_STATUS_E_NOMEM; 2538 2539 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2540 cmd = (wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *)buf_ptr; 2541 2542 WMITLV_SET_HDR(&cmd->tlv_header, 2543 WMITLV_TAG_STRUC_wmi_set_multiple_pdev_vdev_param_cmd_fixed_param, 2544 WMITLV_GET_STRUCT_TLVLEN(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param)); 2545 2546 cmd->is_vdev = params->param_type; 2547 if (params->param_type == MLME_PDEV_SETPARAM) { 2548 if (params->is_host_pdev_id) 2549 params->dev_id = wmi_handle->ops->convert_host_pdev_id_to_target(wmi_handle, 2550 params->dev_id); 2551 else 2552 params->dev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 2553 params->dev_id); 2554 } 2555 cmd->dev_id = params->dev_id; 2556 buf_ptr += sizeof(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param); 2557 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, (num * sizeof(*setparam))); 2558 buf_ptr += WMI_TLV_HDR_SIZE; 2559 for (index = 0; index < num; index++) { 2560 setparam = (wmi_set_param_info *)buf_ptr; 2561 WMITLV_SET_HDR(&setparam->tlv_header, 2562 WMITLV_TAG_STRUC_wmi_set_param_info, 2563 WMITLV_GET_STRUCT_TLVLEN(*setparam)); 2564 setparam->param_id = params->params[index].param_id; 2565 setparam->param_value = params->params[index].param_value; 2566 wmi_nofl_debug("Set %s %d param 0x%x to %u", 2567 dev_string[cmd->is_vdev], params->dev_id, 2568 setparam->param_id, setparam->param_value); 2569 buf_ptr += sizeof(*setparam); 2570 } 2571 wmi_mtrace(WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID, 2572 cmd->dev_id, 0); 2573 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2574 WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID); 2575 if (QDF_IS_STATUS_ERROR(ret)) { 2576 wmi_buf_free(buf); 2577 } 2578 return ret; 2579 } 2580 2581 /** 2582 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2583 * @wmi_handle: wmi handle 2584 * @params: pointer to set_multiple_pdev_vdev_param structure 2585 * 2586 * Return: QDF_STATUS_SUCCESS for success or error code 2587 */ 2588 static QDF_STATUS 2589 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2590 struct set_multiple_pdev_vdev_param *params) 2591 { 2592 if (!wmi_service_enabled(wmi_handle, 2593 wmi_service_combined_set_param_support)) 2594 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, 2595 params); 2596 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2597 } 2598 2599 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2600 /** 2601 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2602 * @wmi_handle: wmi handle 2603 * @params: pointer to set_multiple_pdev_vdev_param structure 2604 * 2605 * Return: QDF_STATUS_SUCCESS for success or error code 2606 */ 2607 static QDF_STATUS 2608 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2609 struct set_multiple_pdev_vdev_param *params) 2610 { 2611 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, params); 2612 } 2613 #endif /* end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2614 2615 /** 2616 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 2617 * @wmi_handle: wmi handle 2618 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 2619 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 2620 * 2621 * Provides notification to the WLAN firmware that host driver is requesting a 2622 * HardWare (HW) Mode change. This command is needed to support iHelium in the 2623 * configurations that include the Dual Band Simultaneous (DBS) feature. 2624 * 2625 * Return: Success if the cmd is sent successfully to the firmware 2626 */ 2627 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 2628 uint32_t hw_mode_index) 2629 { 2630 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 2631 wmi_buf_t buf; 2632 uint32_t len; 2633 2634 len = sizeof(*cmd); 2635 2636 buf = wmi_buf_alloc(wmi_handle, len); 2637 if (!buf) 2638 return QDF_STATUS_E_NOMEM; 2639 2640 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 2641 WMITLV_SET_HDR(&cmd->tlv_header, 2642 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 2643 WMITLV_GET_STRUCT_TLVLEN( 2644 wmi_pdev_set_hw_mode_cmd_fixed_param)); 2645 2646 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2647 wmi_handle, 2648 WMI_HOST_PDEV_ID_SOC); 2649 cmd->hw_mode_index = hw_mode_index; 2650 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 2651 2652 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 2653 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2654 WMI_PDEV_SET_HW_MODE_CMDID)) { 2655 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 2656 wmi_buf_free(buf); 2657 return QDF_STATUS_E_FAILURE; 2658 } 2659 2660 return QDF_STATUS_SUCCESS; 2661 } 2662 2663 /** 2664 * send_pdev_set_rf_path_cmd_tlv() - Send WMI_PDEV_SET_RF_PATH_CMDID to FW 2665 * @wmi_handle: wmi handle 2666 * @rf_path_index: the rf path mode to be selected 2667 * @pdev_id: pdev id 2668 * 2669 * Provides notification to the WLAN firmware that host driver is requesting a 2670 * rf path change. 2671 * 2672 * Return: Success if the cmd is sent successfully to the firmware 2673 */ 2674 static QDF_STATUS send_pdev_set_rf_path_cmd_tlv(wmi_unified_t wmi_handle, 2675 uint32_t rf_path_index, 2676 uint8_t pdev_id) 2677 { 2678 wmi_pdev_set_rf_path_cmd_fixed_param *cmd; 2679 wmi_buf_t buf; 2680 uint32_t len; 2681 2682 len = sizeof(*cmd); 2683 2684 buf = wmi_buf_alloc(wmi_handle, len); 2685 if (!buf) 2686 return QDF_STATUS_E_NOMEM; 2687 2688 cmd = (wmi_pdev_set_rf_path_cmd_fixed_param *)wmi_buf_data(buf); 2689 WMITLV_SET_HDR(&cmd->tlv_header, 2690 WMITLV_TAG_STRUC_wmi_pdev_set_rf_path_cmd_fixed_param, 2691 WMITLV_GET_STRUCT_TLVLEN( 2692 wmi_pdev_set_rf_path_cmd_fixed_param)); 2693 2694 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2695 wmi_handle, 2696 pdev_id); 2697 cmd->rf_path = rf_path_index; 2698 wmi_debug("HW mode index:%d", cmd->rf_path); 2699 2700 wmi_mtrace(WMI_PDEV_SET_RF_PATH_CMDID, NO_SESSION, 0); 2701 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2702 WMI_PDEV_SET_RF_PATH_CMDID)) { 2703 wmi_err("Failed to send WMI_PDEV_SET_RF_PATH_CMDID"); 2704 wmi_buf_free(buf); 2705 return QDF_STATUS_E_FAILURE; 2706 } 2707 2708 return QDF_STATUS_SUCCESS; 2709 } 2710 2711 /** 2712 * send_suspend_cmd_tlv() - WMI suspend function 2713 * @wmi_handle: handle to WMI. 2714 * @param: pointer to hold suspend parameter 2715 * @mac_id: radio context 2716 * 2717 * Return: QDF_STATUS_SUCCESS for success or error code 2718 */ 2719 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 2720 struct suspend_params *param, 2721 uint8_t mac_id) 2722 { 2723 wmi_pdev_suspend_cmd_fixed_param *cmd; 2724 wmi_buf_t wmibuf; 2725 uint32_t len = sizeof(*cmd); 2726 int32_t ret; 2727 2728 /* 2729 * send the command to Target to ignore the 2730 * PCIE reset so as to ensure that Host and target 2731 * states are in sync 2732 */ 2733 wmibuf = wmi_buf_alloc(wmi_handle, len); 2734 if (!wmibuf) 2735 return QDF_STATUS_E_NOMEM; 2736 2737 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 2738 WMITLV_SET_HDR(&cmd->tlv_header, 2739 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 2740 WMITLV_GET_STRUCT_TLVLEN 2741 (wmi_pdev_suspend_cmd_fixed_param)); 2742 if (param->disable_target_intr) 2743 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 2744 else 2745 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2746 2747 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2748 wmi_handle, 2749 mac_id); 2750 2751 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 2752 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 2753 WMI_PDEV_SUSPEND_CMDID); 2754 if (ret) { 2755 wmi_buf_free(wmibuf); 2756 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 2757 } 2758 2759 return ret; 2760 } 2761 2762 /** 2763 * send_resume_cmd_tlv() - WMI resume function 2764 * @wmi_handle: handle to WMI. 2765 * @mac_id: radio context 2766 * 2767 * Return: QDF_STATUS_SUCCESS for success or error code 2768 */ 2769 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 2770 uint8_t mac_id) 2771 { 2772 wmi_buf_t wmibuf; 2773 wmi_pdev_resume_cmd_fixed_param *cmd; 2774 QDF_STATUS ret; 2775 2776 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2777 if (!wmibuf) 2778 return QDF_STATUS_E_NOMEM; 2779 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 2780 WMITLV_SET_HDR(&cmd->tlv_header, 2781 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 2782 WMITLV_GET_STRUCT_TLVLEN 2783 (wmi_pdev_resume_cmd_fixed_param)); 2784 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2785 wmi_handle, 2786 mac_id); 2787 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 2788 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 2789 WMI_PDEV_RESUME_CMDID); 2790 if (QDF_IS_STATUS_ERROR(ret)) { 2791 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 2792 wmi_buf_free(wmibuf); 2793 } 2794 2795 return ret; 2796 } 2797 2798 /** 2799 * send_wow_enable_cmd_tlv() - WMI wow enable function 2800 * @wmi_handle: handle to WMI. 2801 * @param: pointer to hold wow enable parameter 2802 * @mac_id: radio context 2803 * 2804 * Return: QDF_STATUS_SUCCESS for success or error code 2805 */ 2806 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 2807 struct wow_cmd_params *param, 2808 uint8_t mac_id) 2809 { 2810 wmi_wow_enable_cmd_fixed_param *cmd; 2811 wmi_buf_t buf; 2812 int32_t len; 2813 int32_t ret; 2814 2815 len = sizeof(wmi_wow_enable_cmd_fixed_param); 2816 2817 buf = wmi_buf_alloc(wmi_handle, len); 2818 if (!buf) 2819 return QDF_STATUS_E_NOMEM; 2820 2821 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 2822 WMITLV_SET_HDR(&cmd->tlv_header, 2823 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 2824 WMITLV_GET_STRUCT_TLVLEN 2825 (wmi_wow_enable_cmd_fixed_param)); 2826 cmd->enable = param->enable; 2827 if (param->can_suspend_link) 2828 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 2829 else 2830 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 2831 cmd->flags = param->flags; 2832 2833 wmi_debug("suspend type: %s flag is 0x%x", 2834 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 2835 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 2836 cmd->flags); 2837 2838 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 2839 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2840 WMI_WOW_ENABLE_CMDID); 2841 if (ret) 2842 wmi_buf_free(buf); 2843 2844 return ret; 2845 } 2846 2847 /** 2848 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 2849 * @wmi_handle: wmi handle 2850 * @peer_addr: peer mac address 2851 * @param: pointer to ap_ps parameter structure 2852 * 2853 * Return: QDF_STATUS_SUCCESS for success or error code 2854 */ 2855 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2856 uint8_t *peer_addr, 2857 struct ap_ps_params *param) 2858 { 2859 wmi_ap_ps_peer_cmd_fixed_param *cmd; 2860 wmi_buf_t buf; 2861 int32_t err; 2862 2863 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2864 if (!buf) 2865 return QDF_STATUS_E_NOMEM; 2866 2867 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 2868 WMITLV_SET_HDR(&cmd->tlv_header, 2869 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 2870 WMITLV_GET_STRUCT_TLVLEN 2871 (wmi_ap_ps_peer_cmd_fixed_param)); 2872 cmd->vdev_id = param->vdev_id; 2873 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 2874 cmd->param = param->param; 2875 cmd->value = param->value; 2876 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 2877 err = wmi_unified_cmd_send(wmi_handle, buf, 2878 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 2879 if (err) { 2880 wmi_err("Failed to send set_ap_ps_param cmd"); 2881 wmi_buf_free(buf); 2882 return QDF_STATUS_E_FAILURE; 2883 } 2884 2885 return 0; 2886 } 2887 2888 /** 2889 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 2890 * @wmi_handle: wmi handle 2891 * @param: pointer to sta_ps parameter structure 2892 * 2893 * Return: QDF_STATUS_SUCCESS for success or error code 2894 */ 2895 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2896 struct sta_ps_params *param) 2897 { 2898 wmi_sta_powersave_param_cmd_fixed_param *cmd; 2899 wmi_buf_t buf; 2900 int32_t len = sizeof(*cmd); 2901 2902 buf = wmi_buf_alloc(wmi_handle, len); 2903 if (!buf) 2904 return QDF_STATUS_E_NOMEM; 2905 2906 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 2907 WMITLV_SET_HDR(&cmd->tlv_header, 2908 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 2909 WMITLV_GET_STRUCT_TLVLEN 2910 (wmi_sta_powersave_param_cmd_fixed_param)); 2911 cmd->vdev_id = param->vdev_id; 2912 cmd->param = param->param_id; 2913 cmd->value = param->value; 2914 2915 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 2916 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2917 WMI_STA_POWERSAVE_PARAM_CMDID)) { 2918 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 2919 param->vdev_id, param->param_id, param->value); 2920 wmi_buf_free(buf); 2921 return QDF_STATUS_E_FAILURE; 2922 } 2923 2924 return 0; 2925 } 2926 2927 /** 2928 * send_crash_inject_cmd_tlv() - inject fw crash 2929 * @wmi_handle: wmi handle 2930 * @param: pointer to crash inject parameter structure 2931 * 2932 * Return: QDF_STATUS_SUCCESS for success or return error 2933 */ 2934 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 2935 struct crash_inject *param) 2936 { 2937 int32_t ret = 0; 2938 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 2939 uint16_t len = sizeof(*cmd); 2940 wmi_buf_t buf; 2941 2942 buf = wmi_buf_alloc(wmi_handle, len); 2943 if (!buf) 2944 return QDF_STATUS_E_NOMEM; 2945 2946 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 2947 WMITLV_SET_HDR(&cmd->tlv_header, 2948 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 2949 WMITLV_GET_STRUCT_TLVLEN 2950 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 2951 cmd->type = param->type; 2952 cmd->delay_time_ms = param->delay_time_ms; 2953 2954 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 2955 wmi_info("type:%d delay_time_ms:%d current_time:%ld", 2956 cmd->type, cmd->delay_time_ms, qdf_mc_timer_get_system_time()); 2957 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2958 WMI_FORCE_FW_HANG_CMDID); 2959 if (ret) { 2960 wmi_err("Failed to send set param command, ret = %d", ret); 2961 wmi_buf_free(buf); 2962 } 2963 2964 return ret; 2965 } 2966 2967 /** 2968 * send_dbglog_cmd_tlv() - set debug log level 2969 * @wmi_handle: handle to WMI. 2970 * @dbglog_param: pointer to hold dbglog level parameter 2971 * 2972 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_* 2973 */ 2974 static QDF_STATUS 2975 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2976 struct dbglog_params *dbglog_param) 2977 { 2978 wmi_buf_t buf; 2979 wmi_debug_log_config_cmd_fixed_param *configmsg; 2980 QDF_STATUS status; 2981 int32_t i; 2982 int32_t len; 2983 int8_t *buf_ptr; 2984 int32_t *module_id_bitmap_array; /* Used to form the second tlv */ 2985 2986 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2987 2988 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2989 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2990 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2991 buf = wmi_buf_alloc(wmi_handle, len); 2992 if (!buf) 2993 return QDF_STATUS_E_NOMEM; 2994 2995 configmsg = 2996 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2997 buf_ptr = (int8_t *) configmsg; 2998 WMITLV_SET_HDR(&configmsg->tlv_header, 2999 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 3000 WMITLV_GET_STRUCT_TLVLEN 3001 (wmi_debug_log_config_cmd_fixed_param)); 3002 configmsg->dbg_log_param = dbglog_param->param; 3003 configmsg->value = dbglog_param->val; 3004 /* Filling in the data part of second tlv -- should 3005 * follow first tlv _ WMI_TLV_HDR_SIZE */ 3006 module_id_bitmap_array = (uint32_t *) (buf_ptr + 3007 sizeof 3008 (wmi_debug_log_config_cmd_fixed_param) 3009 + WMI_TLV_HDR_SIZE); 3010 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 3011 WMITLV_TAG_ARRAY_UINT32, 3012 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 3013 if (dbglog_param->module_id_bitmap) { 3014 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 3015 module_id_bitmap_array[i] = 3016 dbglog_param->module_id_bitmap[i]; 3017 } 3018 } 3019 3020 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 3021 status = wmi_unified_cmd_send(wmi_handle, buf, 3022 len, WMI_DBGLOG_CFG_CMDID); 3023 3024 if (status != QDF_STATUS_SUCCESS) 3025 wmi_buf_free(buf); 3026 3027 return status; 3028 } 3029 3030 /** 3031 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 3032 * @wmi_handle: handle to WMI. 3033 * @param: pointer to hold vdev set parameter 3034 * 3035 * Return: QDF_STATUS_SUCCESS for success or error code 3036 */ 3037 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 3038 struct vdev_set_params *param) 3039 { 3040 QDF_STATUS ret; 3041 wmi_vdev_set_param_cmd_fixed_param *cmd; 3042 wmi_buf_t buf; 3043 uint16_t len = sizeof(*cmd); 3044 uint32_t vdev_param; 3045 3046 vdev_param = convert_host_vdev_param_tlv(param->param_id); 3047 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 3048 wmi_err("Vdev param %d not available", param->param_id); 3049 return QDF_STATUS_E_INVAL; 3050 3051 } 3052 3053 buf = wmi_buf_alloc(wmi_handle, len); 3054 if (!buf) 3055 return QDF_STATUS_E_NOMEM; 3056 3057 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 3058 WMITLV_SET_HDR(&cmd->tlv_header, 3059 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 3060 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_param_cmd_fixed_param)); 3061 cmd->vdev_id = param->vdev_id; 3062 cmd->param_id = vdev_param; 3063 cmd->param_value = param->param_value; 3064 wmi_nofl_debug("Set vdev %d param 0x%x to %u", 3065 cmd->vdev_id, cmd->param_id, cmd->param_value); 3066 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 3067 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_SET_PARAM_CMDID); 3068 if (QDF_IS_STATUS_ERROR(ret)) { 3069 wmi_buf_free(buf); 3070 } 3071 3072 return ret; 3073 } 3074 3075 /** 3076 * send_multi_param_cmd_using_vdev_param_tlv() - vdev set parameter function 3077 * @wmi_handle : handle to WMI. 3078 * @params: pointer to parameters to set 3079 * 3080 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_* 3081 */ 3082 static QDF_STATUS 3083 send_multi_param_cmd_using_vdev_param_tlv(wmi_unified_t wmi_handle, 3084 struct set_multiple_pdev_vdev_param *params) 3085 { 3086 uint8_t index; 3087 struct vdev_set_params vdevparam; 3088 3089 for (index = 0; index < params->n_params; index++) { 3090 vdevparam.param_id = params->params[index].param_id; 3091 vdevparam.param_value = params->params[index].param_value; 3092 vdevparam.vdev_id = params->dev_id; 3093 if (QDF_IS_STATUS_ERROR(send_vdev_set_param_cmd_tlv(wmi_handle, &vdevparam))) { 3094 wmi_err("failed to send param:%d", vdevparam.param_id); 3095 return QDF_STATUS_E_FAILURE; 3096 } 3097 } 3098 return QDF_STATUS_SUCCESS; 3099 } 3100 3101 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 3102 /** 3103 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 3104 * @wmi_handle : handle to WMI. 3105 * @params: pointer to hold set_multiple_pdev_vdev_param info 3106 * 3107 * Return: QDF_STATUS_SUCCESS for success or error code 3108 */ 3109 static QDF_STATUS 3110 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 3111 struct set_multiple_pdev_vdev_param *params) 3112 { 3113 if (!wmi_service_enabled(wmi_handle, 3114 wmi_service_combined_set_param_support)) 3115 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, 3116 params); 3117 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 3118 } 3119 3120 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 3121 3122 /** 3123 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 3124 * @wmi_handle : handle to WMI. 3125 * @params: pointer to hold set_multiple_pdev_vdev_param info 3126 * 3127 * Return: QDF_STATUS_SUCCESS for success or error code 3128 */ 3129 static QDF_STATUS 3130 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 3131 struct set_multiple_pdev_vdev_param *params) 3132 { 3133 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, params); 3134 } 3135 #endif /*end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 3136 3137 /** 3138 * send_vdev_set_mu_snif_cmd_tlv() - WMI vdev set mu snif function 3139 * @wmi_handle: handle to WMI. 3140 * @param: pointer to hold mu sniffer parameter 3141 * 3142 * Return: QDF_STATUS_SUCCESS for success or error code 3143 */ 3144 static 3145 QDF_STATUS send_vdev_set_mu_snif_cmd_tlv(wmi_unified_t wmi_handle, 3146 struct vdev_set_mu_snif_param *param) 3147 { 3148 QDF_STATUS ret; 3149 wmi_vdev_set_mu_snif_cmd_param *cmd; 3150 wmi_buf_t buf; 3151 uint32_t *tmp_ptr; 3152 uint16_t len = sizeof(*cmd); 3153 uint8_t *buf_ptr; 3154 uint32_t i; 3155 3156 /* Length TLV placeholder for array of uint32_t */ 3157 len += WMI_TLV_HDR_SIZE; 3158 3159 if (param->num_aid) 3160 len += param->num_aid * sizeof(uint32_t); 3161 3162 buf = wmi_buf_alloc(wmi_handle, len); 3163 if (!buf) 3164 return QDF_STATUS_E_NOMEM; 3165 3166 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3167 cmd = (wmi_vdev_set_mu_snif_cmd_param *)buf_ptr; 3168 3169 WMITLV_SET_HDR(&cmd->tlv_header, 3170 WMITLV_TAG_STRUC_wmi_vdev_set_mu_snif_cmd_param, 3171 WMITLV_GET_STRUCT_TLVLEN 3172 (wmi_vdev_set_mu_snif_cmd_param)); 3173 3174 cmd->vdev_id = param->vdev_id; 3175 cmd->mode = param->mode; 3176 cmd->max_num_user = param->num_user; 3177 3178 buf_ptr += sizeof(*cmd); 3179 3180 tmp_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 3181 3182 for (i = 0; i < param->num_aid; ++i) 3183 tmp_ptr[i] = param->aid[i]; 3184 3185 WMITLV_SET_HDR(buf_ptr, 3186 WMITLV_TAG_ARRAY_UINT32, 3187 (param->num_aid * sizeof(uint32_t))); 3188 3189 wmi_debug("Setting vdev %d mode = %x, max user = %u aids= %u", 3190 cmd->vdev_id, cmd->mode, cmd->max_num_user, param->num_aid); 3191 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 3192 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3193 WMI_VDEV_SET_MU_SNIF_CMDID); 3194 if (QDF_IS_STATUS_ERROR(ret)) { 3195 wmi_err("Failed to send set param command ret = %d", ret); 3196 wmi_buf_free(buf); 3197 } 3198 3199 return ret; 3200 } 3201 3202 /** 3203 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 3204 * @wmi_handle: handle to WMI. 3205 * @macaddr: Peer mac address to be filter 3206 * @mac_id: mac id to have radio context 3207 * @enb_dsb: Enable MAC based filtering or Disable 3208 * 3209 * Return: QDF_STATUS 3210 */ 3211 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 3212 uint8_t *macaddr, 3213 uint8_t mac_id, 3214 uint8_t enb_dsb) 3215 { 3216 int32_t ret; 3217 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 3218 wmi_pdev_pktlog_filter_info *mac_info; 3219 wmi_buf_t buf; 3220 uint8_t *buf_ptr; 3221 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 3222 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 3223 3224 buf = wmi_buf_alloc(wmi_handle, len); 3225 if (!buf) 3226 return QDF_STATUS_E_NOMEM; 3227 3228 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3229 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 3230 WMITLV_SET_HDR(&cmd->tlv_header, 3231 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 3232 WMITLV_GET_STRUCT_TLVLEN 3233 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 3234 cmd->pdev_id = mac_id; 3235 cmd->enable = enb_dsb; 3236 cmd->num_of_mac_addresses = 1; 3237 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 3238 3239 buf_ptr += sizeof(*cmd); 3240 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3241 sizeof(wmi_pdev_pktlog_filter_info)); 3242 buf_ptr += WMI_TLV_HDR_SIZE; 3243 3244 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 3245 3246 WMITLV_SET_HDR(&mac_info->tlv_header, 3247 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 3248 WMITLV_GET_STRUCT_TLVLEN 3249 (wmi_pdev_pktlog_filter_info)); 3250 3251 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 3252 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3253 WMI_PDEV_PKTLOG_FILTER_CMDID); 3254 if (ret) { 3255 wmi_err("Failed to send peer based pktlog command to FW =%d" 3256 , ret); 3257 wmi_buf_free(buf); 3258 } 3259 3260 return ret; 3261 } 3262 3263 /** 3264 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 3265 * @wmi_handle: handle to WMI. 3266 * @PKTLOG_EVENT: packet log event 3267 * @mac_id: mac id to have radio context 3268 * 3269 * Return: QDF_STATUS_SUCCESS for success or error code 3270 */ 3271 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 3272 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 3273 { 3274 int32_t ret, idx, max_idx; 3275 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 3276 wmi_buf_t buf; 3277 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 3278 3279 buf = wmi_buf_alloc(wmi_handle, len); 3280 if (!buf) 3281 return -QDF_STATUS_E_NOMEM; 3282 3283 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 3284 WMITLV_SET_HDR(&cmd->tlv_header, 3285 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 3286 WMITLV_GET_STRUCT_TLVLEN 3287 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 3288 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 3289 cmd->evlist = 0; 3290 for (idx = 0; idx < max_idx; idx++) { 3291 if (PKTLOG_EVENT & (1 << idx)) 3292 cmd->evlist |= pktlog_event_tlv[idx]; 3293 } 3294 cmd->pdev_id = mac_id; 3295 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 3296 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3297 WMI_PDEV_PKTLOG_ENABLE_CMDID); 3298 if (ret) { 3299 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 3300 wmi_buf_free(buf); 3301 } 3302 3303 return ret; 3304 } 3305 3306 /** 3307 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 3308 * @wmi_handle: handle to WMI. 3309 * @mac_id: mac id to have radio context 3310 * 3311 * Return: QDF_STATUS_SUCCESS for success or error code 3312 */ 3313 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 3314 uint8_t mac_id) 3315 { 3316 int32_t ret; 3317 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 3318 wmi_buf_t buf; 3319 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 3320 3321 buf = wmi_buf_alloc(wmi_handle, len); 3322 if (!buf) 3323 return -QDF_STATUS_E_NOMEM; 3324 3325 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 3326 WMITLV_SET_HDR(&cmd->tlv_header, 3327 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 3328 WMITLV_GET_STRUCT_TLVLEN 3329 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 3330 cmd->pdev_id = mac_id; 3331 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 3332 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3333 WMI_PDEV_PKTLOG_DISABLE_CMDID); 3334 if (ret) { 3335 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 3336 wmi_buf_free(buf); 3337 } 3338 3339 return ret; 3340 } 3341 3342 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 3343 /** 3344 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 3345 * sync time between between host and firmware 3346 * @wmi_handle: handle to WMI. 3347 * 3348 * Return: None 3349 */ 3350 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 3351 { 3352 wmi_buf_t buf; 3353 QDF_STATUS status = QDF_STATUS_SUCCESS; 3354 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 3355 int32_t len; 3356 qdf_time_t time_ms; 3357 3358 len = sizeof(*time_stamp); 3359 buf = wmi_buf_alloc(wmi_handle, len); 3360 3361 if (!buf) 3362 return; 3363 3364 time_stamp = 3365 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 3366 (wmi_buf_data(buf)); 3367 WMITLV_SET_HDR(&time_stamp->tlv_header, 3368 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 3369 WMITLV_GET_STRUCT_TLVLEN( 3370 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 3371 3372 time_ms = qdf_get_time_of_the_day_ms(); 3373 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 3374 time_stamp->time_stamp_low = time_ms & 3375 WMI_FW_TIME_STAMP_LOW_MASK; 3376 /* 3377 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 3378 * won't exceed 27 bit 3379 */ 3380 time_stamp->time_stamp_high = 0; 3381 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 3382 time_stamp->mode, time_stamp->time_stamp_low, 3383 time_stamp->time_stamp_high); 3384 3385 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 3386 status = wmi_unified_cmd_send(wmi_handle, buf, 3387 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 3388 if (status) { 3389 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 3390 wmi_buf_free(buf); 3391 } 3392 3393 } 3394 3395 /** 3396 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 3397 * @wmi_handle: handle to WMI. 3398 * @param: pointer to hold FILS Discovery send cmd parameter 3399 * 3400 * Return: QDF_STATUS_SUCCESS for success or error code 3401 */ 3402 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 3403 struct fils_discovery_tmpl_params *param) 3404 { 3405 int32_t ret; 3406 wmi_fd_tmpl_cmd_fixed_param *cmd; 3407 wmi_buf_t wmi_buf; 3408 uint8_t *buf_ptr; 3409 uint32_t wmi_buf_len; 3410 3411 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 3412 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 3413 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3414 if (!wmi_buf) 3415 return QDF_STATUS_E_NOMEM; 3416 3417 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3418 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 3419 WMITLV_SET_HDR(&cmd->tlv_header, 3420 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 3421 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 3422 cmd->vdev_id = param->vdev_id; 3423 cmd->buf_len = param->tmpl_len; 3424 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 3425 3426 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3427 buf_ptr += WMI_TLV_HDR_SIZE; 3428 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 3429 3430 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 3431 ret = wmi_unified_cmd_send(wmi_handle, 3432 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 3433 3434 if (ret) { 3435 wmi_err("Failed to send fd tmpl: %d", ret); 3436 wmi_buf_free(wmi_buf); 3437 return ret; 3438 } 3439 3440 return 0; 3441 } 3442 3443 /** 3444 * send_beacon_tmpl_send_cmd_tlv() - WMI beacon send function 3445 * @wmi_handle: handle to WMI. 3446 * @param: pointer to hold beacon send cmd parameter 3447 * 3448 * Return: QDF_STATUS_SUCCESS for success or error code 3449 */ 3450 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 3451 struct beacon_tmpl_params *param) 3452 { 3453 int32_t ret; 3454 wmi_bcn_tmpl_cmd_fixed_param *cmd; 3455 wmi_bcn_prb_info *bcn_prb_info; 3456 wmi_buf_t wmi_buf; 3457 uint8_t *buf_ptr; 3458 uint32_t wmi_buf_len; 3459 3460 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 3461 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 3462 param->tmpl_len_aligned + 3463 bcn_tmpl_mlo_param_size(param) + 3464 bcn_tmpl_ml_info_size(param); 3465 3466 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3467 if (!wmi_buf) 3468 return QDF_STATUS_E_NOMEM; 3469 3470 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3471 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 3472 WMITLV_SET_HDR(&cmd->tlv_header, 3473 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 3474 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 3475 cmd->vdev_id = param->vdev_id; 3476 cmd->tim_ie_offset = param->tim_ie_offset; 3477 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 3478 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 3479 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 3480 cmd->esp_ie_offset = param->esp_ie_offset; 3481 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 3482 cmd->ema_params = param->ema_params; 3483 cmd->buf_len = param->tmpl_len; 3484 cmd->csa_event_bitmap = param->csa_event_bitmap; 3485 3486 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 3487 param->enable_bigtk); 3488 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 3489 3490 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 3491 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 3492 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 3493 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 3494 bcn_prb_info->caps = 0; 3495 bcn_prb_info->erp = 0; 3496 buf_ptr += sizeof(wmi_bcn_prb_info); 3497 3498 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3499 buf_ptr += WMI_TLV_HDR_SIZE; 3500 3501 /* for big endian host, copy engine byte_swap is enabled 3502 * But the frame content is in network byte order 3503 * Need to byte swap the frame content - so when copy engine 3504 * does byte_swap - target gets frame content in the correct order 3505 */ 3506 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 3507 param->tmpl_len); 3508 3509 buf_ptr += roundup(param->tmpl_len, sizeof(uint32_t)); 3510 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 3511 3512 buf_ptr = bcn_tmpl_add_ml_info(buf_ptr, param); 3513 3514 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 3515 ret = wmi_unified_cmd_send(wmi_handle, 3516 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 3517 if (ret) { 3518 wmi_err("Failed to send bcn tmpl: %d", ret); 3519 wmi_buf_free(wmi_buf); 3520 } 3521 3522 return 0; 3523 } 3524 3525 #ifdef WLAN_FEATURE_11BE 3526 static inline void copy_peer_flags_tlv_11be( 3527 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3528 struct peer_assoc_params *param) 3529 { 3530 if (param->bw_320) 3531 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 3532 if (param->eht_flag) 3533 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 3534 3535 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3536 } 3537 #else 3538 static inline void copy_peer_flags_tlv_11be( 3539 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3540 struct peer_assoc_params *param) 3541 { 3542 } 3543 #endif 3544 #ifdef WLAN_FEATURE_11BE_MLO 3545 static inline void copy_peer_flags_tlv_vendor( 3546 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3547 struct peer_assoc_params *param) 3548 { 3549 if (!(param->mlo_params.mlo_enabled)) 3550 return; 3551 if (param->qcn_node_flag) 3552 cmd->peer_flags_ext |= WMI_PEER_EXT_IS_QUALCOMM_NODE; 3553 if (param->mesh_node_flag) 3554 cmd->peer_flags_ext |= WMI_PEER_EXT_IS_MESH_NODE; 3555 3556 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3557 } 3558 #else 3559 static inline void copy_peer_flags_tlv_vendor( 3560 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3561 struct peer_assoc_params *param) 3562 { 3563 } 3564 #endif 3565 3566 static inline void copy_peer_flags_tlv( 3567 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3568 struct peer_assoc_params *param) 3569 { 3570 /* 3571 * The target only needs a subset of the flags maintained in the host. 3572 * Just populate those flags and send it down 3573 */ 3574 cmd->peer_flags = 0; 3575 if (param->peer_dms_capable) 3576 cmd->peer_flags_ext |= WMI_PEER_EXT_DMS_CAPABLE; 3577 /* 3578 * Do not enable HT/VHT if WMM/wme is disabled for vap. 3579 */ 3580 if (param->is_wme_set) { 3581 3582 if (param->qos_flag) 3583 cmd->peer_flags |= WMI_PEER_QOS; 3584 if (param->apsd_flag) 3585 cmd->peer_flags |= WMI_PEER_APSD; 3586 if (param->ht_flag) 3587 cmd->peer_flags |= WMI_PEER_HT; 3588 if (param->bw_40) 3589 cmd->peer_flags |= WMI_PEER_40MHZ; 3590 if (param->bw_80) 3591 cmd->peer_flags |= WMI_PEER_80MHZ; 3592 if (param->bw_160) 3593 cmd->peer_flags |= WMI_PEER_160MHZ; 3594 3595 copy_peer_flags_tlv_11be(cmd, param); 3596 copy_peer_flags_tlv_vendor(cmd, param); 3597 3598 /* Typically if STBC is enabled for VHT it should be enabled 3599 * for HT as well 3600 **/ 3601 if (param->stbc_flag) 3602 cmd->peer_flags |= WMI_PEER_STBC; 3603 3604 /* Typically if LDPC is enabled for VHT it should be enabled 3605 * for HT as well 3606 **/ 3607 if (param->ldpc_flag) 3608 cmd->peer_flags |= WMI_PEER_LDPC; 3609 3610 if (param->static_mimops_flag) 3611 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 3612 if (param->dynamic_mimops_flag) 3613 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 3614 if (param->spatial_mux_flag) 3615 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 3616 if (param->vht_flag) 3617 cmd->peer_flags |= WMI_PEER_VHT; 3618 if (param->he_flag) 3619 cmd->peer_flags |= WMI_PEER_HE; 3620 if (param->p2p_capable_sta) 3621 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 3622 } 3623 3624 if (param->is_pmf_enabled) 3625 cmd->peer_flags |= WMI_PEER_PMF; 3626 /* 3627 * Suppress authorization for all AUTH modes that need 4-way handshake 3628 * (during re-association). 3629 * Authorization will be done for these modes on key installation. 3630 */ 3631 if (param->auth_flag) 3632 cmd->peer_flags |= WMI_PEER_AUTH; 3633 if (param->need_ptk_4_way) 3634 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 3635 else 3636 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 3637 if (param->need_gtk_2_way) 3638 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 3639 /* safe mode bypass the 4-way handshake */ 3640 if (param->safe_mode_enabled) 3641 cmd->peer_flags &= 3642 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 3643 /* inter BSS peer */ 3644 if (param->inter_bss_peer) 3645 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 3646 /* Disable AMSDU for station transmit, if user configures it */ 3647 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 3648 * it 3649 * if (param->amsdu_disable) Add after FW support 3650 **/ 3651 3652 /* Target asserts if node is marked HT and all MCS is set to 0. 3653 * Mark the node as non-HT if all the mcs rates are disabled through 3654 * iwpriv 3655 **/ 3656 if (param->peer_ht_rates.num_rates == 0) 3657 cmd->peer_flags &= ~WMI_PEER_HT; 3658 3659 if (param->twt_requester) 3660 cmd->peer_flags |= WMI_PEER_TWT_REQ; 3661 3662 if (param->twt_responder) 3663 cmd->peer_flags |= WMI_PEER_TWT_RESP; 3664 } 3665 3666 static inline void copy_peer_mac_addr_tlv( 3667 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3668 struct peer_assoc_params *param) 3669 { 3670 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 3671 } 3672 3673 #ifdef WLAN_FEATURE_11BE 3674 static uint8_t *update_peer_flags_tlv_ehtinfo( 3675 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3676 struct peer_assoc_params *param, uint8_t *buf_ptr) 3677 { 3678 wmi_eht_rate_set *eht_mcs; 3679 int i; 3680 3681 cmd->peer_eht_ops = param->peer_eht_ops; 3682 cmd->puncture_20mhz_bitmap = ~param->puncture_bitmap; 3683 3684 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 3685 sizeof(param->peer_eht_cap_macinfo)); 3686 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 3687 sizeof(param->peer_eht_cap_phyinfo)); 3688 qdf_mem_copy(&cmd->peer_eht_ppet, ¶m->peer_eht_ppet, 3689 sizeof(param->peer_eht_ppet)); 3690 3691 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3692 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 3693 buf_ptr += WMI_TLV_HDR_SIZE; 3694 3695 /* Loop through the EHT rate set */ 3696 for (i = 0; i < param->peer_eht_mcs_count; i++) { 3697 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 3698 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 3699 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 3700 3701 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 3702 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 3703 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 3704 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 3705 buf_ptr += sizeof(wmi_eht_rate_set); 3706 } 3707 3708 wmi_debug("nss %d ru mask 0x%x", 3709 cmd->peer_eht_ppet.numss_m1, cmd->peer_eht_ppet.ru_mask); 3710 for (i = 0; i < WMI_MAX_NUM_SS; i++) { 3711 wmi_debug("ppet idx %d ppet %x ", 3712 i, cmd->peer_eht_ppet.ppet16_ppet8_ru3_ru0[i]); 3713 } 3714 3715 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 3716 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3717 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 3718 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3719 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3720 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 3721 param->peer_eht_tx_mcs_set 3722 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3723 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 3724 param->peer_eht_rx_mcs_set 3725 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3726 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3727 QDF_MAC_ADDR_REF(param->peer_mac)); 3728 } 3729 3730 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 3731 cmd->peer_eht_cap_mac[0], 3732 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 3733 cmd->peer_eht_cap_phy[0], cmd->peer_eht_cap_phy[1], 3734 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 3735 3736 return buf_ptr; 3737 } 3738 #else 3739 static uint8_t *update_peer_flags_tlv_ehtinfo( 3740 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3741 struct peer_assoc_params *param, uint8_t *buf_ptr) 3742 { 3743 return buf_ptr; 3744 } 3745 #endif 3746 3747 #ifdef WLAN_FEATURE_11BE 3748 static 3749 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3750 { 3751 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 3752 + WMI_TLV_HDR_SIZE); 3753 } 3754 3755 static void wmi_populate_service_11be(uint32_t *wmi_service) 3756 { 3757 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 3758 } 3759 3760 #else 3761 static 3762 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3763 { 3764 return 0; 3765 } 3766 3767 static void wmi_populate_service_11be(uint32_t *wmi_service) 3768 { 3769 } 3770 3771 #endif 3772 3773 /** 3774 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 3775 * @wmi_handle: handle to WMI. 3776 * @param: pointer to peer assoc parameter 3777 * 3778 * Return: QDF_STATUS_SUCCESS for success or error code 3779 */ 3780 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 3781 struct peer_assoc_params *param) 3782 { 3783 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 3784 wmi_vht_rate_set *mcs; 3785 wmi_he_rate_set *he_mcs; 3786 wmi_buf_t buf; 3787 int32_t len; 3788 uint8_t *buf_ptr; 3789 QDF_STATUS ret; 3790 uint32_t peer_legacy_rates_align; 3791 uint32_t peer_ht_rates_align; 3792 int32_t i; 3793 3794 3795 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 3796 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 3797 3798 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 3799 (peer_legacy_rates_align * sizeof(uint8_t)) + 3800 WMI_TLV_HDR_SIZE + 3801 (peer_ht_rates_align * sizeof(uint8_t)) + 3802 sizeof(wmi_vht_rate_set) + 3803 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 3804 + WMI_TLV_HDR_SIZE) 3805 + wmi_eht_peer_assoc_params_len(param) + 3806 peer_assoc_mlo_params_size(param) + 3807 peer_assoc_t2lm_params_size(param); 3808 3809 buf = wmi_buf_alloc(wmi_handle, len); 3810 if (!buf) 3811 return QDF_STATUS_E_NOMEM; 3812 3813 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3814 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 3815 WMITLV_SET_HDR(&cmd->tlv_header, 3816 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 3817 WMITLV_GET_STRUCT_TLVLEN 3818 (wmi_peer_assoc_complete_cmd_fixed_param)); 3819 3820 cmd->vdev_id = param->vdev_id; 3821 3822 cmd->peer_new_assoc = param->peer_new_assoc; 3823 cmd->peer_associd = param->peer_associd; 3824 3825 copy_peer_flags_tlv(cmd, param); 3826 copy_peer_mac_addr_tlv(cmd, param); 3827 3828 cmd->peer_rate_caps = param->peer_rate_caps; 3829 cmd->peer_caps = param->peer_caps; 3830 cmd->peer_listen_intval = param->peer_listen_intval; 3831 cmd->peer_ht_caps = param->peer_ht_caps; 3832 cmd->peer_max_mpdu = param->peer_max_mpdu; 3833 cmd->peer_mpdu_density = param->peer_mpdu_density; 3834 cmd->peer_vht_caps = param->peer_vht_caps; 3835 cmd->peer_phymode = param->peer_phymode; 3836 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 3837 3838 /* Update 11ax capabilities */ 3839 cmd->peer_he_cap_info = 3840 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 3841 cmd->peer_he_cap_info_ext = 3842 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 3843 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 3844 cmd->peer_he_ops = param->peer_he_ops; 3845 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 3846 sizeof(param->peer_he_cap_phyinfo)); 3847 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 3848 sizeof(param->peer_ppet)); 3849 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 3850 3851 /* Update peer legacy rate information */ 3852 buf_ptr += sizeof(*cmd); 3853 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3854 peer_legacy_rates_align); 3855 buf_ptr += WMI_TLV_HDR_SIZE; 3856 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 3857 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 3858 param->peer_legacy_rates.num_rates); 3859 3860 /* Update peer HT rate information */ 3861 buf_ptr += peer_legacy_rates_align; 3862 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3863 peer_ht_rates_align); 3864 buf_ptr += WMI_TLV_HDR_SIZE; 3865 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 3866 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 3867 param->peer_ht_rates.num_rates); 3868 3869 /* VHT Rates */ 3870 buf_ptr += peer_ht_rates_align; 3871 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 3872 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 3873 3874 cmd->auth_mode = param->akm; 3875 cmd->peer_nss = param->peer_nss; 3876 3877 /* Update bandwidth-NSS mapping */ 3878 cmd->peer_bw_rxnss_override = 0; 3879 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 3880 3881 mcs = (wmi_vht_rate_set *) buf_ptr; 3882 if (param->vht_capable) { 3883 mcs->rx_max_rate = param->rx_max_rate; 3884 mcs->rx_mcs_set = param->rx_mcs_set; 3885 mcs->tx_max_rate = param->tx_max_rate; 3886 mcs->tx_mcs_set = param->tx_mcs_set; 3887 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 3888 } 3889 3890 /* HE Rates */ 3891 cmd->min_data_rate = param->min_data_rate; 3892 cmd->peer_he_mcs = param->peer_he_mcs_count; 3893 buf_ptr += sizeof(wmi_vht_rate_set); 3894 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3895 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 3896 buf_ptr += WMI_TLV_HDR_SIZE; 3897 3898 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 3899 /* Loop through the HE rate set */ 3900 for (i = 0; i < param->peer_he_mcs_count; i++) { 3901 he_mcs = (wmi_he_rate_set *) buf_ptr; 3902 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 3903 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 3904 3905 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 3906 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 3907 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 3908 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 3909 buf_ptr += sizeof(wmi_he_rate_set); 3910 } 3911 3912 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 3913 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3914 == WMI_HOST_HE_INVALID_MCSNSSMAP || 3915 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3916 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3917 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 3918 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3919 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 3920 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3921 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3922 QDF_MAC_ADDR_REF(param->peer_mac)); 3923 } 3924 3925 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 3926 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 3927 "nss %d phymode %d peer_mpdu_density %d " 3928 "cmd->peer_vht_caps %x " 3929 "HE cap_info %x ops %x " 3930 "HE cap_info_ext %x " 3931 "HE phy %x %x %x " 3932 "peer_bw_rxnss_override %x", 3933 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 3934 cmd->peer_rate_caps, cmd->peer_caps, 3935 cmd->peer_listen_intval, cmd->peer_ht_caps, 3936 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 3937 cmd->peer_mpdu_density, 3938 cmd->peer_vht_caps, cmd->peer_he_cap_info, 3939 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 3940 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 3941 cmd->peer_he_cap_phy[2], 3942 cmd->peer_bw_rxnss_override); 3943 3944 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 3945 3946 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 3947 3948 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 3949 3950 buf_ptr = peer_assoc_add_tid_to_link_map(buf_ptr, param); 3951 3952 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 3953 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3954 WMI_PEER_ASSOC_CMDID); 3955 if (QDF_IS_STATUS_ERROR(ret)) { 3956 wmi_err("Failed to send peer assoc command ret = %d", ret); 3957 wmi_buf_free(buf); 3958 } 3959 3960 return ret; 3961 } 3962 3963 /* copy_scan_notify_events() - Helper routine to copy scan notify events 3964 */ 3965 static inline void copy_scan_event_cntrl_flags( 3966 wmi_start_scan_cmd_fixed_param * cmd, 3967 struct scan_req_params *param) 3968 { 3969 3970 /* Scan events subscription */ 3971 if (param->scan_ev_started) 3972 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 3973 if (param->scan_ev_completed) 3974 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 3975 if (param->scan_ev_bss_chan) 3976 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 3977 if (param->scan_ev_foreign_chan) 3978 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 3979 if (param->scan_ev_dequeued) 3980 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 3981 if (param->scan_ev_preempted) 3982 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 3983 if (param->scan_ev_start_failed) 3984 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 3985 if (param->scan_ev_restarted) 3986 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 3987 if (param->scan_ev_foreign_chn_exit) 3988 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 3989 if (param->scan_ev_suspended) 3990 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 3991 if (param->scan_ev_resumed) 3992 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 3993 3994 /** Set scan control flags */ 3995 cmd->scan_ctrl_flags = 0; 3996 if (param->scan_f_passive) 3997 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 3998 if (param->scan_f_strict_passive_pch) 3999 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 4000 if (param->scan_f_promisc_mode) 4001 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 4002 if (param->scan_f_capture_phy_err) 4003 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 4004 if (param->scan_f_half_rate) 4005 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 4006 if (param->scan_f_quarter_rate) 4007 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 4008 if (param->scan_f_cck_rates) 4009 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 4010 if (param->scan_f_ofdm_rates) 4011 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 4012 if (param->scan_f_chan_stat_evnt) 4013 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 4014 if (param->scan_f_filter_prb_req) 4015 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 4016 if (param->scan_f_bcast_probe) 4017 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 4018 if (param->scan_f_offchan_mgmt_tx) 4019 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 4020 if (param->scan_f_offchan_data_tx) 4021 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 4022 if (param->scan_f_force_active_dfs_chn) 4023 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 4024 if (param->scan_f_add_tpc_ie_in_probe) 4025 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 4026 if (param->scan_f_add_ds_ie_in_probe) 4027 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 4028 if (param->scan_f_add_spoofed_mac_in_probe) 4029 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 4030 if (param->scan_f_add_rand_seq_in_probe) 4031 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 4032 if (param->scan_f_en_ie_allowlist_in_probe) 4033 cmd->scan_ctrl_flags |= 4034 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 4035 if (param->scan_f_pause_home_channel) 4036 cmd->scan_ctrl_flags |= 4037 WMI_SCAN_FLAG_PAUSE_HOME_CHANNEL; 4038 if (param->scan_f_report_cca_busy_for_each_20mhz) 4039 cmd->scan_ctrl_flags |= 4040 WMI_SCAN_FLAG_REPORT_CCA_BUSY_FOREACH_20MHZ; 4041 4042 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 4043 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 4044 param->adaptive_dwell_time_mode); 4045 } 4046 4047 /* scan_copy_ie_buffer() - Copy scan ie_data */ 4048 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 4049 struct scan_req_params *params) 4050 { 4051 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 4052 } 4053 4054 /** 4055 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 4056 * @mac: random mac addr 4057 * @mask: random mac mask 4058 * @mac_addr: wmi random mac 4059 * @mac_mask: wmi random mac mask 4060 * 4061 * Return None. 4062 */ 4063 static inline 4064 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 4065 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 4066 { 4067 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 4068 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 4069 } 4070 4071 /* 4072 * wmi_fill_vendor_oui() - fill vendor OUIs 4073 * @buf_ptr: pointer to wmi tlv buffer 4074 * @num_vendor_oui: number of vendor OUIs to be filled 4075 * @param_voui: pointer to OUI buffer 4076 * 4077 * This function populates the wmi tlv buffer when vendor specific OUIs are 4078 * present. 4079 * 4080 * Return: None 4081 */ 4082 static inline 4083 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 4084 uint32_t *pvoui) 4085 { 4086 wmi_vendor_oui *voui = NULL; 4087 uint32_t i; 4088 4089 voui = (wmi_vendor_oui *)buf_ptr; 4090 4091 for (i = 0; i < num_vendor_oui; i++) { 4092 WMITLV_SET_HDR(&voui[i].tlv_header, 4093 WMITLV_TAG_STRUC_wmi_vendor_oui, 4094 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 4095 voui[i].oui_type_subtype = pvoui[i]; 4096 } 4097 } 4098 4099 /* 4100 * wmi_fill_ie_allowlist_attrs() - fill IE allowlist attrs 4101 * @ie_bitmap: output pointer to ie bit map in cmd 4102 * @num_vendor_oui: output pointer to num vendor OUIs 4103 * @ie_allowlist: input parameter 4104 * 4105 * This function populates the IE allowlist attrs of scan, pno and 4106 * scan oui commands for ie_allowlist parameter. 4107 * 4108 * Return: None 4109 */ 4110 static inline 4111 void wmi_fill_ie_allowlist_attrs(uint32_t *ie_bitmap, 4112 uint32_t *num_vendor_oui, 4113 struct probe_req_allowlist_attr *ie_allowlist) 4114 { 4115 uint32_t i = 0; 4116 4117 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 4118 ie_bitmap[i] = ie_allowlist->ie_bitmap[i]; 4119 4120 *num_vendor_oui = ie_allowlist->num_vendor_oui; 4121 } 4122 4123 /** 4124 * send_scan_start_cmd_tlv() - WMI scan start function 4125 * @wmi_handle: handle to WMI. 4126 * @params: pointer to hold scan start cmd parameter 4127 * 4128 * Return: QDF_STATUS_SUCCESS for success or error code 4129 */ 4130 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 4131 struct scan_req_params *params) 4132 { 4133 int32_t ret = 0; 4134 int32_t i; 4135 wmi_buf_t wmi_buf; 4136 wmi_start_scan_cmd_fixed_param *cmd; 4137 uint8_t *buf_ptr; 4138 uint32_t *tmp_ptr; 4139 wmi_ssid *ssid = NULL; 4140 wmi_mac_addr *bssid; 4141 size_t len = sizeof(*cmd); 4142 uint16_t extraie_len_with_pad = 0; 4143 uint8_t phymode_roundup = 0; 4144 struct probe_req_allowlist_attr *ie_allowlist = ¶ms->ie_allowlist; 4145 wmi_hint_freq_short_ssid *s_ssid = NULL; 4146 wmi_hint_freq_bssid *hint_bssid = NULL; 4147 4148 /* Length TLV placeholder for array of uint32_t */ 4149 len += WMI_TLV_HDR_SIZE; 4150 /* calculate the length of buffer required */ 4151 if (params->chan_list.num_chan) 4152 len += params->chan_list.num_chan * sizeof(uint32_t); 4153 4154 /* Length TLV placeholder for array of wmi_ssid structures */ 4155 len += WMI_TLV_HDR_SIZE; 4156 if (params->num_ssids) 4157 len += params->num_ssids * sizeof(wmi_ssid); 4158 4159 /* Length TLV placeholder for array of wmi_mac_addr structures */ 4160 len += WMI_TLV_HDR_SIZE; 4161 if (params->num_bssid) 4162 len += sizeof(wmi_mac_addr) * params->num_bssid; 4163 4164 /* Length TLV placeholder for array of bytes */ 4165 len += WMI_TLV_HDR_SIZE; 4166 if (params->extraie.len) 4167 extraie_len_with_pad = 4168 roundup(params->extraie.len, sizeof(uint32_t)); 4169 len += extraie_len_with_pad; 4170 4171 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 4172 if (ie_allowlist->num_vendor_oui) 4173 len += ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 4174 4175 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 4176 if (params->scan_f_wide_band) 4177 phymode_roundup = 4178 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 4179 sizeof(uint32_t)); 4180 len += phymode_roundup; 4181 4182 len += WMI_TLV_HDR_SIZE; 4183 if (params->num_hint_bssid) 4184 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 4185 4186 len += WMI_TLV_HDR_SIZE; 4187 if (params->num_hint_s_ssid) 4188 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 4189 4190 /* Allocate the memory */ 4191 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4192 if (!wmi_buf) 4193 return QDF_STATUS_E_FAILURE; 4194 4195 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4196 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 4197 WMITLV_SET_HDR(&cmd->tlv_header, 4198 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 4199 WMITLV_GET_STRUCT_TLVLEN 4200 (wmi_start_scan_cmd_fixed_param)); 4201 4202 cmd->scan_id = params->scan_id; 4203 cmd->scan_req_id = params->scan_req_id; 4204 cmd->vdev_id = params->vdev_id; 4205 cmd->scan_priority = params->scan_priority; 4206 4207 copy_scan_event_cntrl_flags(cmd, params); 4208 4209 cmd->dwell_time_active = params->dwell_time_active; 4210 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 4211 cmd->dwell_time_passive = params->dwell_time_passive; 4212 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 4213 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 4214 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 4215 cmd->scan_start_offset = params->scan_offset_time; 4216 cmd->min_rest_time = params->min_rest_time; 4217 cmd->max_rest_time = params->max_rest_time; 4218 cmd->repeat_probe_time = params->repeat_probe_time; 4219 cmd->probe_spacing_time = params->probe_spacing_time; 4220 cmd->idle_time = params->idle_time; 4221 cmd->max_scan_time = params->max_scan_time; 4222 cmd->probe_delay = params->probe_delay; 4223 cmd->burst_duration = params->burst_duration; 4224 cmd->num_chan = params->chan_list.num_chan; 4225 cmd->num_bssid = params->num_bssid; 4226 cmd->num_ssids = params->num_ssids; 4227 cmd->ie_len = params->extraie.len; 4228 cmd->n_probes = params->n_probes; 4229 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 4230 WMI_SCAN_MLD_PARAM_MLD_ID_SET(cmd->mld_parameter, params->mld_id); 4231 wmi_debug("MLD ID: %u", cmd->mld_parameter); 4232 4233 if (params->scan_random.randomize) 4234 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 4235 params->scan_random.mac_mask, 4236 &cmd->mac_addr, 4237 &cmd->mac_mask); 4238 4239 if (ie_allowlist->allow_list) 4240 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 4241 &cmd->num_vendor_oui, 4242 ie_allowlist); 4243 4244 buf_ptr += sizeof(*cmd); 4245 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4246 for (i = 0; i < params->chan_list.num_chan; ++i) { 4247 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 4248 params->chan_list.chan[i].freq); 4249 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 4250 params->chan_list.chan[i].flags); 4251 } 4252 4253 WMITLV_SET_HDR(buf_ptr, 4254 WMITLV_TAG_ARRAY_UINT32, 4255 (params->chan_list.num_chan * sizeof(uint32_t))); 4256 buf_ptr += WMI_TLV_HDR_SIZE + 4257 (params->chan_list.num_chan * sizeof(uint32_t)); 4258 4259 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 4260 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 4261 goto error; 4262 } 4263 4264 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4265 (params->num_ssids * sizeof(wmi_ssid))); 4266 4267 if (params->num_ssids) { 4268 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 4269 for (i = 0; i < params->num_ssids; ++i) { 4270 ssid->ssid_len = params->ssid[i].length; 4271 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 4272 params->ssid[i].length); 4273 ssid++; 4274 } 4275 } 4276 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 4277 4278 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4279 (params->num_bssid * sizeof(wmi_mac_addr))); 4280 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 4281 4282 if (params->num_bssid) { 4283 for (i = 0; i < params->num_bssid; ++i) { 4284 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4285 ¶ms->bssid_list[i].bytes[0], bssid); 4286 bssid++; 4287 } 4288 } 4289 4290 buf_ptr += WMI_TLV_HDR_SIZE + 4291 (params->num_bssid * sizeof(wmi_mac_addr)); 4292 4293 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 4294 if (params->extraie.len) 4295 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 4296 params); 4297 4298 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 4299 4300 /* probe req ie allowlisting */ 4301 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4302 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4303 4304 buf_ptr += WMI_TLV_HDR_SIZE; 4305 4306 if (cmd->num_vendor_oui) { 4307 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4308 ie_allowlist->voui); 4309 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4310 } 4311 4312 /* Add phy mode TLV if it's a wide band scan */ 4313 if (params->scan_f_wide_band) { 4314 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 4315 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4316 for (i = 0; i < params->chan_list.num_chan; ++i) 4317 buf_ptr[i] = 4318 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 4319 buf_ptr += phymode_roundup; 4320 } else { 4321 /* Add ZERO length phy mode TLV */ 4322 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 4323 buf_ptr += WMI_TLV_HDR_SIZE; 4324 } 4325 4326 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4327 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 4328 if (params->num_hint_s_ssid) { 4329 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4330 for (i = 0; i < params->num_hint_s_ssid; ++i) { 4331 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 4332 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 4333 s_ssid++; 4334 } 4335 } 4336 buf_ptr += WMI_TLV_HDR_SIZE + 4337 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 4338 4339 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4340 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 4341 if (params->num_hint_bssid) { 4342 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4343 for (i = 0; i < params->num_hint_bssid; ++i) { 4344 hint_bssid->freq_flags = 4345 params->hint_bssid[i].freq_flags; 4346 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 4347 &hint_bssid->bssid); 4348 hint_bssid++; 4349 } 4350 } 4351 4352 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 4353 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4354 len, WMI_START_SCAN_CMDID); 4355 if (ret) { 4356 wmi_err("Failed to start scan: %d", ret); 4357 wmi_buf_free(wmi_buf); 4358 } 4359 return ret; 4360 error: 4361 wmi_buf_free(wmi_buf); 4362 return QDF_STATUS_E_FAILURE; 4363 } 4364 4365 /** 4366 * send_scan_stop_cmd_tlv() - WMI scan start function 4367 * @wmi_handle: handle to WMI. 4368 * @param: pointer to hold scan cancel cmd parameter 4369 * 4370 * Return: QDF_STATUS_SUCCESS for success or error code 4371 */ 4372 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 4373 struct scan_cancel_param *param) 4374 { 4375 wmi_stop_scan_cmd_fixed_param *cmd; 4376 int ret; 4377 int len = sizeof(*cmd); 4378 wmi_buf_t wmi_buf; 4379 4380 /* Allocate the memory */ 4381 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4382 if (!wmi_buf) { 4383 ret = QDF_STATUS_E_NOMEM; 4384 goto error; 4385 } 4386 4387 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 4388 WMITLV_SET_HDR(&cmd->tlv_header, 4389 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 4390 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 4391 cmd->vdev_id = param->vdev_id; 4392 cmd->requestor = param->requester; 4393 cmd->scan_id = param->scan_id; 4394 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4395 wmi_handle, 4396 param->pdev_id); 4397 /* stop the scan with the corresponding scan_id */ 4398 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 4399 /* Cancelling all scans */ 4400 cmd->req_type = WMI_SCAN_STOP_ALL; 4401 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 4402 /* Cancelling VAP scans */ 4403 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 4404 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 4405 /* Cancelling specific scan */ 4406 cmd->req_type = WMI_SCAN_STOP_ONE; 4407 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 4408 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 4409 } else { 4410 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 4411 wmi_buf_free(wmi_buf); 4412 return QDF_STATUS_E_INVAL; 4413 } 4414 4415 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 4416 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4417 len, WMI_STOP_SCAN_CMDID); 4418 if (ret) { 4419 wmi_err("Failed to send stop scan: %d", ret); 4420 wmi_buf_free(wmi_buf); 4421 } 4422 4423 error: 4424 return ret; 4425 } 4426 4427 #define WMI_MAX_CHAN_INFO_LOG 192 4428 4429 /** 4430 * wmi_scan_chanlist_dump() - Dump scan channel list info 4431 * @scan_chan_list: scan channel list 4432 * 4433 * Return: void 4434 */ 4435 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 4436 { 4437 uint32_t i; 4438 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 4439 uint32_t len = 0; 4440 struct channel_param *chan; 4441 int ret; 4442 4443 wmi_debug("Total chan %d", scan_chan_list->nallchans); 4444 for (i = 0; i < scan_chan_list->nallchans; i++) { 4445 chan = &scan_chan_list->ch_param[i]; 4446 ret = qdf_scnprintf(info + len, sizeof(info) - len, 4447 " %d[%d][%d][%d]", chan->mhz, 4448 chan->maxregpower, 4449 chan->dfs_set, chan->nan_disabled); 4450 if (ret <= 0) 4451 break; 4452 len += ret; 4453 if (len >= (sizeof(info) - 20)) { 4454 wmi_nofl_debug("Chan[TXPwr][DFS][nan_disabled]:%s", 4455 info); 4456 len = 0; 4457 } 4458 } 4459 if (len) 4460 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 4461 } 4462 4463 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 4464 struct scan_chan_list_params *chan_list) 4465 { 4466 wmi_buf_t buf; 4467 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 4468 wmi_scan_chan_list_cmd_fixed_param *cmd; 4469 int i; 4470 uint8_t *buf_ptr; 4471 wmi_channel *chan_info; 4472 struct channel_param *tchan_info; 4473 uint16_t len; 4474 uint16_t num_send_chans, num_sends = 0; 4475 4476 wmi_scan_chanlist_dump(chan_list); 4477 tchan_info = &chan_list->ch_param[0]; 4478 while (chan_list->nallchans) { 4479 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 4480 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 4481 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 4482 else 4483 num_send_chans = chan_list->nallchans; 4484 4485 chan_list->nallchans -= num_send_chans; 4486 len += sizeof(wmi_channel) * num_send_chans; 4487 buf = wmi_buf_alloc(wmi_handle, len); 4488 if (!buf) { 4489 qdf_status = QDF_STATUS_E_NOMEM; 4490 goto end; 4491 } 4492 4493 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4494 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 4495 WMITLV_SET_HDR(&cmd->tlv_header, 4496 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 4497 WMITLV_GET_STRUCT_TLVLEN 4498 (wmi_scan_chan_list_cmd_fixed_param)); 4499 4500 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 4501 4502 if (num_sends) 4503 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 4504 4505 if (chan_list->max_bw_support_present) 4506 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 4507 4508 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4509 wmi_handle, 4510 chan_list->pdev_id); 4511 4512 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 4513 4514 cmd->num_scan_chans = num_send_chans; 4515 WMITLV_SET_HDR((buf_ptr + 4516 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 4517 WMITLV_TAG_ARRAY_STRUC, 4518 sizeof(wmi_channel) * num_send_chans); 4519 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 4520 WMI_TLV_HDR_SIZE); 4521 4522 for (i = 0; i < num_send_chans; ++i) { 4523 WMITLV_SET_HDR(&chan_info->tlv_header, 4524 WMITLV_TAG_STRUC_wmi_channel, 4525 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4526 chan_info->mhz = tchan_info->mhz; 4527 chan_info->band_center_freq1 = 4528 tchan_info->cfreq1; 4529 chan_info->band_center_freq2 = 4530 tchan_info->cfreq2; 4531 4532 if (tchan_info->is_chan_passive) 4533 WMI_SET_CHANNEL_FLAG(chan_info, 4534 WMI_CHAN_FLAG_PASSIVE); 4535 if (tchan_info->dfs_set) 4536 WMI_SET_CHANNEL_FLAG(chan_info, 4537 WMI_CHAN_FLAG_DFS); 4538 4539 if (tchan_info->dfs_set_cfreq2) 4540 WMI_SET_CHANNEL_FLAG(chan_info, 4541 WMI_CHAN_FLAG_DFS_CFREQ2); 4542 4543 if (tchan_info->allow_he) 4544 WMI_SET_CHANNEL_FLAG(chan_info, 4545 WMI_CHAN_FLAG_ALLOW_HE); 4546 4547 if (tchan_info->allow_eht) 4548 WMI_SET_CHANNEL_FLAG(chan_info, 4549 WMI_CHAN_FLAG_ALLOW_EHT); 4550 4551 if (tchan_info->allow_vht) 4552 WMI_SET_CHANNEL_FLAG(chan_info, 4553 WMI_CHAN_FLAG_ALLOW_VHT); 4554 4555 if (tchan_info->allow_ht) 4556 WMI_SET_CHANNEL_FLAG(chan_info, 4557 WMI_CHAN_FLAG_ALLOW_HT); 4558 WMI_SET_CHANNEL_MODE(chan_info, 4559 tchan_info->phy_mode); 4560 4561 if (tchan_info->half_rate) 4562 WMI_SET_CHANNEL_FLAG(chan_info, 4563 WMI_CHAN_FLAG_HALF_RATE); 4564 4565 if (tchan_info->quarter_rate) 4566 WMI_SET_CHANNEL_FLAG(chan_info, 4567 WMI_CHAN_FLAG_QUARTER_RATE); 4568 4569 if (tchan_info->psc_channel) 4570 WMI_SET_CHANNEL_FLAG(chan_info, 4571 WMI_CHAN_FLAG_PSC); 4572 4573 if (tchan_info->nan_disabled) 4574 WMI_SET_CHANNEL_FLAG(chan_info, 4575 WMI_CHAN_FLAG_NAN_DISABLED); 4576 4577 /* also fill in power information */ 4578 WMI_SET_CHANNEL_MIN_POWER(chan_info, 4579 tchan_info->minpower); 4580 WMI_SET_CHANNEL_MAX_POWER(chan_info, 4581 tchan_info->maxpower); 4582 WMI_SET_CHANNEL_REG_POWER(chan_info, 4583 tchan_info->maxregpower); 4584 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 4585 tchan_info->antennamax); 4586 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 4587 tchan_info->reg_class_id); 4588 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 4589 tchan_info->maxregpower); 4590 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 4591 tchan_info->max_bw_supported); 4592 4593 tchan_info++; 4594 chan_info++; 4595 } 4596 4597 qdf_status = wmi_unified_cmd_send( 4598 wmi_handle, 4599 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 4600 4601 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4602 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 4603 wmi_buf_free(buf); 4604 goto end; 4605 } 4606 num_sends++; 4607 } 4608 4609 end: 4610 return qdf_status; 4611 } 4612 4613 /** 4614 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 4615 * 4616 * @bufp: Pointer to buffer 4617 * @param: Pointer to tx param 4618 * 4619 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 4620 */ 4621 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 4622 struct tx_send_params param) 4623 { 4624 wmi_tx_send_params *tx_param; 4625 QDF_STATUS status = QDF_STATUS_SUCCESS; 4626 4627 if (!bufp) { 4628 status = QDF_STATUS_E_FAILURE; 4629 return status; 4630 } 4631 tx_param = (wmi_tx_send_params *)bufp; 4632 WMITLV_SET_HDR(&tx_param->tlv_header, 4633 WMITLV_TAG_STRUC_wmi_tx_send_params, 4634 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4635 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 4636 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 4637 param.mcs_mask); 4638 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 4639 param.nss_mask); 4640 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 4641 param.retry_limit); 4642 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 4643 param.chain_mask); 4644 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 4645 param.bw_mask); 4646 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 4647 param.preamble_type); 4648 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 4649 param.frame_type); 4650 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 4651 param.cfr_enable); 4652 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 4653 param.en_beamforming); 4654 WMI_TX_SEND_PARAM_RETRY_LIMIT_EXT_SET(tx_param->tx_param_dword1, 4655 param.retry_limit_ext); 4656 4657 return status; 4658 } 4659 4660 #ifdef CONFIG_HL_SUPPORT 4661 /** 4662 * send_mgmt_cmd_tlv() - WMI scan start function 4663 * @wmi_handle: handle to WMI. 4664 * @param: pointer to hold mgmt cmd parameter 4665 * 4666 * Return: QDF_STATUS_SUCCESS for success or error code 4667 */ 4668 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4669 struct wmi_mgmt_params *param) 4670 { 4671 wmi_buf_t buf; 4672 uint8_t *bufp; 4673 int32_t cmd_len; 4674 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4675 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4676 mgmt_tx_dl_frm_len; 4677 4678 if (param->frm_len > mgmt_tx_dl_frm_len) { 4679 wmi_err("mgmt frame len %u exceeds %u", 4680 param->frm_len, mgmt_tx_dl_frm_len); 4681 return QDF_STATUS_E_INVAL; 4682 } 4683 4684 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4685 WMI_TLV_HDR_SIZE + 4686 roundup(bufp_len, sizeof(uint32_t)); 4687 4688 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4689 if (!buf) 4690 return QDF_STATUS_E_NOMEM; 4691 4692 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4693 bufp = (uint8_t *) cmd; 4694 WMITLV_SET_HDR(&cmd->tlv_header, 4695 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4696 WMITLV_GET_STRUCT_TLVLEN 4697 (wmi_mgmt_tx_send_cmd_fixed_param)); 4698 4699 cmd->vdev_id = param->vdev_id; 4700 4701 cmd->desc_id = param->desc_id; 4702 cmd->chanfreq = param->chanfreq; 4703 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4704 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4705 sizeof(uint32_t))); 4706 bufp += WMI_TLV_HDR_SIZE; 4707 qdf_mem_copy(bufp, param->pdata, bufp_len); 4708 4709 cmd->frame_len = param->frm_len; 4710 cmd->buf_len = bufp_len; 4711 cmd->tx_params_valid = param->tx_params_valid; 4712 cmd->tx_flags = param->tx_flags; 4713 cmd->peer_rssi = param->peer_rssi; 4714 4715 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4716 bufp, cmd->vdev_id, cmd->chanfreq); 4717 4718 bufp += roundup(bufp_len, sizeof(uint32_t)); 4719 if (param->tx_params_valid) { 4720 if (populate_tx_send_params(bufp, param->tx_param) != 4721 QDF_STATUS_SUCCESS) { 4722 wmi_err("Populate TX send params failed"); 4723 goto free_buf; 4724 } 4725 cmd_len += sizeof(wmi_tx_send_params); 4726 } 4727 4728 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4729 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4730 WMI_MGMT_TX_SEND_CMDID)) { 4731 wmi_err("Failed to send mgmt Tx"); 4732 goto free_buf; 4733 } 4734 return QDF_STATUS_SUCCESS; 4735 4736 free_buf: 4737 wmi_buf_free(buf); 4738 return QDF_STATUS_E_FAILURE; 4739 } 4740 #else 4741 /** 4742 * send_mgmt_cmd_tlv() - WMI scan start function 4743 * @wmi_handle: handle to WMI. 4744 * @param: pointer to hold mgmt cmd parameter 4745 * 4746 * Return: QDF_STATUS_SUCCESS for success or error code 4747 */ 4748 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4749 struct wmi_mgmt_params *param) 4750 { 4751 wmi_buf_t buf; 4752 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4753 int32_t cmd_len; 4754 uint64_t dma_addr; 4755 void *qdf_ctx = param->qdf_ctx; 4756 uint8_t *bufp; 4757 QDF_STATUS status = QDF_STATUS_SUCCESS; 4758 wmi_mlo_tx_send_params *mlo_params; 4759 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4760 mgmt_tx_dl_frm_len; 4761 4762 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4763 WMI_TLV_HDR_SIZE + 4764 roundup(bufp_len, sizeof(uint32_t)); 4765 4766 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len + 4767 WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params)); 4768 if (!buf) 4769 return QDF_STATUS_E_NOMEM; 4770 4771 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4772 bufp = (uint8_t *) cmd; 4773 WMITLV_SET_HDR(&cmd->tlv_header, 4774 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4775 WMITLV_GET_STRUCT_TLVLEN 4776 (wmi_mgmt_tx_send_cmd_fixed_param)); 4777 4778 cmd->vdev_id = param->vdev_id; 4779 4780 cmd->desc_id = param->desc_id; 4781 cmd->chanfreq = param->chanfreq; 4782 cmd->peer_rssi = param->peer_rssi; 4783 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4784 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4785 sizeof(uint32_t))); 4786 bufp += WMI_TLV_HDR_SIZE; 4787 4788 /* for big endian host, copy engine byte_swap is enabled 4789 * But the frame content is in network byte order 4790 * Need to byte swap the frame content - so when copy engine 4791 * does byte_swap - target gets frame content in the correct order 4792 */ 4793 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 4794 4795 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 4796 QDF_DMA_TO_DEVICE); 4797 if (status != QDF_STATUS_SUCCESS) { 4798 wmi_err("wmi buf map failed"); 4799 goto free_buf; 4800 } 4801 4802 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4803 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4804 #if defined(HTT_PADDR64) 4805 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4806 #endif 4807 cmd->frame_len = param->frm_len; 4808 cmd->buf_len = bufp_len; 4809 cmd->tx_params_valid = param->tx_params_valid; 4810 cmd->tx_flags = param->tx_flags; 4811 4812 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4813 bufp, cmd->vdev_id, cmd->chanfreq); 4814 4815 bufp += roundup(bufp_len, sizeof(uint32_t)); 4816 if (param->tx_params_valid) { 4817 status = populate_tx_send_params(bufp, param->tx_param); 4818 if (status != QDF_STATUS_SUCCESS) { 4819 wmi_err("Populate TX send params failed"); 4820 goto unmap_tx_frame; 4821 } 4822 } else { 4823 WMITLV_SET_HDR(&((wmi_tx_send_params *)bufp)->tlv_header, 4824 WMITLV_TAG_STRUC_wmi_tx_send_params, 4825 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4826 } 4827 4828 /* Even tx_params_valid is false, still need reserve space to pass wmi 4829 * tag check */ 4830 cmd_len += sizeof(wmi_tx_send_params); 4831 bufp += sizeof(wmi_tx_send_params); 4832 /* wmi_mlo_tx_send_params */ 4833 if (param->mlo_link_agnostic) { 4834 wmi_debug("Set mlo mgmt tid"); 4835 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_STRUC, 4836 sizeof(wmi_mlo_tx_send_params)); 4837 bufp += WMI_TLV_HDR_SIZE; 4838 mlo_params = (wmi_mlo_tx_send_params *)bufp; 4839 WMITLV_SET_HDR(&mlo_params->tlv_header, 4840 WMITLV_TAG_STRUC_wmi_mlo_tx_send_params, 4841 WMITLV_GET_STRUCT_TLVLEN(wmi_mlo_tx_send_params)); 4842 mlo_params->hw_link_id = WMI_MLO_MGMT_TID; 4843 cmd_len += WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params); 4844 } 4845 4846 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4847 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4848 WMI_MGMT_TX_SEND_CMDID)) { 4849 wmi_err("Failed to send mgmt Tx"); 4850 goto unmap_tx_frame; 4851 } 4852 return QDF_STATUS_SUCCESS; 4853 4854 unmap_tx_frame: 4855 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 4856 QDF_DMA_TO_DEVICE); 4857 free_buf: 4858 wmi_buf_free(buf); 4859 return QDF_STATUS_E_FAILURE; 4860 } 4861 #endif /* CONFIG_HL_SUPPORT */ 4862 4863 /** 4864 * send_offchan_data_tx_cmd_tlv() - Send off-chan tx data 4865 * @wmi_handle: handle to WMI. 4866 * @param: pointer to offchan data tx cmd parameter 4867 * 4868 * Return: QDF_STATUS_SUCCESS on success and error on failure. 4869 */ 4870 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 4871 struct wmi_offchan_data_tx_params *param) 4872 { 4873 wmi_buf_t buf; 4874 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 4875 int32_t cmd_len; 4876 uint64_t dma_addr; 4877 void *qdf_ctx = param->qdf_ctx; 4878 uint8_t *bufp; 4879 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 4880 param->frm_len : mgmt_tx_dl_frm_len; 4881 QDF_STATUS status = QDF_STATUS_SUCCESS; 4882 4883 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 4884 WMI_TLV_HDR_SIZE + 4885 roundup(bufp_len, sizeof(uint32_t)); 4886 4887 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4888 if (!buf) 4889 return QDF_STATUS_E_NOMEM; 4890 4891 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 4892 bufp = (uint8_t *) cmd; 4893 WMITLV_SET_HDR(&cmd->tlv_header, 4894 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 4895 WMITLV_GET_STRUCT_TLVLEN 4896 (wmi_offchan_data_tx_send_cmd_fixed_param)); 4897 4898 cmd->vdev_id = param->vdev_id; 4899 4900 cmd->desc_id = param->desc_id; 4901 cmd->chanfreq = param->chanfreq; 4902 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 4903 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4904 sizeof(uint32_t))); 4905 bufp += WMI_TLV_HDR_SIZE; 4906 qdf_mem_copy(bufp, param->pdata, bufp_len); 4907 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 4908 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4909 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4910 #if defined(HTT_PADDR64) 4911 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4912 #endif 4913 cmd->frame_len = param->frm_len; 4914 cmd->buf_len = bufp_len; 4915 cmd->tx_params_valid = param->tx_params_valid; 4916 4917 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 4918 bufp, cmd->vdev_id, cmd->chanfreq); 4919 4920 bufp += roundup(bufp_len, sizeof(uint32_t)); 4921 if (param->tx_params_valid) { 4922 status = populate_tx_send_params(bufp, param->tx_param); 4923 if (status != QDF_STATUS_SUCCESS) { 4924 wmi_err("Populate TX send params failed"); 4925 goto err1; 4926 } 4927 cmd_len += sizeof(wmi_tx_send_params); 4928 } 4929 4930 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 4931 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4932 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 4933 wmi_err("Failed to offchan data Tx"); 4934 goto err1; 4935 } 4936 4937 return QDF_STATUS_SUCCESS; 4938 4939 err1: 4940 wmi_buf_free(buf); 4941 return QDF_STATUS_E_FAILURE; 4942 } 4943 4944 /** 4945 * send_modem_power_state_cmd_tlv() - set modem power state to fw 4946 * @wmi_handle: wmi handle 4947 * @param_value: parameter value 4948 * 4949 * Return: QDF_STATUS_SUCCESS for success or error code 4950 */ 4951 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 4952 uint32_t param_value) 4953 { 4954 QDF_STATUS ret; 4955 wmi_modem_power_state_cmd_param *cmd; 4956 wmi_buf_t buf; 4957 uint16_t len = sizeof(*cmd); 4958 4959 buf = wmi_buf_alloc(wmi_handle, len); 4960 if (!buf) 4961 return QDF_STATUS_E_NOMEM; 4962 4963 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 4964 WMITLV_SET_HDR(&cmd->tlv_header, 4965 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 4966 WMITLV_GET_STRUCT_TLVLEN 4967 (wmi_modem_power_state_cmd_param)); 4968 cmd->modem_power_state = param_value; 4969 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 4970 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 4971 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4972 WMI_MODEM_POWER_STATE_CMDID); 4973 if (QDF_IS_STATUS_ERROR(ret)) { 4974 wmi_err("Failed to send notify cmd ret = %d", ret); 4975 wmi_buf_free(buf); 4976 } 4977 4978 return ret; 4979 } 4980 4981 /** 4982 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 4983 * @wmi_handle: wmi handle 4984 * @vdev_id: vdev id 4985 * @val: value 4986 * 4987 * Return: QDF_STATUS_SUCCESS for success or error code. 4988 */ 4989 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 4990 uint32_t vdev_id, uint8_t val) 4991 { 4992 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 4993 wmi_buf_t buf; 4994 int32_t len = sizeof(*cmd); 4995 4996 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 4997 4998 buf = wmi_buf_alloc(wmi_handle, len); 4999 if (!buf) 5000 return QDF_STATUS_E_NOMEM; 5001 5002 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 5003 WMITLV_SET_HDR(&cmd->tlv_header, 5004 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 5005 WMITLV_GET_STRUCT_TLVLEN 5006 (wmi_sta_powersave_mode_cmd_fixed_param)); 5007 cmd->vdev_id = vdev_id; 5008 if (val) 5009 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 5010 else 5011 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 5012 5013 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 5014 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5015 WMI_STA_POWERSAVE_MODE_CMDID)) { 5016 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 5017 vdev_id, val); 5018 wmi_buf_free(buf); 5019 return QDF_STATUS_E_FAILURE; 5020 } 5021 return QDF_STATUS_SUCCESS; 5022 } 5023 5024 /** 5025 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 5026 * @wmi_handle: wmi handle 5027 * @val: non-zero to turn monitor on 5028 * 5029 * Return: QDF_STATUS_SUCCESS for success or error code. 5030 */ 5031 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 5032 uint8_t val) 5033 { 5034 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 5035 wmi_buf_t buf; 5036 size_t len = sizeof(*cmd); 5037 5038 buf = wmi_buf_alloc(wmi_handle, len); 5039 if (!buf) 5040 return QDF_STATUS_E_NOMEM; 5041 5042 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 5043 WMITLV_SET_HDR(&cmd->tlv_header, 5044 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 5045 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 5046 5047 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 5048 WMI_IDLE_TRIGGER_MONITOR_OFF); 5049 5050 wmi_debug("val: %d", cmd->idle_trigger_monitor); 5051 5052 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5053 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 5054 wmi_buf_free(buf); 5055 return QDF_STATUS_E_FAILURE; 5056 } 5057 return QDF_STATUS_SUCCESS; 5058 } 5059 5060 /** 5061 * send_set_mimops_cmd_tlv() - set MIMO powersave 5062 * @wmi_handle: wmi handle 5063 * @vdev_id: vdev id 5064 * @value: value 5065 * 5066 * Return: QDF_STATUS_SUCCESS for success or error code. 5067 */ 5068 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 5069 uint8_t vdev_id, int value) 5070 { 5071 QDF_STATUS ret; 5072 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 5073 wmi_buf_t buf; 5074 uint16_t len = sizeof(*cmd); 5075 5076 buf = wmi_buf_alloc(wmi_handle, len); 5077 if (!buf) 5078 return QDF_STATUS_E_NOMEM; 5079 5080 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 5081 WMITLV_SET_HDR(&cmd->tlv_header, 5082 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 5083 WMITLV_GET_STRUCT_TLVLEN 5084 (wmi_sta_smps_force_mode_cmd_fixed_param)); 5085 5086 cmd->vdev_id = vdev_id; 5087 5088 /* WMI_SMPS_FORCED_MODE values do not directly map 5089 * to SM power save values defined in the specification. 5090 * Make sure to send the right mapping. 5091 */ 5092 switch (value) { 5093 case 0: 5094 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 5095 break; 5096 case 1: 5097 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 5098 break; 5099 case 2: 5100 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 5101 break; 5102 case 3: 5103 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 5104 break; 5105 default: 5106 wmi_err("INVALID MIMO PS CONFIG: %d", value); 5107 wmi_buf_free(buf); 5108 return QDF_STATUS_E_FAILURE; 5109 } 5110 5111 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 5112 5113 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 5114 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5115 WMI_STA_SMPS_FORCE_MODE_CMDID); 5116 if (QDF_IS_STATUS_ERROR(ret)) { 5117 wmi_err("Failed to send set Mimo PS ret = %d", ret); 5118 wmi_buf_free(buf); 5119 } 5120 5121 return ret; 5122 } 5123 5124 /** 5125 * send_set_smps_params_cmd_tlv() - set smps params 5126 * @wmi_handle: wmi handle 5127 * @vdev_id: vdev id 5128 * @value: value 5129 * 5130 * Return: QDF_STATUS_SUCCESS for success or error code. 5131 */ 5132 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 5133 int value) 5134 { 5135 QDF_STATUS ret; 5136 wmi_sta_smps_param_cmd_fixed_param *cmd; 5137 wmi_buf_t buf; 5138 uint16_t len = sizeof(*cmd); 5139 5140 buf = wmi_buf_alloc(wmi_handle, len); 5141 if (!buf) 5142 return QDF_STATUS_E_NOMEM; 5143 5144 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 5145 WMITLV_SET_HDR(&cmd->tlv_header, 5146 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 5147 WMITLV_GET_STRUCT_TLVLEN 5148 (wmi_sta_smps_param_cmd_fixed_param)); 5149 5150 cmd->vdev_id = vdev_id; 5151 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 5152 cmd->param = 5153 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 5154 5155 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 5156 cmd->param); 5157 5158 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 5159 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5160 WMI_STA_SMPS_PARAM_CMDID); 5161 if (QDF_IS_STATUS_ERROR(ret)) { 5162 wmi_err("Failed to send set Mimo PS ret = %d", ret); 5163 wmi_buf_free(buf); 5164 } 5165 5166 return ret; 5167 } 5168 5169 /** 5170 * send_get_temperature_cmd_tlv() - get pdev temperature req 5171 * @wmi_handle: wmi handle 5172 * 5173 * Return: QDF_STATUS_SUCCESS for success or error code. 5174 */ 5175 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 5176 { 5177 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 5178 wmi_buf_t wmi_buf; 5179 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 5180 uint8_t *buf_ptr; 5181 5182 if (!wmi_handle) { 5183 wmi_err("WMI is closed, can not issue cmd"); 5184 return QDF_STATUS_E_INVAL; 5185 } 5186 5187 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5188 if (!wmi_buf) 5189 return QDF_STATUS_E_NOMEM; 5190 5191 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5192 5193 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 5194 WMITLV_SET_HDR(&cmd->tlv_header, 5195 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 5196 WMITLV_GET_STRUCT_TLVLEN 5197 (wmi_pdev_get_temperature_cmd_fixed_param)); 5198 5199 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 5200 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5201 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 5202 wmi_err("Failed to send get temperature command"); 5203 wmi_buf_free(wmi_buf); 5204 return QDF_STATUS_E_FAILURE; 5205 } 5206 5207 return QDF_STATUS_SUCCESS; 5208 } 5209 5210 /** 5211 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 5212 * @wmi_handle: wmi handle 5213 * @param: UAPSD trigger parameters 5214 * 5215 * This function sets the trigger 5216 * uapsd params such as service interval, delay interval 5217 * and suspend interval which will be used by the firmware 5218 * to send trigger frames periodically when there is no 5219 * traffic on the transmit side. 5220 * 5221 * Return: QDF_STATUS_SUCCESS for success or error code. 5222 */ 5223 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 5224 struct sta_uapsd_trig_params *param) 5225 { 5226 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 5227 QDF_STATUS ret; 5228 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 5229 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 5230 uint32_t i; 5231 wmi_buf_t buf; 5232 uint8_t *buf_ptr; 5233 struct sta_uapsd_params *uapsd_param; 5234 wmi_sta_uapsd_auto_trig_param *trig_param; 5235 5236 buf = wmi_buf_alloc(wmi_handle, cmd_len); 5237 if (!buf) 5238 return QDF_STATUS_E_NOMEM; 5239 5240 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5241 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 5242 WMITLV_SET_HDR(&cmd->tlv_header, 5243 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 5244 WMITLV_GET_STRUCT_TLVLEN 5245 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 5246 cmd->vdev_id = param->vdevid; 5247 cmd->num_ac = param->num_ac; 5248 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 5249 5250 /* TLV indicating array of structures to follow */ 5251 buf_ptr += sizeof(*cmd); 5252 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 5253 5254 buf_ptr += WMI_TLV_HDR_SIZE; 5255 5256 /* 5257 * Update tag and length for uapsd auto trigger params (this will take 5258 * care of updating tag and length if it is not pre-filled by caller). 5259 */ 5260 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 5261 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 5262 for (i = 0; i < param->num_ac; i++) { 5263 WMITLV_SET_HDR((buf_ptr + 5264 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 5265 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 5266 WMITLV_GET_STRUCT_TLVLEN 5267 (wmi_sta_uapsd_auto_trig_param)); 5268 trig_param->wmm_ac = uapsd_param->wmm_ac; 5269 trig_param->user_priority = uapsd_param->user_priority; 5270 trig_param->service_interval = uapsd_param->service_interval; 5271 trig_param->suspend_interval = uapsd_param->suspend_interval; 5272 trig_param->delay_interval = uapsd_param->delay_interval; 5273 trig_param++; 5274 uapsd_param++; 5275 } 5276 5277 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 5278 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 5279 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 5280 if (QDF_IS_STATUS_ERROR(ret)) { 5281 wmi_err("Failed to send set uapsd param ret = %d", ret); 5282 wmi_buf_free(buf); 5283 } 5284 5285 return ret; 5286 } 5287 5288 /** 5289 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 5290 * @wmi_handle: Pointer to wmi handle 5291 * @thermal_info: Thermal command information 5292 * 5293 * This function sends the thermal management command 5294 * to the firmware 5295 * 5296 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5297 */ 5298 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 5299 struct thermal_cmd_params *thermal_info) 5300 { 5301 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 5302 wmi_buf_t buf = NULL; 5303 QDF_STATUS status; 5304 uint32_t len = 0; 5305 uint8_t action; 5306 5307 switch (thermal_info->thermal_action) { 5308 case THERMAL_MGMT_ACTION_DEFAULT: 5309 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 5310 break; 5311 5312 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 5313 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 5314 break; 5315 5316 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 5317 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 5318 break; 5319 5320 case THERMAL_MGMT_ACTION_CHAINSCALING: 5321 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 5322 break; 5323 5324 default: 5325 wmi_err("Invalid thermal_action code %d", 5326 thermal_info->thermal_action); 5327 return QDF_STATUS_E_FAILURE; 5328 } 5329 5330 len = sizeof(*cmd); 5331 5332 buf = wmi_buf_alloc(wmi_handle, len); 5333 if (!buf) 5334 return QDF_STATUS_E_FAILURE; 5335 5336 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 5337 5338 WMITLV_SET_HDR(&cmd->tlv_header, 5339 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 5340 WMITLV_GET_STRUCT_TLVLEN 5341 (wmi_thermal_mgmt_cmd_fixed_param)); 5342 5343 cmd->lower_thresh_degreeC = thermal_info->min_temp; 5344 cmd->upper_thresh_degreeC = thermal_info->max_temp; 5345 cmd->enable = thermal_info->thermal_enable; 5346 cmd->action = action; 5347 5348 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 5349 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 5350 cmd->enable, cmd->action); 5351 5352 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 5353 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5354 WMI_THERMAL_MGMT_CMDID); 5355 if (QDF_IS_STATUS_ERROR(status)) { 5356 wmi_buf_free(buf); 5357 wmi_err("Failed to send thermal mgmt command"); 5358 } 5359 5360 return status; 5361 } 5362 5363 /** 5364 * send_lro_config_cmd_tlv() - process the LRO config command 5365 * @wmi_handle: Pointer to WMI handle 5366 * @wmi_lro_cmd: Pointer to LRO configuration parameters 5367 * 5368 * This function sends down the LRO configuration parameters to 5369 * the firmware to enable LRO, sets the TCP flags and sets the 5370 * seed values for the toeplitz hash generation 5371 * 5372 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5373 */ 5374 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 5375 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 5376 { 5377 wmi_lro_info_cmd_fixed_param *cmd; 5378 wmi_buf_t buf; 5379 QDF_STATUS status; 5380 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 5381 5382 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5383 if (!buf) 5384 return QDF_STATUS_E_FAILURE; 5385 5386 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 5387 5388 WMITLV_SET_HDR(&cmd->tlv_header, 5389 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 5390 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 5391 5392 cmd->lro_enable = wmi_lro_cmd->lro_enable; 5393 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 5394 wmi_lro_cmd->tcp_flag); 5395 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 5396 wmi_lro_cmd->tcp_flag_mask); 5397 cmd->toeplitz_hash_ipv4_0_3 = 5398 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 5399 cmd->toeplitz_hash_ipv4_4_7 = 5400 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 5401 cmd->toeplitz_hash_ipv4_8_11 = 5402 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 5403 cmd->toeplitz_hash_ipv4_12_15 = 5404 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 5405 cmd->toeplitz_hash_ipv4_16 = 5406 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 5407 5408 cmd->toeplitz_hash_ipv6_0_3 = 5409 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 5410 cmd->toeplitz_hash_ipv6_4_7 = 5411 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 5412 cmd->toeplitz_hash_ipv6_8_11 = 5413 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 5414 cmd->toeplitz_hash_ipv6_12_15 = 5415 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 5416 cmd->toeplitz_hash_ipv6_16_19 = 5417 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 5418 cmd->toeplitz_hash_ipv6_20_23 = 5419 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 5420 cmd->toeplitz_hash_ipv6_24_27 = 5421 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 5422 cmd->toeplitz_hash_ipv6_28_31 = 5423 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 5424 cmd->toeplitz_hash_ipv6_32_35 = 5425 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 5426 cmd->toeplitz_hash_ipv6_36_39 = 5427 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 5428 cmd->toeplitz_hash_ipv6_40 = 5429 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 5430 5431 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5432 wmi_handle, 5433 pdev_id); 5434 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 5435 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 5436 5437 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 5438 status = wmi_unified_cmd_send(wmi_handle, buf, 5439 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 5440 if (QDF_IS_STATUS_ERROR(status)) { 5441 wmi_buf_free(buf); 5442 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 5443 } 5444 5445 return status; 5446 } 5447 5448 /** 5449 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 5450 * @wmi_handle: Pointer to wmi handle 5451 * @rate_report_params: Pointer to peer rate report parameters 5452 * 5453 * 5454 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5455 */ 5456 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 5457 struct wmi_peer_rate_report_params *rate_report_params) 5458 { 5459 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 5460 wmi_buf_t buf = NULL; 5461 QDF_STATUS status = 0; 5462 uint32_t len = 0; 5463 uint32_t i, j; 5464 5465 len = sizeof(*cmd); 5466 5467 buf = wmi_buf_alloc(wmi_handle, len); 5468 if (!buf) 5469 return QDF_STATUS_E_FAILURE; 5470 5471 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 5472 wmi_buf_data(buf); 5473 5474 WMITLV_SET_HDR( 5475 &cmd->tlv_header, 5476 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 5477 WMITLV_GET_STRUCT_TLVLEN( 5478 wmi_peer_set_rate_report_condition_fixed_param)); 5479 5480 cmd->enable_rate_report = rate_report_params->rate_report_enable; 5481 cmd->report_backoff_time = rate_report_params->backoff_time; 5482 cmd->report_timer_period = rate_report_params->timer_period; 5483 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 5484 cmd->cond_per_phy[i].val_cond_flags = 5485 rate_report_params->report_per_phy[i].cond_flags; 5486 cmd->cond_per_phy[i].rate_delta.min_delta = 5487 rate_report_params->report_per_phy[i].delta.delta_min; 5488 cmd->cond_per_phy[i].rate_delta.percentage = 5489 rate_report_params->report_per_phy[i].delta.percent; 5490 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 5491 cmd->cond_per_phy[i].rate_threshold[j] = 5492 rate_report_params->report_per_phy[i]. 5493 report_rate_threshold[j]; 5494 } 5495 } 5496 5497 wmi_debug("enable %d backoff_time %d period %d", 5498 cmd->enable_rate_report, 5499 cmd->report_backoff_time, cmd->report_timer_period); 5500 5501 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 5502 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5503 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 5504 if (QDF_IS_STATUS_ERROR(status)) { 5505 wmi_buf_free(buf); 5506 wmi_err("Failed to send peer_set_report_cond command"); 5507 } 5508 return status; 5509 } 5510 5511 /** 5512 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5513 * @wmi_handle: wmi handle 5514 * @vdev_id: vdev id. 5515 * @mu_edca_param: true if these are MU EDCA params 5516 * @wmm_vparams: edca parameters 5517 * 5518 * This function updates EDCA parameters to the target 5519 * 5520 * Return: CDF Status 5521 */ 5522 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5523 uint8_t vdev_id, bool mu_edca_param, 5524 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5525 { 5526 uint8_t *buf_ptr; 5527 wmi_buf_t buf; 5528 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5529 wmi_wmm_vparams *wmm_param; 5530 struct wmi_host_wme_vparams *twmm_param; 5531 int len = sizeof(*cmd); 5532 int ac; 5533 5534 buf = wmi_buf_alloc(wmi_handle, len); 5535 5536 if (!buf) 5537 return QDF_STATUS_E_NOMEM; 5538 5539 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5540 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5541 WMITLV_SET_HDR(&cmd->tlv_header, 5542 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5543 WMITLV_GET_STRUCT_TLVLEN 5544 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5545 cmd->vdev_id = vdev_id; 5546 cmd->wmm_param_type = mu_edca_param; 5547 5548 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5549 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5550 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5551 WMITLV_SET_HDR(&wmm_param->tlv_header, 5552 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5553 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5554 wmm_param->cwmin = twmm_param->cwmin; 5555 wmm_param->cwmax = twmm_param->cwmax; 5556 wmm_param->aifs = twmm_param->aifs; 5557 if (mu_edca_param) 5558 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5559 else 5560 wmm_param->txoplimit = twmm_param->txoplimit; 5561 wmm_param->acm = twmm_param->acm; 5562 wmm_param->no_ack = twmm_param->noackpolicy; 5563 } 5564 5565 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 5566 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5567 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5568 goto fail; 5569 5570 return QDF_STATUS_SUCCESS; 5571 5572 fail: 5573 wmi_buf_free(buf); 5574 wmi_err("Failed to set WMM Parameters"); 5575 return QDF_STATUS_E_FAILURE; 5576 } 5577 5578 static WMI_EDCA_PARAM_TYPE 5579 wmi_convert_edca_pifs_param_type(enum host_edca_param_type type) 5580 { 5581 switch (type) { 5582 case HOST_EDCA_PARAM_TYPE_AGGRESSIVE: 5583 return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; 5584 case HOST_EDCA_PARAM_TYPE_PIFS: 5585 return WMI_EDCA_PARAM_TYPE_PIFS; 5586 default: 5587 return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; 5588 } 5589 } 5590 5591 /** 5592 * send_update_edca_pifs_param_cmd_tlv() - update EDCA params 5593 * @wmi_handle: wmi handle 5594 * @edca_pifs: edca/pifs parameters 5595 * 5596 * This function updates EDCA/PIFS parameters to the target 5597 * 5598 * Return: QDF Status 5599 */ 5600 5601 static QDF_STATUS 5602 send_update_edca_pifs_param_cmd_tlv(wmi_unified_t wmi_handle, 5603 struct edca_pifs_vparam *edca_pifs) 5604 { 5605 uint8_t *buf_ptr; 5606 wmi_buf_t buf = NULL; 5607 wmi_vdev_set_twt_edca_params_cmd_fixed_param *cmd; 5608 wmi_wmm_params *wmm_params; 5609 wmi_pifs_params *pifs_params; 5610 uint16_t len; 5611 5612 if (!edca_pifs) { 5613 wmi_debug("edca_pifs is NULL"); 5614 return QDF_STATUS_E_FAILURE; 5615 } 5616 5617 len = sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); 5618 if (edca_pifs->param.edca_param_type == 5619 HOST_EDCA_PARAM_TYPE_AGGRESSIVE) { 5620 len += WMI_TLV_HDR_SIZE; 5621 len += sizeof(wmi_wmm_params); 5622 } else { 5623 len += WMI_TLV_HDR_SIZE; 5624 } 5625 if (edca_pifs->param.edca_param_type == 5626 HOST_EDCA_PARAM_TYPE_PIFS) { 5627 len += WMI_TLV_HDR_SIZE; 5628 len += sizeof(wmi_pifs_params); 5629 } else { 5630 len += WMI_TLV_HDR_SIZE; 5631 } 5632 5633 buf = wmi_buf_alloc(wmi_handle, len); 5634 5635 if (!buf) 5636 return QDF_STATUS_E_NOMEM; 5637 5638 cmd = (wmi_vdev_set_twt_edca_params_cmd_fixed_param *)wmi_buf_data(buf); 5639 buf_ptr = (uint8_t *)cmd; 5640 5641 WMITLV_SET_HDR(&cmd->tlv_header, 5642 WMITLV_TAG_STRUC_wmi_vdev_set_twt_edca_params_cmd_fixed_param, 5643 WMITLV_GET_STRUCT_TLVLEN 5644 (wmi_vdev_set_twt_edca_params_cmd_fixed_param)); 5645 5646 cmd->vdev_id = edca_pifs->vdev_id; 5647 cmd->type = wmi_convert_edca_pifs_param_type( 5648 edca_pifs->param.edca_param_type); 5649 buf_ptr += sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); 5650 5651 if (cmd->type == WMI_EDCA_PARAM_TYPE_AGGRESSIVE) { 5652 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5653 sizeof(*wmm_params)); 5654 buf_ptr += WMI_TLV_HDR_SIZE; 5655 wmm_params = (wmi_wmm_params *)buf_ptr; 5656 WMITLV_SET_HDR(&wmm_params->tlv_header, 5657 WMITLV_TAG_STRUC_wmi_wmm_params, 5658 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 5659 5660 wmm_params->cwmin = 5661 BIT(edca_pifs->param.edca_pifs_param.eparam.acvo_cwmin) - 1; 5662 wmm_params->cwmax = 5663 BIT(edca_pifs->param.edca_pifs_param.eparam.acvo_cwmax) - 1; 5664 wmm_params->aifs = 5665 edca_pifs->param.edca_pifs_param.eparam.acvo_aifsn - 1; 5666 wmm_params->txoplimit = 5667 edca_pifs->param.edca_pifs_param.eparam.acvo_txoplimit; 5668 wmm_params->acm = 5669 edca_pifs->param.edca_pifs_param.eparam.acvo_acm; 5670 wmm_params->no_ack = 0; 5671 wmi_debug("vdev_id %d type %d cwmin %d cwmax %d aifsn %d txoplimit %d acm %d no_ack %d", 5672 cmd->vdev_id, cmd->type, wmm_params->cwmin, 5673 wmm_params->cwmax, wmm_params->aifs, 5674 wmm_params->txoplimit, wmm_params->acm, 5675 wmm_params->no_ack); 5676 buf_ptr += sizeof(*wmm_params); 5677 } else { 5678 /* set zero TLV's for wmm_params */ 5679 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5680 WMITLV_GET_STRUCT_TLVLEN(0)); 5681 buf_ptr += WMI_TLV_HDR_SIZE; 5682 } 5683 if (cmd->type == WMI_EDCA_PARAM_TYPE_PIFS) { 5684 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5685 sizeof(*pifs_params)); 5686 buf_ptr += WMI_TLV_HDR_SIZE; 5687 pifs_params = (wmi_pifs_params *)buf_ptr; 5688 WMITLV_SET_HDR(&pifs_params->tlv_header, 5689 WMITLV_TAG_STRUC_wmi_pifs_params, 5690 WMITLV_GET_STRUCT_TLVLEN(wmi_pifs_params)); 5691 5692 pifs_params->sap_pifs_offset = 5693 edca_pifs->param.edca_pifs_param.pparam.sap_pifs_offset; 5694 pifs_params->leb_pifs_offset = 5695 edca_pifs->param.edca_pifs_param.pparam.leb_pifs_offset; 5696 pifs_params->reb_pifs_offset = 5697 edca_pifs->param.edca_pifs_param.pparam.reb_pifs_offset; 5698 wmi_debug("vdev_id %d type %d sap_offset %d leb_offset %d reb_offset %d", 5699 cmd->vdev_id, cmd->type, pifs_params->sap_pifs_offset, 5700 pifs_params->leb_pifs_offset, 5701 pifs_params->reb_pifs_offset); 5702 } else { 5703 /* set zero TLV's for pifs_params */ 5704 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5705 WMITLV_GET_STRUCT_TLVLEN(0)); 5706 buf_ptr += WMI_TLV_HDR_SIZE; 5707 } 5708 5709 wmi_mtrace(WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID, cmd->vdev_id, 0); 5710 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5711 WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID)) 5712 goto fail; 5713 5714 return QDF_STATUS_SUCCESS; 5715 5716 fail: 5717 wmi_buf_free(buf); 5718 wmi_err("Failed to set EDCA/PIFS Parameters"); 5719 return QDF_STATUS_E_FAILURE; 5720 } 5721 5722 /** 5723 * extract_csa_ie_received_ev_params_tlv() - extract csa IE received event 5724 * @wmi_handle: wmi handle 5725 * @evt_buf: pointer to event buffer 5726 * @vdev_id: VDEV ID 5727 * @csa_event: csa event data 5728 * 5729 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 5730 */ 5731 static QDF_STATUS 5732 extract_csa_ie_received_ev_params_tlv(wmi_unified_t wmi_handle, 5733 void *evt_buf, uint8_t *vdev_id, 5734 struct csa_offload_params *csa_event) 5735 { 5736 WMI_CSA_IE_RECEIVED_EVENTID_param_tlvs *param_buf; 5737 wmi_csa_event_fixed_param *csa_ev; 5738 struct xcsa_ie *xcsa_ie; 5739 struct csa_ie *csa_ie; 5740 uint8_t *bssid; 5741 bool ret; 5742 5743 param_buf = (WMI_CSA_IE_RECEIVED_EVENTID_param_tlvs *)evt_buf; 5744 if (!param_buf) { 5745 wmi_err("Invalid csa event buffer"); 5746 return QDF_STATUS_E_FAILURE; 5747 } 5748 csa_ev = param_buf->fixed_param; 5749 WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_ev->i_addr2, 5750 &csa_event->bssid.bytes[0]); 5751 5752 bssid = csa_event->bssid.bytes; 5753 ret = wlan_get_connected_vdev_from_psoc_by_bssid(wmi_handle->soc->wmi_psoc, 5754 bssid, vdev_id); 5755 if (!ret) { 5756 wmi_err("VDEV is not connected with BSSID"); 5757 return QDF_STATUS_E_FAILURE; 5758 } 5759 5760 if (csa_ev->ies_present_flag & WMI_CSA_IE_PRESENT) { 5761 csa_ie = (struct csa_ie *)(&csa_ev->csa_ie[0]); 5762 csa_event->channel = csa_ie->new_channel; 5763 csa_event->switch_mode = csa_ie->switch_mode; 5764 csa_event->ies_present_flag |= MLME_CSA_IE_PRESENT; 5765 } else if (csa_ev->ies_present_flag & WMI_XCSA_IE_PRESENT) { 5766 xcsa_ie = (struct xcsa_ie *)(&csa_ev->xcsa_ie[0]); 5767 csa_event->channel = xcsa_ie->new_channel; 5768 csa_event->switch_mode = xcsa_ie->switch_mode; 5769 csa_event->new_op_class = xcsa_ie->new_class; 5770 csa_event->ies_present_flag |= MLME_XCSA_IE_PRESENT; 5771 } else { 5772 wmi_err("CSA Event error: No CSA IE present"); 5773 return QDF_STATUS_E_INVAL; 5774 } 5775 5776 wmi_debug("CSA IE Received: BSSID " QDF_MAC_ADDR_FMT " chan %d freq %d flag 0x%x width = %d freq1 = %d freq2 = %d op class = %d", 5777 QDF_MAC_ADDR_REF(csa_event->bssid.bytes), 5778 csa_event->channel, 5779 csa_event->csa_chan_freq, 5780 csa_event->ies_present_flag, 5781 csa_event->new_ch_width, 5782 csa_event->new_ch_freq_seg1, 5783 csa_event->new_ch_freq_seg2, 5784 csa_event->new_op_class); 5785 5786 if (!csa_event->channel) { 5787 wmi_err("CSA Event with channel %d. Ignore !!", 5788 csa_event->channel); 5789 return QDF_STATUS_E_FAILURE; 5790 } 5791 5792 return QDF_STATUS_SUCCESS; 5793 } 5794 5795 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 5796 static void 5797 populate_per_band_aoa_caps(struct wlan_psoc_host_rcc_enh_aoa_caps_ext2 *aoa_cap, 5798 wmi_enhanced_aoa_per_band_caps_param per_band_cap) 5799 { 5800 uint8_t tbl_idx; 5801 uint16_t *gain_array = NULL; 5802 5803 if (per_band_cap.band_info == WMI_AOA_2G) 5804 gain_array = aoa_cap->max_agc_gain_per_tbl_2g; 5805 else if (per_band_cap.band_info == WMI_AOA_5G) 5806 gain_array = aoa_cap->max_agc_gain_per_tbl_5g; 5807 else if (per_band_cap.band_info == WMI_AOA_6G) 5808 gain_array = aoa_cap->max_agc_gain_per_tbl_6g; 5809 5810 if (!gain_array) { 5811 wmi_debug("unhandled AOA BAND TYPE!! fix it"); 5812 return; 5813 } 5814 5815 for (tbl_idx = 0; tbl_idx < aoa_cap->max_agc_gain_tbls; tbl_idx++) 5816 WMI_AOA_MAX_AGC_GAIN_GET(per_band_cap.max_agc_gain, 5817 tbl_idx, 5818 gain_array[tbl_idx]); 5819 } 5820 5821 static void 5822 populate_aoa_caps(struct wmi_unified *wmi_handle, 5823 struct wlan_psoc_host_rcc_enh_aoa_caps_ext2 *aoa_cap, 5824 wmi_enhanced_aoa_caps_param *aoa_caps_param) 5825 { 5826 uint8_t tbl_idx; 5827 5828 aoa_cap->max_agc_gain_tbls = aoa_caps_param->max_agc_gain_tbls; 5829 if (aoa_cap->max_agc_gain_tbls > PSOC_MAX_NUM_AGC_GAIN_TBLS) { 5830 wmi_err("Num gain table > PSOC_MAX_NUM_AGC_GAIN_TBLS cap"); 5831 aoa_cap->max_agc_gain_tbls = PSOC_MAX_NUM_AGC_GAIN_TBLS; 5832 } 5833 5834 if (aoa_cap->max_agc_gain_tbls > WMI_AGC_MAX_GAIN_TABLE_IDX) { 5835 wmi_err("num gain table > WMI_AGC_MAX_GAIN_TABLE_IDX cap"); 5836 aoa_cap->max_agc_gain_tbls = WMI_AGC_MAX_GAIN_TABLE_IDX; 5837 } 5838 5839 for (tbl_idx = 0; tbl_idx < aoa_cap->max_agc_gain_tbls; tbl_idx++) { 5840 WMI_AOA_MAX_BDF_ENTRIES_GET 5841 (aoa_caps_param->max_bdf_gain_entries, 5842 tbl_idx, aoa_cap->max_bdf_entries_per_tbl[tbl_idx]); 5843 } 5844 } 5845 5846 /** 5847 * extract_aoa_caps_tlv() - extract aoa cap tlv 5848 * @wmi_handle: wmi handle 5849 * @event: pointer to event buffer 5850 * @aoa_cap: pointer to structure where capability needs to extracted 5851 * 5852 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 5853 */ 5854 static QDF_STATUS 5855 extract_aoa_caps_tlv(struct wmi_unified *wmi_handle, uint8_t *event, 5856 struct wlan_psoc_host_rcc_enh_aoa_caps_ext2 *aoa_cap) 5857 { 5858 int8_t band; 5859 5860 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 5861 5862 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 5863 if (!param_buf) { 5864 wmi_err("NULL param buf"); 5865 return QDF_STATUS_E_INVAL; 5866 } 5867 5868 if (!param_buf->aoa_caps_param) { 5869 wmi_debug("NULL aoa_caps_param"); 5870 return QDF_STATUS_E_INVAL; 5871 } 5872 5873 if (!param_buf->num_aoa_per_band_caps_param || 5874 !param_buf->aoa_per_band_caps_param) { 5875 wmi_debug("No aoa_per_band_caps_param"); 5876 return QDF_STATUS_E_INVAL; 5877 } 5878 populate_aoa_caps(wmi_handle, aoa_cap, param_buf->aoa_caps_param); 5879 5880 for (band = 0; band < param_buf->num_aoa_per_band_caps_param; band++) 5881 populate_per_band_aoa_caps 5882 (aoa_cap, param_buf->aoa_per_band_caps_param[band]); 5883 5884 return QDF_STATUS_SUCCESS; 5885 } 5886 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 5887 5888 /** 5889 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5890 * @wmi_handle: wmi handle 5891 * @vdev_id: vdev id 5892 * @probe_rsp_info: probe response info 5893 * 5894 * Return: QDF_STATUS_SUCCESS for success or error code 5895 */ 5896 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5897 uint8_t vdev_id, 5898 struct wmi_probe_resp_params *probe_rsp_info) 5899 { 5900 wmi_prb_tmpl_cmd_fixed_param *cmd; 5901 wmi_bcn_prb_info *bcn_prb_info; 5902 wmi_buf_t wmi_buf; 5903 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5904 uint8_t *buf_ptr; 5905 QDF_STATUS ret; 5906 5907 wmi_debug("Send probe response template for vdev %d", vdev_id); 5908 5909 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5910 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5911 5912 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5913 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5914 tmpl_len_aligned + 5915 prb_resp_tmpl_ml_info_size(probe_rsp_info); 5916 5917 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5918 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 5919 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5920 return QDF_STATUS_E_INVAL; 5921 } 5922 5923 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5924 if (!wmi_buf) 5925 return QDF_STATUS_E_NOMEM; 5926 5927 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5928 5929 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5930 WMITLV_SET_HDR(&cmd->tlv_header, 5931 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5932 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5933 cmd->vdev_id = vdev_id; 5934 cmd->buf_len = tmpl_len; 5935 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5936 5937 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5938 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5939 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5940 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5941 bcn_prb_info->caps = 0; 5942 bcn_prb_info->erp = 0; 5943 buf_ptr += sizeof(wmi_bcn_prb_info); 5944 5945 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5946 buf_ptr += WMI_TLV_HDR_SIZE; 5947 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5948 buf_ptr += tmpl_len_aligned; 5949 buf_ptr = prb_resp_tmpl_add_ml_info(buf_ptr, probe_rsp_info); 5950 5951 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 5952 ret = wmi_unified_cmd_send(wmi_handle, 5953 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5954 if (QDF_IS_STATUS_ERROR(ret)) { 5955 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 5956 wmi_buf_free(wmi_buf); 5957 } 5958 5959 return ret; 5960 } 5961 5962 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5963 #define WPI_IV_LEN 16 5964 5965 /** 5966 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5967 * 5968 * @dest_tx: destination address of tsc key counter 5969 * @src_tx: source address of tsc key counter 5970 * @dest_rx: destination address of rsc key counter 5971 * @src_rx: source address of rsc key counter 5972 * 5973 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5974 * 5975 * Return: None 5976 * 5977 */ 5978 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5979 uint8_t *dest_rx, uint8_t *src_rx) 5980 { 5981 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5982 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5983 } 5984 #else 5985 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5986 uint8_t *dest_rx, uint8_t *src_rx) 5987 { 5988 return; 5989 } 5990 #endif 5991 5992 /** 5993 * send_setup_install_key_cmd_tlv() - set key parameters 5994 * @wmi_handle: wmi handle 5995 * @key_params: key parameters 5996 * 5997 * This function fills structure from information 5998 * passed in key_params. 5999 * 6000 * Return: QDF_STATUS_SUCCESS - success 6001 * QDF_STATUS_E_FAILURE - failure 6002 * QDF_STATUS_E_NOMEM - not able to allocate buffer 6003 */ 6004 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 6005 struct set_key_params *key_params) 6006 { 6007 wmi_vdev_install_key_cmd_fixed_param *cmd; 6008 wmi_buf_t buf; 6009 uint8_t *buf_ptr; 6010 uint32_t len; 6011 uint8_t *key_data; 6012 QDF_STATUS status; 6013 6014 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 6015 WMI_TLV_HDR_SIZE; 6016 6017 buf = wmi_buf_alloc(wmi_handle, len); 6018 if (!buf) 6019 return QDF_STATUS_E_NOMEM; 6020 6021 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6022 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 6023 WMITLV_SET_HDR(&cmd->tlv_header, 6024 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 6025 WMITLV_GET_STRUCT_TLVLEN 6026 (wmi_vdev_install_key_cmd_fixed_param)); 6027 cmd->vdev_id = key_params->vdev_id; 6028 cmd->key_ix = key_params->key_idx; 6029 if (key_params->group_key_idx) { 6030 cmd->is_group_key_ix_valid = 1; 6031 cmd->group_key_ix = key_params->group_key_idx; 6032 } 6033 6034 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 6035 cmd->key_flags |= key_params->key_flags; 6036 cmd->key_cipher = key_params->key_cipher; 6037 if ((key_params->key_txmic_len) && 6038 (key_params->key_rxmic_len)) { 6039 cmd->key_txmic_len = key_params->key_txmic_len; 6040 cmd->key_rxmic_len = key_params->key_rxmic_len; 6041 } 6042 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 6043 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 6044 key_params->tx_iv, 6045 cmd->wpi_key_rsc_counter, 6046 key_params->rx_iv); 6047 #endif 6048 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 6049 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6050 roundup(key_params->key_len, sizeof(uint32_t))); 6051 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 6052 6053 /* for big endian host, copy engine byte_swap is enabled 6054 * But key_data is in network byte order 6055 * Need to byte swap the key_data - so when copy engine 6056 * does byte_swap - target gets key_data in the correct order 6057 */ 6058 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 6059 (const void *)key_params->key_data, 6060 key_params->key_len); 6061 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_counter, 6062 sizeof(wmi_key_seq_counter)); 6063 cmd->key_len = key_params->key_len; 6064 6065 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 6066 sizeof(wmi_key_seq_counter)); 6067 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 6068 status = wmi_unified_cmd_send(wmi_handle, buf, len, 6069 WMI_VDEV_INSTALL_KEY_CMDID); 6070 if (QDF_IS_STATUS_ERROR(status)) { 6071 qdf_mem_zero(wmi_buf_data(buf), len); 6072 wmi_buf_free(buf); 6073 } 6074 return status; 6075 } 6076 6077 /** 6078 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 6079 * @wmi_handle: wmi handle 6080 * @vdev_id: vdev id 6081 * @p2p_ie: p2p IE 6082 * 6083 * Return: QDF_STATUS_SUCCESS for success or error code 6084 */ 6085 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 6086 uint32_t vdev_id, uint8_t *p2p_ie) 6087 { 6088 QDF_STATUS ret; 6089 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 6090 wmi_buf_t wmi_buf; 6091 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 6092 uint8_t *buf_ptr; 6093 6094 ie_len = (uint32_t) (p2p_ie[1] + 2); 6095 6096 /* More than one P2P IE may be included in a single frame. 6097 If multiple P2P IEs are present, the complete P2P attribute 6098 data consists of the concatenation of the P2P Attribute 6099 fields of the P2P IEs. The P2P Attributes field of each 6100 P2P IE may be any length up to the maximum (251 octets). 6101 In this case host sends one P2P IE to firmware so the length 6102 should not exceed more than 251 bytes 6103 */ 6104 if (ie_len > 251) { 6105 wmi_err("Invalid p2p ie length %u", ie_len); 6106 return QDF_STATUS_E_INVAL; 6107 } 6108 6109 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 6110 6111 wmi_buf_len = 6112 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 6113 WMI_TLV_HDR_SIZE; 6114 6115 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 6116 if (!wmi_buf) 6117 return QDF_STATUS_E_NOMEM; 6118 6119 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6120 6121 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 6122 WMITLV_SET_HDR(&cmd->tlv_header, 6123 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 6124 WMITLV_GET_STRUCT_TLVLEN 6125 (wmi_p2p_go_set_beacon_ie_fixed_param)); 6126 cmd->vdev_id = vdev_id; 6127 cmd->ie_buf_len = ie_len; 6128 6129 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 6130 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 6131 buf_ptr += WMI_TLV_HDR_SIZE; 6132 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 6133 6134 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 6135 6136 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 6137 ret = wmi_unified_cmd_send(wmi_handle, 6138 wmi_buf, wmi_buf_len, 6139 WMI_P2P_GO_SET_BEACON_IE); 6140 if (QDF_IS_STATUS_ERROR(ret)) { 6141 wmi_err("Failed to send bcn tmpl: %d", ret); 6142 wmi_buf_free(wmi_buf); 6143 } 6144 6145 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 6146 return ret; 6147 } 6148 6149 /** 6150 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 6151 * @wmi_handle: wmi handle 6152 * @psetoui: OUI parameters 6153 * 6154 * set scan probe OUI parameters in firmware 6155 * 6156 * Return: QDF status 6157 */ 6158 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 6159 struct scan_mac_oui *psetoui) 6160 { 6161 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 6162 wmi_buf_t wmi_buf; 6163 uint32_t len; 6164 uint8_t *buf_ptr; 6165 uint32_t *oui_buf; 6166 struct probe_req_allowlist_attr *ie_allowlist = &psetoui->ie_allowlist; 6167 6168 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 6169 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 6170 6171 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6172 if (!wmi_buf) 6173 return QDF_STATUS_E_NOMEM; 6174 6175 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6176 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 6177 WMITLV_SET_HDR(&cmd->tlv_header, 6178 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 6179 WMITLV_GET_STRUCT_TLVLEN 6180 (wmi_scan_prob_req_oui_cmd_fixed_param)); 6181 6182 oui_buf = &cmd->prob_req_oui; 6183 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 6184 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 6185 | psetoui->oui[2]; 6186 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 6187 6188 cmd->vdev_id = psetoui->vdev_id; 6189 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 6190 if (psetoui->enb_probe_req_sno_randomization) 6191 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 6192 6193 if (ie_allowlist->allow_list) { 6194 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6195 &cmd->num_vendor_oui, 6196 ie_allowlist); 6197 cmd->flags |= 6198 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6199 } 6200 6201 buf_ptr += sizeof(*cmd); 6202 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6203 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6204 buf_ptr += WMI_TLV_HDR_SIZE; 6205 6206 if (cmd->num_vendor_oui != 0) { 6207 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6208 ie_allowlist->voui); 6209 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6210 } 6211 6212 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 6213 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6214 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 6215 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 6216 wmi_buf_free(wmi_buf); 6217 return QDF_STATUS_E_FAILURE; 6218 } 6219 return QDF_STATUS_SUCCESS; 6220 } 6221 6222 #ifdef IPA_OFFLOAD 6223 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 6224 * @wmi_handle: wmi handle 6225 * @ipa_offload: ipa offload control parameter 6226 * 6227 * Returns: 0 on success, error number otherwise 6228 */ 6229 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 6230 struct ipa_uc_offload_control_params *ipa_offload) 6231 { 6232 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 6233 wmi_buf_t wmi_buf; 6234 uint32_t len; 6235 u_int8_t *buf_ptr; 6236 6237 len = sizeof(*cmd); 6238 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6239 if (!wmi_buf) 6240 return QDF_STATUS_E_NOMEM; 6241 6242 wmi_debug("offload_type=%d, enable=%d", 6243 ipa_offload->offload_type, ipa_offload->enable); 6244 6245 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 6246 6247 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 6248 WMITLV_SET_HDR(&cmd->tlv_header, 6249 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 6250 WMITLV_GET_STRUCT_TLVLEN( 6251 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 6252 6253 cmd->offload_type = ipa_offload->offload_type; 6254 cmd->vdev_id = ipa_offload->vdev_id; 6255 cmd->enable = ipa_offload->enable; 6256 6257 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 6258 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6259 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 6260 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 6261 wmi_buf_free(wmi_buf); 6262 return QDF_STATUS_E_FAILURE; 6263 } 6264 6265 return QDF_STATUS_SUCCESS; 6266 } 6267 #endif 6268 6269 /** 6270 * send_pno_stop_cmd_tlv() - PNO stop request 6271 * @wmi_handle: wmi handle 6272 * @vdev_id: vdev id 6273 * 6274 * This function request FW to stop ongoing PNO operation. 6275 * 6276 * Return: QDF status 6277 */ 6278 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 6279 { 6280 wmi_nlo_config_cmd_fixed_param *cmd; 6281 int32_t len = sizeof(*cmd); 6282 wmi_buf_t buf; 6283 uint8_t *buf_ptr; 6284 int ret; 6285 6286 /* 6287 * TLV place holder for array of structures nlo_configured_parameters 6288 * TLV place holder for array of uint32_t channel_list 6289 * TLV place holder for chnl prediction cfg 6290 */ 6291 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6292 buf = wmi_buf_alloc(wmi_handle, len); 6293 if (!buf) 6294 return QDF_STATUS_E_NOMEM; 6295 6296 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6297 buf_ptr = (uint8_t *) cmd; 6298 6299 WMITLV_SET_HDR(&cmd->tlv_header, 6300 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6301 WMITLV_GET_STRUCT_TLVLEN 6302 (wmi_nlo_config_cmd_fixed_param)); 6303 6304 cmd->vdev_id = vdev_id; 6305 cmd->flags = WMI_NLO_CONFIG_STOP; 6306 buf_ptr += sizeof(*cmd); 6307 6308 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6309 buf_ptr += WMI_TLV_HDR_SIZE; 6310 6311 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 6312 buf_ptr += WMI_TLV_HDR_SIZE; 6313 6314 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6315 buf_ptr += WMI_TLV_HDR_SIZE; 6316 6317 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6318 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6319 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6320 if (ret) { 6321 wmi_err("Failed to send nlo wmi cmd"); 6322 wmi_buf_free(buf); 6323 return QDF_STATUS_E_FAILURE; 6324 } 6325 6326 return QDF_STATUS_SUCCESS; 6327 } 6328 6329 /** 6330 * send_obss_disable_cmd_tlv() - disable obss scan request 6331 * @wmi_handle: wmi handle 6332 * @vdev_id: vdev id 6333 * 6334 * This function request FW to disable ongoing obss scan operation. 6335 * 6336 * Return: QDF status 6337 */ 6338 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 6339 uint8_t vdev_id) 6340 { 6341 QDF_STATUS status; 6342 wmi_buf_t buf; 6343 wmi_obss_scan_disable_cmd_fixed_param *cmd; 6344 int len = sizeof(*cmd); 6345 6346 buf = wmi_buf_alloc(wmi_handle, len); 6347 if (!buf) 6348 return QDF_STATUS_E_NOMEM; 6349 6350 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 6351 6352 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 6353 WMITLV_SET_HDR(&cmd->tlv_header, 6354 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 6355 WMITLV_GET_STRUCT_TLVLEN( 6356 wmi_obss_scan_disable_cmd_fixed_param)); 6357 6358 cmd->vdev_id = vdev_id; 6359 status = wmi_unified_cmd_send(wmi_handle, buf, len, 6360 WMI_OBSS_SCAN_DISABLE_CMDID); 6361 if (QDF_IS_STATUS_ERROR(status)) 6362 wmi_buf_free(buf); 6363 6364 return status; 6365 } 6366 6367 /** 6368 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 6369 * @buf_ptr: Buffer passed by upper layers 6370 * @pno: Buffer to be sent to the firmware 6371 * 6372 * Copy the PNO Channel prediction configuration parameters 6373 * passed by the upper layers to a WMI format TLV and send it 6374 * down to the firmware. 6375 * 6376 * Return: None 6377 */ 6378 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 6379 struct pno_scan_req_params *pno) 6380 { 6381 nlo_channel_prediction_cfg *channel_prediction_cfg = 6382 (nlo_channel_prediction_cfg *) buf_ptr; 6383 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 6384 WMITLV_TAG_ARRAY_BYTE, 6385 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 6386 #ifdef FEATURE_WLAN_SCAN_PNO 6387 channel_prediction_cfg->enable = pno->pno_channel_prediction; 6388 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 6389 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 6390 channel_prediction_cfg->full_scan_period_ms = 6391 pno->channel_prediction_full_scan; 6392 #endif 6393 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6394 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 6395 channel_prediction_cfg->enable, 6396 channel_prediction_cfg->top_k_num, 6397 channel_prediction_cfg->stationary_threshold, 6398 channel_prediction_cfg->full_scan_period_ms); 6399 } 6400 6401 /** 6402 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 6403 * @wmi_handle: wmi handle 6404 * @buf_ptr: Buffer passed by upper layers 6405 * @buf_len: Length of passed buffer by upper layer 6406 * 6407 * Copy the buffer passed by the upper layers and send it 6408 * down to the firmware. 6409 * 6410 * Return: None 6411 */ 6412 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 6413 void *buf_ptr, uint32_t buf_len) 6414 { 6415 wmi_buf_t buf = NULL; 6416 QDF_STATUS status; 6417 int len; 6418 uint8_t *data_ptr; 6419 6420 len = buf_len; 6421 buf = wmi_buf_alloc(wmi_handle, len); 6422 if (!buf) 6423 return QDF_STATUS_E_NOMEM; 6424 6425 data_ptr = (uint8_t *)wmi_buf_data(buf); 6426 qdf_mem_copy(data_ptr, buf_ptr, len); 6427 6428 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6429 status = wmi_unified_cmd_send(wmi_handle, buf, 6430 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 6431 6432 if (QDF_IS_STATUS_ERROR(status)) { 6433 wmi_buf_free(buf); 6434 return QDF_STATUS_E_FAILURE; 6435 } 6436 return QDF_STATUS_SUCCESS; 6437 } 6438 6439 /** 6440 * send_halphy_stats_cmd_tlv() - Send halphy stats wmi command 6441 * @wmi_handle: wmi handle 6442 * @buf_ptr: Buffer passed by upper layers 6443 * @buf_len: Length of passed buffer by upper layer 6444 * 6445 * Copy the buffer passed by the upper layers and send it 6446 * down to the firmware. 6447 * 6448 * Return: None 6449 */ 6450 static QDF_STATUS send_halphy_stats_cmd_tlv(wmi_unified_t wmi_handle, 6451 void *buf_ptr, uint32_t buf_len) 6452 { 6453 wmi_buf_t buf = NULL; 6454 QDF_STATUS status; 6455 int len; 6456 uint8_t *data_ptr; 6457 6458 len = buf_len; 6459 buf = wmi_buf_alloc(wmi_handle, len); 6460 if (!buf) 6461 return QDF_STATUS_E_NOMEM; 6462 6463 data_ptr = (uint8_t *)wmi_buf_data(buf); 6464 qdf_mem_copy(data_ptr, buf_ptr, len); 6465 6466 wmi_mtrace(WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6467 status = wmi_unified_cmd_send(wmi_handle, buf, 6468 len, 6469 WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID); 6470 6471 if (QDF_IS_STATUS_ERROR(status)) { 6472 wmi_buf_free(buf); 6473 return QDF_STATUS_E_FAILURE; 6474 } 6475 return QDF_STATUS_SUCCESS; 6476 } 6477 6478 /** 6479 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 6480 * @wmi_handle: wmi handle 6481 * @evt_buf: event buffer 6482 * @more_flag: buffer to populate more flag 6483 * 6484 * Return: status of operation 6485 */ 6486 static QDF_STATUS 6487 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6488 uint32_t *more_flag) 6489 { 6490 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6491 wmi_ctrl_path_stats_event_fixed_param *ev; 6492 6493 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6494 if (!param_buf) { 6495 wmi_err_rl("param_buf is NULL"); 6496 return QDF_STATUS_E_FAILURE; 6497 } 6498 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 6499 6500 *more_flag = ev->more; 6501 return QDF_STATUS_SUCCESS; 6502 } 6503 6504 /** 6505 * extract_halphy_stats_end_of_event_tlv - api to extract end_of_event flag 6506 * from event data 6507 * @wmi_handle: wmi handle 6508 * @evt_buf: event buffer 6509 * @end_of_event_flag: buffer to populate end_of_event flag 6510 * 6511 * Return: status of operation 6512 */ 6513 static QDF_STATUS 6514 extract_halphy_stats_end_of_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6515 uint32_t *end_of_event_flag) 6516 { 6517 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6518 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6519 6520 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6521 if (!param_buf) { 6522 wmi_err_rl("param_buf is NULL"); 6523 return QDF_STATUS_E_FAILURE; 6524 } 6525 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6526 param_buf->fixed_param; 6527 6528 *end_of_event_flag = ev->end_of_event; 6529 return QDF_STATUS_SUCCESS; 6530 } 6531 6532 /** 6533 * extract_halphy_stats_event_count_tlv() - api to extract event count flag 6534 * from event data 6535 * @wmi_handle: wmi handle 6536 * @evt_buf: event buffer 6537 * @event_count_flag: buffer to populate event_count flag 6538 * 6539 * Return: status of operation 6540 */ 6541 static QDF_STATUS 6542 extract_halphy_stats_event_count_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6543 uint32_t *event_count_flag) 6544 { 6545 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6546 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6547 6548 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6549 if (!param_buf) { 6550 wmi_err_rl("param_buf is NULL"); 6551 return QDF_STATUS_E_FAILURE; 6552 } 6553 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6554 param_buf->fixed_param; 6555 6556 *event_count_flag = ev->event_count; 6557 return QDF_STATUS_SUCCESS; 6558 } 6559 6560 /** 6561 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 6562 * @wmi_handle: wmi handle 6563 * @params: configuration parameters 6564 * 6565 * Return: QDF_STATUS 6566 */ 6567 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 6568 struct nlo_mawc_params *params) 6569 { 6570 wmi_buf_t buf = NULL; 6571 QDF_STATUS status; 6572 int len; 6573 uint8_t *buf_ptr; 6574 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 6575 6576 len = sizeof(*wmi_nlo_mawc_params); 6577 buf = wmi_buf_alloc(wmi_handle, len); 6578 if (!buf) 6579 return QDF_STATUS_E_NOMEM; 6580 6581 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6582 wmi_nlo_mawc_params = 6583 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 6584 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 6585 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 6586 WMITLV_GET_STRUCT_TLVLEN 6587 (wmi_nlo_configure_mawc_cmd_fixed_param)); 6588 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 6589 if (params->enable) 6590 wmi_nlo_mawc_params->enable = 1; 6591 else 6592 wmi_nlo_mawc_params->enable = 0; 6593 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 6594 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 6595 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 6596 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 6597 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 6598 wmi_nlo_mawc_params->exp_backoff_ratio, 6599 wmi_nlo_mawc_params->init_scan_interval, 6600 wmi_nlo_mawc_params->max_scan_interval); 6601 6602 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 6603 status = wmi_unified_cmd_send(wmi_handle, buf, 6604 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 6605 if (QDF_IS_STATUS_ERROR(status)) { 6606 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 6607 status); 6608 wmi_buf_free(buf); 6609 return QDF_STATUS_E_FAILURE; 6610 } 6611 6612 return QDF_STATUS_SUCCESS; 6613 } 6614 6615 /** 6616 * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno 6617 * scan 6618 * @scan_freq_list: frequency list for pno scan 6619 * 6620 * Return: void 6621 */ 6622 static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) 6623 { 6624 uint32_t i; 6625 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 6626 uint32_t len = 0; 6627 struct chan_info *chan_info; 6628 int ret; 6629 6630 wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); 6631 for (i = 0; i < scan_freq_list->num_chan; i++) { 6632 chan_info = &scan_freq_list->chan[i]; 6633 ret = qdf_scnprintf(info + len, sizeof(info) - len, 6634 " %d[%d]", chan_info->freq, 6635 chan_info->flags); 6636 if (ret <= 0) 6637 break; 6638 len += ret; 6639 if (len >= (sizeof(info) - 20)) { 6640 wmi_nofl_debug("Freq[flag]:%s", 6641 info); 6642 len = 0; 6643 } 6644 } 6645 if (len) 6646 wmi_nofl_debug("Freq[flag]:%s", info); 6647 } 6648 6649 /** 6650 * send_pno_start_cmd_tlv() - PNO start request 6651 * @wmi_handle: wmi handle 6652 * @pno: PNO request 6653 * 6654 * This function request FW to start PNO request. 6655 * Request: QDF status 6656 */ 6657 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 6658 struct pno_scan_req_params *pno) 6659 { 6660 wmi_nlo_config_cmd_fixed_param *cmd; 6661 nlo_configured_parameters *nlo_list; 6662 uint32_t *channel_list; 6663 int32_t len; 6664 qdf_freq_t freq; 6665 wmi_buf_t buf; 6666 uint8_t *buf_ptr; 6667 uint8_t i; 6668 int ret; 6669 struct probe_req_allowlist_attr *ie_allowlist = &pno->ie_allowlist; 6670 connected_nlo_rssi_params *nlo_relative_rssi; 6671 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 6672 6673 /* 6674 * TLV place holder for array nlo_configured_parameters(nlo_list) 6675 * TLV place holder for array of uint32_t channel_list 6676 * TLV place holder for chnnl prediction cfg 6677 * TLV place holder for array of wmi_vendor_oui 6678 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 6679 */ 6680 len = sizeof(*cmd) + 6681 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 6682 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6683 6684 len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; 6685 len += sizeof(nlo_configured_parameters) * 6686 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6687 len += sizeof(nlo_channel_prediction_cfg); 6688 len += sizeof(enlo_candidate_score_params); 6689 len += sizeof(wmi_vendor_oui) * ie_allowlist->num_vendor_oui; 6690 len += sizeof(connected_nlo_rssi_params); 6691 len += sizeof(connected_nlo_bss_band_rssi_pref); 6692 6693 buf = wmi_buf_alloc(wmi_handle, len); 6694 if (!buf) 6695 return QDF_STATUS_E_NOMEM; 6696 6697 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6698 6699 buf_ptr = (uint8_t *) cmd; 6700 WMITLV_SET_HDR(&cmd->tlv_header, 6701 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6702 WMITLV_GET_STRUCT_TLVLEN 6703 (wmi_nlo_config_cmd_fixed_param)); 6704 cmd->vdev_id = pno->vdev_id; 6705 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 6706 6707 #ifdef FEATURE_WLAN_SCAN_PNO 6708 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 6709 pno->adaptive_dwell_mode); 6710 #endif 6711 /* Current FW does not support min-max range for dwell time */ 6712 cmd->active_dwell_time = pno->active_dwell_time; 6713 cmd->passive_dwell_time = pno->passive_dwell_time; 6714 6715 if (pno->do_passive_scan) 6716 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 6717 /* Copy scan interval */ 6718 cmd->fast_scan_period = pno->fast_scan_period; 6719 cmd->slow_scan_period = pno->slow_scan_period; 6720 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 6721 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 6722 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 6723 6724 /* mac randomization attributes */ 6725 if (pno->scan_random.randomize) { 6726 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 6727 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 6728 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 6729 pno->scan_random.mac_mask, 6730 &cmd->mac_addr, 6731 &cmd->mac_mask); 6732 } 6733 6734 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 6735 6736 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6737 6738 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6739 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 6740 buf_ptr += WMI_TLV_HDR_SIZE; 6741 6742 nlo_list = (nlo_configured_parameters *) buf_ptr; 6743 for (i = 0; i < cmd->no_of_ssids; i++) { 6744 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 6745 WMITLV_TAG_ARRAY_BYTE, 6746 WMITLV_GET_STRUCT_TLVLEN 6747 (nlo_configured_parameters)); 6748 /* Copy ssid and it's length */ 6749 nlo_list[i].ssid.valid = true; 6750 nlo_list[i].ssid.ssid.ssid_len = 6751 pno->networks_list[i].ssid.length; 6752 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 6753 pno->networks_list[i].ssid.ssid, 6754 nlo_list[i].ssid.ssid.ssid_len); 6755 6756 /* Copy rssi threshold */ 6757 if (pno->networks_list[i].rssi_thresh && 6758 pno->networks_list[i].rssi_thresh > 6759 WMI_RSSI_THOLD_DEFAULT) { 6760 nlo_list[i].rssi_cond.valid = true; 6761 nlo_list[i].rssi_cond.rssi = 6762 pno->networks_list[i].rssi_thresh; 6763 } 6764 nlo_list[i].bcast_nw_type.valid = true; 6765 nlo_list[i].bcast_nw_type.bcast_nw_type = 6766 pno->networks_list[i].bc_new_type; 6767 } 6768 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 6769 6770 /* Copy channel info */ 6771 cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; 6772 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6773 (cmd->num_of_channels * sizeof(uint32_t))); 6774 buf_ptr += WMI_TLV_HDR_SIZE; 6775 6776 channel_list = (uint32_t *) buf_ptr; 6777 for (i = 0; i < cmd->num_of_channels; i++) { 6778 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6779 pno->networks_list[0].pno_chan_list.chan[i].freq); 6780 6781 if (channel_list[i] < WMI_NLO_FREQ_THRESH) { 6782 freq = pno->networks_list[0].pno_chan_list.chan[i].freq; 6783 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6784 wlan_chan_to_freq(freq)); 6785 } 6786 6787 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], 6788 pno->networks_list[0].pno_chan_list.chan[i].flags); 6789 } 6790 6791 wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); 6792 6793 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 6794 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6795 sizeof(nlo_channel_prediction_cfg)); 6796 buf_ptr += WMI_TLV_HDR_SIZE; 6797 wmi_set_pno_channel_prediction(buf_ptr, pno); 6798 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6799 /** TODO: Discrete firmware doesn't have command/option to configure 6800 * App IE which comes from wpa_supplicant as of part PNO start request. 6801 */ 6802 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 6803 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 6804 buf_ptr += sizeof(enlo_candidate_score_params); 6805 6806 if (ie_allowlist->allow_list) { 6807 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6808 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6809 &cmd->num_vendor_oui, 6810 ie_allowlist); 6811 } 6812 6813 /* ie allow list */ 6814 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6815 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6816 buf_ptr += WMI_TLV_HDR_SIZE; 6817 if (cmd->num_vendor_oui != 0) { 6818 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6819 ie_allowlist->voui); 6820 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6821 } 6822 6823 if (pno->relative_rssi_set) 6824 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 6825 6826 /* 6827 * Firmware calculation using connected PNO params: 6828 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 6829 * deduction of rssi_pref for chosen band_pref and 6830 * addition of rssi_pref for remaining bands (other than chosen band). 6831 */ 6832 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 6833 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 6834 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 6835 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 6836 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 6837 buf_ptr += sizeof(*nlo_relative_rssi); 6838 6839 /* 6840 * As of now Kernel and Host supports one band and rssi preference. 6841 * Firmware supports array of band and rssi preferences 6842 */ 6843 cmd->num_cnlo_band_pref = 1; 6844 WMITLV_SET_HDR(buf_ptr, 6845 WMITLV_TAG_ARRAY_STRUC, 6846 cmd->num_cnlo_band_pref * 6847 sizeof(connected_nlo_bss_band_rssi_pref)); 6848 buf_ptr += WMI_TLV_HDR_SIZE; 6849 6850 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 6851 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 6852 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 6853 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 6854 WMITLV_GET_STRUCT_TLVLEN( 6855 connected_nlo_bss_band_rssi_pref)); 6856 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 6857 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 6858 } 6859 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 6860 6861 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6862 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6863 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6864 if (ret) { 6865 wmi_err("Failed to send nlo wmi cmd"); 6866 wmi_buf_free(buf); 6867 return QDF_STATUS_E_FAILURE; 6868 } 6869 6870 return QDF_STATUS_SUCCESS; 6871 } 6872 6873 /** 6874 * is_service_enabled_tlv() - Check if service enabled 6875 * @wmi_handle: wmi handle 6876 * @service_id: service identifier 6877 * 6878 * Return: 1 enabled, 0 disabled 6879 */ 6880 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 6881 uint32_t service_id) 6882 { 6883 struct wmi_soc *soc = wmi_handle->soc; 6884 6885 if (!soc->wmi_service_bitmap) { 6886 wmi_err("WMI service bit map is not saved yet"); 6887 return false; 6888 } 6889 6890 /* if wmi_service_enabled was received with extended2 bitmap, 6891 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 6892 */ 6893 if (soc->wmi_ext2_service_bitmap) { 6894 if (!soc->wmi_ext_service_bitmap) { 6895 wmi_err("WMI service ext bit map is not saved yet"); 6896 return false; 6897 } 6898 6899 if (service_id > WMI_MAX_EXT_SERVICE && 6900 (service_id - WMI_MAX_EXT_SERVICE) / 32 >= 6901 soc->wmi_ext2_service_bitmap_len) { 6902 wmi_err("WMI service ext2 bit = %d is not advertised by fw", 6903 service_id); 6904 return false; 6905 } 6906 6907 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 6908 soc->wmi_ext_service_bitmap, 6909 soc->wmi_ext2_service_bitmap, 6910 service_id); 6911 } 6912 6913 if (service_id >= WMI_MAX_EXT_SERVICE) { 6914 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 6915 service_id); 6916 return false; 6917 } 6918 /* if wmi_service_enabled was received with extended bitmap, 6919 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 6920 */ 6921 if (soc->wmi_ext_service_bitmap) 6922 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 6923 soc->wmi_ext_service_bitmap, 6924 service_id); 6925 6926 if (service_id >= WMI_MAX_SERVICE) { 6927 wmi_err("Service id %d but WMI ext service bitmap is NULL", 6928 service_id); 6929 return false; 6930 } 6931 6932 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 6933 service_id); 6934 } 6935 6936 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 6937 /** 6938 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 6939 * @wmi_handle: wmi handle 6940 * @clear_req: ll stats clear request command params 6941 * 6942 * Return: QDF_STATUS_SUCCESS for success or error code 6943 */ 6944 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 6945 const struct ll_stats_clear_params *clear_req) 6946 { 6947 wmi_clear_link_stats_cmd_fixed_param *cmd; 6948 int32_t len; 6949 wmi_buf_t buf; 6950 uint8_t *buf_ptr; 6951 int ret; 6952 6953 len = sizeof(*cmd); 6954 buf = wmi_buf_alloc(wmi_handle, len); 6955 6956 if (!buf) 6957 return QDF_STATUS_E_NOMEM; 6958 6959 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6960 qdf_mem_zero(buf_ptr, len); 6961 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 6962 6963 WMITLV_SET_HDR(&cmd->tlv_header, 6964 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 6965 WMITLV_GET_STRUCT_TLVLEN 6966 (wmi_clear_link_stats_cmd_fixed_param)); 6967 6968 cmd->stop_stats_collection_req = clear_req->stop_req; 6969 cmd->vdev_id = clear_req->vdev_id; 6970 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 6971 6972 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 6973 &cmd->peer_macaddr); 6974 6975 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 6976 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 6977 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6978 cmd->stop_stats_collection_req, 6979 cmd->vdev_id, cmd->stats_clear_req_mask, 6980 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 6981 6982 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 6983 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6984 WMI_CLEAR_LINK_STATS_CMDID); 6985 if (ret) { 6986 wmi_err("Failed to send clear link stats req"); 6987 wmi_buf_free(buf); 6988 return QDF_STATUS_E_FAILURE; 6989 } 6990 6991 wmi_debug("Clear Link Layer Stats request sent successfully"); 6992 return QDF_STATUS_SUCCESS; 6993 } 6994 6995 /** 6996 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 6997 * @wmi_handle: wmi handle 6998 * @set_req: ll stats set request command params 6999 * 7000 * Return: QDF_STATUS_SUCCESS for success or error code 7001 */ 7002 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 7003 const struct ll_stats_set_params *set_req) 7004 { 7005 wmi_start_link_stats_cmd_fixed_param *cmd; 7006 int32_t len; 7007 wmi_buf_t buf; 7008 uint8_t *buf_ptr; 7009 int ret; 7010 7011 len = sizeof(*cmd); 7012 buf = wmi_buf_alloc(wmi_handle, len); 7013 7014 if (!buf) 7015 return QDF_STATUS_E_NOMEM; 7016 7017 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7018 qdf_mem_zero(buf_ptr, len); 7019 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 7020 7021 WMITLV_SET_HDR(&cmd->tlv_header, 7022 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 7023 WMITLV_GET_STRUCT_TLVLEN 7024 (wmi_start_link_stats_cmd_fixed_param)); 7025 7026 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 7027 cmd->aggressive_statistics_gathering = 7028 set_req->aggressive_statistics_gathering; 7029 7030 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 7031 cmd->mpdu_size_threshold, 7032 cmd->aggressive_statistics_gathering); 7033 7034 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 7035 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7036 WMI_START_LINK_STATS_CMDID); 7037 if (ret) { 7038 wmi_err("Failed to send set link stats request"); 7039 wmi_buf_free(buf); 7040 return QDF_STATUS_E_FAILURE; 7041 } 7042 7043 return QDF_STATUS_SUCCESS; 7044 } 7045 7046 /** 7047 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 7048 * @wmi_handle: wmi handle 7049 * @get_req: ll stats get request command params 7050 * 7051 * Return: QDF_STATUS_SUCCESS for success or error code 7052 */ 7053 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 7054 const struct ll_stats_get_params *get_req) 7055 { 7056 wmi_request_link_stats_cmd_fixed_param *cmd; 7057 int32_t len; 7058 wmi_buf_t buf; 7059 uint8_t *buf_ptr; 7060 int ret; 7061 bool is_link_stats_over_qmi; 7062 7063 len = sizeof(*cmd); 7064 buf = wmi_buf_alloc(wmi_handle, len); 7065 7066 if (!buf) 7067 return QDF_STATUS_E_NOMEM; 7068 7069 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7070 qdf_mem_zero(buf_ptr, len); 7071 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 7072 7073 WMITLV_SET_HDR(&cmd->tlv_header, 7074 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 7075 WMITLV_GET_STRUCT_TLVLEN 7076 (wmi_request_link_stats_cmd_fixed_param)); 7077 7078 cmd->request_id = get_req->req_id; 7079 cmd->stats_type = get_req->param_id_mask; 7080 cmd->vdev_id = get_req->vdev_id; 7081 7082 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 7083 &cmd->peer_macaddr); 7084 7085 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 7086 cmd->request_id, cmd->stats_type, cmd->vdev_id, 7087 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 7088 7089 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 7090 is_link_stats_over_qmi = is_service_enabled_tlv( 7091 wmi_handle, 7092 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 7093 7094 if (is_link_stats_over_qmi) { 7095 ret = wmi_unified_cmd_send_over_qmi( 7096 wmi_handle, buf, len, 7097 WMI_REQUEST_LINK_STATS_CMDID); 7098 } else { 7099 ret = wmi_unified_cmd_send_pm_chk( 7100 wmi_handle, buf, len, 7101 WMI_REQUEST_LINK_STATS_CMDID, true); 7102 } 7103 7104 if (ret) { 7105 wmi_buf_free(buf); 7106 return QDF_STATUS_E_FAILURE; 7107 } 7108 7109 return QDF_STATUS_SUCCESS; 7110 } 7111 7112 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 7113 #ifdef WLAN_FEATURE_11BE_MLO 7114 static int 7115 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 7116 { 7117 int32_t len = 0; 7118 7119 /* In case of MLO connection, update the length of the buffer. 7120 * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, 7121 * hence just update the TLV header, but allocate no memory for it. 7122 */ 7123 if (!get_req->is_mlo_req) 7124 return len; 7125 7126 len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + 7127 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 7128 WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); 7129 7130 return len; 7131 } 7132 7133 static void 7134 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 7135 void *buf_ptr) 7136 { 7137 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 7138 uint32_t *vdev_id_bitmap; 7139 wmi_mac_addr *mld_mac; 7140 7141 /* In case of MLO connection, update the TLV Headers */ 7142 if (!get_req->is_mlo_req) 7143 return; 7144 7145 buf_ptr += sizeof(*unified_cmd); 7146 7147 /* Fill TLV but no data for wmi_inst_rssi_stats_params */ 7148 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7149 buf_ptr += WMI_TLV_HDR_SIZE; 7150 7151 /* Adding vdev_bitmap_id array TLV */ 7152 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7153 sizeof(*vdev_id_bitmap)); 7154 buf_ptr += WMI_TLV_HDR_SIZE; 7155 vdev_id_bitmap = buf_ptr; 7156 *(vdev_id_bitmap) = get_req->vdev_id_bitmap; 7157 buf_ptr += sizeof(*vdev_id_bitmap); 7158 7159 /* Adding mld_macaddr array TLV */ 7160 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 7161 sizeof(*mld_mac)); 7162 buf_ptr += WMI_TLV_HDR_SIZE; 7163 mld_mac = buf_ptr; 7164 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); 7165 7166 wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " 7167 QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, 7168 QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); 7169 } 7170 #else 7171 static inline int 7172 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 7173 { 7174 return 0; 7175 } 7176 7177 static inline void 7178 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 7179 void *buf_ptr) 7180 { 7181 } 7182 #endif 7183 7184 /** 7185 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 7186 * station request 7187 * @wmi_handle: wmi handle 7188 * @get_req: ll stats get request command params 7189 * 7190 * Return: QDF_STATUS_SUCCESS for success or error code 7191 */ 7192 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 7193 wmi_unified_t wmi_handle, 7194 const struct ll_stats_get_params *get_req) 7195 { 7196 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 7197 int32_t len; 7198 wmi_buf_t buf; 7199 void *buf_ptr; 7200 QDF_STATUS ret; 7201 bool is_ll_get_sta_stats_over_qmi; 7202 7203 len = sizeof(*unified_cmd); 7204 len += wmi_get_tlv_length_for_mlo_stats(get_req); 7205 7206 buf = wmi_buf_alloc(wmi_handle, len); 7207 if (!buf) 7208 return QDF_STATUS_E_NOMEM; 7209 7210 buf_ptr = wmi_buf_data(buf); 7211 7212 unified_cmd = buf_ptr; 7213 WMITLV_SET_HDR( 7214 &unified_cmd->tlv_header, 7215 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 7216 WMITLV_GET_STRUCT_TLVLEN 7217 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 7218 7219 unified_cmd->link_stats_type = get_req->param_id_mask; 7220 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 7221 WMI_REQUEST_PEER_STAT | 7222 WMI_REQUEST_VDEV_STAT | 7223 WMI_REQUEST_PDEV_STAT | 7224 WMI_REQUEST_VDEV_EXTD_STAT | 7225 WMI_REQUEST_PEER_EXTD2_STAT | 7226 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 7227 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7228 wmi_handle, 7229 WMI_HOST_PDEV_ID_SOC); 7230 7231 unified_cmd->vdev_id = get_req->vdev_id; 7232 unified_cmd->request_id = get_req->req_id; 7233 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 7234 &unified_cmd->peer_macaddr); 7235 7236 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 7237 QDF_MAC_ADDR_FMT, 7238 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 7239 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 7240 7241 wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); 7242 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 7243 7244 /** 7245 * FW support for LL_get_sta command. True represents the unified 7246 * ll_get_sta command should be sent over QMI always irrespective of 7247 * WOW state. 7248 */ 7249 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 7250 wmi_handle, 7251 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 7252 7253 if (is_ll_get_sta_stats_over_qmi) { 7254 ret = wmi_unified_cmd_send_over_qmi( 7255 wmi_handle, buf, len, 7256 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 7257 } else { 7258 ret = wmi_unified_cmd_send_pm_chk( 7259 wmi_handle, buf, len, 7260 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 7261 true); 7262 } 7263 7264 if (QDF_IS_STATUS_ERROR(ret)) { 7265 wmi_buf_free(buf); 7266 return QDF_STATUS_E_FAILURE; 7267 } 7268 7269 return ret; 7270 } 7271 #endif 7272 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 7273 7274 /** 7275 * send_congestion_cmd_tlv() - send request to fw to get CCA 7276 * @wmi_handle: wmi handle 7277 * @vdev_id: vdev id 7278 * 7279 * Return: QDF status 7280 */ 7281 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 7282 uint8_t vdev_id) 7283 { 7284 wmi_buf_t buf; 7285 wmi_request_stats_cmd_fixed_param *cmd; 7286 uint8_t len; 7287 uint8_t *buf_ptr; 7288 7289 len = sizeof(*cmd); 7290 buf = wmi_buf_alloc(wmi_handle, len); 7291 if (!buf) 7292 return QDF_STATUS_E_FAILURE; 7293 7294 buf_ptr = wmi_buf_data(buf); 7295 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 7296 WMITLV_SET_HDR(&cmd->tlv_header, 7297 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7298 WMITLV_GET_STRUCT_TLVLEN 7299 (wmi_request_stats_cmd_fixed_param)); 7300 7301 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 7302 cmd->vdev_id = vdev_id; 7303 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 7304 cmd->vdev_id, cmd->stats_id); 7305 7306 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7307 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7308 WMI_REQUEST_STATS_CMDID)) { 7309 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 7310 wmi_buf_free(buf); 7311 return QDF_STATUS_E_FAILURE; 7312 } 7313 7314 return QDF_STATUS_SUCCESS; 7315 } 7316 7317 /** 7318 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 7319 * @wmi_handle: wmi handle 7320 * 7321 * Return: QDF status 7322 */ 7323 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 7324 { 7325 wmi_buf_t buf; 7326 wmi_request_stats_cmd_fixed_param *cmd; 7327 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7328 7329 buf = wmi_buf_alloc(wmi_handle, len); 7330 if (!buf) 7331 return QDF_STATUS_E_FAILURE; 7332 7333 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7334 WMITLV_SET_HDR(&cmd->tlv_header, 7335 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7336 WMITLV_GET_STRUCT_TLVLEN 7337 (wmi_request_stats_cmd_fixed_param)); 7338 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 7339 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7340 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7341 WMI_REQUEST_STATS_CMDID)) { 7342 wmi_err("Failed to send host stats request to fw"); 7343 wmi_buf_free(buf); 7344 return QDF_STATUS_E_FAILURE; 7345 } 7346 7347 return QDF_STATUS_SUCCESS; 7348 } 7349 7350 /** 7351 * send_snr_cmd_tlv() - get RSSI from fw 7352 * @wmi_handle: wmi handle 7353 * @vdev_id: vdev id 7354 * 7355 * Return: QDF status 7356 */ 7357 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 7358 { 7359 wmi_buf_t buf; 7360 wmi_request_stats_cmd_fixed_param *cmd; 7361 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7362 7363 buf = wmi_buf_alloc(wmi_handle, len); 7364 if (!buf) 7365 return QDF_STATUS_E_FAILURE; 7366 7367 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7368 cmd->vdev_id = vdev_id; 7369 7370 WMITLV_SET_HDR(&cmd->tlv_header, 7371 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7372 WMITLV_GET_STRUCT_TLVLEN 7373 (wmi_request_stats_cmd_fixed_param)); 7374 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 7375 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7376 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7377 WMI_REQUEST_STATS_CMDID)) { 7378 wmi_err("Failed to send host stats request to fw"); 7379 wmi_buf_free(buf); 7380 return QDF_STATUS_E_FAILURE; 7381 } 7382 7383 return QDF_STATUS_SUCCESS; 7384 } 7385 7386 /** 7387 * send_link_status_req_cmd_tlv() - process link status request from UMAC 7388 * @wmi_handle: wmi handle 7389 * @link_status: get link params 7390 * 7391 * Return: QDF status 7392 */ 7393 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 7394 struct link_status_params *link_status) 7395 { 7396 wmi_buf_t buf; 7397 wmi_request_stats_cmd_fixed_param *cmd; 7398 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7399 7400 buf = wmi_buf_alloc(wmi_handle, len); 7401 if (!buf) 7402 return QDF_STATUS_E_FAILURE; 7403 7404 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7405 WMITLV_SET_HDR(&cmd->tlv_header, 7406 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7407 WMITLV_GET_STRUCT_TLVLEN 7408 (wmi_request_stats_cmd_fixed_param)); 7409 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 7410 cmd->vdev_id = link_status->vdev_id; 7411 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7412 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7413 WMI_REQUEST_STATS_CMDID)) { 7414 wmi_err("Failed to send WMI link status request to fw"); 7415 wmi_buf_free(buf); 7416 return QDF_STATUS_E_FAILURE; 7417 } 7418 7419 return QDF_STATUS_SUCCESS; 7420 } 7421 7422 #ifdef WLAN_SUPPORT_GREEN_AP 7423 /** 7424 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 7425 * @wmi_handle: wmi handler 7426 * @egap_params: pointer to egap_params 7427 * 7428 * Return: 0 for success, otherwise appropriate error code 7429 */ 7430 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 7431 struct wlan_green_ap_egap_params *egap_params) 7432 { 7433 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 7434 wmi_buf_t buf; 7435 int32_t err; 7436 7437 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7438 if (!buf) 7439 return QDF_STATUS_E_NOMEM; 7440 7441 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 7442 WMITLV_SET_HDR(&cmd->tlv_header, 7443 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 7444 WMITLV_GET_STRUCT_TLVLEN( 7445 wmi_ap_ps_egap_param_cmd_fixed_param)); 7446 7447 cmd->enable = egap_params->host_enable_egap; 7448 cmd->inactivity_time = egap_params->egap_inactivity_time; 7449 cmd->wait_time = egap_params->egap_wait_time; 7450 cmd->flags = egap_params->egap_feature_flags; 7451 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 7452 err = wmi_unified_cmd_send(wmi_handle, buf, 7453 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 7454 if (err) { 7455 wmi_err("Failed to send ap_ps_egap cmd"); 7456 wmi_buf_free(buf); 7457 return QDF_STATUS_E_FAILURE; 7458 } 7459 7460 return QDF_STATUS_SUCCESS; 7461 } 7462 #endif 7463 7464 /** 7465 * send_csa_offload_enable_cmd_tlv() - send CSA offload enable command 7466 * @wmi_handle: wmi handle 7467 * @vdev_id: vdev id 7468 * 7469 * Return: QDF_STATUS_SUCCESS for success or error code 7470 */ 7471 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 7472 uint8_t vdev_id) 7473 { 7474 wmi_csa_offload_enable_cmd_fixed_param *cmd; 7475 wmi_buf_t buf; 7476 int32_t len = sizeof(*cmd); 7477 7478 wmi_debug("vdev_id %d", vdev_id); 7479 buf = wmi_buf_alloc(wmi_handle, len); 7480 if (!buf) 7481 return QDF_STATUS_E_NOMEM; 7482 7483 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 7484 WMITLV_SET_HDR(&cmd->tlv_header, 7485 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 7486 WMITLV_GET_STRUCT_TLVLEN 7487 (wmi_csa_offload_enable_cmd_fixed_param)); 7488 cmd->vdev_id = vdev_id; 7489 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 7490 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 7491 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7492 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 7493 wmi_err("Failed to send CSA offload enable command"); 7494 wmi_buf_free(buf); 7495 return QDF_STATUS_E_FAILURE; 7496 } 7497 7498 return 0; 7499 } 7500 7501 #ifdef WLAN_FEATURE_CIF_CFR 7502 /** 7503 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 7504 * @wmi_handle: wmi handle 7505 * @cfg: dma cfg req 7506 * 7507 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 7508 */ 7509 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 7510 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 7511 { 7512 wmi_buf_t buf; 7513 uint8_t *cmd; 7514 QDF_STATUS ret; 7515 7516 WMITLV_SET_HDR(cfg, 7517 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 7518 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 7519 7520 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 7521 if (!buf) 7522 return QDF_STATUS_E_FAILURE; 7523 7524 cmd = (uint8_t *) wmi_buf_data(buf); 7525 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 7526 wmi_debug("Sending OEM Data Request to target, data len %lu", 7527 sizeof(*cfg)); 7528 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 7529 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 7530 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 7531 if (QDF_IS_STATUS_ERROR(ret)) { 7532 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 7533 wmi_buf_free(buf); 7534 } 7535 7536 return ret; 7537 } 7538 #endif 7539 7540 /** 7541 * send_start_11d_scan_cmd_tlv() - start 11d scan request 7542 * @wmi_handle: wmi handle 7543 * @start_11d_scan: 11d scan start request parameters 7544 * 7545 * This function request FW to start 11d scan. 7546 * 7547 * Return: QDF status 7548 */ 7549 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7550 struct reg_start_11d_scan_req *start_11d_scan) 7551 { 7552 wmi_11d_scan_start_cmd_fixed_param *cmd; 7553 int32_t len; 7554 wmi_buf_t buf; 7555 int ret; 7556 7557 len = sizeof(*cmd); 7558 buf = wmi_buf_alloc(wmi_handle, len); 7559 if (!buf) 7560 return QDF_STATUS_E_NOMEM; 7561 7562 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 7563 7564 WMITLV_SET_HDR(&cmd->tlv_header, 7565 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 7566 WMITLV_GET_STRUCT_TLVLEN 7567 (wmi_11d_scan_start_cmd_fixed_param)); 7568 7569 cmd->vdev_id = start_11d_scan->vdev_id; 7570 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 7571 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 7572 7573 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 7574 7575 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 7576 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7577 WMI_11D_SCAN_START_CMDID); 7578 if (ret) { 7579 wmi_err("Failed to send start 11d scan wmi cmd"); 7580 wmi_buf_free(buf); 7581 return QDF_STATUS_E_FAILURE; 7582 } 7583 7584 return QDF_STATUS_SUCCESS; 7585 } 7586 7587 /** 7588 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 7589 * @wmi_handle: wmi handle 7590 * @stop_11d_scan: 11d scan stop request parameters 7591 * 7592 * This function request FW to stop 11d scan. 7593 * 7594 * Return: QDF status 7595 */ 7596 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7597 struct reg_stop_11d_scan_req *stop_11d_scan) 7598 { 7599 wmi_11d_scan_stop_cmd_fixed_param *cmd; 7600 int32_t len; 7601 wmi_buf_t buf; 7602 int ret; 7603 7604 len = sizeof(*cmd); 7605 buf = wmi_buf_alloc(wmi_handle, len); 7606 if (!buf) 7607 return QDF_STATUS_E_NOMEM; 7608 7609 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 7610 7611 WMITLV_SET_HDR(&cmd->tlv_header, 7612 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 7613 WMITLV_GET_STRUCT_TLVLEN 7614 (wmi_11d_scan_stop_cmd_fixed_param)); 7615 7616 cmd->vdev_id = stop_11d_scan->vdev_id; 7617 7618 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 7619 7620 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 7621 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7622 WMI_11D_SCAN_STOP_CMDID); 7623 if (ret) { 7624 wmi_err("Failed to send stop 11d scan wmi cmd"); 7625 wmi_buf_free(buf); 7626 return QDF_STATUS_E_FAILURE; 7627 } 7628 7629 return QDF_STATUS_SUCCESS; 7630 } 7631 7632 /** 7633 * send_start_oem_data_cmd_tlv() - start OEM data request to target 7634 * @wmi_handle: wmi handle 7635 * @data_len: the length of @data 7636 * @data: the pointer to data buf 7637 * 7638 * Return: QDF status 7639 */ 7640 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 7641 uint32_t data_len, 7642 uint8_t *data) 7643 { 7644 wmi_buf_t buf; 7645 uint8_t *cmd; 7646 QDF_STATUS ret; 7647 7648 buf = wmi_buf_alloc(wmi_handle, 7649 (data_len + WMI_TLV_HDR_SIZE)); 7650 if (!buf) 7651 return QDF_STATUS_E_FAILURE; 7652 7653 cmd = (uint8_t *) wmi_buf_data(buf); 7654 7655 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 7656 cmd += WMI_TLV_HDR_SIZE; 7657 qdf_mem_copy(cmd, data, 7658 data_len); 7659 7660 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 7661 7662 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 7663 ret = wmi_unified_cmd_send(wmi_handle, buf, 7664 (data_len + 7665 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 7666 7667 if (QDF_IS_STATUS_ERROR(ret)) { 7668 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 7669 wmi_buf_free(buf); 7670 } 7671 7672 return ret; 7673 } 7674 7675 #ifdef FEATURE_OEM_DATA 7676 /** 7677 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 7678 * @wmi_handle: wmi handle 7679 * @oem_data: the pointer to oem data 7680 * 7681 * Return: QDF status 7682 */ 7683 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 7684 struct oem_data *oem_data) 7685 { 7686 QDF_STATUS ret; 7687 wmi_oem_data_cmd_fixed_param *cmd; 7688 struct wmi_ops *ops; 7689 wmi_buf_t buf; 7690 uint16_t len = sizeof(*cmd); 7691 uint16_t oem_data_len_aligned; 7692 uint8_t *buf_ptr; 7693 uint32_t pdev_id; 7694 7695 if (!oem_data || !oem_data->data) { 7696 wmi_err_rl("oem data is not valid"); 7697 return QDF_STATUS_E_FAILURE; 7698 } 7699 7700 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 7701 if (oem_data_len_aligned < oem_data->data_len) { 7702 wmi_err_rl("integer overflow while rounding up data_len"); 7703 return QDF_STATUS_E_FAILURE; 7704 } 7705 7706 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 7707 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 7708 return QDF_STATUS_E_FAILURE; 7709 } 7710 7711 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 7712 buf = wmi_buf_alloc(wmi_handle, len); 7713 if (!buf) 7714 return QDF_STATUS_E_NOMEM; 7715 7716 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7717 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 7718 WMITLV_SET_HDR(&cmd->tlv_header, 7719 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 7720 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 7721 7722 pdev_id = oem_data->pdev_id; 7723 if (oem_data->pdev_vdev_flag) { 7724 ops = wmi_handle->ops; 7725 if (oem_data->is_host_pdev_id) 7726 pdev_id = 7727 ops->convert_host_pdev_id_to_target(wmi_handle, 7728 pdev_id); 7729 else 7730 pdev_id = 7731 ops->convert_pdev_id_host_to_target(wmi_handle, 7732 pdev_id); 7733 } 7734 7735 cmd->vdev_id = oem_data->vdev_id; 7736 cmd->data_len = oem_data->data_len; 7737 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 7738 cmd->pdev_id = pdev_id; 7739 7740 buf_ptr += sizeof(*cmd); 7741 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 7742 buf_ptr += WMI_TLV_HDR_SIZE; 7743 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 7744 7745 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 7746 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 7747 if (QDF_IS_STATUS_ERROR(ret)) { 7748 wmi_err_rl("Failed with ret = %d", ret); 7749 wmi_buf_free(buf); 7750 } 7751 7752 return ret; 7753 } 7754 #endif 7755 7756 /** 7757 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 7758 * @wmi_handle: wmi handle 7759 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 7760 * 7761 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 7762 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 7763 * to firmware based on phyerr filtering 7764 * offload status. 7765 * 7766 * Return: 1 success, 0 failure 7767 */ 7768 static QDF_STATUS 7769 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 7770 bool dfs_phyerr_filter_offload) 7771 { 7772 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 7773 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 7774 wmi_buf_t buf; 7775 uint16_t len; 7776 QDF_STATUS ret; 7777 7778 7779 if (false == dfs_phyerr_filter_offload) { 7780 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 7781 len = sizeof(*disable_phyerr_offload_cmd); 7782 buf = wmi_buf_alloc(wmi_handle, len); 7783 if (!buf) 7784 return 0; 7785 7786 disable_phyerr_offload_cmd = 7787 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 7788 wmi_buf_data(buf); 7789 7790 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 7791 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 7792 WMITLV_GET_STRUCT_TLVLEN 7793 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 7794 7795 /* 7796 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 7797 * to the firmware to disable the phyerror 7798 * filtering offload. 7799 */ 7800 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 7801 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7802 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 7803 if (QDF_IS_STATUS_ERROR(ret)) { 7804 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 7805 ret); 7806 wmi_buf_free(buf); 7807 return QDF_STATUS_E_FAILURE; 7808 } 7809 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 7810 } else { 7811 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 7812 7813 len = sizeof(*enable_phyerr_offload_cmd); 7814 buf = wmi_buf_alloc(wmi_handle, len); 7815 if (!buf) 7816 return QDF_STATUS_E_FAILURE; 7817 7818 enable_phyerr_offload_cmd = 7819 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 7820 wmi_buf_data(buf); 7821 7822 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 7823 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 7824 WMITLV_GET_STRUCT_TLVLEN 7825 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 7826 7827 /* 7828 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 7829 * to the firmware to enable the phyerror 7830 * filtering offload. 7831 */ 7832 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 7833 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7834 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 7835 7836 if (QDF_IS_STATUS_ERROR(ret)) { 7837 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 7838 wmi_buf_free(buf); 7839 return QDF_STATUS_E_FAILURE; 7840 } 7841 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 7842 } 7843 7844 return QDF_STATUS_SUCCESS; 7845 } 7846 7847 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 7848 /** 7849 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 7850 * @wmi_handle: wmi handle 7851 * @pktlog_event: pktlog event 7852 * @cmd_id: pktlog cmd id 7853 * @user_triggered: user triggered input for PKTLOG enable mode 7854 * 7855 * Return: QDF status 7856 */ 7857 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 7858 WMI_PKTLOG_EVENT pktlog_event, 7859 WMI_CMD_ID cmd_id, uint8_t user_triggered) 7860 { 7861 WMI_PKTLOG_EVENT PKTLOG_EVENT; 7862 WMI_CMD_ID CMD_ID; 7863 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 7864 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 7865 int len = 0; 7866 wmi_buf_t buf; 7867 int32_t idx, max_idx; 7868 7869 PKTLOG_EVENT = pktlog_event; 7870 CMD_ID = cmd_id; 7871 7872 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 7873 switch (CMD_ID) { 7874 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 7875 len = sizeof(*cmd); 7876 buf = wmi_buf_alloc(wmi_handle, len); 7877 if (!buf) 7878 return QDF_STATUS_E_NOMEM; 7879 7880 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 7881 wmi_buf_data(buf); 7882 WMITLV_SET_HDR(&cmd->tlv_header, 7883 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 7884 WMITLV_GET_STRUCT_TLVLEN 7885 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 7886 cmd->evlist = 0; 7887 for (idx = 0; idx < max_idx; idx++) { 7888 if (PKTLOG_EVENT & (1 << idx)) 7889 cmd->evlist |= pktlog_event_tlv[idx]; 7890 } 7891 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 7892 : WMI_PKTLOG_ENABLE_AUTO; 7893 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7894 wmi_handle, 7895 WMI_HOST_PDEV_ID_SOC); 7896 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 7897 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7898 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 7899 wmi_err("Failed to send pktlog enable cmdid"); 7900 goto wmi_send_failed; 7901 } 7902 break; 7903 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 7904 len = sizeof(*disable_cmd); 7905 buf = wmi_buf_alloc(wmi_handle, len); 7906 if (!buf) 7907 return QDF_STATUS_E_NOMEM; 7908 7909 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 7910 wmi_buf_data(buf); 7911 WMITLV_SET_HDR(&disable_cmd->tlv_header, 7912 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 7913 WMITLV_GET_STRUCT_TLVLEN 7914 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 7915 disable_cmd->pdev_id = 7916 wmi_handle->ops->convert_pdev_id_host_to_target( 7917 wmi_handle, 7918 WMI_HOST_PDEV_ID_SOC); 7919 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 7920 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7921 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 7922 wmi_err("failed to send pktlog disable cmdid"); 7923 goto wmi_send_failed; 7924 } 7925 break; 7926 default: 7927 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 7928 break; 7929 } 7930 7931 return QDF_STATUS_SUCCESS; 7932 7933 wmi_send_failed: 7934 wmi_buf_free(buf); 7935 return QDF_STATUS_E_FAILURE; 7936 } 7937 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 7938 7939 /** 7940 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 7941 * @wmi_handle: wmi handle 7942 * @preq: stats ext params 7943 * 7944 * Return: QDF status 7945 */ 7946 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 7947 struct stats_ext_params *preq) 7948 { 7949 QDF_STATUS ret; 7950 wmi_req_stats_ext_cmd_fixed_param *cmd; 7951 wmi_buf_t buf; 7952 size_t len; 7953 uint8_t *buf_ptr; 7954 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 7955 uint32_t *vdev_bitmap; 7956 7957 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 7958 sizeof(*cmd))) { 7959 wmi_err("Data length=%d is greater than max wmi msg size", 7960 preq->request_data_len); 7961 return QDF_STATUS_E_FAILURE; 7962 } 7963 7964 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len + 7965 WMI_TLV_HDR_SIZE + sizeof(uint32_t); 7966 7967 buf = wmi_buf_alloc(wmi_handle, len); 7968 if (!buf) 7969 return QDF_STATUS_E_NOMEM; 7970 7971 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7972 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 7973 7974 WMITLV_SET_HDR(&cmd->tlv_header, 7975 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 7976 WMITLV_GET_STRUCT_TLVLEN 7977 (wmi_req_stats_ext_cmd_fixed_param)); 7978 cmd->vdev_id = preq->vdev_id; 7979 cmd->data_len = preq->request_data_len; 7980 7981 wmi_debug("The data len value is %u and vdev id set is %u", 7982 preq->request_data_len, preq->vdev_id); 7983 7984 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 7985 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 7986 7987 buf_ptr += WMI_TLV_HDR_SIZE; 7988 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 7989 7990 buf_ptr += cmd->data_len; 7991 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 7992 7993 buf_ptr += WMI_TLV_HDR_SIZE; 7994 7995 vdev_bitmap = (A_UINT32 *)buf_ptr; 7996 7997 vdev_bitmap[0] = preq->vdev_id_bitmap; 7998 7999 wmi_debug("Sending MLO vdev_id_bitmap:%x", vdev_bitmap[0]); 8000 8001 buf_ptr += sizeof(uint32_t); 8002 8003 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 8004 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8005 WMI_REQUEST_STATS_EXT_CMDID); 8006 if (QDF_IS_STATUS_ERROR(ret)) { 8007 wmi_err("Failed to send notify cmd ret = %d", ret); 8008 wmi_buf_free(buf); 8009 } 8010 8011 return ret; 8012 } 8013 8014 /** 8015 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 8016 * @wmi_handle: wmi handle 8017 * @params: DHCP server offload info 8018 * 8019 * Return: QDF_STATUS_SUCCESS for success or error code 8020 */ 8021 static QDF_STATUS 8022 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 8023 struct dhcp_offload_info_params *params) 8024 { 8025 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 8026 wmi_buf_t buf; 8027 QDF_STATUS status; 8028 8029 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8030 if (!buf) 8031 return QDF_STATUS_E_NOMEM; 8032 8033 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 8034 8035 WMITLV_SET_HDR(&cmd->tlv_header, 8036 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 8037 WMITLV_GET_STRUCT_TLVLEN 8038 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 8039 cmd->vdev_id = params->vdev_id; 8040 cmd->enable = params->dhcp_offload_enabled; 8041 cmd->num_client = params->dhcp_client_num; 8042 cmd->srv_ipv4 = params->dhcp_srv_addr; 8043 cmd->start_lsb = 0; 8044 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 8045 status = wmi_unified_cmd_send(wmi_handle, buf, 8046 sizeof(*cmd), 8047 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 8048 if (QDF_IS_STATUS_ERROR(status)) { 8049 wmi_err("Failed to send set_dhcp_server_offload cmd"); 8050 wmi_buf_free(buf); 8051 return QDF_STATUS_E_FAILURE; 8052 } 8053 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 8054 8055 return status; 8056 } 8057 8058 /** 8059 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 8060 * @wmi_handle: wmi handle 8061 * @param: pointer to pdev regdomain params 8062 * 8063 * Return: QDF_STATUS_SUCCESS for success or error code 8064 */ 8065 static QDF_STATUS 8066 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 8067 struct pdev_set_regdomain_params *param) 8068 { 8069 wmi_buf_t buf; 8070 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 8071 int32_t len = sizeof(*cmd); 8072 8073 buf = wmi_buf_alloc(wmi_handle, len); 8074 if (!buf) 8075 return QDF_STATUS_E_NOMEM; 8076 8077 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 8078 WMITLV_SET_HDR(&cmd->tlv_header, 8079 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 8080 WMITLV_GET_STRUCT_TLVLEN 8081 (wmi_pdev_set_regdomain_cmd_fixed_param)); 8082 8083 cmd->reg_domain = param->currentRDinuse; 8084 cmd->reg_domain_2G = param->currentRD2G; 8085 cmd->reg_domain_5G = param->currentRD5G; 8086 cmd->conformance_test_limit_2G = param->ctl_2G; 8087 cmd->conformance_test_limit_5G = param->ctl_5G; 8088 cmd->dfs_domain = param->dfsDomain; 8089 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8090 wmi_handle, 8091 param->pdev_id); 8092 8093 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 8094 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8095 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 8096 wmi_err("Failed to send pdev set regdomain command"); 8097 wmi_buf_free(buf); 8098 return QDF_STATUS_E_FAILURE; 8099 } 8100 8101 return QDF_STATUS_SUCCESS; 8102 } 8103 8104 /** 8105 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 8106 * @wmi_handle: wmi handle 8107 * @reg_dmn: reg domain 8108 * @regdmn2G: 2G reg domain 8109 * @regdmn5G: 5G reg domain 8110 * @ctl2G: 2G test limit 8111 * @ctl5G: 5G test limit 8112 * 8113 * Return: none 8114 */ 8115 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 8116 uint32_t reg_dmn, uint16_t regdmn2G, 8117 uint16_t regdmn5G, uint8_t ctl2G, 8118 uint8_t ctl5G) 8119 { 8120 wmi_buf_t buf; 8121 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 8122 int32_t len = sizeof(*cmd); 8123 8124 8125 buf = wmi_buf_alloc(wmi_handle, len); 8126 if (!buf) 8127 return QDF_STATUS_E_NOMEM; 8128 8129 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 8130 WMITLV_SET_HDR(&cmd->tlv_header, 8131 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 8132 WMITLV_GET_STRUCT_TLVLEN 8133 (wmi_pdev_set_regdomain_cmd_fixed_param)); 8134 cmd->reg_domain = reg_dmn; 8135 cmd->reg_domain_2G = regdmn2G; 8136 cmd->reg_domain_5G = regdmn5G; 8137 cmd->conformance_test_limit_2G = ctl2G; 8138 cmd->conformance_test_limit_5G = ctl5G; 8139 8140 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 8141 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 8142 cmd->conformance_test_limit_2G, 8143 cmd->conformance_test_limit_5G); 8144 8145 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 8146 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8147 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 8148 wmi_err("Failed to send pdev set regdomain command"); 8149 wmi_buf_free(buf); 8150 return QDF_STATUS_E_FAILURE; 8151 } 8152 8153 return QDF_STATUS_SUCCESS; 8154 } 8155 8156 /** 8157 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 8158 * @param: param sent from the host side 8159 * @cmd: param to be sent to the fw side 8160 */ 8161 static inline void copy_custom_aggr_bitmap( 8162 struct set_custom_aggr_size_params *param, 8163 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 8164 { 8165 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 8166 param->ac); 8167 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 8168 param->aggr_type); 8169 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 8170 param->tx_aggr_size_disable); 8171 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 8172 param->rx_aggr_size_disable); 8173 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 8174 param->tx_ac_enable); 8175 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 8176 param->aggr_ba_enable); 8177 } 8178 8179 /** 8180 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 8181 * @wmi_handle: wmi handle 8182 * @param: pointer to hold custom aggr size params 8183 * 8184 * Return: QDF_STATUS_SUCCESS for success or error code 8185 */ 8186 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 8187 wmi_unified_t wmi_handle, 8188 struct set_custom_aggr_size_params *param) 8189 { 8190 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 8191 wmi_buf_t buf; 8192 int32_t len = sizeof(*cmd); 8193 8194 buf = wmi_buf_alloc(wmi_handle, len); 8195 if (!buf) 8196 return QDF_STATUS_E_FAILURE; 8197 8198 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 8199 wmi_buf_data(buf); 8200 WMITLV_SET_HDR(&cmd->tlv_header, 8201 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 8202 WMITLV_GET_STRUCT_TLVLEN( 8203 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 8204 cmd->vdev_id = param->vdev_id; 8205 cmd->tx_aggr_size = param->tx_aggr_size; 8206 cmd->rx_aggr_size = param->rx_aggr_size; 8207 copy_custom_aggr_bitmap(param, cmd); 8208 8209 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 8210 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 8211 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 8212 "tx_ac_enable=0x%X", 8213 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 8214 param->ac, param->aggr_type, param->tx_aggr_size_disable, 8215 param->rx_aggr_size_disable, param->tx_ac_enable); 8216 8217 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 8218 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8219 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 8220 wmi_err("Setting custom aggregation size failed"); 8221 wmi_buf_free(buf); 8222 return QDF_STATUS_E_FAILURE; 8223 } 8224 8225 return QDF_STATUS_SUCCESS; 8226 } 8227 8228 /** 8229 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 8230 * @wmi_handle: handle to WMI. 8231 * @param: pointer to tx antenna param 8232 * 8233 * Return: QDF_STATUS_SUCCESS for success or error code 8234 */ 8235 8236 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 8237 struct set_qdepth_thresh_params *param) 8238 { 8239 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 8240 wmi_msduq_qdepth_thresh_update *cmd_update; 8241 wmi_buf_t buf; 8242 int32_t len = 0; 8243 int i; 8244 uint8_t *buf_ptr; 8245 QDF_STATUS ret; 8246 8247 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 8248 wmi_err("Invalid Update Count!"); 8249 return QDF_STATUS_E_INVAL; 8250 } 8251 8252 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 8253 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 8254 param->num_of_msduq_updates); 8255 buf = wmi_buf_alloc(wmi_handle, len); 8256 8257 if (!buf) 8258 return QDF_STATUS_E_NOMEM; 8259 8260 buf_ptr = (uint8_t *)wmi_buf_data(buf); 8261 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 8262 buf_ptr; 8263 8264 WMITLV_SET_HDR(&cmd->tlv_header, 8265 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 8266 , WMITLV_GET_STRUCT_TLVLEN( 8267 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 8268 8269 cmd->pdev_id = 8270 wmi_handle->ops->convert_pdev_id_host_to_target( 8271 wmi_handle, 8272 param->pdev_id); 8273 cmd->vdev_id = param->vdev_id; 8274 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 8275 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 8276 8277 buf_ptr += sizeof( 8278 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 8279 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8280 param->num_of_msduq_updates * 8281 sizeof(wmi_msduq_qdepth_thresh_update)); 8282 buf_ptr += WMI_TLV_HDR_SIZE; 8283 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 8284 8285 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 8286 WMITLV_SET_HDR(&cmd_update->tlv_header, 8287 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 8288 WMITLV_GET_STRUCT_TLVLEN( 8289 wmi_msduq_qdepth_thresh_update)); 8290 cmd_update->tid_num = param->update_params[i].tid_num; 8291 cmd_update->msduq_update_mask = 8292 param->update_params[i].msduq_update_mask; 8293 cmd_update->qdepth_thresh_value = 8294 param->update_params[i].qdepth_thresh_value; 8295 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 8296 "mac_addr_upper4=%X, mac_addr_lower2:%X," 8297 " update mask=0x%X thresh val=0x%X", 8298 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 8299 cmd->peer_mac_address.mac_addr31to0, 8300 cmd->peer_mac_address.mac_addr47to32, 8301 cmd_update->msduq_update_mask, 8302 cmd_update->qdepth_thresh_value); 8303 cmd_update++; 8304 } 8305 8306 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 8307 cmd->vdev_id, 0); 8308 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8309 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 8310 8311 if (ret != 0) { 8312 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 8313 wmi_buf_free(buf); 8314 } 8315 8316 return ret; 8317 } 8318 8319 /** 8320 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 8321 * @wmi_handle: wmi handle 8322 * @param: pointer to hold vap dscp tid map param 8323 * 8324 * Return: QDF_STATUS_SUCCESS for success or error code 8325 */ 8326 static QDF_STATUS 8327 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 8328 struct vap_dscp_tid_map_params *param) 8329 { 8330 wmi_buf_t buf; 8331 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 8332 int32_t len = sizeof(*cmd); 8333 8334 buf = wmi_buf_alloc(wmi_handle, len); 8335 if (!buf) 8336 return QDF_STATUS_E_FAILURE; 8337 8338 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 8339 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 8340 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 8341 8342 cmd->vdev_id = param->vdev_id; 8343 cmd->enable_override = 0; 8344 8345 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 8346 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 8347 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8348 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 8349 wmi_err("Failed to set dscp cmd"); 8350 wmi_buf_free(buf); 8351 return QDF_STATUS_E_FAILURE; 8352 } 8353 8354 return QDF_STATUS_SUCCESS; 8355 } 8356 8357 /** 8358 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 8359 * @wmi_handle: wmi handle 8360 * @param: pointer to hold fwtest param 8361 * 8362 * Return: QDF_STATUS_SUCCESS for success or error code 8363 */ 8364 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 8365 struct set_fwtest_params *param) 8366 { 8367 wmi_fwtest_set_param_cmd_fixed_param *cmd; 8368 wmi_buf_t buf; 8369 int32_t len = sizeof(*cmd); 8370 8371 buf = wmi_buf_alloc(wmi_handle, len); 8372 8373 if (!buf) 8374 return QDF_STATUS_E_FAILURE; 8375 8376 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 8377 WMITLV_SET_HDR(&cmd->tlv_header, 8378 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 8379 WMITLV_GET_STRUCT_TLVLEN( 8380 wmi_fwtest_set_param_cmd_fixed_param)); 8381 cmd->param_id = param->arg; 8382 cmd->param_value = param->value; 8383 8384 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 8385 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 8386 wmi_err("Setting FW test param failed"); 8387 wmi_buf_free(buf); 8388 return QDF_STATUS_E_FAILURE; 8389 } 8390 8391 return QDF_STATUS_SUCCESS; 8392 } 8393 8394 /** 8395 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 8396 * @wmi_handle: handle to WMI. 8397 * 8398 * Return: QDF_STATUS_SUCCESS for success or error code 8399 */ 8400 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 8401 { 8402 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 8403 wmi_buf_t buf; 8404 QDF_STATUS ret; 8405 int32_t len; 8406 8407 len = sizeof(*cmd); 8408 8409 buf = wmi_buf_alloc(wmi_handle, len); 8410 if (!buf) 8411 return QDF_STATUS_E_FAILURE; 8412 8413 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 8414 WMITLV_SET_HDR(&cmd->tlv_header, 8415 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 8416 WMITLV_GET_STRUCT_TLVLEN( 8417 wmi_pdev_dfs_disable_cmd_fixed_param)); 8418 /* Filling it with WMI_PDEV_ID_SOC for now */ 8419 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8420 wmi_handle, 8421 WMI_HOST_PDEV_ID_SOC); 8422 8423 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 8424 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8425 WMI_PDEV_DFS_DISABLE_CMDID); 8426 8427 if (ret != 0) { 8428 wmi_err("Sending PDEV DFS disable cmd failed"); 8429 wmi_buf_free(buf); 8430 } 8431 8432 return ret; 8433 } 8434 8435 /** 8436 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 8437 * @wmi_handle: handle to WMI. 8438 * 8439 * Return: QDF_STATUS_SUCCESS for success or error code 8440 */ 8441 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 8442 { 8443 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 8444 wmi_buf_t buf; 8445 QDF_STATUS ret; 8446 int32_t len; 8447 8448 len = sizeof(*cmd); 8449 8450 buf = wmi_buf_alloc(wmi_handle, len); 8451 if (!buf) 8452 return QDF_STATUS_E_FAILURE; 8453 8454 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 8455 WMITLV_SET_HDR(&cmd->tlv_header, 8456 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 8457 WMITLV_GET_STRUCT_TLVLEN( 8458 wmi_pdev_dfs_enable_cmd_fixed_param)); 8459 /* Reserved for future use */ 8460 cmd->reserved0 = 0; 8461 8462 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 8463 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8464 WMI_PDEV_DFS_ENABLE_CMDID); 8465 8466 if (ret != 0) { 8467 wmi_err("Sending PDEV DFS enable cmd failed"); 8468 wmi_buf_free(buf); 8469 } 8470 8471 return ret; 8472 } 8473 8474 /** 8475 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 8476 * to fw 8477 * @wmi_handle: wmi handle 8478 * @param: pointer to hold periodic chan stats param 8479 * 8480 * Return: QDF_STATUS_SUCCESS for success or error code 8481 */ 8482 static QDF_STATUS 8483 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 8484 struct periodic_chan_stats_params *param) 8485 { 8486 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 8487 wmi_buf_t buf; 8488 QDF_STATUS ret; 8489 int32_t len; 8490 8491 len = sizeof(*cmd); 8492 8493 buf = wmi_buf_alloc(wmi_handle, len); 8494 if (!buf) 8495 return QDF_STATUS_E_FAILURE; 8496 8497 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 8498 wmi_buf_data(buf); 8499 WMITLV_SET_HDR(&cmd->tlv_header, 8500 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 8501 WMITLV_GET_STRUCT_TLVLEN( 8502 wmi_set_periodic_channel_stats_config_fixed_param)); 8503 cmd->enable = param->enable; 8504 cmd->stats_period = param->stats_period; 8505 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8506 wmi_handle, 8507 param->pdev_id); 8508 8509 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 8510 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8511 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 8512 8513 if (ret != 0) { 8514 wmi_err("Sending periodic chan stats config failed"); 8515 wmi_buf_free(buf); 8516 } 8517 8518 return ret; 8519 } 8520 8521 #ifdef WLAN_IOT_SIM_SUPPORT 8522 /** 8523 * send_simulation_test_cmd_tlv() - send simulation test command to fw 8524 * 8525 * @wmi_handle: wmi handle 8526 * @param: pointer to hold simulation test parameter 8527 * 8528 * Return: QDF_STATUS_SUCCESS for success or error code 8529 */ 8530 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 8531 struct simulation_test_params 8532 *param) 8533 { 8534 wmi_simulation_test_cmd_fixed_param *cmd; 8535 u32 wmi_buf_len; 8536 wmi_buf_t buf; 8537 u8 *buf_ptr; 8538 u32 aligned_len = 0; 8539 8540 wmi_buf_len = sizeof(*cmd); 8541 if (param->buf_len) { 8542 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 8543 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 8544 } 8545 8546 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 8547 if (!buf) { 8548 wmi_err("wmi_buf_alloc failed"); 8549 return QDF_STATUS_E_NOMEM; 8550 } 8551 8552 buf_ptr = wmi_buf_data(buf); 8553 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 8554 WMITLV_SET_HDR(&cmd->tlv_header, 8555 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 8556 WMITLV_GET_STRUCT_TLVLEN( 8557 wmi_simulation_test_cmd_fixed_param)); 8558 cmd->pdev_id = param->pdev_id; 8559 cmd->vdev_id = param->vdev_id; 8560 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 8561 cmd->test_cmd_type = param->test_cmd_type; 8562 cmd->test_subcmd_type = param->test_subcmd_type; 8563 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 8564 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 8565 param->frame_subtype); 8566 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 8567 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 8568 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 8569 cmd->buf_len = param->buf_len; 8570 8571 if (param->buf_len) { 8572 buf_ptr += sizeof(*cmd); 8573 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 8574 buf_ptr += WMI_TLV_HDR_SIZE; 8575 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 8576 } 8577 8578 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 8579 WMI_SIMULATION_TEST_CMDID)) { 8580 wmi_err("Failed to send test simulation cmd"); 8581 wmi_buf_free(buf); 8582 return QDF_STATUS_E_FAILURE; 8583 } 8584 8585 return QDF_STATUS_SUCCESS; 8586 } 8587 #endif 8588 8589 #ifdef WLAN_FEATURE_11BE 8590 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 8591 #else 8592 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 8593 #endif 8594 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 8595 { 8596 switch (wmi_width) { 8597 case WMI_CHAN_WIDTH_20: 8598 return CH_WIDTH_20MHZ; 8599 case WMI_CHAN_WIDTH_40: 8600 return CH_WIDTH_40MHZ; 8601 case WMI_CHAN_WIDTH_80: 8602 return CH_WIDTH_80MHZ; 8603 case WMI_CHAN_WIDTH_160: 8604 return CH_WIDTH_160MHZ; 8605 case WMI_CHAN_WIDTH_80P80: 8606 return CH_WIDTH_80P80MHZ; 8607 case WMI_CHAN_WIDTH_5: 8608 return CH_WIDTH_5MHZ; 8609 case WMI_CHAN_WIDTH_10: 8610 return CH_WIDTH_10MHZ; 8611 case WMI_CHAN_WIDTH_320: 8612 return WLAN_PHY_CH_WIDTH_320MHZ; 8613 default: 8614 return CH_WIDTH_INVALID; 8615 } 8616 } 8617 8618 #ifdef WLAN_FEATURE_11BE 8619 /** 8620 * wmi_host_to_fw_phymode_11be() - convert host to fw phymode for 11be phymode 8621 * @host_phymode: phymode to convert 8622 * 8623 * Return: one of the 11be values defined in enum WMI_HOST_WLAN_PHY_MODE; 8624 * or WMI_HOST_MODE_UNKNOWN if the input is not an 11be phymode 8625 */ 8626 static WMI_HOST_WLAN_PHY_MODE 8627 wmi_host_to_fw_phymode_11be(enum wlan_phymode host_phymode) 8628 { 8629 switch (host_phymode) { 8630 case WLAN_PHYMODE_11BEA_EHT20: 8631 return WMI_HOST_MODE_11BE_EHT20; 8632 case WLAN_PHYMODE_11BEA_EHT40: 8633 return WMI_HOST_MODE_11BE_EHT40; 8634 case WLAN_PHYMODE_11BEA_EHT80: 8635 return WMI_HOST_MODE_11BE_EHT80; 8636 case WLAN_PHYMODE_11BEA_EHT160: 8637 return WMI_HOST_MODE_11BE_EHT160; 8638 case WLAN_PHYMODE_11BEA_EHT320: 8639 return WMI_HOST_MODE_11BE_EHT320; 8640 case WLAN_PHYMODE_11BEG_EHT20: 8641 return WMI_HOST_MODE_11BE_EHT20_2G; 8642 case WLAN_PHYMODE_11BEG_EHT40: 8643 case WLAN_PHYMODE_11BEG_EHT40PLUS: 8644 case WLAN_PHYMODE_11BEG_EHT40MINUS: 8645 return WMI_HOST_MODE_11BE_EHT40_2G; 8646 default: 8647 return WMI_HOST_MODE_UNKNOWN; 8648 } 8649 } 8650 #else 8651 static WMI_HOST_WLAN_PHY_MODE 8652 wmi_host_to_fw_phymode_11be(enum wlan_phymode host_phymode) 8653 { 8654 return WMI_HOST_MODE_UNKNOWN; 8655 } 8656 #endif 8657 8658 WMI_HOST_WLAN_PHY_MODE wmi_host_to_fw_phymode(enum wlan_phymode host_phymode) 8659 { 8660 switch (host_phymode) { 8661 case WLAN_PHYMODE_11A: 8662 return WMI_HOST_MODE_11A; 8663 case WLAN_PHYMODE_11G: 8664 return WMI_HOST_MODE_11G; 8665 case WLAN_PHYMODE_11B: 8666 return WMI_HOST_MODE_11B; 8667 case WLAN_PHYMODE_11G_ONLY: 8668 return WMI_HOST_MODE_11GONLY; 8669 case WLAN_PHYMODE_11NA_HT20: 8670 return WMI_HOST_MODE_11NA_HT20; 8671 case WLAN_PHYMODE_11NG_HT20: 8672 return WMI_HOST_MODE_11NG_HT20; 8673 case WLAN_PHYMODE_11NA_HT40: 8674 return WMI_HOST_MODE_11NA_HT40; 8675 case WLAN_PHYMODE_11NG_HT40: 8676 case WLAN_PHYMODE_11NG_HT40PLUS: 8677 case WLAN_PHYMODE_11NG_HT40MINUS: 8678 return WMI_HOST_MODE_11NG_HT40; 8679 case WLAN_PHYMODE_11AC_VHT20: 8680 return WMI_HOST_MODE_11AC_VHT20; 8681 case WLAN_PHYMODE_11AC_VHT40: 8682 return WMI_HOST_MODE_11AC_VHT40; 8683 case WLAN_PHYMODE_11AC_VHT80: 8684 return WMI_HOST_MODE_11AC_VHT80; 8685 case WLAN_PHYMODE_11AC_VHT20_2G: 8686 return WMI_HOST_MODE_11AC_VHT20_2G; 8687 case WLAN_PHYMODE_11AC_VHT40PLUS_2G: 8688 case WLAN_PHYMODE_11AC_VHT40MINUS_2G: 8689 case WLAN_PHYMODE_11AC_VHT40_2G: 8690 return WMI_HOST_MODE_11AC_VHT40_2G; 8691 case WLAN_PHYMODE_11AC_VHT80_2G: 8692 return WMI_HOST_MODE_11AC_VHT80_2G; 8693 case WLAN_PHYMODE_11AC_VHT80_80: 8694 return WMI_HOST_MODE_11AC_VHT80_80; 8695 case WLAN_PHYMODE_11AC_VHT160: 8696 return WMI_HOST_MODE_11AC_VHT160; 8697 case WLAN_PHYMODE_11AXA_HE20: 8698 return WMI_HOST_MODE_11AX_HE20; 8699 case WLAN_PHYMODE_11AXA_HE40: 8700 return WMI_HOST_MODE_11AX_HE40; 8701 case WLAN_PHYMODE_11AXA_HE80: 8702 return WMI_HOST_MODE_11AX_HE80; 8703 case WLAN_PHYMODE_11AXA_HE80_80: 8704 return WMI_HOST_MODE_11AX_HE80_80; 8705 case WLAN_PHYMODE_11AXA_HE160: 8706 return WMI_HOST_MODE_11AX_HE160; 8707 case WLAN_PHYMODE_11AXG_HE20: 8708 return WMI_HOST_MODE_11AX_HE20_2G; 8709 case WLAN_PHYMODE_11AXG_HE40: 8710 case WLAN_PHYMODE_11AXG_HE40PLUS: 8711 case WLAN_PHYMODE_11AXG_HE40MINUS: 8712 return WMI_HOST_MODE_11AX_HE40_2G; 8713 case WLAN_PHYMODE_11AXG_HE80: 8714 return WMI_HOST_MODE_11AX_HE80_2G; 8715 default: 8716 return wmi_host_to_fw_phymode_11be(host_phymode); 8717 } 8718 } 8719 8720 /* 8721 * convert_host_to_target_ch_width()- map host channel width(enum phy_ch_width) 8722 * to wmi channel width 8723 * @chan_width: Host channel width 8724 * 8725 * Return: wmi channel width 8726 */ 8727 static 8728 wmi_channel_width convert_host_to_target_ch_width(uint32_t chan_width) 8729 { 8730 switch (chan_width) { 8731 case CH_WIDTH_20MHZ: 8732 return WMI_CHAN_WIDTH_20; 8733 case CH_WIDTH_40MHZ: 8734 return WMI_CHAN_WIDTH_40; 8735 case CH_WIDTH_80MHZ: 8736 return WMI_CHAN_WIDTH_80; 8737 case CH_WIDTH_160MHZ: 8738 return WMI_CHAN_WIDTH_160; 8739 case CH_WIDTH_80P80MHZ: 8740 return WMI_CHAN_WIDTH_80P80; 8741 case CH_WIDTH_5MHZ: 8742 return WMI_CHAN_WIDTH_5; 8743 case CH_WIDTH_10MHZ: 8744 return WMI_CHAN_WIDTH_10; 8745 #ifdef WLAN_FEATURE_11BE 8746 case CH_WIDTH_320MHZ: 8747 return WMI_CHAN_WIDTH_320; 8748 #endif 8749 default: 8750 return WMI_CHAN_WIDTH_MAX; 8751 } 8752 } 8753 8754 /** 8755 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 8756 * command to fw 8757 * @wmi_handle: wmi handle 8758 * @param: pointer to hold spectral config parameter 8759 * 8760 * Return: QDF_STATUS_SUCCESS for success or error code 8761 */ 8762 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 8763 struct vdev_spectral_configure_params *param) 8764 { 8765 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 8766 wmi_buf_t buf; 8767 QDF_STATUS ret; 8768 int32_t len; 8769 8770 len = sizeof(*cmd); 8771 buf = wmi_buf_alloc(wmi_handle, len); 8772 if (!buf) 8773 return QDF_STATUS_E_FAILURE; 8774 8775 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 8776 WMITLV_SET_HDR(&cmd->tlv_header, 8777 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 8778 WMITLV_GET_STRUCT_TLVLEN( 8779 wmi_vdev_spectral_configure_cmd_fixed_param)); 8780 8781 cmd->vdev_id = param->vdev_id; 8782 cmd->spectral_scan_count = param->count; 8783 cmd->spectral_scan_period = param->period; 8784 cmd->spectral_scan_priority = param->spectral_pri; 8785 cmd->spectral_scan_fft_size = param->fft_size; 8786 cmd->spectral_scan_gc_ena = param->gc_enable; 8787 cmd->spectral_scan_restart_ena = param->restart_enable; 8788 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 8789 cmd->spectral_scan_init_delay = param->init_delay; 8790 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 8791 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 8792 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 8793 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 8794 cmd->spectral_scan_rssi_thr = param->rssi_thr; 8795 cmd->spectral_scan_pwr_format = param->pwr_format; 8796 cmd->spectral_scan_rpt_mode = param->rpt_mode; 8797 cmd->spectral_scan_bin_scale = param->bin_scale; 8798 cmd->spectral_scan_dBm_adj = param->dbm_adj; 8799 cmd->spectral_scan_chn_mask = param->chn_mask; 8800 cmd->spectral_scan_mode = param->mode; 8801 cmd->spectral_scan_center_freq1 = param->center_freq1; 8802 cmd->spectral_scan_center_freq2 = param->center_freq2; 8803 cmd->spectral_scan_chan_width = 8804 convert_host_to_target_ch_width(param->chan_width); 8805 cmd->recapture_sample_on_gain_change = param->fft_recap; 8806 /* Not used, fill with zeros */ 8807 cmd->spectral_scan_chan_freq = 0; 8808 8809 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 8810 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8811 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 8812 8813 if (ret != 0) { 8814 wmi_err("Sending set quiet cmd failed"); 8815 wmi_buf_free(buf); 8816 } 8817 8818 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 8819 wmi_debug("vdev_id: %u spectral_scan_count: %u", 8820 param->vdev_id, param->count); 8821 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 8822 param->period, param->spectral_pri); 8823 wmi_debug("spectral_fft_recapture_cap: %u", param->fft_recap); 8824 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 8825 param->fft_size, param->gc_enable); 8826 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 8827 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 8828 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 8829 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 8830 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 8831 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 8832 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 8833 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 8834 param->rssi_thr, param->pwr_format); 8835 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 8836 param->rpt_mode, param->bin_scale); 8837 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 8838 param->dbm_adj, param->chn_mask); 8839 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 8840 param->mode, param->center_freq1); 8841 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 8842 param->center_freq2, param->chan_freq); 8843 wmi_debug("spectral_scan_chan_width: %u Status: %d", 8844 param->chan_width, ret); 8845 8846 return ret; 8847 } 8848 8849 /** 8850 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 8851 * command to fw 8852 * @wmi_handle: wmi handle 8853 * @param: pointer to hold spectral enable parameter 8854 * 8855 * Return: QDF_STATUS_SUCCESS for success or error code 8856 */ 8857 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 8858 struct vdev_spectral_enable_params *param) 8859 { 8860 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 8861 wmi_buf_t buf; 8862 QDF_STATUS ret; 8863 int32_t len; 8864 8865 len = sizeof(*cmd); 8866 buf = wmi_buf_alloc(wmi_handle, len); 8867 if (!buf) 8868 return QDF_STATUS_E_FAILURE; 8869 8870 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 8871 WMITLV_SET_HDR(&cmd->tlv_header, 8872 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 8873 WMITLV_GET_STRUCT_TLVLEN( 8874 wmi_vdev_spectral_enable_cmd_fixed_param)); 8875 8876 cmd->vdev_id = param->vdev_id; 8877 8878 if (param->active_valid) { 8879 cmd->trigger_cmd = param->active ? 1 : 2; 8880 /* 1: Trigger, 2: Clear Trigger */ 8881 } else { 8882 cmd->trigger_cmd = 0; /* 0: Ignore */ 8883 } 8884 8885 if (param->enabled_valid) { 8886 cmd->enable_cmd = param->enabled ? 1 : 2; 8887 /* 1: Enable 2: Disable */ 8888 } else { 8889 cmd->enable_cmd = 0; /* 0: Ignore */ 8890 } 8891 cmd->spectral_scan_mode = param->mode; 8892 8893 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 8894 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 8895 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 8896 8897 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 8898 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8899 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 8900 8901 if (ret != 0) { 8902 wmi_err("Sending scan enable CMD failed"); 8903 wmi_buf_free(buf); 8904 } 8905 8906 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 8907 ret); 8908 8909 return ret; 8910 } 8911 8912 #ifdef WLAN_CONV_SPECTRAL_ENABLE 8913 static QDF_STATUS 8914 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 8915 wmi_unified_t wmi_handle, 8916 uint8_t *event, struct spectral_startscan_resp_params *param) 8917 { 8918 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8919 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 8920 8921 if (!wmi_handle) { 8922 wmi_err("WMI handle is null"); 8923 return QDF_STATUS_E_INVAL; 8924 } 8925 8926 if (!event) { 8927 wmi_err("WMI event is null"); 8928 return QDF_STATUS_E_INVAL; 8929 } 8930 8931 if (!param) { 8932 wmi_err("Spectral startscan response params is null"); 8933 return QDF_STATUS_E_INVAL; 8934 } 8935 8936 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8937 if (!param_buf) 8938 return QDF_STATUS_E_INVAL; 8939 8940 ev = param_buf->fixed_param; 8941 if (!ev) 8942 return QDF_STATUS_E_INVAL; 8943 8944 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 8945 wmi_handle, 8946 ev->pdev_id); 8947 param->smode = ev->spectral_scan_mode; 8948 param->num_fft_bin_index = param_buf->num_fft_bin_index; 8949 param->num_det_info = param_buf->num_det_info; 8950 8951 wmi_debug("pdev id:%u smode:%u num_fft_bin_index:%u num_det_info:%u", 8952 ev->pdev_id, ev->spectral_scan_mode, 8953 param_buf->num_fft_bin_index, param_buf->num_det_info); 8954 8955 return QDF_STATUS_SUCCESS; 8956 } 8957 8958 static QDF_STATUS 8959 extract_pdev_sscan_fft_bin_index_tlv( 8960 wmi_unified_t wmi_handle, uint8_t *event, 8961 struct spectral_fft_bin_markers_160_165mhz *param) 8962 { 8963 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8964 wmi_pdev_sscan_fft_bin_index *ev; 8965 8966 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8967 if (!param_buf) 8968 return QDF_STATUS_E_INVAL; 8969 8970 ev = param_buf->fft_bin_index; 8971 if (!ev) 8972 return QDF_STATUS_E_INVAL; 8973 8974 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 8975 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 8976 param->start_pri80 + 1; 8977 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 8978 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 8979 param->start_sec80 + 1; 8980 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 8981 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 8982 param->start_5mhz + 1; 8983 param->is_valid = true; 8984 8985 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 8986 param->start_pri80, param->num_pri80, 8987 param->start_sec80, param->num_sec80, 8988 param->start_5mhz, param->num_5mhz); 8989 8990 return QDF_STATUS_SUCCESS; 8991 } 8992 8993 /** 8994 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 8995 * for a spectral scan session 8996 * @wmi_handle: handle to WMI. 8997 * @event: Event buffer 8998 * @chan_info: Spectral session channel information data structure to be filled 8999 * by this API 9000 * 9001 * Return: QDF_STATUS of operation 9002 */ 9003 static QDF_STATUS 9004 extract_pdev_spectral_session_chan_info_tlv( 9005 wmi_unified_t wmi_handle, void *event, 9006 struct spectral_session_chan_info *chan_info) 9007 { 9008 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 9009 wmi_pdev_sscan_chan_info *chan_info_tlv; 9010 9011 if (!param_buf) { 9012 wmi_err("param_buf is NULL"); 9013 return QDF_STATUS_E_NULL_VALUE; 9014 } 9015 9016 if (!chan_info) { 9017 wmi_err("chan_info is NULL"); 9018 return QDF_STATUS_E_NULL_VALUE; 9019 } 9020 9021 chan_info_tlv = param_buf->chan_info; 9022 if (!chan_info_tlv) { 9023 wmi_err("chan_info tlv is not present in the event"); 9024 return QDF_STATUS_E_NULL_VALUE; 9025 } 9026 9027 wmi_debug("operating_pri20_freq:%u operating_cfreq1:%u" 9028 "operating_cfreq2:%u operating_bw:%u" 9029 "operating_puncture_20mhz_bitmap:%u" 9030 "sscan_cfreq1:%u sscan_cfreq2:%u" 9031 "sscan_bw:%u sscan_puncture_20mhz_bitmap:%u", 9032 chan_info_tlv->operating_pri20_freq, 9033 chan_info_tlv->operating_cfreq1, 9034 chan_info_tlv->operating_cfreq2, chan_info_tlv->operating_bw, 9035 chan_info_tlv->operating_puncture_20mhz_bitmap, 9036 chan_info_tlv->sscan_cfreq1, chan_info_tlv->sscan_cfreq2, 9037 chan_info_tlv->sscan_bw, 9038 chan_info_tlv->sscan_puncture_20mhz_bitmap); 9039 9040 chan_info->operating_pri20_freq = 9041 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 9042 chan_info->operating_cfreq1 = 9043 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 9044 chan_info->operating_cfreq2 = 9045 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 9046 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 9047 chan_info->operating_puncture_20mhz_bitmap = 9048 chan_info_tlv->operating_puncture_20mhz_bitmap; 9049 9050 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 9051 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 9052 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 9053 chan_info->sscan_puncture_20mhz_bitmap = 9054 chan_info_tlv->sscan_puncture_20mhz_bitmap; 9055 9056 return QDF_STATUS_SUCCESS; 9057 } 9058 9059 static QDF_STATUS 9060 extract_pdev_spectral_session_detector_info_tlv( 9061 wmi_unified_t wmi_handle, void *event, 9062 struct spectral_session_det_info *det_info, uint8_t idx) 9063 { 9064 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 9065 wmi_pdev_sscan_per_detector_info *det_info_tlv; 9066 9067 if (!param_buf) { 9068 wmi_err("param_buf is NULL"); 9069 return QDF_STATUS_E_NULL_VALUE; 9070 } 9071 9072 if (!det_info) { 9073 wmi_err("chan_info is NULL"); 9074 return QDF_STATUS_E_NULL_VALUE; 9075 } 9076 9077 if (!param_buf->det_info) { 9078 wmi_err("det_info tlv is not present in the event"); 9079 return QDF_STATUS_E_NULL_VALUE; 9080 } 9081 9082 if (idx >= param_buf->num_det_info) { 9083 wmi_err("det_info index(%u) is greater than or equal to %u", 9084 idx, param_buf->num_det_info); 9085 return QDF_STATUS_E_FAILURE; 9086 } 9087 9088 det_info_tlv = ¶m_buf->det_info[idx]; 9089 9090 wmi_debug("det_info_idx: %u detector_id:%u start_freq:%u end_freq:%u", 9091 idx, det_info_tlv->detector_id, 9092 det_info_tlv->start_freq, det_info_tlv->end_freq); 9093 9094 det_info->det_id = det_info_tlv->detector_id; 9095 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 9096 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 9097 9098 return QDF_STATUS_SUCCESS; 9099 } 9100 9101 /** 9102 * extract_spectral_caps_fixed_param_tlv() - Extract fixed params from Spectral 9103 * capabilities WMI event 9104 * @wmi_handle: handle to WMI. 9105 * @event: Event buffer 9106 * @params: Spectral capabilities event parameters data structure to be filled 9107 * by this API 9108 * 9109 * Return: QDF_STATUS of operation 9110 */ 9111 static QDF_STATUS 9112 extract_spectral_caps_fixed_param_tlv( 9113 wmi_unified_t wmi_handle, void *event, 9114 struct spectral_capabilities_event_params *params) 9115 { 9116 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9117 9118 if (!param_buf) { 9119 wmi_err("param_buf is NULL"); 9120 return QDF_STATUS_E_NULL_VALUE; 9121 } 9122 9123 if (!params) { 9124 wmi_err("event parameters is NULL"); 9125 return QDF_STATUS_E_NULL_VALUE; 9126 } 9127 9128 params->num_sscan_bw_caps = param_buf->num_sscan_bw_caps; 9129 params->num_fft_size_caps = param_buf->num_fft_size_caps; 9130 9131 wmi_debug("num_sscan_bw_caps:%u num_fft_size_caps:%u", 9132 params->num_sscan_bw_caps, params->num_fft_size_caps); 9133 9134 return QDF_STATUS_SUCCESS; 9135 } 9136 9137 /** 9138 * extract_spectral_scan_bw_caps_tlv() - Extract bandwidth caps from 9139 * Spectral capabilities WMI event 9140 * @wmi_handle: handle to WMI. 9141 * @event: Event buffer 9142 * @bw_caps: Data structure to be populated by this API after extraction 9143 * 9144 * Return: QDF_STATUS of operation 9145 */ 9146 static QDF_STATUS 9147 extract_spectral_scan_bw_caps_tlv( 9148 wmi_unified_t wmi_handle, void *event, 9149 struct spectral_scan_bw_capabilities *bw_caps) 9150 { 9151 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9152 int idx; 9153 9154 if (!param_buf) { 9155 wmi_err("param_buf is NULL"); 9156 return QDF_STATUS_E_NULL_VALUE; 9157 } 9158 9159 if (!bw_caps) { 9160 wmi_err("bw_caps is null"); 9161 return QDF_STATUS_E_NULL_VALUE; 9162 } 9163 9164 for (idx = 0; idx < param_buf->num_sscan_bw_caps; idx++) { 9165 bw_caps[idx].pdev_id = 9166 wmi_handle->ops->convert_pdev_id_target_to_host( 9167 wmi_handle, 9168 param_buf->sscan_bw_caps[idx].pdev_id); 9169 bw_caps[idx].smode = param_buf->sscan_bw_caps[idx].sscan_mode; 9170 bw_caps[idx].operating_bw = wmi_map_ch_width( 9171 param_buf->sscan_bw_caps[idx].operating_bw); 9172 bw_caps[idx].supported_bws = 9173 param_buf->sscan_bw_caps[idx].supported_flags; 9174 9175 wmi_debug("bw_caps[%u]:: pdev_id:%u smode:%u" 9176 "operating_bw:%u supported_flags:0x%x", 9177 idx, param_buf->sscan_bw_caps[idx].pdev_id, 9178 param_buf->sscan_bw_caps[idx].sscan_mode, 9179 param_buf->sscan_bw_caps[idx].operating_bw, 9180 param_buf->sscan_bw_caps[idx].supported_flags); 9181 } 9182 9183 return QDF_STATUS_SUCCESS; 9184 } 9185 9186 /** 9187 * extract_spectral_fft_size_caps_tlv() - Extract FFT size caps from 9188 * Spectral capabilities WMI event 9189 * @wmi_handle: handle to WMI. 9190 * @event: Event buffer 9191 * @fft_size_caps: Data structure to be populated by this API after extraction 9192 * 9193 * Return: QDF_STATUS of operation 9194 */ 9195 static QDF_STATUS 9196 extract_spectral_fft_size_caps_tlv( 9197 wmi_unified_t wmi_handle, void *event, 9198 struct spectral_fft_size_capabilities *fft_size_caps) 9199 { 9200 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9201 int idx; 9202 9203 if (!param_buf) { 9204 wmi_err("param_buf is NULL"); 9205 return QDF_STATUS_E_NULL_VALUE; 9206 } 9207 9208 if (!fft_size_caps) { 9209 wmi_err("fft size caps is NULL"); 9210 return QDF_STATUS_E_NULL_VALUE; 9211 } 9212 9213 for (idx = 0; idx < param_buf->num_fft_size_caps; idx++) { 9214 fft_size_caps[idx].pdev_id = 9215 wmi_handle->ops->convert_pdev_id_target_to_host( 9216 wmi_handle, 9217 param_buf->fft_size_caps[idx].pdev_id); 9218 fft_size_caps[idx].sscan_bw = wmi_map_ch_width( 9219 param_buf->fft_size_caps[idx].sscan_bw); 9220 fft_size_caps[idx].supports_fft_sizes = 9221 param_buf->fft_size_caps[idx].supported_flags; 9222 9223 wmi_debug("fft_size_caps[%u]:: pdev_id:%u sscan_bw:%u" 9224 "supported_flags:0x%x", 9225 idx, param_buf->fft_size_caps[idx].pdev_id, 9226 param_buf->fft_size_caps[idx].sscan_bw, 9227 param_buf->fft_size_caps[idx].supported_flags); 9228 } 9229 9230 return QDF_STATUS_SUCCESS; 9231 } 9232 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 9233 9234 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 9235 static inline void 9236 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 9237 struct thermal_mitigation_params *param) 9238 { 9239 tt_conf->client_id = param->client_id; 9240 tt_conf->priority = param->priority; 9241 } 9242 #else 9243 static inline void 9244 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 9245 struct thermal_mitigation_params *param) 9246 { 9247 } 9248 #endif 9249 9250 /** 9251 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 9252 * @wmi_handle : handle to WMI. 9253 * @param : pointer to hold thermal mitigation param 9254 * 9255 * Return: QDF_STATUS_SUCCESS for success or error code 9256 */ 9257 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 9258 wmi_unified_t wmi_handle, 9259 struct thermal_mitigation_params *param) 9260 { 9261 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 9262 wmi_therm_throt_level_config_info *lvl_conf = NULL; 9263 wmi_buf_t buf = NULL; 9264 uint8_t *buf_ptr = NULL; 9265 int error; 9266 int32_t len; 9267 int i; 9268 9269 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 9270 param->num_thermal_conf * 9271 sizeof(wmi_therm_throt_level_config_info); 9272 9273 buf = wmi_buf_alloc(wmi_handle, len); 9274 if (!buf) 9275 return QDF_STATUS_E_NOMEM; 9276 9277 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 9278 9279 /* init fixed params */ 9280 WMITLV_SET_HDR(tt_conf, 9281 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 9282 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 9283 9284 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9285 wmi_handle, 9286 param->pdev_id); 9287 tt_conf->enable = param->enable; 9288 tt_conf->dc = param->dc; 9289 tt_conf->dc_per_event = param->dc_per_event; 9290 tt_conf->therm_throt_levels = param->num_thermal_conf; 9291 wmi_fill_client_id_priority(tt_conf, param); 9292 buf_ptr = (uint8_t *) ++tt_conf; 9293 /* init TLV params */ 9294 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9295 (param->num_thermal_conf * 9296 sizeof(wmi_therm_throt_level_config_info))); 9297 9298 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 9299 for (i = 0; i < param->num_thermal_conf; i++) { 9300 WMITLV_SET_HDR(&lvl_conf->tlv_header, 9301 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 9302 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 9303 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 9304 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 9305 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 9306 lvl_conf->prio = param->levelconf[i].priority; 9307 lvl_conf++; 9308 } 9309 9310 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 9311 error = wmi_unified_cmd_send(wmi_handle, buf, len, 9312 WMI_THERM_THROT_SET_CONF_CMDID); 9313 if (QDF_IS_STATUS_ERROR(error)) { 9314 wmi_buf_free(buf); 9315 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 9316 } 9317 9318 return error; 9319 } 9320 9321 /** 9322 * send_coex_config_cmd_tlv() - send coex config command to fw 9323 * @wmi_handle: wmi handle 9324 * @param: pointer to coex config param 9325 * 9326 * Return: QDF_STATUS_SUCCESS for success or error code 9327 */ 9328 static QDF_STATUS 9329 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 9330 struct coex_config_params *param) 9331 { 9332 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 9333 wmi_buf_t buf; 9334 QDF_STATUS ret; 9335 int32_t len; 9336 9337 len = sizeof(*cmd); 9338 buf = wmi_buf_alloc(wmi_handle, len); 9339 if (!buf) 9340 return QDF_STATUS_E_FAILURE; 9341 9342 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 9343 WMITLV_SET_HDR(&cmd->tlv_header, 9344 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 9345 WMITLV_GET_STRUCT_TLVLEN( 9346 WMI_COEX_CONFIG_CMD_fixed_param)); 9347 9348 cmd->vdev_id = param->vdev_id; 9349 cmd->config_type = param->config_type; 9350 cmd->config_arg1 = param->config_arg1; 9351 cmd->config_arg2 = param->config_arg2; 9352 cmd->config_arg3 = param->config_arg3; 9353 cmd->config_arg4 = param->config_arg4; 9354 cmd->config_arg5 = param->config_arg5; 9355 cmd->config_arg6 = param->config_arg6; 9356 9357 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 9358 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9359 WMI_COEX_CONFIG_CMDID); 9360 9361 if (ret != 0) { 9362 wmi_err("Sending COEX CONFIG CMD failed"); 9363 wmi_buf_free(buf); 9364 } 9365 9366 return ret; 9367 } 9368 9369 /** 9370 * send_coex_multi_config_cmd_tlv() - send coex multiple config command to fw 9371 * @wmi_handle: wmi handle 9372 * @param: pointer to coex multiple config parameters 9373 * 9374 * Return: QDF_STATUS_SUCCESS for success or error code 9375 */ 9376 static QDF_STATUS 9377 send_coex_multi_config_cmd_tlv(wmi_unified_t wmi_handle, 9378 struct coex_multi_config *param) 9379 { 9380 wmi_coex_multiple_config_cmd_fixed_param *cmd; 9381 WMI_COEX_CONFIG_CMD_fixed_param *dst_cfg; 9382 struct coex_config_item *src_cfg; 9383 wmi_buf_t buf; 9384 QDF_STATUS ret; 9385 uint32_t len, i; 9386 uint8_t *buf_ptr; 9387 9388 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9389 param->num_configs * sizeof(*dst_cfg); 9390 buf = wmi_buf_alloc(wmi_handle, len); 9391 if (!buf) 9392 return QDF_STATUS_E_FAILURE; 9393 9394 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9395 cmd = (wmi_coex_multiple_config_cmd_fixed_param *)buf_ptr; 9396 WMITLV_SET_HDR(&cmd->tlv_header, 9397 WMITLV_TAG_STRUC_wmi_coex_multiple_config_cmd_fixed_param, 9398 WMITLV_GET_STRUCT_TLVLEN( 9399 wmi_coex_multiple_config_cmd_fixed_param)); 9400 9401 buf_ptr += sizeof(*cmd); 9402 9403 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9404 sizeof(*dst_cfg) * param->num_configs); 9405 buf_ptr += WMI_TLV_HDR_SIZE; 9406 9407 dst_cfg = (WMI_COEX_CONFIG_CMD_fixed_param *)buf_ptr; 9408 for (i = 0; i < param->num_configs; i++, dst_cfg++) { 9409 src_cfg = ¶m->cfg_items[i]; 9410 WMITLV_SET_HDR(&dst_cfg->tlv_header, 9411 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 9412 WMITLV_GET_STRUCT_TLVLEN( 9413 WMI_COEX_CONFIG_CMD_fixed_param)); 9414 dst_cfg->vdev_id = param->vdev_id; 9415 dst_cfg->config_type = src_cfg->config_type; 9416 dst_cfg->config_arg1 = src_cfg->config_arg1; 9417 dst_cfg->config_arg2 = src_cfg->config_arg2; 9418 dst_cfg->config_arg3 = src_cfg->config_arg3; 9419 dst_cfg->config_arg4 = src_cfg->config_arg4; 9420 dst_cfg->config_arg5 = src_cfg->config_arg5; 9421 dst_cfg->config_arg6 = src_cfg->config_arg6; 9422 } 9423 9424 wmi_mtrace(WMI_COEX_MULTIPLE_CONFIG_CMDID, param->vdev_id, 0); 9425 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9426 WMI_COEX_MULTIPLE_CONFIG_CMDID); 9427 9428 if (QDF_IS_STATUS_ERROR(ret)) { 9429 wmi_err("Sending COEX MULTIPLE CONFIG CMD failed"); 9430 wmi_buf_free(buf); 9431 } 9432 9433 return ret; 9434 } 9435 9436 #ifdef WLAN_FEATURE_DBAM_CONFIG 9437 9438 static enum wmi_coex_dbam_mode_type 9439 map_to_wmi_coex_dbam_mode_type(enum coex_dbam_config_mode mode) 9440 { 9441 switch (mode) { 9442 case COEX_DBAM_ENABLE: 9443 return WMI_COEX_DBAM_ENABLE; 9444 case COEX_DBAM_FORCE_ENABLE: 9445 return WMI_COEX_DBAM_FORCED; 9446 case COEX_DBAM_DISABLE: 9447 default: 9448 return WMI_COEX_DBAM_DISABLE; 9449 } 9450 } 9451 9452 /** 9453 * send_dbam_config_cmd_tlv() - send coex DBAM config command to fw 9454 * @wmi_handle: wmi handle 9455 * @param: pointer to coex dbam config param 9456 * 9457 * Return: QDF_STATUS_SUCCESS for success or error code 9458 */ 9459 static QDF_STATUS 9460 send_dbam_config_cmd_tlv(wmi_unified_t wmi_handle, 9461 struct coex_dbam_config_params *param) 9462 { 9463 wmi_coex_dbam_cmd_fixed_param *cmd; 9464 wmi_buf_t buf; 9465 void *buf_ptr; 9466 QDF_STATUS ret; 9467 int32_t len; 9468 9469 len = sizeof(*cmd); 9470 buf = wmi_buf_alloc(wmi_handle, len); 9471 if (!buf) { 9472 wmi_err_rl("Failed to allocate wmi buffer"); 9473 return QDF_STATUS_E_NOMEM; 9474 } 9475 9476 buf_ptr = wmi_buf_data(buf); 9477 cmd = buf_ptr; 9478 WMITLV_SET_HDR(&cmd->tlv_header, 9479 WMITLV_TAG_STRUC_wmi_coex_dbam_cmd_fixed_param, 9480 WMITLV_GET_STRUCT_TLVLEN( 9481 wmi_coex_dbam_cmd_fixed_param)); 9482 9483 cmd->vdev_id = param->vdev_id; 9484 cmd->dbam_mode = map_to_wmi_coex_dbam_mode_type(param->dbam_mode); 9485 9486 wmi_mtrace(WMI_COEX_DBAM_CMDID, cmd->vdev_id, 0); 9487 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9488 WMI_COEX_DBAM_CMDID); 9489 9490 if (QDF_IS_STATUS_ERROR(ret)) { 9491 wmi_err("Sending DBAM CONFIG CMD failed"); 9492 wmi_buf_free(buf); 9493 return QDF_STATUS_E_FAILURE; 9494 } 9495 9496 return ret; 9497 } 9498 9499 static enum coex_dbam_comp_status 9500 wmi_convert_dbam_comp_status(wmi_coex_dbam_comp_status status) 9501 { 9502 switch (status) { 9503 case WMI_COEX_DBAM_COMP_SUCCESS: 9504 case WMI_COEX_DBAM_COMP_ONGOING: 9505 case WMI_COEX_DBAM_COMP_DELAYED: 9506 return COEX_DBAM_COMP_SUCCESS; 9507 case WMI_COEX_DBAM_COMP_NOT_SUPPORT: 9508 return COEX_DBAM_COMP_NOT_SUPPORT; 9509 case WMI_COEX_DBAM_COMP_INVALID_PARAM: 9510 case WMI_COEX_DBAM_COMP_FAIL: 9511 default: 9512 return COEX_DBAM_COMP_FAIL; 9513 } 9514 } 9515 9516 /** 9517 * extract_dbam_config_resp_event_tlv() - extract dbam complete status event 9518 * @wmi_handle: WMI handle 9519 * @evt_buf: event buffer 9520 * @resp: pointer to coex dbam config response 9521 * 9522 * Return: QDF_STATUS 9523 */ 9524 static QDF_STATUS 9525 extract_dbam_config_resp_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 9526 struct coex_dbam_config_resp *resp) 9527 { 9528 WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *param_buf; 9529 wmi_coex_dbam_complete_event_fixed_param *event; 9530 9531 param_buf = (WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *)evt_buf; 9532 9533 event = param_buf->fixed_param; 9534 9535 resp->dbam_resp = wmi_convert_dbam_comp_status(event->comp_status); 9536 9537 return QDF_STATUS_SUCCESS; 9538 } 9539 #endif 9540 9541 #ifdef WLAN_SUPPORT_TWT 9542 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 9543 target_resource_config *tgt_res_cfg) 9544 { 9545 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 9546 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 9547 } 9548 #else 9549 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 9550 target_resource_config *tgt_res_cfg) 9551 { 9552 resource_cfg->twt_ap_pdev_count = 0; 9553 resource_cfg->twt_ap_sta_count = 0; 9554 } 9555 #endif 9556 9557 #ifdef WLAN_FEATURE_NAN 9558 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 9559 { 9560 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 9561 resource_cfg->host_service_flags, 1); 9562 } 9563 #else 9564 static inline 9565 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 9566 { 9567 } 9568 #endif 9569 9570 #if defined(CONFIG_AFC_SUPPORT) 9571 static 9572 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 9573 target_resource_config *tgt_res_cfg) 9574 { 9575 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_INDOOR_SUPPORT_CHECK_SET( 9576 resource_cfg->host_service_flags, 9577 tgt_res_cfg->afc_indoor_support); 9578 9579 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_OUTDOOR_SUPPORT_CHECK_SET( 9580 resource_cfg->host_service_flags, 9581 tgt_res_cfg->afc_outdoor_support); 9582 } 9583 #else 9584 static 9585 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 9586 target_resource_config *tgt_res_cfg) 9587 { 9588 } 9589 #endif 9590 9591 #ifdef DP_TX_PACKET_INSPECT_FOR_ILP 9592 static inline 9593 void wmi_copy_latency_flowq_support(wmi_resource_config *resource_cfg, 9594 target_resource_config *tgt_res_cfg) 9595 { 9596 if (tgt_res_cfg->tx_ilp_enable) 9597 WMI_RSRC_CFG_FLAGS2_LATENCY_FLOWQ_SUPPORT_SET( 9598 resource_cfg->flags2, 1); 9599 } 9600 #else 9601 static inline 9602 void wmi_copy_latency_flowq_support(wmi_resource_config *resource_cfg, 9603 target_resource_config *tgt_res_cfg) 9604 { 9605 } 9606 #endif 9607 9608 #ifdef MOBILE_DFS_SUPPORT 9609 static inline 9610 void wmi_copy_full_bw_nol_cfg(wmi_resource_config *resource_cfg, 9611 target_resource_config *tgt_res_cfg) 9612 { 9613 WMI_RSRC_CFG_HOST_SERVICE_FLAG_RADAR_FLAGS_FULL_BW_NOL_SET(resource_cfg->host_service_flags, 9614 tgt_res_cfg->is_full_bw_nol_supported); 9615 } 9616 #else 9617 static inline 9618 void wmi_copy_full_bw_nol_cfg(wmi_resource_config *resource_cfg, 9619 target_resource_config *tgt_res_cfg) 9620 { 9621 } 9622 #endif 9623 9624 static 9625 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 9626 target_resource_config *tgt_res_cfg) 9627 { 9628 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 9629 resource_cfg->num_peers = tgt_res_cfg->num_peers; 9630 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 9631 resource_cfg->num_offload_reorder_buffs = 9632 tgt_res_cfg->num_offload_reorder_buffs; 9633 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 9634 resource_cfg->num_tids = tgt_res_cfg->num_tids; 9635 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 9636 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 9637 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 9638 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 9639 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 9640 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 9641 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 9642 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 9643 resource_cfg->scan_max_pending_req = 9644 tgt_res_cfg->scan_max_pending_req; 9645 resource_cfg->bmiss_offload_max_vdev = 9646 tgt_res_cfg->bmiss_offload_max_vdev; 9647 resource_cfg->roam_offload_max_vdev = 9648 tgt_res_cfg->roam_offload_max_vdev; 9649 resource_cfg->roam_offload_max_ap_profiles = 9650 tgt_res_cfg->roam_offload_max_ap_profiles; 9651 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 9652 resource_cfg->num_mcast_table_elems = 9653 tgt_res_cfg->num_mcast_table_elems; 9654 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 9655 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 9656 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 9657 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 9658 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 9659 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 9660 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 9661 resource_cfg->vow_config = tgt_res_cfg->vow_config; 9662 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 9663 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 9664 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 9665 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 9666 resource_cfg->num_tdls_conn_table_entries = 9667 tgt_res_cfg->num_tdls_conn_table_entries; 9668 resource_cfg->beacon_tx_offload_max_vdev = 9669 tgt_res_cfg->beacon_tx_offload_max_vdev; 9670 resource_cfg->num_multicast_filter_entries = 9671 tgt_res_cfg->num_multicast_filter_entries; 9672 resource_cfg->num_wow_filters = 9673 tgt_res_cfg->num_wow_filters; 9674 resource_cfg->num_keep_alive_pattern = 9675 tgt_res_cfg->num_keep_alive_pattern; 9676 resource_cfg->keep_alive_pattern_size = 9677 tgt_res_cfg->keep_alive_pattern_size; 9678 resource_cfg->max_tdls_concurrent_sleep_sta = 9679 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 9680 resource_cfg->max_tdls_concurrent_buffer_sta = 9681 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 9682 resource_cfg->wmi_send_separate = 9683 tgt_res_cfg->wmi_send_separate; 9684 resource_cfg->num_ocb_vdevs = 9685 tgt_res_cfg->num_ocb_vdevs; 9686 resource_cfg->num_ocb_channels = 9687 tgt_res_cfg->num_ocb_channels; 9688 resource_cfg->num_ocb_schedules = 9689 tgt_res_cfg->num_ocb_schedules; 9690 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 9691 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 9692 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 9693 resource_cfg->max_num_dbs_scan_duty_cycle = 9694 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 9695 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 9696 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 9697 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 9698 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 9699 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 9700 /* Deferred AI: Max rnr neighbors supported in multisoc case 9701 * where in SoC can support 6ghz. During WMI init of a SoC 9702 * currently there is no way to figure if another SOC is plugged in 9703 * and it can support 6Ghz. 9704 */ 9705 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 9706 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 9707 resource_cfg->ema_max_profile_period = 9708 tgt_res_cfg->ema_max_profile_period; 9709 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 9710 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 9711 9712 if (tgt_res_cfg->max_ndp_sessions) 9713 resource_cfg->max_ndp_sessions = 9714 tgt_res_cfg->max_ndp_sessions; 9715 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 9716 resource_cfg->num_max_active_vdevs = tgt_res_cfg->num_max_active_vdevs; 9717 resource_cfg->num_max_mlo_link_per_ml_bss = 9718 tgt_res_cfg->num_max_mlo_link_per_ml_bss; 9719 9720 if (tgt_res_cfg->atf_config) 9721 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 9722 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 9723 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 9724 resource_cfg->flag1, 1); 9725 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 9726 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 9727 resource_cfg->flag1, 1); 9728 if (tgt_res_cfg->cce_disable) 9729 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 9730 if (tgt_res_cfg->enable_pci_gen) 9731 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 9732 resource_cfg->flag1, 1); 9733 if (tgt_res_cfg->eapol_minrate_set) { 9734 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 9735 resource_cfg->flag1, 1); 9736 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 9737 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 9738 resource_cfg->flag1, 1); 9739 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 9740 resource_cfg->flag1, 9741 tgt_res_cfg->eapol_minrate_ac_set); 9742 } 9743 } 9744 if (tgt_res_cfg->new_htt_msg_format) { 9745 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 9746 resource_cfg->flag1, 1); 9747 } 9748 9749 if (tgt_res_cfg->peer_unmap_conf_support) 9750 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 9751 resource_cfg->flag1, 1); 9752 9753 if (tgt_res_cfg->tstamp64_en) 9754 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 9755 resource_cfg->flag1, 1); 9756 9757 if (tgt_res_cfg->three_way_coex_config_legacy_en) 9758 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 9759 resource_cfg->flag1, 1); 9760 if (tgt_res_cfg->pktcapture_support) 9761 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 9762 resource_cfg->flag1, 1); 9763 9764 /* 9765 * Control padding using config param/ini of iphdr_pad_config 9766 */ 9767 if (tgt_res_cfg->iphdr_pad_config) 9768 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 9769 resource_cfg->flag1, 1); 9770 9771 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 9772 tgt_res_cfg->ipa_disable); 9773 9774 if (tgt_res_cfg->time_sync_ftm) 9775 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 9776 1); 9777 9778 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 9779 resource_cfg->peer_map_unmap_versions = 9780 tgt_res_cfg->peer_map_unmap_version; 9781 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 9782 if (tgt_res_cfg->re_ul_resp) 9783 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 9784 tgt_res_cfg->re_ul_resp); 9785 9786 /* 9787 * Enable Service Aware Wifi 9788 */ 9789 if (tgt_res_cfg->sawf) 9790 WMI_RSRC_CFG_FLAGS2_SAWF_CONFIG_ENABLE_SET(resource_cfg->flags2, 9791 tgt_res_cfg->sawf); 9792 9793 /* 9794 * Enable ast flow override per peer 9795 */ 9796 resource_cfg->msdu_flow_override_config0 = 0; 9797 WMI_MSDU_FLOW_AST_ENABLE_SET( 9798 resource_cfg->msdu_flow_override_config0, 9799 WMI_CONFIG_MSDU_AST_INDEX_1, 9800 tgt_res_cfg->ast_1_valid_mask_enable); 9801 9802 WMI_MSDU_FLOW_AST_ENABLE_SET( 9803 resource_cfg->msdu_flow_override_config0, 9804 WMI_CONFIG_MSDU_AST_INDEX_2, 9805 tgt_res_cfg->ast_2_valid_mask_enable); 9806 9807 WMI_MSDU_FLOW_AST_ENABLE_SET( 9808 resource_cfg->msdu_flow_override_config0, 9809 WMI_CONFIG_MSDU_AST_INDEX_3, 9810 tgt_res_cfg->ast_3_valid_mask_enable); 9811 9812 /* 9813 * Enable ast flow mask and TID valid mask configurations 9814 */ 9815 resource_cfg->msdu_flow_override_config1 = 0; 9816 9817 /*Enable UDP flow for Ast index 0*/ 9818 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9819 resource_cfg->msdu_flow_override_config1, 9820 WMI_CONFIG_MSDU_AST_INDEX_0, 9821 tgt_res_cfg->ast_0_flow_mask_enable); 9822 9823 /*Enable Non UDP flow for Ast index 1*/ 9824 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9825 resource_cfg->msdu_flow_override_config1, 9826 WMI_CONFIG_MSDU_AST_INDEX_1, 9827 tgt_res_cfg->ast_1_flow_mask_enable); 9828 9829 /*Enable Hi-Priority flow for Ast index 2*/ 9830 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9831 resource_cfg->msdu_flow_override_config1, 9832 WMI_CONFIG_MSDU_AST_INDEX_2, 9833 tgt_res_cfg->ast_2_flow_mask_enable); 9834 9835 /*Enable Low-Priority flow for Ast index 3*/ 9836 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9837 resource_cfg->msdu_flow_override_config1, 9838 WMI_CONFIG_MSDU_AST_INDEX_3, 9839 tgt_res_cfg->ast_3_flow_mask_enable); 9840 9841 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 9842 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 9843 resource_cfg->msdu_flow_override_config1, 9844 tgt_res_cfg->ast_tid_high_mask_enable); 9845 9846 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 9847 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 9848 resource_cfg->msdu_flow_override_config1, 9849 tgt_res_cfg->ast_tid_low_mask_enable); 9850 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 9851 resource_cfg->host_service_flags, 9852 tgt_res_cfg->nan_separate_iface_support); 9853 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 9854 resource_cfg->host_service_flags, 1); 9855 9856 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 9857 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 9858 9859 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 9860 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 9861 resource_cfg->flags2, 1); 9862 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 9863 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 9864 resource_cfg->flags2, 1); 9865 9866 if (tgt_res_cfg->sae_eapol_offload) 9867 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 9868 resource_cfg->host_service_flags, 1); 9869 9870 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 9871 resource_cfg->host_service_flags, 9872 tgt_res_cfg->is_reg_cc_ext_event_supported); 9873 9874 WMI_RSRC_CFG_HOST_SERVICE_FLAG_BANG_RADAR_320M_SUPPORT_SET( 9875 resource_cfg->host_service_flags, 9876 tgt_res_cfg->is_host_dfs_320mhz_bangradar_supported); 9877 9878 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 9879 resource_cfg->host_service_flags, 9880 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 9881 9882 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 9883 resource_cfg->host_service_flags, 9884 tgt_res_cfg->afc_timer_check_disable); 9885 9886 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 9887 resource_cfg->host_service_flags, 9888 tgt_res_cfg->afc_req_id_check_disable); 9889 9890 wmi_copy_afc_deployment_config(resource_cfg, tgt_res_cfg); 9891 9892 wmi_set_nan_channel_support(resource_cfg); 9893 9894 if (tgt_res_cfg->twt_ack_support_cap) 9895 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 9896 resource_cfg->host_service_flags, 1); 9897 9898 if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) 9899 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( 9900 resource_cfg->host_service_flags, 1); 9901 /* 9902 * DP Peer Meta data FW version 9903 */ 9904 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET( 9905 resource_cfg->flags2, 9906 tgt_res_cfg->dp_peer_meta_data_ver); 9907 9908 if (tgt_res_cfg->notify_frame_support) 9909 WMI_RSRC_CFG_FLAGS2_NOTIFY_FRAME_CONFIG_ENABLE_SET( 9910 resource_cfg->flags2, 1); 9911 9912 if (tgt_res_cfg->rf_path) 9913 WMI_RSRC_CFG_FLAGS2_RF_PATH_MODE_SET( 9914 resource_cfg->flags2, tgt_res_cfg->rf_path); 9915 9916 if (tgt_res_cfg->fw_ast_indication_disable) { 9917 WMI_RSRC_CFG_FLAGS2_DISABLE_WDS_PEER_MAP_UNMAP_EVENT_SET 9918 (resource_cfg->flags2, 9919 tgt_res_cfg->fw_ast_indication_disable); 9920 } 9921 9922 wmi_copy_latency_flowq_support(resource_cfg, tgt_res_cfg); 9923 wmi_copy_full_bw_nol_cfg(resource_cfg, tgt_res_cfg); 9924 9925 } 9926 9927 #ifdef FEATURE_SET 9928 /** 9929 * convert_host_to_target_vendor1_req2_version() -Convert host vendor1 9930 * requirement2 version to target vendor1 requirement2 version 9931 * @vendor1_req2_ver: Host vendor1 requirement2 version 9932 * 9933 * Return: Target vendor1 requirement2 version 9934 */ 9935 static WMI_VENDOR1_REQ2_VERSION convert_host_to_target_vendor1_req2_version( 9936 WMI_HOST_VENDOR1_REQ2_VERSION vendor1_req2_ver) 9937 { 9938 switch (vendor1_req2_ver) { 9939 case WMI_HOST_VENDOR1_REQ2_VERSION_3_00: 9940 return WMI_VENDOR1_REQ2_VERSION_3_00; 9941 case WMI_HOST_VENDOR1_REQ2_VERSION_3_01: 9942 return WMI_VENDOR1_REQ2_VERSION_3_01; 9943 case WMI_HOST_VENDOR1_REQ2_VERSION_3_20: 9944 return WMI_VENDOR1_REQ2_VERSION_3_20; 9945 case WMI_HOST_VENDOR1_REQ2_VERSION_3_50: 9946 return WMI_VENDOR1_REQ2_VERSION_3_50; 9947 default: 9948 return WMI_VENDOR1_REQ2_VERSION_3_00; 9949 } 9950 } 9951 9952 /** 9953 * convert_host_to_target_vendor1_req1_version() -Convert host vendor1 9954 * requirement1 version to target vendor1 requirement1 version 9955 * @vendor1_req1_ver: Host vendor1 requirement1 version 9956 * 9957 * Return: Target vendor1 requirement1 version 9958 */ 9959 static WMI_VENDOR1_REQ1_VERSION convert_host_to_target_vendor1_req1_version( 9960 WMI_HOST_VENDOR1_REQ1_VERSION vendor1_req1_ver) 9961 { 9962 switch (vendor1_req1_ver) { 9963 case WMI_HOST_VENDOR1_REQ1_VERSION_3_00: 9964 return WMI_VENDOR1_REQ1_VERSION_3_00; 9965 case WMI_HOST_VENDOR1_REQ1_VERSION_3_01: 9966 return WMI_VENDOR1_REQ1_VERSION_3_01; 9967 case WMI_HOST_VENDOR1_REQ1_VERSION_3_20: 9968 return WMI_VENDOR1_REQ1_VERSION_3_20; 9969 case WMI_HOST_VENDOR1_REQ1_VERSION_3_30: 9970 return WMI_VENDOR1_REQ1_VERSION_3_30; 9971 case WMI_HOST_VENDOR1_REQ1_VERSION_3_40: 9972 return WMI_VENDOR1_REQ1_VERSION_3_40; 9973 case WMI_HOST_VENDOR1_REQ1_VERSION_4_00: 9974 return WMI_VENDOR1_REQ1_VERSION_4_00; 9975 default: 9976 return WMI_VENDOR1_REQ1_VERSION_3_00; 9977 } 9978 } 9979 9980 /** 9981 * convert_host_to_target_wifi_standard() -Convert host wifi standard to 9982 * target wifi standard 9983 * @wifi_standard: Host wifi standard 9984 * 9985 * Return: Target wifi standard 9986 */ 9987 static WMI_WIFI_STANDARD convert_host_to_target_wifi_standard( 9988 WMI_HOST_WIFI_STANDARD wifi_standard) 9989 { 9990 switch (wifi_standard) { 9991 case WMI_HOST_WIFI_STANDARD_4: 9992 return WMI_WIFI_STANDARD_4; 9993 case WMI_HOST_WIFI_STANDARD_5: 9994 return WMI_WIFI_STANDARD_5; 9995 case WMI_HOST_WIFI_STANDARD_6: 9996 return WMI_WIFI_STANDARD_6; 9997 case WMI_HOST_WIFI_STANDARD_6E: 9998 return WMI_WIFI_STANDARD_6E; 9999 case WMI_HOST_WIFI_STANDARD_7: 10000 return WMI_WIFI_STANDARD_7; 10001 default: 10002 return WMI_WIFI_STANDARD_4; 10003 } 10004 } 10005 10006 /** 10007 * convert_host_to_target_band_concurrency() -Convert host band concurrency to 10008 * target band concurrency 10009 * @band_concurrency: Host Band concurrency 10010 * 10011 * Return: Target band concurrency 10012 */ 10013 static WMI_BAND_CONCURRENCY convert_host_to_target_band_concurrency( 10014 WMI_HOST_BAND_CONCURRENCY band_concurrency) 10015 { 10016 switch (band_concurrency) { 10017 case WMI_HOST_BAND_CONCURRENCY_DBS: 10018 return WMI_HOST_DBS; 10019 case WMI_HOST_BAND_CONCURRENCY_DBS_SBS: 10020 return WMI_HOST_DBS_SBS; 10021 default: 10022 return WMI_HOST_NONE; 10023 } 10024 } 10025 10026 /** 10027 * convert_host_to_target_num_antennas() -Convert host num antennas to 10028 * target num antennas 10029 * @num_antennas: Host num antennas 10030 * 10031 * Return: Target num antennas 10032 */ 10033 static WMI_NUM_ANTENNAS convert_host_to_target_num_antennas( 10034 WMI_HOST_NUM_ANTENNAS num_antennas) 10035 { 10036 switch (num_antennas) { 10037 case WMI_HOST_SISO: 10038 return WMI_SISO; 10039 case WMI_HOST_MIMO_2X2: 10040 return WMI_MIMO_2X2; 10041 default: 10042 return WMI_SISO; 10043 } 10044 } 10045 10046 /** 10047 * convert_host_to_target_band_capability() -Convert host band capability to 10048 * target band capability 10049 * @host_band_capability: Host band capability 10050 * 10051 * Return: Target band capability bitmap 10052 */ 10053 static uint8_t 10054 convert_host_to_target_band_capability(uint32_t host_band_capability) 10055 { 10056 uint8_t band_capability; 10057 10058 band_capability = (host_band_capability & WMI_HOST_BAND_CAP_2GHZ) | 10059 (host_band_capability & WMI_HOST_BAND_CAP_5GHZ) | 10060 (host_band_capability & WMI_HOST_BAND_CAP_6GHZ); 10061 return band_capability; 10062 } 10063 10064 /** 10065 * copy_feature_set_info() -Copy feature set info from host to target 10066 * @feature_set_bitmap: Target feature set pointer 10067 * @feature_set: Host feature set structure 10068 * 10069 * Return: None 10070 */ 10071 static inline void copy_feature_set_info(uint32_t *feature_set_bitmap, 10072 struct target_feature_set *feature_set) 10073 { 10074 WMI_NUM_ANTENNAS num_antennas; 10075 WMI_BAND_CONCURRENCY band_concurrency; 10076 WMI_WIFI_STANDARD wifi_standard; 10077 WMI_VENDOR1_REQ1_VERSION vendor1_req1_version; 10078 WMI_VENDOR1_REQ2_VERSION vendor1_req2_version; 10079 uint8_t band_capability; 10080 10081 num_antennas = convert_host_to_target_num_antennas( 10082 feature_set->num_antennas); 10083 band_concurrency = convert_host_to_target_band_concurrency( 10084 feature_set->concurrency_support); 10085 wifi_standard = convert_host_to_target_wifi_standard( 10086 feature_set->wifi_standard); 10087 vendor1_req1_version = convert_host_to_target_vendor1_req1_version( 10088 feature_set->vendor_req_1_version); 10089 vendor1_req2_version = convert_host_to_target_vendor1_req2_version( 10090 feature_set->vendor_req_2_version); 10091 10092 band_capability = 10093 convert_host_to_target_band_capability( 10094 feature_set->band_capability); 10095 10096 WMI_SET_WIFI_STANDARD(feature_set_bitmap, wifi_standard); 10097 WMI_SET_BAND_CONCURRENCY_SUPPORT(feature_set_bitmap, band_concurrency); 10098 WMI_SET_PNO_SCAN_IN_UNASSOC_STATE(feature_set_bitmap, 10099 feature_set->pno_in_unassoc_state); 10100 WMI_SET_PNO_SCAN_IN_ASSOC_STATE(feature_set_bitmap, 10101 feature_set->pno_in_assoc_state); 10102 WMI_SET_TWT_FEATURE_SUPPORT(feature_set_bitmap, 10103 feature_set->enable_twt); 10104 WMI_SET_TWT_REQUESTER(feature_set_bitmap, 10105 feature_set->enable_twt_requester); 10106 WMI_SET_TWT_BROADCAST(feature_set_bitmap, 10107 feature_set->enable_twt_broadcast); 10108 WMI_SET_TWT_FLEXIBLE(feature_set_bitmap, 10109 feature_set->enable_twt_flexible); 10110 WMI_SET_WIFI_OPT_FEATURE_SUPPORT(feature_set_bitmap, 10111 feature_set->enable_wifi_optimizer); 10112 WMI_SET_RFC8325_FEATURE_SUPPORT(feature_set_bitmap, 10113 feature_set->enable_rfc835); 10114 WMI_SET_MHS_5G_SUPPORT(feature_set_bitmap, 10115 feature_set->sap_5g_supported); 10116 WMI_SET_MHS_6G_SUPPORT(feature_set_bitmap, 10117 feature_set->sap_6g_supported); 10118 WMI_SET_MHS_MAX_CLIENTS_SUPPORT(feature_set_bitmap, 10119 feature_set->sap_max_num_clients); 10120 WMI_SET_MHS_SET_COUNTRY_CODE_HAL_SUPPORT( 10121 feature_set_bitmap, 10122 feature_set->set_country_code_hal_supported); 10123 WMI_SET_MHS_GETVALID_CHANNELS_SUPPORT( 10124 feature_set_bitmap, 10125 feature_set->get_valid_channel_supported); 10126 WMI_SET_MHS_DOT11_MODE_SUPPORT(feature_set_bitmap, 10127 feature_set->supported_dot11mode); 10128 WMI_SET_MHS_WPA3_SUPPORT(feature_set_bitmap, 10129 feature_set->sap_wpa3_support); 10130 WMI_SET_VENDOR_REQ_1_VERSION(feature_set_bitmap, vendor1_req1_version); 10131 WMI_SET_ROAMING_HIGH_CU_ROAM_TRIGGER( 10132 feature_set_bitmap, 10133 feature_set->roaming_high_cu_roam_trigger); 10134 WMI_SET_ROAMING_EMERGENCY_TRIGGER( 10135 feature_set_bitmap, 10136 feature_set->roaming_emergency_trigger); 10137 WMI_SET_ROAMING_BTM_TRIGGER(feature_set_bitmap, 10138 feature_set->roaming_btm_trihgger); 10139 WMI_SET_ROAMING_IDLE_TRIGGER(feature_set_bitmap, 10140 feature_set->roaming_idle_trigger); 10141 WMI_SET_ROAMING_WTC_TRIGGER(feature_set_bitmap, 10142 feature_set->roaming_wtc_trigger); 10143 WMI_SET_ROAMING_BTCOEX_TRIGGER(feature_set_bitmap, 10144 feature_set->roaming_btcoex_trigger); 10145 WMI_SET_ROAMING_BTW_WPA_WPA2(feature_set_bitmap, 10146 feature_set->roaming_btw_wpa_wpa2); 10147 WMI_SET_ROAMING_MANAGE_CHAN_LIST_API( 10148 feature_set_bitmap, 10149 feature_set->roaming_manage_chan_list_api); 10150 WMI_SET_ROAMING_ADAPTIVE_11R(feature_set_bitmap, 10151 feature_set->roaming_adaptive_11r); 10152 WMI_SET_ROAMING_CTRL_API_GET_SET(feature_set_bitmap, 10153 feature_set->roaming_ctrl_api_get_set); 10154 WMI_SET_ROAMING_CTRL_API_REASSOC(feature_set_bitmap, 10155 feature_set->roaming_ctrl_api_reassoc); 10156 WMI_SET_ROAMING_CTRL_GET_CU(feature_set_bitmap, 10157 feature_set->roaming_ctrl_get_cu); 10158 WMI_SET_VENDOR_REQ_2_VERSION(feature_set_bitmap, vendor1_req2_version); 10159 WMI_SET_ASSURANCE_DISCONNECT_REASON_API( 10160 feature_set_bitmap, 10161 feature_set->assurance_disconnect_reason_api); 10162 WMI_SET_FRAME_PCAP_LOG_MGMT(feature_set_bitmap, 10163 feature_set->frame_pcap_log_mgmt); 10164 WMI_SET_FRAME_PCAP_LOG_CTRL(feature_set_bitmap, 10165 feature_set->frame_pcap_log_ctrl); 10166 WMI_SET_FRAME_PCAP_LOG_DATA(feature_set_bitmap, 10167 feature_set->frame_pcap_log_data); 10168 WMI_SET_SECURITY_WPA3_SAE_H2E(feature_set_bitmap, 10169 feature_set->security_wpa3_sae_h2e); 10170 WMI_SET_SECURITY_WPA3_SAE_FT(feature_set_bitmap, 10171 feature_set->security_wpa3_sae_ft); 10172 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB( 10173 feature_set_bitmap, 10174 feature_set->security_wpa3_enterp_suitb); 10175 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB_192bit( 10176 feature_set_bitmap, 10177 feature_set->security_wpa3_enterp_suitb_192bit); 10178 WMI_SET_SECURITY_FILS_SHA256(feature_set_bitmap, 10179 feature_set->security_fills_sha_256); 10180 WMI_SET_SECURITY_FILS_SHA384(feature_set_bitmap, 10181 feature_set->security_fills_sha_384); 10182 WMI_SET_SECURITY_FILS_SHA256_FT(feature_set_bitmap, 10183 feature_set->security_fills_sha_256_FT); 10184 WMI_SET_SECURITY_FILS_SHA384_FT(feature_set_bitmap, 10185 feature_set->security_fills_sha_384_FT); 10186 WMI_SET_SECURITY_ENCHANCED_OPEN(feature_set_bitmap, 10187 feature_set->security_enhanced_open); 10188 WMI_SET_NAN_SUPPORT(feature_set_bitmap, feature_set->enable_nan); 10189 WMI_SET_TDLS_SUPPORT(feature_set_bitmap, feature_set->enable_tdls); 10190 WMI_SET_P2P6E_SUPPORT(feature_set_bitmap, feature_set->enable_p2p_6e); 10191 WMI_SET_TDLS_OFFCHAN_SUPPORT(feature_set_bitmap, 10192 feature_set->enable_tdls_offchannel); 10193 WMI_SET_TDLS_CAP_ENHANCE(feature_set_bitmap, 10194 feature_set->enable_tdls_capability_enhance); 10195 WMI_SET_MAX_TDLS_PEERS_SUPPORT(feature_set_bitmap, 10196 feature_set->max_tdls_peers); 10197 WMI_SET_STA_DUAL_P2P_SUPPORT(feature_set_bitmap, 10198 (feature_set->iface_combinations & 10199 MLME_IFACE_STA_DUAL_P2P_SUPPORT) > 0); 10200 WMI_SET_STA_P2P_SUPPORT(feature_set_bitmap, 10201 (feature_set->iface_combinations & 10202 MLME_IFACE_STA_P2P_SUPPORT) > 0); 10203 WMI_SET_STA_SAP_SUPPORT(feature_set_bitmap, 10204 (feature_set->iface_combinations & 10205 MLME_IFACE_STA_SAP_SUPPORT) > 0); 10206 WMI_SET_STA_NAN_SUPPORT(feature_set_bitmap, 10207 (feature_set->iface_combinations & 10208 MLME_IFACE_STA_NAN_SUPPORT) > 0); 10209 WMI_SET_STA_TDLS_SUPPORT(feature_set_bitmap, 10210 (feature_set->iface_combinations & 10211 MLME_IFACE_STA_TDLS_SUPPORT) > 0); 10212 WMI_SET_STA_SAP_P2P_SUPPORT(feature_set_bitmap, 10213 (feature_set->iface_combinations & 10214 MLME_IFACE_STA_SAP_P2P_SUPPORT) > 0); 10215 WMI_SET_STA_SAP_NAN_SUPPORT(feature_set_bitmap, 10216 (feature_set->iface_combinations & 10217 MLME_IFACE_STA_SAP_NAN_SUPPORT) > 0); 10218 WMI_SET_STA_P2P_NAN_SUPPORT(feature_set_bitmap, 10219 (feature_set->iface_combinations & 10220 MLME_IFACE_STA_P2P_NAN_SUPPORT) > 0); 10221 WMI_SET_STA_P2P_TDLS_SUPPORT(feature_set_bitmap, 10222 (feature_set->iface_combinations & 10223 MLME_IFACE_STA_P2P_TDLS_SUPPORT) > 0); 10224 WMI_SET_STA_SAP_TDLS_SUPPORT(feature_set_bitmap, 10225 (feature_set->iface_combinations & 10226 MLME_IFACE_STA_SAP_TDLS_SUPPORT) > 0); 10227 WMI_SET_STA_NAN_TDLS_SUPPORT(feature_set_bitmap, 10228 (feature_set->iface_combinations & 10229 MLME_IFACE_STA_NAN_TDLS_SUPPORT) > 0); 10230 WMI_SET_STA_SAP_P2P_TDLS_SUPPORT(feature_set_bitmap, 10231 (feature_set->iface_combinations & 10232 MLME_IFACE_STA_SAP_P2P_TDLS_SUPPORT) > 0); 10233 WMI_SET_STA_SAP_NAN_TDLS_SUPPORT(feature_set_bitmap, 10234 (feature_set->iface_combinations & 10235 MLME_IFACE_STA_SAP_NAN_TDLS_SUPPORT) > 0); 10236 WMI_SET_STA_P2P_P2P_TDLS_SUPPORT(feature_set_bitmap, 10237 (feature_set->iface_combinations & 10238 MLME_IFACE_STA_P2P_P2P_TDLS_SUPPORT) > 0); 10239 WMI_SET_STA_P2P_NAN_TDLS_SUPPORT(feature_set_bitmap, 10240 (feature_set->iface_combinations & 10241 MLME_IFACE_STA_P2P_NAN_TDLS_SUPPORT) > 0); 10242 WMI_SET_PEER_BIGDATA_GETBSSINFO_API_SUPPORT( 10243 feature_set_bitmap, 10244 feature_set->peer_bigdata_getbssinfo_support); 10245 WMI_SET_PEER_BIGDATA_GETASSOCREJECTINFO_API_SUPPORT( 10246 feature_set_bitmap, 10247 feature_set->peer_bigdata_assocreject_info_support); 10248 WMI_SET_PEER_BIGDATA_GETSTAINFO_API_SUPPORT( 10249 feature_set_bitmap, 10250 feature_set->peer_getstainfo_support); 10251 WMI_SET_FEATURE_SET_VERSION(feature_set_bitmap, 10252 feature_set->feature_set_version); 10253 WMI_SET_NUM_ANTENNAS(feature_set_bitmap, num_antennas); 10254 WMI_SET_HOST_BAND_CAP(feature_set_bitmap, band_capability); 10255 WMI_SET_STA_DUMP_SUPPORT(feature_set_bitmap, 10256 feature_set->sta_dump_support); 10257 } 10258 10259 /** 10260 * feature_set_cmd_send_tlv() -Send feature set command 10261 * @wmi_handle: WMI handle 10262 * @feature_set: Feature set structure 10263 * 10264 * Return: QDF_STATUS_SUCCESS on success else return failure 10265 */ 10266 static QDF_STATUS feature_set_cmd_send_tlv( 10267 struct wmi_unified *wmi_handle, 10268 struct target_feature_set *feature_set) 10269 { 10270 wmi_pdev_featureset_cmd_fixed_param *cmd; 10271 wmi_buf_t buf; 10272 uint16_t len; 10273 QDF_STATUS ret; 10274 uint8_t *buf_ptr; 10275 uint32_t *feature_set_bitmap; 10276 10277 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10278 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t); 10279 buf = wmi_buf_alloc(wmi_handle, len); 10280 10281 if (!buf) 10282 return QDF_STATUS_E_NOMEM; 10283 10284 wmi_debug("Send feature set param"); 10285 10286 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10287 10288 cmd = (wmi_pdev_featureset_cmd_fixed_param *)wmi_buf_data(buf); 10289 10290 WMITLV_SET_HDR(&cmd->tlv_header, 10291 WMITLV_TAG_STRUC_wmi_pdev_featureset_cmd_fixed_param, 10292 WMITLV_GET_STRUCT_TLVLEN( 10293 wmi_pdev_featureset_cmd_fixed_param)); 10294 10295 feature_set_bitmap = (uint32_t *)(buf_ptr + sizeof(*cmd) + 10296 WMI_TLV_HDR_SIZE); 10297 WMITLV_SET_HDR(buf_ptr + sizeof(*cmd), WMITLV_TAG_ARRAY_UINT32, 10298 (WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t))); 10299 copy_feature_set_info(feature_set_bitmap, feature_set); 10300 10301 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10302 feature_set_bitmap, 10303 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * 10304 sizeof(uint32_t)); 10305 10306 wmi_mtrace(WMI_PDEV_FEATURESET_CMDID, NO_SESSION, 0); 10307 10308 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10309 WMI_PDEV_FEATURESET_CMDID); 10310 if (QDF_IS_STATUS_ERROR(ret)) 10311 wmi_buf_free(buf); 10312 10313 return ret; 10314 } 10315 #endif 10316 10317 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 10318 * @wmi_handle: pointer to wmi handle 10319 * @buf_ptr: pointer to current position in init command buffer 10320 * @len: pointer to length. This will be updated with current length of cmd 10321 * @param: point host parameters for init command 10322 * 10323 * Return: Updated pointer of buf_ptr. 10324 */ 10325 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 10326 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 10327 { 10328 uint16_t idx; 10329 10330 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 10331 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 10332 wmi_pdev_band_to_mac *band_to_mac; 10333 10334 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 10335 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 10336 sizeof(wmi_resource_config) + 10337 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 10338 sizeof(wlan_host_memory_chunk))); 10339 10340 WMITLV_SET_HDR(&hw_mode->tlv_header, 10341 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 10342 (WMITLV_GET_STRUCT_TLVLEN 10343 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 10344 10345 hw_mode->hw_mode_index = param->hw_mode_id; 10346 hw_mode->num_band_to_mac = param->num_band_to_mac; 10347 10348 buf_ptr = (uint8_t *) (hw_mode + 1); 10349 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 10350 WMI_TLV_HDR_SIZE); 10351 for (idx = 0; idx < param->num_band_to_mac; idx++) { 10352 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 10353 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 10354 WMITLV_GET_STRUCT_TLVLEN 10355 (wmi_pdev_band_to_mac)); 10356 band_to_mac[idx].pdev_id = 10357 wmi_handle->ops->convert_pdev_id_host_to_target( 10358 wmi_handle, 10359 param->band_to_mac[idx].pdev_id); 10360 band_to_mac[idx].start_freq = 10361 param->band_to_mac[idx].start_freq; 10362 band_to_mac[idx].end_freq = 10363 param->band_to_mac[idx].end_freq; 10364 } 10365 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 10366 (param->num_band_to_mac * 10367 sizeof(wmi_pdev_band_to_mac)) + 10368 WMI_TLV_HDR_SIZE; 10369 10370 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10371 (param->num_band_to_mac * 10372 sizeof(wmi_pdev_band_to_mac))); 10373 } 10374 10375 return buf_ptr; 10376 } 10377 10378 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 10379 wmi_init_cmd_fixed_param *cmd) 10380 { 10381 int num_allowlist; 10382 wmi_abi_version my_vers; 10383 10384 num_allowlist = sizeof(version_whitelist) / 10385 sizeof(wmi_whitelist_version_info); 10386 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 10387 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 10388 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 10389 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 10390 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 10391 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 10392 10393 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 10394 &my_vers, 10395 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 10396 &cmd->host_abi_vers); 10397 10398 qdf_debug("INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 10399 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 10400 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 10401 cmd->host_abi_vers.abi_version_ns_0, 10402 cmd->host_abi_vers.abi_version_ns_1, 10403 cmd->host_abi_vers.abi_version_ns_2, 10404 cmd->host_abi_vers.abi_version_ns_3); 10405 10406 /* Save version sent from host - 10407 * Will be used to check ready event 10408 */ 10409 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 10410 sizeof(wmi_abi_version)); 10411 } 10412 10413 /* 10414 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 10415 * @wmi_handle: Pointer to WMi handle 10416 * @ie_data: Pointer for ie data 10417 * 10418 * This function sends action frame tb ppdu cfg to FW 10419 * 10420 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10421 * 10422 */ 10423 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 10424 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 10425 { 10426 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 10427 wmi_buf_t buf; 10428 uint8_t *buf_ptr; 10429 uint32_t len, frm_len_aligned; 10430 QDF_STATUS ret; 10431 10432 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 10433 /* Allocate memory for the WMI command */ 10434 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 10435 10436 buf = wmi_buf_alloc(wmi_handle, len); 10437 if (!buf) 10438 return QDF_STATUS_E_NOMEM; 10439 10440 buf_ptr = wmi_buf_data(buf); 10441 qdf_mem_zero(buf_ptr, len); 10442 10443 /* Populate the WMI command */ 10444 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 10445 10446 WMITLV_SET_HDR(&cmd->tlv_header, 10447 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 10448 WMITLV_GET_STRUCT_TLVLEN( 10449 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 10450 cmd->enable = cfg_msg->cfg; 10451 cmd->data_len = cfg_msg->frm_len; 10452 10453 buf_ptr += sizeof(*cmd); 10454 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 10455 buf_ptr += WMI_TLV_HDR_SIZE; 10456 10457 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 10458 10459 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10460 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 10461 if (QDF_IS_STATUS_ERROR(ret)) { 10462 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 10463 wmi_buf_free(buf); 10464 } 10465 10466 return ret; 10467 } 10468 10469 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 10470 { 10471 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10472 wmi_service_ready_event_fixed_param *ev; 10473 10474 10475 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10476 10477 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 10478 if (!ev) 10479 return QDF_STATUS_E_FAILURE; 10480 10481 /*Save fw version from service ready message */ 10482 /*This will be used while sending INIT message */ 10483 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10484 sizeof(wmi_handle->fw_abi_version)); 10485 10486 return QDF_STATUS_SUCCESS; 10487 } 10488 10489 /** 10490 * check_and_update_fw_version_cmd_tlv() - save fw version 10491 * @wmi_handle: pointer to wmi handle 10492 * @evt_buf: pointer to the event buffer 10493 * 10494 * This function extracts and saves the firmware WMI ABI version 10495 * 10496 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10497 * 10498 */ 10499 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 10500 void *evt_buf) 10501 { 10502 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10503 wmi_ready_event_fixed_param *ev = NULL; 10504 10505 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10506 ev = param_buf->fixed_param; 10507 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 10508 &wmi_handle->final_abi_vers, 10509 &ev->fw_abi_vers)) { 10510 /* 10511 * Error: Our host version and the given firmware version 10512 * are incompatible. 10513 **/ 10514 wmi_debug("Error: Incompatible WMI version." 10515 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 10516 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 10517 abi_version_0), 10518 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 10519 abi_version_0), 10520 wmi_handle->final_abi_vers.abi_version_ns_0, 10521 wmi_handle->final_abi_vers.abi_version_ns_1, 10522 wmi_handle->final_abi_vers.abi_version_ns_2, 10523 wmi_handle->final_abi_vers.abi_version_ns_3, 10524 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 10525 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 10526 ev->fw_abi_vers.abi_version_ns_0, 10527 ev->fw_abi_vers.abi_version_ns_1, 10528 ev->fw_abi_vers.abi_version_ns_2, 10529 ev->fw_abi_vers.abi_version_ns_3); 10530 10531 return QDF_STATUS_E_FAILURE; 10532 } 10533 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 10534 sizeof(wmi_abi_version)); 10535 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10536 sizeof(wmi_abi_version)); 10537 10538 return QDF_STATUS_SUCCESS; 10539 } 10540 10541 /** 10542 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 10543 * @wmi_handle: wmi handle 10544 * @event: Event received from FW 10545 * @len: Length of the event 10546 * 10547 * Enables the low frequency events and disables the high frequency 10548 * events. Bit 17 indicates if the event if low/high frequency. 10549 * 1 - high frequency, 0 - low frequency 10550 * 10551 * Return: QDF_STATUS_SUCCESS for success or error code 10552 */ 10553 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 10554 uint8_t *event, 10555 uint32_t len) 10556 { 10557 uint32_t num_of_diag_events_logs; 10558 wmi_diag_event_log_config_fixed_param *cmd; 10559 wmi_buf_t buf; 10560 uint8_t *buf_ptr; 10561 uint32_t *cmd_args, *evt_args; 10562 uint32_t buf_len, i; 10563 10564 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 10565 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 10566 10567 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 10568 10569 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 10570 if (!param_buf) { 10571 wmi_err("Invalid log supported event buffer"); 10572 return QDF_STATUS_E_INVAL; 10573 } 10574 wmi_event = param_buf->fixed_param; 10575 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 10576 10577 if (num_of_diag_events_logs > 10578 param_buf->num_diag_events_logs_list) { 10579 wmi_err("message number of events %d is more than tlv hdr content %d", 10580 num_of_diag_events_logs, 10581 param_buf->num_diag_events_logs_list); 10582 return QDF_STATUS_E_INVAL; 10583 } 10584 10585 evt_args = param_buf->diag_events_logs_list; 10586 if (!evt_args) { 10587 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 10588 num_of_diag_events_logs); 10589 return QDF_STATUS_E_INVAL; 10590 } 10591 10592 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 10593 10594 /* Free any previous allocation */ 10595 if (wmi_handle->events_logs_list) { 10596 qdf_mem_free(wmi_handle->events_logs_list); 10597 wmi_handle->events_logs_list = NULL; 10598 } 10599 10600 if (num_of_diag_events_logs > 10601 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 10602 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 10603 QDF_ASSERT(0); 10604 return QDF_STATUS_E_INVAL; 10605 } 10606 /* Store the event list for run time enable/disable */ 10607 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 10608 sizeof(uint32_t)); 10609 if (!wmi_handle->events_logs_list) 10610 return QDF_STATUS_E_NOMEM; 10611 10612 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 10613 10614 /* Prepare the send buffer */ 10615 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10616 (num_of_diag_events_logs * sizeof(uint32_t)); 10617 10618 buf = wmi_buf_alloc(wmi_handle, buf_len); 10619 if (!buf) { 10620 qdf_mem_free(wmi_handle->events_logs_list); 10621 wmi_handle->events_logs_list = NULL; 10622 return QDF_STATUS_E_NOMEM; 10623 } 10624 10625 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10626 buf_ptr = (uint8_t *) cmd; 10627 10628 WMITLV_SET_HDR(&cmd->tlv_header, 10629 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10630 WMITLV_GET_STRUCT_TLVLEN( 10631 wmi_diag_event_log_config_fixed_param)); 10632 10633 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 10634 10635 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10636 10637 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10638 (num_of_diag_events_logs * sizeof(uint32_t))); 10639 10640 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10641 10642 /* Populate the events */ 10643 for (i = 0; i < num_of_diag_events_logs; i++) { 10644 /* Low freq (0) - Enable (1) the event 10645 * High freq (1) - Disable (0) the event 10646 */ 10647 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 10648 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 10649 /* Set the event ID */ 10650 WMI_DIAG_ID_SET(cmd_args[i], 10651 WMI_DIAG_ID_GET(evt_args[i])); 10652 /* Set the type */ 10653 WMI_DIAG_TYPE_SET(cmd_args[i], 10654 WMI_DIAG_TYPE_GET(evt_args[i])); 10655 /* Storing the event/log list in WMI */ 10656 wmi_handle->events_logs_list[i] = evt_args[i]; 10657 } 10658 10659 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10660 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 10661 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10662 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10663 wmi_buf_free(buf); 10664 /* Not clearing events_logs_list, though wmi cmd failed. 10665 * Host can still have this list 10666 */ 10667 return QDF_STATUS_E_INVAL; 10668 } 10669 10670 return 0; 10671 } 10672 10673 /** 10674 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 10675 * @wmi_handle: wmi handle 10676 * @start_log: Start logging related parameters 10677 * 10678 * Send the command to the FW based on which specific logging of diag 10679 * event/log id can be started/stopped 10680 * 10681 * Return: None 10682 */ 10683 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 10684 struct wmi_wifi_start_log *start_log) 10685 { 10686 wmi_diag_event_log_config_fixed_param *cmd; 10687 wmi_buf_t buf; 10688 uint8_t *buf_ptr; 10689 uint32_t len, count, log_level, i; 10690 uint32_t *cmd_args; 10691 uint32_t total_len; 10692 count = 0; 10693 10694 if (!wmi_handle->events_logs_list) { 10695 wmi_debug("Not received event/log list from FW, yet"); 10696 return QDF_STATUS_E_NOMEM; 10697 } 10698 /* total_len stores the number of events where BITS 17 and 18 are set. 10699 * i.e., events of high frequency (17) and for extended debugging (18) 10700 */ 10701 total_len = 0; 10702 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10703 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 10704 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 10705 total_len++; 10706 } 10707 10708 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10709 (total_len * sizeof(uint32_t)); 10710 10711 buf = wmi_buf_alloc(wmi_handle, len); 10712 if (!buf) 10713 return QDF_STATUS_E_NOMEM; 10714 10715 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10716 buf_ptr = (uint8_t *) cmd; 10717 10718 WMITLV_SET_HDR(&cmd->tlv_header, 10719 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10720 WMITLV_GET_STRUCT_TLVLEN( 10721 wmi_diag_event_log_config_fixed_param)); 10722 10723 cmd->num_of_diag_events_logs = total_len; 10724 10725 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10726 10727 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10728 (total_len * sizeof(uint32_t))); 10729 10730 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10731 10732 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 10733 log_level = 1; 10734 else 10735 log_level = 0; 10736 10737 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 10738 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10739 uint32_t val = wmi_handle->events_logs_list[i]; 10740 if ((WMI_DIAG_FREQUENCY_GET(val)) && 10741 (WMI_DIAG_EXT_FEATURE_GET(val))) { 10742 10743 WMI_DIAG_ID_SET(cmd_args[count], 10744 WMI_DIAG_ID_GET(val)); 10745 WMI_DIAG_TYPE_SET(cmd_args[count], 10746 WMI_DIAG_TYPE_GET(val)); 10747 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 10748 log_level); 10749 wmi_debug("Idx:%d, val:%x", i, val); 10750 count++; 10751 } 10752 } 10753 10754 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10755 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10756 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10757 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10758 wmi_buf_free(buf); 10759 return QDF_STATUS_E_INVAL; 10760 } 10761 10762 return QDF_STATUS_SUCCESS; 10763 } 10764 10765 /** 10766 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 10767 * @wmi_handle: WMI handle 10768 * 10769 * This function is used to send the flush command to the FW, 10770 * that will flush the fw logs that are residue in the FW 10771 * 10772 * Return: None 10773 */ 10774 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 10775 { 10776 wmi_debug_mesg_flush_fixed_param *cmd; 10777 wmi_buf_t buf; 10778 int len = sizeof(*cmd); 10779 QDF_STATUS ret; 10780 10781 buf = wmi_buf_alloc(wmi_handle, len); 10782 if (!buf) 10783 return QDF_STATUS_E_NOMEM; 10784 10785 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 10786 WMITLV_SET_HDR(&cmd->tlv_header, 10787 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 10788 WMITLV_GET_STRUCT_TLVLEN( 10789 wmi_debug_mesg_flush_fixed_param)); 10790 cmd->reserved0 = 0; 10791 10792 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 10793 ret = wmi_unified_cmd_send(wmi_handle, 10794 buf, 10795 len, 10796 WMI_DEBUG_MESG_FLUSH_CMDID); 10797 if (QDF_IS_STATUS_ERROR(ret)) { 10798 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 10799 wmi_buf_free(buf); 10800 return QDF_STATUS_E_INVAL; 10801 } 10802 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 10803 10804 return ret; 10805 } 10806 10807 #ifdef BIG_ENDIAN_HOST 10808 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10809 /** 10810 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 10811 * @wmi_handle: wmi handle 10812 * @param: fips extend param related parameters 10813 * 10814 * Return: QDF_STATUS - success or error status 10815 */ 10816 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10817 struct fips_extend_params *param) 10818 { 10819 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 10820 int c; 10821 u_int8_t *key_aligned = NULL; 10822 u_int8_t *nonce_iv_aligned = NULL; 10823 u_int8_t *data_aligned = NULL; 10824 int ret = QDF_STATUS_SUCCESS; 10825 10826 /* Assigning unaligned space to copy the key */ 10827 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10828 param->cmd_params.key_len + FIPS_ALIGN); 10829 /* Checking if kmalloc is successful to allocate space */ 10830 if (!key_unaligned) 10831 return QDF_STATUS_E_INVAL; 10832 10833 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 10834 FIPS_ALIGN); 10835 /* Checking if kmalloc is successful to allocate space */ 10836 if (!data_unaligned) { 10837 ret = QDF_STATUS_E_INVAL; 10838 goto fips_align_fail_data; 10839 } 10840 10841 /* Checking if space is aligned */ 10842 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10843 /* align to 4 */ 10844 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10845 FIPS_ALIGN); 10846 } else { 10847 key_aligned = (u_int8_t *)key_unaligned; 10848 } 10849 10850 /* memset and copy content from key to key aligned */ 10851 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 10852 OS_MEMCPY(key_aligned, param->cmd_params.key, 10853 param->cmd_params.key_len); 10854 10855 /* print a hexdump for host debug */ 10856 wmi_debug("Aligned and Copied Key: "); 10857 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10858 key_aligned, param->cmd_params.key_len); 10859 10860 /* Checking of space is aligned */ 10861 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10862 /* align to 4 */ 10863 data_aligned = 10864 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 10865 } else { 10866 data_aligned = (u_int8_t *)data_unaligned; 10867 } 10868 10869 /* memset and copy content from data to data aligned */ 10870 OS_MEMSET(data_aligned, 0, param->data_len); 10871 OS_MEMCPY(data_aligned, param->data, param->data_len); 10872 10873 /* print a hexdump for host debug */ 10874 wmi_debug("\t Properly Aligned and Copied Data: "); 10875 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10876 data_aligned, param->data_len); 10877 10878 /* converting to little Endian */ 10879 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 10880 *((u_int32_t *)key_aligned + c) = 10881 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 10882 } 10883 for (c = 0; c < param->data_len / 4; c++) { 10884 *((u_int32_t *)data_aligned + c) = 10885 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 10886 } 10887 10888 /* update endian data */ 10889 OS_MEMCPY(param->cmd_params.key, key_aligned, 10890 param->cmd_params.key_len); 10891 OS_MEMCPY(param->data, data_aligned, param->data_len); 10892 10893 if (param->cmd_params.nonce_iv_len) { 10894 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10895 param->cmd_params.nonce_iv_len + 10896 FIPS_ALIGN); 10897 10898 /* Checking if kmalloc is successful to allocate space */ 10899 if (!nonce_iv_unaligned) { 10900 ret = QDF_STATUS_E_INVAL; 10901 goto fips_align_fail_nonce_iv; 10902 } 10903 /* Checking if space is aligned */ 10904 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 10905 /* align to 4 */ 10906 nonce_iv_aligned = 10907 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 10908 FIPS_ALIGN); 10909 } else { 10910 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 10911 } 10912 10913 /* memset and copy content from iv to iv aligned */ 10914 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 10915 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 10916 param->cmd_params.nonce_iv_len); 10917 10918 /* print a hexdump for host debug */ 10919 wmi_debug("\t Aligned and Copied Nonce_IV: "); 10920 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10921 nonce_iv_aligned, 10922 param->cmd_params.nonce_iv_len); 10923 10924 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 10925 *((u_int32_t *)nonce_iv_aligned + c) = 10926 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 10927 } 10928 } 10929 10930 /* clean up allocated spaces */ 10931 qdf_mem_free(nonce_iv_unaligned); 10932 nonce_iv_unaligned = NULL; 10933 nonce_iv_aligned = NULL; 10934 10935 fips_align_fail_nonce_iv: 10936 qdf_mem_free(data_unaligned); 10937 data_unaligned = NULL; 10938 data_aligned = NULL; 10939 10940 fips_align_fail_data: 10941 qdf_mem_free(key_unaligned); 10942 key_unaligned = NULL; 10943 key_aligned = NULL; 10944 10945 return ret; 10946 } 10947 #endif 10948 10949 /** 10950 * fips_align_data_be() - LE to BE conversion of FIPS ev data 10951 * @wmi_handle: wmi handle 10952 * @param: fips param related parameters 10953 * 10954 * Return: QDF_STATUS - success or error status 10955 */ 10956 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10957 struct fips_params *param) 10958 { 10959 unsigned char *key_unaligned, *data_unaligned; 10960 int c; 10961 u_int8_t *key_aligned = NULL; 10962 u_int8_t *data_aligned = NULL; 10963 10964 /* Assigning unaligned space to copy the key */ 10965 key_unaligned = qdf_mem_malloc( 10966 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 10967 data_unaligned = qdf_mem_malloc( 10968 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 10969 10970 /* Checking if kmalloc is successful to allocate space */ 10971 if (!key_unaligned) 10972 return QDF_STATUS_SUCCESS; 10973 /* Checking if space is aligned */ 10974 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10975 /* align to 4 */ 10976 key_aligned = 10977 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10978 FIPS_ALIGN); 10979 } else { 10980 key_aligned = (u_int8_t *)key_unaligned; 10981 } 10982 10983 /* memset and copy content from key to key aligned */ 10984 OS_MEMSET(key_aligned, 0, param->key_len); 10985 OS_MEMCPY(key_aligned, param->key, param->key_len); 10986 10987 /* print a hexdump for host debug */ 10988 print_hex_dump(KERN_DEBUG, 10989 "\t Aligned and Copied Key:@@@@ ", 10990 DUMP_PREFIX_NONE, 10991 16, 1, key_aligned, param->key_len, true); 10992 10993 /* Checking if kmalloc is successful to allocate space */ 10994 if (!data_unaligned) 10995 return QDF_STATUS_SUCCESS; 10996 /* Checking of space is aligned */ 10997 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10998 /* align to 4 */ 10999 data_aligned = 11000 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 11001 FIPS_ALIGN); 11002 } else { 11003 data_aligned = (u_int8_t *)data_unaligned; 11004 } 11005 11006 /* memset and copy content from data to data aligned */ 11007 OS_MEMSET(data_aligned, 0, param->data_len); 11008 OS_MEMCPY(data_aligned, param->data, param->data_len); 11009 11010 /* print a hexdump for host debug */ 11011 print_hex_dump(KERN_DEBUG, 11012 "\t Properly Aligned and Copied Data:@@@@ ", 11013 DUMP_PREFIX_NONE, 11014 16, 1, data_aligned, param->data_len, true); 11015 11016 /* converting to little Endian both key_aligned and 11017 * data_aligned*/ 11018 for (c = 0; c < param->key_len/4; c++) { 11019 *((u_int32_t *)key_aligned+c) = 11020 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 11021 } 11022 for (c = 0; c < param->data_len/4; c++) { 11023 *((u_int32_t *)data_aligned+c) = 11024 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 11025 } 11026 11027 /* update endian data to key and data vectors */ 11028 OS_MEMCPY(param->key, key_aligned, param->key_len); 11029 OS_MEMCPY(param->data, data_aligned, param->data_len); 11030 11031 /* clean up allocated spaces */ 11032 qdf_mem_free(key_unaligned); 11033 key_unaligned = NULL; 11034 key_aligned = NULL; 11035 11036 qdf_mem_free(data_unaligned); 11037 data_unaligned = NULL; 11038 data_aligned = NULL; 11039 11040 return QDF_STATUS_SUCCESS; 11041 } 11042 #else 11043 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 11044 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 11045 struct fips_extend_params *param) 11046 { 11047 return QDF_STATUS_SUCCESS; 11048 } 11049 #endif 11050 11051 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 11052 struct fips_params *param) 11053 { 11054 return QDF_STATUS_SUCCESS; 11055 } 11056 #endif 11057 11058 #ifdef WLAN_FEATURE_DISA 11059 /** 11060 * send_encrypt_decrypt_send_cmd_tlv() - send encrypt/decrypt cmd to fw 11061 * @wmi_handle: wmi handle 11062 * @encrypt_decrypt_params: encrypt/decrypt params 11063 * 11064 * Return: QDF_STATUS_SUCCESS for success or error code 11065 */ 11066 static QDF_STATUS 11067 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 11068 struct disa_encrypt_decrypt_req_params 11069 *encrypt_decrypt_params) 11070 { 11071 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 11072 wmi_buf_t wmi_buf; 11073 uint8_t *buf_ptr; 11074 QDF_STATUS ret; 11075 uint32_t len; 11076 11077 wmi_debug("Send encrypt decrypt cmd"); 11078 11079 len = sizeof(*cmd) + 11080 encrypt_decrypt_params->data_len + 11081 WMI_TLV_HDR_SIZE; 11082 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11083 if (!wmi_buf) 11084 return QDF_STATUS_E_NOMEM; 11085 11086 buf_ptr = wmi_buf_data(wmi_buf); 11087 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 11088 11089 WMITLV_SET_HDR(&cmd->tlv_header, 11090 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 11091 WMITLV_GET_STRUCT_TLVLEN( 11092 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 11093 11094 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 11095 cmd->key_flag = encrypt_decrypt_params->key_flag; 11096 cmd->key_idx = encrypt_decrypt_params->key_idx; 11097 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 11098 cmd->key_len = encrypt_decrypt_params->key_len; 11099 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 11100 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 11101 11102 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 11103 encrypt_decrypt_params->key_len); 11104 11105 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 11106 MAX_MAC_HEADER_LEN); 11107 11108 cmd->data_len = encrypt_decrypt_params->data_len; 11109 11110 if (cmd->data_len) { 11111 buf_ptr += sizeof(*cmd); 11112 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 11113 roundup(encrypt_decrypt_params->data_len, 11114 sizeof(uint32_t))); 11115 buf_ptr += WMI_TLV_HDR_SIZE; 11116 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 11117 encrypt_decrypt_params->data_len); 11118 } 11119 11120 /* This conversion is to facilitate data to FW in little endian */ 11121 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 11122 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 11123 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 11124 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 11125 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 11126 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 11127 11128 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 11129 ret = wmi_unified_cmd_send(wmi_handle, 11130 wmi_buf, len, 11131 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 11132 if (QDF_IS_STATUS_ERROR(ret)) { 11133 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 11134 wmi_buf_free(wmi_buf); 11135 } 11136 11137 return ret; 11138 } 11139 #endif /* WLAN_FEATURE_DISA */ 11140 11141 /** 11142 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 11143 * @wmi_handle: wmi handle 11144 * @param: pointer to hold pdev fips param 11145 * 11146 * Return: QDF_STATUS_SUCCESS for success or error code 11147 */ 11148 static QDF_STATUS 11149 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 11150 struct fips_params *param) 11151 { 11152 wmi_pdev_fips_cmd_fixed_param *cmd; 11153 wmi_buf_t buf; 11154 uint8_t *buf_ptr; 11155 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 11156 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11157 11158 /* Length TLV placeholder for array of bytes */ 11159 len += WMI_TLV_HDR_SIZE; 11160 if (param->data_len) 11161 len += (param->data_len*sizeof(uint8_t)); 11162 11163 /* 11164 * Data length must be multiples of 16 bytes - checked against 0xF - 11165 * and must be less than WMI_SVC_MSG_SIZE - static size of 11166 * wmi_pdev_fips_cmd structure 11167 */ 11168 11169 /* do sanity on the input */ 11170 if (!(((param->data_len & 0xF) == 0) && 11171 ((param->data_len > 0) && 11172 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 11173 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 11174 return QDF_STATUS_E_INVAL; 11175 } 11176 11177 buf = wmi_buf_alloc(wmi_handle, len); 11178 if (!buf) 11179 return QDF_STATUS_E_FAILURE; 11180 11181 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11182 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 11183 WMITLV_SET_HDR(&cmd->tlv_header, 11184 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 11185 WMITLV_GET_STRUCT_TLVLEN 11186 (wmi_pdev_fips_cmd_fixed_param)); 11187 11188 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11189 wmi_handle, 11190 param->pdev_id); 11191 if (param->key && param->data) { 11192 cmd->key_len = param->key_len; 11193 cmd->data_len = param->data_len; 11194 cmd->fips_cmd = !!(param->op); 11195 11196 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 11197 return QDF_STATUS_E_FAILURE; 11198 11199 qdf_mem_copy(cmd->key, param->key, param->key_len); 11200 11201 if (param->mode == FIPS_ENGINE_AES_CTR || 11202 param->mode == FIPS_ENGINE_AES_MIC) { 11203 cmd->mode = param->mode; 11204 } else { 11205 cmd->mode = FIPS_ENGINE_AES_CTR; 11206 } 11207 11208 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 11209 cmd->key, cmd->key_len, true); 11210 buf_ptr += sizeof(*cmd); 11211 11212 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 11213 11214 buf_ptr += WMI_TLV_HDR_SIZE; 11215 if (param->data_len) 11216 qdf_mem_copy(buf_ptr, 11217 (uint8_t *) param->data, param->data_len); 11218 11219 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 11220 16, 1, buf_ptr, cmd->data_len, true); 11221 11222 buf_ptr += param->data_len; 11223 11224 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 11225 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11226 WMI_PDEV_FIPS_CMDID); 11227 } else { 11228 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 11229 wmi_buf_free(buf); 11230 retval = -QDF_STATUS_E_BADMSG; 11231 } 11232 11233 return retval; 11234 } 11235 11236 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 11237 /** 11238 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 11239 * @wmi_handle: wmi handle 11240 * @param: pointer to hold pdev fips param 11241 * 11242 * Return: QDF_STATUS_SUCCESS for success or error code 11243 */ 11244 static QDF_STATUS 11245 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 11246 struct fips_extend_params *param) 11247 { 11248 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 11249 wmi_buf_t buf; 11250 uint8_t *buf_ptr; 11251 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 11252 uint32_t data_len_aligned; 11253 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11254 11255 len += WMI_TLV_HDR_SIZE; 11256 if (param->frag_idx == 0) 11257 len += sizeof(wmi_fips_extend_cmd_init_params); 11258 11259 /* Length TLV placeholder for array of bytes */ 11260 len += WMI_TLV_HDR_SIZE; 11261 if (param->data_len) { 11262 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 11263 len += (data_len_aligned * sizeof(uint8_t)); 11264 } 11265 11266 buf = wmi_buf_alloc(wmi_handle, len); 11267 if (!buf) 11268 return QDF_STATUS_E_FAILURE; 11269 11270 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11271 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 11272 WMITLV_SET_HDR(&cmd->tlv_header, 11273 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 11274 WMITLV_GET_STRUCT_TLVLEN 11275 (wmi_pdev_fips_extend_cmd_fixed_param)); 11276 11277 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11278 wmi_handle, 11279 param->pdev_id); 11280 11281 cmd->fips_cookie = param->cookie; 11282 cmd->frag_idx = param->frag_idx; 11283 cmd->more_bit = param->more_bit; 11284 cmd->data_len = param->data_len; 11285 11286 if (fips_extend_align_data_be(wmi_handle, param) != 11287 QDF_STATUS_SUCCESS) { 11288 wmi_buf_free(buf); 11289 return QDF_STATUS_E_FAILURE; 11290 } 11291 11292 buf_ptr = (uint8_t *)(cmd + 1); 11293 if (cmd->frag_idx == 0) { 11294 wmi_fips_extend_cmd_init_params *cmd_params; 11295 11296 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11297 sizeof(wmi_fips_extend_cmd_init_params)); 11298 buf_ptr += WMI_TLV_HDR_SIZE; 11299 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 11300 WMITLV_SET_HDR(buf_ptr, 11301 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 11302 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 11303 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 11304 cmd_params->key_cipher = param->cmd_params.key_cipher; 11305 cmd_params->key_len = param->cmd_params.key_len; 11306 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 11307 cmd_params->tag_len = param->cmd_params.tag_len; 11308 cmd_params->aad_len = param->cmd_params.aad_len; 11309 cmd_params->payload_len = param->cmd_params.payload_len; 11310 11311 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 11312 param->cmd_params.key_len); 11313 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 11314 param->cmd_params.nonce_iv_len); 11315 11316 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 11317 cmd_params->key_len, cmd_params->nonce_iv_len, 11318 cmd_params->tag_len, cmd_params->aad_len, 11319 cmd_params->payload_len); 11320 11321 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 11322 } else { 11323 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11324 buf_ptr += WMI_TLV_HDR_SIZE; 11325 } 11326 11327 if (param->data_len && param->data) { 11328 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 11329 data_len_aligned); 11330 11331 buf_ptr += WMI_TLV_HDR_SIZE; 11332 if (param->data_len) 11333 qdf_mem_copy(buf_ptr, 11334 (uint8_t *)param->data, param->data_len); 11335 11336 wmi_debug("Data: "); 11337 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 11338 buf_ptr, cmd->data_len); 11339 11340 if (param->data_len) 11341 buf_ptr += param->data_len; 11342 } else { 11343 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 11344 buf_ptr += WMI_TLV_HDR_SIZE; 11345 } 11346 11347 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 11348 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11349 WMI_PDEV_FIPS_EXTEND_CMDID); 11350 11351 if (retval) { 11352 wmi_err("Failed to send FIPS cmd"); 11353 wmi_buf_free(buf); 11354 } 11355 11356 return retval; 11357 } 11358 11359 /** 11360 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 11361 * @wmi_handle: wmi handle 11362 * @param: pointer to hold pdev fips param 11363 * 11364 * Return: QDF_STATUS_SUCCESS for success or error code 11365 */ 11366 static QDF_STATUS 11367 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 11368 struct fips_mode_set_params *param) 11369 { 11370 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 11371 wmi_buf_t buf; 11372 uint8_t *buf_ptr; 11373 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 11374 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11375 11376 buf = wmi_buf_alloc(wmi_handle, len); 11377 if (!buf) 11378 return QDF_STATUS_E_FAILURE; 11379 11380 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11381 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 11382 WMITLV_SET_HDR(&cmd->tlv_header, 11383 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 11384 WMITLV_GET_STRUCT_TLVLEN 11385 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 11386 11387 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11388 wmi_handle, 11389 param->pdev_id); 11390 11391 cmd->fips_mode_set = param->mode; 11392 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 11393 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11394 WMI_PDEV_FIPS_MODE_SET_CMDID); 11395 if (retval) { 11396 wmi_err("Failed to send FIPS mode enable cmd"); 11397 wmi_buf_free(buf); 11398 } 11399 return retval; 11400 } 11401 #endif 11402 11403 /** 11404 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 11405 * to fw 11406 * @wmi_handle: wmi handle 11407 * @param: pointer to wlan profile param 11408 * 11409 * Return: QDF_STATUS_SUCCESS for success or error code 11410 */ 11411 static QDF_STATUS 11412 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 11413 struct wlan_profile_params *param) 11414 { 11415 wmi_buf_t buf; 11416 uint16_t len; 11417 QDF_STATUS ret; 11418 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 11419 11420 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 11421 buf = wmi_buf_alloc(wmi_handle, len); 11422 if (!buf) { 11423 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 11424 return QDF_STATUS_E_NOMEM; 11425 } 11426 11427 profile_enable_cmd = 11428 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 11429 wmi_buf_data(buf); 11430 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 11431 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 11432 WMITLV_GET_STRUCT_TLVLEN 11433 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 11434 11435 profile_enable_cmd->profile_id = param->profile_id; 11436 profile_enable_cmd->enable = param->enable; 11437 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 11438 NO_SESSION, 0); 11439 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11440 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 11441 if (ret) { 11442 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 11443 wmi_buf_free(buf); 11444 } 11445 return ret; 11446 } 11447 11448 /** 11449 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 11450 * to fw 11451 * @wmi_handle: wmi handle 11452 * @param: pointer to wlan profile param 11453 * 11454 * Return: QDF_STATUS_SUCCESS for success or error code 11455 */ 11456 static QDF_STATUS 11457 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 11458 struct wlan_profile_params *param) 11459 { 11460 wmi_buf_t buf; 11461 uint16_t len; 11462 QDF_STATUS ret; 11463 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 11464 11465 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 11466 buf = wmi_buf_alloc(wmi_handle, len); 11467 if (!buf) { 11468 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 11469 return QDF_STATUS_E_NOMEM; 11470 } 11471 11472 prof_trig_cmd = 11473 (wmi_wlan_profile_trigger_cmd_fixed_param *) 11474 wmi_buf_data(buf); 11475 11476 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 11477 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 11478 WMITLV_GET_STRUCT_TLVLEN 11479 (wmi_wlan_profile_trigger_cmd_fixed_param)); 11480 11481 prof_trig_cmd->enable = param->enable; 11482 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 11483 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11484 WMI_WLAN_PROFILE_TRIGGER_CMDID); 11485 if (ret) { 11486 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 11487 wmi_buf_free(buf); 11488 } 11489 return ret; 11490 } 11491 11492 /** 11493 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 11494 * to fw 11495 * @wmi_handle: wmi handle 11496 * @param: pointer to wlan profile param 11497 * 11498 * Return: QDF_STATUS_SUCCESS for success or error code 11499 */ 11500 static QDF_STATUS 11501 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 11502 struct wlan_profile_params *param) 11503 { 11504 wmi_buf_t buf; 11505 int32_t len = 0; 11506 QDF_STATUS ret; 11507 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 11508 11509 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 11510 buf = wmi_buf_alloc(wmi_handle, len); 11511 if (!buf) { 11512 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 11513 return QDF_STATUS_E_NOMEM; 11514 } 11515 11516 hist_intvl_cmd = 11517 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 11518 wmi_buf_data(buf); 11519 11520 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 11521 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 11522 WMITLV_GET_STRUCT_TLVLEN 11523 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 11524 11525 hist_intvl_cmd->profile_id = param->profile_id; 11526 hist_intvl_cmd->value = param->enable; 11527 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 11528 NO_SESSION, 0); 11529 11530 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11531 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 11532 if (ret) { 11533 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 11534 wmi_buf_free(buf); 11535 } 11536 return ret; 11537 } 11538 11539 /** 11540 * send_fw_test_cmd_tlv() - send fw test command to fw. 11541 * @wmi_handle: wmi handle 11542 * @wmi_fwtest: fw test command 11543 * 11544 * This function sends fw test command to fw. 11545 * 11546 * Return: CDF STATUS 11547 */ 11548 static 11549 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 11550 struct set_fwtest_params *wmi_fwtest) 11551 { 11552 wmi_fwtest_set_param_cmd_fixed_param *cmd; 11553 wmi_buf_t wmi_buf; 11554 uint16_t len; 11555 11556 len = sizeof(*cmd); 11557 11558 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11559 if (!wmi_buf) 11560 return QDF_STATUS_E_NOMEM; 11561 11562 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11563 WMITLV_SET_HDR(&cmd->tlv_header, 11564 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 11565 WMITLV_GET_STRUCT_TLVLEN( 11566 wmi_fwtest_set_param_cmd_fixed_param)); 11567 cmd->param_id = wmi_fwtest->arg; 11568 cmd->param_value = wmi_fwtest->value; 11569 11570 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 11571 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11572 WMI_FWTEST_CMDID)) { 11573 wmi_err("Failed to send fw test command"); 11574 wmi_buf_free(wmi_buf); 11575 return QDF_STATUS_E_FAILURE; 11576 } 11577 11578 return QDF_STATUS_SUCCESS; 11579 } 11580 11581 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 11582 { 11583 uint16_t len = 0; 11584 11585 if (config == WFA_CONFIG_RXNE) 11586 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 11587 else 11588 len += WMI_TLV_HDR_SIZE; 11589 11590 if (config == WFA_CONFIG_CSA) 11591 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 11592 else 11593 len += WMI_TLV_HDR_SIZE; 11594 11595 if (config == WFA_CONFIG_OCV) 11596 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 11597 else 11598 len += WMI_TLV_HDR_SIZE; 11599 11600 if (config == WFA_CONFIG_SA_QUERY) 11601 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 11602 else 11603 len += WMI_TLV_HDR_SIZE; 11604 11605 return len; 11606 } 11607 11608 /** 11609 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 11610 * @host_frmtype: Host defined OCV frame type 11611 * @ocv_frmtype: Pointer to hold WMI OCV frame type 11612 * 11613 * This function converts and fills host defined OCV frame type into WMI OCV 11614 * frame type. 11615 * 11616 * Return: CDF STATUS 11617 */ 11618 static QDF_STATUS 11619 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 11620 { 11621 switch (host_frmtype) { 11622 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 11623 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 11624 break; 11625 11626 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 11627 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 11628 break; 11629 11630 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 11631 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 11632 break; 11633 11634 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 11635 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 11636 break; 11637 11638 default: 11639 wmi_err("Invalid command type cmd %d", host_frmtype); 11640 return QDF_STATUS_E_FAILURE; 11641 } 11642 11643 return QDF_STATUS_SUCCESS; 11644 } 11645 11646 /** 11647 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 11648 * @wmi_handle: wmi handle 11649 * @wmi_wfatest: wfa test command 11650 * 11651 * This function sends wfa test command to fw. 11652 * 11653 * Return: CDF STATUS 11654 */ 11655 static 11656 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 11657 struct set_wfatest_params *wmi_wfatest) 11658 { 11659 wmi_wfa_config_cmd_fixed_param *cmd; 11660 wmi_wfa_config_rsnxe *rxne; 11661 wmi_wfa_config_csa *csa; 11662 wmi_wfa_config_ocv *ocv; 11663 wmi_wfa_config_saquery *saquery; 11664 wmi_buf_t wmi_buf; 11665 uint16_t len = sizeof(*cmd); 11666 uint8_t *buf_ptr; 11667 11668 len += wfa_config_param_len(wmi_wfatest->cmd); 11669 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11670 if (!wmi_buf) 11671 return QDF_STATUS_E_NOMEM; 11672 11673 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 11674 WMITLV_SET_HDR(&cmd->tlv_header, 11675 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 11676 WMITLV_GET_STRUCT_TLVLEN( 11677 wmi_wfa_config_cmd_fixed_param)); 11678 11679 cmd->vdev_id = wmi_wfatest->vdev_id; 11680 buf_ptr = (uint8_t *)(cmd + 1); 11681 11682 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 11683 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11684 sizeof(wmi_wfa_config_rsnxe)); 11685 buf_ptr += WMI_TLV_HDR_SIZE; 11686 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 11687 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 11688 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 11689 rxne->rsnxe_param = wmi_wfatest->value; 11690 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 11691 } else { 11692 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11693 buf_ptr += WMI_TLV_HDR_SIZE; 11694 } 11695 11696 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 11697 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11698 sizeof(wmi_wfa_config_csa)); 11699 buf_ptr += WMI_TLV_HDR_SIZE; 11700 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 11701 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 11702 csa = (wmi_wfa_config_csa *)buf_ptr; 11703 csa->ignore_csa = wmi_wfatest->value; 11704 buf_ptr += sizeof(wmi_wfa_config_csa); 11705 } else { 11706 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11707 buf_ptr += WMI_TLV_HDR_SIZE; 11708 } 11709 11710 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 11711 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11712 sizeof(wmi_wfa_config_ocv)); 11713 buf_ptr += WMI_TLV_HDR_SIZE; 11714 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 11715 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 11716 ocv = (wmi_wfa_config_ocv *)buf_ptr; 11717 11718 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 11719 &ocv->frame_types)) 11720 goto error; 11721 11722 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 11723 buf_ptr += sizeof(wmi_wfa_config_ocv); 11724 } else { 11725 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11726 buf_ptr += WMI_TLV_HDR_SIZE; 11727 } 11728 11729 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 11730 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11731 sizeof(wmi_wfa_config_saquery)); 11732 buf_ptr += WMI_TLV_HDR_SIZE; 11733 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 11734 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 11735 11736 saquery = (wmi_wfa_config_saquery *)buf_ptr; 11737 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 11738 } else { 11739 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11740 buf_ptr += WMI_TLV_HDR_SIZE; 11741 } 11742 11743 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 11744 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11745 WMI_WFA_CONFIG_CMDID)) { 11746 wmi_err("Failed to send wfa test command"); 11747 goto error; 11748 } 11749 11750 return QDF_STATUS_SUCCESS; 11751 11752 error: 11753 wmi_buf_free(wmi_buf); 11754 return QDF_STATUS_E_FAILURE; 11755 } 11756 11757 /** 11758 * send_unit_test_cmd_tlv() - send unit test command to fw. 11759 * @wmi_handle: wmi handle 11760 * @wmi_utest: unit test command 11761 * 11762 * This function send unit test command to fw. 11763 * 11764 * Return: CDF STATUS 11765 */ 11766 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 11767 struct wmi_unit_test_cmd *wmi_utest) 11768 { 11769 wmi_unit_test_cmd_fixed_param *cmd; 11770 wmi_buf_t wmi_buf; 11771 uint8_t *buf_ptr; 11772 int i; 11773 uint16_t len, args_tlv_len; 11774 uint32_t *unit_test_cmd_args; 11775 11776 args_tlv_len = 11777 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 11778 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 11779 11780 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11781 if (!wmi_buf) 11782 return QDF_STATUS_E_NOMEM; 11783 11784 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11785 buf_ptr = (uint8_t *) cmd; 11786 WMITLV_SET_HDR(&cmd->tlv_header, 11787 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 11788 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 11789 cmd->vdev_id = wmi_utest->vdev_id; 11790 cmd->module_id = wmi_utest->module_id; 11791 cmd->num_args = wmi_utest->num_args; 11792 cmd->diag_token = wmi_utest->diag_token; 11793 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 11794 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11795 (wmi_utest->num_args * sizeof(uint32_t))); 11796 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11797 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 11798 cmd->vdev_id, cmd->module_id, cmd->diag_token); 11799 wmi_debug("%d num of args = ", wmi_utest->num_args); 11800 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 11801 unit_test_cmd_args[i] = wmi_utest->args[i]; 11802 wmi_debug("%d,", wmi_utest->args[i]); 11803 } 11804 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 11805 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11806 WMI_UNIT_TEST_CMDID)) { 11807 wmi_err("Failed to send unit test command"); 11808 wmi_buf_free(wmi_buf); 11809 return QDF_STATUS_E_FAILURE; 11810 } 11811 11812 return QDF_STATUS_SUCCESS; 11813 } 11814 11815 /** 11816 * send_power_dbg_cmd_tlv() - send power debug commands 11817 * @wmi_handle: wmi handle 11818 * @param: wmi power debug parameter 11819 * 11820 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 11821 * 11822 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11823 */ 11824 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 11825 struct wmi_power_dbg_params *param) 11826 { 11827 wmi_buf_t buf = NULL; 11828 QDF_STATUS status; 11829 int len, args_tlv_len; 11830 uint8_t *buf_ptr; 11831 uint8_t i; 11832 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 11833 uint32_t *cmd_args; 11834 11835 /* Prepare and send power debug cmd parameters */ 11836 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 11837 len = sizeof(*cmd) + args_tlv_len; 11838 buf = wmi_buf_alloc(wmi_handle, len); 11839 if (!buf) 11840 return QDF_STATUS_E_NOMEM; 11841 11842 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11843 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 11844 WMITLV_SET_HDR(&cmd->tlv_header, 11845 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 11846 WMITLV_GET_STRUCT_TLVLEN 11847 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 11848 11849 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11850 wmi_handle, 11851 param->pdev_id); 11852 cmd->module_id = param->module_id; 11853 cmd->num_args = param->num_args; 11854 buf_ptr += sizeof(*cmd); 11855 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11856 (param->num_args * sizeof(uint32_t))); 11857 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11858 wmi_debug("%d num of args = ", param->num_args); 11859 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 11860 cmd_args[i] = param->args[i]; 11861 wmi_debug("%d,", param->args[i]); 11862 } 11863 11864 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 11865 status = wmi_unified_cmd_send(wmi_handle, buf, 11866 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 11867 if (QDF_IS_STATUS_ERROR(status)) { 11868 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 11869 status); 11870 goto error; 11871 } 11872 11873 return QDF_STATUS_SUCCESS; 11874 error: 11875 wmi_buf_free(buf); 11876 11877 return status; 11878 } 11879 11880 /** 11881 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 11882 * @wmi_handle: wmi handle 11883 * @pdev_id: pdev id 11884 * 11885 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 11886 * 11887 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11888 */ 11889 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 11890 uint32_t pdev_id) 11891 { 11892 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 11893 wmi_buf_t buf; 11894 uint16_t len; 11895 QDF_STATUS ret; 11896 11897 len = sizeof(*cmd); 11898 buf = wmi_buf_alloc(wmi_handle, len); 11899 11900 wmi_debug("pdev_id=%d", pdev_id); 11901 11902 if (!buf) 11903 return QDF_STATUS_E_NOMEM; 11904 11905 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 11906 wmi_buf_data(buf); 11907 11908 WMITLV_SET_HDR(&cmd->tlv_header, 11909 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 11910 WMITLV_GET_STRUCT_TLVLEN( 11911 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 11912 11913 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11914 wmi_handle, 11915 pdev_id); 11916 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 11917 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11918 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 11919 if (QDF_IS_STATUS_ERROR(ret)) { 11920 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11921 ret, pdev_id); 11922 wmi_buf_free(buf); 11923 return QDF_STATUS_E_FAILURE; 11924 } 11925 11926 return QDF_STATUS_SUCCESS; 11927 } 11928 11929 /** 11930 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 11931 * @wmi_handle: wmi handle 11932 * @pdev_id: pdev id 11933 * 11934 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 11935 * 11936 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11937 */ 11938 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 11939 uint32_t pdev_id) 11940 { 11941 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 11942 wmi_buf_t buf; 11943 uint16_t len; 11944 QDF_STATUS ret; 11945 11946 len = sizeof(*cmd); 11947 buf = wmi_buf_alloc(wmi_handle, len); 11948 11949 wmi_debug("pdev_id=%d", pdev_id); 11950 11951 if (!buf) 11952 return QDF_STATUS_E_NOMEM; 11953 11954 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 11955 wmi_buf_data(buf); 11956 11957 WMITLV_SET_HDR(&cmd->tlv_header, 11958 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 11959 WMITLV_GET_STRUCT_TLVLEN( 11960 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 11961 11962 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11963 wmi_handle, 11964 pdev_id); 11965 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 11966 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11967 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 11968 if (QDF_IS_STATUS_ERROR(ret)) { 11969 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11970 ret, pdev_id); 11971 wmi_buf_free(buf); 11972 return QDF_STATUS_E_FAILURE; 11973 } 11974 11975 return QDF_STATUS_SUCCESS; 11976 } 11977 11978 #ifdef QCA_SUPPORT_AGILE_DFS 11979 static 11980 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 11981 struct vdev_adfs_ch_cfg_params *param) 11982 { 11983 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 11984 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 11985 wmi_buf_t buf; 11986 QDF_STATUS ret; 11987 uint16_t len; 11988 11989 len = sizeof(*cmd); 11990 buf = wmi_buf_alloc(wmi_handle, len); 11991 11992 if (!buf) { 11993 wmi_err("wmi_buf_alloc failed"); 11994 return QDF_STATUS_E_NOMEM; 11995 } 11996 11997 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 11998 wmi_buf_data(buf); 11999 12000 WMITLV_SET_HDR(&cmd->tlv_header, 12001 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 12002 WMITLV_GET_STRUCT_TLVLEN 12003 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 12004 12005 cmd->vdev_id = param->vdev_id; 12006 cmd->ocac_mode = param->ocac_mode; 12007 cmd->center_freq1 = param->center_freq1; 12008 cmd->center_freq2 = param->center_freq2; 12009 cmd->chan_freq = param->chan_freq; 12010 cmd->chan_width = param->chan_width; 12011 cmd->min_duration_ms = param->min_duration_ms; 12012 cmd->max_duration_ms = param->max_duration_ms; 12013 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 12014 cmd->vdev_id, cmd->ocac_mode, 12015 cmd->center_freq); 12016 12017 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 12018 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12019 WMI_VDEV_ADFS_CH_CFG_CMDID); 12020 12021 if (QDF_IS_STATUS_ERROR(ret)) { 12022 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12023 wmi_buf_free(buf); 12024 return QDF_STATUS_E_FAILURE; 12025 } 12026 12027 return QDF_STATUS_SUCCESS; 12028 } 12029 12030 static 12031 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 12032 struct vdev_adfs_abort_params *param) 12033 { 12034 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 12035 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 12036 wmi_buf_t buf; 12037 QDF_STATUS ret; 12038 uint16_t len; 12039 12040 len = sizeof(*cmd); 12041 buf = wmi_buf_alloc(wmi_handle, len); 12042 12043 if (!buf) { 12044 wmi_err("wmi_buf_alloc failed"); 12045 return QDF_STATUS_E_NOMEM; 12046 } 12047 12048 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 12049 wmi_buf_data(buf); 12050 12051 WMITLV_SET_HDR 12052 (&cmd->tlv_header, 12053 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 12054 WMITLV_GET_STRUCT_TLVLEN 12055 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 12056 12057 cmd->vdev_id = param->vdev_id; 12058 12059 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 12060 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12061 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 12062 12063 if (QDF_IS_STATUS_ERROR(ret)) { 12064 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12065 wmi_buf_free(buf); 12066 return QDF_STATUS_E_FAILURE; 12067 } 12068 12069 return QDF_STATUS_SUCCESS; 12070 } 12071 #endif 12072 12073 /** 12074 * init_cmd_send_tlv() - send initialization cmd to fw 12075 * @wmi_handle: wmi handle 12076 * @param: pointer to wmi init param 12077 * 12078 * Return: QDF_STATUS_SUCCESS for success or error code 12079 */ 12080 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 12081 struct wmi_init_cmd_param *param) 12082 { 12083 wmi_buf_t buf; 12084 wmi_init_cmd_fixed_param *cmd; 12085 uint8_t *buf_ptr; 12086 wmi_resource_config *resource_cfg; 12087 wlan_host_memory_chunk *host_mem_chunks; 12088 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 12089 uint16_t idx; 12090 int len; 12091 QDF_STATUS ret; 12092 12093 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 12094 WMI_TLV_HDR_SIZE; 12095 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 12096 12097 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 12098 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 12099 WMI_TLV_HDR_SIZE + 12100 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 12101 12102 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 12103 if (!buf) 12104 return QDF_STATUS_E_FAILURE; 12105 12106 buf_ptr = (uint8_t *) wmi_buf_data(buf); 12107 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 12108 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 12109 12110 host_mem_chunks = (wlan_host_memory_chunk *) 12111 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 12112 + WMI_TLV_HDR_SIZE); 12113 12114 WMITLV_SET_HDR(&cmd->tlv_header, 12115 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 12116 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 12117 wmi_copy_resource_config(resource_cfg, param->res_cfg); 12118 WMITLV_SET_HDR(&resource_cfg->tlv_header, 12119 WMITLV_TAG_STRUC_wmi_resource_config, 12120 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 12121 12122 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 12123 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 12124 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 12125 WMITLV_GET_STRUCT_TLVLEN 12126 (wlan_host_memory_chunk)); 12127 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 12128 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 12129 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 12130 if (is_service_enabled_tlv(wmi_handle, 12131 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 12132 host_mem_chunks[idx].ptr_high = 12133 qdf_get_upper_32_bits( 12134 param->mem_chunks[idx].paddr); 12135 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 12136 "chunk %d len %d requested ,ptr 0x%x ", 12137 idx, host_mem_chunks[idx].size, 12138 host_mem_chunks[idx].ptr); 12139 } 12140 cmd->num_host_mem_chunks = param->num_mem_chunks; 12141 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 12142 12143 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 12144 WMITLV_TAG_ARRAY_STRUC, 12145 (sizeof(wlan_host_memory_chunk) * 12146 param->num_mem_chunks)); 12147 12148 wmi_debug("num peers: %d , num offload peers: %d, num vdevs: %d, num tids: %d, num tdls conn tb entries: %d, num tdls vdevs: %d", 12149 resource_cfg->num_peers, resource_cfg->num_offload_peers, 12150 resource_cfg->num_vdevs, resource_cfg->num_tids, 12151 resource_cfg->num_tdls_conn_table_entries, 12152 resource_cfg->num_tdls_vdevs); 12153 12154 /* Fill hw mode id config */ 12155 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 12156 12157 /* Fill fw_abi_vers */ 12158 copy_fw_abi_version_tlv(wmi_handle, cmd); 12159 12160 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 12161 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 12162 if (QDF_IS_STATUS_ERROR(ret)) { 12163 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 12164 ret); 12165 wmi_buf_free(buf); 12166 } 12167 12168 return ret; 12169 12170 } 12171 12172 /** 12173 * send_addba_send_cmd_tlv() - send addba send command to fw 12174 * @wmi_handle: wmi handle 12175 * @param: pointer to delba send params 12176 * @macaddr: peer mac address 12177 * 12178 * Send WMI_ADDBA_SEND_CMDID command to firmware 12179 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 12180 */ 12181 static QDF_STATUS 12182 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 12183 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 12184 struct addba_send_params *param) 12185 { 12186 wmi_addba_send_cmd_fixed_param *cmd; 12187 wmi_buf_t buf; 12188 uint16_t len; 12189 QDF_STATUS ret; 12190 12191 len = sizeof(*cmd); 12192 12193 buf = wmi_buf_alloc(wmi_handle, len); 12194 if (!buf) 12195 return QDF_STATUS_E_NOMEM; 12196 12197 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 12198 12199 WMITLV_SET_HDR(&cmd->tlv_header, 12200 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 12201 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 12202 12203 cmd->vdev_id = param->vdev_id; 12204 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12205 cmd->tid = param->tidno; 12206 cmd->buffersize = param->buffersize; 12207 12208 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 12209 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 12210 if (QDF_IS_STATUS_ERROR(ret)) { 12211 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12212 wmi_buf_free(buf); 12213 return QDF_STATUS_E_FAILURE; 12214 } 12215 12216 return QDF_STATUS_SUCCESS; 12217 } 12218 12219 /** 12220 * send_delba_send_cmd_tlv() - send delba send command to fw 12221 * @wmi_handle: wmi handle 12222 * @param: pointer to delba send params 12223 * @macaddr: peer mac address 12224 * 12225 * Send WMI_DELBA_SEND_CMDID command to firmware 12226 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 12227 */ 12228 static QDF_STATUS 12229 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 12230 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 12231 struct delba_send_params *param) 12232 { 12233 wmi_delba_send_cmd_fixed_param *cmd; 12234 wmi_buf_t buf; 12235 uint16_t len; 12236 QDF_STATUS ret; 12237 12238 len = sizeof(*cmd); 12239 12240 buf = wmi_buf_alloc(wmi_handle, len); 12241 if (!buf) 12242 return QDF_STATUS_E_NOMEM; 12243 12244 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 12245 12246 WMITLV_SET_HDR(&cmd->tlv_header, 12247 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 12248 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 12249 12250 cmd->vdev_id = param->vdev_id; 12251 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12252 cmd->tid = param->tidno; 12253 cmd->initiator = param->initiator; 12254 cmd->reasoncode = param->reasoncode; 12255 12256 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 12257 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 12258 if (QDF_IS_STATUS_ERROR(ret)) { 12259 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12260 wmi_buf_free(buf); 12261 return QDF_STATUS_E_FAILURE; 12262 } 12263 12264 return QDF_STATUS_SUCCESS; 12265 } 12266 12267 /** 12268 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 12269 * to fw 12270 * @wmi_handle: wmi handle 12271 * @param: pointer to addba clearresp params 12272 * @macaddr: peer mac address 12273 * Return: QDF_STATUS_SUCCESS for success or error code 12274 */ 12275 static QDF_STATUS 12276 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 12277 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 12278 struct addba_clearresponse_params *param) 12279 { 12280 wmi_addba_clear_resp_cmd_fixed_param *cmd; 12281 wmi_buf_t buf; 12282 uint16_t len; 12283 QDF_STATUS ret; 12284 12285 len = sizeof(*cmd); 12286 12287 buf = wmi_buf_alloc(wmi_handle, len); 12288 if (!buf) 12289 return QDF_STATUS_E_FAILURE; 12290 12291 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 12292 12293 WMITLV_SET_HDR(&cmd->tlv_header, 12294 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 12295 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 12296 12297 cmd->vdev_id = param->vdev_id; 12298 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12299 12300 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 12301 ret = wmi_unified_cmd_send(wmi_handle, 12302 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 12303 if (QDF_IS_STATUS_ERROR(ret)) { 12304 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12305 wmi_buf_free(buf); 12306 return QDF_STATUS_E_FAILURE; 12307 } 12308 12309 return QDF_STATUS_SUCCESS; 12310 } 12311 12312 #ifdef OBSS_PD 12313 /** 12314 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 12315 * def thresh to fw 12316 * @wmi_handle: wmi handle 12317 * @thresh: pointer to obss_spatial_reuse_def_thresh 12318 * 12319 * Return: QDF_STATUS_SUCCESS for success or error code 12320 */ 12321 static 12322 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 12323 wmi_unified_t wmi_handle, 12324 struct wmi_host_obss_spatial_reuse_set_def_thresh 12325 *thresh) 12326 { 12327 wmi_buf_t buf; 12328 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 12329 QDF_STATUS ret; 12330 uint32_t cmd_len; 12331 uint32_t tlv_len; 12332 12333 cmd_len = sizeof(*cmd); 12334 12335 buf = wmi_buf_alloc(wmi_handle, cmd_len); 12336 if (!buf) 12337 return QDF_STATUS_E_NOMEM; 12338 12339 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 12340 wmi_buf_data(buf); 12341 12342 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 12343 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 12344 12345 WMITLV_SET_HDR(&cmd->tlv_header, 12346 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 12347 tlv_len); 12348 12349 cmd->obss_min = thresh->obss_min; 12350 cmd->obss_max = thresh->obss_max; 12351 cmd->vdev_type = thresh->vdev_type; 12352 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 12353 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 12354 if (QDF_IS_STATUS_ERROR(ret)) 12355 wmi_buf_free(buf); 12356 12357 return ret; 12358 } 12359 12360 /** 12361 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 12362 * @wmi_handle: wmi handle 12363 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 12364 * 12365 * Return: QDF_STATUS_SUCCESS for success or error code 12366 */ 12367 static 12368 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 12369 struct wmi_host_obss_spatial_reuse_set_param 12370 *obss_spatial_reuse_param) 12371 { 12372 wmi_buf_t buf; 12373 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 12374 QDF_STATUS ret; 12375 uint32_t len; 12376 12377 len = sizeof(*cmd); 12378 12379 buf = wmi_buf_alloc(wmi_handle, len); 12380 if (!buf) 12381 return QDF_STATUS_E_FAILURE; 12382 12383 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 12384 WMITLV_SET_HDR(&cmd->tlv_header, 12385 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 12386 WMITLV_GET_STRUCT_TLVLEN 12387 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 12388 12389 cmd->enable = obss_spatial_reuse_param->enable; 12390 cmd->obss_min = obss_spatial_reuse_param->obss_min; 12391 cmd->obss_max = obss_spatial_reuse_param->obss_max; 12392 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 12393 12394 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12395 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 12396 12397 if (QDF_IS_STATUS_ERROR(ret)) { 12398 wmi_err( 12399 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 12400 ret); 12401 wmi_buf_free(buf); 12402 } 12403 12404 return ret; 12405 } 12406 12407 /** 12408 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 12409 * to be used by SRG based Spatial Reuse feature to the FW 12410 * @wmi_handle: wmi handle 12411 * @bitmap_0: lower 32 bits in BSS color bitmap 12412 * @bitmap_1: upper 32 bits in BSS color bitmap 12413 * @pdev_id: pdev ID 12414 * 12415 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12416 */ 12417 static QDF_STATUS 12418 send_self_srg_bss_color_bitmap_set_cmd_tlv( 12419 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12420 uint32_t bitmap_1, uint8_t pdev_id) 12421 { 12422 wmi_buf_t buf; 12423 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 12424 QDF_STATUS ret; 12425 uint32_t len; 12426 12427 len = sizeof(*cmd); 12428 12429 buf = wmi_buf_alloc(wmi_handle, len); 12430 if (!buf) 12431 return QDF_STATUS_E_FAILURE; 12432 12433 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 12434 wmi_buf_data(buf); 12435 12436 WMITLV_SET_HDR( 12437 &cmd->tlv_header, 12438 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 12439 WMITLV_GET_STRUCT_TLVLEN 12440 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 12441 12442 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12443 wmi_handle, pdev_id); 12444 cmd->srg_bss_color_bitmap[0] = bitmap_0; 12445 cmd->srg_bss_color_bitmap[1] = bitmap_1; 12446 12447 ret = wmi_unified_cmd_send( 12448 wmi_handle, buf, len, 12449 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 12450 12451 if (QDF_IS_STATUS_ERROR(ret)) { 12452 wmi_err( 12453 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 12454 ret); 12455 wmi_buf_free(buf); 12456 } 12457 12458 return ret; 12459 } 12460 12461 /** 12462 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 12463 * bitmap to be used by SRG based Spatial Reuse feature to the FW 12464 * @wmi_handle: wmi handle 12465 * @bitmap_0: lower 32 bits in partial BSSID bitmap 12466 * @bitmap_1: upper 32 bits in partial BSSID bitmap 12467 * @pdev_id: pdev ID 12468 * 12469 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12470 */ 12471 static QDF_STATUS 12472 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 12473 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12474 uint32_t bitmap_1, uint8_t pdev_id) 12475 { 12476 wmi_buf_t buf; 12477 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 12478 QDF_STATUS ret; 12479 uint32_t len; 12480 12481 len = sizeof(*cmd); 12482 12483 buf = wmi_buf_alloc(wmi_handle, len); 12484 if (!buf) 12485 return QDF_STATUS_E_FAILURE; 12486 12487 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 12488 wmi_buf_data(buf); 12489 12490 WMITLV_SET_HDR( 12491 &cmd->tlv_header, 12492 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 12493 WMITLV_GET_STRUCT_TLVLEN 12494 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 12495 12496 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12497 wmi_handle, pdev_id); 12498 12499 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 12500 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 12501 12502 ret = wmi_unified_cmd_send( 12503 wmi_handle, buf, len, 12504 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 12505 12506 if (QDF_IS_STATUS_ERROR(ret)) { 12507 wmi_err( 12508 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 12509 ret); 12510 wmi_buf_free(buf); 12511 } 12512 12513 return ret; 12514 } 12515 12516 /** 12517 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 12518 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 12519 * @wmi_handle: wmi handle 12520 * @bitmap_0: lower 32 bits in BSS color enable bitmap 12521 * @bitmap_1: upper 32 bits in BSS color enable bitmap 12522 * @pdev_id: pdev ID 12523 * 12524 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12525 */ 12526 static QDF_STATUS 12527 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 12528 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12529 uint32_t bitmap_1, uint8_t pdev_id) 12530 { 12531 wmi_buf_t buf; 12532 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 12533 QDF_STATUS ret; 12534 uint32_t len; 12535 12536 len = sizeof(*cmd); 12537 12538 buf = wmi_buf_alloc(wmi_handle, len); 12539 if (!buf) 12540 return QDF_STATUS_E_FAILURE; 12541 12542 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 12543 wmi_buf_data(buf); 12544 12545 WMITLV_SET_HDR( 12546 &cmd->tlv_header, 12547 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 12548 WMITLV_GET_STRUCT_TLVLEN 12549 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 12550 12551 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12552 wmi_handle, pdev_id); 12553 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 12554 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 12555 12556 ret = wmi_unified_cmd_send( 12557 wmi_handle, buf, len, 12558 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 12559 12560 if (QDF_IS_STATUS_ERROR(ret)) { 12561 wmi_err( 12562 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 12563 ret); 12564 wmi_buf_free(buf); 12565 } 12566 12567 return ret; 12568 } 12569 12570 /** 12571 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 12572 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 12573 * @wmi_handle: wmi handle 12574 * @bitmap_0: lower 32 bits in BSSID enable bitmap 12575 * @bitmap_1: upper 32 bits in BSSID enable bitmap 12576 * @pdev_id: pdev ID 12577 * 12578 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12579 */ 12580 static QDF_STATUS 12581 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 12582 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12583 uint32_t bitmap_1, uint8_t pdev_id) 12584 { 12585 wmi_buf_t buf; 12586 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 12587 QDF_STATUS ret; 12588 uint32_t len; 12589 12590 len = sizeof(*cmd); 12591 12592 buf = wmi_buf_alloc(wmi_handle, len); 12593 if (!buf) 12594 return QDF_STATUS_E_FAILURE; 12595 12596 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12597 wmi_buf_data(buf); 12598 12599 WMITLV_SET_HDR( 12600 &cmd->tlv_header, 12601 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12602 WMITLV_GET_STRUCT_TLVLEN 12603 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12604 12605 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12606 wmi_handle, pdev_id); 12607 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 12608 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 12609 12610 ret = wmi_unified_cmd_send( 12611 wmi_handle, buf, len, 12612 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12613 12614 if (QDF_IS_STATUS_ERROR(ret)) { 12615 wmi_err( 12616 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12617 ret); 12618 wmi_buf_free(buf); 12619 } 12620 12621 return ret; 12622 } 12623 12624 /** 12625 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 12626 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 12627 * @wmi_handle: wmi handle 12628 * @bitmap_0: lower 32 bits in BSS color enable bitmap 12629 * @bitmap_1: upper 32 bits in BSS color enable bitmap 12630 * @pdev_id: pdev ID 12631 * 12632 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12633 */ 12634 static QDF_STATUS 12635 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 12636 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12637 uint32_t bitmap_1, uint8_t pdev_id) 12638 { 12639 wmi_buf_t buf; 12640 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 12641 QDF_STATUS ret; 12642 uint32_t len; 12643 12644 len = sizeof(*cmd); 12645 12646 buf = wmi_buf_alloc(wmi_handle, len); 12647 if (!buf) 12648 return QDF_STATUS_E_FAILURE; 12649 12650 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 12651 wmi_buf_data(buf); 12652 12653 WMITLV_SET_HDR( 12654 &cmd->tlv_header, 12655 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 12656 WMITLV_GET_STRUCT_TLVLEN 12657 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 12658 12659 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12660 wmi_handle, pdev_id); 12661 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 12662 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 12663 12664 ret = wmi_unified_cmd_send( 12665 wmi_handle, buf, len, 12666 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 12667 12668 if (QDF_IS_STATUS_ERROR(ret)) { 12669 wmi_err( 12670 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 12671 ret); 12672 wmi_buf_free(buf); 12673 } 12674 12675 return ret; 12676 } 12677 12678 /** 12679 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 12680 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 12681 * @wmi_handle: wmi handle 12682 * @bitmap_0: lower 32 bits in BSSID enable bitmap 12683 * @bitmap_1: upper 32 bits in BSSID enable bitmap 12684 * @pdev_id: pdev ID 12685 * 12686 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12687 */ 12688 static QDF_STATUS 12689 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 12690 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12691 uint32_t bitmap_1, uint8_t pdev_id) 12692 { 12693 wmi_buf_t buf; 12694 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 12695 QDF_STATUS ret; 12696 uint32_t len; 12697 12698 len = sizeof(*cmd); 12699 12700 buf = wmi_buf_alloc(wmi_handle, len); 12701 if (!buf) 12702 return QDF_STATUS_E_FAILURE; 12703 12704 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12705 wmi_buf_data(buf); 12706 12707 WMITLV_SET_HDR( 12708 &cmd->tlv_header, 12709 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12710 WMITLV_GET_STRUCT_TLVLEN 12711 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12712 12713 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12714 wmi_handle, pdev_id); 12715 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 12716 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 12717 12718 ret = wmi_unified_cmd_send( 12719 wmi_handle, buf, len, 12720 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12721 12722 if (QDF_IS_STATUS_ERROR(ret)) { 12723 wmi_err( 12724 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12725 ret); 12726 wmi_buf_free(buf); 12727 } 12728 12729 return ret; 12730 } 12731 #endif 12732 12733 static 12734 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 12735 struct wmi_host_injector_frame_params *inject_config_params) 12736 { 12737 wmi_buf_t buf; 12738 wmi_frame_inject_cmd_fixed_param *cmd; 12739 QDF_STATUS ret; 12740 uint32_t len; 12741 12742 len = sizeof(*cmd); 12743 12744 buf = wmi_buf_alloc(wmi_handle, len); 12745 if (!buf) 12746 return QDF_STATUS_E_NOMEM; 12747 12748 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 12749 WMITLV_SET_HDR(&cmd->tlv_header, 12750 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 12751 WMITLV_GET_STRUCT_TLVLEN 12752 (wmi_frame_inject_cmd_fixed_param)); 12753 12754 cmd->vdev_id = inject_config_params->vdev_id; 12755 cmd->enable = inject_config_params->enable; 12756 cmd->frame_type = inject_config_params->frame_type; 12757 cmd->frame_inject_period = inject_config_params->frame_inject_period; 12758 cmd->fc_duration = inject_config_params->frame_duration; 12759 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 12760 &cmd->frame_addr1); 12761 cmd->bw = inject_config_params->frame_bw; 12762 12763 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12764 WMI_PDEV_FRAME_INJECT_CMDID); 12765 12766 if (QDF_IS_STATUS_ERROR(ret)) { 12767 wmi_err( 12768 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 12769 ret); 12770 wmi_buf_free(buf); 12771 } 12772 12773 return ret; 12774 } 12775 #ifdef QCA_SUPPORT_CP_STATS 12776 /** 12777 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 12778 * @wmi_handle: wma handle 12779 * @evt_buf: event buffer 12780 * @out_buff: buffer to populated after stats extraction 12781 * 12782 * Return: status of operation 12783 */ 12784 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 12785 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 12786 { 12787 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12788 wmi_congestion_stats *congestion_stats; 12789 12790 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 12791 congestion_stats = param_buf->congestion_stats; 12792 if (!congestion_stats) 12793 return QDF_STATUS_E_INVAL; 12794 12795 out_buff->vdev_id = congestion_stats->vdev_id; 12796 out_buff->congestion = congestion_stats->congestion; 12797 12798 wmi_debug("cca stats event processed"); 12799 return QDF_STATUS_SUCCESS; 12800 } 12801 #endif /* QCA_SUPPORT_CP_STATS */ 12802 12803 /** 12804 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 12805 * event 12806 * @wmi_handle: wmi handle 12807 * @evt_buf: pointer to event buffer 12808 * @param: Pointer to hold peer ctl data 12809 * 12810 * Return: QDF_STATUS_SUCCESS for success or error code 12811 */ 12812 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 12813 wmi_unified_t wmi_handle, 12814 void *evt_buf, 12815 struct wmi_host_pdev_ctl_failsafe_event *param) 12816 { 12817 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 12818 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 12819 12820 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 12821 if (!param_buf) { 12822 wmi_err("Invalid ctl_failsafe event buffer"); 12823 return QDF_STATUS_E_INVAL; 12824 } 12825 12826 fix_param = param_buf->fixed_param; 12827 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 12828 12829 return QDF_STATUS_SUCCESS; 12830 } 12831 12832 /** 12833 * save_service_bitmap_tlv() - save service bitmap 12834 * @wmi_handle: wmi handle 12835 * @evt_buf: pointer to event buffer 12836 * @bitmap_buf: bitmap buffer, for converged legacy support 12837 * 12838 * Return: QDF_STATUS 12839 */ 12840 static 12841 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12842 void *bitmap_buf) 12843 { 12844 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12845 struct wmi_soc *soc = wmi_handle->soc; 12846 12847 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12848 12849 /* If it is already allocated, use that buffer. This can happen 12850 * during target stop/start scenarios where host allocation is skipped. 12851 */ 12852 if (!soc->wmi_service_bitmap) { 12853 soc->wmi_service_bitmap = 12854 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 12855 if (!soc->wmi_service_bitmap) 12856 return QDF_STATUS_E_NOMEM; 12857 } 12858 12859 qdf_mem_copy(soc->wmi_service_bitmap, 12860 param_buf->wmi_service_bitmap, 12861 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12862 12863 if (bitmap_buf) 12864 qdf_mem_copy(bitmap_buf, 12865 param_buf->wmi_service_bitmap, 12866 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12867 12868 return QDF_STATUS_SUCCESS; 12869 } 12870 12871 /** 12872 * save_ext_service_bitmap_tlv() - save extendend service bitmap 12873 * @wmi_handle: wmi handle 12874 * @evt_buf: pointer to event buffer 12875 * @bitmap_buf: bitmap buffer, for converged legacy support 12876 * 12877 * Return: QDF_STATUS 12878 */ 12879 static 12880 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12881 void *bitmap_buf) 12882 { 12883 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 12884 wmi_service_available_event_fixed_param *ev; 12885 struct wmi_soc *soc = wmi_handle->soc; 12886 uint32_t i = 0; 12887 12888 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 12889 12890 ev = param_buf->fixed_param; 12891 12892 /* If it is already allocated, use that buffer. This can happen 12893 * during target stop/start scenarios where host allocation is skipped. 12894 */ 12895 if (!soc->wmi_ext_service_bitmap) { 12896 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 12897 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 12898 if (!soc->wmi_ext_service_bitmap) 12899 return QDF_STATUS_E_NOMEM; 12900 } 12901 12902 qdf_mem_copy(soc->wmi_ext_service_bitmap, 12903 ev->wmi_service_segment_bitmap, 12904 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12905 12906 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 12907 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 12908 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 12909 12910 if (bitmap_buf) 12911 qdf_mem_copy(bitmap_buf, 12912 soc->wmi_ext_service_bitmap, 12913 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12914 12915 if (!param_buf->wmi_service_ext_bitmap) { 12916 wmi_debug("wmi_service_ext_bitmap not available"); 12917 return QDF_STATUS_SUCCESS; 12918 } 12919 12920 if (!soc->wmi_ext2_service_bitmap || 12921 (param_buf->num_wmi_service_ext_bitmap > 12922 soc->wmi_ext2_service_bitmap_len)) { 12923 if (soc->wmi_ext2_service_bitmap) { 12924 qdf_mem_free(soc->wmi_ext2_service_bitmap); 12925 soc->wmi_ext2_service_bitmap = NULL; 12926 } 12927 soc->wmi_ext2_service_bitmap = 12928 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 12929 sizeof(uint32_t)); 12930 if (!soc->wmi_ext2_service_bitmap) 12931 return QDF_STATUS_E_NOMEM; 12932 12933 soc->wmi_ext2_service_bitmap_len = 12934 param_buf->num_wmi_service_ext_bitmap; 12935 } 12936 12937 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 12938 param_buf->wmi_service_ext_bitmap, 12939 (param_buf->num_wmi_service_ext_bitmap * 12940 sizeof(uint32_t))); 12941 12942 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 12943 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 12944 i, soc->wmi_ext2_service_bitmap[i]); 12945 } 12946 12947 return QDF_STATUS_SUCCESS; 12948 } 12949 12950 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 12951 struct wlan_psoc_target_capability_info *cap) 12952 { 12953 /* except LDPC all flags are common between legacy and here 12954 * also IBFEER is not defined for TLV 12955 */ 12956 cap->ht_cap_info |= ev_target_cap & ( 12957 WMI_HT_CAP_ENABLED 12958 | WMI_HT_CAP_HT20_SGI 12959 | WMI_HT_CAP_DYNAMIC_SMPS 12960 | WMI_HT_CAP_TX_STBC 12961 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 12962 | WMI_HT_CAP_RX_STBC 12963 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 12964 | WMI_HT_CAP_LDPC 12965 | WMI_HT_CAP_L_SIG_TXOP_PROT 12966 | WMI_HT_CAP_MPDU_DENSITY 12967 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 12968 | WMI_HT_CAP_HT40_SGI); 12969 if (ev_target_cap & WMI_HT_CAP_LDPC) 12970 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 12971 WMI_HOST_HT_CAP_TX_LDPC; 12972 } 12973 /** 12974 * extract_service_ready_tlv() - extract service ready event 12975 * @wmi_handle: wmi handle 12976 * @evt_buf: pointer to received event buffer 12977 * @cap: pointer to hold target capability information extracted from even 12978 * 12979 * Return: QDF_STATUS_SUCCESS for success or error code 12980 */ 12981 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 12982 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 12983 { 12984 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12985 wmi_service_ready_event_fixed_param *ev; 12986 12987 12988 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12989 12990 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12991 if (!ev) { 12992 qdf_print("%s: wmi_buf_alloc failed", __func__); 12993 return QDF_STATUS_E_FAILURE; 12994 } 12995 12996 cap->phy_capability = ev->phy_capability; 12997 cap->max_frag_entry = ev->max_frag_entry; 12998 cap->num_rf_chains = ev->num_rf_chains; 12999 copy_ht_cap_info(ev->ht_cap_info, cap); 13000 cap->vht_cap_info = ev->vht_cap_info; 13001 cap->vht_supp_mcs = ev->vht_supp_mcs; 13002 cap->hw_min_tx_power = ev->hw_min_tx_power; 13003 cap->hw_max_tx_power = ev->hw_max_tx_power; 13004 cap->sys_cap_info = ev->sys_cap_info; 13005 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 13006 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 13007 cap->max_num_scan_channels = ev->max_num_scan_channels; 13008 cap->max_supported_macs = ev->max_supported_macs; 13009 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 13010 cap->txrx_chainmask = ev->txrx_chainmask; 13011 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 13012 cap->num_msdu_desc = ev->num_msdu_desc; 13013 cap->fw_version = ev->fw_build_vers; 13014 /* fw_version_1 is not available in TLV. */ 13015 cap->fw_version_1 = 0; 13016 13017 return QDF_STATUS_SUCCESS; 13018 } 13019 13020 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 13021 * to host internal HOST_REGDMN_MODE values. 13022 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 13023 * host currently. Add this in the future if required. 13024 * 11AX (Phase II) : 11ax related values are not currently 13025 * advertised separately by FW. As part of phase II regulatory bring-up, 13026 * finalize the advertisement mechanism. 13027 * @target_wireless_mode: target wireless mode received in message 13028 * 13029 * Return: returns the host internal wireless mode. 13030 */ 13031 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 13032 { 13033 13034 uint32_t wireless_modes = 0; 13035 13036 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 13037 13038 if (target_wireless_mode & REGDMN_MODE_11A) 13039 wireless_modes |= HOST_REGDMN_MODE_11A; 13040 13041 if (target_wireless_mode & REGDMN_MODE_TURBO) 13042 wireless_modes |= HOST_REGDMN_MODE_TURBO; 13043 13044 if (target_wireless_mode & REGDMN_MODE_11B) 13045 wireless_modes |= HOST_REGDMN_MODE_11B; 13046 13047 if (target_wireless_mode & REGDMN_MODE_PUREG) 13048 wireless_modes |= HOST_REGDMN_MODE_PUREG; 13049 13050 if (target_wireless_mode & REGDMN_MODE_11G) 13051 wireless_modes |= HOST_REGDMN_MODE_11G; 13052 13053 if (target_wireless_mode & REGDMN_MODE_108G) 13054 wireless_modes |= HOST_REGDMN_MODE_108G; 13055 13056 if (target_wireless_mode & REGDMN_MODE_108A) 13057 wireless_modes |= HOST_REGDMN_MODE_108A; 13058 13059 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 13060 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 13061 13062 if (target_wireless_mode & REGDMN_MODE_XR) 13063 wireless_modes |= HOST_REGDMN_MODE_XR; 13064 13065 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 13066 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 13067 13068 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 13069 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 13070 13071 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 13072 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 13073 13074 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 13075 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 13076 13077 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 13078 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 13079 13080 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 13081 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 13082 13083 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 13084 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 13085 13086 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 13087 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 13088 13089 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 13090 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 13091 13092 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 13093 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 13094 13095 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 13096 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 13097 13098 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 13099 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 13100 13101 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 13102 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 13103 13104 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 13105 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 13106 13107 return wireless_modes; 13108 } 13109 13110 /** 13111 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 13112 * to regulatory flags. 13113 * @target_phybitmap: target phybitmap. 13114 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 13115 * phybitmap. 13116 * 13117 * Return: None 13118 */ 13119 13120 #ifdef WLAN_FEATURE_11BE 13121 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 13122 uint32_t *phybitmap) 13123 { 13124 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 13125 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 13126 } 13127 #else 13128 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 13129 uint32_t *phybitmap) 13130 { 13131 } 13132 #endif 13133 13134 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 13135 * target to host internal REGULATORY_PHYMODE values. 13136 * 13137 * @target_target_phybitmap: target phybitmap received in the message. 13138 * 13139 * Return: returns the host internal REGULATORY_PHYMODE. 13140 */ 13141 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 13142 { 13143 uint32_t phybitmap = 0; 13144 13145 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 13146 13147 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 13148 phybitmap |= REGULATORY_PHYMODE_NO11A; 13149 13150 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 13151 phybitmap |= REGULATORY_PHYMODE_NO11B; 13152 13153 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 13154 phybitmap |= REGULATORY_PHYMODE_NO11G; 13155 13156 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 13157 phybitmap |= REGULATORY_CHAN_NO11N; 13158 13159 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 13160 phybitmap |= REGULATORY_PHYMODE_NO11AC; 13161 13162 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 13163 phybitmap |= REGULATORY_PHYMODE_NO11AX; 13164 13165 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 13166 13167 return phybitmap; 13168 } 13169 13170 /** 13171 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 13172 * advertised by the target to wireless mode ext flags. 13173 * @target_wireless_modes_ext: Target wireless mode 13174 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 13175 * 13176 * Return: None 13177 */ 13178 #ifdef WLAN_FEATURE_11BE 13179 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 13180 uint64_t *wireless_modes_ext) 13181 { 13182 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 13183 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 13184 13185 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 13186 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 13187 13188 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 13189 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 13190 13191 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 13192 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 13193 13194 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 13195 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 13196 13197 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 13198 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 13199 13200 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 13201 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 13202 13203 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 13204 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 13205 13206 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 13207 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 13208 } 13209 #else 13210 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 13211 uint64_t *wireless_modes_ext) 13212 { 13213 } 13214 #endif 13215 13216 static inline uint64_t convert_wireless_modes_ext_tlv( 13217 uint32_t target_wireless_modes_ext) 13218 { 13219 uint64_t wireless_modes_ext = 0; 13220 13221 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 13222 13223 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 13224 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 13225 13226 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 13227 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 13228 13229 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 13230 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 13231 13232 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 13233 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 13234 13235 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 13236 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 13237 13238 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 13239 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 13240 13241 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 13242 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 13243 13244 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 13245 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 13246 13247 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 13248 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 13249 13250 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 13251 &wireless_modes_ext); 13252 13253 return wireless_modes_ext; 13254 } 13255 13256 /** 13257 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 13258 * @wmi_handle: wmi handle 13259 * @evt_buf: Pointer to event buffer 13260 * @cap: pointer to hold HAL reg capabilities 13261 * 13262 * Return: QDF_STATUS_SUCCESS for success or error code 13263 */ 13264 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 13265 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 13266 { 13267 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13268 13269 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13270 if (!param_buf || !param_buf->hal_reg_capabilities) { 13271 wmi_err("Invalid arguments"); 13272 return QDF_STATUS_E_FAILURE; 13273 } 13274 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 13275 sizeof(uint32_t)), 13276 sizeof(struct wlan_psoc_hal_reg_capability)); 13277 13278 cap->wireless_modes = convert_wireless_modes_tlv( 13279 param_buf->hal_reg_capabilities->wireless_modes); 13280 13281 return QDF_STATUS_SUCCESS; 13282 } 13283 13284 /** 13285 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 13286 * @wmi_handle: wmi handle 13287 * @evt_buf: Pointer to event buffer 13288 * @phy_idx: Specific phy to extract 13289 * @param: pointer to hold HAL reg capabilities 13290 * 13291 * Return: QDF_STATUS_SUCCESS for success or error code 13292 */ 13293 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 13294 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 13295 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 13296 { 13297 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13298 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 13299 13300 if (!evt_buf) { 13301 wmi_err("null evt_buf"); 13302 return QDF_STATUS_E_INVAL; 13303 } 13304 13305 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 13306 13307 if (!param_buf->num_hal_reg_caps) 13308 return QDF_STATUS_SUCCESS; 13309 13310 if (phy_idx >= param_buf->num_hal_reg_caps) 13311 return QDF_STATUS_E_INVAL; 13312 13313 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 13314 13315 param->phy_id = reg_caps->phy_id; 13316 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 13317 reg_caps->wireless_modes_ext); 13318 param->low_2ghz_chan_ext = reg_caps->low_2ghz_chan_ext; 13319 param->high_2ghz_chan_ext = reg_caps->high_2ghz_chan_ext; 13320 param->low_5ghz_chan_ext = reg_caps->low_5ghz_chan_ext; 13321 param->high_5ghz_chan_ext = reg_caps->high_5ghz_chan_ext; 13322 13323 return QDF_STATUS_SUCCESS; 13324 } 13325 13326 /** 13327 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 13328 * @wmi_handle: wmi handle 13329 * @evt_buf: pointer to event buffer 13330 * 13331 * Return: Number of entries requested 13332 */ 13333 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 13334 void *evt_buf) 13335 { 13336 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13337 wmi_service_ready_event_fixed_param *ev; 13338 13339 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13340 13341 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13342 if (!ev) { 13343 qdf_print("%s: wmi_buf_alloc failed", __func__); 13344 return 0; 13345 } 13346 13347 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 13348 wmi_err("Invalid num_mem_reqs %d:%d", 13349 ev->num_mem_reqs, param_buf->num_mem_reqs); 13350 return 0; 13351 } 13352 13353 return ev->num_mem_reqs; 13354 } 13355 13356 /** 13357 * extract_host_mem_req_tlv() - Extract host memory required from 13358 * service ready event 13359 * @wmi_handle: wmi handle 13360 * @evt_buf: pointer to event buffer 13361 * @mem_reqs: pointer to host memory request structure 13362 * @num_active_peers: number of active peers for peer cache 13363 * @num_peers: number of peers 13364 * @fw_prio: FW priority 13365 * @idx: index for memory request 13366 * 13367 * Return: Host memory request parameters requested by target 13368 */ 13369 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 13370 void *evt_buf, 13371 host_mem_req *mem_reqs, 13372 uint32_t num_active_peers, 13373 uint32_t num_peers, 13374 enum wmi_fw_mem_prio fw_prio, 13375 uint16_t idx) 13376 { 13377 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13378 13379 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 13380 13381 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 13382 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 13383 mem_reqs->num_unit_info = 13384 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 13385 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 13386 mem_reqs->tgt_num_units = 0; 13387 13388 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 13389 (mem_reqs->num_unit_info & 13390 REQ_TO_HOST_FOR_CONT_MEMORY)) || 13391 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 13392 (!(mem_reqs->num_unit_info & 13393 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 13394 /* First allocate the memory that requires contiguous memory */ 13395 mem_reqs->tgt_num_units = mem_reqs->num_units; 13396 if (mem_reqs->num_unit_info) { 13397 if (mem_reqs->num_unit_info & 13398 NUM_UNITS_IS_NUM_PEERS) { 13399 /* 13400 * number of units allocated is equal to number 13401 * of peers, 1 extra for self peer on target. 13402 * this needs to be fixed, host and target can 13403 * get out of sync 13404 */ 13405 mem_reqs->tgt_num_units = num_peers + 1; 13406 } 13407 if (mem_reqs->num_unit_info & 13408 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 13409 /* 13410 * Requesting allocation of memory using 13411 * num_active_peers in qcache. if qcache is 13412 * disabled in host, then it should allocate 13413 * memory for num_peers instead of 13414 * num_active_peers. 13415 */ 13416 if (num_active_peers) 13417 mem_reqs->tgt_num_units = 13418 num_active_peers + 1; 13419 else 13420 mem_reqs->tgt_num_units = 13421 num_peers + 1; 13422 } 13423 } 13424 13425 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 13426 "unit size %d actual units %d", 13427 idx, mem_reqs->req_id, 13428 mem_reqs->num_units, 13429 mem_reqs->num_unit_info, 13430 mem_reqs->unit_size, 13431 mem_reqs->tgt_num_units); 13432 } 13433 13434 return QDF_STATUS_SUCCESS; 13435 } 13436 13437 /** 13438 * save_fw_version_in_service_ready_tlv() - Save fw version in service 13439 * ready function 13440 * @wmi_handle: wmi handle 13441 * @evt_buf: pointer to event buffer 13442 * 13443 * Return: QDF_STATUS_SUCCESS for success or error code 13444 */ 13445 static QDF_STATUS 13446 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 13447 { 13448 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13449 wmi_service_ready_event_fixed_param *ev; 13450 13451 13452 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13453 13454 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13455 if (!ev) { 13456 qdf_print("%s: wmi_buf_alloc failed", __func__); 13457 return QDF_STATUS_E_FAILURE; 13458 } 13459 13460 /*Save fw version from service ready message */ 13461 /*This will be used while sending INIT message */ 13462 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13463 sizeof(wmi_handle->fw_abi_version)); 13464 13465 return QDF_STATUS_SUCCESS; 13466 } 13467 13468 /** 13469 * ready_extract_init_status_tlv() - Extract init status from ready event 13470 * @wmi_handle: wmi handle 13471 * @evt_buf: Pointer to event buffer 13472 * 13473 * Return: ready status 13474 */ 13475 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 13476 void *evt_buf) 13477 { 13478 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13479 wmi_ready_event_fixed_param *ev = NULL; 13480 13481 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13482 ev = param_buf->fixed_param; 13483 13484 wmi_info("%s:%d", __func__, ev->status); 13485 13486 return ev->status; 13487 } 13488 13489 /** 13490 * ready_extract_mac_addr_tlv() - extract mac address from ready event 13491 * @wmi_handle: wmi handle 13492 * @evt_buf: pointer to event buffer 13493 * @macaddr: Pointer to hold MAC address 13494 * 13495 * Return: QDF_STATUS_SUCCESS for success or error code 13496 */ 13497 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_handle, 13498 void *evt_buf, uint8_t *macaddr) 13499 { 13500 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13501 wmi_ready_event_fixed_param *ev = NULL; 13502 13503 13504 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13505 ev = param_buf->fixed_param; 13506 13507 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 13508 13509 return QDF_STATUS_SUCCESS; 13510 } 13511 13512 /** 13513 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 13514 * @wmi_handle: wmi handle 13515 * @evt_buf: pointer to event buffer 13516 * @num_mac: Pointer to hold number of MAC addresses 13517 * 13518 * Return: Pointer to addr list 13519 */ 13520 static wmi_host_mac_addr * 13521 ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_handle, 13522 void *evt_buf, uint8_t *num_mac) 13523 { 13524 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13525 wmi_ready_event_fixed_param *ev = NULL; 13526 13527 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13528 ev = param_buf->fixed_param; 13529 13530 *num_mac = ev->num_extra_mac_addr; 13531 13532 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 13533 } 13534 13535 /** 13536 * extract_ready_event_params_tlv() - Extract data from ready event apart from 13537 * status, macaddr and version. 13538 * @wmi_handle: Pointer to WMI handle. 13539 * @evt_buf: Pointer to Ready event buffer. 13540 * @ev_param: Pointer to host defined struct to copy the data from event. 13541 * 13542 * Return: QDF_STATUS_SUCCESS on success. 13543 */ 13544 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 13545 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 13546 { 13547 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13548 wmi_ready_event_fixed_param *ev = NULL; 13549 13550 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13551 ev = param_buf->fixed_param; 13552 13553 ev_param->status = ev->status; 13554 ev_param->num_dscp_table = ev->num_dscp_table; 13555 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 13556 ev_param->num_total_peer = ev->num_total_peers; 13557 ev_param->num_extra_peer = ev->num_extra_peers; 13558 /* Agile_capability in ready event is supported in TLV target, 13559 * as per aDFS FR 13560 */ 13561 ev_param->max_ast_index = ev->max_ast_index; 13562 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 13563 ev_param->agile_capability = 1; 13564 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 13565 13566 return QDF_STATUS_SUCCESS; 13567 } 13568 13569 /** 13570 * extract_dbglog_data_len_tlv() - extract debuglog data length 13571 * @wmi_handle: wmi handle 13572 * @evt_buf: pointer to event buffer 13573 * @len: length of the log 13574 * 13575 * Return: pointer to the debug log 13576 */ 13577 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 13578 void *evt_buf, uint32_t *len) 13579 { 13580 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 13581 13582 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 13583 13584 *len = param_buf->num_bufp; 13585 13586 return param_buf->bufp; 13587 } 13588 13589 13590 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 13591 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 13592 #else 13593 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 13594 ((_status) & WMI_RXERR_DECRYPT) 13595 #endif 13596 13597 /** 13598 * extract_mgmt_rx_params_tlv() - extract management rx params from event 13599 * @wmi_handle: wmi handle 13600 * @evt_buf: pointer to event buffer 13601 * @hdr: Pointer to hold header 13602 * @bufp: Pointer to hold pointer to rx param buffer 13603 * 13604 * Return: QDF_STATUS_SUCCESS for success or error code 13605 */ 13606 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 13607 void *evt_buf, struct mgmt_rx_event_params *hdr, 13608 uint8_t **bufp) 13609 { 13610 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 13611 wmi_mgmt_rx_hdr *ev_hdr = NULL; 13612 int i; 13613 13614 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 13615 if (!param_tlvs) { 13616 wmi_err_rl("Get NULL point message from FW"); 13617 return QDF_STATUS_E_INVAL; 13618 } 13619 13620 ev_hdr = param_tlvs->hdr; 13621 if (!hdr) { 13622 wmi_err_rl("Rx event is NULL"); 13623 return QDF_STATUS_E_INVAL; 13624 } 13625 13626 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 13627 wmi_err_rl("RX mgmt frame decrypt error, discard it"); 13628 return QDF_STATUS_E_INVAL; 13629 } 13630 if ((ev_hdr->status) & WMI_RXERR_MIC) { 13631 wmi_err_rl("RX mgmt frame MIC mismatch for beacon protected frame"); 13632 } 13633 13634 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 13635 wmi_err_rl("Rx mgmt frame length mismatch, discard it"); 13636 return QDF_STATUS_E_INVAL; 13637 } 13638 13639 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13640 wmi_handle, 13641 ev_hdr->pdev_id); 13642 hdr->chan_freq = ev_hdr->chan_freq; 13643 hdr->channel = ev_hdr->channel; 13644 hdr->snr = ev_hdr->snr; 13645 hdr->rate = ev_hdr->rate; 13646 hdr->phy_mode = ev_hdr->phy_mode; 13647 hdr->buf_len = ev_hdr->buf_len; 13648 hdr->status = ev_hdr->status; 13649 hdr->flags = ev_hdr->flags; 13650 hdr->rssi = ev_hdr->rssi; 13651 hdr->tsf_delta = ev_hdr->tsf_delta; 13652 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 13653 for (i = 0; i < ATH_MAX_ANTENNA; i++) 13654 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 13655 13656 *bufp = param_tlvs->bufp; 13657 13658 extract_mgmt_rx_mlo_link_removal_tlv_count( 13659 param_tlvs->num_link_removal_tbtt_count, hdr); 13660 13661 return QDF_STATUS_SUCCESS; 13662 } 13663 13664 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 13665 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 13666 { 13667 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13668 wmi_mgmt_rx_params_ext *ext_params_tlv; 13669 wmi_mgmt_rx_hdr *ev_hdr; 13670 wmi_mgmt_rx_params_ext_meta_t meta_id; 13671 uint8_t *ie_data; 13672 13673 /* initialize to zero and set it only if tlv has valid meta data */ 13674 ext_params->u.addba.ba_win_size = 0; 13675 ext_params->u.addba.reo_win_size = 0; 13676 13677 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 13678 if (!param_tlvs) { 13679 wmi_err("param_tlvs is NULL"); 13680 return QDF_STATUS_E_INVAL; 13681 } 13682 13683 ev_hdr = param_tlvs->hdr; 13684 if (!ev_hdr) { 13685 wmi_err("Rx event is NULL"); 13686 return QDF_STATUS_E_INVAL; 13687 } 13688 13689 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 13690 if (ext_params_tlv) { 13691 meta_id = WMI_RX_PARAM_EXT_META_ID_GET( 13692 ext_params_tlv->mgmt_rx_params_ext_dword0); 13693 if (meta_id == WMI_RX_PARAMS_EXT_META_ADDBA) { 13694 ext_params->meta_id = MGMT_RX_PARAMS_EXT_META_ADDBA; 13695 ext_params->u.addba.ba_win_size = 13696 WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 13697 ext_params_tlv->mgmt_rx_params_ext_dword1); 13698 if (ext_params->u.addba.ba_win_size > 1024) { 13699 wmi_info("ba win size %d from TLV is Invalid", 13700 ext_params->u.addba.ba_win_size); 13701 return QDF_STATUS_E_INVAL; 13702 } 13703 13704 ext_params->u.addba.reo_win_size = 13705 WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 13706 ext_params_tlv->mgmt_rx_params_ext_dword1); 13707 if (ext_params->u.addba.reo_win_size > 2048) { 13708 wmi_info("reo win size %d from TLV is Invalid", 13709 ext_params->u.addba.reo_win_size); 13710 return QDF_STATUS_E_INVAL; 13711 } 13712 } 13713 if (meta_id == WMI_RX_PARAMS_EXT_META_TWT) { 13714 ext_params->meta_id = MGMT_RX_PARAMS_EXT_META_TWT; 13715 ext_params->u.twt.ie_len = 13716 ext_params_tlv->twt_ie_buf_len; 13717 ie_data = param_tlvs->ie_data; 13718 if (ext_params->u.twt.ie_len && 13719 (ext_params->u.twt.ie_len < 13720 MAX_TWT_IE_RX_PARAMS_LEN)) { 13721 qdf_mem_copy(ext_params->u.twt.ie_data, 13722 ie_data, 13723 ext_params_tlv->twt_ie_buf_len); 13724 } 13725 } 13726 } 13727 13728 return QDF_STATUS_SUCCESS; 13729 } 13730 13731 #ifdef WLAN_MGMT_RX_REO_SUPPORT 13732 /** 13733 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 13734 * @wmi_handle: wmi handle 13735 * @evt_buf: pointer to event buffer 13736 * @params: Pointer to MGMT Rx REO parameters 13737 * 13738 * Return: QDF_STATUS_SUCCESS for success or error code 13739 */ 13740 static QDF_STATUS 13741 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 13742 void *evt_buf, 13743 struct mgmt_rx_reo_params *params) 13744 { 13745 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 13746 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 13747 13748 param_tlvs = evt_buf; 13749 if (!param_tlvs) { 13750 wmi_err("param_tlvs is NULL"); 13751 return QDF_STATUS_E_INVAL; 13752 } 13753 13754 ev_hdr = param_tlvs->hdr; 13755 if (!params) { 13756 wmi_err("Rx REO parameters is NULL"); 13757 return QDF_STATUS_E_INVAL; 13758 } 13759 13760 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13761 wmi_handle, 13762 ev_hdr->pdev_id); 13763 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 13764 ev_hdr->mgmt_pkt_ctr_info); 13765 params->global_timestamp = ev_hdr->global_timestamp; 13766 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 13767 ev_hdr->mgmt_pkt_ctr_info); 13768 params->duration_us = ev_hdr->rx_ppdu_duration_us; 13769 params->start_timestamp = params->global_timestamp; 13770 params->end_timestamp = params->start_timestamp + 13771 params->duration_us; 13772 13773 return QDF_STATUS_SUCCESS; 13774 } 13775 13776 /** 13777 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 13778 * MGMT_RX_EVENT_ID 13779 * @wmi_handle: wmi handle 13780 * @evt_buf: pointer to event buffer 13781 * @reo_params: Pointer to MGMT Rx REO parameters 13782 * 13783 * Return: QDF_STATUS_SUCCESS for success or error code 13784 */ 13785 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 13786 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 13787 { 13788 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13789 wmi_mgmt_rx_reo_params *reo_params_tlv; 13790 wmi_mgmt_rx_hdr *ev_hdr; 13791 13792 param_tlvs = evt_buf; 13793 if (!param_tlvs) { 13794 wmi_err("param_tlvs is NULL"); 13795 return QDF_STATUS_E_INVAL; 13796 } 13797 13798 ev_hdr = param_tlvs->hdr; 13799 if (!ev_hdr) { 13800 wmi_err("Rx event is NULL"); 13801 return QDF_STATUS_E_INVAL; 13802 } 13803 13804 reo_params_tlv = param_tlvs->reo_params; 13805 if (!reo_params_tlv) { 13806 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 13807 return QDF_STATUS_E_INVAL; 13808 } 13809 13810 if (!reo_params) { 13811 wmi_err("MGMT Rx REO params is NULL"); 13812 return QDF_STATUS_E_INVAL; 13813 } 13814 13815 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13816 wmi_handle, 13817 ev_hdr->pdev_id); 13818 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 13819 reo_params_tlv->mgmt_pkt_ctr_link_info); 13820 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 13821 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 13822 reo_params_tlv->mgmt_pkt_ctr_link_info); 13823 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 13824 reo_params->start_timestamp = reo_params->global_timestamp; 13825 reo_params->end_timestamp = reo_params->start_timestamp + 13826 reo_params->duration_us; 13827 13828 return QDF_STATUS_SUCCESS; 13829 } 13830 13831 /** 13832 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 13833 * configuration command 13834 * @wmi_handle: wmi handle 13835 * @pdev_id: pdev ID of the radio 13836 * @filter: Pointer to MGMT Rx REO filter 13837 * 13838 * Return: QDF_STATUS_SUCCESS for success or error code 13839 */ 13840 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 13841 wmi_unified_t wmi_handle, 13842 uint8_t pdev_id, 13843 struct mgmt_rx_reo_filter *filter) 13844 { 13845 QDF_STATUS ret; 13846 wmi_buf_t buf; 13847 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 13848 size_t len = sizeof(*cmd); 13849 13850 if (!filter) { 13851 wmi_err("mgmt_rx_reo_filter is NULL"); 13852 return QDF_STATUS_E_INVAL; 13853 } 13854 13855 buf = wmi_buf_alloc(wmi_handle, len); 13856 if (!buf) { 13857 wmi_err("wmi_buf_alloc failed"); 13858 return QDF_STATUS_E_NOMEM; 13859 } 13860 13861 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 13862 wmi_buf_data(buf); 13863 13864 WMITLV_SET_HDR(&cmd->tlv_header, 13865 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 13866 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 13867 13868 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 13869 wmi_handle, 13870 pdev_id); 13871 cmd->filter_low = filter->low; 13872 cmd->filter_high = filter->high; 13873 13874 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 13875 ret = wmi_unified_cmd_send( 13876 wmi_handle, buf, len, 13877 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 13878 13879 if (QDF_IS_STATUS_ERROR(ret)) { 13880 wmi_err("Failed to send WMI command"); 13881 wmi_buf_free(buf); 13882 } 13883 13884 return ret; 13885 } 13886 #endif 13887 13888 /** 13889 * extract_frame_pn_params_tlv() - extract PN params from event 13890 * @wmi_handle: wmi handle 13891 * @evt_buf: pointer to event buffer 13892 * @pn_params: Pointer to Frame PN params 13893 * 13894 * Return: QDF_STATUS_SUCCESS for success or error code 13895 */ 13896 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 13897 void *evt_buf, 13898 struct frame_pn_params *pn_params) 13899 { 13900 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13901 wmi_frame_pn_params *pn_params_tlv; 13902 13903 if (!is_service_enabled_tlv(wmi_handle, 13904 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 13905 return QDF_STATUS_SUCCESS; 13906 13907 param_tlvs = evt_buf; 13908 if (!param_tlvs) { 13909 wmi_err("Got NULL point message from FW"); 13910 return QDF_STATUS_E_INVAL; 13911 } 13912 13913 if (!pn_params) { 13914 wmi_err("PN Params is NULL"); 13915 return QDF_STATUS_E_INVAL; 13916 } 13917 13918 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 13919 * found by target 13920 */ 13921 pn_params_tlv = param_tlvs->pn_params; 13922 if (!pn_params_tlv) 13923 return QDF_STATUS_SUCCESS; 13924 13925 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 13926 sizeof(pn_params->curr_pn)); 13927 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 13928 sizeof(pn_params->prev_pn)); 13929 13930 return QDF_STATUS_SUCCESS; 13931 } 13932 13933 /** 13934 * extract_is_conn_ap_frm_param_tlv() - extract is_conn_ap_frame param from 13935 * event 13936 * @wmi_handle: wmi handle 13937 * @evt_buf: pointer to event buffer 13938 * @is_conn_ap: Pointer for is_conn_ap frame 13939 * 13940 * Return: QDF_STATUS_SUCCESS for success or error code 13941 */ 13942 static QDF_STATUS extract_is_conn_ap_frm_param_tlv( 13943 wmi_unified_t wmi_handle, 13944 void *evt_buf, 13945 struct frm_conn_ap *is_conn_ap) 13946 { 13947 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13948 wmi_is_my_mgmt_frame *my_frame_tlv; 13949 13950 param_tlvs = evt_buf; 13951 if (!param_tlvs) { 13952 wmi_err("Got NULL point message from FW"); 13953 return QDF_STATUS_E_INVAL; 13954 } 13955 13956 if (!is_conn_ap) { 13957 wmi_err(" is connected ap param is NULL"); 13958 return QDF_STATUS_E_INVAL; 13959 } 13960 13961 my_frame_tlv = param_tlvs->my_frame; 13962 if (!my_frame_tlv) 13963 return QDF_STATUS_SUCCESS; 13964 13965 is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type; 13966 is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame; 13967 13968 return QDF_STATUS_SUCCESS; 13969 } 13970 13971 /** 13972 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 13973 * @wmi_handle: wmi handle 13974 * @evt_buf: pointer to event buffer 13975 * @param: Pointer to hold roam param 13976 * 13977 * Return: QDF_STATUS_SUCCESS for success or error code 13978 */ 13979 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 13980 void *evt_buf, wmi_host_roam_event *param) 13981 { 13982 WMI_ROAM_EVENTID_param_tlvs *param_buf; 13983 wmi_roam_event_fixed_param *evt; 13984 13985 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 13986 if (!param_buf) { 13987 wmi_err("Invalid roam event buffer"); 13988 return QDF_STATUS_E_INVAL; 13989 } 13990 13991 evt = param_buf->fixed_param; 13992 qdf_mem_zero(param, sizeof(*param)); 13993 13994 param->vdev_id = evt->vdev_id; 13995 param->reason = evt->reason; 13996 param->rssi = evt->rssi; 13997 13998 return QDF_STATUS_SUCCESS; 13999 } 14000 14001 /** 14002 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 14003 * @wmi_handle: wmi handle 14004 * @evt_buf: pointer to event buffer 14005 * @param: Pointer to hold vdev scan param 14006 * 14007 * Return: QDF_STATUS_SUCCESS for success or error code 14008 */ 14009 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 14010 void *evt_buf, struct scan_event *param) 14011 { 14012 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 14013 wmi_scan_event_fixed_param *evt = NULL; 14014 14015 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 14016 evt = param_buf->fixed_param; 14017 14018 qdf_mem_zero(param, sizeof(*param)); 14019 14020 switch (evt->event) { 14021 case WMI_SCAN_EVENT_STARTED: 14022 param->type = SCAN_EVENT_TYPE_STARTED; 14023 break; 14024 case WMI_SCAN_EVENT_COMPLETED: 14025 param->type = SCAN_EVENT_TYPE_COMPLETED; 14026 break; 14027 case WMI_SCAN_EVENT_BSS_CHANNEL: 14028 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 14029 break; 14030 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 14031 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 14032 break; 14033 case WMI_SCAN_EVENT_DEQUEUED: 14034 param->type = SCAN_EVENT_TYPE_DEQUEUED; 14035 break; 14036 case WMI_SCAN_EVENT_PREEMPTED: 14037 param->type = SCAN_EVENT_TYPE_PREEMPTED; 14038 break; 14039 case WMI_SCAN_EVENT_START_FAILED: 14040 param->type = SCAN_EVENT_TYPE_START_FAILED; 14041 break; 14042 case WMI_SCAN_EVENT_RESTARTED: 14043 param->type = SCAN_EVENT_TYPE_RESTARTED; 14044 break; 14045 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 14046 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 14047 break; 14048 case WMI_SCAN_EVENT_MAX: 14049 default: 14050 param->type = SCAN_EVENT_TYPE_MAX; 14051 break; 14052 }; 14053 14054 switch (evt->reason) { 14055 case WMI_SCAN_REASON_NONE: 14056 param->reason = SCAN_REASON_NONE; 14057 break; 14058 case WMI_SCAN_REASON_COMPLETED: 14059 param->reason = SCAN_REASON_COMPLETED; 14060 break; 14061 case WMI_SCAN_REASON_CANCELLED: 14062 param->reason = SCAN_REASON_CANCELLED; 14063 break; 14064 case WMI_SCAN_REASON_PREEMPTED: 14065 param->reason = SCAN_REASON_PREEMPTED; 14066 break; 14067 case WMI_SCAN_REASON_TIMEDOUT: 14068 param->reason = SCAN_REASON_TIMEDOUT; 14069 break; 14070 case WMI_SCAN_REASON_INTERNAL_FAILURE: 14071 param->reason = SCAN_REASON_INTERNAL_FAILURE; 14072 break; 14073 case WMI_SCAN_REASON_SUSPENDED: 14074 param->reason = SCAN_REASON_SUSPENDED; 14075 break; 14076 case WMI_SCAN_REASON_DFS_VIOLATION: 14077 param->reason = SCAN_REASON_DFS_VIOLATION; 14078 break; 14079 case WMI_SCAN_REASON_MAX: 14080 param->reason = SCAN_REASON_MAX; 14081 break; 14082 default: 14083 param->reason = SCAN_REASON_MAX; 14084 break; 14085 }; 14086 14087 param->chan_freq = evt->channel_freq; 14088 param->requester = evt->requestor; 14089 param->scan_id = evt->scan_id; 14090 param->vdev_id = evt->vdev_id; 14091 param->timestamp = evt->tsf_timestamp; 14092 14093 return QDF_STATUS_SUCCESS; 14094 } 14095 14096 #ifdef FEATURE_WLAN_SCAN_PNO 14097 /** 14098 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 14099 * @wmi_handle: pointer to WMI handle 14100 * @evt_buf: pointer to WMI event buffer 14101 * @param: pointer to scan event param for NLO match 14102 * 14103 * Return: QDF_STATUS_SUCCESS for success or error code 14104 */ 14105 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 14106 void *evt_buf, 14107 struct scan_event *param) 14108 { 14109 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 14110 wmi_nlo_event *evt = param_buf->fixed_param; 14111 14112 qdf_mem_zero(param, sizeof(*param)); 14113 14114 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 14115 param->vdev_id = evt->vdev_id; 14116 14117 return QDF_STATUS_SUCCESS; 14118 } 14119 14120 /** 14121 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 14122 * @wmi_handle: pointer to WMI handle 14123 * @evt_buf: pointer to WMI event buffer 14124 * @param: pointer to scan event param for NLO complete 14125 * 14126 * Return: QDF_STATUS_SUCCESS for success or error code 14127 */ 14128 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 14129 void *evt_buf, 14130 struct scan_event *param) 14131 { 14132 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 14133 wmi_nlo_event *evt = param_buf->fixed_param; 14134 14135 qdf_mem_zero(param, sizeof(*param)); 14136 14137 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 14138 param->vdev_id = evt->vdev_id; 14139 14140 return QDF_STATUS_SUCCESS; 14141 } 14142 #endif 14143 14144 /** 14145 * extract_unit_test_tlv() - extract unit test data 14146 * @wmi_handle: wmi handle 14147 * @evt_buf: pointer to event buffer 14148 * @unit_test: pointer to hold unit test data 14149 * @maxspace: Amount of space in evt_buf 14150 * 14151 * Return: QDF_STATUS_SUCCESS for success or error code 14152 */ 14153 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 14154 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 14155 { 14156 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 14157 wmi_unit_test_event_fixed_param *ev_param; 14158 uint32_t num_bufp; 14159 uint32_t copy_size; 14160 uint8_t *bufp; 14161 14162 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 14163 ev_param = param_buf->fixed_param; 14164 bufp = param_buf->bufp; 14165 num_bufp = param_buf->num_bufp; 14166 unit_test->vdev_id = ev_param->vdev_id; 14167 unit_test->module_id = ev_param->module_id; 14168 unit_test->diag_token = ev_param->diag_token; 14169 unit_test->flag = ev_param->flag; 14170 unit_test->payload_len = ev_param->payload_len; 14171 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 14172 ev_param->vdev_id, 14173 ev_param->module_id, 14174 ev_param->diag_token, 14175 ev_param->flag); 14176 wmi_debug("Unit-test data given below %d", num_bufp); 14177 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 14178 bufp, num_bufp); 14179 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 14180 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 14181 unit_test->buffer_len = copy_size; 14182 14183 return QDF_STATUS_SUCCESS; 14184 } 14185 14186 /** 14187 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 14188 * @wmi_handle: wmi handle 14189 * @evt_buf: pointer to event buffer 14190 * @index: Index into extended pdev stats 14191 * @pdev_ext_stats: Pointer to hold extended pdev stats 14192 * 14193 * Return: QDF_STATUS_SUCCESS for success or error code 14194 */ 14195 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 14196 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 14197 { 14198 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14199 wmi_pdev_extd_stats *ev; 14200 14201 param_buf = evt_buf; 14202 if (!param_buf) 14203 return QDF_STATUS_E_FAILURE; 14204 14205 if (!param_buf->pdev_extd_stats) 14206 return QDF_STATUS_E_FAILURE; 14207 14208 ev = param_buf->pdev_extd_stats + index; 14209 14210 pdev_ext_stats->pdev_id = 14211 wmi_handle->ops->convert_target_pdev_id_to_host( 14212 wmi_handle, 14213 ev->pdev_id); 14214 pdev_ext_stats->my_rx_count = ev->my_rx_count; 14215 pdev_ext_stats->rx_matched_11ax_msdu_cnt = ev->rx_matched_11ax_msdu_cnt; 14216 pdev_ext_stats->rx_other_11ax_msdu_cnt = ev->rx_other_11ax_msdu_cnt; 14217 14218 return QDF_STATUS_SUCCESS; 14219 } 14220 14221 /** 14222 * extract_bcn_stats_tlv() - extract bcn stats from event 14223 * @wmi_handle: wmi handle 14224 * @evt_buf: pointer to event buffer 14225 * @index: Index into vdev stats 14226 * @bcn_stats: Pointer to hold bcn stats 14227 * 14228 * Return: QDF_STATUS_SUCCESS for success or error code 14229 */ 14230 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 14231 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 14232 { 14233 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14234 wmi_stats_event_fixed_param *ev_param; 14235 uint8_t *data; 14236 14237 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 14238 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 14239 data = (uint8_t *) param_buf->data; 14240 14241 if (index < ev_param->num_bcn_stats) { 14242 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 14243 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 14244 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 14245 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 14246 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 14247 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 14248 (index * sizeof(wmi_bcn_stats))); 14249 14250 bcn_stats->vdev_id = ev->vdev_id; 14251 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 14252 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 14253 } 14254 14255 return QDF_STATUS_SUCCESS; 14256 } 14257 14258 #ifdef WLAN_FEATURE_11BE_MLO 14259 /** 14260 * wmi_is_mlo_vdev_active() - get if mlo vdev is active or not 14261 * @flag: vdev link status info 14262 * 14263 * Return: True if active, else False 14264 */ 14265 static bool wmi_is_mlo_vdev_active(uint32_t flag) 14266 { 14267 if ((flag & WMI_VDEV_STATS_FLAGS_LINK_ACTIVE_FLAG_IS_VALID_MASK) && 14268 (flag & WMI_VDEV_STATS_FLAGS_IS_LINK_ACTIVE_MASK)) 14269 return true; 14270 14271 return false; 14272 } 14273 14274 static QDF_STATUS 14275 extract_mlo_vdev_status_info(WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf, 14276 wmi_vdev_extd_stats *ev, 14277 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14278 { 14279 if (!param_buf->num_vdev_extd_stats) { 14280 wmi_err("No vdev_extd_stats in the event buffer"); 14281 return QDF_STATUS_E_INVAL; 14282 } 14283 14284 vdev_stats->is_mlo_vdev_active = wmi_is_mlo_vdev_active(ev->flags); 14285 return QDF_STATUS_SUCCESS; 14286 } 14287 #else 14288 static QDF_STATUS 14289 extract_mlo_vdev_status_info(WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf, 14290 wmi_vdev_extd_stats *ev, 14291 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14292 { 14293 return QDF_STATUS_SUCCESS; 14294 } 14295 #endif 14296 14297 /** 14298 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 14299 * stats from event 14300 * @wmi_handle: wmi handle 14301 * @evt_buf: pointer to event buffer 14302 * @index: Index into vdev stats 14303 * @vdev_stats: Pointer to hold vdev probe and fils stats 14304 * 14305 * Return: QDF_STATUS_SUCCESS for success or error code 14306 */ 14307 static QDF_STATUS 14308 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 14309 void *evt_buf, uint32_t index, 14310 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14311 { 14312 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14313 wmi_vdev_extd_stats *ev; 14314 QDF_STATUS status = QDF_STATUS_SUCCESS; 14315 14316 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 14317 14318 if (param_buf->vdev_extd_stats) { 14319 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 14320 index); 14321 vdev_stats->vdev_id = ev->vdev_id; 14322 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 14323 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 14324 vdev_stats->unsolicited_prb_succ_cnt = 14325 ev->unsolicited_prb_succ_cnt; 14326 vdev_stats->unsolicited_prb_fail_cnt = 14327 ev->unsolicited_prb_fail_cnt; 14328 status = extract_mlo_vdev_status_info(param_buf, ev, 14329 vdev_stats); 14330 vdev_stats->vdev_tx_power = ev->vdev_tx_power; 14331 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 14332 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 14333 ev->unsolicited_prb_succ_cnt, 14334 ev->unsolicited_prb_fail_cnt); 14335 wmi_debug("vdev txpwr: %d", ev->vdev_tx_power); 14336 } 14337 14338 return status; 14339 } 14340 14341 /** 14342 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 14343 * @wmi_handle: wmi handle 14344 * @evt_buf: pointer to event buffer 14345 * @index: Index into bcn fault stats 14346 * @bcnflt_stats: Pointer to hold bcn fault stats 14347 * 14348 * Return: QDF_STATUS_SUCCESS for success or error code 14349 */ 14350 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 14351 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *bcnflt_stats) 14352 { 14353 return QDF_STATUS_SUCCESS; 14354 } 14355 14356 /** 14357 * extract_chan_stats_tlv() - extract chan stats from event 14358 * @wmi_handle: wmi handle 14359 * @evt_buf: pointer to event buffer 14360 * @index: Index into chan stats 14361 * @chan_stats: Pointer to hold chan stats 14362 * 14363 * Return: QDF_STATUS_SUCCESS for success or error code 14364 */ 14365 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 14366 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 14367 { 14368 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14369 wmi_stats_event_fixed_param *ev_param; 14370 uint8_t *data; 14371 14372 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 14373 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 14374 data = (uint8_t *) param_buf->data; 14375 14376 if (index < ev_param->num_chan_stats) { 14377 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 14378 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 14379 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 14380 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 14381 (index * sizeof(wmi_chan_stats))); 14382 14383 14384 /* Non-TLV doesn't have num_chan_stats */ 14385 chan_stats->chan_mhz = ev->chan_mhz; 14386 chan_stats->sampling_period_us = ev->sampling_period_us; 14387 chan_stats->rx_clear_count = ev->rx_clear_count; 14388 chan_stats->tx_duration_us = ev->tx_duration_us; 14389 chan_stats->rx_duration_us = ev->rx_duration_us; 14390 } 14391 14392 return QDF_STATUS_SUCCESS; 14393 } 14394 14395 /** 14396 * extract_profile_ctx_tlv() - extract profile context from event 14397 * @wmi_handle: wmi handle 14398 * @evt_buf: pointer to event buffer 14399 * @profile_ctx: Pointer to hold profile context 14400 * 14401 * Return: QDF_STATUS_SUCCESS for success or error code 14402 */ 14403 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 14404 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 14405 { 14406 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 14407 14408 wmi_wlan_profile_ctx_t *ev; 14409 14410 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 14411 if (!param_buf) { 14412 wmi_err("Invalid profile data event buf"); 14413 return QDF_STATUS_E_INVAL; 14414 } 14415 14416 ev = param_buf->profile_ctx; 14417 14418 profile_ctx->tot = ev->tot; 14419 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 14420 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 14421 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 14422 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 14423 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 14424 profile_ctx->bin_count = ev->bin_count; 14425 14426 return QDF_STATUS_SUCCESS; 14427 } 14428 14429 /** 14430 * extract_profile_data_tlv() - extract profile data from event 14431 * @wmi_handle: wmi handle 14432 * @evt_buf: pointer to event buffer 14433 * @idx: profile stats index to extract 14434 * @profile_data: Pointer to hold profile data 14435 * 14436 * Return: QDF_STATUS_SUCCESS for success or error code 14437 */ 14438 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 14439 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 14440 { 14441 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 14442 wmi_wlan_profile_t *ev; 14443 14444 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 14445 if (!param_buf) { 14446 wmi_err("Invalid profile data event buf"); 14447 return QDF_STATUS_E_INVAL; 14448 } 14449 14450 ev = ¶m_buf->profile_data[idx]; 14451 profile_data->id = ev->id; 14452 profile_data->cnt = ev->cnt; 14453 profile_data->tot = ev->tot; 14454 profile_data->min = ev->min; 14455 profile_data->max = ev->max; 14456 profile_data->hist_intvl = ev->hist_intvl; 14457 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 14458 14459 return QDF_STATUS_SUCCESS; 14460 } 14461 14462 /** 14463 * extract_pdev_utf_event_tlv() - extract UTF data info from event 14464 * @wmi_handle: WMI handle 14465 * @evt_buf: Pointer to event buffer 14466 * @event: Pointer to hold data 14467 * 14468 * Return: QDF_STATUS_SUCCESS for success or error code 14469 */ 14470 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 14471 uint8_t *evt_buf, 14472 struct wmi_host_pdev_utf_event *event) 14473 { 14474 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 14475 struct wmi_host_utf_seg_header_info *seg_hdr; 14476 wmi_pdev_utf_event_fixed_param *ev_param; 14477 bool is_pdev_id_over_utf; 14478 14479 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 14480 event->data = param_buf->data; 14481 event->datalen = param_buf->num_data; 14482 14483 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 14484 wmi_err("Invalid datalen: %d", event->datalen); 14485 return QDF_STATUS_E_INVAL; 14486 } 14487 14488 is_pdev_id_over_utf = is_service_enabled_tlv(wmi_handle, 14489 WMI_SERVICE_PDEV_PARAM_IN_UTF_WMI); 14490 if (is_pdev_id_over_utf && param_buf->fixed_param && 14491 param_buf->num_fixed_param) { 14492 ev_param = 14493 (wmi_pdev_utf_event_fixed_param *)param_buf->fixed_param; 14494 event->pdev_id = 14495 wmi_handle->ops->convert_pdev_id_target_to_host( 14496 wmi_handle, 14497 ev_param->pdev_id); 14498 } else { 14499 seg_hdr = 14500 (struct wmi_host_utf_seg_header_info *)param_buf->data; 14501 event->pdev_id = 14502 wmi_handle->ops->convert_pdev_id_target_to_host( 14503 wmi_handle, 14504 seg_hdr->pdev_id); 14505 } 14506 14507 return QDF_STATUS_SUCCESS; 14508 } 14509 14510 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 14511 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 14512 uint8_t *event, 14513 uint32_t *num_rf_characterization_entries) 14514 { 14515 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 14516 14517 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 14518 if (!param_buf) 14519 return QDF_STATUS_E_INVAL; 14520 14521 *num_rf_characterization_entries = 14522 param_buf->num_wmi_chan_rf_characterization_info; 14523 14524 return QDF_STATUS_SUCCESS; 14525 } 14526 14527 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 14528 uint8_t *event, 14529 uint32_t num_rf_characterization_entries, 14530 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 14531 { 14532 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 14533 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 14534 uint8_t ix; 14535 14536 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 14537 if (!param_buf) 14538 return QDF_STATUS_E_INVAL; 14539 14540 wmi_rf_characterization_entry = 14541 param_buf->wmi_chan_rf_characterization_info; 14542 if (!wmi_rf_characterization_entry) 14543 return QDF_STATUS_E_INVAL; 14544 14545 /* 14546 * Using num_wmi_chan_rf_characterization instead of param_buf value 14547 * since memory for rf_characterization_entries was allocated using 14548 * the former. 14549 */ 14550 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 14551 rf_characterization_entries[ix].freq = 14552 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 14553 &wmi_rf_characterization_entry[ix]); 14554 14555 rf_characterization_entries[ix].bw = 14556 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 14557 &wmi_rf_characterization_entry[ix]); 14558 14559 rf_characterization_entries[ix].chan_metric = 14560 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 14561 &wmi_rf_characterization_entry[ix]); 14562 14563 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 14564 "bw: %u, chan_metric: %u", 14565 ix, rf_characterization_entries[ix].freq, 14566 rf_characterization_entries[ix].bw, 14567 rf_characterization_entries[ix].chan_metric); 14568 } 14569 14570 return QDF_STATUS_SUCCESS; 14571 } 14572 #endif 14573 14574 #ifdef WLAN_FEATURE_11BE 14575 static void 14576 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 14577 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 14578 { 14579 cap->supports_chan_width_320 = 14580 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 14581 cap->supports_aDFS_320 = 14582 WMI_SUPPORT_ADFS_320_GET(chainmask_caps->supported_flags); 14583 } 14584 #else 14585 static void 14586 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 14587 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 14588 { 14589 } 14590 #endif /* WLAN_FEATURE_11BE */ 14591 14592 /** 14593 * extract_chainmask_tables_tlv() - extract chain mask tables from event 14594 * @wmi_handle: wmi handle 14595 * @event: pointer to event buffer 14596 * @chainmask_table: Pointer to hold extracted chainmask tables 14597 * 14598 * Return: QDF_STATUS_SUCCESS for success or error code 14599 */ 14600 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 14601 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 14602 { 14603 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14604 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 14605 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14606 uint8_t i = 0, j = 0; 14607 uint32_t num_mac_phy_chainmask_caps = 0; 14608 14609 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14610 if (!param_buf) 14611 return QDF_STATUS_E_INVAL; 14612 14613 hw_caps = param_buf->soc_hw_mode_caps; 14614 if (!hw_caps) 14615 return QDF_STATUS_E_INVAL; 14616 14617 if ((!hw_caps->num_chainmask_tables) || 14618 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 14619 (hw_caps->num_chainmask_tables > 14620 param_buf->num_mac_phy_chainmask_combo)) 14621 return QDF_STATUS_E_INVAL; 14622 14623 chainmask_caps = param_buf->mac_phy_chainmask_caps; 14624 14625 if (!chainmask_caps) 14626 return QDF_STATUS_E_INVAL; 14627 14628 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 14629 if (chainmask_table[i].num_valid_chainmasks > 14630 (UINT_MAX - num_mac_phy_chainmask_caps)) { 14631 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 14632 num_mac_phy_chainmask_caps, i, 14633 chainmask_table[i].num_valid_chainmasks); 14634 return QDF_STATUS_E_INVAL; 14635 } 14636 num_mac_phy_chainmask_caps += 14637 chainmask_table[i].num_valid_chainmasks; 14638 } 14639 14640 if (num_mac_phy_chainmask_caps > 14641 param_buf->num_mac_phy_chainmask_caps) { 14642 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 14643 num_mac_phy_chainmask_caps, 14644 param_buf->num_mac_phy_chainmask_caps); 14645 return QDF_STATUS_E_INVAL; 14646 } 14647 14648 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 14649 14650 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 14651 i); 14652 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 14653 14654 chainmask_table[i].cap_list[j].chainmask = 14655 chainmask_caps->chainmask; 14656 14657 chainmask_table[i].cap_list[j].supports_chan_width_20 = 14658 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 14659 14660 chainmask_table[i].cap_list[j].supports_chan_width_40 = 14661 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 14662 14663 chainmask_table[i].cap_list[j].supports_chan_width_80 = 14664 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 14665 14666 chainmask_table[i].cap_list[j].supports_chan_width_160 = 14667 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 14668 14669 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 14670 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 14671 14672 chainmask_table[i].cap_list[j].chain_mask_2G = 14673 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 14674 14675 chainmask_table[i].cap_list[j].chain_mask_5G = 14676 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 14677 14678 chainmask_table[i].cap_list[j].chain_mask_tx = 14679 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 14680 14681 chainmask_table[i].cap_list[j].chain_mask_rx = 14682 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 14683 14684 chainmask_table[i].cap_list[j].supports_aDFS = 14685 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 14686 14687 chainmask_table[i].cap_list[j].supports_aSpectral = 14688 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 14689 14690 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 14691 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 14692 14693 chainmask_table[i].cap_list[j].supports_aDFS_160 = 14694 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 14695 14696 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 14697 chainmask_caps); 14698 14699 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 14700 chainmask_caps->supported_flags, 14701 chainmask_caps->chainmask); 14702 chainmask_caps++; 14703 } 14704 } 14705 14706 return QDF_STATUS_SUCCESS; 14707 } 14708 14709 /** 14710 * extract_service_ready_ext_tlv() - extract basic extended service ready params 14711 * from event 14712 * @wmi_handle: wmi handle 14713 * @event: pointer to event buffer 14714 * @param: Pointer to hold evt buf 14715 * 14716 * Return: QDF_STATUS_SUCCESS for success or error code 14717 */ 14718 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 14719 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 14720 { 14721 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14722 wmi_service_ready_ext_event_fixed_param *ev; 14723 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14724 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 14725 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 14726 uint8_t i = 0; 14727 14728 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14729 if (!param_buf) 14730 return QDF_STATUS_E_INVAL; 14731 14732 ev = param_buf->fixed_param; 14733 if (!ev) 14734 return QDF_STATUS_E_INVAL; 14735 14736 /* Move this to host based bitmap */ 14737 param->default_conc_scan_config_bits = 14738 ev->default_conc_scan_config_bits; 14739 param->default_fw_config_bits = ev->default_fw_config_bits; 14740 param->he_cap_info = ev->he_cap_info; 14741 param->mpdu_density = ev->mpdu_density; 14742 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 14743 param->fw_build_vers_ext = ev->fw_build_vers_ext; 14744 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14745 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 14746 param->max_bssid_indicator = ev->max_bssid_indicator; 14747 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 14748 14749 hw_caps = param_buf->soc_hw_mode_caps; 14750 if (hw_caps) 14751 param->num_hw_modes = hw_caps->num_hw_modes; 14752 else 14753 param->num_hw_modes = 0; 14754 14755 reg_caps = param_buf->soc_hal_reg_caps; 14756 if (reg_caps) 14757 param->num_phy = reg_caps->num_phy; 14758 else 14759 param->num_phy = 0; 14760 14761 if (hw_caps) { 14762 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 14763 wmi_nofl_debug("Num chain mask tables: %d", 14764 hw_caps->num_chainmask_tables); 14765 } else 14766 param->num_chainmask_tables = 0; 14767 14768 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 14769 param->num_chainmask_tables > 14770 param_buf->num_mac_phy_chainmask_combo) { 14771 wmi_err_rl("num_chainmask_tables is OOB: %u", 14772 param->num_chainmask_tables); 14773 return QDF_STATUS_E_INVAL; 14774 } 14775 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 14776 14777 if (!chain_mask_combo) 14778 return QDF_STATUS_SUCCESS; 14779 14780 wmi_nofl_info_high("Dumping chain mask combo data"); 14781 14782 for (i = 0; i < param->num_chainmask_tables; i++) { 14783 14784 wmi_nofl_info_high("table_id : %d Num valid chainmasks: %d", 14785 chain_mask_combo->chainmask_table_id, 14786 chain_mask_combo->num_valid_chainmask); 14787 14788 param->chainmask_table[i].table_id = 14789 chain_mask_combo->chainmask_table_id; 14790 param->chainmask_table[i].num_valid_chainmasks = 14791 chain_mask_combo->num_valid_chainmask; 14792 chain_mask_combo++; 14793 } 14794 wmi_nofl_info_high("chain mask combo end"); 14795 14796 return QDF_STATUS_SUCCESS; 14797 } 14798 14799 #if defined(CONFIG_AFC_SUPPORT) 14800 /** 14801 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 14802 * type from event 14803 * @ev: pointer to event fixed param 14804 * @param: Pointer to hold the params 14805 * 14806 * Return: void 14807 */ 14808 static void 14809 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14810 struct wlan_psoc_host_service_ext2_param *param) 14811 { 14812 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 14813 enum reg_afc_dev_deploy_type reg_afc_dev_type; 14814 14815 tgt_afc_dev_type = ev->afc_deployment_type; 14816 switch (tgt_afc_dev_type) { 14817 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 14818 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14819 break; 14820 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 14821 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14822 break; 14823 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 14824 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 14825 break; 14826 default: 14827 wmi_err("invalid afc deployment %d", tgt_afc_dev_type); 14828 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 14829 break; 14830 } 14831 param->afc_dev_type = reg_afc_dev_type; 14832 14833 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 14834 } 14835 #else 14836 static inline void 14837 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14838 struct wlan_psoc_host_service_ext2_param *param) 14839 { 14840 } 14841 #endif 14842 14843 /** 14844 * extract_ul_mumimo_support() - extract UL-MUMIMO capability from target cap 14845 * @param: Pointer to hold the params 14846 * 14847 * Return: Void 14848 */ 14849 static void 14850 extract_ul_mumimo_support(struct wlan_psoc_host_service_ext2_param *param) 14851 { 14852 uint32_t tgt_cap = param->target_cap_flags; 14853 14854 param->ul_mumimo_rx_2g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_2GHZ_GET(tgt_cap); 14855 param->ul_mumimo_rx_5g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_5GHZ_GET(tgt_cap); 14856 param->ul_mumimo_rx_6g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_6GHZ_GET(tgt_cap); 14857 param->ul_mumimo_tx_2g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_2GHZ_GET(tgt_cap); 14858 param->ul_mumimo_tx_5g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_5GHZ_GET(tgt_cap); 14859 param->ul_mumimo_tx_6g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_6GHZ_GET(tgt_cap); 14860 } 14861 14862 /** 14863 * extract_hw_bdf_status() - extract service ready ext2 BDF hw status 14864 * type from event 14865 * @ev: pointer to event fixed param 14866 * 14867 * Return: void 14868 */ 14869 14870 static void 14871 extract_hw_bdf_status(wmi_service_ready_ext2_event_fixed_param *ev) 14872 { 14873 uint8_t hw_bdf_s; 14874 14875 hw_bdf_s = ev->hw_bd_status; 14876 switch (hw_bdf_s) { 14877 case WMI_BDF_VERSION_CHECK_DISABLED: 14878 wmi_info("BDF VER is %d, FW and BDF ver check skipped", 14879 hw_bdf_s); 14880 break; 14881 case WMI_BDF_VERSION_CHECK_GOOD: 14882 wmi_info("BDF VER is %d, FW and BDF ver check good", 14883 hw_bdf_s); 14884 break; 14885 case WMI_BDF_VERSION_TEMPLATE_TOO_OLD: 14886 wmi_info("BDF VER is %d, BDF ver is older than the oldest version supported by FW", 14887 hw_bdf_s); 14888 break; 14889 case WMI_BDF_VERSION_TEMPLATE_TOO_NEW: 14890 wmi_info("BDF VER is %d, BDF ver is newer than the newest version supported by FW", 14891 hw_bdf_s); 14892 break; 14893 case WMI_BDF_VERSION_FW_TOO_OLD: 14894 wmi_info("BDF VER is %d, FW ver is older than the major version supported by BDF", 14895 hw_bdf_s); 14896 break; 14897 case WMI_BDF_VERSION_FW_TOO_NEW: 14898 wmi_info("BDF VER is %d, FW ver is newer than the minor version supported by BDF", 14899 hw_bdf_s); 14900 break; 14901 default: 14902 wmi_info("unknown BDF VER %d", hw_bdf_s); 14903 break; 14904 } 14905 } 14906 14907 #ifdef QCA_MULTIPASS_SUPPORT 14908 static void 14909 extract_multipass_sap_cap(struct wlan_psoc_host_service_ext2_param *param, 14910 uint32_t target_cap_flag) 14911 { 14912 param->is_multipass_sap = 14913 WMI_TARGET_CAP_MULTIPASS_SAP_SUPPORT_GET(target_cap_flag); 14914 } 14915 #else 14916 static void 14917 extract_multipass_sap_cap(struct wlan_psoc_host_service_ext2_param *param, 14918 uint32_t target_cap_flag) 14919 { 14920 } 14921 #endif 14922 14923 #if defined(WLAN_FEATURE_11BE_MLO_ADV_FEATURE) 14924 static inline void 14925 extract_num_max_mlo_link(wmi_service_ready_ext2_event_fixed_param *ev, 14926 struct wlan_psoc_host_service_ext2_param *param) 14927 { 14928 param->num_max_mlo_link_per_ml_bss_supp = 14929 ev->num_max_mlo_link_per_ml_bss_supp; 14930 14931 wmi_debug("Firmware Max MLO link support: %d", 14932 param->num_max_mlo_link_per_ml_bss_supp); 14933 } 14934 #else 14935 static inline void 14936 extract_num_max_mlo_link(wmi_service_ready_ext2_event_fixed_param *ev, 14937 struct wlan_psoc_host_service_ext2_param *param) 14938 { 14939 } 14940 #endif 14941 14942 /** 14943 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 14944 * event 14945 * @wmi_handle: wmi handle 14946 * @event: pointer to event buffer 14947 * @param: Pointer to hold the params 14948 * 14949 * Return: QDF_STATUS_SUCCESS for success or error code 14950 */ 14951 static QDF_STATUS 14952 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 14953 struct wlan_psoc_host_service_ext2_param *param) 14954 { 14955 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14956 wmi_service_ready_ext2_event_fixed_param *ev; 14957 14958 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14959 if (!param_buf) 14960 return QDF_STATUS_E_INVAL; 14961 14962 ev = param_buf->fixed_param; 14963 if (!ev) 14964 return QDF_STATUS_E_INVAL; 14965 14966 param->reg_db_version_major = 14967 WMI_REG_DB_VERSION_MAJOR_GET( 14968 ev->reg_db_version); 14969 param->reg_db_version_minor = 14970 WMI_REG_DB_VERSION_MINOR_GET( 14971 ev->reg_db_version); 14972 param->bdf_reg_db_version_major = 14973 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 14974 ev->reg_db_version); 14975 param->bdf_reg_db_version_minor = 14976 WMI_BDF_REG_DB_VERSION_MINOR_GET( 14977 ev->reg_db_version); 14978 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 14979 14980 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14981 14982 param->num_msdu_idx_qtype_map = 14983 param_buf->num_htt_msdu_idx_to_qtype_map; 14984 14985 if (param_buf->nan_cap) { 14986 param->max_ndp_sessions = 14987 param_buf->nan_cap->max_ndp_sessions; 14988 param->max_nan_pairing_sessions = 14989 param_buf->nan_cap->max_pairing_sessions; 14990 } else { 14991 param->max_ndp_sessions = 0; 14992 param->max_nan_pairing_sessions = 0; 14993 } 14994 14995 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 14996 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 14997 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 14998 ev->max_user_per_ppdu_ofdma); 14999 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 15000 ev->max_user_per_ppdu_ofdma); 15001 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 15002 ev->max_user_per_ppdu_mumimo); 15003 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 15004 ev->max_user_per_ppdu_mumimo); 15005 param->target_cap_flags = ev->target_cap_flags; 15006 15007 param->dp_peer_meta_data_ver = 15008 WMI_TARGET_CAP_FLAGS_RX_PEER_METADATA_VERSION_GET( 15009 ev->target_cap_flags); 15010 15011 extract_multipass_sap_cap(param, ev->target_cap_flags); 15012 15013 extract_ul_mumimo_support(param); 15014 wmi_debug("htt peer data :%d", ev->target_cap_flags); 15015 15016 extract_svc_rdy_ext2_afc_tlv(ev, param); 15017 15018 extract_hw_bdf_status(ev); 15019 15020 extract_num_max_mlo_link(ev, param); 15021 15022 param->num_aux_dev_caps = param_buf->num_aux_dev_caps; 15023 15024 return QDF_STATUS_SUCCESS; 15025 } 15026 15027 /* 15028 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 15029 * service ready ext 2 15030 * 15031 * @wmi_handle: wmi handle 15032 * @event: pointer to event buffer 15033 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 15034 * it indicates async SBS mode is supported, and 15035 * lower-band/higher band to MAC mapping is 15036 * switch-able. unit: mhz. examples 5180, 5320 15037 * 15038 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15039 */ 15040 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 15041 wmi_unified_t wmi_handle, uint8_t *event, 15042 uint32_t *sbs_lower_band_end_freq) 15043 { 15044 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15045 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 15046 15047 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15048 if (!param_buf) 15049 return QDF_STATUS_E_INVAL; 15050 15051 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 15052 if (!dbs_or_sbs_caps) 15053 return QDF_STATUS_E_INVAL; 15054 15055 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 15056 15057 return QDF_STATUS_SUCCESS; 15058 } 15059 15060 /** 15061 * extract_sar_cap_service_ready_ext_tlv() - 15062 * extract SAR cap from service ready event 15063 * @wmi_handle: wmi handle 15064 * @event: pointer to event buffer 15065 * @ext_param: extended target info 15066 * 15067 * Return: QDF_STATUS_SUCCESS for success or error code 15068 */ 15069 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 15070 wmi_unified_t wmi_handle, 15071 uint8_t *event, 15072 struct wlan_psoc_host_service_ext_param *ext_param) 15073 { 15074 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15075 WMI_SAR_CAPABILITIES *sar_caps; 15076 15077 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 15078 15079 if (!param_buf) 15080 return QDF_STATUS_E_INVAL; 15081 15082 sar_caps = param_buf->sar_caps; 15083 if (sar_caps) 15084 ext_param->sar_version = sar_caps->active_version; 15085 else 15086 ext_param->sar_version = 0; 15087 15088 return QDF_STATUS_SUCCESS; 15089 } 15090 15091 /** 15092 * extract_hw_mode_cap_service_ready_ext_tlv() - 15093 * extract HW mode cap from service ready event 15094 * @wmi_handle: wmi handle 15095 * @event: pointer to event buffer 15096 * @hw_mode_idx: hw mode idx should be less than num_mode 15097 * @param: Pointer to hold evt buf 15098 * 15099 * Return: QDF_STATUS_SUCCESS for success or error code 15100 */ 15101 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 15102 wmi_unified_t wmi_handle, 15103 uint8_t *event, uint8_t hw_mode_idx, 15104 struct wlan_psoc_host_hw_mode_caps *param) 15105 { 15106 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15107 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 15108 15109 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 15110 if (!param_buf) 15111 return QDF_STATUS_E_INVAL; 15112 15113 hw_caps = param_buf->soc_hw_mode_caps; 15114 if (!hw_caps) 15115 return QDF_STATUS_E_INVAL; 15116 15117 if (!hw_caps->num_hw_modes || 15118 !param_buf->hw_mode_caps || 15119 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 15120 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 15121 return QDF_STATUS_E_INVAL; 15122 15123 if (hw_mode_idx >= hw_caps->num_hw_modes) 15124 return QDF_STATUS_E_INVAL; 15125 15126 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 15127 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 15128 15129 param->hw_mode_config_type = 15130 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 15131 15132 return QDF_STATUS_SUCCESS; 15133 } 15134 15135 /** 15136 * extract_service_ready_11be_support() - api to extract 11be support 15137 * @param: host mac phy capabilities 15138 * @mac_phy_caps: mac phy capabilities 15139 * 15140 * Return: void 15141 */ 15142 #ifdef WLAN_FEATURE_11BE 15143 static void 15144 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 15145 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 15146 { 15147 param->supports_11be = 15148 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 15149 15150 wmi_debug("11be support %d", param->supports_11be); 15151 } 15152 #else 15153 static void 15154 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 15155 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 15156 { 15157 } 15158 #endif 15159 15160 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 15161 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 15162 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 15163 { 15164 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 15165 } 15166 #else 15167 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 15168 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 15169 { 15170 } 15171 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 15172 15173 /** 15174 * extract_mac_phy_cap_service_ready_ext_tlv() - 15175 * extract MAC phy cap from service ready event 15176 * @wmi_handle: wmi handle 15177 * @event: pointer to event buffer 15178 * @hw_mode_id: hw mode idx should be less than num_mode 15179 * @phy_id: phy id within hw_mode 15180 * @param: Pointer to hold evt buf 15181 * 15182 * Return: QDF_STATUS_SUCCESS for success or error code 15183 */ 15184 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 15185 wmi_unified_t wmi_handle, 15186 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 15187 struct wlan_psoc_host_mac_phy_caps *param) 15188 { 15189 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15190 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 15191 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 15192 uint32_t phy_map; 15193 uint8_t hw_idx, phy_idx = 0, pdev_id; 15194 15195 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 15196 if (!param_buf) 15197 return QDF_STATUS_E_INVAL; 15198 15199 hw_caps = param_buf->soc_hw_mode_caps; 15200 if (!hw_caps) 15201 return QDF_STATUS_E_INVAL; 15202 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 15203 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 15204 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 15205 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 15206 return QDF_STATUS_E_INVAL; 15207 } 15208 15209 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 15210 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 15211 break; 15212 15213 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 15214 while (phy_map) { 15215 phy_map >>= 1; 15216 phy_idx++; 15217 } 15218 } 15219 15220 if (hw_idx == hw_caps->num_hw_modes) 15221 return QDF_STATUS_E_INVAL; 15222 15223 phy_idx += phy_id; 15224 if (phy_idx >= param_buf->num_mac_phy_caps) 15225 return QDF_STATUS_E_INVAL; 15226 15227 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 15228 15229 param->hw_mode_id = mac_phy_caps->hw_mode_id; 15230 param->phy_idx = phy_idx; 15231 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 15232 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15233 wmi_handle, 15234 pdev_id); 15235 param->tgt_pdev_id = pdev_id; 15236 extract_hw_link_id(param, mac_phy_caps); 15237 param->phy_id = mac_phy_caps->phy_id; 15238 param->supports_11b = 15239 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 15240 param->supports_11g = 15241 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 15242 param->supports_11a = 15243 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 15244 param->supports_11n = 15245 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 15246 param->supports_11ac = 15247 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 15248 param->supports_11ax = 15249 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 15250 15251 extract_service_ready_11be_support(param, mac_phy_caps); 15252 15253 param->supported_bands = mac_phy_caps->supported_bands; 15254 param->ampdu_density = mac_phy_caps->ampdu_density; 15255 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 15256 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 15257 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 15258 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 15259 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 15260 mac_phy_caps->he_cap_info_2G; 15261 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 15262 mac_phy_caps->he_cap_info_2G_ext; 15263 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 15264 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 15265 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 15266 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 15267 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 15268 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 15269 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 15270 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 15271 mac_phy_caps->he_cap_info_5G; 15272 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 15273 mac_phy_caps->he_cap_info_5G_ext; 15274 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 15275 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 15276 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 15277 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 15278 qdf_mem_copy(¶m->he_cap_phy_info_2G, 15279 &mac_phy_caps->he_cap_phy_info_2G, 15280 sizeof(param->he_cap_phy_info_2G)); 15281 qdf_mem_copy(¶m->he_cap_phy_info_5G, 15282 &mac_phy_caps->he_cap_phy_info_5G, 15283 sizeof(param->he_cap_phy_info_5G)); 15284 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 15285 sizeof(param->he_ppet2G)); 15286 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 15287 sizeof(param->he_ppet5G)); 15288 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 15289 param->lmac_id = mac_phy_caps->lmac_id; 15290 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 15291 (mac_phy_caps->wireless_modes); 15292 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 15293 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 15294 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 15295 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 15296 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 15297 mac_phy_caps->nss_ratio); 15298 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 15299 15300 return QDF_STATUS_SUCCESS; 15301 } 15302 15303 #ifdef WLAN_FEATURE_11BE_MLO 15304 /** 15305 * extract_mac_phy_emlcap() - API to extract EML Capabilities 15306 * @param: host ext2 mac phy capabilities 15307 * @mac_phy_caps: ext mac phy capabilities 15308 * 15309 * Return: void 15310 */ 15311 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15312 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15313 { 15314 if (!param || !mac_phy_caps) 15315 return; 15316 15317 param->emlcap.emlsr_supp = WMI_SUPPORT_EMLSR_GET(mac_phy_caps->eml_capability); 15318 param->emlcap.emlsr_pad_delay = WMI_EMLSR_PADDING_DELAY_GET(mac_phy_caps->eml_capability); 15319 param->emlcap.emlsr_trans_delay = WMI_EMLSR_TRANSITION_DELAY_GET(mac_phy_caps->eml_capability); 15320 param->emlcap.emlmr_supp = WMI_SUPPORT_EMLMR_GET(mac_phy_caps->eml_capability); 15321 param->emlcap.emlmr_delay = WMI_EMLMR_DELAY_GET(mac_phy_caps->eml_capability); 15322 param->emlcap.trans_timeout = WMI_TRANSITION_TIMEOUT_GET(mac_phy_caps->eml_capability); 15323 } 15324 15325 /** 15326 * extract_mac_phy_mldcap() - API to extract MLD Capabilities 15327 * @param: host ext2 mac phy capabilities 15328 * @mac_phy_caps: ext mac phy capabilities 15329 * 15330 * Return: void 15331 */ 15332 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15333 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15334 { 15335 if (!param || !mac_phy_caps) 15336 return; 15337 15338 param->mldcap.max_simult_link = WMI_MAX_NUM_SIMULTANEOUS_LINKS_GET(mac_phy_caps->mld_capability); 15339 param->mldcap.srs_support = WMI_SUPPORT_SRS_GET(mac_phy_caps->mld_capability); 15340 param->mldcap.tid2link_neg_support = WMI_TID_TO_LINK_NEGOTIATION_GET(mac_phy_caps->mld_capability); 15341 param->mldcap.str_freq_sep = WMI_FREQ_SEPERATION_STR_GET(mac_phy_caps->mld_capability); 15342 param->mldcap.aar_support = WMI_SUPPORT_AAR_GET(mac_phy_caps->mld_capability); 15343 } 15344 15345 /** 15346 * extract_mac_phy_msdcap() - API to extract MSD Capabilities 15347 * @param: host ext2 mac phy capabilities 15348 * @mac_phy_caps: ext mac phy capabilities 15349 * 15350 * Return: void 15351 */ 15352 static void extract_mac_phy_msdcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15353 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15354 { 15355 if (!param || !mac_phy_caps) 15356 return; 15357 15358 param->msdcap.medium_sync_duration = WMI_MEDIUM_SYNC_DURATION_GET(mac_phy_caps->msd_capability); 15359 param->msdcap.medium_sync_ofdm_ed_thresh = WMI_MEDIUM_SYNC_OFDM_ED_THRESHOLD_GET(mac_phy_caps->msd_capability); 15360 param->msdcap.medium_sync_max_txop_num = WMI_MEDIUM_SYNC_MAX_NO_TXOPS_GET(mac_phy_caps->msd_capability); 15361 } 15362 #else 15363 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15364 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15365 { 15366 } 15367 15368 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15369 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15370 { 15371 } 15372 15373 static void extract_mac_phy_msdcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15374 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15375 { 15376 } 15377 #endif 15378 15379 /** 15380 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 15381 * @param: host ext2 mac phy capabilities 15382 * @mac_phy_caps: ext mac phy capabilities 15383 * 15384 * Return: void 15385 */ 15386 #ifdef WLAN_FEATURE_11BE 15387 static void extract_mac_phy_cap_ehtcaps( 15388 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15389 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15390 { 15391 uint32_t i; 15392 15393 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 15394 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 15395 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 15396 15397 qdf_mem_copy(¶m->eht_cap_info_2G, 15398 &mac_phy_caps->eht_cap_mac_info_2G, 15399 sizeof(param->eht_cap_info_2G)); 15400 qdf_mem_copy(¶m->eht_cap_info_5G, 15401 &mac_phy_caps->eht_cap_mac_info_5G, 15402 sizeof(param->eht_cap_info_5G)); 15403 15404 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 15405 &mac_phy_caps->eht_cap_phy_info_2G, 15406 sizeof(param->eht_cap_phy_info_2G)); 15407 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 15408 &mac_phy_caps->eht_cap_phy_info_5G, 15409 sizeof(param->eht_cap_phy_info_5G)); 15410 15411 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 15412 &mac_phy_caps->eht_supp_mcs_ext_2G, 15413 sizeof(param->eht_supp_mcs_ext_2G)); 15414 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 15415 &mac_phy_caps->eht_supp_mcs_ext_5G, 15416 sizeof(param->eht_supp_mcs_ext_5G)); 15417 15418 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 15419 sizeof(param->eht_ppet2G)); 15420 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 15421 sizeof(param->eht_ppet5G)); 15422 15423 wmi_debug("EHT mac caps: mac cap_info_2G %x, mac cap_info_5G %x, supp_mcs_2G %x, supp_mcs_5G %x, info_internal %x", 15424 mac_phy_caps->eht_cap_mac_info_2G[0], 15425 mac_phy_caps->eht_cap_mac_info_5G[0], 15426 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 15427 mac_phy_caps->eht_cap_info_internal); 15428 15429 wmi_nofl_debug("EHT phy caps: "); 15430 15431 wmi_nofl_debug("2G:"); 15432 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 15433 wmi_nofl_debug("index %d value %x", 15434 i, param->eht_cap_phy_info_2G[i]); 15435 } 15436 wmi_nofl_debug("5G:"); 15437 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 15438 wmi_nofl_debug("index %d value %x", 15439 i, param->eht_cap_phy_info_5G[i]); 15440 } 15441 wmi_nofl_debug("2G MCS ext Map:"); 15442 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 15443 wmi_nofl_debug("index %d value %x", 15444 i, param->eht_supp_mcs_ext_2G[i]); 15445 } 15446 wmi_nofl_debug("5G MCS ext Map:"); 15447 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 15448 wmi_nofl_debug("index %d value %x", 15449 i, param->eht_supp_mcs_ext_5G[i]); 15450 } 15451 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 15452 param->eht_ppet2G.numss_m1, 15453 param->eht_ppet2G.ru_bit_mask); 15454 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 15455 wmi_nofl_debug("index %d value %x", 15456 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 15457 } 15458 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 15459 param->eht_ppet5G.numss_m1, 15460 param->eht_ppet5G.ru_bit_mask); 15461 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 15462 wmi_nofl_debug("index %d value %x", 15463 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 15464 } 15465 } 15466 #else 15467 static void extract_mac_phy_cap_ehtcaps( 15468 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15469 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15470 { 15471 } 15472 #endif 15473 15474 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 15475 wmi_unified_t wmi_handle, 15476 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 15477 uint8_t phy_idx, 15478 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 15479 { 15480 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15481 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 15482 15483 if (!event) { 15484 wmi_err("null evt_buf"); 15485 return QDF_STATUS_E_INVAL; 15486 } 15487 15488 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15489 15490 if (!param_buf->num_mac_phy_caps) 15491 return QDF_STATUS_SUCCESS; 15492 15493 if (phy_idx >= param_buf->num_mac_phy_caps) 15494 return QDF_STATUS_E_INVAL; 15495 15496 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 15497 15498 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 15499 (phy_id != mac_phy_caps->phy_id)) 15500 return QDF_STATUS_E_INVAL; 15501 15502 param->hw_mode_id = mac_phy_caps->hw_mode_id; 15503 param->phy_id = mac_phy_caps->phy_id; 15504 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15505 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 15506 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 15507 mac_phy_caps->wireless_modes_ext); 15508 15509 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 15510 extract_mac_phy_emlcap(param, mac_phy_caps); 15511 extract_mac_phy_mldcap(param, mac_phy_caps); 15512 extract_mac_phy_msdcap(param, mac_phy_caps); 15513 15514 return QDF_STATUS_SUCCESS; 15515 } 15516 15517 /** 15518 * extract_reg_cap_service_ready_ext_tlv() - 15519 * extract REG cap from service ready event 15520 * @wmi_handle: wmi handle 15521 * @event: pointer to event buffer 15522 * @phy_idx: phy idx should be less than num_mode 15523 * @param: Pointer to hold evt buf 15524 * 15525 * Return: QDF_STATUS_SUCCESS for success or error code 15526 */ 15527 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 15528 wmi_unified_t wmi_handle, 15529 uint8_t *event, uint8_t phy_idx, 15530 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 15531 { 15532 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15533 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 15534 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 15535 15536 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 15537 if (!param_buf) 15538 return QDF_STATUS_E_INVAL; 15539 15540 reg_caps = param_buf->soc_hal_reg_caps; 15541 if (!reg_caps) 15542 return QDF_STATUS_E_INVAL; 15543 15544 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 15545 return QDF_STATUS_E_INVAL; 15546 15547 if (phy_idx >= reg_caps->num_phy) 15548 return QDF_STATUS_E_INVAL; 15549 15550 if (!param_buf->hal_reg_caps) 15551 return QDF_STATUS_E_INVAL; 15552 15553 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 15554 15555 param->phy_id = ext_reg_cap->phy_id; 15556 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 15557 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 15558 param->regcap1 = ext_reg_cap->regcap1; 15559 param->regcap2 = ext_reg_cap->regcap2; 15560 param->wireless_modes = convert_wireless_modes_tlv( 15561 ext_reg_cap->wireless_modes); 15562 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 15563 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 15564 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 15565 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 15566 15567 return QDF_STATUS_SUCCESS; 15568 } 15569 15570 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 15571 uint8_t num_dma_ring_caps) 15572 { 15573 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 15574 if (!num_dma_ring_caps) { 15575 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 15576 return QDF_STATUS_E_INVAL; 15577 } 15578 if (idx >= num_dma_ring_caps) { 15579 wmi_err("Index %d exceeds range", idx); 15580 return QDF_STATUS_E_INVAL; 15581 } 15582 return QDF_STATUS_SUCCESS; 15583 } 15584 15585 static void 15586 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 15587 struct wlan_psoc_host_dbr_ring_caps *param, 15588 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 15589 { 15590 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 15591 wmi_handle, 15592 dbr_ring_caps->pdev_id); 15593 param->mod_id = dbr_ring_caps->mod_id; 15594 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 15595 param->min_buf_size = dbr_ring_caps->min_buf_size; 15596 param->min_buf_align = dbr_ring_caps->min_buf_align; 15597 } 15598 15599 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 15600 wmi_unified_t wmi_handle, 15601 uint8_t *event, uint8_t idx, 15602 struct wlan_psoc_host_dbr_ring_caps *param) 15603 { 15604 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15605 QDF_STATUS status; 15606 15607 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 15608 if (!param_buf) 15609 return QDF_STATUS_E_INVAL; 15610 15611 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 15612 if (status != QDF_STATUS_SUCCESS) 15613 return status; 15614 15615 populate_dbr_ring_cap_elems(wmi_handle, param, 15616 ¶m_buf->dma_ring_caps[idx]); 15617 return QDF_STATUS_SUCCESS; 15618 } 15619 15620 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 15621 wmi_unified_t wmi_handle, 15622 uint8_t *event, uint8_t idx, 15623 struct wlan_psoc_host_dbr_ring_caps *param) 15624 { 15625 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15626 QDF_STATUS status; 15627 15628 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15629 if (!param_buf) 15630 return QDF_STATUS_E_INVAL; 15631 15632 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 15633 if (status != QDF_STATUS_SUCCESS) 15634 return status; 15635 15636 populate_dbr_ring_cap_elems(wmi_handle, param, 15637 ¶m_buf->dma_ring_caps[idx]); 15638 return QDF_STATUS_SUCCESS; 15639 } 15640 15641 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 15642 wmi_unified_t wmi_handle, 15643 uint8_t *event, uint8_t idx, 15644 struct wlan_psoc_host_scan_radio_caps *param) 15645 { 15646 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15647 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 15648 15649 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15650 if (!param_buf) 15651 return QDF_STATUS_E_INVAL; 15652 15653 if (idx >= param_buf->num_wmi_scan_radio_caps) 15654 return QDF_STATUS_E_INVAL; 15655 15656 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 15657 param->phy_id = scan_radio_caps->phy_id; 15658 param->scan_radio_supported = 15659 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 15660 param->dfs_en = 15661 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 15662 param->blanking_en = 15663 WMI_SCAN_RADIO_CAP_BLANKING_SUPPORT_GET(scan_radio_caps->flags); 15664 15665 return QDF_STATUS_SUCCESS; 15666 } 15667 15668 static QDF_STATUS extract_msdu_idx_qtype_map_service_ready_ext2_tlv( 15669 wmi_unified_t wmi_handle, 15670 uint8_t *event, uint8_t idx, 15671 uint8_t *msdu_qtype) 15672 { 15673 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15674 wmi_htt_msdu_idx_to_htt_msdu_qtype *msdu_idx_to_qtype; 15675 uint8_t wmi_htt_msdu_idx; 15676 15677 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15678 if (!param_buf) 15679 return QDF_STATUS_E_INVAL; 15680 15681 if (idx >= param_buf->num_htt_msdu_idx_to_qtype_map) 15682 return QDF_STATUS_E_INVAL; 15683 15684 msdu_idx_to_qtype = ¶m_buf->htt_msdu_idx_to_qtype_map[idx]; 15685 wmi_htt_msdu_idx = 15686 WMI_HTT_MSDUQ_IDX_TO_MSDUQ_QTYPE_INDEX_GET( 15687 msdu_idx_to_qtype->index_and_type); 15688 if (wmi_htt_msdu_idx != idx) { 15689 wmi_err("wmi_htt_msdu_idx 0x%x is not same as idx 0x%x", 15690 wmi_htt_msdu_idx, idx); 15691 return QDF_STATUS_E_INVAL; 15692 } 15693 15694 *msdu_qtype = 15695 WMI_HTT_MSDUQ_IDX_TO_MSDUQ_QTYPE_TYPE_GET( 15696 msdu_idx_to_qtype->index_and_type); 15697 15698 return QDF_STATUS_SUCCESS; 15699 } 15700 15701 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 15702 uint8_t *event, 15703 struct wmi_host_sw_cal_ver *cal) 15704 { 15705 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15706 wmi_sw_cal_ver_cap *fw_cap; 15707 15708 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15709 if (!param_buf) 15710 return QDF_STATUS_E_INVAL; 15711 15712 fw_cap = param_buf->sw_cal_ver_cap; 15713 if (!fw_cap) 15714 return QDF_STATUS_E_INVAL; 15715 15716 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 15717 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 15718 cal->status = fw_cap->status; 15719 15720 return QDF_STATUS_SUCCESS; 15721 } 15722 15723 static QDF_STATUS extract_aux_dev_cap_service_ready_ext2_tlv( 15724 wmi_unified_t wmi_handle, 15725 uint8_t *event, uint8_t idx, 15726 struct wlan_psoc_host_aux_dev_caps *param) 15727 15728 { 15729 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15730 wmi_aux_dev_capabilities *aux_dev_caps; 15731 15732 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15733 15734 if (!param_buf->num_aux_dev_caps) 15735 return QDF_STATUS_E_INVAL; 15736 15737 if (!param_buf->aux_dev_caps) { 15738 wmi_err("aux_dev_caps is NULL"); 15739 return QDF_STATUS_E_INVAL; 15740 } 15741 15742 if (idx >= param_buf->num_aux_dev_caps) 15743 return QDF_STATUS_E_INVAL; 15744 15745 aux_dev_caps = ¶m_buf->aux_dev_caps[idx]; 15746 15747 param->aux_index = aux_dev_caps->aux_index; 15748 param->hw_mode_id = aux_dev_caps->hw_mode_id; 15749 param->supported_modes_bitmap = aux_dev_caps->supported_modes_bitmap; 15750 param->listen_pdev_id_map = aux_dev_caps->listen_pdev_id_map; 15751 param->emlsr_pdev_id_map = aux_dev_caps->emlsr_pdev_id_map; 15752 15753 wmi_info("idx %u aux_index %u, hw_mode_id %u, supported_modes_bitmap 0x%x, listen_pdev_id_map 0x%x, emlsr_pdev_id_map 0x%x", 15754 idx, aux_dev_caps->aux_index, 15755 aux_dev_caps->hw_mode_id, 15756 aux_dev_caps->supported_modes_bitmap, 15757 aux_dev_caps->listen_pdev_id_map, 15758 aux_dev_caps->emlsr_pdev_id_map); 15759 15760 return QDF_STATUS_SUCCESS; 15761 } 15762 15763 /** 15764 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 15765 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 15766 * 15767 * Return: host thermal throt level 15768 */ 15769 static enum thermal_throttle_level 15770 wmi_tgt_thermal_level_to_host(uint32_t level) 15771 { 15772 switch (level) { 15773 case WMI_THERMAL_FULLPERF: 15774 return THERMAL_FULLPERF; 15775 case WMI_THERMAL_MITIGATION: 15776 return THERMAL_MITIGATION; 15777 case WMI_THERMAL_SHUTOFF: 15778 return THERMAL_SHUTOFF; 15779 case WMI_THERMAL_SHUTDOWN_TGT: 15780 return THERMAL_SHUTDOWN_TARGET; 15781 default: 15782 return THERMAL_UNKNOWN; 15783 } 15784 } 15785 15786 #ifdef THERMAL_STATS_SUPPORT 15787 static void 15788 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 15789 uint32_t *therm_throt_levels, 15790 struct thermal_throt_level_stats *tt_temp_range_stats) 15791 { 15792 uint8_t lvl_idx; 15793 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 15794 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 15795 15796 tt_stats_event = param_buf->fixed_param; 15797 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 15798 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 15799 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 15800 tt_stats_event->therm_throt_levels; 15801 15802 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 15803 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 15804 *therm_throt_levels, 15805 param_buf->num_temp_range_stats); 15806 return; 15807 } 15808 15809 wmi_tt_stats = param_buf->temp_range_stats; 15810 if (!wmi_tt_stats) { 15811 wmi_err("wmi_tt_stats Null"); 15812 return; 15813 } 15814 15815 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 15816 tt_temp_range_stats[lvl_idx].start_temp_level = 15817 wmi_tt_stats[lvl_idx].start_temp_level; 15818 tt_temp_range_stats[lvl_idx].end_temp_level = 15819 wmi_tt_stats[lvl_idx].end_temp_level; 15820 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 15821 wmi_tt_stats[lvl_idx].total_time_ms_lo; 15822 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 15823 wmi_tt_stats[lvl_idx].total_time_ms_hi; 15824 tt_temp_range_stats[lvl_idx].num_entry = 15825 wmi_tt_stats[lvl_idx].num_entry; 15826 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 15827 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 15828 wmi_tt_stats[lvl_idx].end_temp_level, 15829 wmi_tt_stats[lvl_idx].total_time_ms_lo, 15830 wmi_tt_stats[lvl_idx].total_time_ms_hi, 15831 wmi_tt_stats[lvl_idx].num_entry); 15832 } 15833 } 15834 #else 15835 static void 15836 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 15837 uint32_t *therm_throt_levels, 15838 struct thermal_throt_level_stats *tt_temp_range_stats) 15839 { 15840 } 15841 #endif 15842 15843 /** 15844 * extract_thermal_stats_tlv() - extract thermal stats from event 15845 * @wmi_handle: wmi handle 15846 * @evt_buf: Pointer to event buffer 15847 * @temp: Pointer to hold extracted temperature 15848 * @level: Pointer to hold extracted level in host enum 15849 * @therm_throt_levels: Pointer to hold extracted thermal throttle temp 15850 * range 15851 * @tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 15852 * every level 15853 * @pdev_id: Pointer to hold extracted pdev id 15854 * 15855 * Return: QDF_STATUS_SUCCESS for success or error code 15856 */ 15857 static QDF_STATUS 15858 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 15859 void *evt_buf, uint32_t *temp, 15860 enum thermal_throttle_level *level, 15861 uint32_t *therm_throt_levels, 15862 struct thermal_throt_level_stats *tt_temp_range_stats_event, 15863 uint32_t *pdev_id) 15864 { 15865 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 15866 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 15867 15868 param_buf = 15869 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 15870 if (!param_buf) 15871 return QDF_STATUS_E_INVAL; 15872 15873 tt_stats_event = param_buf->fixed_param; 15874 wmi_debug("thermal temperature %d level %d", 15875 tt_stats_event->temp, tt_stats_event->level); 15876 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15877 wmi_handle, 15878 tt_stats_event->pdev_id); 15879 *temp = tt_stats_event->temp; 15880 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 15881 15882 if (tt_stats_event->therm_throt_levels) 15883 populate_thermal_stats(param_buf, therm_throt_levels, 15884 tt_temp_range_stats_event); 15885 15886 return QDF_STATUS_SUCCESS; 15887 } 15888 15889 /** 15890 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 15891 * @wmi_handle: wmi handle 15892 * @evt_buf: pointer to event buffer 15893 * @idx: Index to level stats 15894 * @levelcount: Pointer to hold levelcount 15895 * @dccount: Pointer to hold dccount 15896 * 15897 * Return: QDF_STATUS_SUCCESS for success or error code 15898 */ 15899 static QDF_STATUS 15900 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 15901 void *evt_buf, uint8_t idx, uint32_t *levelcount, 15902 uint32_t *dccount) 15903 { 15904 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 15905 wmi_therm_throt_level_stats_info *tt_level_info; 15906 15907 param_buf = 15908 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 15909 if (!param_buf) 15910 return QDF_STATUS_E_INVAL; 15911 15912 tt_level_info = param_buf->therm_throt_level_stats_info; 15913 15914 if (idx < THERMAL_LEVELS) { 15915 *levelcount = tt_level_info[idx].level_count; 15916 *dccount = tt_level_info[idx].dc_count; 15917 return QDF_STATUS_SUCCESS; 15918 } 15919 15920 return QDF_STATUS_E_FAILURE; 15921 } 15922 15923 /** 15924 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 15925 * @data_len: data length 15926 * @data: pointer to data 15927 * 15928 * Return: QDF_STATUS - success or error status 15929 */ 15930 #ifdef BIG_ENDIAN_HOST 15931 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15932 { 15933 uint8_t *data_aligned = NULL; 15934 int c; 15935 unsigned char *data_unaligned; 15936 15937 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 15938 FIPS_ALIGN)); 15939 /* Assigning unaligned space to copy the data */ 15940 /* Checking if kmalloc does successful allocation */ 15941 if (!data_unaligned) 15942 return QDF_STATUS_E_FAILURE; 15943 15944 /* Checking if space is aligned */ 15945 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 15946 /* align the data space */ 15947 data_aligned = 15948 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 15949 } else { 15950 data_aligned = (u_int8_t *)data_unaligned; 15951 } 15952 15953 /* memset and copy content from data to data aligned */ 15954 OS_MEMSET(data_aligned, 0, data_len); 15955 OS_MEMCPY(data_aligned, data, data_len); 15956 /* Endianness to LE */ 15957 for (c = 0; c < data_len/4; c++) { 15958 *((u_int32_t *)data_aligned + c) = 15959 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 15960 } 15961 15962 /* Copy content to event->data */ 15963 OS_MEMCPY(data, data_aligned, data_len); 15964 15965 /* clean up allocated space */ 15966 qdf_mem_free(data_unaligned); 15967 data_aligned = NULL; 15968 data_unaligned = NULL; 15969 15970 /*************************************************************/ 15971 15972 return QDF_STATUS_SUCCESS; 15973 } 15974 #else 15975 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15976 { 15977 return QDF_STATUS_SUCCESS; 15978 } 15979 #endif 15980 15981 /** 15982 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 15983 * @wmi_handle: wmi handle 15984 * @params: PN request params for peer 15985 * 15986 * Return: QDF_STATUS - success or error status 15987 */ 15988 static QDF_STATUS 15989 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 15990 struct peer_request_pn_param *params) 15991 { 15992 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 15993 wmi_buf_t buf; 15994 uint8_t *buf_ptr; 15995 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 15996 15997 buf = wmi_buf_alloc(wmi_handle, len); 15998 if (!buf) { 15999 wmi_err("wmi_buf_alloc failed"); 16000 return QDF_STATUS_E_FAILURE; 16001 } 16002 16003 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16004 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 16005 16006 WMITLV_SET_HDR(&cmd->tlv_header, 16007 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 16008 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 16009 16010 cmd->vdev_id = params->vdev_id; 16011 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 16012 cmd->key_type = params->key_type; 16013 cmd->key_ix = params->keyix; 16014 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16015 WMI_PEER_TX_PN_REQUEST_CMDID)) { 16016 wmi_err("Failed to send WMI command"); 16017 wmi_buf_free(buf); 16018 return QDF_STATUS_E_FAILURE; 16019 } 16020 return QDF_STATUS_SUCCESS; 16021 } 16022 16023 /** 16024 * extract_get_pn_data_tlv() - extract pn resp 16025 * @wmi_handle: wmi handle 16026 * @evt_buf: pointer to event buffer 16027 * @param: PN response params for peer 16028 * 16029 * Return: QDF_STATUS - success or error status 16030 */ 16031 static QDF_STATUS 16032 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16033 struct wmi_host_get_pn_event *param) 16034 { 16035 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 16036 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 16037 16038 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 16039 event = 16040 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 16041 16042 param->vdev_id = event->vdev_id; 16043 param->key_type = event->key_type; 16044 param->key_ix = event->key_ix; 16045 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 16046 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 16047 16048 return QDF_STATUS_SUCCESS; 16049 } 16050 16051 /** 16052 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 16053 * @wmi_handle: wmi handle 16054 * @params: Rx PN request params for peer 16055 * 16056 * Return: QDF_STATUS - success or error status 16057 */ 16058 static QDF_STATUS 16059 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 16060 struct peer_request_rxpn_param *params) 16061 { 16062 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 16063 wmi_buf_t buf; 16064 uint8_t *buf_ptr; 16065 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 16066 16067 if (!is_service_enabled_tlv(wmi_handle, 16068 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 16069 wmi_err("Rx PN Replay Check not supported by target"); 16070 return QDF_STATUS_E_NOSUPPORT; 16071 } 16072 16073 buf = wmi_buf_alloc(wmi_handle, len); 16074 if (!buf) { 16075 wmi_err("wmi_buf_alloc failed"); 16076 return QDF_STATUS_E_FAILURE; 16077 } 16078 16079 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16080 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 16081 16082 WMITLV_SET_HDR(&cmd->tlv_header, 16083 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 16084 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 16085 16086 cmd->vdev_id = params->vdev_id; 16087 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 16088 cmd->key_ix = params->keyix; 16089 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16090 WMI_PEER_RX_PN_REQUEST_CMDID)) { 16091 wmi_err("Failed to send WMI command"); 16092 wmi_buf_free(buf); 16093 return QDF_STATUS_E_FAILURE; 16094 } 16095 return QDF_STATUS_SUCCESS; 16096 } 16097 16098 /** 16099 * extract_get_rxpn_data_tlv() - extract Rx PN resp 16100 * @wmi_handle: wmi handle 16101 * @evt_buf: pointer to event buffer 16102 * @params: Rx PN response params for peer 16103 * 16104 * Return: QDF_STATUS - success or error status 16105 */ 16106 static QDF_STATUS 16107 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16108 struct wmi_host_get_rxpn_event *params) 16109 { 16110 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 16111 wmi_peer_rx_pn_response_event_fixed_param *event; 16112 16113 param_buf = evt_buf; 16114 event = param_buf->fixed_param; 16115 16116 params->vdev_id = event->vdev_id; 16117 params->keyix = event->key_idx; 16118 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 16119 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 16120 16121 return QDF_STATUS_SUCCESS; 16122 } 16123 16124 /** 16125 * extract_fips_event_data_tlv() - extract fips event data 16126 * @wmi_handle: wmi handle 16127 * @evt_buf: pointer to event buffer 16128 * @param: pointer FIPS event params 16129 * 16130 * Return: QDF_STATUS_SUCCESS for success or error code 16131 */ 16132 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 16133 void *evt_buf, struct wmi_host_fips_event_param *param) 16134 { 16135 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 16136 wmi_pdev_fips_event_fixed_param *event; 16137 16138 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 16139 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 16140 16141 if (event->data_len > param_buf->num_data) 16142 return QDF_STATUS_E_FAILURE; 16143 16144 if (fips_conv_data_be(event->data_len, param_buf->data) != 16145 QDF_STATUS_SUCCESS) 16146 return QDF_STATUS_E_FAILURE; 16147 16148 param->data = (uint32_t *)param_buf->data; 16149 param->data_len = event->data_len; 16150 param->error_status = event->error_status; 16151 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 16152 wmi_handle, 16153 event->pdev_id); 16154 16155 return QDF_STATUS_SUCCESS; 16156 } 16157 16158 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 16159 /** 16160 * extract_fips_extend_event_data_tlv() - extract fips event data 16161 * @wmi_handle: wmi handle 16162 * @evt_buf: pointer to event buffer 16163 * @param: pointer FIPS event params 16164 * 16165 * Return: QDF_STATUS_SUCCESS for success or error code 16166 */ 16167 static QDF_STATUS 16168 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 16169 void *evt_buf, 16170 struct wmi_host_fips_extend_event_param 16171 *param) 16172 { 16173 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 16174 wmi_pdev_fips_extend_event_fixed_param *event; 16175 16176 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 16177 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 16178 16179 if (fips_conv_data_be(event->data_len, param_buf->data) != 16180 QDF_STATUS_SUCCESS) 16181 return QDF_STATUS_E_FAILURE; 16182 16183 param->data = (uint32_t *)param_buf->data; 16184 param->data_len = event->data_len; 16185 param->error_status = event->error_status; 16186 param->fips_cookie = event->fips_cookie; 16187 param->cmd_frag_idx = event->cmd_frag_idx; 16188 param->more_bit = event->more_bit; 16189 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 16190 wmi_handle, 16191 event->pdev_id); 16192 16193 return QDF_STATUS_SUCCESS; 16194 } 16195 #endif 16196 16197 #ifdef WLAN_FEATURE_DISA 16198 /** 16199 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 16200 * params from event 16201 * @wmi_handle: wmi handle 16202 * @evt_buf: pointer to event buffer 16203 * @resp: Pointer to hold resp parameters 16204 * 16205 * Return: QDF_STATUS_SUCCESS for success or error code 16206 */ 16207 static QDF_STATUS 16208 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 16209 void *evt_buf, 16210 struct disa_encrypt_decrypt_resp_params 16211 *resp) 16212 { 16213 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 16214 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 16215 16216 param_buf = evt_buf; 16217 if (!param_buf) { 16218 wmi_err("encrypt decrypt resp evt_buf is NULL"); 16219 return QDF_STATUS_E_INVAL; 16220 } 16221 16222 data_event = param_buf->fixed_param; 16223 16224 resp->vdev_id = data_event->vdev_id; 16225 resp->status = data_event->status; 16226 16227 if ((data_event->data_length > param_buf->num_enc80211_frame) || 16228 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 16229 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 16230 wmi_err("FW msg data_len %d more than TLV hdr %d", 16231 data_event->data_length, 16232 param_buf->num_enc80211_frame); 16233 return QDF_STATUS_E_INVAL; 16234 } 16235 16236 resp->data_len = data_event->data_length; 16237 16238 if (resp->data_len) 16239 resp->data = (uint8_t *)param_buf->enc80211_frame; 16240 16241 return QDF_STATUS_SUCCESS; 16242 } 16243 #endif /* WLAN_FEATURE_DISA */ 16244 16245 static bool is_management_record_tlv(uint32_t cmd_id) 16246 { 16247 switch (cmd_id) { 16248 case WMI_MGMT_TX_SEND_CMDID: 16249 case WMI_MGMT_TX_COMPLETION_EVENTID: 16250 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 16251 case WMI_MGMT_RX_EVENTID: 16252 return true; 16253 default: 16254 return false; 16255 } 16256 } 16257 16258 static bool is_force_fw_hang_cmd_tlv(uint32_t cmd_id) 16259 { 16260 if (cmd_id == WMI_FORCE_FW_HANG_CMDID) 16261 return true; 16262 16263 return false; 16264 } 16265 16266 static bool is_diag_event_tlv(uint32_t event_id) 16267 { 16268 if (WMI_DIAG_EVENTID == event_id) 16269 return true; 16270 16271 return false; 16272 } 16273 16274 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 16275 { 16276 uint16_t tag = 0; 16277 16278 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 16279 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 16280 __func__); 16281 return tag; 16282 } 16283 16284 if (wmi_handle->tag_crash_inject) 16285 tag = HTC_TX_PACKET_TAG_AUTO_PM; 16286 16287 wmi_handle->tag_crash_inject = false; 16288 return tag; 16289 } 16290 16291 /** 16292 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 16293 * @wmi_handle: WMI handle 16294 * @buf: WMI buffer 16295 * @cmd_id: WMI command Id 16296 * 16297 * Return: htc_tx_tag 16298 */ 16299 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 16300 wmi_buf_t buf, 16301 uint32_t cmd_id) 16302 { 16303 uint16_t htc_tx_tag = 0; 16304 16305 switch (cmd_id) { 16306 case WMI_WOW_ENABLE_CMDID: 16307 case WMI_PDEV_SUSPEND_CMDID: 16308 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 16309 case WMI_PDEV_RESUME_CMDID: 16310 case WMI_HB_SET_ENABLE_CMDID: 16311 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 16312 #ifdef FEATURE_WLAN_D0WOW 16313 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 16314 #endif 16315 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 16316 break; 16317 case WMI_FORCE_FW_HANG_CMDID: 16318 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 16319 break; 16320 default: 16321 break; 16322 } 16323 16324 return htc_tx_tag; 16325 } 16326 16327 #ifdef CONFIG_BAND_6GHZ 16328 16329 static struct cur_reg_rule 16330 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 16331 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 16332 { 16333 struct cur_reg_rule *reg_rule_ptr; 16334 uint32_t count; 16335 16336 if (!num_reg_rules) 16337 return NULL; 16338 16339 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 16340 sizeof(*reg_rule_ptr)); 16341 16342 if (!reg_rule_ptr) 16343 return NULL; 16344 16345 for (count = 0; count < num_reg_rules; count++) { 16346 reg_rule_ptr[count].start_freq = 16347 WMI_REG_RULE_START_FREQ_GET( 16348 wmi_reg_rule[count].freq_info); 16349 reg_rule_ptr[count].end_freq = 16350 WMI_REG_RULE_END_FREQ_GET( 16351 wmi_reg_rule[count].freq_info); 16352 reg_rule_ptr[count].max_bw = 16353 WMI_REG_RULE_MAX_BW_GET( 16354 wmi_reg_rule[count].bw_pwr_info); 16355 reg_rule_ptr[count].reg_power = 16356 WMI_REG_RULE_REG_POWER_GET( 16357 wmi_reg_rule[count].bw_pwr_info); 16358 reg_rule_ptr[count].ant_gain = 16359 WMI_REG_RULE_ANTENNA_GAIN_GET( 16360 wmi_reg_rule[count].bw_pwr_info); 16361 reg_rule_ptr[count].flags = 16362 WMI_REG_RULE_FLAGS_GET( 16363 wmi_reg_rule[count].flag_info); 16364 reg_rule_ptr[count].psd_flag = 16365 WMI_REG_RULE_PSD_FLAG_GET( 16366 wmi_reg_rule[count].psd_power_info); 16367 reg_rule_ptr[count].psd_eirp = 16368 WMI_REG_RULE_PSD_EIRP_GET( 16369 wmi_reg_rule[count].psd_power_info); 16370 } 16371 16372 return reg_rule_ptr; 16373 } 16374 #endif 16375 16376 static struct cur_reg_rule 16377 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 16378 wmi_regulatory_rule_struct *wmi_reg_rule) 16379 { 16380 struct cur_reg_rule *reg_rule_ptr; 16381 uint32_t count; 16382 16383 if (!num_reg_rules) 16384 return NULL; 16385 16386 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 16387 sizeof(*reg_rule_ptr)); 16388 16389 if (!reg_rule_ptr) 16390 return NULL; 16391 16392 for (count = 0; count < num_reg_rules; count++) { 16393 reg_rule_ptr[count].start_freq = 16394 WMI_REG_RULE_START_FREQ_GET( 16395 wmi_reg_rule[count].freq_info); 16396 reg_rule_ptr[count].end_freq = 16397 WMI_REG_RULE_END_FREQ_GET( 16398 wmi_reg_rule[count].freq_info); 16399 reg_rule_ptr[count].max_bw = 16400 WMI_REG_RULE_MAX_BW_GET( 16401 wmi_reg_rule[count].bw_pwr_info); 16402 reg_rule_ptr[count].reg_power = 16403 WMI_REG_RULE_REG_POWER_GET( 16404 wmi_reg_rule[count].bw_pwr_info); 16405 reg_rule_ptr[count].ant_gain = 16406 WMI_REG_RULE_ANTENNA_GAIN_GET( 16407 wmi_reg_rule[count].bw_pwr_info); 16408 reg_rule_ptr[count].flags = 16409 WMI_REG_RULE_FLAGS_GET( 16410 wmi_reg_rule[count].flag_info); 16411 } 16412 16413 return reg_rule_ptr; 16414 } 16415 16416 static enum cc_setting_code wmi_reg_status_to_reg_status( 16417 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 16418 { 16419 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) { 16420 wmi_nofl_debug("REG_SET_CC_STATUS_PASS"); 16421 return REG_SET_CC_STATUS_PASS; 16422 } else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) { 16423 wmi_nofl_debug("WMI_REG_CURRENT_ALPHA2_NOT_FOUND"); 16424 return REG_CURRENT_ALPHA2_NOT_FOUND; 16425 } else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) { 16426 wmi_nofl_debug("WMI_REG_INIT_ALPHA2_NOT_FOUND"); 16427 return REG_INIT_ALPHA2_NOT_FOUND; 16428 } else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) { 16429 wmi_nofl_debug("WMI_REG_SET_CC_CHANGE_NOT_ALLOWED"); 16430 return REG_SET_CC_CHANGE_NOT_ALLOWED; 16431 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) { 16432 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_NO_MEMORY"); 16433 return REG_SET_CC_STATUS_NO_MEMORY; 16434 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) { 16435 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_FAIL"); 16436 return REG_SET_CC_STATUS_FAIL; 16437 } 16438 16439 wmi_debug("Unknown reg status code from WMI"); 16440 return REG_SET_CC_STATUS_FAIL; 16441 } 16442 16443 #ifdef CONFIG_BAND_6GHZ 16444 /** 16445 * reg_print_ap_power_type_6ghz - Prints the AP Power type 16446 * @ap_type: 6ghz-AP Power type 16447 * 16448 * Return: void 16449 */ 16450 static void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 16451 { 16452 switch (ap_type) { 16453 case REG_INDOOR_AP: 16454 wmi_nofl_debug("AP Power type %s", "LOW POWER INDOOR"); 16455 break; 16456 case REG_STANDARD_POWER_AP: 16457 wmi_nofl_debug("AP Power type %s", "STANDARD POWER"); 16458 break; 16459 case REG_VERY_LOW_POWER_AP: 16460 wmi_nofl_debug("AP Power type %s", "VERY LOW POWER INDOOR"); 16461 break; 16462 default: 16463 wmi_nofl_debug("Invalid AP Power type %u", ap_type); 16464 } 16465 } 16466 16467 /** 16468 * reg_print_6ghz_client_type - Prints the client type 16469 * @client_type: 6ghz-client type 16470 * 16471 * Return: void 16472 */ 16473 static void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 16474 { 16475 switch (client_type) { 16476 case REG_DEFAULT_CLIENT: 16477 wmi_nofl_debug("Client type %s", "DEFAULT CLIENT"); 16478 break; 16479 case REG_SUBORDINATE_CLIENT: 16480 wmi_nofl_debug("Client type %s", "SUBORDINATE CLIENT"); 16481 break; 16482 default: 16483 wmi_nofl_debug("Invalid Client type %u", client_type); 16484 } 16485 } 16486 #else 16487 static inline void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 16488 { 16489 } 16490 16491 static inline void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 16492 { 16493 } 16494 #endif /* CONFIG_BAND_6GHZ */ 16495 16496 #ifdef CONFIG_BAND_6GHZ 16497 16498 #ifdef CONFIG_REG_CLIENT 16499 #define MAX_NUM_FCC_RULES 2 16500 16501 /** 16502 * extract_ext_fcc_rules_from_wmi - extract fcc rules from WMI TLV 16503 * @num_fcc_rules: Number of FCC rules 16504 * @wmi_fcc_rule: WMI FCC rules TLV 16505 * 16506 * Return: fcc_rule_ptr 16507 */ 16508 static struct cur_fcc_rule 16509 *extract_ext_fcc_rules_from_wmi(uint32_t num_fcc_rules, 16510 wmi_regulatory_fcc_rule_struct *wmi_fcc_rule) 16511 { 16512 struct cur_fcc_rule *fcc_rule_ptr; 16513 uint32_t count; 16514 16515 if (!wmi_fcc_rule) 16516 return NULL; 16517 16518 fcc_rule_ptr = qdf_mem_malloc(num_fcc_rules * 16519 sizeof(*fcc_rule_ptr)); 16520 if (!fcc_rule_ptr) 16521 return NULL; 16522 16523 for (count = 0; count < num_fcc_rules; count++) { 16524 fcc_rule_ptr[count].center_freq = 16525 WMI_REG_FCC_RULE_CHAN_FREQ_GET( 16526 wmi_fcc_rule[count].freq_info); 16527 fcc_rule_ptr[count].tx_power = 16528 WMI_REG_FCC_RULE_FCC_TX_POWER_GET( 16529 wmi_fcc_rule[count].freq_info); 16530 } 16531 16532 return fcc_rule_ptr; 16533 } 16534 16535 /** 16536 * extract_reg_fcc_rules_tlv - Extract reg fcc rules TLV 16537 * @param_buf: Pointer to WMI params TLV 16538 * @ext_chan_list_event_hdr: Pointer to REG CHAN LIST CC EXT EVENT Fixed 16539 * Params TLV 16540 * @ext_wmi_reg_rule: Pointer to REG CHAN LIST CC EXT EVENT Reg Rules TLV 16541 * @ext_wmi_chan_priority: Pointer to REG CHAN LIST CC EXT EVENT Chan 16542 * Priority TLV 16543 * @evt_buf: Pointer to REG CHAN LIST CC EXT EVENT event buffer 16544 * @reg_info: Pointer to Regulatory Info 16545 * @len: Length of REG CHAN LIST CC EXT EVENT buffer 16546 * 16547 * Return: QDF_STATUS 16548 */ 16549 static QDF_STATUS extract_reg_fcc_rules_tlv( 16550 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 16551 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 16552 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 16553 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 16554 uint8_t *evt_buf, 16555 struct cur_regulatory_info *reg_info, 16556 uint32_t len) 16557 { 16558 int i; 16559 wmi_regulatory_fcc_rule_struct *ext_wmi_fcc_rule; 16560 16561 if (!param_buf) { 16562 wmi_err("invalid channel list event buf"); 16563 return QDF_STATUS_E_INVAL; 16564 } 16565 16566 reg_info->num_fcc_rules = 0; 16567 if (param_buf->reg_fcc_rule) { 16568 if (param_buf->num_reg_fcc_rule > MAX_NUM_FCC_RULES) { 16569 wmi_err("Number of fcc rules is greater than MAX_NUM_FCC_RULES"); 16570 return QDF_STATUS_E_INVAL; 16571 } 16572 16573 ext_wmi_fcc_rule = 16574 (wmi_regulatory_fcc_rule_struct *) 16575 ((uint8_t *)ext_chan_list_event_hdr + 16576 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 16577 WMI_TLV_HDR_SIZE + 16578 sizeof(wmi_regulatory_rule_ext_struct) * 16579 param_buf->num_reg_rule_array + 16580 WMI_TLV_HDR_SIZE + 16581 sizeof(wmi_regulatory_chan_priority_struct) * 16582 param_buf->num_reg_chan_priority + 16583 WMI_TLV_HDR_SIZE); 16584 16585 reg_info->fcc_rules_ptr = extract_ext_fcc_rules_from_wmi( 16586 param_buf->num_reg_fcc_rule, 16587 ext_wmi_fcc_rule); 16588 16589 reg_info->num_fcc_rules = param_buf->num_reg_fcc_rule; 16590 } else { 16591 wmi_err("Fcc rules not sent by fw"); 16592 } 16593 16594 if (reg_info->fcc_rules_ptr) { 16595 for (i = 0; i < reg_info->num_fcc_rules; i++) { 16596 wmi_nofl_debug("FCC rule %d center_freq %d tx_power %d", 16597 i, reg_info->fcc_rules_ptr[i].center_freq, 16598 reg_info->fcc_rules_ptr[i].tx_power); 16599 } 16600 } 16601 return QDF_STATUS_SUCCESS; 16602 } 16603 #else 16604 static QDF_STATUS extract_reg_fcc_rules_tlv( 16605 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 16606 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 16607 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 16608 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 16609 uint8_t *evt_buf, 16610 struct cur_regulatory_info *reg_info, 16611 uint32_t len) 16612 { 16613 return QDF_STATUS_SUCCESS; 16614 } 16615 #endif 16616 16617 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 16618 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16619 struct cur_regulatory_info *reg_info, uint32_t len) 16620 { 16621 uint32_t i, j, k; 16622 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 16623 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 16624 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 16625 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 16626 uint32_t num_2g_reg_rules, num_5g_reg_rules; 16627 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 16628 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 16629 uint32_t total_reg_rules = 0; 16630 QDF_STATUS status; 16631 16632 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 16633 if (!param_buf) { 16634 wmi_err("invalid channel list event buf"); 16635 return QDF_STATUS_E_FAILURE; 16636 } 16637 16638 ext_chan_list_event_hdr = param_buf->fixed_param; 16639 ext_wmi_chan_priority = param_buf->reg_chan_priority; 16640 16641 if (ext_wmi_chan_priority) 16642 reg_info->reg_6g_thresh_priority_freq = 16643 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 16644 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 16645 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 16646 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 16647 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 16648 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 16649 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 16650 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 16651 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 16652 16653 wmi_debug("num reg rules from fw, AP SP %d, LPI %d, VLP %d", 16654 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16655 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 16656 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16657 16658 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16659 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 16660 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 16661 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 16662 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 16663 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 16664 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 16665 wmi_nofl_debug("client %d SP %d, LPI %d, VLP %d", i, 16666 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 16667 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 16668 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 16669 } 16670 16671 num_2g_reg_rules = reg_info->num_2g_reg_rules; 16672 total_reg_rules += num_2g_reg_rules; 16673 num_5g_reg_rules = reg_info->num_5g_reg_rules; 16674 total_reg_rules += num_5g_reg_rules; 16675 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 16676 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 16677 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 16678 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 16679 num_6g_reg_rules_ap[i]); 16680 return QDF_STATUS_E_FAILURE; 16681 } 16682 total_reg_rules += num_6g_reg_rules_ap[i]; 16683 num_6g_reg_rules_client[i] = 16684 reg_info->num_6g_reg_rules_client[i]; 16685 } 16686 16687 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16688 total_reg_rules += 16689 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 16690 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 16691 total_reg_rules += 16692 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 16693 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 16694 MAX_6G_REG_RULES) || 16695 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 16696 MAX_6G_REG_RULES) || 16697 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 16698 MAX_6G_REG_RULES)) { 16699 wmi_err_rl("Invalid num_6g_reg_rules_client_sp: %u, num_6g_reg_rules_client_lpi: %u, num_6g_reg_rules_client_vlp: %u, client %d", 16700 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 16701 num_6g_reg_rules_client[REG_INDOOR_AP][i], 16702 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 16703 i); 16704 return QDF_STATUS_E_FAILURE; 16705 } 16706 } 16707 16708 if (total_reg_rules != param_buf->num_reg_rule_array) { 16709 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 16710 total_reg_rules, param_buf->num_reg_rule_array); 16711 return QDF_STATUS_E_FAILURE; 16712 } 16713 16714 if ((num_2g_reg_rules > MAX_REG_RULES) || 16715 (num_5g_reg_rules > MAX_REG_RULES)) { 16716 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 16717 num_2g_reg_rules, num_5g_reg_rules); 16718 return QDF_STATUS_E_FAILURE; 16719 } 16720 16721 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 16722 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 16723 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 16724 wmi_err_rl("Invalid num_6g_reg_rules_ap_sp: %u, num_6g_reg_rules_ap_lpi: %u, num_6g_reg_rules_ap_vlp: %u", 16725 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16726 num_6g_reg_rules_ap[REG_INDOOR_AP], 16727 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16728 return QDF_STATUS_E_FAILURE; 16729 } 16730 16731 if (param_buf->num_reg_rule_array > 16732 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 16733 sizeof(*ext_wmi_reg_rule)) { 16734 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 16735 param_buf->num_reg_rule_array); 16736 return QDF_STATUS_E_FAILURE; 16737 } 16738 16739 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 16740 REG_ALPHA2_LEN); 16741 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 16742 reg_info->phybitmap = convert_phybitmap_tlv( 16743 ext_chan_list_event_hdr->phybitmap); 16744 reg_info->offload_enabled = true; 16745 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 16746 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16747 wmi_handle, ext_chan_list_event_hdr->phy_id); 16748 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 16749 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 16750 16751 reg_info->status_code = 16752 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 16753 status_code); 16754 16755 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 16756 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 16757 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 16758 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 16759 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 16760 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 16761 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 16762 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 16763 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 16764 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 16765 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 16766 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 16767 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 16768 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 16769 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 16770 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 16771 16772 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16773 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 16774 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 16775 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 16776 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 16777 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 16778 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 16779 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 16780 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 16781 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 16782 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 16783 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 16784 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 16785 } 16786 16787 wmi_nofl_debug("num_phys = %u and phy_id = %u", 16788 reg_info->num_phy, reg_info->phy_id); 16789 16790 wmi_nofl_debug("cc %s dfs_region %d reg_dmn_pair %x BW: min_2g %d max_2g %d min_5g %d max_5g %d", 16791 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 16792 reg_info->min_bw_2g, reg_info->max_bw_2g, reg_info->min_bw_5g, 16793 reg_info->max_bw_5g); 16794 16795 wmi_nofl_debug("min_bw_6g_ap_sp %d max_bw_6g_ap_sp %d min_bw_6g_ap_lpi %d max_bw_6g_ap_lpi %d min_bw_6g_ap_vlp %d max_bw_6g_ap_vlp %d", 16796 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 16797 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 16798 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 16799 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 16800 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 16801 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 16802 16803 wmi_nofl_debug("min_bw_6g_def_cli_sp %d max_bw_6g_def_cli_sp %d min_bw_6g_def_cli_lpi %d max_bw_6g_def_cli_lpi %d min_bw_6g_def_cli_vlp %d max_bw_6g_def_cli_vlp %d", 16804 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16805 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16806 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16807 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16808 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 16809 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 16810 16811 wmi_nofl_debug("min_bw_6g_sub_client_sp %d max_bw_6g_sub_client_sp %d min_bw_6g_sub_client_lpi %d max_bw_6g_sub_client_lpi %d min_bw_6g_sub_client_vlp %d max_bw_6g_sub_client_vlp %d", 16812 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16813 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16814 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16815 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16816 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 16817 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 16818 16819 wmi_nofl_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 16820 num_2g_reg_rules, num_5g_reg_rules); 16821 16822 wmi_nofl_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 16823 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16824 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 16825 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16826 16827 wmi_nofl_debug("num_6g_def_cli_sp_reg_rules %d num_6g_def_cli_lpi_reg_rules %d num_6g_def_cli_vlp_reg_rules %d", 16828 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16829 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16830 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 16831 16832 wmi_nofl_debug("num_6g_sub_cli_sp_reg_rules %d num_6g_sub_cli_lpi_reg_rules %d num_6g_sub_cli_vlp_reg_rules %d", 16833 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16834 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16835 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 16836 16837 ext_wmi_reg_rule = 16838 (wmi_regulatory_rule_ext_struct *) 16839 ((uint8_t *)ext_chan_list_event_hdr + 16840 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 16841 WMI_TLV_HDR_SIZE); 16842 reg_info->reg_rules_2g_ptr = 16843 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 16844 ext_wmi_reg_rule); 16845 ext_wmi_reg_rule += num_2g_reg_rules; 16846 if (!num_2g_reg_rules) 16847 wmi_nofl_debug("No 2ghz reg rule"); 16848 for (i = 0; i < num_2g_reg_rules; i++) { 16849 if (!reg_info->reg_rules_2g_ptr) 16850 break; 16851 wmi_nofl_debug("2 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u psd_flag %u psd_eirp %u", 16852 i, reg_info->reg_rules_2g_ptr[i].start_freq, 16853 reg_info->reg_rules_2g_ptr[i].end_freq, 16854 reg_info->reg_rules_2g_ptr[i].max_bw, 16855 reg_info->reg_rules_2g_ptr[i].reg_power, 16856 reg_info->reg_rules_2g_ptr[i].ant_gain, 16857 reg_info->reg_rules_2g_ptr[i].flags, 16858 reg_info->reg_rules_2g_ptr[i].psd_flag, 16859 reg_info->reg_rules_2g_ptr[i].psd_eirp); 16860 } 16861 reg_info->reg_rules_5g_ptr = 16862 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 16863 ext_wmi_reg_rule); 16864 ext_wmi_reg_rule += num_5g_reg_rules; 16865 if (!num_5g_reg_rules) 16866 wmi_nofl_debug("No 5ghz reg rule"); 16867 for (i = 0; i < num_5g_reg_rules; i++) { 16868 if (!reg_info->reg_rules_5g_ptr) 16869 break; 16870 wmi_nofl_debug("5 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u psd_flag %u psd_eirp %u", 16871 i, reg_info->reg_rules_5g_ptr[i].start_freq, 16872 reg_info->reg_rules_5g_ptr[i].end_freq, 16873 reg_info->reg_rules_5g_ptr[i].max_bw, 16874 reg_info->reg_rules_5g_ptr[i].reg_power, 16875 reg_info->reg_rules_5g_ptr[i].ant_gain, 16876 reg_info->reg_rules_5g_ptr[i].flags, 16877 reg_info->reg_rules_5g_ptr[i].psd_flag, 16878 reg_info->reg_rules_5g_ptr[i].psd_eirp); 16879 } 16880 16881 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 16882 reg_print_ap_power_type_6ghz(i); 16883 reg_info->reg_rules_6g_ap_ptr[i] = 16884 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 16885 ext_wmi_reg_rule); 16886 16887 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 16888 if (!num_6g_reg_rules_ap[i]) 16889 wmi_nofl_debug("No 6ghz reg rule"); 16890 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 16891 if (!reg_info->reg_rules_6g_ap_ptr[i]) 16892 break; 16893 wmi_nofl_debug("AP 6GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u psd_flag %u psd_eirp %u", 16894 j, reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 16895 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 16896 reg_info->reg_rules_6g_ap_ptr[i][j].max_bw, 16897 reg_info->reg_rules_6g_ap_ptr[i][j].reg_power, 16898 reg_info->reg_rules_6g_ap_ptr[i][j].ant_gain, 16899 reg_info->reg_rules_6g_ap_ptr[i][j].flags, 16900 reg_info->reg_rules_6g_ap_ptr[i][j].psd_flag, 16901 reg_info->reg_rules_6g_ap_ptr[i][j].psd_eirp); 16902 } 16903 } 16904 16905 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 16906 reg_print_ap_power_type_6ghz(j); 16907 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16908 reg_print_6ghz_client_type(i); 16909 reg_info->reg_rules_6g_client_ptr[j][i] = 16910 create_ext_reg_rules_from_wmi( 16911 num_6g_reg_rules_client[j][i], 16912 ext_wmi_reg_rule); 16913 16914 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 16915 if (!num_6g_reg_rules_client[j][i]) 16916 wmi_nofl_debug("No 6ghz reg rule for [%d][%d]", j, i); 16917 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 16918 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 16919 break; 16920 wmi_nofl_debug("CLI 6GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u psd_flag %u psd_eirp %u", 16921 k, reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 16922 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 16923 reg_info->reg_rules_6g_client_ptr[j][i][k].max_bw, 16924 reg_info->reg_rules_6g_client_ptr[j][i][k].reg_power, 16925 reg_info->reg_rules_6g_client_ptr[j][i][k].ant_gain, 16926 reg_info->reg_rules_6g_client_ptr[j][i][k].flags, 16927 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_flag, 16928 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_eirp); 16929 } 16930 } 16931 } 16932 16933 reg_info->client_type = ext_chan_list_event_hdr->client_type; 16934 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 16935 reg_info->unspecified_ap_usable = 16936 ext_chan_list_event_hdr->unspecified_ap_usable; 16937 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 16938 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 16939 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 16940 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 16941 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 16942 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 16943 16944 wmi_nofl_debug("client type %d, RNR TPE usable %d, unspecified AP usable %d, domain code AP SP %d, LPI %d, VLP %d", 16945 reg_info->client_type, reg_info->rnr_tpe_usable, 16946 reg_info->unspecified_ap_usable, 16947 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 16948 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 16949 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 16950 16951 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16952 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 16953 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 16954 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 16955 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 16956 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 16957 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 16958 wmi_nofl_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 16959 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 16960 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 16961 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 16962 } 16963 16964 reg_info->domain_code_6g_super_id = 16965 ext_chan_list_event_hdr->domain_code_6g_super_id; 16966 16967 status = extract_reg_fcc_rules_tlv(param_buf, ext_chan_list_event_hdr, 16968 ext_wmi_reg_rule, ext_wmi_chan_priority, 16969 evt_buf, reg_info, len); 16970 if (status != QDF_STATUS_SUCCESS) 16971 return status; 16972 16973 return QDF_STATUS_SUCCESS; 16974 } 16975 16976 #ifdef CONFIG_AFC_SUPPORT 16977 /** 16978 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 16979 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 16980 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 16981 * an index pointer required to store the current index of 16982 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 16983 * @chan_eirp_info: pointer to chan_eirp_info 16984 * @num_chans: Number of channels 16985 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16986 * @index: Pointer to index 16987 * 16988 * Return: void 16989 */ 16990 static void 16991 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 16992 uint8_t num_chans, 16993 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 16994 uint8_t *index) 16995 { 16996 uint8_t chan_idx; 16997 16998 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 16999 chan_eirp_info[chan_idx].cfi = 17000 chan_eirp_power_info_hdr[*index].channel_cfi; 17001 chan_eirp_info[chan_idx].eirp_power = 17002 chan_eirp_power_info_hdr[*index].eirp_pwr; 17003 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 17004 chan_idx, 17005 chan_eirp_info[chan_idx].cfi, 17006 chan_eirp_info[chan_idx].eirp_power); 17007 } 17008 } 17009 17010 /** 17011 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 17012 * to the internal buffer afc_chan_info. 17013 * @afc_chan_info: pointer to afc_chan_info 17014 * @num_chan_objs: Number of channel objects 17015 * @channel_info_hdr: Pointer to channel_info_hdr 17016 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 17017 * 17018 * Return: void 17019 */ 17020 static void 17021 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 17022 uint8_t num_chan_objs, 17023 wmi_6g_afc_channel_info *channel_info_hdr, 17024 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 17025 { 17026 uint8_t count; 17027 uint8_t src_pwr_index = 0; 17028 17029 for (count = 0; count < num_chan_objs; count++) { 17030 afc_chan_info[count].global_opclass = 17031 channel_info_hdr[count].global_operating_class; 17032 afc_chan_info[count].num_chans = 17033 channel_info_hdr[count].num_channels; 17034 wmi_debug("Chan object count = %d global opclasss = %d", 17035 count, 17036 afc_chan_info[count].global_opclass); 17037 wmi_debug("Number of Channel EIRP objects = %d", 17038 afc_chan_info[count].num_chans); 17039 17040 if (afc_chan_info[count].num_chans > 0) { 17041 struct chan_eirp_obj *chan_eirp_info; 17042 17043 chan_eirp_info = 17044 qdf_mem_malloc(afc_chan_info[count].num_chans * 17045 sizeof(*chan_eirp_info)); 17046 17047 if (!chan_eirp_info) 17048 return; 17049 17050 copy_afc_chan_eirp_info(chan_eirp_info, 17051 afc_chan_info[count].num_chans, 17052 chan_eirp_power_info_hdr, 17053 &src_pwr_index); 17054 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 17055 } else { 17056 wmi_err("Number of channels is zero in object idx %d", 17057 count); 17058 } 17059 } 17060 } 17061 17062 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 17063 uint8_t num_freq_objs, 17064 wmi_6g_afc_frequency_info *freq_info_hdr) 17065 { 17066 uint8_t count; 17067 17068 for (count = 0; count < num_freq_objs; count++) { 17069 afc_freq_info[count].low_freq = 17070 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 17071 afc_freq_info[count].high_freq = 17072 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 17073 afc_freq_info[count].max_psd = 17074 freq_info_hdr[count].psd_power_info; 17075 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 17076 count, 17077 afc_freq_info[count].low_freq, 17078 afc_freq_info[count].high_freq, 17079 afc_freq_info[count].max_psd); 17080 } 17081 } 17082 17083 /** 17084 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 17085 * the power event info from the WMI AFC event buffer to the internal buffer 17086 * power_info. 17087 * @power_info: pointer to power_info 17088 * @afc_power_event_hdr: pointer to afc_power_event_hdr 17089 * 17090 * Return: void 17091 */ 17092 static void 17093 copy_afc_event_fixed_hdr_power_info( 17094 struct reg_fw_afc_power_event *power_info, 17095 wmi_afc_power_event_param *afc_power_event_hdr) 17096 { 17097 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 17098 power_info->resp_id = afc_power_event_hdr->resp_id; 17099 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 17100 power_info->afc_wfa_version = 17101 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 17102 power_info->afc_wfa_version |= 17103 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 17104 17105 power_info->avail_exp_time_d = 17106 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 17107 power_info->avail_exp_time_d |= 17108 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 17109 power_info->avail_exp_time_d |= 17110 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 17111 17112 power_info->avail_exp_time_t = 17113 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 17114 power_info->avail_exp_time_t |= 17115 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 17116 power_info->avail_exp_time_t |= 17117 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 17118 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 17119 power_info->fw_status_code, 17120 power_info->resp_id, 17121 power_info->serv_resp_code); 17122 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 17123 power_info->afc_wfa_version, 17124 power_info->avail_exp_time_d, 17125 power_info->avail_exp_time_t); 17126 } 17127 17128 /** 17129 * copy_power_event() - Copy the power event parameters from the AFC event 17130 * buffer to the power_info within the afc_info. 17131 * @afc_info: pointer to afc_info 17132 * @param_buf: pointer to param_buf 17133 * 17134 * Return: void 17135 */ 17136 static void copy_power_event(struct afc_regulatory_info *afc_info, 17137 WMI_AFC_EVENTID_param_tlvs *param_buf) 17138 { 17139 struct reg_fw_afc_power_event *power_info; 17140 wmi_afc_power_event_param *afc_power_event_hdr; 17141 struct afc_freq_obj *afc_freq_info; 17142 17143 power_info = qdf_mem_malloc(sizeof(*power_info)); 17144 17145 if (!power_info) 17146 return; 17147 17148 afc_power_event_hdr = param_buf->afc_power_event_param; 17149 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 17150 afc_info->power_info = power_info; 17151 17152 power_info->num_freq_objs = param_buf->num_freq_info_array; 17153 wmi_debug("Number of frequency objects = %d", 17154 power_info->num_freq_objs); 17155 if (power_info->num_freq_objs > 0) { 17156 wmi_6g_afc_frequency_info *freq_info_hdr; 17157 17158 freq_info_hdr = param_buf->freq_info_array; 17159 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 17160 sizeof(*afc_freq_info)); 17161 17162 if (!afc_freq_info) 17163 return; 17164 17165 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 17166 freq_info_hdr); 17167 power_info->afc_freq_info = afc_freq_info; 17168 } else { 17169 wmi_err("Number of frequency objects is zero"); 17170 } 17171 17172 power_info->num_chan_objs = param_buf->num_channel_info_array; 17173 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 17174 if (power_info->num_chan_objs > 0) { 17175 struct afc_chan_obj *afc_chan_info; 17176 wmi_6g_afc_channel_info *channel_info_hdr; 17177 17178 channel_info_hdr = param_buf->channel_info_array; 17179 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 17180 sizeof(*afc_chan_info)); 17181 17182 if (!afc_chan_info) 17183 return; 17184 17185 copy_afc_chan_obj_info(afc_chan_info, 17186 power_info->num_chan_objs, 17187 channel_info_hdr, 17188 param_buf->chan_eirp_power_info_array); 17189 power_info->afc_chan_info = afc_chan_info; 17190 } else { 17191 wmi_err("Number of channel objects is zero"); 17192 } 17193 } 17194 17195 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 17196 WMI_AFC_EVENTID_param_tlvs *param_buf) 17197 { 17198 struct reg_afc_expiry_event *expiry_info; 17199 17200 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 17201 17202 if (!expiry_info) 17203 return; 17204 17205 expiry_info->request_id = 17206 param_buf->expiry_event_param->request_id; 17207 expiry_info->event_subtype = 17208 param_buf->expiry_event_param->event_subtype; 17209 wmi_debug("Event subtype %d request ID %d", 17210 expiry_info->event_subtype, 17211 expiry_info->request_id); 17212 afc_info->expiry_info = expiry_info; 17213 } 17214 17215 /** 17216 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 17217 * in the AFC event. 'Common' indicates that these parameters are common for 17218 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 17219 * @wmi_handle: wmi handle 17220 * @afc_info: pointer to afc_info 17221 * @event_fixed_hdr: pointer to event_fixed_hdr 17222 * 17223 * Return: void 17224 */ 17225 static void 17226 copy_afc_event_common_info(wmi_unified_t wmi_handle, 17227 struct afc_regulatory_info *afc_info, 17228 wmi_afc_event_fixed_param *event_fixed_hdr) 17229 { 17230 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 17231 wmi_handle, event_fixed_hdr->phy_id); 17232 wmi_debug("phy_id %d", afc_info->phy_id); 17233 afc_info->event_type = event_fixed_hdr->event_type; 17234 } 17235 17236 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 17237 uint8_t *evt_buf, 17238 struct afc_regulatory_info *afc_info, 17239 uint32_t len) 17240 { 17241 WMI_AFC_EVENTID_param_tlvs *param_buf; 17242 wmi_afc_event_fixed_param *event_fixed_hdr; 17243 17244 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 17245 if (!param_buf) { 17246 wmi_err("Invalid AFC event buf"); 17247 return QDF_STATUS_E_FAILURE; 17248 } 17249 17250 event_fixed_hdr = param_buf->fixed_param; 17251 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 17252 wmi_debug("AFC event type %d received", afc_info->event_type); 17253 17254 switch (afc_info->event_type) { 17255 case WMI_AFC_EVENT_POWER_INFO: 17256 copy_power_event(afc_info, param_buf); 17257 break; 17258 case WMI_AFC_EVENT_TIMER_EXPIRY: 17259 copy_expiry_event(afc_info, param_buf); 17260 return QDF_STATUS_SUCCESS; 17261 default: 17262 wmi_err("Invalid event type"); 17263 return QDF_STATUS_E_FAILURE; 17264 } 17265 17266 return QDF_STATUS_SUCCESS; 17267 } 17268 #endif 17269 #endif 17270 17271 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 17272 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17273 struct cur_regulatory_info *reg_info, uint32_t len) 17274 { 17275 uint32_t i; 17276 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 17277 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 17278 wmi_regulatory_rule_struct *wmi_reg_rule; 17279 uint32_t num_2g_reg_rules, num_5g_reg_rules; 17280 17281 wmi_debug("processing regulatory channel list"); 17282 17283 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 17284 if (!param_buf) { 17285 wmi_err("invalid channel list event buf"); 17286 return QDF_STATUS_E_FAILURE; 17287 } 17288 17289 chan_list_event_hdr = param_buf->fixed_param; 17290 17291 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 17292 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 17293 num_2g_reg_rules = reg_info->num_2g_reg_rules; 17294 num_5g_reg_rules = reg_info->num_5g_reg_rules; 17295 if ((num_2g_reg_rules > MAX_REG_RULES) || 17296 (num_5g_reg_rules > MAX_REG_RULES) || 17297 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 17298 (num_2g_reg_rules + num_5g_reg_rules != 17299 param_buf->num_reg_rule_array)) { 17300 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 17301 num_2g_reg_rules, num_5g_reg_rules); 17302 return QDF_STATUS_E_FAILURE; 17303 } 17304 if (param_buf->num_reg_rule_array > 17305 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 17306 sizeof(*wmi_reg_rule)) { 17307 wmi_err_rl("Invalid num_reg_rule_array: %u", 17308 param_buf->num_reg_rule_array); 17309 return QDF_STATUS_E_FAILURE; 17310 } 17311 17312 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 17313 REG_ALPHA2_LEN); 17314 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 17315 reg_info->phybitmap = convert_phybitmap_tlv( 17316 chan_list_event_hdr->phybitmap); 17317 reg_info->offload_enabled = true; 17318 reg_info->num_phy = chan_list_event_hdr->num_phy; 17319 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 17320 wmi_handle, chan_list_event_hdr->phy_id); 17321 reg_info->ctry_code = chan_list_event_hdr->country_id; 17322 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 17323 17324 reg_info->status_code = 17325 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 17326 17327 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 17328 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 17329 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 17330 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 17331 17332 wmi_debug("num_phys = %u and phy_id = %u", 17333 reg_info->num_phy, reg_info->phy_id); 17334 17335 wmi_debug("cc %s dfs_region %d reg_dmn_pair %x BW: min_2g %d max_2g %d min_5g %d max_5g %d", 17336 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 17337 reg_info->min_bw_2g, reg_info->max_bw_2g, 17338 reg_info->min_bw_5g, reg_info->max_bw_5g); 17339 17340 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 17341 num_2g_reg_rules, num_5g_reg_rules); 17342 wmi_reg_rule = 17343 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 17344 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 17345 + WMI_TLV_HDR_SIZE); 17346 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 17347 wmi_reg_rule); 17348 wmi_reg_rule += num_2g_reg_rules; 17349 if (!num_2g_reg_rules) 17350 wmi_nofl_debug("No 2ghz reg rule"); 17351 for (i = 0; i < num_2g_reg_rules; i++) { 17352 if (!reg_info->reg_rules_2g_ptr) 17353 break; 17354 wmi_nofl_debug("2 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 17355 i, reg_info->reg_rules_2g_ptr[i].start_freq, 17356 reg_info->reg_rules_2g_ptr[i].end_freq, 17357 reg_info->reg_rules_2g_ptr[i].max_bw, 17358 reg_info->reg_rules_2g_ptr[i].reg_power, 17359 reg_info->reg_rules_2g_ptr[i].ant_gain, 17360 reg_info->reg_rules_2g_ptr[i].flags); 17361 } 17362 17363 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 17364 wmi_reg_rule); 17365 if (!num_5g_reg_rules) 17366 wmi_nofl_debug("No 5ghz reg rule"); 17367 for (i = 0; i < num_5g_reg_rules; i++) { 17368 if (!reg_info->reg_rules_5g_ptr) 17369 break; 17370 wmi_nofl_debug("5 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 17371 i, reg_info->reg_rules_5g_ptr[i].start_freq, 17372 reg_info->reg_rules_5g_ptr[i].end_freq, 17373 reg_info->reg_rules_5g_ptr[i].max_bw, 17374 reg_info->reg_rules_5g_ptr[i].reg_power, 17375 reg_info->reg_rules_5g_ptr[i].ant_gain, 17376 reg_info->reg_rules_5g_ptr[i].flags); 17377 } 17378 17379 wmi_debug("processed regulatory channel list"); 17380 17381 return QDF_STATUS_SUCCESS; 17382 } 17383 17384 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 17385 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17386 struct reg_11d_new_country *reg_11d_country, uint32_t len) 17387 { 17388 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 17389 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 17390 17391 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 17392 if (!param_buf) { 17393 wmi_err("invalid 11d country event buf"); 17394 return QDF_STATUS_E_FAILURE; 17395 } 17396 17397 reg_11d_country_event = param_buf->fixed_param; 17398 17399 qdf_mem_copy(reg_11d_country->alpha2, 17400 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 17401 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 17402 17403 wmi_debug("processed 11d country event, new cc %s", 17404 reg_11d_country->alpha2); 17405 17406 return QDF_STATUS_SUCCESS; 17407 } 17408 17409 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 17410 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17411 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 17412 { 17413 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 17414 wmi_avoid_freq_range_desc *afr_desc; 17415 uint32_t num_freq_ranges, freq_range_idx; 17416 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 17417 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 17418 17419 if (!param_buf) { 17420 wmi_err("Invalid channel avoid event buffer"); 17421 return QDF_STATUS_E_INVAL; 17422 } 17423 17424 afr_fixed_param = param_buf->fixed_param; 17425 if (!afr_fixed_param) { 17426 wmi_err("Invalid channel avoid event fixed param buffer"); 17427 return QDF_STATUS_E_INVAL; 17428 } 17429 17430 if (!ch_avoid_ind) { 17431 wmi_err("Invalid channel avoid indication buffer"); 17432 return QDF_STATUS_E_INVAL; 17433 } 17434 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 17435 wmi_err("no.of freq ranges exceeded the limit"); 17436 return QDF_STATUS_E_INVAL; 17437 } 17438 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 17439 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 17440 afr_fixed_param->num_freq_ranges; 17441 17442 wmi_debug("Channel avoid event received with %d ranges", 17443 num_freq_ranges); 17444 17445 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 17446 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 17447 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 17448 freq_range_idx++) { 17449 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 17450 afr_desc->start_freq; 17451 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 17452 afr_desc->end_freq; 17453 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 17454 freq_range_idx, afr_desc->tlv_header, 17455 afr_desc->start_freq, afr_desc->end_freq); 17456 afr_desc++; 17457 } 17458 17459 return QDF_STATUS_SUCCESS; 17460 } 17461 17462 #ifdef DFS_COMPONENT_ENABLE 17463 /** 17464 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 17465 * @wmi_handle: wma handle 17466 * @evt_buf: event buffer 17467 * @vdev_id: vdev id 17468 * @len: length of buffer 17469 * 17470 * Return: QDF_STATUS_SUCCESS for success or error code 17471 */ 17472 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 17473 uint8_t *evt_buf, 17474 uint32_t *vdev_id, 17475 uint32_t len) 17476 { 17477 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 17478 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 17479 17480 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 17481 if (!param_tlvs) { 17482 wmi_err("invalid cac complete event buf"); 17483 return QDF_STATUS_E_FAILURE; 17484 } 17485 17486 cac_event = param_tlvs->fixed_param; 17487 *vdev_id = cac_event->vdev_id; 17488 wmi_debug("processed cac complete event vdev %d", *vdev_id); 17489 17490 return QDF_STATUS_SUCCESS; 17491 } 17492 17493 /** 17494 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 17495 * @wmi_handle: wma handle 17496 * @evt_buf: event buffer 17497 * @param: extracted event 17498 * 17499 * Return: QDF_STATUS_SUCCESS for success or error code 17500 */ 17501 static QDF_STATUS 17502 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 17503 uint8_t *evt_buf, 17504 struct vdev_adfs_complete_status *param) 17505 { 17506 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 17507 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 17508 17509 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 17510 if (!param_tlvs) { 17511 wmi_err("invalid ocac complete event buf"); 17512 return QDF_STATUS_E_FAILURE; 17513 } 17514 17515 if (!param_tlvs->fixed_param) { 17516 wmi_err("invalid param_tlvs->fixed_param"); 17517 return QDF_STATUS_E_FAILURE; 17518 } 17519 17520 ocac_complete_status = param_tlvs->fixed_param; 17521 param->vdev_id = ocac_complete_status->vdev_id; 17522 param->chan_freq = ocac_complete_status->chan_freq; 17523 param->center_freq1 = ocac_complete_status->center_freq1; 17524 param->center_freq2 = ocac_complete_status->center_freq2; 17525 param->ocac_status = ocac_complete_status->status; 17526 param->chan_width = ocac_complete_status->chan_width; 17527 wmi_debug("processed ocac complete event vdev %d" 17528 " agile chan %d %d width %d status %d", 17529 param->vdev_id, 17530 param->center_freq1, 17531 param->center_freq2, 17532 param->chan_width, 17533 param->ocac_status); 17534 17535 return QDF_STATUS_SUCCESS; 17536 } 17537 17538 /** 17539 * extract_dfs_radar_detection_event_tlv() - extract radar found event 17540 * @wmi_handle: wma handle 17541 * @evt_buf: event buffer 17542 * @radar_found: radar found event info 17543 * @len: length of buffer 17544 * 17545 * Return: QDF_STATUS_SUCCESS for success or error code 17546 */ 17547 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 17548 wmi_unified_t wmi_handle, 17549 uint8_t *evt_buf, 17550 struct radar_found_info *radar_found, 17551 uint32_t len) 17552 { 17553 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 17554 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 17555 17556 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 17557 if (!param_tlv) { 17558 wmi_err("invalid radar detection event buf"); 17559 return QDF_STATUS_E_FAILURE; 17560 } 17561 17562 radar_event = param_tlv->fixed_param; 17563 17564 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 17565 wmi_handle, 17566 radar_event->pdev_id); 17567 17568 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 17569 return QDF_STATUS_E_FAILURE; 17570 17571 qdf_mem_zero(radar_found, sizeof(struct radar_found_info)); 17572 radar_found->detection_mode = radar_event->detection_mode; 17573 radar_found->chan_freq = radar_event->chan_freq; 17574 radar_found->chan_width = radar_event->chan_width; 17575 radar_found->detector_id = radar_event->detector_id; 17576 radar_found->segment_id = radar_event->segment_id; 17577 radar_found->timestamp = radar_event->timestamp; 17578 radar_found->is_chirp = radar_event->is_chirp; 17579 radar_found->freq_offset = radar_event->freq_offset; 17580 radar_found->sidx = radar_event->sidx; 17581 17582 if (is_service_enabled_tlv(wmi_handle, 17583 WMI_SERVICE_RADAR_FLAGS_SUPPORT)) { 17584 WMI_RADAR_FLAGS *radar_flags; 17585 17586 radar_flags = param_tlv->radar_flags; 17587 if (radar_flags) { 17588 radar_found->is_full_bw_nol = 17589 WMI_RADAR_FLAGS_FULL_BW_NOL_GET(radar_flags->flags); 17590 wmi_debug("Is full bw nol %d", 17591 radar_found->is_full_bw_nol); 17592 } 17593 } 17594 17595 wmi_debug("processed radar found event pdev %d," 17596 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 17597 "chan_width (RSSI) %d,detector_id (false_radar) %d," 17598 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 17599 "is_chirp %d,detection mode %d", 17600 radar_event->pdev_id, radar_found->pdev_id, 17601 radar_event->timestamp, radar_event->chan_freq, 17602 radar_event->chan_width, radar_event->detector_id, 17603 radar_event->freq_offset, radar_event->segment_id, 17604 radar_event->sidx, radar_event->is_chirp, 17605 radar_event->detection_mode); 17606 17607 return QDF_STATUS_SUCCESS; 17608 } 17609 17610 #ifdef MOBILE_DFS_SUPPORT 17611 /** 17612 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 17613 * @wmi_handle: wma handle 17614 * @evt_buf: event buffer 17615 * @wlan_radar_event: Pointer to struct radar_event_info 17616 * @len: length of buffer 17617 * 17618 * Return: QDF_STATUS 17619 */ 17620 static QDF_STATUS extract_wlan_radar_event_info_tlv( 17621 wmi_unified_t wmi_handle, 17622 uint8_t *evt_buf, 17623 struct radar_event_info *wlan_radar_event, 17624 uint32_t len) 17625 { 17626 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 17627 wmi_dfs_radar_event_fixed_param *radar_event; 17628 17629 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 17630 if (!param_tlv) { 17631 wmi_err("invalid wlan radar event buf"); 17632 return QDF_STATUS_E_FAILURE; 17633 } 17634 17635 radar_event = param_tlv->fixed_param; 17636 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 17637 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 17638 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 17639 wlan_radar_event->rssi = radar_event->rssi; 17640 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 17641 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 17642 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 17643 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 17644 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 17645 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 17646 if (radar_event->pulse_flags & 17647 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 17648 wlan_radar_event->is_psidx_diff_valid = true; 17649 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 17650 } else { 17651 wlan_radar_event->is_psidx_diff_valid = false; 17652 } 17653 17654 wlan_radar_event->pdev_id = radar_event->pdev_id; 17655 17656 return QDF_STATUS_SUCCESS; 17657 } 17658 #else 17659 static QDF_STATUS extract_wlan_radar_event_info_tlv( 17660 wmi_unified_t wmi_handle, 17661 uint8_t *evt_buf, 17662 struct radar_event_info *wlan_radar_event, 17663 uint32_t len) 17664 { 17665 return QDF_STATUS_SUCCESS; 17666 } 17667 #endif 17668 #endif 17669 17670 /** 17671 * send_get_rcpi_cmd_tlv() - send request for rcpi value 17672 * @wmi_handle: wmi handle 17673 * @get_rcpi_param: rcpi params 17674 * 17675 * Return: QDF status 17676 */ 17677 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 17678 struct rcpi_req *get_rcpi_param) 17679 { 17680 wmi_buf_t buf; 17681 wmi_request_rcpi_cmd_fixed_param *cmd; 17682 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 17683 17684 buf = wmi_buf_alloc(wmi_handle, len); 17685 if (!buf) 17686 return QDF_STATUS_E_NOMEM; 17687 17688 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 17689 WMITLV_SET_HDR(&cmd->tlv_header, 17690 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 17691 WMITLV_GET_STRUCT_TLVLEN 17692 (wmi_request_rcpi_cmd_fixed_param)); 17693 17694 cmd->vdev_id = get_rcpi_param->vdev_id; 17695 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 17696 &cmd->peer_macaddr); 17697 17698 switch (get_rcpi_param->measurement_type) { 17699 17700 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 17701 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17702 break; 17703 17704 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 17705 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 17706 break; 17707 17708 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 17709 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 17710 break; 17711 17712 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 17713 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 17714 break; 17715 17716 default: 17717 /* 17718 * invalid rcpi measurement type, fall back to 17719 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 17720 */ 17721 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17722 break; 17723 } 17724 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 17725 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 17726 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17727 WMI_REQUEST_RCPI_CMDID)) { 17728 17729 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 17730 wmi_buf_free(buf); 17731 return QDF_STATUS_E_FAILURE; 17732 } 17733 17734 return QDF_STATUS_SUCCESS; 17735 } 17736 17737 /** 17738 * extract_rcpi_response_event_tlv() - Extract RCPI event params 17739 * @wmi_handle: wmi handle 17740 * @evt_buf: pointer to event buffer 17741 * @res: pointer to hold rcpi response from firmware 17742 * 17743 * Return: QDF_STATUS_SUCCESS for successful event parse 17744 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 17745 */ 17746 static QDF_STATUS 17747 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 17748 void *evt_buf, struct rcpi_res *res) 17749 { 17750 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 17751 wmi_update_rcpi_event_fixed_param *event; 17752 17753 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 17754 if (!param_buf) { 17755 wmi_err("Invalid rcpi event"); 17756 return QDF_STATUS_E_INVAL; 17757 } 17758 17759 event = param_buf->fixed_param; 17760 res->vdev_id = event->vdev_id; 17761 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 17762 17763 switch (event->measurement_type) { 17764 17765 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 17766 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17767 break; 17768 17769 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 17770 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 17771 break; 17772 17773 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 17774 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 17775 break; 17776 17777 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 17778 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 17779 break; 17780 17781 default: 17782 wmi_err("Invalid rcpi measurement type from firmware"); 17783 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 17784 return QDF_STATUS_E_FAILURE; 17785 } 17786 17787 if (event->status) 17788 return QDF_STATUS_E_FAILURE; 17789 else 17790 return QDF_STATUS_SUCCESS; 17791 } 17792 17793 /** 17794 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 17795 * host to target defines. For legacy there is not conversion 17796 * required. Just return pdev_id as it is. 17797 * @wmi_handle: handle to WMI. 17798 * @pdev_id: host pdev_id to be converted. 17799 * Return: target pdev_id after conversion. 17800 */ 17801 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 17802 wmi_unified_t wmi_handle, 17803 uint32_t pdev_id) 17804 { 17805 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 17806 return WMI_PDEV_ID_SOC; 17807 17808 /*No conversion required*/ 17809 return pdev_id; 17810 } 17811 17812 /** 17813 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 17814 * target to host defines. For legacy there is not conversion 17815 * required. Just return pdev_id as it is. 17816 * @wmi_handle: handle to WMI. 17817 * @pdev_id: target pdev_id to be converted. 17818 * Return: host pdev_id after conversion. 17819 */ 17820 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 17821 wmi_unified_t wmi_handle, 17822 uint32_t pdev_id) 17823 { 17824 /*No conversion required*/ 17825 return pdev_id; 17826 } 17827 17828 /** 17829 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 17830 * host to target defines. For legacy there is not conversion 17831 * required. Just return phy_id as it is. 17832 * @wmi_handle: handle to WMI. 17833 * @phy_id: host phy_id to be converted. 17834 * 17835 * Return: target phy_id after conversion. 17836 */ 17837 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 17838 wmi_unified_t wmi_handle, 17839 uint32_t phy_id) 17840 { 17841 /*No conversion required*/ 17842 return phy_id; 17843 } 17844 17845 /** 17846 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 17847 * target to host defines. For legacy there is not conversion 17848 * required. Just return phy_id as it is. 17849 * @wmi_handle: handle to WMI. 17850 * @phy_id: target phy_id to be converted. 17851 * 17852 * Return: host phy_id after conversion. 17853 */ 17854 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 17855 wmi_unified_t wmi_handle, 17856 uint32_t phy_id) 17857 { 17858 /*No conversion required*/ 17859 return phy_id; 17860 } 17861 17862 /** 17863 * send_set_country_cmd_tlv() - WMI scan channel list function 17864 * @wmi_handle: handle to WMI. 17865 * @params: pointer to hold scan channel list parameter 17866 * 17867 * Return: QDF_STATUS_SUCCESS for success or error code 17868 */ 17869 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 17870 struct set_country *params) 17871 { 17872 wmi_buf_t buf; 17873 QDF_STATUS qdf_status; 17874 wmi_set_current_country_cmd_fixed_param *cmd; 17875 uint16_t len = sizeof(*cmd); 17876 uint8_t pdev_id = params->pdev_id; 17877 17878 buf = wmi_buf_alloc(wmi_handle, len); 17879 if (!buf) { 17880 qdf_status = QDF_STATUS_E_NOMEM; 17881 goto end; 17882 } 17883 17884 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 17885 WMITLV_SET_HDR(&cmd->tlv_header, 17886 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 17887 WMITLV_GET_STRUCT_TLVLEN 17888 (wmi_set_current_country_cmd_fixed_param)); 17889 17890 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 17891 wmi_handle, 17892 pdev_id); 17893 wmi_debug("setting current country to %s and target pdev_id = %u", 17894 params->country, cmd->pdev_id); 17895 17896 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 17897 17898 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 17899 qdf_status = wmi_unified_cmd_send(wmi_handle, 17900 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 17901 17902 if (QDF_IS_STATUS_ERROR(qdf_status)) { 17903 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 17904 wmi_buf_free(buf); 17905 } 17906 17907 end: 17908 return qdf_status; 17909 } 17910 17911 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 17912 WMI_SET_BITS(alpha, 0, 8, val0); \ 17913 WMI_SET_BITS(alpha, 8, 8, val1); \ 17914 WMI_SET_BITS(alpha, 16, 8, val2); \ 17915 } while (0) 17916 17917 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 17918 uint8_t pdev_id, struct cc_regdmn_s *rd) 17919 { 17920 wmi_set_init_country_cmd_fixed_param *cmd; 17921 uint16_t len; 17922 wmi_buf_t buf; 17923 int ret; 17924 17925 len = sizeof(wmi_set_init_country_cmd_fixed_param); 17926 buf = wmi_buf_alloc(wmi_handle, len); 17927 if (!buf) 17928 return QDF_STATUS_E_NOMEM; 17929 17930 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 17931 WMITLV_SET_HDR(&cmd->tlv_header, 17932 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 17933 WMITLV_GET_STRUCT_TLVLEN 17934 (wmi_set_init_country_cmd_fixed_param)); 17935 17936 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 17937 wmi_handle, 17938 pdev_id); 17939 17940 if (rd->flags == CC_IS_SET) { 17941 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 17942 cmd->country_code.country_id = rd->cc.country_code; 17943 } else if (rd->flags == ALPHA_IS_SET) { 17944 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 17945 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 17946 rd->cc.alpha[0], 17947 rd->cc.alpha[1], 17948 rd->cc.alpha[2]); 17949 } else if (rd->flags == REGDMN_IS_SET) { 17950 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 17951 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 17952 rd->cc.regdmn.reg_2g_5g_pair_id); 17953 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 17954 rd->cc.regdmn.sixg_superdmn_id); 17955 } 17956 17957 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 17958 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17959 WMI_SET_INIT_COUNTRY_CMDID); 17960 if (ret) { 17961 wmi_err("Failed to config wow wakeup event"); 17962 wmi_buf_free(buf); 17963 return QDF_STATUS_E_FAILURE; 17964 } 17965 17966 return QDF_STATUS_SUCCESS; 17967 } 17968 17969 /** 17970 * send_obss_detection_cfg_cmd_tlv() - send obss detection 17971 * configurations to firmware. 17972 * @wmi_handle: wmi handle 17973 * @obss_cfg_param: obss detection configurations 17974 * 17975 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 17976 * 17977 * Return: QDF_STATUS 17978 */ 17979 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 17980 struct wmi_obss_detection_cfg_param *obss_cfg_param) 17981 { 17982 wmi_buf_t buf; 17983 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 17984 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 17985 17986 buf = wmi_buf_alloc(wmi_handle, len); 17987 if (!buf) 17988 return QDF_STATUS_E_NOMEM; 17989 17990 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 17991 WMITLV_SET_HDR(&cmd->tlv_header, 17992 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 17993 WMITLV_GET_STRUCT_TLVLEN 17994 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 17995 17996 cmd->vdev_id = obss_cfg_param->vdev_id; 17997 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 17998 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 17999 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 18000 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 18001 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 18002 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 18003 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 18004 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 18005 18006 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 18007 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18008 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 18009 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 18010 wmi_buf_free(buf); 18011 return QDF_STATUS_E_FAILURE; 18012 } 18013 18014 return QDF_STATUS_SUCCESS; 18015 } 18016 18017 /** 18018 * extract_obss_detection_info_tlv() - Extract obss detection info 18019 * received from firmware. 18020 * @evt_buf: pointer to event buffer 18021 * @obss_detection: Pointer to hold obss detection info 18022 * 18023 * Return: QDF_STATUS 18024 */ 18025 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 18026 struct wmi_obss_detect_info 18027 *obss_detection) 18028 { 18029 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 18030 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 18031 18032 if (!obss_detection) { 18033 wmi_err("Invalid obss_detection event buffer"); 18034 return QDF_STATUS_E_INVAL; 18035 } 18036 18037 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 18038 if (!param_buf) { 18039 wmi_err("Invalid evt_buf"); 18040 return QDF_STATUS_E_INVAL; 18041 } 18042 18043 fix_param = param_buf->fixed_param; 18044 obss_detection->vdev_id = fix_param->vdev_id; 18045 obss_detection->matched_detection_masks = 18046 fix_param->matched_detection_masks; 18047 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 18048 &obss_detection->matched_bssid_addr[0]); 18049 switch (fix_param->reason) { 18050 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 18051 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 18052 break; 18053 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 18054 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 18055 break; 18056 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 18057 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 18058 break; 18059 default: 18060 wmi_err("Invalid reason: %d", fix_param->reason); 18061 return QDF_STATUS_E_INVAL; 18062 } 18063 18064 return QDF_STATUS_SUCCESS; 18065 } 18066 18067 /** 18068 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 18069 * @wmi_handle: wmi handle 18070 * @params: pointer to request structure 18071 * 18072 * Return: QDF_STATUS 18073 */ 18074 static QDF_STATUS 18075 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 18076 struct wmi_roam_scan_stats_req *params) 18077 { 18078 wmi_buf_t buf; 18079 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 18080 WMITLV_TAG_ID tag; 18081 uint32_t size; 18082 uint32_t len = sizeof(*cmd); 18083 18084 buf = wmi_buf_alloc(wmi_handle, len); 18085 if (!buf) 18086 return QDF_STATUS_E_FAILURE; 18087 18088 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 18089 18090 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 18091 size = WMITLV_GET_STRUCT_TLVLEN( 18092 wmi_request_roam_scan_stats_cmd_fixed_param); 18093 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 18094 18095 cmd->vdev_id = params->vdev_id; 18096 18097 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 18098 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18099 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 18100 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 18101 wmi_buf_free(buf); 18102 return QDF_STATUS_E_FAILURE; 18103 } 18104 18105 return QDF_STATUS_SUCCESS; 18106 } 18107 18108 /** 18109 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 18110 * channel list from firmware 18111 * @wmi_handle: wmi handler 18112 * @vdev_id: vdev id 18113 * 18114 * Return: QDF_STATUS 18115 */ 18116 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 18117 uint32_t vdev_id) 18118 { 18119 wmi_buf_t buf; 18120 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 18121 uint16_t len = sizeof(*cmd); 18122 int ret; 18123 18124 buf = wmi_buf_alloc(wmi_handle, len); 18125 if (!buf) { 18126 wmi_err("Failed to allocate wmi buffer"); 18127 return QDF_STATUS_E_NOMEM; 18128 } 18129 18130 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 18131 wmi_buf_data(buf); 18132 WMITLV_SET_HDR(&cmd->tlv_header, 18133 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 18134 WMITLV_GET_STRUCT_TLVLEN( 18135 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 18136 cmd->vdev_id = vdev_id; 18137 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 18138 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18139 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 18140 if (QDF_IS_STATUS_ERROR(ret)) { 18141 wmi_err("Failed to send get roam scan channels request = %d", 18142 ret); 18143 wmi_buf_free(buf); 18144 } 18145 return ret; 18146 } 18147 18148 /** 18149 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 18150 * @wmi_handle: wmi handle 18151 * @evt_buf: pointer to event buffer 18152 * @vdev_id: output pointer to hold vdev id 18153 * @res_param: output pointer to hold the allocated response 18154 * 18155 * Return: QDF_STATUS 18156 */ 18157 static QDF_STATUS 18158 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18159 uint32_t *vdev_id, 18160 struct wmi_roam_scan_stats_res **res_param) 18161 { 18162 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 18163 wmi_roam_scan_stats_event_fixed_param *fixed_param; 18164 uint32_t *client_id = NULL; 18165 wmi_roaming_timestamp *timestamp = NULL; 18166 uint32_t *num_channels = NULL; 18167 uint32_t *chan_info = NULL; 18168 wmi_mac_addr *old_bssid = NULL; 18169 uint32_t *is_roaming_success = NULL; 18170 wmi_mac_addr *new_bssid = NULL; 18171 uint32_t *num_roam_candidates = NULL; 18172 wmi_roam_scan_trigger_reason *roam_reason = NULL; 18173 wmi_mac_addr *bssid = NULL; 18174 uint32_t *score = NULL; 18175 uint32_t *channel = NULL; 18176 uint32_t *rssi = NULL; 18177 int chan_idx = 0, cand_idx = 0; 18178 uint32_t total_len; 18179 struct wmi_roam_scan_stats_res *res; 18180 uint32_t i, j; 18181 uint32_t num_scans, scan_param_size; 18182 18183 *res_param = NULL; 18184 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 18185 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 18186 if (!param_buf) { 18187 wmi_err("Invalid roam scan stats event"); 18188 return QDF_STATUS_E_INVAL; 18189 } 18190 18191 fixed_param = param_buf->fixed_param; 18192 18193 num_scans = fixed_param->num_roam_scans; 18194 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 18195 *vdev_id = fixed_param->vdev_id; 18196 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 18197 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 18198 num_scans, WMI_ROAM_SCAN_STATS_MAX); 18199 return QDF_STATUS_E_INVAL; 18200 } 18201 18202 total_len = sizeof(*res) + num_scans * scan_param_size; 18203 18204 res = qdf_mem_malloc(total_len); 18205 if (!res) 18206 return QDF_STATUS_E_NOMEM; 18207 18208 if (!num_scans) { 18209 *res_param = res; 18210 return QDF_STATUS_SUCCESS; 18211 } 18212 18213 if (param_buf->client_id && 18214 param_buf->num_client_id == num_scans) 18215 client_id = param_buf->client_id; 18216 18217 if (param_buf->timestamp && 18218 param_buf->num_timestamp == num_scans) 18219 timestamp = param_buf->timestamp; 18220 18221 if (param_buf->old_bssid && 18222 param_buf->num_old_bssid == num_scans) 18223 old_bssid = param_buf->old_bssid; 18224 18225 if (param_buf->new_bssid && 18226 param_buf->num_new_bssid == num_scans) 18227 new_bssid = param_buf->new_bssid; 18228 18229 if (param_buf->is_roaming_success && 18230 param_buf->num_is_roaming_success == num_scans) 18231 is_roaming_success = param_buf->is_roaming_success; 18232 18233 if (param_buf->roam_reason && 18234 param_buf->num_roam_reason == num_scans) 18235 roam_reason = param_buf->roam_reason; 18236 18237 if (param_buf->num_channels && 18238 param_buf->num_num_channels == num_scans) { 18239 uint32_t count, chan_info_sum = 0; 18240 18241 num_channels = param_buf->num_channels; 18242 for (count = 0; count < param_buf->num_num_channels; count++) { 18243 if (param_buf->num_channels[count] > 18244 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 18245 wmi_err_rl("%u exceeded max scan channels %u", 18246 param_buf->num_channels[count], 18247 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 18248 goto error; 18249 } 18250 chan_info_sum += param_buf->num_channels[count]; 18251 } 18252 18253 if (param_buf->chan_info && 18254 param_buf->num_chan_info == chan_info_sum) 18255 chan_info = param_buf->chan_info; 18256 } 18257 18258 if (param_buf->num_roam_candidates && 18259 param_buf->num_num_roam_candidates == num_scans) { 18260 uint32_t cnt, roam_cand_sum = 0; 18261 18262 num_roam_candidates = param_buf->num_roam_candidates; 18263 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 18264 if (param_buf->num_roam_candidates[cnt] > 18265 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 18266 wmi_err_rl("%u exceeded max scan cand %u", 18267 param_buf->num_roam_candidates[cnt], 18268 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 18269 goto error; 18270 } 18271 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 18272 } 18273 18274 if (param_buf->bssid && 18275 param_buf->num_bssid == roam_cand_sum) 18276 bssid = param_buf->bssid; 18277 18278 if (param_buf->score && 18279 param_buf->num_score == roam_cand_sum) 18280 score = param_buf->score; 18281 18282 if (param_buf->channel && 18283 param_buf->num_channel == roam_cand_sum) 18284 channel = param_buf->channel; 18285 18286 if (param_buf->rssi && 18287 param_buf->num_rssi == roam_cand_sum) 18288 rssi = param_buf->rssi; 18289 } 18290 18291 res->num_roam_scans = num_scans; 18292 for (i = 0; i < num_scans; i++) { 18293 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 18294 18295 if (timestamp) 18296 roam->time_stamp = timestamp[i].lower32bit | 18297 (timestamp[i].upper32bit << 31); 18298 18299 if (client_id) 18300 roam->client_id = client_id[i]; 18301 18302 if (num_channels) { 18303 roam->num_scan_chans = num_channels[i]; 18304 if (chan_info) { 18305 for (j = 0; j < num_channels[i]; j++) 18306 roam->scan_freqs[j] = 18307 chan_info[chan_idx++]; 18308 } 18309 } 18310 18311 if (is_roaming_success) 18312 roam->is_roam_successful = is_roaming_success[i]; 18313 18314 if (roam_reason) { 18315 roam->trigger_id = roam_reason[i].trigger_id; 18316 roam->trigger_value = roam_reason[i].trigger_value; 18317 } 18318 18319 if (num_roam_candidates) { 18320 roam->num_roam_candidates = num_roam_candidates[i]; 18321 18322 for (j = 0; j < num_roam_candidates[i]; j++) { 18323 if (score) 18324 roam->cand[j].score = score[cand_idx]; 18325 if (rssi) 18326 roam->cand[j].rssi = rssi[cand_idx]; 18327 if (channel) 18328 roam->cand[j].freq = 18329 channel[cand_idx]; 18330 18331 if (bssid) 18332 WMI_MAC_ADDR_TO_CHAR_ARRAY( 18333 &bssid[cand_idx], 18334 roam->cand[j].bssid); 18335 18336 cand_idx++; 18337 } 18338 } 18339 18340 if (old_bssid) 18341 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 18342 roam->old_bssid); 18343 18344 if (new_bssid) 18345 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 18346 roam->new_bssid); 18347 } 18348 18349 *res_param = res; 18350 18351 return QDF_STATUS_SUCCESS; 18352 error: 18353 qdf_mem_free(res); 18354 return QDF_STATUS_E_FAILURE; 18355 } 18356 18357 /** 18358 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 18359 * @wmi_handle: wmi handle 18360 * @evt_buf: pointer to event buffer 18361 * @vdev_id: output pointer to hold vdev id 18362 * @tx_status: output pointer to hold the tx_status 18363 * 18364 * Return: QDF_STATUS 18365 */ 18366 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 18367 void *evt_buf, 18368 uint32_t *vdev_id, 18369 uint32_t *tx_status) { 18370 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 18371 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 18372 18373 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 18374 if (!param_buf) { 18375 wmi_err("Invalid offload bcn tx status event buffer"); 18376 return QDF_STATUS_E_INVAL; 18377 } 18378 18379 bcn_tx_status_event = param_buf->fixed_param; 18380 *vdev_id = bcn_tx_status_event->vdev_id; 18381 *tx_status = bcn_tx_status_event->tx_status; 18382 18383 return QDF_STATUS_SUCCESS; 18384 } 18385 18386 #ifdef WLAN_SUPPORT_GREEN_AP 18387 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 18388 uint8_t *evt_buf, 18389 struct wlan_green_ap_egap_status_info *egap_status_info_params) 18390 { 18391 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 18392 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 18393 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 18394 18395 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 18396 if (!param_buf) { 18397 wmi_err("Invalid EGAP Info status event buffer"); 18398 return QDF_STATUS_E_INVAL; 18399 } 18400 18401 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 18402 param_buf->fixed_param; 18403 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 18404 param_buf->chainmask_list; 18405 18406 if (!egap_info_event || !chainmask_event) { 18407 wmi_err("Invalid EGAP Info event or chainmask event"); 18408 return QDF_STATUS_E_INVAL; 18409 } 18410 18411 egap_status_info_params->status = egap_info_event->status; 18412 egap_status_info_params->mac_id = chainmask_event->mac_id; 18413 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 18414 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 18415 18416 return QDF_STATUS_SUCCESS; 18417 } 18418 #endif 18419 18420 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 18421 static QDF_STATUS extract_green_ap_ll_ps_param_tlv( 18422 uint8_t *evt_buf, 18423 struct wlan_green_ap_ll_ps_event_param *ll_ps_params) 18424 { 18425 WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 18426 wmi_xgap_enable_complete_event_fixed_param *ll_ps_event; 18427 18428 param_buf = (WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 18429 if (!param_buf) { 18430 wmi_err("Invalid XGAP SAP info status"); 18431 return QDF_STATUS_E_INVAL; 18432 } 18433 18434 ll_ps_event = (wmi_xgap_enable_complete_event_fixed_param *) 18435 param_buf->fixed_param; 18436 if (!ll_ps_event) { 18437 wmi_err("Invalid low latency power save event buffer"); 18438 return QDF_STATUS_E_INVAL; 18439 } 18440 18441 ll_ps_params->dialog_token = ll_ps_event->dialog_token; 18442 ll_ps_params->next_tsf = 18443 ((uint64_t)ll_ps_event->next_tsf_high32 << 32) | 18444 ll_ps_event->next_tsf_low32; 18445 18446 wmi_debug("cookie : %u next_tsf %llu", ll_ps_params->dialog_token, 18447 ll_ps_params->next_tsf); 18448 18449 return QDF_STATUS_SUCCESS; 18450 } 18451 #endif 18452 18453 /* 18454 * extract_comb_phyerr_tlv() - extract comb phy error from event 18455 * @wmi_handle: wmi handle 18456 * @evt_buf: pointer to event buffer 18457 * @datalen: data length of event buffer 18458 * @buf_offset: Pointer to hold value of current event buffer offset 18459 * post extraction 18460 * @phyerr: Pointer to hold phyerr 18461 * 18462 * Return: QDF_STATUS 18463 */ 18464 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 18465 void *evt_buf, 18466 uint16_t datalen, 18467 uint16_t *buf_offset, 18468 wmi_host_phyerr_t *phyerr) 18469 { 18470 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 18471 wmi_comb_phyerr_rx_hdr *pe_hdr; 18472 18473 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 18474 if (!param_tlvs) { 18475 wmi_debug("Received null data from FW"); 18476 return QDF_STATUS_E_FAILURE; 18477 } 18478 18479 pe_hdr = param_tlvs->hdr; 18480 if (!pe_hdr) { 18481 wmi_debug("Received Data PE Header is NULL"); 18482 return QDF_STATUS_E_FAILURE; 18483 } 18484 18485 /* Ensure it's at least the size of the header */ 18486 if (datalen < sizeof(*pe_hdr)) { 18487 wmi_debug("Expected minimum size %zu, received %d", 18488 sizeof(*pe_hdr), datalen); 18489 return QDF_STATUS_E_FAILURE; 18490 } 18491 18492 phyerr->pdev_id = wmi_handle->ops-> 18493 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 18494 phyerr->tsf64 = pe_hdr->tsf_l32; 18495 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 18496 phyerr->bufp = param_tlvs->bufp; 18497 18498 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 18499 wmi_debug("Invalid buf_len %d, num_bufp %d", 18500 pe_hdr->buf_len, param_tlvs->num_bufp); 18501 return QDF_STATUS_E_FAILURE; 18502 } 18503 18504 phyerr->buf_len = pe_hdr->buf_len; 18505 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 18506 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 18507 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 18508 18509 return QDF_STATUS_SUCCESS; 18510 } 18511 18512 /** 18513 * extract_single_phyerr_tlv() - extract single phy error from event 18514 * @wmi_handle: wmi handle 18515 * @evt_buf: pointer to event buffer 18516 * @datalen: data length of event buffer 18517 * @buf_offset: Pointer to hold value of current event buffer offset 18518 * post extraction 18519 * @phyerr: Pointer to hold phyerr 18520 * 18521 * Return: QDF_STATUS 18522 */ 18523 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 18524 void *evt_buf, 18525 uint16_t datalen, 18526 uint16_t *buf_offset, 18527 wmi_host_phyerr_t *phyerr) 18528 { 18529 wmi_single_phyerr_rx_event *ev; 18530 uint16_t n = *buf_offset; 18531 uint8_t *data = (uint8_t *)evt_buf; 18532 18533 if (n < datalen) { 18534 if ((datalen - n) < sizeof(ev->hdr)) { 18535 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 18536 datalen, n, sizeof(ev->hdr)); 18537 return QDF_STATUS_E_FAILURE; 18538 } 18539 18540 /* 18541 * Obtain a pointer to the beginning of the current event. 18542 * data[0] is the beginning of the WMI payload. 18543 */ 18544 ev = (wmi_single_phyerr_rx_event *)&data[n]; 18545 18546 /* 18547 * Sanity check the buffer length of the event against 18548 * what we currently have. 18549 * 18550 * Since buf_len is 32 bits, we check if it overflows 18551 * a large 32 bit value. It's not 0x7fffffff because 18552 * we increase n by (buf_len + sizeof(hdr)), which would 18553 * in itself cause n to overflow. 18554 * 18555 * If "int" is 64 bits then this becomes a moot point. 18556 */ 18557 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 18558 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 18559 return QDF_STATUS_E_FAILURE; 18560 } 18561 18562 if ((n + ev->hdr.buf_len) > datalen) { 18563 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 18564 n, ev->hdr.buf_len, datalen); 18565 return QDF_STATUS_E_FAILURE; 18566 } 18567 18568 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 18569 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 18570 phyerr->bufp = &ev->bufp[0]; 18571 phyerr->buf_len = ev->hdr.buf_len; 18572 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 18573 18574 /* 18575 * Advance the buffer pointer to the next PHY error. 18576 * buflen is the length of this payload, so we need to 18577 * advance past the current header _AND_ the payload. 18578 */ 18579 n += sizeof(*ev) + ev->hdr.buf_len; 18580 } 18581 *buf_offset = n; 18582 18583 return QDF_STATUS_SUCCESS; 18584 } 18585 18586 /** 18587 * extract_esp_estimation_ev_param_tlv() - extract air time from event 18588 * @wmi_handle: wmi handle 18589 * @evt_buf: pointer to event buffer 18590 * @param: Pointer to hold esp event 18591 * 18592 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 18593 */ 18594 static QDF_STATUS 18595 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 18596 void *evt_buf, 18597 struct esp_estimation_event *param) 18598 { 18599 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 18600 wmi_esp_estimate_event_fixed_param *esp_event; 18601 18602 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 18603 if (!param_buf) { 18604 wmi_err("Invalid ESP Estimate Event buffer"); 18605 return QDF_STATUS_E_INVAL; 18606 } 18607 esp_event = param_buf->fixed_param; 18608 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 18609 18610 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 18611 wmi_handle, 18612 esp_event->pdev_id); 18613 18614 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 18615 return QDF_STATUS_E_FAILURE; 18616 18617 return QDF_STATUS_SUCCESS; 18618 } 18619 18620 /* 18621 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 18622 * updating bss color change within firmware when AP announces bss color change. 18623 * @wmi_handle: wmi handle 18624 * @vdev_id: vdev ID 18625 * @enable: enable bss color change within firmware 18626 * 18627 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 18628 * 18629 * Return: QDF_STATUS 18630 */ 18631 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 18632 uint32_t vdev_id, 18633 bool enable) 18634 { 18635 wmi_buf_t buf; 18636 wmi_bss_color_change_enable_fixed_param *cmd; 18637 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 18638 18639 buf = wmi_buf_alloc(wmi_handle, len); 18640 if (!buf) 18641 return QDF_STATUS_E_NOMEM; 18642 18643 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 18644 WMITLV_SET_HDR(&cmd->tlv_header, 18645 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 18646 WMITLV_GET_STRUCT_TLVLEN 18647 (wmi_bss_color_change_enable_fixed_param)); 18648 cmd->vdev_id = vdev_id; 18649 cmd->enable = enable; 18650 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 18651 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18652 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 18653 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 18654 wmi_buf_free(buf); 18655 return QDF_STATUS_E_FAILURE; 18656 } 18657 18658 return QDF_STATUS_SUCCESS; 18659 } 18660 18661 /** 18662 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 18663 * configurations to firmware. 18664 * @wmi_handle: wmi handle 18665 * @cfg_param: obss detection configurations 18666 * 18667 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 18668 * 18669 * Return: QDF_STATUS 18670 */ 18671 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 18672 wmi_unified_t wmi_handle, 18673 struct wmi_obss_color_collision_cfg_param *cfg_param) 18674 { 18675 wmi_buf_t buf; 18676 wmi_obss_color_collision_det_config_fixed_param *cmd; 18677 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 18678 18679 buf = wmi_buf_alloc(wmi_handle, len); 18680 if (!buf) 18681 return QDF_STATUS_E_NOMEM; 18682 18683 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 18684 buf); 18685 WMITLV_SET_HDR(&cmd->tlv_header, 18686 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 18687 WMITLV_GET_STRUCT_TLVLEN 18688 (wmi_obss_color_collision_det_config_fixed_param)); 18689 cmd->vdev_id = cfg_param->vdev_id; 18690 cmd->flags = cfg_param->flags; 18691 cmd->current_bss_color = cfg_param->current_bss_color; 18692 cmd->detection_period_ms = cfg_param->detection_period_ms; 18693 cmd->scan_period_ms = cfg_param->scan_period_ms; 18694 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 18695 18696 switch (cfg_param->evt_type) { 18697 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 18698 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 18699 break; 18700 case OBSS_COLOR_COLLISION_DETECTION: 18701 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 18702 break; 18703 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 18704 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 18705 break; 18706 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 18707 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 18708 break; 18709 default: 18710 wmi_err("Invalid event type: %d", cfg_param->evt_type); 18711 wmi_buf_free(buf); 18712 return QDF_STATUS_E_FAILURE; 18713 } 18714 18715 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 18716 "detection_period_ms: %d scan_period_ms: %d " 18717 "free_slot_expiry_timer_ms: %d", 18718 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 18719 cmd->detection_period_ms, cmd->scan_period_ms, 18720 cmd->free_slot_expiry_time_ms); 18721 18722 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 18723 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18724 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 18725 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 18726 cfg_param->vdev_id); 18727 wmi_buf_free(buf); 18728 return QDF_STATUS_E_FAILURE; 18729 } 18730 18731 return QDF_STATUS_SUCCESS; 18732 } 18733 18734 /** 18735 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 18736 * received from firmware. 18737 * @evt_buf: pointer to event buffer 18738 * @info: Pointer to hold bss collision info 18739 * 18740 * Return: QDF_STATUS 18741 */ 18742 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 18743 struct wmi_obss_color_collision_info *info) 18744 { 18745 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 18746 wmi_obss_color_collision_evt_fixed_param *fix_param; 18747 18748 if (!info) { 18749 wmi_err("Invalid obss color buffer"); 18750 return QDF_STATUS_E_INVAL; 18751 } 18752 18753 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 18754 evt_buf; 18755 if (!param_buf) { 18756 wmi_err("Invalid evt_buf"); 18757 return QDF_STATUS_E_INVAL; 18758 } 18759 18760 fix_param = param_buf->fixed_param; 18761 info->vdev_id = fix_param->vdev_id; 18762 info->obss_color_bitmap_bit0to31 = 18763 fix_param->bss_color_bitmap_bit0to31; 18764 info->obss_color_bitmap_bit32to63 = 18765 fix_param->bss_color_bitmap_bit32to63; 18766 18767 switch (fix_param->evt_type) { 18768 case WMI_BSS_COLOR_COLLISION_DISABLE: 18769 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 18770 break; 18771 case WMI_BSS_COLOR_COLLISION_DETECTION: 18772 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 18773 break; 18774 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 18775 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 18776 break; 18777 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 18778 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 18779 break; 18780 default: 18781 wmi_err("Invalid event type: %d, vdev_id: %d", 18782 fix_param->evt_type, fix_param->vdev_id); 18783 return QDF_STATUS_E_FAILURE; 18784 } 18785 18786 return QDF_STATUS_SUCCESS; 18787 } 18788 18789 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 18790 { 18791 struct wmi_ops *ops = wmi_handle->ops; 18792 18793 ops->send_obss_color_collision_cfg_cmd = 18794 send_obss_color_collision_cfg_cmd_tlv; 18795 ops->extract_obss_color_collision_info = 18796 extract_obss_color_collision_info_tlv; 18797 } 18798 18799 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 18800 static QDF_STATUS 18801 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 18802 struct config_fils_params *param) 18803 { 18804 wmi_buf_t buf; 18805 wmi_enable_fils_cmd_fixed_param *cmd; 18806 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 18807 18808 buf = wmi_buf_alloc(wmi_handle, len); 18809 if (!buf) 18810 return QDF_STATUS_E_NOMEM; 18811 18812 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 18813 buf); 18814 WMITLV_SET_HDR(&cmd->tlv_header, 18815 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 18816 WMITLV_GET_STRUCT_TLVLEN 18817 (wmi_enable_fils_cmd_fixed_param)); 18818 cmd->vdev_id = param->vdev_id; 18819 cmd->fd_period = param->fd_period; 18820 if (param->send_prb_rsp_frame) 18821 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 18822 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 18823 cmd->vdev_id, cmd->fd_period, cmd->flags); 18824 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 18825 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18826 WMI_ENABLE_FILS_CMDID)) { 18827 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 18828 wmi_buf_free(buf); 18829 return QDF_STATUS_E_FAILURE; 18830 } 18831 18832 return QDF_STATUS_SUCCESS; 18833 } 18834 #endif 18835 18836 #ifdef WLAN_MWS_INFO_DEBUGFS 18837 /** 18838 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 18839 * 18840 * @wmi_handle: wmi handle 18841 * @vdev_id: vdev id 18842 * @cmd_id: Coex command id 18843 * 18844 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 18845 * 18846 * Return: QDF_STATUS 18847 */ 18848 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 18849 uint32_t vdev_id, 18850 uint32_t cmd_id) 18851 { 18852 wmi_buf_t buf; 18853 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 18854 uint16_t len = sizeof(*cmd); 18855 int ret; 18856 18857 buf = wmi_buf_alloc(wmi_handle, len); 18858 if (!buf) { 18859 wmi_err("Failed to allocate wmi buffer"); 18860 return QDF_STATUS_E_NOMEM; 18861 } 18862 18863 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 18864 WMITLV_SET_HDR(&cmd->tlv_header, 18865 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 18866 WMITLV_GET_STRUCT_TLVLEN 18867 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 18868 cmd->vdev_id = vdev_id; 18869 cmd->cmd_id = cmd_id; 18870 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 18871 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18872 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 18873 if (QDF_IS_STATUS_ERROR(ret)) { 18874 wmi_err("Failed to send set param command ret = %d", ret); 18875 wmi_buf_free(buf); 18876 } 18877 return ret; 18878 } 18879 #endif 18880 18881 #ifdef FEATURE_MEC_OFFLOAD 18882 static QDF_STATUS 18883 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 18884 struct set_mec_timer_params *param) 18885 { 18886 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 18887 wmi_buf_t buf; 18888 int32_t len = sizeof(*cmd); 18889 18890 buf = wmi_buf_alloc(wmi_handle, len); 18891 if (!buf) { 18892 wmi_err("wmi_buf_alloc failed"); 18893 return QDF_STATUS_E_FAILURE; 18894 } 18895 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 18896 wmi_buf_data(buf); 18897 WMITLV_SET_HDR(&cmd->tlv_header, 18898 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 18899 WMITLV_GET_STRUCT_TLVLEN( 18900 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 18901 cmd->pdev_id = param->pdev_id; 18902 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 18903 18904 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 18905 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18906 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 18907 wmi_err("Failed to set mec aging timer param"); 18908 wmi_buf_free(buf); 18909 return QDF_STATUS_E_FAILURE; 18910 } 18911 18912 return QDF_STATUS_SUCCESS; 18913 } 18914 #endif 18915 18916 #ifdef WIFI_POS_CONVERGED 18917 /** 18918 * extract_oem_response_param_tlv() - Extract oem response params 18919 * @wmi_handle: wmi handle 18920 * @resp_buf: response buffer 18921 * @oem_resp_param: pointer to hold oem response params 18922 * 18923 * Return: QDF_STATUS_SUCCESS on success or proper error code. 18924 */ 18925 static QDF_STATUS 18926 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 18927 struct wmi_oem_response_param *oem_resp_param) 18928 { 18929 uint64_t temp_addr; 18930 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 18931 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 18932 18933 if (!param_buf) { 18934 wmi_err("Invalid OEM response"); 18935 return QDF_STATUS_E_INVAL; 18936 } 18937 18938 if (param_buf->num_data) { 18939 oem_resp_param->num_data1 = param_buf->num_data; 18940 oem_resp_param->data_1 = param_buf->data; 18941 } 18942 18943 if (param_buf->num_data2) { 18944 oem_resp_param->num_data2 = param_buf->num_data2; 18945 oem_resp_param->data_2 = param_buf->data2; 18946 } 18947 18948 if (param_buf->indirect_data) { 18949 oem_resp_param->indirect_data.pdev_id = 18950 param_buf->indirect_data->pdev_id; 18951 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 18952 oem_resp_param->indirect_data.addr = 18953 param_buf->indirect_data->addr_lo + 18954 ((uint64_t)temp_addr << 32); 18955 oem_resp_param->indirect_data.len = 18956 param_buf->indirect_data->len; 18957 } 18958 18959 return QDF_STATUS_SUCCESS; 18960 } 18961 #endif /* WIFI_POS_CONVERGED */ 18962 18963 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 18964 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 18965 18966 static QDF_STATUS 18967 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18968 struct wifi_pos_pasn_peer_data *dst) 18969 { 18970 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 18971 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 18972 wmi_rtt_pasn_peer_create_req_param *buf; 18973 uint8_t security_mode, i; 18974 18975 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 18976 if (!param_buf) { 18977 wmi_err("Invalid peer_create req buffer"); 18978 return QDF_STATUS_E_INVAL; 18979 } 18980 18981 fixed_param = param_buf->fixed_param; 18982 18983 if (param_buf->num_rtt_pasn_peer_param > 18984 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18985 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 18986 wmi_err("Invalid TLV size"); 18987 return QDF_STATUS_E_INVAL; 18988 } 18989 18990 if (!param_buf->num_rtt_pasn_peer_param || 18991 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 18992 wmi_err("Invalid num TLV:%d", 18993 param_buf->num_rtt_pasn_peer_param); 18994 return QDF_STATUS_E_INVAL; 18995 } 18996 18997 dst->vdev_id = fixed_param->vdev_id; 18998 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 18999 wmi_err("Invalid vdev id:%d", dst->vdev_id); 19000 return QDF_STATUS_E_INVAL; 19001 } 19002 19003 buf = param_buf->rtt_pasn_peer_param; 19004 if (!buf) { 19005 wmi_err("NULL peer param TLV"); 19006 return QDF_STATUS_E_INVAL; 19007 } 19008 19009 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 19010 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 19011 dst->peer_info[i].self_mac.bytes); 19012 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 19013 dst->peer_info[i].peer_mac.bytes); 19014 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 19015 buf->control_flag); 19016 if (security_mode) 19017 dst->peer_info[i].peer_type = 19018 WLAN_WIFI_POS_PASN_SECURE_PEER; 19019 else 19020 dst->peer_info[i].peer_type = 19021 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 19022 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 19023 dst->peer_info[i].is_ltf_keyseed_required = true; 19024 19025 dst->peer_info[i].force_self_mac_usage = 19026 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 19027 buf->control_flag); 19028 dst->num_peers++; 19029 buf++; 19030 } 19031 19032 return QDF_STATUS_SUCCESS; 19033 } 19034 19035 static QDF_STATUS 19036 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19037 struct wifi_pos_pasn_peer_data *dst) 19038 { 19039 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 19040 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 19041 wmi_rtt_pasn_peer_delete_param *buf; 19042 uint8_t i; 19043 19044 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 19045 if (!param_buf) { 19046 wmi_err("Invalid peer_delete evt buffer"); 19047 return QDF_STATUS_E_INVAL; 19048 } 19049 19050 fixed_param = param_buf->fixed_param; 19051 19052 if (param_buf->num_rtt_pasn_peer_param > 19053 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 19054 sizeof(wmi_rtt_pasn_peer_delete_param))) { 19055 wmi_err("Invalid TLV size"); 19056 return QDF_STATUS_E_INVAL; 19057 } 19058 19059 if (!param_buf->num_rtt_pasn_peer_param || 19060 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 19061 wmi_err("Invalid num TLV:%d", 19062 param_buf->num_rtt_pasn_peer_param); 19063 return QDF_STATUS_E_INVAL; 19064 } 19065 19066 dst->vdev_id = fixed_param->vdev_id; 19067 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 19068 wmi_err("Invalid vdev id:%d", dst->vdev_id); 19069 return QDF_STATUS_E_INVAL; 19070 } 19071 19072 buf = param_buf->rtt_pasn_peer_param; 19073 if (!buf) { 19074 wmi_err("NULL peer param TLV"); 19075 return QDF_STATUS_E_INVAL; 19076 } 19077 19078 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 19079 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 19080 dst->peer_info[i].peer_mac.bytes); 19081 dst->peer_info[i].control_flags = buf->control_flag; 19082 19083 dst->num_peers++; 19084 buf++; 19085 } 19086 19087 return QDF_STATUS_SUCCESS; 19088 } 19089 19090 static QDF_STATUS 19091 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 19092 struct wlan_pasn_auth_status *data) 19093 { 19094 QDF_STATUS status; 19095 wmi_buf_t buf; 19096 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 19097 uint8_t *buf_ptr; 19098 uint8_t i; 19099 size_t len = sizeof(*fixed_param) + 19100 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 19101 WMI_TLV_HDR_SIZE; 19102 19103 buf = wmi_buf_alloc(wmi_handle, len); 19104 if (!buf) { 19105 wmi_err("wmi_buf_alloc failed"); 19106 return QDF_STATUS_E_FAILURE; 19107 } 19108 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19109 fixed_param = 19110 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 19111 WMITLV_SET_HDR(&fixed_param->tlv_header, 19112 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 19113 WMITLV_GET_STRUCT_TLVLEN( 19114 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 19115 buf_ptr += sizeof(*fixed_param); 19116 19117 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 19118 (data->num_peers * 19119 sizeof(wmi_rtt_pasn_auth_status_param))); 19120 buf_ptr += WMI_TLV_HDR_SIZE; 19121 19122 for (i = 0; i < data->num_peers; i++) { 19123 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 19124 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 19125 19126 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 19127 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 19128 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 19129 19130 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 19131 &auth_status_tlv->peer_mac_addr); 19132 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 19133 &auth_status_tlv->source_mac_addr); 19134 auth_status_tlv->status = data->auth_status[i].status; 19135 wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", 19136 QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), 19137 QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), 19138 auth_status_tlv->status); 19139 19140 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 19141 } 19142 19143 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 19144 status = wmi_unified_cmd_send(wmi_handle, buf, len, 19145 WMI_RTT_PASN_AUTH_STATUS_CMD); 19146 if (QDF_IS_STATUS_ERROR(status)) { 19147 wmi_err("Failed to send Auth status command ret = %d", status); 19148 wmi_buf_free(buf); 19149 } 19150 19151 return status; 19152 } 19153 19154 static QDF_STATUS 19155 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 19156 struct qdf_mac_addr *peer_mac) 19157 { 19158 QDF_STATUS status; 19159 wmi_buf_t buf; 19160 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 19161 size_t len = sizeof(*fixed_param); 19162 19163 buf = wmi_buf_alloc(wmi_handle, len); 19164 if (!buf) { 19165 wmi_err("wmi_buf_alloc failed"); 19166 return QDF_STATUS_E_FAILURE; 19167 } 19168 fixed_param = 19169 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 19170 WMITLV_SET_HDR(&fixed_param->tlv_header, 19171 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 19172 WMITLV_GET_STRUCT_TLVLEN( 19173 wmi_rtt_pasn_deauth_cmd_fixed_param)); 19174 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 19175 &fixed_param->peer_mac_addr); 19176 19177 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 19178 status = wmi_unified_cmd_send(wmi_handle, buf, len, 19179 WMI_RTT_PASN_DEAUTH_CMD); 19180 if (QDF_IS_STATUS_ERROR(status)) { 19181 wmi_err("Failed to send pasn deauth command ret = %d", status); 19182 wmi_buf_free(buf); 19183 } 19184 19185 return status; 19186 } 19187 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 19188 19189 static QDF_STATUS 19190 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 19191 struct wlan_crypto_ltf_keyseed_data *data) 19192 { 19193 QDF_STATUS status; 19194 wmi_buf_t buf; 19195 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 19196 uint8_t *buf_ptr; 19197 size_t len = sizeof(*fixed_param) + data->key_seed_len + 19198 WMI_TLV_HDR_SIZE; 19199 19200 buf = wmi_buf_alloc(wmi_handle, len); 19201 if (!buf) { 19202 wmi_err("wmi_buf_alloc failed"); 19203 return QDF_STATUS_E_FAILURE; 19204 } 19205 19206 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19207 fixed_param = 19208 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 19209 WMITLV_SET_HDR(&fixed_param->tlv_header, 19210 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 19211 WMITLV_GET_STRUCT_TLVLEN( 19212 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 19213 19214 fixed_param->vdev_id = data->vdev_id; 19215 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 19216 &fixed_param->peer_macaddr); 19217 fixed_param->key_seed_len = data->key_seed_len; 19218 fixed_param->rsn_authmode = data->rsn_authmode; 19219 19220 buf_ptr += sizeof(*fixed_param); 19221 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 19222 (fixed_param->key_seed_len * sizeof(A_UINT8))); 19223 buf_ptr += WMI_TLV_HDR_SIZE; 19224 19225 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 19226 19227 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 19228 status = wmi_unified_cmd_send(wmi_handle, buf, len, 19229 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 19230 if (QDF_IS_STATUS_ERROR(status)) { 19231 wmi_err("Failed to send ltf keyseed command ret = %d", status); 19232 wmi_buf_free(buf); 19233 } 19234 19235 return status; 19236 } 19237 19238 /** 19239 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 19240 * @wmi_handle: wmi handle 19241 * @evt_buf: pointer to event buffer 19242 * @cmd_status: status of HW mode change command 19243 * 19244 * Return: QDF_STATUS_SUCCESS on success or proper error code. 19245 */ 19246 static QDF_STATUS 19247 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19248 uint32_t *cmd_status) 19249 { 19250 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 19251 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 19252 19253 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 19254 if (!param_buf) { 19255 wmi_err("Invalid mode change event buffer"); 19256 return QDF_STATUS_E_INVAL; 19257 } 19258 19259 fixed_param = param_buf->fixed_param; 19260 if (!fixed_param) { 19261 wmi_err("Invalid fixed param"); 19262 return QDF_STATUS_E_INVAL; 19263 } 19264 19265 *cmd_status = fixed_param->status; 19266 return QDF_STATUS_SUCCESS; 19267 } 19268 19269 /** 19270 * extract_rf_path_resp_tlv() - Extract RF path change status 19271 * @wmi_handle: wmi handle 19272 * @evt_buf: pointer to event buffer 19273 * @cmd_status: status of RF path change request 19274 * 19275 * Return: QDF_STATUS_SUCCESS on success or proper error code. 19276 */ 19277 static QDF_STATUS 19278 extract_rf_path_resp_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19279 uint32_t *cmd_status) 19280 { 19281 WMI_PDEV_SET_RF_PATH_RESP_EVENTID_param_tlvs *param_buf; 19282 wmi_pdev_set_rf_path_event_fixed_param *fixed_param; 19283 19284 param_buf = (WMI_PDEV_SET_RF_PATH_RESP_EVENTID_param_tlvs *)evt_buf; 19285 if (!param_buf) { 19286 wmi_err("Invalid RF path event buffer"); 19287 return QDF_STATUS_E_INVAL; 19288 } 19289 19290 fixed_param = param_buf->fixed_param; 19291 if (!fixed_param) { 19292 wmi_err("Invalid fixed param"); 19293 return QDF_STATUS_E_INVAL; 19294 } 19295 19296 *cmd_status = fixed_param->status; 19297 return QDF_STATUS_SUCCESS; 19298 } 19299 19300 #ifdef FEATURE_ANI_LEVEL_REQUEST 19301 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 19302 uint32_t *freqs, 19303 uint8_t num_freqs) 19304 { 19305 wmi_buf_t buf; 19306 wmi_get_channel_ani_cmd_fixed_param *cmd; 19307 QDF_STATUS ret; 19308 uint32_t len; 19309 A_UINT32 *chan_list; 19310 uint8_t i, *buf_ptr; 19311 19312 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 19313 WMI_TLV_HDR_SIZE + 19314 num_freqs * sizeof(A_UINT32); 19315 19316 buf = wmi_buf_alloc(wmi_handle, len); 19317 if (!buf) 19318 return QDF_STATUS_E_FAILURE; 19319 19320 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19321 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 19322 WMITLV_SET_HDR(&cmd->tlv_header, 19323 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 19324 WMITLV_GET_STRUCT_TLVLEN( 19325 wmi_get_channel_ani_cmd_fixed_param)); 19326 19327 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 19328 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 19329 (num_freqs * sizeof(A_UINT32))); 19330 19331 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 19332 for (i = 0; i < num_freqs; i++) { 19333 chan_list[i] = freqs[i]; 19334 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 19335 } 19336 19337 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19338 WMI_GET_CHANNEL_ANI_CMDID); 19339 19340 if (QDF_IS_STATUS_ERROR(ret)) { 19341 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 19342 wmi_buf_free(buf); 19343 } 19344 19345 return ret; 19346 } 19347 19348 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 19349 struct wmi_host_ani_level_event **info, 19350 uint32_t *num_freqs) 19351 { 19352 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 19353 wmi_get_channel_ani_event_fixed_param *fixed_param; 19354 wmi_channel_ani_info_tlv_param *tlv_params; 19355 uint8_t *buf_ptr, i; 19356 19357 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 19358 if (!param_buf) { 19359 wmi_err("Invalid ani level event buffer"); 19360 return QDF_STATUS_E_INVAL; 19361 } 19362 19363 fixed_param = 19364 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 19365 if (!fixed_param) { 19366 wmi_err("Invalid fixed param"); 19367 return QDF_STATUS_E_INVAL; 19368 } 19369 19370 buf_ptr = (uint8_t *)fixed_param; 19371 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 19372 buf_ptr += WMI_TLV_HDR_SIZE; 19373 19374 *num_freqs = param_buf->num_ani_info; 19375 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 19376 wmi_err("Invalid number of freqs received"); 19377 return QDF_STATUS_E_INVAL; 19378 } 19379 19380 *info = qdf_mem_malloc(*num_freqs * 19381 sizeof(struct wmi_host_ani_level_event)); 19382 if (!(*info)) 19383 return QDF_STATUS_E_NOMEM; 19384 19385 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 19386 for (i = 0; i < param_buf->num_ani_info; i++) { 19387 (*info)[i].ani_level = tlv_params->ani_level; 19388 (*info)[i].chan_freq = tlv_params->chan_freq; 19389 tlv_params++; 19390 } 19391 19392 return QDF_STATUS_SUCCESS; 19393 } 19394 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 19395 19396 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 19397 /** 19398 * convert_wtc_scan_mode() - Function to convert TLV specific 19399 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 19400 * @scan_mode: scan freq scheme coming from firmware 19401 * 19402 * Return: ROAM_TRIGGER_SCAN_MODE 19403 */ 19404 static enum roam_scan_freq_scheme 19405 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 19406 { 19407 switch (scan_mode) { 19408 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 19409 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 19410 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 19411 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 19412 case ROAM_TRIGGER_SCAN_MODE_FULL: 19413 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 19414 default: 19415 return ROAM_SCAN_FREQ_SCHEME_NONE; 19416 } 19417 } 19418 19419 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 19420 { 19421 switch (fw_trig_reason) { 19422 case WMI_ROAM_TRIGGER_REASON_NONE: 19423 return ROAM_TRIGGER_REASON_NONE; 19424 case WMI_ROAM_TRIGGER_REASON_PER: 19425 return ROAM_TRIGGER_REASON_PER; 19426 case WMI_ROAM_TRIGGER_REASON_BMISS: 19427 return ROAM_TRIGGER_REASON_BMISS; 19428 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 19429 return ROAM_TRIGGER_REASON_LOW_RSSI; 19430 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 19431 return ROAM_TRIGGER_REASON_HIGH_RSSI; 19432 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 19433 return ROAM_TRIGGER_REASON_PERIODIC; 19434 case WMI_ROAM_TRIGGER_REASON_MAWC: 19435 return ROAM_TRIGGER_REASON_MAWC; 19436 case WMI_ROAM_TRIGGER_REASON_DENSE: 19437 return ROAM_TRIGGER_REASON_DENSE; 19438 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 19439 return ROAM_TRIGGER_REASON_BACKGROUND; 19440 case WMI_ROAM_TRIGGER_REASON_FORCED: 19441 return ROAM_TRIGGER_REASON_FORCED; 19442 case WMI_ROAM_TRIGGER_REASON_BTM: 19443 return ROAM_TRIGGER_REASON_BTM; 19444 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 19445 return ROAM_TRIGGER_REASON_UNIT_TEST; 19446 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 19447 return ROAM_TRIGGER_REASON_BSS_LOAD; 19448 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 19449 return ROAM_TRIGGER_REASON_DEAUTH; 19450 case WMI_ROAM_TRIGGER_REASON_IDLE: 19451 return ROAM_TRIGGER_REASON_IDLE; 19452 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 19453 return ROAM_TRIGGER_REASON_STA_KICKOUT; 19454 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 19455 return ROAM_TRIGGER_REASON_ESS_RSSI; 19456 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 19457 return ROAM_TRIGGER_REASON_WTC_BTM; 19458 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 19459 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 19460 case WMI_ROAM_TRIGGER_REASON_BTC: 19461 return ROAM_TRIGGER_REASON_BTC; 19462 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 19463 return ROAM_TRIGGER_REASON_MAX; 19464 default: 19465 return ROAM_TRIGGER_REASON_NONE; 19466 } 19467 } 19468 19469 /** 19470 * extract_roam_11kv_candidate_info - Extract btm candidate info 19471 * @wmi_handle: wmi_handle 19472 * @evt_buf: Event buffer 19473 * @dst_info: Destination buffer 19474 * @btm_idx: BTM index 19475 * @num_cand: Number of candidates 19476 * 19477 * Return: QDF_STATUS 19478 */ 19479 static QDF_STATUS 19480 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 19481 struct wmi_btm_req_candidate_info *dst_info, 19482 uint8_t btm_idx, uint16_t num_cand) 19483 { 19484 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19485 wmi_roam_btm_request_candidate_info *src_data; 19486 uint8_t i; 19487 19488 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19489 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 19490 !param_buf->num_roam_btm_request_candidate_info || 19491 (btm_idx + 19492 num_cand) > param_buf->num_roam_btm_request_candidate_info) 19493 return QDF_STATUS_SUCCESS; 19494 19495 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 19496 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 19497 num_cand = WLAN_MAX_BTM_CANDIDATE; 19498 for (i = 0; i < num_cand; i++) { 19499 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 19500 dst_info->candidate_bssid.bytes); 19501 dst_info->preference = src_data->preference; 19502 src_data++; 19503 dst_info++; 19504 } 19505 19506 return QDF_STATUS_SUCCESS; 19507 } 19508 19509 static enum roam_trigger_sub_reason 19510 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 19511 { 19512 switch (subreason) { 19513 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 19514 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 19515 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 19516 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 19517 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 19518 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 19519 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 19520 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 19521 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 19522 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 19523 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 19524 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 19525 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 19526 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 19527 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 19528 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 19529 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 19530 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 19531 default: 19532 break; 19533 } 19534 19535 return 0; 19536 } 19537 19538 /** 19539 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 19540 * @wmi_roam_fail_reason: roam fail enum 19541 * 19542 * Return: Roaming failure reason codes 19543 */ 19544 static enum wlan_roam_failure_reason_code 19545 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 19546 { 19547 switch (wmi_roam_fail_reason) { 19548 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 19549 return ROAM_FAIL_REASON_NO_SCAN_START; 19550 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 19551 return ROAM_FAIL_REASON_NO_AP_FOUND; 19552 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 19553 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 19554 case WMI_ROAM_FAIL_REASON_HOST: 19555 return ROAM_FAIL_REASON_HOST; 19556 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 19557 return ROAM_FAIL_REASON_AUTH_SEND; 19558 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 19559 return ROAM_FAIL_REASON_AUTH_RECV; 19560 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 19561 return ROAM_FAIL_REASON_NO_AUTH_RESP; 19562 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 19563 return ROAM_FAIL_REASON_REASSOC_SEND; 19564 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 19565 return ROAM_FAIL_REASON_REASSOC_RECV; 19566 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 19567 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 19568 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 19569 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 19570 case WMI_ROAM_FAIL_REASON_MLME: 19571 return ROAM_FAIL_REASON_MLME; 19572 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 19573 return ROAM_FAIL_REASON_INTERNAL_ABORT; 19574 case WMI_ROAM_FAIL_REASON_SCAN_START: 19575 return ROAM_FAIL_REASON_SCAN_START; 19576 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 19577 return ROAM_FAIL_REASON_AUTH_NO_ACK; 19578 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 19579 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 19580 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 19581 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 19582 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 19583 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 19584 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 19585 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 19586 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 19587 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 19588 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 19589 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 19590 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 19591 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 19592 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 19593 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 19594 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 19595 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 19596 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 19597 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 19598 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 19599 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 19600 case WMI_ROAM_FAIL_REASON_DISCONNECT: 19601 return ROAM_FAIL_REASON_DISCONNECT; 19602 case WMI_ROAM_FAIL_REASON_SYNC: 19603 return ROAM_FAIL_REASON_SYNC; 19604 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 19605 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 19606 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 19607 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 19608 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 19609 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 19610 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 19611 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 19612 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND_AND_FINAL_BMISS_SENT: 19613 return ROAM_FAIL_REASON_NO_AP_FOUND_AND_FINAL_BMISS_SENT; 19614 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND_AND_FINAL_BMISS_SENT: 19615 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND_AND_FINAL_BMISS_SENT; 19616 case WMI_ROAM_FAIL_REASON_CURR_AP_STILL_OK: 19617 return ROAM_FAIL_REASON_CURR_AP_STILL_OK; 19618 default: 19619 return ROAM_FAIL_REASON_UNKNOWN; 19620 } 19621 } 19622 19623 /** 19624 * wmi_convert_to_cm_roam_invoke_reason() - Convert FW enum to Host enum 19625 * @reason: roam invoke reason from fw 19626 * 19627 * Return: Roam invoke reason code defined in host driver 19628 */ 19629 static enum roam_invoke_reason 19630 wmi_convert_to_cm_roam_invoke_reason(enum wlan_roam_invoke_reason reason) 19631 { 19632 switch (reason) { 19633 case ROAM_INVOKE_REASON_UNDEFINED: 19634 return WLAN_ROAM_STATS_INVOKE_REASON_UNDEFINED; 19635 case ROAM_INVOKE_REASON_NUD_FAILURE: 19636 return WLAN_ROAM_STATS_INVOKE_REASON_NUD_FAILURE; 19637 case ROAM_INVOKE_REASON_USER_SPACE: 19638 return WLAN_ROAM_STATS_INVOKE_REASON_USER_SPACE; 19639 default: 19640 return WLAN_ROAM_STATS_INVOKE_REASON_UNDEFINED; 19641 } 19642 } 19643 19644 /** 19645 * wmi_convert_to_cm_roam_tx_fail_reason() - Convert FW enum to Host enum 19646 * @tx_fail_reason: roam tx fail reason from fw 19647 * 19648 * Return: Roam tx fail reason code defined in host driver 19649 */ 19650 static enum roam_tx_failures_reason 19651 wmi_convert_to_cm_roam_tx_fail_reason(PEER_KICKOUT_REASON tx_fail_reason) 19652 { 19653 switch (tx_fail_reason) { 19654 case WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED: 19655 return WLAN_ROAM_STATS_KICKOUT_REASON_UNSPECIFIED; 19656 case WMI_PEER_STA_KICKOUT_REASON_XRETRY: 19657 return WLAN_ROAM_STATS_KICKOUT_REASON_XRETRY; 19658 case WMI_PEER_STA_KICKOUT_REASON_INACTIVITY: 19659 return WLAN_ROAM_STATS_KICKOUT_REASON_INACTIVITY; 19660 case WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT: 19661 return WLAN_ROAM_STATS_KICKOUT_REASON_IBSS_DISCONNECT; 19662 case WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT: 19663 return WLAN_ROAM_STATS_KICKOUT_REASON_TDLS_DISCONNECT; 19664 case WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT: 19665 return WLAN_ROAM_STATS_KICKOUT_REASON_SA_QUERY_TIMEOUT; 19666 case WMI_PEER_STA_KICKOUT_REASON_ROAMING_EVENT: 19667 return WLAN_ROAM_STATS_KICKOUT_REASON_ROAMING_EVENT; 19668 default: 19669 return WLAN_ROAM_STATS_KICKOUT_REASON_UNSPECIFIED; 19670 } 19671 } 19672 19673 /** 19674 * wmi_convert_roam_abort_reason() - Convert FW enum to Host enum 19675 * @abort_reason: roam abort reason from fw 19676 * 19677 * Return: Roam abort reason code defined in host driver 19678 */ 19679 static enum roam_abort_reason 19680 wmi_convert_roam_abort_reason(WMI_ROAM_FAIL_SUB_REASON_ID abort_reason) 19681 { 19682 switch (abort_reason) { 19683 case WMI_ROAM_ABORT_UNSPECIFIED: 19684 return WLAN_ROAM_STATS_ABORT_UNSPECIFIED; 19685 case WMI_ROAM_ABORT_LOWRSSI_DATA_RSSI_HIGH: 19686 return WLAN_ROAM_STATS_ABORT_LOWRSSI_DATA_RSSI_HIGH; 19687 case WMI_ROAM_ABORT_LOWRSSI_LINK_SPEED_GOOD: 19688 return WLAN_ROAM_STATS_ABORT_LOWRSSI_LINK_SPEED_GOOD; 19689 case WMI_ROAM_ABORT_BG_DATA_RSSI_HIGH: 19690 return WLAN_ROAM_STATS_ABORT_BG_DATA_RSSI_HIGH; 19691 case WMI_ROAM_ABORT_BG_RSSI_ABOVE_THRESHOLD: 19692 return WLAN_ROAM_STATS_ABORT_BG_RSSI_ABOVE_THRESHOLD; 19693 default: 19694 return WLAN_ROAM_STATS_ABORT_UNSPECIFIED; 19695 } 19696 } 19697 19698 /** 19699 * wlan_roam_scan_type() - Convert FW enum to Host enum 19700 * @scan_type: roam scan type from fw 19701 * 19702 * Return: Roam scan type defined in host driver 19703 */ 19704 static enum roam_stats_scan_type 19705 wlan_roam_scan_type(uint32_t scan_type) 19706 { 19707 switch (scan_type) { 19708 case 0: 19709 return ROAM_STATS_SCAN_TYPE_PARTIAL; 19710 case 1: 19711 return ROAM_STATS_SCAN_TYPE_FULL; 19712 case 2: 19713 return ROAM_STATS_SCAN_TYPE_NO_SCAN; 19714 case 3: 19715 return ROAM_STATS_SCAN_TYPE_HIGHER_BAND_5GHZ_6GHZ; 19716 case 4: 19717 return ROAM_STATS_SCAN_TYPE_HIGHER_BAND_6GHZ; 19718 default: 19719 return ROAM_STATS_SCAN_TYPE_PARTIAL; 19720 } 19721 } 19722 19723 /** 19724 * wlan_roam_dwell_type() - Convert FW enum to Host enum 19725 * @dwell_type: roam channel scan dwell type from fw 19726 * 19727 * Return: Roam channel scan dwell type defined in host driver 19728 */ 19729 static enum roam_scan_dwell_type 19730 wlan_roam_dwell_type(uint32_t dwell_type) 19731 { 19732 switch (dwell_type) { 19733 case 0: 19734 return WLAN_ROAM_DWELL_TYPE_UNSPECIFIED; 19735 case 1: 19736 return WLAN_ROAM_DWELL_ACTIVE_TYPE; 19737 case 2: 19738 return WLAN_ROAM_DWELL_PASSIVE_TYPE; 19739 default: 19740 return WLAN_ROAM_DWELL_TYPE_UNSPECIFIED; 19741 } 19742 } 19743 19744 #define WLAN_ROAM_PER_TX_RATE_OFFSET 0 19745 #define WLAN_ROAM_PER_RX_RATE_OFFSET 16 19746 #define WLAN_ROAM_BMISS_FINNAL_OFFSET 0 19747 #define WLAN_ROAM_BMISS_CONSECUTIVE_OFFSET 7 19748 #define WLAN_ROAM_BMISS_QOSNULL_OFFSET 24 19749 #define WLAN_ROAM_DENSE_ROAMABLE_OFFSET 0 19750 19751 /** 19752 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 19753 * from the WMI_ROAM_STATS_EVENTID 19754 * @wmi_handle: wmi handle 19755 * @evt_buf: Pointer to the event buffer 19756 * @trig: Pointer to destination structure to fill data 19757 * @idx: TLV id 19758 * @btm_idx: BTM index 19759 */ 19760 static QDF_STATUS 19761 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19762 struct wmi_roam_trigger_info *trig, uint8_t idx, 19763 uint8_t btm_idx) 19764 { 19765 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19766 wmi_roam_trigger_reason *src_data = NULL; 19767 uint32_t trig_reason = 0; 19768 uint32_t fail_reason = 0; 19769 uint32_t abort = 0; 19770 uint32_t invoke = 0; 19771 uint32_t tx_fail = 0; 19772 wmi_roam_trigger_reason_cmm *cmn_data = NULL; 19773 wmi_roam_trigger_per *per_data = NULL; 19774 wmi_roam_trigger_bmiss *bmiss_data = NULL; 19775 wmi_roam_trigger_hi_rssi *hi_rssi_data = NULL; 19776 wmi_roam_trigger_dense *dense_data = NULL; 19777 wmi_roam_trigger_force *force_data = NULL; 19778 wmi_roam_trigger_btm *btm_data = NULL; 19779 wmi_roam_trigger_bss_load *bss_load_data = NULL; 19780 wmi_roam_trigger_deauth *deauth_data = NULL; 19781 wmi_roam_trigger_periodic *periodic_data = NULL; 19782 wmi_roam_trigger_rssi *rssi_data = NULL; 19783 wmi_roam_trigger_kickout *kickout_data = NULL; 19784 wmi_roam_result *roam_result = NULL; 19785 wmi_roam_scan_info *scan_info = NULL; 19786 19787 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19788 if (!param_buf) { 19789 wmi_err("Param buf is NULL"); 19790 return QDF_STATUS_E_FAILURE; 19791 } 19792 19793 if (!param_buf->roam_result || idx >= param_buf->num_roam_result) 19794 wmi_err("roam_result or idx error.%u", idx); 19795 19796 if (!param_buf->roam_scan_info || idx >= param_buf->num_roam_scan_info) 19797 wmi_err("roam_scan_info or idx error.%u", idx); 19798 19799 trig->present = true; 19800 19801 if (param_buf->roam_scan_info) 19802 scan_info = ¶m_buf->roam_scan_info[idx]; 19803 19804 if (param_buf->roam_trigger_reason_cmm) 19805 cmn_data = ¶m_buf->roam_trigger_reason_cmm[idx]; 19806 19807 if (param_buf->roam_trigger_reason) 19808 src_data = ¶m_buf->roam_trigger_reason[idx]; 19809 19810 if (cmn_data) { 19811 trig_reason = cmn_data->trigger_reason; 19812 trig->trigger_reason = 19813 wmi_convert_fw_to_cm_trig_reason(trig_reason); 19814 trig->trigger_sub_reason = 19815 wmi_convert_roam_sub_reason(cmn_data->trigger_sub_reason); 19816 trig->timestamp = cmn_data->timestamp; 19817 trig->common_roam = true; 19818 } else if (src_data) { 19819 trig_reason = src_data->trigger_reason; 19820 trig->trigger_reason = 19821 wmi_convert_fw_to_cm_trig_reason(trig_reason); 19822 trig->trigger_sub_reason = 19823 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 19824 trig->current_rssi = src_data->current_rssi; 19825 trig->timestamp = src_data->timestamp; 19826 trig->common_roam = false; 19827 } 19828 19829 if (param_buf->roam_trigger_rssi) 19830 rssi_data = ¶m_buf->roam_trigger_rssi[idx]; 19831 19832 if (param_buf->roam_result) { 19833 roam_result = ¶m_buf->roam_result[idx]; 19834 19835 if (roam_result) { 19836 trig->roam_status = roam_result->roam_status; 19837 if (trig->roam_status) { 19838 fail_reason = roam_result->roam_fail_reason; 19839 trig->fail_reason = 19840 wlan_roam_fail_reason_code(fail_reason); 19841 19842 if (rssi_data) { 19843 abort = roam_result->roam_abort_reason; 19844 trig->abort_reason.abort_reason_code = 19845 wmi_convert_roam_abort_reason(abort); 19846 trig->abort_reason.data_rssi = 19847 rssi_data->data_rssi; 19848 trig->abort_reason.data_rssi_threshold = 19849 rssi_data->data_rssi_threshold; 19850 trig->abort_reason.rx_linkspeed_status = 19851 rssi_data->rx_linkspeed_status; 19852 } 19853 } 19854 } 19855 } 19856 19857 if (scan_info) 19858 trig->scan_type = 19859 wlan_roam_scan_type(scan_info->roam_scan_type); 19860 19861 switch (trig_reason) { 19862 case WMI_ROAM_TRIGGER_REASON_PER: 19863 if (param_buf->roam_trigger_per) 19864 per_data = ¶m_buf->roam_trigger_per[idx]; 19865 if (per_data) { 19866 trig->per_trig_data.tx_rate_thresh_percent = 19867 WMI_GET_BITS(per_data->rate_thresh_percnt, 19868 WLAN_ROAM_PER_RX_RATE_OFFSET, 8); 19869 trig->per_trig_data.rx_rate_thresh_percent = 19870 WMI_GET_BITS(per_data->rate_thresh_percnt, 19871 WLAN_ROAM_PER_TX_RATE_OFFSET, 8); 19872 } 19873 return QDF_STATUS_SUCCESS; 19874 19875 case WMI_ROAM_TRIGGER_REASON_BMISS: 19876 if (param_buf->roam_trigger_bmiss) 19877 bmiss_data = ¶m_buf->roam_trigger_bmiss[idx]; 19878 if (bmiss_data) { 19879 trig->bmiss_trig_data.final_bmiss_cnt = 19880 WMI_GET_BITS(bmiss_data->bmiss_status, 19881 WLAN_ROAM_BMISS_FINNAL_OFFSET, 7); 19882 trig->bmiss_trig_data.consecutive_bmiss_cnt = 19883 WMI_GET_BITS(bmiss_data->bmiss_status, 19884 WLAN_ROAM_BMISS_CONSECUTIVE_OFFSET, 19885 17); 19886 trig->bmiss_trig_data.qos_null_success = 19887 WMI_GET_BITS(bmiss_data->bmiss_status, 19888 WLAN_ROAM_BMISS_QOSNULL_OFFSET, 1); 19889 } 19890 return QDF_STATUS_SUCCESS; 19891 19892 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 19893 if (param_buf->roam_trigger_hi_rssi) 19894 hi_rssi_data = ¶m_buf->roam_trigger_hi_rssi[idx]; 19895 19896 if (hi_rssi_data && cmn_data) { 19897 trig->hi_rssi_trig_data.current_rssi = 19898 (uint8_t)cmn_data->current_rssi; 19899 trig->hi_rssi_trig_data.hirssi_threshold = 19900 (uint8_t)hi_rssi_data->hi_rssi_threshold; 19901 } 19902 return QDF_STATUS_SUCCESS; 19903 19904 case WMI_ROAM_TRIGGER_REASON_MAWC: 19905 case WMI_ROAM_TRIGGER_REASON_DENSE: 19906 if (param_buf->roam_trigger_dense) 19907 dense_data = ¶m_buf->roam_trigger_dense[idx]; 19908 if (dense_data) { 19909 trig->congestion_trig_data.rx_tput = 19910 dense_data->rx_tput; 19911 trig->congestion_trig_data.tx_tput = 19912 dense_data->tx_tput; 19913 trig->congestion_trig_data.roamable_count = 19914 WMI_GET_BITS(dense_data->dense_status, 19915 WLAN_ROAM_DENSE_ROAMABLE_OFFSET, 19916 8); 19917 } 19918 return QDF_STATUS_SUCCESS; 19919 19920 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 19921 if (cmn_data && rssi_data) { 19922 trig->background_trig_data.current_rssi = 19923 (uint8_t)cmn_data->current_rssi; 19924 trig->background_trig_data.data_rssi = 19925 (uint8_t)rssi_data->data_rssi; 19926 trig->background_trig_data.data_rssi_threshold = 19927 (uint8_t)rssi_data->data_rssi_threshold; 19928 } 19929 return QDF_STATUS_SUCCESS; 19930 19931 case WMI_ROAM_TRIGGER_REASON_IDLE: 19932 case WMI_ROAM_TRIGGER_REASON_FORCED: 19933 if (param_buf->roam_trigger_force) 19934 force_data = ¶m_buf->roam_trigger_force[idx]; 19935 if (force_data) { 19936 invoke = force_data->invoke_reason; 19937 trig->user_trig_data.invoke_reason = 19938 wmi_convert_to_cm_roam_invoke_reason(invoke); 19939 } 19940 return QDF_STATUS_SUCCESS; 19941 19942 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 19943 case WMI_ROAM_TRIGGER_REASON_BTC: 19944 return QDF_STATUS_SUCCESS; 19945 19946 case WMI_ROAM_TRIGGER_REASON_BTM: 19947 if (param_buf->roam_trigger_btm) 19948 btm_data = ¶m_buf->roam_trigger_btm[idx]; 19949 if (btm_data) { 19950 trig->btm_trig_data.btm_request_mode = 19951 btm_data->btm_request_mode; 19952 trig->btm_trig_data.disassoc_timer = 19953 btm_data->disassoc_imminent_timer; 19954 trig->btm_trig_data.validity_interval = 19955 btm_data->validity_internal; 19956 trig->btm_trig_data.candidate_list_count = 19957 btm_data->candidate_list_count; 19958 trig->btm_trig_data.btm_resp_status = 19959 btm_data->btm_response_status_code; 19960 trig->btm_trig_data.btm_bss_termination_timeout = 19961 btm_data->btm_bss_termination_timeout; 19962 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 19963 btm_data->btm_mbo_assoc_retry_timeout; 19964 trig->btm_trig_data.token = 19965 (uint16_t)btm_data->btm_req_dialog_token; 19966 if (scan_info) { 19967 trig->btm_trig_data.band = 19968 WMI_GET_MLO_BAND(scan_info->flags); 19969 if (trig->btm_trig_data.band != 19970 WMI_MLO_BAND_NO_MLO) 19971 trig->btm_trig_data.is_mlo = true; 19972 } 19973 } else if (src_data) { 19974 trig->btm_trig_data.btm_request_mode = 19975 src_data->btm_request_mode; 19976 trig->btm_trig_data.disassoc_timer = 19977 src_data->disassoc_imminent_timer; 19978 trig->btm_trig_data.validity_interval = 19979 src_data->validity_internal; 19980 trig->btm_trig_data.candidate_list_count = 19981 src_data->candidate_list_count; 19982 trig->btm_trig_data.btm_resp_status = 19983 src_data->btm_response_status_code; 19984 trig->btm_trig_data.btm_bss_termination_timeout = 19985 src_data->btm_bss_termination_timeout; 19986 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 19987 src_data->btm_mbo_assoc_retry_timeout; 19988 trig->btm_trig_data.token = 19989 src_data->btm_req_dialog_token; 19990 if (scan_info) { 19991 trig->btm_trig_data.band = 19992 WMI_GET_MLO_BAND(scan_info->flags); 19993 if (trig->btm_trig_data.band != 19994 WMI_MLO_BAND_NO_MLO) 19995 trig->btm_trig_data.is_mlo = true; 19996 } 19997 if ((btm_idx + 19998 trig->btm_trig_data.candidate_list_count) <= 19999 param_buf->num_roam_btm_request_candidate_info) 20000 extract_roam_11kv_candidate_info( 20001 wmi_handle, evt_buf, 20002 trig->btm_trig_data.btm_cand, 20003 btm_idx, 20004 src_data->candidate_list_count); 20005 } 20006 20007 return QDF_STATUS_SUCCESS; 20008 20009 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 20010 if (param_buf->roam_trigger_bss_load) 20011 bss_load_data = ¶m_buf->roam_trigger_bss_load[idx]; 20012 if (bss_load_data) 20013 trig->cu_trig_data.cu_load = bss_load_data->cu_load; 20014 else if (src_data) 20015 trig->cu_trig_data.cu_load = src_data->cu_load; 20016 return QDF_STATUS_SUCCESS; 20017 20018 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 20019 if (param_buf->roam_trigger_deauth) 20020 deauth_data = ¶m_buf->roam_trigger_deauth[idx]; 20021 if (deauth_data) { 20022 trig->deauth_trig_data.type = deauth_data->deauth_type; 20023 trig->deauth_trig_data.reason = 20024 deauth_data->deauth_reason; 20025 } else if (src_data) { 20026 trig->deauth_trig_data.type = src_data->deauth_type; 20027 trig->deauth_trig_data.reason = src_data->deauth_reason; 20028 } 20029 return QDF_STATUS_SUCCESS; 20030 20031 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 20032 if (param_buf->roam_trigger_periodic) 20033 periodic_data = ¶m_buf->roam_trigger_periodic[idx]; 20034 if (periodic_data) { 20035 trig->periodic_trig_data.periodic_timer_ms = 20036 periodic_data->periodic_timer_ms; 20037 } else if (src_data) 20038 trig->rssi_trig_data.threshold = 20039 src_data->roam_rssi_threshold; 20040 return QDF_STATUS_SUCCESS; 20041 20042 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 20043 if (cmn_data && rssi_data) { 20044 trig->low_rssi_trig_data.current_rssi = 20045 (uint8_t)cmn_data->current_rssi; 20046 trig->low_rssi_trig_data.roam_rssi_threshold = 20047 (uint8_t)rssi_data->roam_rssi_threshold; 20048 trig->low_rssi_trig_data.rx_linkspeed_status = 20049 (uint8_t)rssi_data->rx_linkspeed_status; 20050 } else if (src_data) 20051 trig->rssi_trig_data.threshold = 20052 src_data->roam_rssi_threshold; 20053 20054 return QDF_STATUS_SUCCESS; 20055 20056 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 20057 if (param_buf->roam_trigger_kickout) 20058 kickout_data = ¶m_buf->roam_trigger_kickout[idx]; 20059 if (kickout_data) { 20060 tx_fail = kickout_data->kickout_reason; 20061 trig->tx_failures_trig_data.kickout_threshold = 20062 kickout_data->kickout_th; 20063 trig->tx_failures_trig_data.kickout_reason = 20064 wmi_convert_to_cm_roam_tx_fail_reason(tx_fail); 20065 } 20066 return QDF_STATUS_SUCCESS; 20067 20068 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 20069 if (src_data) { 20070 trig->wtc_btm_trig_data.roaming_mode = 20071 src_data->vendor_specific1[0]; 20072 trig->wtc_btm_trig_data.vsie_trigger_reason = 20073 src_data->vendor_specific1[1]; 20074 trig->wtc_btm_trig_data.sub_code = 20075 src_data->vendor_specific1[2]; 20076 trig->wtc_btm_trig_data.wtc_mode = 20077 src_data->vendor_specific1[3]; 20078 trig->wtc_btm_trig_data.wtc_scan_mode = 20079 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 20080 trig->wtc_btm_trig_data.wtc_rssi_th = 20081 src_data->vendor_specific1[5]; 20082 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 20083 src_data->vendor_specific1[6]; 20084 20085 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 20086 src_data->vendor_specific2[0]; 20087 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 20088 src_data->vendor_specific2[1]; 20089 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 20090 src_data->vendor_specific2[2]; 20091 trig->wtc_btm_trig_data.duration = 20092 src_data->vendor_specific2[3]; 20093 } 20094 return QDF_STATUS_SUCCESS; 20095 default: 20096 return QDF_STATUS_SUCCESS; 20097 } 20098 20099 return QDF_STATUS_SUCCESS; 20100 } 20101 20102 /** 20103 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 20104 * from the WMI_ROAM_STATS_EVENTID 20105 * @wmi_handle: wmi handle 20106 * @evt_buf: Pointer to the event buffer 20107 * @dst: Pointer to destination structure to fill data 20108 * @ap_idx: TLV index for this roam scan 20109 * @num_cand: number of candidates list in the roam scan 20110 */ 20111 static QDF_STATUS 20112 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20113 struct wmi_roam_candidate_info *dst, 20114 uint8_t ap_idx, uint16_t num_cand) 20115 { 20116 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20117 wmi_roam_ap_info *src = NULL; 20118 uint8_t i; 20119 20120 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20121 if (!param_buf) { 20122 wmi_err("Param buf is NULL"); 20123 return QDF_STATUS_E_FAILURE; 20124 } 20125 20126 if (ap_idx >= param_buf->num_roam_ap_info) { 20127 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 20128 ap_idx, param_buf->num_roam_ap_info); 20129 return QDF_STATUS_E_FAILURE; 20130 } 20131 20132 src = ¶m_buf->roam_ap_info[ap_idx]; 20133 20134 for (i = 0; i < num_cand; i++) { 20135 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 20136 dst->type = src->candidate_type; 20137 dst->freq = src->channel; 20138 dst->etp = src->etp; 20139 dst->rssi = src->rssi; 20140 dst->rssi_score = src->rssi_score; 20141 dst->cu_load = src->cu_load; 20142 dst->cu_score = src->cu_score; 20143 dst->total_score = src->total_score; 20144 dst->timestamp = src->timestamp; 20145 dst->dl_reason = src->bl_reason; 20146 dst->dl_source = src->bl_source; 20147 dst->dl_timestamp = src->bl_timestamp; 20148 dst->dl_original_timeout = src->bl_original_timeout; 20149 dst->is_mlo = WMI_GET_AP_INFO_MLO_STATUS(src->flags); 20150 20151 src++; 20152 dst++; 20153 } 20154 20155 return QDF_STATUS_SUCCESS; 20156 } 20157 20158 #define ROAM_SUCCESS 0 20159 20160 /** 20161 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 20162 * from the WMI_ROAM_STATS_EVENTID 20163 * @wmi_handle: wmi handle 20164 * @evt_buf: Pointer to the event buffer 20165 * @dst: Pointer to destination structure to fill data 20166 * @idx: TLV id 20167 * @chan_idx: Index of the channel tlv for the current roam trigger 20168 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 20169 */ 20170 static QDF_STATUS 20171 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20172 struct wmi_roam_scan_data *dst, uint8_t idx, 20173 uint8_t chan_idx, uint8_t ap_idx) 20174 { 20175 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20176 wmi_roam_scan_info *src_data = NULL; 20177 wmi_roam_scan_channel_info *src_chan = NULL; 20178 QDF_STATUS status; 20179 uint8_t i; 20180 20181 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20182 if (!param_buf || !param_buf->roam_scan_info || 20183 idx >= param_buf->num_roam_scan_info) 20184 return QDF_STATUS_E_FAILURE; 20185 20186 src_data = ¶m_buf->roam_scan_info[idx]; 20187 20188 dst->present = true; 20189 dst->type = src_data->roam_scan_type; 20190 dst->num_chan = src_data->roam_scan_channel_count; 20191 dst->scan_complete_timestamp = src_data->scan_complete_timestamp; 20192 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 20193 dst->is_btcoex_active = WMI_GET_BTCONNECT_STATUS(src_data->flags); 20194 dst->frame_info_count = src_data->frame_info_count; 20195 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 20196 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 20197 20198 dst->band = WMI_GET_MLO_BAND(src_data->flags); 20199 if (dst->band != WMI_MLO_BAND_NO_MLO) 20200 dst->is_mlo = true; 20201 20202 /* Read the channel data only for dst->type is 0 (partial scan) */ 20203 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 20204 chan_idx < param_buf->num_roam_scan_chan_info) { 20205 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 20206 dst->num_chan = MAX_ROAM_SCAN_CHAN; 20207 20208 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 20209 20210 if ((dst->num_chan + chan_idx) > 20211 param_buf->num_roam_scan_chan_info) { 20212 wmi_err("Invalid TLV. num_chan %d chan_idx %d num_roam_scan_chan_info %d", 20213 dst->num_chan, chan_idx, 20214 param_buf->num_roam_scan_chan_info); 20215 return QDF_STATUS_SUCCESS; 20216 } 20217 20218 for (i = 0; i < dst->num_chan; i++) { 20219 dst->chan_freq[i] = src_chan->channel; 20220 dst->dwell_type[i] = 20221 (uint8_t)wlan_roam_dwell_type(src_chan->ch_dwell_type); 20222 src_chan++; 20223 } 20224 } 20225 20226 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 20227 return QDF_STATUS_SUCCESS; 20228 20229 dst->num_ap = src_data->roam_ap_count; 20230 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 20231 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 20232 20233 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 20234 ap_idx, dst->num_ap); 20235 if (QDF_IS_STATUS_ERROR(status)) { 20236 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 20237 return status; 20238 } 20239 20240 return QDF_STATUS_SUCCESS; 20241 } 20242 20243 /** 20244 * extract_roam_result_stats_tlv() - Extract the Roam trigger stats 20245 * from the WMI_ROAM_STATS_EVENTID 20246 * @wmi_handle: wmi handle 20247 * @evt_buf: Pointer to the event buffer 20248 * @dst: Pointer to destination structure to fill data 20249 * @idx: TLV id 20250 */ 20251 static QDF_STATUS 20252 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20253 struct wmi_roam_result *dst, uint8_t idx) 20254 { 20255 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20256 wmi_roam_result *src_data = NULL; 20257 20258 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20259 if (!param_buf || !param_buf->roam_result || 20260 idx >= param_buf->num_roam_result) 20261 return QDF_STATUS_E_FAILURE; 20262 20263 src_data = ¶m_buf->roam_result[idx]; 20264 20265 dst->present = true; 20266 dst->status = src_data->roam_status; 20267 dst->timestamp = src_data->timestamp; 20268 if (src_data->roam_fail_reason != ROAM_SUCCESS) 20269 dst->fail_reason = 20270 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 20271 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 20272 20273 return QDF_STATUS_SUCCESS; 20274 } 20275 20276 /** 20277 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 20278 * from the WMI_ROAM_STATS_EVENTID 20279 * @wmi_handle: wmi handle 20280 * @evt_buf: Pointer to the event buffer 20281 * @dst: Pointer to destination structure to fill data 20282 * @idx: TLV id 20283 * @rpt_idx: Neighbor report Channel index 20284 */ 20285 static QDF_STATUS 20286 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20287 struct wmi_neighbor_report_data *dst, 20288 uint8_t idx, uint8_t rpt_idx) 20289 { 20290 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20291 wmi_roam_neighbor_report_info *src_data = NULL; 20292 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 20293 uint8_t i; 20294 20295 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20296 if (!param_buf || !param_buf->roam_neighbor_report_info || 20297 !param_buf->num_roam_neighbor_report_info || 20298 idx >= param_buf->num_roam_neighbor_report_info) { 20299 wmi_debug("Invalid 1kv param buf"); 20300 return QDF_STATUS_E_FAILURE; 20301 } 20302 20303 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 20304 20305 dst->present = true; 20306 dst->req_type = src_data->request_type; 20307 dst->num_freq = src_data->neighbor_report_channel_count; 20308 dst->req_time = src_data->neighbor_report_request_timestamp; 20309 dst->resp_time = src_data->neighbor_report_response_timestamp; 20310 dst->btm_query_token = src_data->btm_query_token; 20311 dst->btm_query_reason = src_data->btm_query_reason_code; 20312 dst->req_token = 20313 WMI_ROAM_NEIGHBOR_REPORT_INFO_REQUEST_TOKEN_GET(src_data->neighbor_report_detail); 20314 dst->resp_token = 20315 WMI_ROAM_NEIGHBOR_REPORT_INFO_RESPONSE_TOKEN_GET(src_data->neighbor_report_detail); 20316 dst->num_rpt = 20317 WMI_ROAM_NEIGHBOR_REPORT_INFO_NUM_OF_NRIE_GET(src_data->neighbor_report_detail); 20318 20319 dst->band = 20320 WMI_ROAM_NEIGHBOR_REPORT_INFO_MLO_BAND_INFO_GET(src_data->neighbor_report_detail); 20321 20322 if (dst->band != WMI_MLO_BAND_NO_MLO) 20323 dst->is_mlo = true; 20324 20325 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 20326 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 20327 return QDF_STATUS_SUCCESS; 20328 20329 if (!param_buf->roam_neighbor_report_chan_info) { 20330 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 20331 dst->num_freq); 20332 dst->num_freq = 0; 20333 /* return success as its optional tlv and we can print neighbor 20334 * report received info 20335 */ 20336 return QDF_STATUS_SUCCESS; 20337 } 20338 20339 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 20340 20341 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 20342 dst->num_freq = MAX_ROAM_SCAN_CHAN; 20343 20344 if ((dst->num_freq + rpt_idx) > 20345 param_buf->num_roam_neighbor_report_chan_info) { 20346 wmi_err("Invalid TLV. num_freq %d rpt_idx %d num_roam_neighbor_report_chan_info %d", 20347 dst->num_freq, rpt_idx, 20348 param_buf->num_roam_scan_chan_info); 20349 return QDF_STATUS_SUCCESS; 20350 } 20351 20352 for (i = 0; i < dst->num_freq; i++) { 20353 dst->freq[i] = src_freq->channel; 20354 src_freq++; 20355 } 20356 20357 return QDF_STATUS_SUCCESS; 20358 } 20359 20360 /** 20361 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 20362 * @wmi_handle: handle to WMI. 20363 * @roam_param: pointer to hold roam set parameter 20364 * 20365 * Return: QDF_STATUS_SUCCESS for success or error code 20366 */ 20367 static QDF_STATUS 20368 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 20369 struct vdev_set_params *roam_param) 20370 { 20371 QDF_STATUS ret; 20372 wmi_roam_set_param_cmd_fixed_param *cmd; 20373 wmi_buf_t buf; 20374 uint16_t len = sizeof(*cmd); 20375 20376 buf = wmi_buf_alloc(wmi_handle, len); 20377 if (!buf) 20378 return QDF_STATUS_E_NOMEM; 20379 20380 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 20381 WMITLV_SET_HDR(&cmd->tlv_header, 20382 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 20383 WMITLV_GET_STRUCT_TLVLEN 20384 (wmi_roam_set_param_cmd_fixed_param)); 20385 cmd->vdev_id = roam_param->vdev_id; 20386 cmd->param_id = roam_param->param_id; 20387 cmd->param_value = roam_param->param_value; 20388 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 20389 cmd->vdev_id, cmd->param_id, cmd->param_value); 20390 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 20391 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20392 WMI_ROAM_SET_PARAM_CMDID); 20393 if (QDF_IS_STATUS_ERROR(ret)) { 20394 wmi_err("Failed to send roam set param command, ret = %d", ret); 20395 wmi_buf_free(buf); 20396 } 20397 20398 return ret; 20399 } 20400 #else 20401 static inline QDF_STATUS 20402 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20403 struct wmi_roam_trigger_info *trig, uint8_t idx, 20404 uint8_t btm_idx) 20405 { 20406 return QDF_STATUS_E_NOSUPPORT; 20407 } 20408 20409 static inline QDF_STATUS 20410 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20411 struct wmi_roam_result *dst, uint8_t idx) 20412 { 20413 return QDF_STATUS_E_NOSUPPORT; 20414 } 20415 20416 static QDF_STATUS 20417 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20418 struct wmi_neighbor_report_data *dst, 20419 uint8_t idx, uint8_t rpt_idx) 20420 { 20421 return QDF_STATUS_E_NOSUPPORT; 20422 } 20423 20424 static QDF_STATUS 20425 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20426 struct wmi_roam_scan_data *dst, uint8_t idx, 20427 uint8_t chan_idx, uint8_t ap_idx) 20428 { 20429 return QDF_STATUS_E_NOSUPPORT; 20430 } 20431 #endif 20432 20433 #ifdef WLAN_FEATURE_PKT_CAPTURE 20434 static QDF_STATUS 20435 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 20436 struct mgmt_offload_event_params *params) 20437 { 20438 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 20439 wmi_mgmt_hdr *hdr; 20440 20441 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 20442 if (!param_tlvs) 20443 return QDF_STATUS_E_INVAL; 20444 20445 hdr = param_tlvs->fixed_param; 20446 if (!hdr) 20447 return QDF_STATUS_E_INVAL; 20448 20449 if (hdr->buf_len > param_tlvs->num_bufp) 20450 return QDF_STATUS_E_INVAL; 20451 20452 params->tsf_l32 = hdr->tsf_l32; 20453 params->chan_freq = hdr->chan_freq; 20454 params->rate_kbps = hdr->rate_kbps; 20455 params->rssi = hdr->rssi; 20456 params->buf_len = hdr->buf_len; 20457 params->tx_status = hdr->tx_status; 20458 params->buf = param_tlvs->bufp; 20459 params->tx_retry_cnt = hdr->tx_retry_cnt; 20460 return QDF_STATUS_SUCCESS; 20461 } 20462 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 20463 20464 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20465 static QDF_STATUS 20466 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 20467 struct smu_event_params *params) 20468 { 20469 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 20470 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 20471 20472 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 20473 if (!param_buf) { 20474 wmi_err("Invalid smart monitor event"); 20475 return QDF_STATUS_E_INVAL; 20476 } 20477 20478 smu_event = param_buf->fixed_param; 20479 if (!smu_event) { 20480 wmi_err("smart monitor event fixed param is NULL"); 20481 return QDF_STATUS_E_INVAL; 20482 } 20483 20484 params->vdev_id = smu_event->vdev_id; 20485 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 20486 return QDF_STATUS_E_INVAL; 20487 20488 params->rx_vht_sgi = smu_event->rx_vht_sgi; 20489 20490 return QDF_STATUS_SUCCESS; 20491 } 20492 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 20493 20494 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20495 /** 20496 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 20497 * 20498 * @wmi: wmi handle 20499 * @vdev_id: vdev id 20500 * @burst_mode: Indicates whether relation derived using FTM is needed for 20501 * each FTM frame or only aggregated result is required. 20502 * 20503 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 20504 * 20505 * Return: QDF_STATUS 20506 */ 20507 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 20508 uint32_t vdev_id, 20509 bool burst_mode) 20510 { 20511 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 20512 wmi_buf_t buf; 20513 int32_t len = sizeof(*cmd); 20514 20515 buf = wmi_buf_alloc(wmi, len); 20516 if (!buf) { 20517 wmi_err("wmi_buf_alloc failed"); 20518 return QDF_STATUS_E_NOMEM; 20519 } 20520 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 20521 WMITLV_SET_HDR(&cmd->tlv_header, 20522 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 20523 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 20524 cmd->vdev_id = vdev_id; 20525 cmd->agg_relation = burst_mode ? false : true; 20526 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 20527 wmi_err("Failed to send audio sync trigger cmd"); 20528 wmi_buf_free(buf); 20529 return QDF_STATUS_E_FAILURE; 20530 } 20531 20532 return QDF_STATUS_SUCCESS; 20533 } 20534 20535 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 20536 uint32_t vdev_id, 20537 uint64_t lpass_ts) 20538 { 20539 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 20540 wmi_buf_t buf; 20541 int32_t len = sizeof(*cmd); 20542 20543 buf = wmi_buf_alloc(wmi, len); 20544 if (!buf) { 20545 wmi_err("wmi_buf_alloc failed"); 20546 return QDF_STATUS_E_NOMEM; 20547 } 20548 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 20549 WMITLV_SET_HDR(&cmd->tlv_header, 20550 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 20551 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 20552 cmd->vdev_id = vdev_id; 20553 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 20554 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 20555 20556 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 20557 wmi_err("Failed to send audio qtime command"); 20558 wmi_buf_free(buf); 20559 return QDF_STATUS_E_FAILURE; 20560 } 20561 20562 return QDF_STATUS_SUCCESS; 20563 } 20564 20565 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 20566 wmi_unified_t wmi, void *buf, 20567 struct ftm_time_sync_start_stop_params *param) 20568 { 20569 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 20570 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 20571 20572 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 20573 if (!param_buf) { 20574 wmi_err("Invalid audio sync start stop event buffer"); 20575 return QDF_STATUS_E_FAILURE; 20576 } 20577 20578 resp_event = param_buf->fixed_param; 20579 if (!resp_event) { 20580 wmi_err("Invalid audio sync start stop fixed param buffer"); 20581 return QDF_STATUS_E_FAILURE; 20582 } 20583 20584 param->vdev_id = resp_event->vdev_id; 20585 param->timer_interval = resp_event->periodicity; 20586 param->num_reads = resp_event->reads_needed; 20587 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 20588 resp_event->qtimer_l32; 20589 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 20590 resp_event->mac_timer_l32; 20591 20592 wmi_debug("FTM time sync time_interval %d, num_reads %d", 20593 param->timer_interval, param->num_reads); 20594 20595 return QDF_STATUS_SUCCESS; 20596 } 20597 20598 static QDF_STATUS 20599 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 20600 struct ftm_time_sync_offset *param) 20601 { 20602 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 20603 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 20604 wmi_audio_sync_q_master_slave_times *q_pair; 20605 int iter; 20606 20607 param_buf = 20608 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 20609 if (!param_buf) { 20610 wmi_err("Invalid timesync ftm offset event buffer"); 20611 return QDF_STATUS_E_FAILURE; 20612 } 20613 20614 resp_event = param_buf->fixed_param; 20615 if (!resp_event) { 20616 wmi_err("Invalid timesync ftm offset fixed param buffer"); 20617 return QDF_STATUS_E_FAILURE; 20618 } 20619 20620 param->vdev_id = resp_event->vdev_id; 20621 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 20622 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 20623 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 20624 20625 q_pair = param_buf->audio_sync_q_master_slave_times; 20626 if (!q_pair) { 20627 wmi_err("Invalid q_master_slave_times buffer"); 20628 return QDF_STATUS_E_FAILURE; 20629 } 20630 20631 for (iter = 0; iter < param->num_qtime; iter++) { 20632 param->pairs[iter].qtime_initiator = ( 20633 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 20634 q_pair[iter].qmaster_l32; 20635 param->pairs[iter].qtime_target = ( 20636 (uint64_t)q_pair[iter].qslave_u32 << 32) | 20637 q_pair[iter].qslave_l32; 20638 } 20639 return QDF_STATUS_SUCCESS; 20640 } 20641 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 20642 20643 /** 20644 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 20645 * @wmi: wmi handle 20646 * @vdev_id: vdev id 20647 * 20648 * TSF_TSTAMP_READ_VALUE is the only operation supported 20649 * Return: QDF_STATUS_SUCCESS for success or error code 20650 */ 20651 static QDF_STATUS 20652 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 20653 { 20654 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 20655 wmi_buf_t buf; 20656 int32_t len = sizeof(*cmd); 20657 20658 buf = wmi_buf_alloc(wmi, len); 20659 if (!buf) 20660 return QDF_STATUS_E_NOMEM; 20661 20662 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 20663 WMITLV_SET_HDR(&cmd->tlv_header, 20664 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 20665 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 20666 cmd->vdev_id = vdev_id; 20667 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 20668 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 20669 if (wmi_unified_cmd_send(wmi, buf, len, 20670 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 20671 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 20672 __func__); 20673 wmi_buf_free(buf); 20674 return QDF_STATUS_E_FAILURE; 20675 } 20676 20677 return QDF_STATUS_SUCCESS; 20678 } 20679 20680 /** 20681 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 20682 * @wmi_handle: wmi handle 20683 * @evt_buf: pointer to event buffer 20684 * @param: Pointer to struct to hold event info 20685 * 20686 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 20687 */ 20688 static QDF_STATUS 20689 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20690 struct wmi_host_tsf_event *param) 20691 { 20692 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 20693 wmi_vdev_tsf_report_event_fixed_param *evt; 20694 20695 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 20696 if (!param_buf) { 20697 wmi_err("Invalid tsf report event buffer"); 20698 return QDF_STATUS_E_INVAL; 20699 } 20700 20701 evt = param_buf->fixed_param; 20702 param->vdev_id = evt->vdev_id; 20703 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 20704 param->tsf_low = evt->tsf_low; 20705 param->tsf_high = evt->tsf_high; 20706 param->qtimer_low = evt->qtimer_low; 20707 param->qtimer_high = evt->qtimer_high; 20708 param->tsf_id = evt->tsf_id; 20709 param->tsf_id_valid = evt->tsf_id_valid; 20710 param->mac_id = evt->mac_id; 20711 param->mac_id_valid = evt->mac_id_valid; 20712 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 20713 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 20714 param->tqm_timer_low = evt->tqm_timer_low; 20715 param->tqm_timer_high = evt->tqm_timer_high; 20716 param->use_tqm_timer = evt->use_tqm_timer; 20717 20718 return QDF_STATUS_SUCCESS; 20719 } 20720 20721 /** 20722 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 20723 * status tlv 20724 * @wmi_handle: wmi handle 20725 * @evt_buf: pointer to event buffer 20726 * @param: Pointer to hold csa switch count status event param 20727 * 20728 * Return: QDF_STATUS_SUCCESS for success or error code 20729 */ 20730 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 20731 wmi_unified_t wmi_handle, 20732 void *evt_buf, 20733 struct pdev_csa_switch_count_status *param) 20734 { 20735 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 20736 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 20737 20738 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 20739 evt_buf; 20740 if (!param_buf) { 20741 wmi_err("Invalid CSA status event"); 20742 return QDF_STATUS_E_INVAL; 20743 } 20744 20745 csa_status = param_buf->fixed_param; 20746 20747 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20748 wmi_handle, 20749 csa_status->pdev_id); 20750 param->current_switch_count = csa_status->current_switch_count; 20751 param->num_vdevs = csa_status->num_vdevs; 20752 param->vdev_ids = param_buf->vdev_ids; 20753 20754 return QDF_STATUS_SUCCESS; 20755 } 20756 20757 #ifdef CONFIG_AFC_SUPPORT 20758 /** 20759 * send_afc_cmd_tlv() - Sends the AFC indication to FW 20760 * @wmi_handle: wmi handle 20761 * @pdev_id: Pdev id 20762 * @param: Pointer to hold AFC indication. 20763 * 20764 * Return: QDF_STATUS_SUCCESS for success or error code 20765 */ 20766 static 20767 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 20768 uint8_t pdev_id, 20769 struct reg_afc_resp_rx_ind_info *param) 20770 { 20771 wmi_buf_t buf; 20772 wmi_afc_cmd_fixed_param *cmd; 20773 uint32_t len; 20774 uint8_t *buf_ptr; 20775 QDF_STATUS ret; 20776 20777 len = sizeof(wmi_afc_cmd_fixed_param); 20778 buf = wmi_buf_alloc(wmi_handle, len); 20779 if (!buf) 20780 return QDF_STATUS_E_NOMEM; 20781 20782 buf_ptr = (uint8_t *)wmi_buf_data(buf); 20783 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 20784 20785 WMITLV_SET_HDR(&cmd->tlv_header, 20786 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 20787 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 20788 20789 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 20790 wmi_handle, 20791 pdev_id); 20792 cmd->cmd_type = param->cmd_type; 20793 cmd->serv_resp_format = param->serv_resp_format; 20794 20795 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 20796 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 20797 if (QDF_IS_STATUS_ERROR(ret)) { 20798 wmi_err("Failed to send WMI_AFC_CMDID"); 20799 wmi_buf_free(buf); 20800 return QDF_STATUS_E_FAILURE; 20801 } 20802 20803 return QDF_STATUS_SUCCESS; 20804 } 20805 #endif 20806 20807 /** 20808 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 20809 * @wmi_handle: wmi handle 20810 * @vdev_id: vdev id 20811 * @param: Pointer to hold TX power info 20812 * 20813 * Return: QDF_STATUS_SUCCESS for success or error code 20814 */ 20815 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 20816 uint8_t vdev_id, 20817 struct reg_tpc_power_info *param) 20818 { 20819 wmi_buf_t buf; 20820 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 20821 wmi_vdev_ch_power_info *ch_power_info; 20822 uint8_t *buf_ptr; 20823 uint16_t idx; 20824 uint32_t len; 20825 QDF_STATUS ret; 20826 20827 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 20828 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 20829 20830 buf = wmi_buf_alloc(wmi_handle, len); 20831 if (!buf) 20832 return QDF_STATUS_E_NOMEM; 20833 20834 buf_ptr = (uint8_t *)wmi_buf_data(buf); 20835 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 20836 20837 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 20838 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 20839 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 20840 20841 tpc_power_info_param->vdev_id = vdev_id; 20842 tpc_power_info_param->psd_power = param->is_psd_power; 20843 tpc_power_info_param->eirp_power = param->eirp_power; 20844 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 20845 wmi_debug("eirp_power = %d is_psd_power = %d", 20846 tpc_power_info_param->eirp_power, 20847 tpc_power_info_param->psd_power); 20848 reg_print_ap_power_type_6ghz(tpc_power_info_param->power_type_6ghz); 20849 20850 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 20851 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 20852 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 20853 20854 buf_ptr += WMI_TLV_HDR_SIZE; 20855 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 20856 20857 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 20858 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 20859 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 20860 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 20861 ch_power_info[idx].chan_cfreq = 20862 param->chan_power_info[idx].chan_cfreq; 20863 ch_power_info[idx].tx_power = 20864 param->chan_power_info[idx].tx_power; 20865 wmi_debug("chan_cfreq = %d tx_power = %d", 20866 ch_power_info[idx].chan_cfreq, 20867 ch_power_info[idx].tx_power); 20868 buf_ptr += sizeof(wmi_vdev_ch_power_info); 20869 } 20870 20871 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 20872 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20873 WMI_VDEV_SET_TPC_POWER_CMDID); 20874 if (QDF_IS_STATUS_ERROR(ret)) 20875 wmi_buf_free(buf); 20876 20877 20878 return ret; 20879 } 20880 20881 /** 20882 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 20883 * @wmi_handle: wmi handle 20884 * @evt_buf: event buffer 20885 * @param: dpd status info 20886 * 20887 * Return: QDF_STATUS_SUCCESS for success or error code 20888 */ 20889 static QDF_STATUS 20890 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 20891 void *evt_buf, 20892 struct wmi_host_pdev_get_dpd_status_event *param) 20893 { 20894 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 20895 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 20896 20897 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 20898 if (!param_buf) { 20899 wmi_err("Invalid get dpd_status event"); 20900 return QDF_STATUS_E_INVAL; 20901 } 20902 20903 dpd_status = param_buf->fixed_param; 20904 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 20905 (wmi_handle, dpd_status->pdev_id); 20906 param->dpd_status = dpd_status->dpd_status; 20907 20908 return QDF_STATUS_SUCCESS; 20909 } 20910 20911 static int 20912 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 20913 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 20914 { 20915 if (status->halphy_cal_valid_bmap && valid_bit) 20916 return (status->halphy_cal_status && valid_bit); 20917 20918 return 0; 20919 } 20920 20921 static QDF_STATUS 20922 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 20923 void *evt_buf, 20924 struct wmi_host_pdev_get_halphy_cal_status_event *param) 20925 { 20926 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 20927 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 20928 20929 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 20930 if (!param_buf) { 20931 wmi_err("Invalid get halphy cal status event"); 20932 return QDF_STATUS_E_INVAL; 20933 } 20934 20935 halphy_cal_status = param_buf->fixed_param; 20936 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 20937 (wmi_handle, halphy_cal_status->pdev_id); 20938 param->halphy_cal_adc_status = 20939 convert_halphy_status(halphy_cal_status, 20940 WMI_HALPHY_CAL_ADC_BMAP); 20941 param->halphy_cal_bwfilter_status = 20942 convert_halphy_status(halphy_cal_status, 20943 WMI_HALPHY_CAL_BWFILTER_BMAP); 20944 param->halphy_cal_pdet_and_pal_status = 20945 convert_halphy_status(halphy_cal_status, 20946 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 20947 param->halphy_cal_rxdco_status = 20948 convert_halphy_status(halphy_cal_status, 20949 WMI_HALPHY_CAL_RXDCO_BMAP); 20950 param->halphy_cal_comb_txiq_rxiq_status = 20951 convert_halphy_status(halphy_cal_status, 20952 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 20953 param->halphy_cal_ibf_status = 20954 convert_halphy_status(halphy_cal_status, 20955 WMI_HALPHY_CAL_IBF_BMAP); 20956 param->halphy_cal_pa_droop_status = 20957 convert_halphy_status(halphy_cal_status, 20958 WMI_HALPHY_CAL_PA_DROOP_BMAP); 20959 param->halphy_cal_dac_status = 20960 convert_halphy_status(halphy_cal_status, 20961 WMI_HALPHY_CAL_DAC_BMAP); 20962 param->halphy_cal_ani_status = 20963 convert_halphy_status(halphy_cal_status, 20964 WMI_HALPHY_CAL_ANI_BMAP); 20965 param->halphy_cal_noise_floor_status = 20966 convert_halphy_status(halphy_cal_status, 20967 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 20968 20969 return QDF_STATUS_SUCCESS; 20970 } 20971 20972 /** 20973 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 20974 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 20975 * 20976 * Return: host_set_halphy_cal_status 20977 */ 20978 static enum wmi_host_set_halphy_cal_status 20979 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 20980 { 20981 if (fw_status == 0) 20982 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 20983 else if (fw_status == 1) 20984 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 20985 20986 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 20987 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 20988 } 20989 20990 /** 20991 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 20992 * @wmi_handle: wmi handle 20993 * @evt_buf: event buffer 20994 * @param: set halphy cal status info 20995 * 20996 * Return: QDF_STATUS_SUCCESS for success or error code 20997 */ 20998 static QDF_STATUS 20999 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 21000 void *evt_buf, 21001 struct wmi_host_pdev_set_halphy_cal_event *param) 21002 { 21003 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 21004 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 21005 21006 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 21007 if (!param_buf) { 21008 wmi_err("Invalid set halphy_status event"); 21009 return QDF_STATUS_E_INVAL; 21010 } 21011 21012 set_halphy_status = param_buf->fixed_param; 21013 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 21014 (wmi_handle, set_halphy_status->pdev_id); 21015 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 21016 21017 return QDF_STATUS_SUCCESS; 21018 } 21019 21020 /** 21021 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 21022 * @wmi_handle: wmi handle 21023 * @evt_buf: pointer to event buffer 21024 * @len: length of the event buffer 21025 * @param: Pointer to hold install key complete event param 21026 * 21027 * Return: QDF_STATUS_SUCCESS for success or error code 21028 */ 21029 static QDF_STATUS 21030 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 21031 void *evt_buf, uint32_t len, 21032 struct wmi_install_key_comp_event *param) 21033 { 21034 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 21035 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 21036 21037 if (len < sizeof(*param_buf)) { 21038 wmi_err("invalid event buf len %d", len); 21039 return QDF_STATUS_E_INVAL; 21040 } 21041 21042 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 21043 if (!param_buf) { 21044 wmi_err("received null buf from target"); 21045 return QDF_STATUS_E_INVAL; 21046 } 21047 21048 key_fp = param_buf->fixed_param; 21049 if (!key_fp) { 21050 wmi_err("received null event data from target"); 21051 return QDF_STATUS_E_INVAL; 21052 } 21053 21054 param->vdev_id = key_fp->vdev_id; 21055 param->key_ix = key_fp->key_ix; 21056 param->key_flags = key_fp->key_flags; 21057 param->status = key_fp->status; 21058 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 21059 param->peer_macaddr); 21060 21061 return QDF_STATUS_SUCCESS; 21062 } 21063 21064 static QDF_STATUS 21065 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 21066 struct wmi_host_send_set_halphy_cal_info *param) 21067 { 21068 wmi_buf_t buf; 21069 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 21070 QDF_STATUS ret; 21071 uint32_t len; 21072 21073 len = sizeof(*cmd); 21074 21075 buf = wmi_buf_alloc(wmi_handle, len); 21076 if (!buf) 21077 return QDF_STATUS_E_FAILURE; 21078 21079 cmd = (void *)wmi_buf_data(buf); 21080 21081 WMITLV_SET_HDR(&cmd->tlv_header, 21082 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 21083 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 21084 21085 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 21086 param->pdev_id); 21087 cmd->online_halphy_cals_bmap = param->value; 21088 cmd->home_scan_channel = param->chan_sel; 21089 21090 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 21091 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 21092 if (QDF_IS_STATUS_ERROR(ret)) { 21093 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 21094 wmi_buf_free(buf); 21095 } 21096 21097 return ret; 21098 } 21099 21100 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21101 /** 21102 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 21103 * @wmi: wmi handle 21104 * @params: set MAC address command params 21105 * 21106 * Return: QDF_STATUS_SUCCESS for success or error code 21107 */ 21108 static QDF_STATUS 21109 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 21110 struct set_mac_addr_params *params) 21111 { 21112 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 21113 wmi_buf_t buf; 21114 int32_t len = sizeof(*cmd); 21115 21116 buf = wmi_buf_alloc(wmi, len); 21117 if (!buf) 21118 return QDF_STATUS_E_NOMEM; 21119 21120 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 21121 WMITLV_SET_HDR( 21122 &cmd->tlv_header, 21123 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 21124 WMITLV_GET_STRUCT_TLVLEN 21125 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 21126 cmd->vdev_id = params->vdev_id; 21127 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 21128 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 21129 21130 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 21131 QDF_MAC_ADDR_FMT, cmd->vdev_id, 21132 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 21133 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 21134 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 21135 if (wmi_unified_cmd_send(wmi, buf, len, 21136 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 21137 wmi_buf_free(buf); 21138 return QDF_STATUS_E_FAILURE; 21139 } 21140 21141 return QDF_STATUS_SUCCESS; 21142 } 21143 21144 /** 21145 * extract_update_mac_address_event_tlv() - extract update MAC address event 21146 * @wmi_handle: WMI handle 21147 * @evt_buf: event buffer 21148 * @vdev_id: VDEV ID 21149 * @status: FW status of the set MAC address operation 21150 * 21151 * Return: QDF_STATUS 21152 */ 21153 static QDF_STATUS extract_update_mac_address_event_tlv( 21154 wmi_unified_t wmi_handle, void *evt_buf, 21155 uint8_t *vdev_id, uint8_t *status) 21156 { 21157 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 21158 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 21159 21160 param_buf = 21161 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 21162 21163 event = param_buf->fixed_param; 21164 21165 *vdev_id = event->vdev_id; 21166 *status = event->status; 21167 21168 return QDF_STATUS_SUCCESS; 21169 } 21170 #endif 21171 21172 #ifdef WLAN_FEATURE_11BE_MLO 21173 /** 21174 * extract_quiet_offload_event_tlv() - extract quiet offload event 21175 * @wmi_handle: WMI handle 21176 * @evt_buf: event buffer 21177 * @quiet_event: quiet event extracted from the buffer 21178 * 21179 * Return: QDF_STATUS 21180 */ 21181 static QDF_STATUS extract_quiet_offload_event_tlv( 21182 wmi_unified_t wmi_handle, void *evt_buf, 21183 struct vdev_sta_quiet_event *quiet_event) 21184 { 21185 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 21186 wmi_quiet_event_fixed_param *event; 21187 21188 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 21189 21190 event = param_buf->fixed_param; 21191 21192 if (!(event->mld_mac_address_present && event->linkid_present) && 21193 !event->link_mac_address_present) { 21194 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 21195 event->mld_mac_address_present, 21196 event->linkid_present, 21197 event->link_mac_address_present); 21198 return QDF_STATUS_E_INVAL; 21199 } 21200 21201 if (event->mld_mac_address_present) 21202 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 21203 quiet_event->mld_mac.bytes); 21204 if (event->link_mac_address_present) 21205 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 21206 quiet_event->link_mac.bytes); 21207 if (event->linkid_present) 21208 quiet_event->link_id = event->linkid; 21209 quiet_event->quiet_status = (event->quiet_status == 21210 WMI_QUIET_EVENT_START); 21211 21212 return QDF_STATUS_SUCCESS; 21213 } 21214 #endif 21215 21216 /** 21217 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 21218 * @wmi_handle: wmi handle 21219 * @params: RxFilter params 21220 * 21221 * Return: QDF_STATUS_SUCCESS for success or error code 21222 */ 21223 static QDF_STATUS 21224 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 21225 struct vdev_pn_mgmt_rxfilter_params *params) 21226 { 21227 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 21228 wmi_buf_t buf; 21229 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 21230 21231 if (!is_service_enabled_tlv(wmi_handle, 21232 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 21233 wmi_err("Rx PN Replay Check not supported by target"); 21234 return QDF_STATUS_E_NOSUPPORT; 21235 } 21236 21237 buf = wmi_buf_alloc(wmi_handle, len); 21238 if (!buf) { 21239 wmi_err("wmi buf alloc failed"); 21240 return QDF_STATUS_E_NOMEM; 21241 } 21242 21243 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 21244 WMITLV_SET_HDR( 21245 &cmd->tlv_header, 21246 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 21247 WMITLV_GET_STRUCT_TLVLEN 21248 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 21249 21250 cmd->vdev_id = params->vdev_id; 21251 cmd->pn_rx_filter = params->pn_rxfilter; 21252 21253 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21254 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 21255 wmi_err("Failed to send WMI command"); 21256 wmi_buf_free(buf); 21257 return QDF_STATUS_E_FAILURE; 21258 } 21259 21260 return QDF_STATUS_SUCCESS; 21261 } 21262 21263 static QDF_STATUS 21264 send_egid_info_cmd_tlv(wmi_unified_t wmi_handle, 21265 struct esl_egid_params *param) 21266 { 21267 wmi_esl_egid_cmd_fixed_param *cmd; 21268 wmi_buf_t buf; 21269 21270 uint32_t len = sizeof(*cmd); 21271 21272 buf = wmi_buf_alloc(wmi_handle, len); 21273 if (!buf) { 21274 wmi_err("wmi_buf_alloc failed"); 21275 return QDF_STATUS_E_NOMEM; 21276 } 21277 21278 cmd = (wmi_esl_egid_cmd_fixed_param *)wmi_buf_data(buf); 21279 WMITLV_SET_HDR( 21280 &cmd->tlv_header, 21281 WMITLV_TAG_STRUC_wmi_esl_egid_cmd_fixed_param, 21282 WMITLV_GET_STRUCT_TLVLEN(wmi_esl_egid_cmd_fixed_param)); 21283 qdf_mem_copy(cmd->egid_info, 21284 param->egid_info, 21285 sizeof(param->egid_info)); 21286 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ESL_EGID_CMDID)) { 21287 wmi_err("Failed to send WMI command"); 21288 wmi_buf_free(buf); 21289 return QDF_STATUS_E_FAILURE; 21290 } 21291 21292 return QDF_STATUS_SUCCESS; 21293 } 21294 21295 static QDF_STATUS 21296 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 21297 uint8_t *pdev_id, uint8_t *software_image, 21298 uint8_t *chip_info, 21299 uint32_t *pktlog_json_version) 21300 { 21301 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 21302 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 21303 21304 param_buf = 21305 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 21306 21307 event = param_buf->fixed_param; 21308 21309 if ((event->software_image[0] == '\0') || 21310 (event->chip_info[0] == '\0')) { 21311 *pdev_id = event->pdev_id; 21312 return QDF_STATUS_E_INVAL; 21313 } 21314 21315 qdf_mem_copy(software_image, event->software_image, 40); 21316 qdf_mem_copy(chip_info, event->chip_info, 40); 21317 *pktlog_json_version = event->pktlog_defs_json_version; 21318 *pdev_id = event->pdev_id; 21319 return QDF_STATUS_SUCCESS; 21320 } 21321 21322 #ifdef HEALTH_MON_SUPPORT 21323 /** 21324 * extract_health_mon_init_done_info_event_tlv() - Extract health monitor from 21325 * fw 21326 * @wmi_handle: wmi handle 21327 * @evt_buf: pointer to event buffer 21328 * @param: health monitor params 21329 * 21330 * Return: QDF_STATUS_SUCCESS for success or error code 21331 */ 21332 static QDF_STATUS 21333 extract_health_mon_init_done_info_event_tlv(wmi_unified_t wmi_handle, 21334 void *evt_buf, 21335 struct wmi_health_mon_params *param) 21336 { 21337 WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *param_buf; 21338 wmi_health_mon_init_done_fixed_param *event; 21339 21340 param_buf = 21341 (WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *)evt_buf; 21342 21343 event = param_buf->fixed_param; 21344 21345 param->ring_buf_paddr_low = event->ring_buf_paddr_low; 21346 param->ring_buf_paddr_high = event->ring_buf_paddr_high; 21347 param->initial_upload_period_ms = event->initial_upload_period_ms; 21348 param->read_index = 0; 21349 21350 return QDF_STATUS_SUCCESS; 21351 } 21352 #endif /* HEALTH_MON_SUPPORT */ 21353 21354 /** 21355 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 21356 * @wmi_handle: wmi handle 21357 * @evt_buf: pointer to event buffer 21358 * @pdev_stats: Pointer to hold pdev telemetry stats 21359 * 21360 * Return: QDF_STATUS_SUCCESS for success or error code 21361 */ 21362 static QDF_STATUS 21363 extract_pdev_telemetry_stats_tlv( 21364 wmi_unified_t wmi_handle, void *evt_buf, 21365 struct wmi_host_pdev_telemetry_stats *pdev_stats) 21366 { 21367 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 21368 wmi_pdev_telemetry_stats *ev; 21369 21370 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 21371 21372 if (param_buf->pdev_telemetry_stats) { 21373 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 21374 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 21375 ev->avg_chan_lat_per_ac, 21376 sizeof(ev->avg_chan_lat_per_ac)); 21377 pdev_stats->estimated_air_time_per_ac = 21378 ev->estimated_air_time_per_ac; 21379 } 21380 21381 return QDF_STATUS_SUCCESS; 21382 } 21383 21384 static QDF_STATUS 21385 send_set_mac_addr_rx_filter_cmd_tlv(wmi_unified_t wmi_handle, 21386 struct set_rx_mac_filter *param) 21387 { 21388 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *cmd; 21389 uint32_t len; 21390 wmi_buf_t buf; 21391 int ret; 21392 21393 if (!wmi_handle) { 21394 wmi_err("WMA context is invalid!"); 21395 return QDF_STATUS_E_INVAL; 21396 } 21397 21398 len = sizeof(*cmd); 21399 buf = wmi_buf_alloc(wmi_handle, len); 21400 if (!buf) { 21401 wmi_err("Failed allocate wmi buffer"); 21402 return QDF_STATUS_E_NOMEM; 21403 } 21404 21405 cmd = (wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *) 21406 wmi_buf_data(buf); 21407 21408 WMITLV_SET_HDR( 21409 &cmd->tlv_header, 21410 WMITLV_TAG_STRUC_wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param, 21411 WMITLV_GET_STRUCT_TLVLEN( 21412 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param)); 21413 21414 cmd->vdev_id = param->vdev_id; 21415 cmd->freq = param->freq; 21416 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac, &cmd->mac_addr); 21417 if (param->set) 21418 cmd->enable = 1; 21419 else 21420 cmd->enable = 0; 21421 wmi_debug("set random mac rx vdev:%d freq:%d set:%d " QDF_MAC_ADDR_FMT, 21422 param->vdev_id, param->freq, param->set, 21423 QDF_MAC_ADDR_REF(param->mac)); 21424 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 21425 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID); 21426 if (ret) { 21427 wmi_err("Failed to send action frame random mac cmd"); 21428 wmi_buf_free(buf); 21429 return QDF_STATUS_E_FAILURE; 21430 } 21431 21432 return QDF_STATUS_SUCCESS; 21433 } 21434 21435 static QDF_STATUS 21436 extract_sap_coex_fix_chan_caps(wmi_unified_t wmi_handle, 21437 uint8_t *event, 21438 struct wmi_host_coex_fix_chan_cap *cap) 21439 { 21440 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 21441 WMI_COEX_FIX_CHANNEL_CAPABILITIES *fw_cap; 21442 21443 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 21444 if (!param_buf) 21445 return QDF_STATUS_E_INVAL; 21446 21447 fw_cap = param_buf->coex_fix_channel_caps; 21448 if (!fw_cap) 21449 return QDF_STATUS_E_INVAL; 21450 21451 cap->fix_chan_priority = fw_cap->fix_channel_priority; 21452 21453 return QDF_STATUS_SUCCESS; 21454 } 21455 21456 static QDF_STATUS extract_tgtr2p_table_event_tlv(wmi_unified_t wmi_handle, 21457 uint8_t *evt_buf, 21458 struct r2p_table_update_status_obj *update_status, 21459 uint32_t len) 21460 { 21461 WMI_PDEV_SET_TGTR2P_TABLE_EVENTID_param_tlvs *param_buf; 21462 wmi_pdev_set_tgtr2p_table_event_fixed_param *event_fixed_hdr; 21463 21464 param_buf = (WMI_PDEV_SET_TGTR2P_TABLE_EVENTID_param_tlvs *)evt_buf; 21465 if (!param_buf) { 21466 wmi_err("Invalid TGTR2P event buf"); 21467 return QDF_STATUS_E_FAILURE; 21468 } 21469 21470 event_fixed_hdr = param_buf->fixed_param; 21471 update_status->pdev_id = event_fixed_hdr->pdev_id; 21472 update_status->status = event_fixed_hdr->status; 21473 21474 if (update_status->status != WMI_PDEV_TGTR2P_SUCCESS && 21475 update_status->status != 21476 WMI_PDEV_TGTR2P_SUCCESS_WAITING_FOR_END_OF_UPDATE) { 21477 wmi_err("Rate2Power table update failed. Status = %d", 21478 update_status->status); 21479 } 21480 21481 return QDF_STATUS_SUCCESS; 21482 } 21483 21484 struct wmi_ops tlv_ops = { 21485 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 21486 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 21487 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 21488 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 21489 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 21490 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 21491 .send_peer_param_cmd = send_peer_param_cmd_tlv, 21492 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 21493 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 21494 .send_peer_create_cmd = send_peer_create_cmd_tlv, 21495 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 21496 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 21497 .send_peer_rx_reorder_queue_setup_cmd = 21498 send_peer_rx_reorder_queue_setup_cmd_tlv, 21499 .send_peer_multi_rx_reorder_queue_setup_cmd = 21500 send_peer_multi_rx_reorder_queue_setup_cmd_tlv, 21501 .send_peer_rx_reorder_queue_remove_cmd = 21502 send_peer_rx_reorder_queue_remove_cmd_tlv, 21503 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 21504 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 21505 .send_multiple_pdev_param_cmd = send_multiple_pdev_param_cmd_tlv, 21506 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 21507 .send_pdev_set_rf_path_cmd = send_pdev_set_rf_path_cmd_tlv, 21508 .send_suspend_cmd = send_suspend_cmd_tlv, 21509 .send_resume_cmd = send_resume_cmd_tlv, 21510 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 21511 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 21512 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 21513 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 21514 .send_dbglog_cmd = send_dbglog_cmd_tlv, 21515 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 21516 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 21517 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 21518 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 21519 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 21520 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 21521 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 21522 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 21523 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 21524 .send_scan_start_cmd = send_scan_start_cmd_tlv, 21525 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 21526 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 21527 .send_mgmt_cmd = send_mgmt_cmd_tlv, 21528 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 21529 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 21530 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 21531 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 21532 .send_set_sta_uapsd_auto_trig_cmd = 21533 send_set_sta_uapsd_auto_trig_cmd_tlv, 21534 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 21535 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 21536 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 21537 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 21538 .send_lro_config_cmd = send_lro_config_cmd_tlv, 21539 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 21540 .send_probe_rsp_tmpl_send_cmd = 21541 send_probe_rsp_tmpl_send_cmd_tlv, 21542 .send_p2p_go_set_beacon_ie_cmd = 21543 send_p2p_go_set_beacon_ie_cmd_tlv, 21544 .send_setup_install_key_cmd = 21545 send_setup_install_key_cmd_tlv, 21546 .send_scan_probe_setoui_cmd = 21547 send_scan_probe_setoui_cmd_tlv, 21548 #ifdef IPA_OFFLOAD 21549 .send_ipa_offload_control_cmd = 21550 send_ipa_offload_control_cmd_tlv, 21551 #endif 21552 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 21553 .send_pno_start_cmd = send_pno_start_cmd_tlv, 21554 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 21555 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 21556 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 21557 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 21558 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 21559 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 21560 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 21561 .send_unified_ll_stats_get_sta_cmd = 21562 send_unified_ll_stats_get_sta_cmd_tlv, 21563 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 21564 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 21565 .send_congestion_cmd = send_congestion_cmd_tlv, 21566 .send_snr_request_cmd = send_snr_request_cmd_tlv, 21567 .send_snr_cmd = send_snr_cmd_tlv, 21568 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 21569 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 21570 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 21571 #endif 21572 #ifdef WLAN_SUPPORT_GREEN_AP 21573 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 21574 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 21575 .extract_green_ap_egap_status_info = 21576 extract_green_ap_egap_status_info_tlv, 21577 #endif 21578 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 21579 .send_green_ap_ll_ps_cmd = send_green_ap_ll_ps_cmd_tlv, 21580 .extract_green_ap_ll_ps_param = extract_green_ap_ll_ps_param_tlv, 21581 #endif 21582 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 21583 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 21584 #ifdef FEATURE_OEM_DATA 21585 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 21586 #endif 21587 #ifdef WLAN_FEATURE_CIF_CFR 21588 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 21589 #endif 21590 .send_dfs_phyerr_filter_offload_en_cmd = 21591 send_dfs_phyerr_filter_offload_en_cmd_tlv, 21592 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 21593 .send_process_dhcpserver_offload_cmd = 21594 send_process_dhcpserver_offload_cmd_tlv, 21595 .send_pdev_set_regdomain_cmd = 21596 send_pdev_set_regdomain_cmd_tlv, 21597 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 21598 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 21599 .save_fw_version_cmd = save_fw_version_cmd_tlv, 21600 .check_and_update_fw_version = 21601 check_and_update_fw_version_cmd_tlv, 21602 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 21603 .send_enable_specific_fw_logs_cmd = 21604 send_enable_specific_fw_logs_cmd_tlv, 21605 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 21606 .send_unit_test_cmd = send_unit_test_cmd_tlv, 21607 #ifdef FEATURE_WLAN_APF 21608 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 21609 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 21610 .send_apf_write_work_memory_cmd = 21611 wmi_send_apf_write_work_memory_cmd_tlv, 21612 .send_apf_read_work_memory_cmd = 21613 wmi_send_apf_read_work_memory_cmd_tlv, 21614 .extract_apf_read_memory_resp_event = 21615 wmi_extract_apf_read_memory_resp_event_tlv, 21616 #endif /* FEATURE_WLAN_APF */ 21617 .init_cmd_send = init_cmd_send_tlv, 21618 .send_vdev_set_custom_aggr_size_cmd = 21619 send_vdev_set_custom_aggr_size_cmd_tlv, 21620 .send_vdev_set_qdepth_thresh_cmd = 21621 send_vdev_set_qdepth_thresh_cmd_tlv, 21622 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 21623 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 21624 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 21625 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 21626 .send_periodic_chan_stats_config_cmd = 21627 send_periodic_chan_stats_config_cmd_tlv, 21628 #ifdef WLAN_IOT_SIM_SUPPORT 21629 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 21630 #endif 21631 .send_vdev_spectral_configure_cmd = 21632 send_vdev_spectral_configure_cmd_tlv, 21633 .send_vdev_spectral_enable_cmd = 21634 send_vdev_spectral_enable_cmd_tlv, 21635 #ifdef WLAN_CONV_SPECTRAL_ENABLE 21636 .extract_pdev_sscan_fw_cmd_fixed_param = 21637 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 21638 .extract_pdev_sscan_fft_bin_index = 21639 extract_pdev_sscan_fft_bin_index_tlv, 21640 .extract_pdev_spectral_session_chan_info = 21641 extract_pdev_spectral_session_chan_info_tlv, 21642 .extract_pdev_spectral_session_detector_info = 21643 extract_pdev_spectral_session_detector_info_tlv, 21644 .extract_spectral_caps_fixed_param = 21645 extract_spectral_caps_fixed_param_tlv, 21646 .extract_spectral_scan_bw_caps = 21647 extract_spectral_scan_bw_caps_tlv, 21648 .extract_spectral_fft_size_caps = 21649 extract_spectral_fft_size_caps_tlv, 21650 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 21651 .send_thermal_mitigation_param_cmd = 21652 send_thermal_mitigation_param_cmd_tlv, 21653 .send_process_update_edca_param_cmd = 21654 send_process_update_edca_param_cmd_tlv, 21655 .send_bss_color_change_enable_cmd = 21656 send_bss_color_change_enable_cmd_tlv, 21657 .send_coex_config_cmd = send_coex_config_cmd_tlv, 21658 .send_coex_multi_config_cmd = send_coex_multi_config_cmd_tlv, 21659 .send_set_country_cmd = send_set_country_cmd_tlv, 21660 .send_addba_send_cmd = send_addba_send_cmd_tlv, 21661 .send_delba_send_cmd = send_delba_send_cmd_tlv, 21662 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 21663 .get_target_cap_from_service_ready = extract_service_ready_tlv, 21664 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 21665 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 21666 .extract_host_mem_req = extract_host_mem_req_tlv, 21667 .save_service_bitmap = save_service_bitmap_tlv, 21668 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 21669 .is_service_enabled = is_service_enabled_tlv, 21670 .save_fw_version = save_fw_version_in_service_ready_tlv, 21671 .ready_extract_init_status = ready_extract_init_status_tlv, 21672 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 21673 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 21674 .extract_ready_event_params = extract_ready_event_params_tlv, 21675 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 21676 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 21677 .extract_frame_pn_params = extract_frame_pn_params_tlv, 21678 .extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv, 21679 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 21680 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 21681 #ifdef FEATURE_WLAN_SCAN_PNO 21682 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 21683 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 21684 #endif 21685 .extract_unit_test = extract_unit_test_tlv, 21686 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 21687 .extract_bcn_stats = extract_bcn_stats_tlv, 21688 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 21689 .extract_chan_stats = extract_chan_stats_tlv, 21690 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 21691 .extract_profile_ctx = extract_profile_ctx_tlv, 21692 .extract_profile_data = extract_profile_data_tlv, 21693 .send_fw_test_cmd = send_fw_test_cmd_tlv, 21694 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 21695 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 21696 .extract_service_ready_ext = extract_service_ready_ext_tlv, 21697 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 21698 .extract_dbs_or_sbs_service_ready_ext2 = 21699 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 21700 .extract_hw_mode_cap_service_ready_ext = 21701 extract_hw_mode_cap_service_ready_ext_tlv, 21702 .extract_mac_phy_cap_service_ready_ext = 21703 extract_mac_phy_cap_service_ready_ext_tlv, 21704 .extract_mac_phy_cap_service_ready_ext2 = 21705 extract_mac_phy_cap_service_ready_ext2_tlv, 21706 .extract_reg_cap_service_ready_ext = 21707 extract_reg_cap_service_ready_ext_tlv, 21708 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 21709 .extract_dbr_ring_cap_service_ready_ext = 21710 extract_dbr_ring_cap_service_ready_ext_tlv, 21711 .extract_dbr_ring_cap_service_ready_ext2 = 21712 extract_dbr_ring_cap_service_ready_ext2_tlv, 21713 .extract_scan_radio_cap_service_ready_ext2 = 21714 extract_scan_radio_cap_service_ready_ext2_tlv, 21715 .extract_msdu_idx_qtype_map_service_ready_ext2 = 21716 extract_msdu_idx_qtype_map_service_ready_ext2_tlv, 21717 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 21718 .extract_aux_dev_cap_service_ready_ext2 = 21719 extract_aux_dev_cap_service_ready_ext2_tlv, 21720 .extract_sar_cap_service_ready_ext = 21721 extract_sar_cap_service_ready_ext_tlv, 21722 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 21723 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 21724 .extract_fips_event_data = extract_fips_event_data_tlv, 21725 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21726 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 21727 #endif 21728 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 21729 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 21730 #endif 21731 #ifdef WLAN_FEATURE_DISA 21732 .extract_encrypt_decrypt_resp_event = 21733 extract_encrypt_decrypt_resp_event_tlv, 21734 #endif 21735 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 21736 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21737 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 21738 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 21739 #endif 21740 .extract_get_pn_data = extract_get_pn_data_tlv, 21741 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 21742 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 21743 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 21744 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 21745 #ifdef WLAN_FEATURE_DISA 21746 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 21747 #endif 21748 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 21749 .send_wlan_profile_hist_intvl_cmd = 21750 send_wlan_profile_hist_intvl_cmd_tlv, 21751 .is_management_record = is_management_record_tlv, 21752 .is_diag_event = is_diag_event_tlv, 21753 .is_force_fw_hang_cmd = is_force_fw_hang_cmd_tlv, 21754 #ifdef WLAN_FEATURE_ACTION_OUI 21755 .send_action_oui_cmd = send_action_oui_cmd_tlv, 21756 #endif 21757 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 21758 #ifdef QCA_SUPPORT_AGILE_DFS 21759 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 21760 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 21761 #endif 21762 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 21763 .extract_reg_chan_list_update_event = 21764 extract_reg_chan_list_update_event_tlv, 21765 #ifdef CONFIG_BAND_6GHZ 21766 .extract_reg_chan_list_ext_update_event = 21767 extract_reg_chan_list_ext_update_event_tlv, 21768 #ifdef CONFIG_AFC_SUPPORT 21769 .extract_afc_event = extract_afc_event_tlv, 21770 #endif 21771 #endif 21772 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 21773 .extract_num_rf_characterization_entries = 21774 extract_num_rf_characterization_entries_tlv, 21775 .extract_rf_characterization_entries = 21776 extract_rf_characterization_entries_tlv, 21777 #endif 21778 .extract_chainmask_tables = 21779 extract_chainmask_tables_tlv, 21780 .extract_thermal_stats = extract_thermal_stats_tlv, 21781 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 21782 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 21783 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 21784 #ifdef DFS_COMPONENT_ENABLE 21785 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 21786 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 21787 .extract_dfs_radar_detection_event = 21788 extract_dfs_radar_detection_event_tlv, 21789 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 21790 #endif 21791 .convert_pdev_id_host_to_target = 21792 convert_host_pdev_id_to_target_pdev_id_legacy, 21793 .convert_pdev_id_target_to_host = 21794 convert_target_pdev_id_to_host_pdev_id_legacy, 21795 21796 .convert_host_pdev_id_to_target = 21797 convert_host_pdev_id_to_target_pdev_id, 21798 .convert_target_pdev_id_to_host = 21799 convert_target_pdev_id_to_host_pdev_id, 21800 21801 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 21802 21803 .convert_phy_id_host_to_target = 21804 convert_host_phy_id_to_target_phy_id_legacy, 21805 .convert_phy_id_target_to_host = 21806 convert_target_phy_id_to_host_phy_id_legacy, 21807 21808 .convert_host_phy_id_to_target = 21809 convert_host_phy_id_to_target_phy_id, 21810 .convert_target_phy_id_to_host = 21811 convert_target_phy_id_to_host_phy_id, 21812 21813 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 21814 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 21815 .extract_reg_11d_new_country_event = 21816 extract_reg_11d_new_country_event_tlv, 21817 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 21818 .extract_reg_ch_avoid_event = 21819 extract_reg_ch_avoid_event_tlv, 21820 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 21821 .extract_obss_detection_info = extract_obss_detection_info_tlv, 21822 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 21823 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 21824 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 21825 .wmi_check_command_params = wmitlv_check_command_tlv_params, 21826 .extract_comb_phyerr = extract_comb_phyerr_tlv, 21827 .extract_single_phyerr = extract_single_phyerr_tlv, 21828 #ifdef QCA_SUPPORT_CP_STATS 21829 .extract_cca_stats = extract_cca_stats_tlv, 21830 #endif 21831 .extract_esp_estimation_ev_param = 21832 extract_esp_estimation_ev_param_tlv, 21833 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 21834 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 21835 #ifdef OBSS_PD 21836 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 21837 .send_obss_spatial_reuse_set_def_thresh = 21838 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 21839 .send_self_srg_bss_color_bitmap_set = 21840 send_self_srg_bss_color_bitmap_set_cmd_tlv, 21841 .send_self_srg_partial_bssid_bitmap_set = 21842 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 21843 .send_self_srg_obss_color_enable_bitmap = 21844 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 21845 .send_self_srg_obss_bssid_enable_bitmap = 21846 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 21847 .send_self_non_srg_obss_color_enable_bitmap = 21848 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 21849 .send_self_non_srg_obss_bssid_enable_bitmap = 21850 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 21851 #endif 21852 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 21853 .extract_ctl_failsafe_check_ev_param = 21854 extract_ctl_failsafe_check_ev_param_tlv, 21855 #ifdef WIFI_POS_CONVERGED 21856 .extract_oem_response_param = extract_oem_response_param_tlv, 21857 #endif /* WIFI_POS_CONVERGED */ 21858 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 21859 .extract_pasn_peer_create_req_event = 21860 extract_pasn_peer_create_req_event_tlv, 21861 .extract_pasn_peer_delete_req_event = 21862 extract_pasn_peer_delete_req_event_tlv, 21863 .send_rtt_pasn_auth_status_cmd = 21864 send_rtt_pasn_auth_status_cmd_tlv, 21865 .send_rtt_pasn_deauth_cmd = 21866 send_rtt_pasn_deauth_cmd_tlv, 21867 #endif 21868 #ifdef WLAN_MWS_INFO_DEBUGFS 21869 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 21870 #endif 21871 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 21872 #ifdef FEATURE_ANI_LEVEL_REQUEST 21873 .send_ani_level_cmd = send_ani_level_cmd_tlv, 21874 .extract_ani_level = extract_ani_level_tlv, 21875 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 21876 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 21877 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 21878 .extract_roam_result_stats = extract_roam_result_stats_tlv, 21879 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 21880 #ifdef WLAN_FEATURE_PKT_CAPTURE 21881 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 21882 #endif 21883 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 21884 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 21885 #endif 21886 21887 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 21888 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 21889 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 21890 .extract_time_sync_ftm_start_stop_event = 21891 extract_time_sync_ftm_start_stop_event_tlv, 21892 .extract_time_sync_ftm_offset_event = 21893 extract_time_sync_ftm_offset_event_tlv, 21894 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 21895 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 21896 .send_injector_config_cmd = send_injector_config_cmd_tlv, 21897 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 21898 .send_halphy_stats_cmd = send_halphy_stats_cmd_tlv, 21899 #ifdef FEATURE_MEC_OFFLOAD 21900 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 21901 #endif 21902 #if defined(WLAN_SUPPORT_INFRA_CTRL_PATH_STATS) || defined(WLAN_CONFIG_TELEMETRY_AGENT) 21903 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 21904 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 21905 .extract_cp_stats_more_pending = 21906 extract_cp_stats_more_pending_tlv, 21907 .extract_halphy_stats_end_of_event = 21908 extract_halphy_stats_end_of_event_tlv, 21909 .extract_halphy_stats_event_count = 21910 extract_halphy_stats_event_count_tlv, 21911 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 21912 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 21913 .extract_pdev_csa_switch_count_status = 21914 extract_pdev_csa_switch_count_status_tlv, 21915 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 21916 #ifdef CONFIG_AFC_SUPPORT 21917 .send_afc_cmd = send_afc_cmd_tlv, 21918 #endif 21919 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 21920 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 21921 .send_vdev_set_ltf_key_seed_cmd = 21922 send_vdev_set_ltf_key_seed_cmd_tlv, 21923 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 21924 .send_set_halphy_cal = send_set_halphy_cal_tlv, 21925 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 21926 #ifdef WLAN_MGMT_RX_REO_SUPPORT 21927 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 21928 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 21929 .send_mgmt_rx_reo_filter_config_cmd = 21930 send_mgmt_rx_reo_filter_config_cmd_tlv, 21931 #endif 21932 21933 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 21934 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 21935 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 21936 21937 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21938 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 21939 .extract_update_mac_address_event = 21940 extract_update_mac_address_event_tlv, 21941 #endif 21942 21943 #ifdef WLAN_FEATURE_11BE_MLO 21944 .extract_quiet_offload_event = 21945 extract_quiet_offload_event_tlv, 21946 #endif 21947 21948 #ifdef WLAN_SUPPORT_PPEDS 21949 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 21950 #endif /* WLAN_SUPPORT_PPEDS */ 21951 21952 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 21953 .extract_pktlog_decode_info_event = 21954 extract_pktlog_decode_info_event_tlv, 21955 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 21956 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 21957 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 21958 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 21959 #endif 21960 #ifdef WLAN_FEATURE_DBAM_CONFIG 21961 .send_dbam_config_cmd = send_dbam_config_cmd_tlv, 21962 .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, 21963 #endif 21964 #ifdef FEATURE_SET 21965 .feature_set_cmd_send = feature_set_cmd_send_tlv, 21966 #endif 21967 #ifdef HEALTH_MON_SUPPORT 21968 .extract_health_mon_init_done_info_event = 21969 extract_health_mon_init_done_info_event_tlv, 21970 #endif /* HEALTH_MON_SUPPORT */ 21971 .send_multiple_vdev_param_cmd = send_multiple_vdev_param_cmd_tlv, 21972 .set_mac_addr_rx_filter = send_set_mac_addr_rx_filter_cmd_tlv, 21973 .send_update_edca_pifs_param_cmd = 21974 send_update_edca_pifs_param_cmd_tlv, 21975 .extract_sap_coex_cap_service_ready_ext2 = 21976 extract_sap_coex_fix_chan_caps, 21977 .extract_tgtr2p_table_event = extract_tgtr2p_table_event_tlv, 21978 .send_egid_info_cmd = send_egid_info_cmd_tlv, 21979 .extract_csa_ie_received_ev_params = 21980 extract_csa_ie_received_ev_params_tlv, 21981 .extract_rf_path_resp = extract_rf_path_resp_tlv, 21982 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 21983 .extract_aoa_caps_service_ready_ext2 = 21984 extract_aoa_caps_tlv, 21985 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 21986 }; 21987 21988 #ifdef WLAN_FEATURE_11BE_MLO 21989 static void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 21990 { 21991 event_ids[wmi_mlo_setup_complete_event_id] = 21992 WMI_MLO_SETUP_COMPLETE_EVENTID; 21993 event_ids[wmi_mlo_teardown_complete_event_id] = 21994 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 21995 event_ids[wmi_mlo_link_set_active_resp_eventid] = 21996 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 21997 event_ids[wmi_vdev_quiet_offload_eventid] = 21998 WMI_QUIET_HANDLING_EVENTID; 21999 event_ids[wmi_mlo_ap_vdev_tid_to_link_map_eventid] = 22000 WMI_MLO_AP_VDEV_TID_TO_LINK_MAP_EVENTID; 22001 event_ids[wmi_mlo_link_removal_eventid] = 22002 WMI_MLO_LINK_REMOVAL_EVENTID; 22003 event_ids[wmi_mlo_link_state_info_eventid] = 22004 WMI_MLO_VDEV_LINK_INFO_EVENTID; 22005 event_ids[wmi_mlo_link_disable_request_eventid] = 22006 WMI_MLO_LINK_DISABLE_REQUEST_EVENTID; 22007 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 22008 event_ids[wmi_mlo_link_switch_request_eventid] = 22009 WMI_MLO_LINK_SWITCH_REQUEST_EVENTID; 22010 event_ids[wmi_mlo_link_state_switch_eventid] = 22011 WMI_MLO_LINK_STATE_SWITCH_EVENTID; 22012 #endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */ 22013 } 22014 #else /* WLAN_FEATURE_11BE_MLO */ 22015 static inline void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 22016 { 22017 } 22018 #endif /* WLAN_FEATURE_11BE_MLO */ 22019 22020 /** 22021 * populate_tlv_events_id() - populates wmi event ids 22022 * @event_ids: Pointer to hold event ids 22023 * 22024 * Return: None 22025 */ 22026 static void populate_tlv_events_id(WMI_EVT_ID *event_ids) 22027 { 22028 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 22029 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 22030 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 22031 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22032 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 22033 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 22034 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 22035 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 22036 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 22037 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 22038 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 22039 event_ids[wmi_service_ready_ext_event_id] = 22040 WMI_SERVICE_READY_EXT_EVENTID; 22041 event_ids[wmi_service_ready_ext2_event_id] = 22042 WMI_SERVICE_READY_EXT2_EVENTID; 22043 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 22044 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 22045 event_ids[wmi_vdev_install_key_complete_event_id] = 22046 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 22047 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 22048 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 22049 22050 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 22051 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 22052 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 22053 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 22054 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 22055 event_ids[wmi_peer_estimated_linkspeed_event_id] = 22056 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 22057 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 22058 event_ids[wmi_peer_create_conf_event_id] = 22059 WMI_PEER_CREATE_CONF_EVENTID; 22060 event_ids[wmi_peer_delete_response_event_id] = 22061 WMI_PEER_DELETE_RESP_EVENTID; 22062 event_ids[wmi_peer_delete_all_response_event_id] = 22063 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 22064 event_ids[wmi_peer_oper_mode_change_event_id] = 22065 WMI_PEER_OPER_MODE_CHANGE_EVENTID; 22066 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 22067 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 22068 event_ids[wmi_tbttoffset_update_event_id] = 22069 WMI_TBTTOFFSET_UPDATE_EVENTID; 22070 event_ids[wmi_ext_tbttoffset_update_event_id] = 22071 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 22072 event_ids[wmi_offload_bcn_tx_status_event_id] = 22073 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 22074 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 22075 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 22076 event_ids[wmi_mgmt_tx_completion_event_id] = 22077 WMI_MGMT_TX_COMPLETION_EVENTID; 22078 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 22079 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 22080 event_ids[wmi_tx_delba_complete_event_id] = 22081 WMI_TX_DELBA_COMPLETE_EVENTID; 22082 event_ids[wmi_tx_addba_complete_event_id] = 22083 WMI_TX_ADDBA_COMPLETE_EVENTID; 22084 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 22085 22086 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 22087 22088 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 22089 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 22090 22091 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 22092 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 22093 22094 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 22095 22096 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 22097 event_ids[wmi_p2p_lo_stop_event_id] = 22098 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 22099 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 22100 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 22101 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 22102 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 22103 event_ids[wmi_d0_wow_disable_ack_event_id] = 22104 WMI_D0_WOW_DISABLE_ACK_EVENTID; 22105 event_ids[wmi_wow_initial_wakeup_event_id] = 22106 WMI_WOW_INITIAL_WAKEUP_EVENTID; 22107 22108 event_ids[wmi_rtt_meas_report_event_id] = 22109 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 22110 event_ids[wmi_tsf_meas_report_event_id] = 22111 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 22112 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 22113 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 22114 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 22115 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 22116 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 22117 event_ids[wmi_diag_event_id_log_supported_event_id] = 22118 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 22119 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 22120 event_ids[wmi_nlo_scan_complete_event_id] = 22121 WMI_NLO_SCAN_COMPLETE_EVENTID; 22122 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 22123 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 22124 22125 event_ids[wmi_gtk_offload_status_event_id] = 22126 WMI_GTK_OFFLOAD_STATUS_EVENTID; 22127 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 22128 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 22129 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 22130 22131 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 22132 22133 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 22134 22135 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 22136 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 22137 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 22138 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 22139 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 22140 event_ids[wmi_wlan_profile_data_event_id] = 22141 WMI_WLAN_PROFILE_DATA_EVENTID; 22142 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 22143 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 22144 event_ids[wmi_vdev_get_keepalive_event_id] = 22145 WMI_VDEV_GET_KEEPALIVE_EVENTID; 22146 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 22147 22148 event_ids[wmi_diag_container_event_id] = 22149 WMI_DIAG_DATA_CONTAINER_EVENTID; 22150 22151 event_ids[wmi_host_auto_shutdown_event_id] = 22152 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 22153 22154 event_ids[wmi_update_whal_mib_stats_event_id] = 22155 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 22156 22157 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 22158 event_ids[wmi_update_vdev_rate_stats_event_id] = 22159 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 22160 22161 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 22162 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 22163 22164 /** Set OCB Sched Response, deprecated */ 22165 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 22166 22167 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 22168 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 22169 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 22170 22171 /* GPIO Event */ 22172 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 22173 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 22174 22175 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 22176 event_ids[wmi_rfkill_state_change_event_id] = 22177 WMI_RFKILL_STATE_CHANGE_EVENTID; 22178 22179 /* TDLS Event */ 22180 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 22181 22182 event_ids[wmi_batch_scan_enabled_event_id] = 22183 WMI_BATCH_SCAN_ENABLED_EVENTID; 22184 event_ids[wmi_batch_scan_result_event_id] = 22185 WMI_BATCH_SCAN_RESULT_EVENTID; 22186 /* OEM Event */ 22187 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 22188 event_ids[wmi_oem_meas_report_event_id] = 22189 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 22190 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 22191 22192 /* NAN Event */ 22193 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 22194 22195 /* LPI Event */ 22196 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 22197 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 22198 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 22199 22200 /* ExtScan events */ 22201 event_ids[wmi_extscan_start_stop_event_id] = 22202 WMI_EXTSCAN_START_STOP_EVENTID; 22203 event_ids[wmi_extscan_operation_event_id] = 22204 WMI_EXTSCAN_OPERATION_EVENTID; 22205 event_ids[wmi_extscan_table_usage_event_id] = 22206 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 22207 event_ids[wmi_extscan_cached_results_event_id] = 22208 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 22209 event_ids[wmi_extscan_wlan_change_results_event_id] = 22210 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 22211 event_ids[wmi_extscan_hotlist_match_event_id] = 22212 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 22213 event_ids[wmi_extscan_capabilities_event_id] = 22214 WMI_EXTSCAN_CAPABILITIES_EVENTID; 22215 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 22216 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 22217 22218 /* mDNS offload events */ 22219 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 22220 22221 /* SAP Authentication offload events */ 22222 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 22223 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 22224 22225 /** Out-of-context-of-bss (OCB) events */ 22226 event_ids[wmi_ocb_set_config_resp_event_id] = 22227 WMI_OCB_SET_CONFIG_RESP_EVENTID; 22228 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 22229 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 22230 event_ids[wmi_dcc_get_stats_resp_event_id] = 22231 WMI_DCC_GET_STATS_RESP_EVENTID; 22232 event_ids[wmi_dcc_update_ndl_resp_event_id] = 22233 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 22234 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 22235 /* System-On-Chip events */ 22236 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 22237 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 22238 event_ids[wmi_soc_hw_mode_transition_event_id] = 22239 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 22240 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 22241 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 22242 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 22243 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 22244 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 22245 #endif 22246 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 22247 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 22248 event_ids[wmi_vdev_ocac_complete_event_id] = 22249 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 22250 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 22251 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 22252 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 22253 #ifdef CONFIG_AFC_SUPPORT 22254 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 22255 #endif 22256 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 22257 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22258 event_ids[wmi_peer_sta_ps_statechg_event_id] = 22259 WMI_PEER_STA_PS_STATECHG_EVENTID; 22260 event_ids[wmi_pdev_channel_hopping_event_id] = 22261 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 22262 event_ids[wmi_offchan_data_tx_completion_event] = 22263 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 22264 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 22265 event_ids[wmi_dfs_radar_detection_event_id] = 22266 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 22267 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 22268 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 22269 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 22270 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 22271 event_ids[wmi_service_available_event_id] = 22272 WMI_SERVICE_AVAILABLE_EVENTID; 22273 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 22274 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 22275 /* NDP events */ 22276 event_ids[wmi_ndp_initiator_rsp_event_id] = 22277 WMI_NDP_INITIATOR_RSP_EVENTID; 22278 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 22279 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 22280 event_ids[wmi_ndp_responder_rsp_event_id] = 22281 WMI_NDP_RESPONDER_RSP_EVENTID; 22282 event_ids[wmi_ndp_end_indication_event_id] = 22283 WMI_NDP_END_INDICATION_EVENTID; 22284 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 22285 event_ids[wmi_ndl_schedule_update_event_id] = 22286 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 22287 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 22288 22289 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 22290 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 22291 event_ids[wmi_pdev_chip_power_stats_event_id] = 22292 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 22293 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 22294 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 22295 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 22296 event_ids[wmi_apf_capability_info_event_id] = 22297 WMI_BPF_CAPABILIY_INFO_EVENTID; 22298 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 22299 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 22300 event_ids[wmi_report_rx_aggr_failure_event_id] = 22301 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 22302 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 22303 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 22304 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 22305 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 22306 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 22307 event_ids[wmi_pdev_hw_mode_transition_event_id] = 22308 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 22309 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 22310 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 22311 event_ids[wmi_coex_bt_activity_event_id] = 22312 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 22313 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 22314 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 22315 event_ids[wmi_radio_tx_power_level_stats_event_id] = 22316 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 22317 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 22318 event_ids[wmi_dma_buf_release_event_id] = 22319 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 22320 event_ids[wmi_sap_obss_detection_report_event_id] = 22321 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 22322 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 22323 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 22324 event_ids[wmi_obss_color_collision_report_event_id] = 22325 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 22326 event_ids[wmi_pdev_div_rssi_antid_event_id] = 22327 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 22328 #ifdef WLAN_SUPPORT_TWT 22329 event_ids[wmi_twt_enable_complete_event_id] = 22330 WMI_TWT_ENABLE_COMPLETE_EVENTID; 22331 event_ids[wmi_twt_disable_complete_event_id] = 22332 WMI_TWT_DISABLE_COMPLETE_EVENTID; 22333 event_ids[wmi_twt_add_dialog_complete_event_id] = 22334 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 22335 event_ids[wmi_twt_del_dialog_complete_event_id] = 22336 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 22337 event_ids[wmi_twt_pause_dialog_complete_event_id] = 22338 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 22339 event_ids[wmi_twt_resume_dialog_complete_event_id] = 22340 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 22341 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 22342 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 22343 event_ids[wmi_twt_session_stats_event_id] = 22344 WMI_TWT_SESSION_STATS_EVENTID; 22345 event_ids[wmi_twt_notify_event_id] = 22346 WMI_TWT_NOTIFY_EVENTID; 22347 event_ids[wmi_twt_ack_complete_event_id] = 22348 WMI_TWT_ACK_EVENTID; 22349 #endif 22350 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 22351 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 22352 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 22353 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 22354 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 22355 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 22356 event_ids[wmi_pdev_interop_issues_ap_event_id] = 22357 WMI_PDEV_RAP_INFO_EVENTID; 22358 #endif 22359 #ifdef AST_HKV1_WORKAROUND 22360 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 22361 #endif 22362 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 22363 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 22364 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 22365 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 22366 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 22367 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 22368 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 22369 event_ids[wmi_pdev_cold_boot_cal_event_id] = 22370 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 22371 #ifdef WLAN_MWS_INFO_DEBUGFS 22372 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 22373 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 22374 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 22375 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 22376 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 22377 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 22378 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 22379 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 22380 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 22381 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 22382 #endif 22383 event_ids[wmi_coex_report_antenna_isolation_event_id] = 22384 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 22385 event_ids[wmi_peer_ratecode_list_event_id] = 22386 WMI_PEER_RATECODE_LIST_EVENTID; 22387 event_ids[wmi_chan_rf_characterization_info_event_id] = 22388 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 22389 event_ids[wmi_roam_auth_offload_event_id] = 22390 WMI_ROAM_PREAUTH_START_EVENTID; 22391 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 22392 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 22393 event_ids[wmi_motion_det_base_line_host_eventid] = 22394 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 22395 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 22396 event_ids[wmi_peer_tx_pn_response_event_id] = 22397 WMI_PEER_TX_PN_RESPONSE_EVENTID; 22398 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 22399 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 22400 event_ids[wmi_mgmt_offload_data_event_id] = 22401 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 22402 event_ids[wmi_nan_dmesg_event_id] = 22403 WMI_NAN_DMESG_EVENTID; 22404 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 22405 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 22406 event_ids[wmi_roam_pmkid_request_event_id] = 22407 WMI_ROAM_PMKID_REQUEST_EVENTID; 22408 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 22409 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 22410 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 22411 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 22412 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 22413 #endif 22414 event_ids[wmi_roam_scan_chan_list_id] = 22415 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 22416 event_ids[wmi_muedca_params_config_eventid] = 22417 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 22418 event_ids[wmi_pdev_sscan_fw_param_eventid] = 22419 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 22420 event_ids[wmi_roam_cap_report_event_id] = 22421 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 22422 event_ids[wmi_vdev_bcn_latency_event_id] = 22423 WMI_VDEV_BCN_LATENCY_EVENTID; 22424 event_ids[wmi_vdev_disconnect_event_id] = 22425 WMI_VDEV_DISCONNECT_EVENTID; 22426 event_ids[wmi_peer_create_conf_event_id] = 22427 WMI_PEER_CREATE_CONF_EVENTID; 22428 event_ids[wmi_pdev_cp_fwstats_eventid] = 22429 WMI_CTRL_PATH_STATS_EVENTID; 22430 event_ids[wmi_pdev_halphy_fwstats_eventid] = 22431 WMI_HALPHY_CTRL_PATH_STATS_EVENTID; 22432 event_ids[wmi_vdev_send_big_data_p2_eventid] = 22433 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 22434 event_ids[wmi_pdev_get_dpd_status_event_id] = 22435 WMI_PDEV_GET_DPD_STATUS_EVENTID; 22436 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 22437 event_ids[wmi_vdev_smart_monitor_event_id] = 22438 WMI_VDEV_SMART_MONITOR_EVENTID; 22439 #endif 22440 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 22441 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 22442 event_ids[wmi_pdev_set_halphy_cal_event_id] = 22443 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 22444 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 22445 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 22446 #ifdef WLAN_MGMT_RX_REO_SUPPORT 22447 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 22448 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 22449 #endif 22450 populate_tlv_events_id_mlo(event_ids); 22451 event_ids[wmi_roam_frame_event_id] = 22452 WMI_ROAM_FRAME_EVENTID; 22453 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 22454 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 22455 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 22456 #endif 22457 #ifdef WLAN_FEATURE_MCC_QUOTA 22458 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 22459 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 22460 #endif 22461 event_ids[wmi_peer_rx_pn_response_event_id] = 22462 WMI_PEER_RX_PN_RESPONSE_EVENTID; 22463 event_ids[wmi_extract_pktlog_decode_info_eventid] = 22464 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 22465 #ifdef QCA_RSSI_DB2DBM 22466 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 22467 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 22468 #endif 22469 #ifdef MULTI_CLIENT_LL_SUPPORT 22470 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 22471 #endif 22472 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 22473 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 22474 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 22475 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 22476 WMI_RTT_PASN_PEER_DELETE_EVENTID; 22477 #endif 22478 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 22479 event_ids[wmi_get_roam_vendor_control_param_event_id] = 22480 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 22481 #endif 22482 #ifdef WLAN_FEATURE_DBAM_CONFIG 22483 event_ids[wmi_coex_dbam_complete_event_id] = 22484 WMI_COEX_DBAM_COMPLETE_EVENTID; 22485 #endif 22486 event_ids[wmi_spectral_capabilities_eventid] = 22487 WMI_SPECTRAL_CAPABILITIES_EVENTID; 22488 #ifdef WLAN_FEATURE_COAP 22489 event_ids[wmi_wow_coap_buf_info_eventid] = 22490 WMI_WOW_COAP_BUF_INFO_EVENTID; 22491 #endif 22492 #ifdef HEALTH_MON_SUPPORT 22493 event_ids[wmi_extract_health_mon_init_done_info_eventid] = 22494 WMI_HEALTH_MON_INIT_DONE_EVENTID; 22495 #endif /* HEALTH_MON_SUPPORT */ 22496 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 22497 event_ids[wmi_xgap_enable_complete_eventid] = 22498 WMI_XGAP_ENABLE_COMPLETE_EVENTID; 22499 #endif 22500 event_ids[wmi_pdev_set_tgtr2p_table_eventid] = 22501 WMI_PDEV_SET_TGTR2P_TABLE_EVENTID; 22502 #ifdef QCA_MANUAL_TRIGGERED_ULOFDMA 22503 event_ids[wmi_manual_ul_ofdma_trig_feedback_eventid] = 22504 WMI_MANUAL_UL_OFDMA_TRIG_FEEDBACK_EVENTID; 22505 event_ids[wmi_manual_ul_ofdma_trig_rx_peer_userinfo_eventid] = 22506 WMI_MANUAL_UL_OFDMA_TRIG_RX_PEER_USERINFO_EVENTID; 22507 #endif 22508 #ifdef QCA_STANDALONE_SOUNDING_TRIGGER 22509 event_ids[wmi_vdev_standalone_sound_complete_eventid] = 22510 WMI_VDEV_STANDALONE_SOUND_COMPLETE_EVENTID; 22511 #endif 22512 event_ids[wmi_csa_ie_received_event_id] = WMI_CSA_IE_RECEIVED_EVENTID; 22513 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_11BE_MLO) 22514 event_ids[wmi_roam_synch_key_event_id] = WMI_ROAM_SYNCH_KEY_EVENTID; 22515 #endif 22516 #ifdef QCA_SUPPORT_PRIMARY_LINK_MIGRATE 22517 event_ids[wmi_peer_ptqm_migration_response_eventid] = 22518 WMI_MLO_PRIMARY_LINK_PEER_MIGRATION_EVENTID; 22519 #endif 22520 event_ids[wmi_pdev_set_rf_path_resp_eventid] = 22521 WMI_PDEV_SET_RF_PATH_RESP_EVENTID; 22522 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 22523 event_ids[wmi_pdev_enhanced_aoa_phasedelta_eventid] = 22524 WMI_PDEV_ENHANCED_AOA_PHASEDELTA_EVENTID; 22525 #endif 22526 #ifdef WLAN_FEATURE_LL_LT_SAP 22527 event_ids[wmi_audio_transport_switch_type_event_id] = 22528 WMI_AUDIO_TRANSPORT_SWITCH_TYPE_EVENTID; 22529 #endif 22530 22531 } 22532 22533 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 22534 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 22535 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22536 { 22537 wmi_service[wmi_service_get_station_in_ll_stats_req] = 22538 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 22539 } 22540 #else 22541 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22542 { 22543 } 22544 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 22545 #else 22546 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22547 { 22548 } 22549 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 22550 22551 #ifdef WLAN_FEATURE_11BE_MLO 22552 static void populate_tlv_service_mlo(uint32_t *wmi_service) 22553 { 22554 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 22555 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 22556 } 22557 #else /* WLAN_FEATURE_11BE_MLO */ 22558 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 22559 { 22560 } 22561 #endif /* WLAN_FEATURE_11BE_MLO */ 22562 22563 /** 22564 * populate_tlv_service() - populates wmi services 22565 * @wmi_service: Pointer to hold wmi_service 22566 * 22567 * Return: None 22568 */ 22569 static void populate_tlv_service(uint32_t *wmi_service) 22570 { 22571 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 22572 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 22573 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 22574 wmi_service[wmi_service_roam_scan_offload] = 22575 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 22576 wmi_service[wmi_service_bcn_miss_offload] = 22577 WMI_SERVICE_BCN_MISS_OFFLOAD; 22578 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 22579 wmi_service[wmi_service_sta_advanced_pwrsave] = 22580 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 22581 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 22582 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 22583 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 22584 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 22585 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 22586 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 22587 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 22588 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 22589 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 22590 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 22591 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 22592 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 22593 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 22594 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 22595 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 22596 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 22597 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 22598 wmi_service[wmi_service_packet_power_save] = 22599 WMI_SERVICE_PACKET_POWER_SAVE; 22600 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 22601 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 22602 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 22603 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 22604 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 22605 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 22606 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 22607 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 22608 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 22609 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 22610 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 22611 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 22612 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 22613 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 22614 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 22615 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 22616 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 22617 wmi_service[wmi_service_mcc_bcn_interval_change] = 22618 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 22619 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 22620 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 22621 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 22622 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 22623 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 22624 wmi_service[wmi_service_lte_ant_share_support] = 22625 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 22626 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 22627 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 22628 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 22629 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 22630 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 22631 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 22632 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 22633 wmi_service[wmi_service_bcn_txrate_override] = 22634 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 22635 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 22636 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 22637 wmi_service[wmi_service_estimate_linkspeed] = 22638 WMI_SERVICE_ESTIMATE_LINKSPEED; 22639 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 22640 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 22641 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 22642 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 22643 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 22644 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 22645 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 22646 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 22647 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 22648 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 22649 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 22650 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 22651 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 22652 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 22653 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 22654 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 22655 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 22656 wmi_service[wmi_service_sap_auth_offload] = 22657 WMI_SERVICE_SAP_AUTH_OFFLOAD; 22658 wmi_service[wmi_service_dual_band_simultaneous_support] = 22659 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 22660 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 22661 wmi_service[wmi_service_ap_arpns_offload] = 22662 WMI_SERVICE_AP_ARPNS_OFFLOAD; 22663 wmi_service[wmi_service_per_band_chainmask_support] = 22664 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 22665 wmi_service[wmi_service_packet_filter_offload] = 22666 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 22667 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 22668 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 22669 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 22670 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 22671 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 22672 wmi_service[wmi_service_multiple_vdev_restart] = 22673 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 22674 wmi_service[wmi_service_multiple_vdev_restart_bmap] = 22675 WMI_SERVICE_MULTIPLE_VDEV_RESTART_BITMAP_SUPPORT; 22676 wmi_service[wmi_service_smart_antenna_sw_support] = 22677 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 22678 wmi_service[wmi_service_smart_antenna_hw_support] = 22679 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 22680 22681 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 22682 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 22683 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 22684 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 22685 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 22686 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 22687 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 22688 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 22689 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 22690 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 22691 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 22692 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 22693 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 22694 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 22695 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 22696 wmi_service[wmi_service_periodic_chan_stat_support] = 22697 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 22698 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 22699 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 22700 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 22701 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 22702 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 22703 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22704 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 22705 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 22706 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 22707 wmi_service[wmi_service_unified_wow_capability] = 22708 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 22709 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22710 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 22711 wmi_service[wmi_service_sync_delete_cmds] = 22712 WMI_SERVICE_SYNC_DELETE_CMDS; 22713 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 22714 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 22715 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 22716 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 22717 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 22718 wmi_service[wmi_service_deprecated_replace] = 22719 WMI_SERVICE_DEPRECATED_REPLACE; 22720 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 22721 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 22722 wmi_service[wmi_service_enhanced_mcast_filter] = 22723 WMI_SERVICE_ENHANCED_MCAST_FILTER; 22724 wmi_service[wmi_service_half_rate_quarter_rate_support] = 22725 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 22726 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 22727 wmi_service[wmi_service_p2p_listen_offload_support] = 22728 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 22729 wmi_service[wmi_service_mark_first_wakeup_packet] = 22730 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 22731 wmi_service[wmi_service_multiple_mcast_filter_set] = 22732 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 22733 wmi_service[wmi_service_host_managed_rx_reorder] = 22734 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 22735 wmi_service[wmi_service_flash_rdwr_support] = 22736 WMI_SERVICE_FLASH_RDWR_SUPPORT; 22737 wmi_service[wmi_service_wlan_stats_report] = 22738 WMI_SERVICE_WLAN_STATS_REPORT; 22739 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 22740 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 22741 wmi_service[wmi_service_dfs_phyerr_offload] = 22742 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 22743 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 22744 wmi_service[wmi_service_fw_mem_dump_support] = 22745 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 22746 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 22747 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 22748 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 22749 wmi_service[wmi_service_hw_data_filtering] = 22750 WMI_SERVICE_HW_DATA_FILTERING; 22751 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 22752 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 22753 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 22754 wmi_service[wmi_service_extended_nss_support] = 22755 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 22756 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 22757 wmi_service[wmi_service_bcn_offload_start_stop_support] = 22758 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 22759 wmi_service[wmi_service_offchan_data_tid_support] = 22760 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 22761 wmi_service[wmi_service_support_dma] = 22762 WMI_SERVICE_SUPPORT_DIRECT_DMA; 22763 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 22764 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 22765 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 22766 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 22767 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 22768 wmi_service[wmi_service_11k_neighbour_report_support] = 22769 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 22770 wmi_service[wmi_service_ap_obss_detection_offload] = 22771 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 22772 wmi_service[wmi_service_bss_color_offload] = 22773 WMI_SERVICE_BSS_COLOR_OFFLOAD; 22774 wmi_service[wmi_service_gmac_offload_support] = 22775 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 22776 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 22777 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 22778 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 22779 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 22780 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 22781 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 22782 wmi_service[wmi_service_listen_interval_offload_support] = 22783 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 22784 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 22785 wmi_service[wmi_service_obss_spatial_reuse] = 22786 WMI_SERVICE_OBSS_SPATIAL_REUSE; 22787 wmi_service[wmi_service_per_vdev_chain_support] = 22788 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 22789 wmi_service[wmi_service_new_htt_msg_format] = 22790 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 22791 wmi_service[wmi_service_peer_unmap_cnf_support] = 22792 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 22793 wmi_service[wmi_service_beacon_reception_stats] = 22794 WMI_SERVICE_BEACON_RECEPTION_STATS; 22795 wmi_service[wmi_service_vdev_latency_config] = 22796 WMI_SERVICE_VDEV_LATENCY_CONFIG; 22797 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 22798 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 22799 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 22800 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 22801 wmi_service[wmi_service_nan_disable_support] = 22802 WMI_SERVICE_NAN_DISABLE_SUPPORT; 22803 wmi_service[wmi_service_sta_plus_sta_support] = 22804 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 22805 wmi_service[wmi_service_hw_db2dbm_support] = 22806 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 22807 wmi_service[wmi_service_wlm_stats_support] = 22808 WMI_SERVICE_WLM_STATS_REQUEST; 22809 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 22810 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 22811 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 22812 wmi_service[wmi_service_cfr_capture_support] = 22813 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 22814 wmi_service[wmi_service_cfr_capture_pdev_id_soc] = 22815 WMI_SERVICE_CFR_CAPTURE_PDEV_ID_SOC; 22816 wmi_service[wmi_service_bcast_twt_support] = 22817 WMI_SERVICE_BROADCAST_TWT; 22818 wmi_service[wmi_service_wpa3_ft_sae_support] = 22819 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 22820 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 22821 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 22822 wmi_service[wmi_service_ft_fils] = 22823 WMI_SERVICE_WPA3_FT_FILS; 22824 wmi_service[wmi_service_adaptive_11r_support] = 22825 WMI_SERVICE_ADAPTIVE_11R_ROAM; 22826 wmi_service[wmi_service_tx_compl_tsf64] = 22827 WMI_SERVICE_TX_COMPL_TSF64; 22828 wmi_service[wmi_service_data_stall_recovery_support] = 22829 WMI_SERVICE_DSM_ROAM_FILTER; 22830 wmi_service[wmi_service_vdev_delete_all_peer] = 22831 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 22832 wmi_service[wmi_service_three_way_coex_config_legacy] = 22833 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 22834 wmi_service[wmi_service_multiple_coex_config_support] = 22835 WMI_SERVICE_MULTIPLE_COEX_CONFIG_SUPPORT; 22836 wmi_service[wmi_service_rx_fse_support] = 22837 WMI_SERVICE_RX_FSE_SUPPORT; 22838 wmi_service[wmi_service_sae_roam_support] = 22839 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 22840 wmi_service[wmi_service_owe_roam_support] = 22841 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 22842 wmi_service[wmi_service_6ghz_support] = 22843 WMI_SERVICE_6GHZ_SUPPORT; 22844 wmi_service[wmi_service_bw_165mhz_support] = 22845 WMI_SERVICE_BW_165MHZ_SUPPORT; 22846 wmi_service[wmi_service_bw_restricted_80p80_support] = 22847 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 22848 wmi_service[wmi_service_packet_capture_support] = 22849 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 22850 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 22851 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 22852 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 22853 wmi_service[wmi_service_multiple_vdev_restart_ext] = 22854 WMI_SERVICE_UNAVAILABLE; 22855 wmi_service[wmi_service_time_sync_ftm] = 22856 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 22857 wmi_service[wmi_service_nss_ratio_to_host_support] = 22858 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 22859 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 22860 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 22861 wmi_service[wmi_beacon_protection_support] = 22862 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 22863 wmi_service[wmi_service_sta_nan_ndi_four_port] = 22864 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 22865 wmi_service[wmi_service_host_scan_stop_vdev_all] = 22866 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 22867 wmi_service[wmi_support_extend_address] = 22868 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 22869 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 22870 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 22871 wmi_service[wmi_service_suiteb_roam_support] = 22872 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 22873 wmi_service[wmi_service_no_interband_mcc_support] = 22874 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 22875 wmi_service[wmi_service_dual_sta_roam_support] = 22876 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 22877 wmi_service[wmi_service_peer_create_conf] = 22878 WMI_SERVICE_PEER_CREATE_CONF; 22879 wmi_service[wmi_service_configure_roam_trigger_param_support] = 22880 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 22881 wmi_service[wmi_service_5dot9_ghz_support] = 22882 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 22883 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 22884 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 22885 wmi_service[wmi_service_cfr_capture_count_support] = 22886 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 22887 wmi_service[wmi_service_ocv_support] = 22888 WMI_SERVICE_OCV_SUPPORT; 22889 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 22890 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 22891 wmi_service[wmi_service_thermal_multi_client_support] = 22892 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 22893 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 22894 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 22895 wmi_service[wmi_service_fse_cmem_alloc_support] = 22896 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 22897 wmi_service[wmi_service_scan_conf_per_ch_support] = 22898 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 22899 wmi_service[wmi_service_csa_beacon_template] = 22900 WMI_SERVICE_CSA_BEACON_TEMPLATE; 22901 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 22902 wmi_service[wmi_service_rtt_11az_ntb_support] = 22903 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 22904 wmi_service[wmi_service_rtt_11az_tb_support] = 22905 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 22906 wmi_service[wmi_service_rtt_11az_tb_rsta_support] = 22907 WMI_SERVICE_RTT_11AZ_TB_RSTA_SUPPORT; 22908 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 22909 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 22910 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 22911 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 22912 #endif 22913 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 22914 wmi_service[wmi_service_igmp_offload_support] = 22915 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 22916 #endif 22917 22918 #ifdef FEATURE_WLAN_TDLS 22919 #ifdef WLAN_FEATURE_11AX 22920 wmi_service[wmi_service_tdls_ax_support] = 22921 WMI_SERVICE_11AX_TDLS_SUPPORT; 22922 wmi_service[wmi_service_tdls_6g_support] = 22923 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 22924 #endif 22925 wmi_service[wmi_service_tdls_wideband_support] = 22926 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 22927 wmi_service[wmi_service_tdls_concurrency_support] = 22928 WMI_SERVICE_TDLS_CONCURRENCY_SUPPORT; 22929 #endif 22930 #ifdef FEATURE_WLAN_TDLS 22931 #ifdef WLAN_FEATURE_11BE 22932 wmi_service[wmi_service_tdls_mlo_support] = 22933 WMI_SERVICE_11BE_MLO_TDLS_SUPPORT; 22934 #endif 22935 #endif 22936 #ifdef WLAN_SUPPORT_TWT 22937 wmi_service[wmi_service_twt_bcast_req_support] = 22938 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 22939 wmi_service[wmi_service_twt_bcast_resp_support] = 22940 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 22941 wmi_service[wmi_service_twt_nudge] = 22942 WMI_SERVICE_TWT_NUDGE; 22943 wmi_service[wmi_service_all_twt] = 22944 WMI_SERVICE_TWT_ALL_DIALOG_ID; 22945 wmi_service[wmi_service_twt_statistics] = 22946 WMI_SERVICE_TWT_STATS; 22947 wmi_service[wmi_service_restricted_twt] = WMI_SERVICE_RESTRICTED_TWT; 22948 #endif 22949 wmi_service[wmi_service_spectral_scan_disabled] = 22950 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 22951 wmi_service[wmi_service_sae_eapol_offload_support] = 22952 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 22953 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 22954 22955 wmi_service[wmi_service_wapi_concurrency_supported] = 22956 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 22957 wmi_service[wmi_service_sap_connected_d3_wow] = 22958 WMI_SERVICE_SAP_CONNECTED_D3WOW; 22959 wmi_service[wmi_service_go_connected_d3_wow] = 22960 WMI_SERVICE_SAP_CONNECTED_D3WOW; 22961 wmi_service[wmi_service_ext_tpc_reg_support] = 22962 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 22963 wmi_service[wmi_service_eirp_preferred_support] = 22964 WMI_SERVICE_EIRP_PREFERRED_SUPPORT; 22965 wmi_service[wmi_service_ndi_txbf_support] = 22966 WMI_SERVICE_NDI_TXBF_SUPPORT; 22967 wmi_service[wmi_service_reg_cc_ext_event_support] = 22968 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 22969 wmi_service[wmi_service_bang_radar_320_support] = 22970 WMI_SERVICE_BANG_RADAR_320_SUPPORT; 22971 #if defined(CONFIG_BAND_6GHZ) 22972 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 22973 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 22974 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 22975 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 22976 #ifdef CONFIG_AFC_SUPPORT 22977 wmi_service[wmi_service_afc_support] = 22978 WMI_SERVICE_AFC_SUPPORT; 22979 #endif 22980 #endif 22981 wmi_service[wmi_service_dcs_awgn_int_support] = 22982 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 22983 wmi_populate_service_11be(wmi_service); 22984 22985 #ifdef WLAN_FEATURE_BIG_DATA_STATS 22986 wmi_service[wmi_service_big_data_support] = 22987 WMI_SERVICE_BIG_DATA_SUPPORT; 22988 #endif 22989 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 22990 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 22991 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 22992 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 22993 wmi_service[wmi_service_halphy_cal_status] = 22994 WMI_SERVICE_HALPHY_CAL_STATUS; 22995 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 22996 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 22997 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 22998 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 22999 wmi_service[wmi_service_ema_multiple_group_supported] = 23000 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 23001 wmi_service[wmi_service_large_beacon_supported] = 23002 WMI_SERVICE_LARGE_BEACON_SUPPORT; 23003 wmi_service[wmi_service_aoa_for_rcc_supported] = 23004 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 23005 #ifdef WLAN_FEATURE_P2P_P2P_STA 23006 wmi_service[wmi_service_p2p_p2p_cc_support] = 23007 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 23008 #endif 23009 #ifdef THERMAL_STATS_SUPPORT 23010 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 23011 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 23012 #endif 23013 wmi_service[wmi_service_hw_mode_policy_offload_support] = 23014 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 23015 wmi_service[wmi_service_mgmt_rx_reo_supported] = 23016 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 23017 wmi_service[wmi_service_phy_dma_byte_swap_support] = 23018 WMI_SERVICE_UNAVAILABLE; 23019 wmi_service[wmi_service_spectral_session_info_support] = 23020 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 23021 wmi_service[wmi_service_umac_hang_recovery_support] = 23022 WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; 23023 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 23024 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 23025 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 23026 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 23027 #endif 23028 wmi_service[wmi_service_probe_all_bw_support] = 23029 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 23030 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 23031 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 23032 #ifdef QCA_UNDECODED_METADATA_SUPPORT 23033 wmi_service[wmi_service_fp_phy_err_filter_support] = 23034 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 23035 #endif 23036 populate_tlv_service_mlo(wmi_service); 23037 wmi_service[wmi_service_pdev_rate_config_support] = 23038 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 23039 wmi_service[wmi_service_multi_peer_group_cmd_support] = 23040 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 23041 #ifdef WLAN_FEATURE_11BE 23042 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 23043 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 23044 #endif 23045 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 23046 wmi_service[wmi_service_combined_set_param_support] = 23047 WMI_SERVICE_COMBINED_SET_PARAM_SUPPORT; 23048 #endif 23049 wmi_service[wmi_service_pn_replay_check_support] = 23050 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 23051 #ifdef QCA_RSSI_DB2DBM 23052 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 23053 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 23054 #endif 23055 wmi_service[wmi_service_pktlog_decode_info_support] = 23056 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 23057 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 23058 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 23059 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 23060 #endif 23061 #ifdef MULTI_CLIENT_LL_SUPPORT 23062 wmi_service[wmi_service_configure_multi_client_ll_support] = 23063 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 23064 #endif 23065 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 23066 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 23067 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 23068 #endif 23069 wmi_service[wmi_service_linkspeed_roam_trigger_support] = 23070 WMI_SERVICE_LINKSPEED_ROAM_TRIGGER_SUPPORT; 23071 #ifdef FEATURE_SET 23072 wmi_service[wmi_service_feature_set_event_support] = 23073 WMI_SERVICE_FEATURE_SET_EVENT_SUPPORT; 23074 #endif 23075 #ifdef WLAN_FEATURE_SR 23076 wmi_service[wmi_service_obss_per_packet_sr_support] = 23077 WMI_SERVICE_OBSS_PER_PACKET_SR_SUPPORT; 23078 #endif 23079 wmi_service[wmi_service_wpa3_sha384_roam_support] = 23080 WMI_SERVICE_WMI_SERVICE_WPA3_SHA384_ROAM_SUPPORT; 23081 wmi_service[wmi_service_self_mld_roam_between_dbs_and_hbs] = 23082 WMI_SERVICE_SELF_MLD_ROAM_BETWEEN_DBS_AND_HBS; 23083 /* TODO: Assign FW Enum after FW Shared header changes are merged */ 23084 wmi_service[wmi_service_v1a_v1b_supported] = 23085 WMI_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT; 23086 #ifdef QCA_MANUAL_TRIGGERED_ULOFDMA 23087 wmi_service[wmi_service_manual_ulofdma_trigger_support] = 23088 WMI_SERVICE_MANUAL_ULOFDMA_TRIGGER_SUPPORT; 23089 #endif 23090 wmi_service[wmi_service_pre_rx_timeout] = 23091 WMI_SERVICE_PRE_RX_TO; 23092 #ifdef QCA_STANDALONE_SOUNDING_TRIGGER 23093 wmi_service[wmi_service_standalone_sound] = 23094 WMI_SERVICE_STANDALONE_SOUND; 23095 #endif 23096 wmi_service[wmi_service_cca_busy_info_for_each_20mhz] = 23097 WMI_SERVICE_CCA_BUSY_INFO_FOREACH_20MHZ; 23098 wmi_service[wmi_service_vdev_param_chwidth_with_notify_support] = 23099 WMI_SERVICE_VDEV_PARAM_CHWIDTH_WITH_NOTIFY_SUPPORT; 23100 #ifdef WLAN_FEATURE_11BE_MLO 23101 wmi_service[wmi_service_mlo_tsf_sync] = WMI_SERVICE_MLO_TSF_SYNC; 23102 wmi_service[wmi_service_n_link_mlo_support] = 23103 WMI_SERVICE_N_LINK_MLO_SUPPORT; 23104 wmi_service[wmi_service_per_link_stats_support] = 23105 WMI_SERVICE_PER_LINK_STATS_SUPPORT; 23106 wmi_service[wmi_service_pdev_wsi_stats_info_support] = 23107 WMI_SERVICE_PDEV_WSI_STATS_INFO_SUPPORT; 23108 wmi_service[wmi_service_mlo_tid_to_link_mapping_support] = 23109 WMI_SERVICE_MLO_TID_TO_LINK_MAPPING_SUPPORT; 23110 #endif 23111 wmi_service[wmi_service_aux_mac_support] = WMI_SERVICE_AUX_MAC_SUPPORT; 23112 #ifdef WLAN_ATF_INCREASED_STA 23113 wmi_service[wmi_service_atf_max_client_512_support] = 23114 WMI_SERVICE_ATF_MAX_CLIENT_512_SUPPORT; 23115 #endif 23116 wmi_service[wmi_service_fisa_dynamic_msdu_aggr_size_support] = 23117 WMI_SERVICE_FISA_DYNAMIC_MSDU_AGGR_SIZE_SUPPORT; 23118 wmi_service[wmi_service_radar_flags_support] = 23119 WMI_SERVICE_RADAR_FLAGS_SUPPORT; 23120 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 23121 wmi_service[wmi_service_5ghz_hi_rssi_roam_support] = 23122 WMI_SERVICE_5GHZ_HI_RSSI_ROAM_SUPPORT; 23123 #endif 23124 wmi_service[wmi_service_pdev_param_in_utf_wmi] = 23125 WMI_SERVICE_PDEV_PARAM_IN_UTF_WMI; 23126 #ifdef WLAN_FEATURE_LL_LT_SAP 23127 wmi_service[wmi_service_xpan_support] = WMI_SERVICE_XPAN_SUPPORT; 23128 #endif 23129 wmi_service[wmi_service_multiple_reorder_queue_setup_support] = 23130 WMI_SERVICE_MULTIPLE_REORDER_QUEUE_SETUP_SUPPORT; 23131 wmi_service[wmi_service_p2p_device_update_mac_addr_support] = 23132 WMI_SERVICE_P2P_DEVICE_UPDATE_MAC_ADDR_SUPPORT; 23133 } 23134 23135 /** 23136 * wmi_ocb_ut_attach() - Attach OCB test framework 23137 * @wmi_handle: wmi handle 23138 * 23139 * Return: None 23140 */ 23141 #ifdef WLAN_OCB_UT 23142 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 23143 #else 23144 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 23145 { 23146 return; 23147 } 23148 #endif 23149 23150 /** 23151 * wmi_tlv_attach() - Attach TLV APIs 23152 * @wmi_handle: wmi handle 23153 * Return: None 23154 */ 23155 void wmi_tlv_attach(wmi_unified_t wmi_handle) 23156 { 23157 wmi_handle->ops = &tlv_ops; 23158 wmi_ocb_ut_attach(wmi_handle); 23159 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 23160 #ifdef WMI_INTERFACE_EVENT_LOGGING 23161 /* Skip saving WMI_CMD_HDR and TLV HDR */ 23162 wmi_handle->soc->buf_offset_command = 8; 23163 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 23164 wmi_handle->soc->buf_offset_event = 4; 23165 #endif 23166 populate_tlv_events_id(wmi_handle->wmi_events); 23167 populate_tlv_service(wmi_handle->services); 23168 wmi_wds_attach_tlv(wmi_handle); 23169 wmi_twt_attach_tlv(wmi_handle); 23170 wmi_extscan_attach_tlv(wmi_handle); 23171 wmi_smart_ant_attach_tlv(wmi_handle); 23172 wmi_dbr_attach_tlv(wmi_handle); 23173 wmi_atf_attach_tlv(wmi_handle); 23174 wmi_ap_attach_tlv(wmi_handle); 23175 wmi_bcn_attach_tlv(wmi_handle); 23176 wmi_ocb_attach_tlv(wmi_handle); 23177 wmi_nan_attach_tlv(wmi_handle); 23178 wmi_p2p_attach_tlv(wmi_handle); 23179 wmi_interop_issues_ap_attach_tlv(wmi_handle); 23180 wmi_dcs_attach_tlv(wmi_handle); 23181 wmi_roam_attach_tlv(wmi_handle); 23182 wmi_concurrency_attach_tlv(wmi_handle); 23183 wmi_pmo_attach_tlv(wmi_handle); 23184 wmi_sta_attach_tlv(wmi_handle); 23185 wmi_11ax_bss_color_attach_tlv(wmi_handle); 23186 wmi_fwol_attach_tlv(wmi_handle); 23187 wmi_vdev_attach_tlv(wmi_handle); 23188 wmi_cfr_attach_tlv(wmi_handle); 23189 wmi_cp_stats_attach_tlv(wmi_handle); 23190 wmi_gpio_attach_tlv(wmi_handle); 23191 wmi_11be_attach_tlv(wmi_handle); 23192 wmi_coap_attach_tlv(wmi_handle); 23193 wmi_mlme_attach_tlv(wmi_handle); 23194 } 23195 qdf_export_symbol(wmi_tlv_attach); 23196 23197 /** 23198 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 23199 * 23200 * Return: None 23201 */ 23202 void wmi_tlv_init(void) 23203 { 23204 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 23205 } 23206