1 /* 2 * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "wmi_unified_api.h" 20 #include "wmi.h" 21 #include "wmi_version.h" 22 #include "wmi_unified_priv.h" 23 #include "wmi_version_whitelist.h" 24 #include <qdf_module.h> 25 #include <wlan_defs.h> 26 #include <wlan_cmn.h> 27 #include <htc_services.h> 28 #ifdef FEATURE_WLAN_APF 29 #include "wmi_unified_apf_tlv.h" 30 #endif 31 #ifdef WLAN_FEATURE_ACTION_OUI 32 #include "wmi_unified_action_oui_tlv.h" 33 #endif 34 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 35 #include "wlan_pmo_hw_filter_public_struct.h" 36 #endif 37 #include <wlan_utility.h> 38 #ifdef WLAN_SUPPORT_GREEN_AP 39 #include "wlan_green_ap_api.h" 40 #endif 41 42 #include "wmi_unified_twt_api.h" 43 44 #ifdef WLAN_POLICY_MGR_ENABLE 45 #include "wlan_policy_mgr_public_struct.h" 46 #endif 47 48 #ifdef WMI_SMART_ANT_SUPPORT 49 #include "wmi_unified_smart_ant_api.h" 50 #endif 51 52 #ifdef WMI_DBR_SUPPORT 53 #include "wmi_unified_dbr_api.h" 54 #endif 55 56 #ifdef WMI_ATF_SUPPORT 57 #include "wmi_unified_atf_api.h" 58 #endif 59 60 #ifdef WMI_AP_SUPPORT 61 #include "wmi_unified_ap_api.h" 62 #endif 63 64 #include <wmi_unified_vdev_api.h> 65 #include <wmi_unified_vdev_tlv.h> 66 67 /* 68 * If FW supports WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 69 * then channel_list may fill the upper 12 bits with channel flags, 70 * while using only the lower 20 bits for channel frequency. 71 * If FW doesn't support WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 72 * then channel_list only holds the frequency value. 73 */ 74 #define CHAN_LIST_FLAG_MASK_POS 20 75 #define TARGET_SET_FREQ_IN_CHAN_LIST_TLV(buf, freq) \ 76 ((buf) |= ((freq) & WMI_SCAN_CHANNEL_FREQ_MASK)) 77 #define TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(buf, flags) \ 78 ((buf) |= ((flags) << CHAN_LIST_FLAG_MASK_POS)) 79 80 /* HTC service ids for WMI for multi-radio */ 81 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 82 WMI_CONTROL_SVC_WMAC1, 83 WMI_CONTROL_SVC_WMAC2}; 84 85 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 86 /*Populate peer_param array whose index as host id and 87 *value as target id 88 */ 89 static const uint32_t peer_param_tlv[] = { 90 [WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE, 91 [WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU, 92 [WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE, 93 [WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH, 94 [WMI_HOST_PEER_NSS] = WMI_PEER_NSS, 95 [WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR, 96 [WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP, 97 [WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS, 98 [WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] = 99 WMI_PEER_CRIT_PROTO_HINT_ENABLED, 100 [WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR, 101 [WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S, 102 [WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] = 103 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, 104 [WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE, 105 [WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR, 106 [WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE, 107 [WMI_HOST_PEER_SET_MU_WHITELIST] = WMI_PEER_SET_MU_WHITELIST, 108 [WMI_HOST_PEER_SET_MAC_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE, 109 [WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE, 110 [WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING, 111 [WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160, 112 [WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80, 113 [WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] = 114 WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL, 115 [WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] = 116 WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL, 117 [WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] = 118 WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE, 119 [WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE, 120 [WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE, 121 [WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT, 122 }; 123 124 /** 125 * Populate pdev_param_value whose index is host param and value is target 126 * param 127 */ 128 static const uint32_t pdev_param_tlv[] = { 129 [wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 130 [wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK, 131 [wmi_pdev_param_txpower_limit2g] = WMI_PDEV_PARAM_TXPOWER_LIMIT2G, 132 [wmi_pdev_param_txpower_limit5g] = WMI_PDEV_PARAM_TXPOWER_LIMIT5G, 133 [wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE, 134 [wmi_pdev_param_beacon_gen_mode] = WMI_PDEV_PARAM_BEACON_GEN_MODE, 135 [wmi_pdev_param_beacon_tx_mode] = WMI_PDEV_PARAM_BEACON_TX_MODE, 136 [wmi_pdev_param_resmgr_offchan_mode] = 137 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 138 [wmi_pdev_param_protection_mode] = WMI_PDEV_PARAM_PROTECTION_MODE, 139 [wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW, 140 [wmi_pdev_param_non_agg_sw_retry_th] = 141 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 142 [wmi_pdev_param_agg_sw_retry_th] = WMI_PDEV_PARAM_AGG_SW_RETRY_TH, 143 [wmi_pdev_param_sta_kickout_th] = WMI_PDEV_PARAM_STA_KICKOUT_TH, 144 [wmi_pdev_param_ac_aggrsize_scaling] = 145 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, 146 [wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE, 147 [wmi_pdev_param_ltr_ac_latency_be] = 148 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, 149 [wmi_pdev_param_ltr_ac_latency_bk] = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, 150 [wmi_pdev_param_ltr_ac_latency_vi] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, 151 [wmi_pdev_param_ltr_ac_latency_vo] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, 152 [wmi_pdev_param_ltr_ac_latency_timeout] = 153 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 154 [wmi_pdev_param_ltr_sleep_override] = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 155 [wmi_pdev_param_ltr_rx_override] = WMI_PDEV_PARAM_LTR_RX_OVERRIDE, 156 [wmi_pdev_param_ltr_tx_activity_timeout] = 157 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 158 [wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE, 159 [wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE, 160 [wmi_pdev_param_pcielp_txbuf_flush] = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, 161 [wmi_pdev_param_pcielp_txbuf_watermark] = 162 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK, 163 [wmi_pdev_param_pcielp_txbuf_tmo_en] = 164 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 165 [wmi_pdev_param_pcielp_txbuf_tmo_value] = 166 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, 167 [wmi_pdev_param_pdev_stats_update_period] = 168 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 169 [wmi_pdev_param_vdev_stats_update_period] = 170 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 171 [wmi_pdev_param_peer_stats_update_period] = 172 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 173 [wmi_pdev_param_bcnflt_stats_update_period] = 174 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 175 [wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS, 176 [wmi_pdev_param_arp_ac_override] = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 177 [wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS, 178 [wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE, 179 [wmi_pdev_param_ani_poll_period] = WMI_PDEV_PARAM_ANI_POLL_PERIOD, 180 [wmi_pdev_param_ani_listen_period] = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, 181 [wmi_pdev_param_ani_ofdm_level] = WMI_PDEV_PARAM_ANI_OFDM_LEVEL, 182 [wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL, 183 [wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN, 184 [wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA, 185 [wmi_pdev_param_idle_ps_config] = WMI_PDEV_PARAM_IDLE_PS_CONFIG, 186 [wmi_pdev_param_power_gating_sleep] = WMI_PDEV_PARAM_POWER_GATING_SLEEP, 187 [wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE, 188 [wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR, 189 [wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE, 190 [wmi_pdev_param_hw_rfkill_config] = WMI_PDEV_PARAM_HW_RFKILL_CONFIG, 191 [wmi_pdev_param_low_power_rf_enable] = 192 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE, 193 [wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK, 194 [wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN, 195 [wmi_pdev_param_power_collapse_enable] = 196 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE, 197 [wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE, 198 [wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE, 199 [wmi_pdev_param_audio_over_wlan_latency] = 200 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY, 201 [wmi_pdev_param_audio_over_wlan_enable] = 202 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE, 203 [wmi_pdev_param_whal_mib_stats_update_enable] = 204 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE, 205 [wmi_pdev_param_vdev_rate_stats_update_period] = 206 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD, 207 [wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW, 208 [wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG, 209 [wmi_pdev_param_adaptive_early_rx_enable] = 210 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE, 211 [wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 212 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP, 213 [wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 214 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP, 215 [wmi_pdev_param_early_rx_fix_sleep_slop] = 216 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP, 217 [wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 218 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE, 219 [wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 220 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT, 221 [wmi_pdev_param_bmiss_bto_inc_dec_step] = 222 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP, 223 [wmi_pdev_param_bto_fix_bcn_timeout] = 224 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT, 225 [wmi_pdev_param_ce_based_adaptive_bto_enable] = 226 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE, 227 [wmi_pdev_param_ce_bto_combo_ce_value] = 228 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE, 229 [wmi_pdev_param_tx_chain_mask_2g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_2G, 230 [wmi_pdev_param_rx_chain_mask_2g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_2G, 231 [wmi_pdev_param_tx_chain_mask_5g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_5G, 232 [wmi_pdev_param_rx_chain_mask_5g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_5G, 233 [wmi_pdev_param_tx_chain_mask_cck] = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK, 234 [wmi_pdev_param_tx_chain_mask_1ss] = WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, 235 [wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER, 236 [wmi_pdev_set_mcast_to_ucast_tid] = WMI_PDEV_SET_MCAST_TO_UCAST_TID, 237 [wmi_pdev_param_mgmt_retry_limit] = WMI_PDEV_PARAM_MGMT_RETRY_LIMIT, 238 [wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST, 239 [wmi_pdev_peer_sta_ps_statechg_enable] = 240 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE, 241 [wmi_pdev_param_proxy_sta_mode] = WMI_PDEV_PARAM_PROXY_STA_MODE, 242 [wmi_pdev_param_mu_group_policy] = WMI_PDEV_PARAM_MU_GROUP_POLICY, 243 [wmi_pdev_param_noise_detection] = WMI_PDEV_PARAM_NOISE_DETECTION, 244 [wmi_pdev_param_noise_threshold] = WMI_PDEV_PARAM_NOISE_THRESHOLD, 245 [wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE, 246 [wmi_pdev_param_set_mcast_bcast_echo] = 247 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO, 248 [wmi_pdev_param_atf_strict_sch] = WMI_PDEV_PARAM_ATF_STRICT_SCH, 249 [wmi_pdev_param_atf_sched_duration] = WMI_PDEV_PARAM_ATF_SCHED_DURATION, 250 [wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN, 251 [wmi_pdev_param_sensitivity_level] = WMI_PDEV_PARAM_SENSITIVITY_LEVEL, 252 [wmi_pdev_param_signed_txpower_2g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_2G, 253 [wmi_pdev_param_signed_txpower_5g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_5G, 254 [wmi_pdev_param_enable_per_tid_amsdu] = 255 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU, 256 [wmi_pdev_param_enable_per_tid_ampdu] = 257 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU, 258 [wmi_pdev_param_cca_threshold] = WMI_PDEV_PARAM_CCA_THRESHOLD, 259 [wmi_pdev_param_rts_fixed_rate] = WMI_PDEV_PARAM_RTS_FIXED_RATE, 260 [wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM, 261 [wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET, 262 [wmi_pdev_param_wapi_mbssid_offset] = WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET, 263 [wmi_pdev_param_arp_srcaddr] = WMI_PDEV_PARAM_ARP_DBG_SRCADDR, 264 [wmi_pdev_param_arp_dstaddr] = WMI_PDEV_PARAM_ARP_DBG_DSTADDR, 265 [wmi_pdev_param_txpower_decr_db] = WMI_PDEV_PARAM_TXPOWER_DECR_DB, 266 [wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM, 267 [wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM, 268 [wmi_pdev_param_atf_obss_noise_sch] = 269 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH, 270 [wmi_pdev_param_atf_obss_noise_scaling_factor] = 271 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR, 272 [wmi_pdev_param_cust_txpower_scale] = WMI_PDEV_PARAM_CUST_TXPOWER_SCALE, 273 [wmi_pdev_param_atf_dynamic_enable] = WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE, 274 [wmi_pdev_param_atf_ssid_group_policy] = WMI_UNAVAILABLE_PARAM, 275 [wmi_pdev_param_igmpmld_override] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 276 [wmi_pdev_param_igmpmld_tid] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 277 [wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN, 278 [wmi_pdev_param_block_interbss] = WMI_PDEV_PARAM_BLOCK_INTERBSS, 279 [wmi_pdev_param_set_disable_reset_cmdid] = 280 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID, 281 [wmi_pdev_param_set_msdu_ttl_cmdid] = WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID, 282 [wmi_pdev_param_txbf_sound_period_cmdid] = 283 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID, 284 [wmi_pdev_param_set_burst_mode_cmdid] = 285 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID, 286 [wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS, 287 [wmi_pdev_param_mesh_mcast_enable] = WMI_PDEV_PARAM_MESH_MCAST_ENABLE, 288 [wmi_pdev_param_set_promisc_mode_cmdid] = 289 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID, 290 [wmi_pdev_param_set_ppdu_duration_cmdid] = 291 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID, 292 [wmi_pdev_param_remove_mcast2ucast_buffer] = 293 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, 294 [wmi_pdev_param_set_mcast2ucast_buffer] = 295 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, 296 [wmi_pdev_param_set_mcast2ucast_mode] = 297 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE, 298 [wmi_pdev_param_smart_antenna_default_antenna] = 299 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA, 300 [wmi_pdev_param_fast_channel_reset] = 301 WMI_PDEV_PARAM_FAST_CHANNEL_RESET, 302 [wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE, 303 [wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT, 304 [wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE, 305 [wmi_pdev_param_antenna_gain_half_db] = 306 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB, 307 [wmi_pdev_param_esp_indication_period] = 308 WMI_PDEV_PARAM_ESP_INDICATION_PERIOD, 309 [wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW, 310 [wmi_pdev_param_esp_airtime_fraction] = 311 WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION, 312 [wmi_pdev_param_esp_ppdu_duration] = WMI_PDEV_PARAM_ESP_PPDU_DURATION, 313 [wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_UL_RU26_ALLOWED, 314 [wmi_pdev_param_use_nol] = WMI_PDEV_PARAM_USE_NOL, 315 /* Trigger interval for all trigger types. */ 316 [wmi_pdev_param_ul_trig_int] = WMI_PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL, 317 [wmi_pdev_param_sub_channel_marking] = 318 WMI_PDEV_PARAM_SUB_CHANNEL_MARKING, 319 [wmi_pdev_param_ul_ppdu_duration] = WMI_PDEV_PARAM_SET_UL_PPDU_DURATION, 320 [wmi_pdev_param_equal_ru_allocation_enable] = 321 WMI_PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE, 322 [wmi_pdev_param_per_peer_prd_cfr_enable] = 323 WMI_PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE, 324 [wmi_pdev_param_nav_override_config] = 325 WMI_PDEV_PARAM_NAV_OVERRIDE_CONFIG, 326 [wmi_pdev_param_set_mgmt_ttl] = WMI_PDEV_PARAM_SET_MGMT_TTL, 327 [wmi_pdev_param_set_prb_rsp_ttl] = 328 WMI_PDEV_PARAM_SET_PROBE_RESP_TTL, 329 [wmi_pdev_param_set_mu_ppdu_duration] = 330 WMI_PDEV_PARAM_SET_MU_PPDU_DURATION, 331 [wmi_pdev_param_set_tbtt_ctrl] = 332 WMI_PDEV_PARAM_SET_TBTT_CTRL, 333 [wmi_pdev_param_set_cmd_obss_pd_threshold] = 334 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 335 [wmi_pdev_param_set_cmd_obss_pd_per_ac] = 336 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 337 [wmi_pdev_param_set_cong_ctrl_max_msdus] = 338 WMI_PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS, 339 [wmi_pdev_param_enable_fw_dynamic_he_edca] = 340 WMI_PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA, 341 [wmi_pdev_param_enable_srp] = WMI_PDEV_PARAM_ENABLE_SRP, 342 [wmi_pdev_param_enable_sr_prohibit] = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT, 343 [wmi_pdev_param_sr_trigger_margin] = WMI_PDEV_PARAM_SR_TRIGGER_MARGIN, 344 [wmi_pdev_param_pream_punct_bw] = WMI_PDEV_PARAM_SET_PREAM_PUNCT_BW, 345 [wmi_pdev_param_enable_mbssid_ctrl_frame] = WMI_PDEV_PARAM_ENABLE_MBSSID_CTRL_FRAME, 346 }; 347 348 /** 349 * Populate vdev_param_value_tlv array whose index is host param 350 * and value is target param 351 */ 352 static const uint32_t vdev_param_tlv[] = { 353 [wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD, 354 [wmi_vdev_param_fragmentation_threshold] = 355 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 356 [wmi_vdev_param_beacon_interval] = WMI_VDEV_PARAM_BEACON_INTERVAL, 357 [wmi_vdev_param_listen_interval] = WMI_VDEV_PARAM_LISTEN_INTERVAL, 358 [wmi_vdev_param_multicast_rate] = WMI_VDEV_PARAM_MULTICAST_RATE, 359 [wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE, 360 [wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME, 361 [wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE, 362 [wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME, 363 [wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD, 364 [wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME, 365 [wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL, 366 [wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD, 367 [wmi_vdev_oc_scheduler_air_time_limit] = 368 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 369 [wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS, 370 [wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW, 371 [wmi_vdev_param_bmiss_count_max] = WMI_VDEV_PARAM_BMISS_COUNT_MAX, 372 [wmi_vdev_param_bmiss_first_bcnt] = WMI_VDEV_PARAM_BMISS_FIRST_BCNT, 373 [wmi_vdev_param_bmiss_final_bcnt] = WMI_VDEV_PARAM_BMISS_FINAL_BCNT, 374 [wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM, 375 [wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH, 376 [wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET, 377 [wmi_vdev_param_disable_htprotection] = 378 WMI_VDEV_PARAM_DISABLE_HTPROTECTION, 379 [wmi_vdev_param_sta_quickkickout] = WMI_VDEV_PARAM_STA_QUICKKICKOUT, 380 [wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE, 381 [wmi_vdev_param_protection_mode] = WMI_VDEV_PARAM_PROTECTION_MODE, 382 [wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE, 383 [wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI, 384 [wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC, 385 [wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC, 386 [wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC, 387 [wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD, 388 [wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID, 389 [wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS, 390 [wmi_vdev_param_bcast_data_rate] = WMI_VDEV_PARAM_BCAST_DATA_RATE, 391 [wmi_vdev_param_mcast_data_rate] = WMI_VDEV_PARAM_MCAST_DATA_RATE, 392 [wmi_vdev_param_mcast_indicate] = WMI_VDEV_PARAM_MCAST_INDICATE, 393 [wmi_vdev_param_dhcp_indicate] = WMI_VDEV_PARAM_DHCP_INDICATE, 394 [wmi_vdev_param_unknown_dest_indicate] = 395 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 396 [wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 397 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 398 [wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 399 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 400 [wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 401 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 402 [wmi_vdev_param_ap_enable_nawds] = WMI_VDEV_PARAM_AP_ENABLE_NAWDS, 403 [wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS, 404 [wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF, 405 [wmi_vdev_param_packet_powersave] = WMI_VDEV_PARAM_PACKET_POWERSAVE, 406 [wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY, 407 [wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE, 408 [wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 409 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, 410 [wmi_vdev_param_early_rx_adjust_enable] = 411 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE, 412 [wmi_vdev_param_early_rx_tgt_bmiss_num] = 413 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM, 414 [wmi_vdev_param_early_rx_bmiss_sample_cycle] = 415 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE, 416 [wmi_vdev_param_early_rx_slop_step] = WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP, 417 [wmi_vdev_param_early_rx_init_slop] = WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP, 418 [wmi_vdev_param_early_rx_adjust_pause] = 419 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE, 420 [wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT, 421 [wmi_vdev_param_snr_num_for_cal] = WMI_VDEV_PARAM_SNR_NUM_FOR_CAL, 422 [wmi_vdev_param_roam_fw_offload] = WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 423 [wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC, 424 [wmi_vdev_param_ibss_max_bcn_lost_ms] = 425 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, 426 [wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE, 427 [wmi_vdev_param_early_rx_drift_sample] = 428 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE, 429 [wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 430 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR, 431 [wmi_vdev_param_ebt_resync_timeout] = 432 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT, 433 [wmi_vdev_param_aggr_trig_event_enable] = 434 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE, 435 [wmi_vdev_param_is_ibss_power_save_allowed] = 436 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED, 437 [wmi_vdev_param_is_power_collapse_allowed] = 438 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED, 439 [wmi_vdev_param_is_awake_on_txrx_enabled] = 440 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED, 441 [wmi_vdev_param_inactivity_cnt] = WMI_VDEV_PARAM_INACTIVITY_CNT, 442 [wmi_vdev_param_txsp_end_inactivity_time_ms] = 443 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS, 444 [wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY, 445 [wmi_vdev_param_ibss_ps_warmup_time_secs] = 446 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS, 447 [wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 448 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE, 449 [wmi_vdev_param_rx_leak_window] = WMI_VDEV_PARAM_RX_LEAK_WINDOW, 450 [wmi_vdev_param_stats_avg_factor] = 451 WMI_VDEV_PARAM_STATS_AVG_FACTOR, 452 [wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH, 453 [wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE, 454 [wmi_vdev_param_mcc_rtscts_protection_enable] = 455 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE, 456 [wmi_vdev_param_mcc_broadcast_probe_enable] = 457 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE, 458 [wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER, 459 [wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE, 460 [wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE, 461 [wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM, 462 [wmi_vdev_param_he_range_ext_enable] = WMI_VDEV_PARAM_HE_RANGE_EXT, 463 [wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR, 464 [wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE, 465 [wmi_vdev_param_set_he_sounding_mode] = 466 WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE, 467 [wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31, 468 [wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP, 469 [wmi_vdev_param_dtim_enable_cts] = WMI_VDEV_PARAM_DTIM_ENABLE_CTS, 470 [wmi_vdev_param_atf_ssid_sched_policy] = 471 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY, 472 [wmi_vdev_param_disable_dyn_bw_rts] = WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS, 473 [wmi_vdev_param_mcast2ucast_set] = WMI_VDEV_PARAM_MCAST2UCAST_SET, 474 [wmi_vdev_param_rc_num_retries] = WMI_VDEV_PARAM_RC_NUM_RETRIES, 475 [wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR, 476 [wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET, 477 [wmi_vdev_param_rts_fixed_rate] = WMI_VDEV_PARAM_RTS_FIXED_RATE, 478 [wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK, 479 [wmi_vdev_param_vht80_ratemask] = WMI_VDEV_PARAM_VHT80_RATEMASK, 480 [wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA, 481 [wmi_vdev_param_bw_nss_ratemask] = WMI_VDEV_PARAM_BW_NSS_RATEMASK, 482 [wmi_vdev_param_set_he_ltf] = WMI_VDEV_PARAM_HE_LTF, 483 [wmi_vdev_param_disable_cabq] = WMI_VDEV_PARAM_DISABLE_CABQ, 484 [wmi_vdev_param_rate_dropdown_bmap] = WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP, 485 [wmi_vdev_param_set_ba_mode] = WMI_VDEV_PARAM_BA_MODE, 486 [wmi_vdev_param_capabilities] = WMI_VDEV_PARAM_CAPABILITIES, 487 [wmi_vdev_param_autorate_misc_cfg] = WMI_VDEV_PARAM_AUTORATE_MISC_CFG, 488 [wmi_vdev_param_ul_shortgi] = WMI_VDEV_PARAM_UL_GI, 489 [wmi_vdev_param_ul_he_ltf] = WMI_VDEV_PARAM_UL_HE_LTF, 490 [wmi_vdev_param_ul_nss] = WMI_VDEV_PARAM_UL_NSS, 491 [wmi_vdev_param_ul_ppdu_bw] = WMI_VDEV_PARAM_UL_PPDU_BW, 492 [wmi_vdev_param_ul_ldpc] = WMI_VDEV_PARAM_UL_LDPC, 493 [wmi_vdev_param_ul_stbc] = WMI_VDEV_PARAM_UL_STBC, 494 [wmi_vdev_param_ul_fixed_rate] = WMI_VDEV_PARAM_UL_FIXED_RATE, 495 [wmi_vdev_param_rawmode_open_war] = WMI_VDEV_PARAM_RAW_IS_ENCRYPTED, 496 [wmi_vdev_param_max_mtu_size] = WMI_VDEV_PARAM_MAX_MTU_SIZE, 497 [wmi_vdev_param_mcast_rc_stale_period] = 498 WMI_VDEV_PARAM_MCAST_RC_STALE_PERIOD, 499 [wmi_vdev_param_enable_multi_group_key] = 500 WMI_VDEV_PARAM_ENABLE_MULTI_GROUP_KEY, 501 [wmi_vdev_param_max_group_keys] = WMI_VDEV_PARAM_NUM_GROUP_KEYS, 502 [wmi_vdev_param_enable_mcast_rc] = WMI_VDEV_PARAM_ENABLE_MCAST_RC, 503 [wmi_vdev_param_6ghz_params] = WMI_VDEV_PARAM_6GHZ_PARAMS, 504 [wmi_vdev_param_enable_disable_roam_reason_vsie] = 505 WMI_VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE, 506 [wmi_vdev_param_set_cmd_obss_pd_threshold] = 507 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 508 [wmi_vdev_param_set_cmd_obss_pd_per_ac] = 509 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 510 [wmi_vdev_param_enable_srp] = WMI_VDEV_PARAM_ENABLE_SRP, 511 [wmi_vdev_param_nan_config_features] = 512 WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES, 513 }; 514 #endif 515 516 /** 517 * Populate the pktlog event tlv array, where 518 * the values are the FW WMI events, which host 519 * uses to communicate with FW for pktlog 520 */ 521 522 static const uint32_t pktlog_event_tlv[] = { 523 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 524 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 525 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 526 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 527 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 528 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 529 WMI_PKTLOG_EVENT_SMART_ANTENNA, 530 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 531 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 532 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 533 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 534 }; 535 536 /** 537 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 538 * host to target defines. 539 * @wmi_handle: pointer to wmi_handle 540 * @param pdev_id: host pdev_id to be converted. 541 * Return: target pdev_id after conversion. 542 */ 543 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 544 uint32_t pdev_id) 545 { 546 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 547 if (!wmi_handle->soc->is_pdev_is_map_enable) { 548 switch (pdev_id) { 549 case WMI_HOST_PDEV_ID_0: 550 return WMI_PDEV_ID_1ST; 551 case WMI_HOST_PDEV_ID_1: 552 return WMI_PDEV_ID_2ND; 553 case WMI_HOST_PDEV_ID_2: 554 return WMI_PDEV_ID_3RD; 555 } 556 } else { 557 return wmi_handle->cmd_pdev_id_map[pdev_id]; 558 } 559 } else { 560 return WMI_PDEV_ID_SOC; 561 } 562 563 QDF_ASSERT(0); 564 565 return WMI_PDEV_ID_SOC; 566 } 567 568 /** 569 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 570 * target to host defines. 571 * @wmi_handle: pointer to wmi_handle 572 * @param pdev_id: target pdev_id to be converted. 573 * Return: host pdev_id after conversion. 574 */ 575 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 576 uint32_t pdev_id) 577 { 578 579 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 580 if (!wmi_handle->soc->is_pdev_is_map_enable) { 581 switch (pdev_id) { 582 case WMI_PDEV_ID_1ST: 583 return WMI_HOST_PDEV_ID_0; 584 case WMI_PDEV_ID_2ND: 585 return WMI_HOST_PDEV_ID_1; 586 case WMI_PDEV_ID_3RD: 587 return WMI_HOST_PDEV_ID_2; 588 } 589 } else { 590 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 591 } 592 } else if (pdev_id == WMI_PDEV_ID_SOC) { 593 return WMI_HOST_PDEV_ID_SOC; 594 } else { 595 wmi_err("Invalid pdev_id"); 596 } 597 598 return WMI_HOST_PDEV_ID_INVALID; 599 } 600 601 /** 602 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 603 * host to target defines. 604 * @wmi_handle: pointer to wmi_handle 605 * @param phy_id: host pdev_id to be converted. 606 * Return: target phy_id after conversion. 607 */ 608 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 609 uint32_t phy_id) 610 { 611 if (!wmi_handle->soc->is_phy_id_map_enable || 612 phy_id >= WMI_MAX_RADIOS) { 613 return phy_id; 614 } 615 616 return wmi_handle->cmd_phy_id_map[phy_id]; 617 } 618 619 /** 620 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 621 * target to host defines. 622 * @wmi_handle: pointer to wmi_handle 623 * @param phy_id: target phy_id to be converted. 624 * Return: host phy_id after conversion. 625 */ 626 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 627 uint32_t phy_id) 628 { 629 if (!wmi_handle->soc->is_phy_id_map_enable || 630 phy_id >= WMI_MAX_RADIOS) { 631 return phy_id; 632 } 633 634 return wmi_handle->evt_phy_id_map[phy_id]; 635 } 636 637 /** 638 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 639 * 640 * Return None. 641 */ 642 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 643 uint32_t *pdev_id_map, 644 uint8_t size) 645 { 646 int i = 0; 647 648 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 649 for (i = 0; i < size; i++) { 650 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 651 wmi_handle->evt_pdev_id_map[i] = 652 WMI_HOST_PDEV_ID_INVALID; 653 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 654 wmi_handle->evt_phy_id_map[i] = 655 WMI_HOST_PDEV_ID_INVALID; 656 } 657 658 for (i = 0; i < size; i++) { 659 if (wmi_handle->cmd_pdev_id_map[i] != 660 WMI_HOST_PDEV_ID_INVALID) { 661 wmi_handle->evt_pdev_id_map 662 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 663 } 664 if (wmi_handle->cmd_phy_id_map[i] != 665 WMI_HOST_PDEV_ID_INVALID) { 666 wmi_handle->evt_phy_id_map 667 [wmi_handle->cmd_phy_id_map[i]] = i; 668 } 669 } 670 wmi_handle->soc->is_pdev_is_map_enable = true; 671 wmi_handle->soc->is_phy_id_map_enable = true; 672 } else { 673 wmi_handle->soc->is_pdev_is_map_enable = false; 674 wmi_handle->soc->is_phy_id_map_enable = false; 675 } 676 677 wmi_handle->ops->convert_pdev_id_host_to_target = 678 convert_host_pdev_id_to_target_pdev_id; 679 wmi_handle->ops->convert_pdev_id_target_to_host = 680 convert_target_pdev_id_to_host_pdev_id; 681 682 /* phy_id convert function assignments */ 683 wmi_handle->ops->convert_phy_id_host_to_target = 684 convert_host_phy_id_to_target_phy_id; 685 wmi_handle->ops->convert_phy_id_target_to_host = 686 convert_target_phy_id_to_host_phy_id; 687 } 688 689 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 690 * buffer. 691 * @wmi_handle: pointer to wmi_handle 692 * @cmd: pointer target vdev create command buffer 693 * @param: pointer host params for vdev create 694 * 695 * Return: None 696 */ 697 static inline void copy_vdev_create_pdev_id( 698 struct wmi_unified *wmi_handle, 699 wmi_vdev_create_cmd_fixed_param * cmd, 700 struct vdev_create_params *param) 701 { 702 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 703 wmi_handle, 704 param->pdev_id); 705 } 706 707 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 708 { 709 uint16_t mtrace_message_id; 710 711 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 712 (QDF_WMI_MTRACE_GRP_ID(message_id) << 713 QDF_WMI_MTRACE_CMD_NUM_BITS); 714 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 715 mtrace_message_id, vdev_id, data); 716 } 717 qdf_export_symbol(wmi_mtrace); 718 719 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 720 wmi_buf_t buf, 721 uint32_t buflen, uint32_t cmd_id) 722 { 723 if (!wmi_is_qmi_stats_enabled(wmi_handle)) 724 goto send_over_wmi; 725 726 if (wmi_is_target_suspended(wmi_handle)) { 727 if (QDF_IS_STATUS_SUCCESS( 728 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 729 buflen, cmd_id))) 730 return QDF_STATUS_SUCCESS; 731 } 732 733 send_over_wmi: 734 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 735 736 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 737 } 738 739 /** 740 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 741 * @wmi_handle: wmi handle 742 * @param: pointer to hold vdev create parameter 743 * @macaddr: vdev mac address 744 * 745 * Return: QDF_STATUS_SUCCESS for success or error code 746 */ 747 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 748 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 749 struct vdev_create_params *param) 750 { 751 wmi_vdev_create_cmd_fixed_param *cmd; 752 wmi_buf_t buf; 753 int32_t len = sizeof(*cmd); 754 QDF_STATUS ret; 755 int num_bands = 2; 756 uint8_t *buf_ptr; 757 wmi_vdev_txrx_streams *txrx_streams; 758 759 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 760 buf = wmi_buf_alloc(wmi_handle, len); 761 if (!buf) 762 return QDF_STATUS_E_NOMEM; 763 764 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 765 WMITLV_SET_HDR(&cmd->tlv_header, 766 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 767 WMITLV_GET_STRUCT_TLVLEN 768 (wmi_vdev_create_cmd_fixed_param)); 769 cmd->vdev_id = param->vdev_id; 770 cmd->vdev_type = param->type; 771 cmd->vdev_subtype = param->subtype; 772 cmd->flags = param->mbssid_flags; 773 cmd->flags |= (param->special_vdev_mode ? VDEV_FLAGS_SCAN_MODE_VAP : 0); 774 cmd->vdevid_trans = param->vdevid_trans; 775 cmd->num_cfg_txrx_streams = num_bands; 776 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 777 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 778 wmi_debug("ID = %d[pdev:%d] VAP Addr = "QDF_MAC_ADDR_FMT, 779 param->vdev_id, cmd->pdev_id, 780 QDF_MAC_ADDR_REF(macaddr)); 781 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 782 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 783 (num_bands * sizeof(wmi_vdev_txrx_streams))); 784 buf_ptr += WMI_TLV_HDR_SIZE; 785 786 wmi_debug("type %d, subtype %d, nss_2g %d, nss_5g %d", 787 param->type, param->subtype, 788 param->nss_2g, param->nss_5g); 789 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 790 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 791 txrx_streams->supported_tx_streams = param->nss_2g; 792 txrx_streams->supported_rx_streams = param->nss_2g; 793 WMITLV_SET_HDR(&txrx_streams->tlv_header, 794 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 795 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 796 797 txrx_streams++; 798 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 799 txrx_streams->supported_tx_streams = param->nss_5g; 800 txrx_streams->supported_rx_streams = param->nss_5g; 801 WMITLV_SET_HDR(&txrx_streams->tlv_header, 802 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 803 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 804 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 805 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 806 if (QDF_IS_STATUS_ERROR(ret)) { 807 wmi_err("Failed to send WMI_VDEV_CREATE_CMDID"); 808 wmi_buf_free(buf); 809 } 810 811 return ret; 812 } 813 814 /** 815 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 816 * @wmi_handle: wmi handle 817 * @if_id: vdev id 818 * 819 * Return: QDF_STATUS_SUCCESS for success or error code 820 */ 821 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 822 uint8_t if_id) 823 { 824 wmi_vdev_delete_cmd_fixed_param *cmd; 825 wmi_buf_t buf; 826 QDF_STATUS ret; 827 828 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 829 if (!buf) 830 return QDF_STATUS_E_NOMEM; 831 832 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 833 WMITLV_SET_HDR(&cmd->tlv_header, 834 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 835 WMITLV_GET_STRUCT_TLVLEN 836 (wmi_vdev_delete_cmd_fixed_param)); 837 cmd->vdev_id = if_id; 838 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 839 ret = wmi_unified_cmd_send(wmi_handle, buf, 840 sizeof(wmi_vdev_delete_cmd_fixed_param), 841 WMI_VDEV_DELETE_CMDID); 842 if (QDF_IS_STATUS_ERROR(ret)) { 843 wmi_err("Failed to send WMI_VDEV_DELETE_CMDID"); 844 wmi_buf_free(buf); 845 } 846 wmi_debug("vdev id = %d", if_id); 847 848 return ret; 849 } 850 851 /** 852 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 853 * @wmi_handle: wmi handle 854 * @vdev_id: vdev id 855 * @nss_chains_user_cfg: user configured nss chain params 856 * 857 * Return: QDF_STATUS_SUCCESS for success or error code 858 */ 859 static QDF_STATUS 860 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 861 uint8_t vdev_id, 862 struct vdev_nss_chains *user_cfg) 863 { 864 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 865 wmi_buf_t buf; 866 QDF_STATUS ret; 867 868 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 869 if (!buf) 870 return QDF_STATUS_E_NOMEM; 871 872 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 873 WMITLV_SET_HDR(&cmd->tlv_header, 874 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 875 WMITLV_GET_STRUCT_TLVLEN 876 (wmi_vdev_chainmask_config_cmd_fixed_param)); 877 cmd->vdev_id = vdev_id; 878 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 879 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 880 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 881 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 882 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 883 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 884 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 885 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 886 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 887 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 888 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 889 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 890 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 891 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 892 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 893 894 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 895 ret = wmi_unified_cmd_send(wmi_handle, buf, 896 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 897 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 898 if (QDF_IS_STATUS_ERROR(ret)) { 899 wmi_err("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 900 wmi_buf_free(buf); 901 } 902 wmi_debug("vdev_id %d", vdev_id); 903 904 return ret; 905 } 906 907 /** 908 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 909 * @wmi: wmi handle 910 * @vdev_id: vdev id 911 * 912 * Return: QDF_STATUS_SUCCESS for success or erro code 913 */ 914 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 915 uint8_t vdev_id) 916 { 917 wmi_vdev_stop_cmd_fixed_param *cmd; 918 wmi_buf_t buf; 919 int32_t len = sizeof(*cmd); 920 921 buf = wmi_buf_alloc(wmi, len); 922 if (!buf) 923 return QDF_STATUS_E_NOMEM; 924 925 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 926 WMITLV_SET_HDR(&cmd->tlv_header, 927 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 928 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 929 cmd->vdev_id = vdev_id; 930 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 931 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 932 wmi_err("Failed to send vdev stop command"); 933 wmi_buf_free(buf); 934 return QDF_STATUS_E_FAILURE; 935 } 936 wmi_debug("vdev id = %d", vdev_id); 937 938 return 0; 939 } 940 941 /** 942 * send_vdev_down_cmd_tlv() - send vdev down command to fw 943 * @wmi: wmi handle 944 * @vdev_id: vdev id 945 * 946 * Return: QDF_STATUS_SUCCESS for success or error code 947 */ 948 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 949 { 950 wmi_vdev_down_cmd_fixed_param *cmd; 951 wmi_buf_t buf; 952 int32_t len = sizeof(*cmd); 953 954 buf = wmi_buf_alloc(wmi, len); 955 if (!buf) 956 return QDF_STATUS_E_NOMEM; 957 958 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 959 WMITLV_SET_HDR(&cmd->tlv_header, 960 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 961 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 962 cmd->vdev_id = vdev_id; 963 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 964 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 965 wmi_err("Failed to send vdev down"); 966 wmi_buf_free(buf); 967 return QDF_STATUS_E_FAILURE; 968 } 969 wmi_debug("vdev_id %d", vdev_id); 970 971 return 0; 972 } 973 974 static inline void copy_channel_info( 975 wmi_vdev_start_request_cmd_fixed_param * cmd, 976 wmi_channel *chan, 977 struct vdev_start_params *req) 978 { 979 chan->mhz = req->channel.mhz; 980 981 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 982 983 chan->band_center_freq1 = req->channel.cfreq1; 984 chan->band_center_freq2 = req->channel.cfreq2; 985 986 if (req->channel.half_rate) 987 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 988 else if (req->channel.quarter_rate) 989 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 990 991 if (req->channel.dfs_set) { 992 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 993 cmd->disable_hw_ack = req->disable_hw_ack; 994 } 995 996 if (req->channel.dfs_set_cfreq2) 997 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 998 999 /* According to firmware both reg power and max tx power 1000 * on set channel power is used and set it to max reg 1001 * power from regulatory. 1002 */ 1003 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 1004 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 1005 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 1006 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 1007 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 1008 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 1009 1010 } 1011 1012 /** 1013 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1014 * @wmi_handle: wmi handle 1015 * @req: vdev start params 1016 * 1017 * Return: QDF status 1018 */ 1019 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1020 struct vdev_start_params *req) 1021 { 1022 wmi_vdev_start_request_cmd_fixed_param *cmd; 1023 wmi_buf_t buf; 1024 wmi_channel *chan; 1025 int32_t len, ret; 1026 uint8_t *buf_ptr; 1027 1028 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1029 buf = wmi_buf_alloc(wmi_handle, len); 1030 if (!buf) 1031 return QDF_STATUS_E_NOMEM; 1032 1033 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1034 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1035 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1036 WMITLV_SET_HDR(&cmd->tlv_header, 1037 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1038 WMITLV_GET_STRUCT_TLVLEN 1039 (wmi_vdev_start_request_cmd_fixed_param)); 1040 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1041 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1042 cmd->vdev_id = req->vdev_id; 1043 1044 /* Fill channel info */ 1045 copy_channel_info(cmd, chan, req); 1046 cmd->beacon_interval = req->beacon_interval; 1047 cmd->dtim_period = req->dtim_period; 1048 1049 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1050 if (req->bcn_tx_rate_code) 1051 wmi_enable_bcn_ratecode(&cmd->flags); 1052 1053 if (!req->is_restart) { 1054 if (req->pmf_enabled) 1055 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1056 1057 cmd->mbss_capability_flags = req->mbssid_flags; 1058 cmd->vdevid_trans = req->vdevid_trans; 1059 } 1060 1061 /* Copy the SSID */ 1062 if (req->ssid.length) { 1063 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1064 cmd->ssid.ssid_len = req->ssid.length; 1065 else 1066 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1067 qdf_mem_copy(cmd->ssid.ssid, req->ssid.ssid, 1068 cmd->ssid.ssid_len); 1069 } 1070 1071 if (req->hidden_ssid) 1072 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1073 1074 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1075 cmd->num_noa_descriptors = req->num_noa_descriptors; 1076 cmd->preferred_rx_streams = req->preferred_rx_streams; 1077 cmd->preferred_tx_streams = req->preferred_tx_streams; 1078 cmd->cac_duration_ms = req->cac_duration_ms; 1079 cmd->regdomain = req->regdomain; 1080 cmd->he_ops = req->he_ops; 1081 1082 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1083 sizeof(wmi_channel)); 1084 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1085 cmd->num_noa_descriptors * 1086 sizeof(wmi_p2p_noa_descriptor)); 1087 wmi_info("vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1088 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1089 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1090 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1091 "req->dis_hw_ack: %d ", req->vdev_id, 1092 chan->mhz, req->channel.phy_mode, chan->info, 1093 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1094 chan->band_center_freq1, chan->band_center_freq2, 1095 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1096 req->preferred_tx_streams, req->preferred_rx_streams, 1097 req->ldpc_rx_enabled, req->cac_duration_ms, 1098 req->regdomain, req->he_ops, 1099 req->disable_hw_ack); 1100 1101 if (req->is_restart) { 1102 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1103 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1104 WMI_VDEV_RESTART_REQUEST_CMDID); 1105 } else { 1106 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1107 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1108 WMI_VDEV_START_REQUEST_CMDID); 1109 } 1110 if (ret) { 1111 wmi_err("Failed to send vdev start command"); 1112 wmi_buf_free(buf); 1113 return QDF_STATUS_E_FAILURE; 1114 } 1115 1116 return QDF_STATUS_SUCCESS; 1117 } 1118 1119 /** 1120 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1121 * @wmi: wmi handle 1122 * @peer_addr: peer mac address 1123 * @param: pointer to hold peer flush tid parameter 1124 * 1125 * Return: 0 for success or error code 1126 */ 1127 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1128 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1129 struct peer_flush_params *param) 1130 { 1131 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1132 wmi_buf_t buf; 1133 int32_t len = sizeof(*cmd); 1134 1135 buf = wmi_buf_alloc(wmi, len); 1136 if (!buf) 1137 return QDF_STATUS_E_NOMEM; 1138 1139 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1140 WMITLV_SET_HDR(&cmd->tlv_header, 1141 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1142 WMITLV_GET_STRUCT_TLVLEN 1143 (wmi_peer_flush_tids_cmd_fixed_param)); 1144 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1145 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1146 cmd->vdev_id = param->vdev_id; 1147 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d and peer bitmap %d", 1148 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id, 1149 param->peer_tid_bitmap); 1150 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1151 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1152 wmi_err("Failed to send flush tid command"); 1153 wmi_buf_free(buf); 1154 return QDF_STATUS_E_FAILURE; 1155 } 1156 1157 return 0; 1158 } 1159 1160 /** 1161 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1162 * @wmi: wmi handle 1163 * @peer_addr: peer mac addr 1164 * @vdev_id: vdev id 1165 * 1166 * Return: QDF_STATUS_SUCCESS for success or error code 1167 */ 1168 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1169 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1170 uint8_t vdev_id) 1171 { 1172 wmi_peer_delete_cmd_fixed_param *cmd; 1173 wmi_buf_t buf; 1174 int32_t len = sizeof(*cmd); 1175 buf = wmi_buf_alloc(wmi, len); 1176 if (!buf) 1177 return QDF_STATUS_E_NOMEM; 1178 1179 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 1180 WMITLV_SET_HDR(&cmd->tlv_header, 1181 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1182 WMITLV_GET_STRUCT_TLVLEN 1183 (wmi_peer_delete_cmd_fixed_param)); 1184 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1185 cmd->vdev_id = vdev_id; 1186 1187 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1188 QDF_MAC_ADDR_REF(peer_addr), vdev_id); 1189 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1190 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1191 wmi_err("Failed to send peer delete command"); 1192 wmi_buf_free(buf); 1193 return QDF_STATUS_E_FAILURE; 1194 } 1195 1196 return 0; 1197 } 1198 1199 /** 1200 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1201 * @wmi: wmi handle 1202 * @param: pointer to hold peer delete all parameter 1203 * 1204 * Return: QDF_STATUS_SUCCESS for success or error code 1205 */ 1206 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1207 wmi_unified_t wmi, 1208 struct peer_delete_all_params *param) 1209 { 1210 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1211 wmi_buf_t buf; 1212 int32_t len = sizeof(*cmd); 1213 1214 buf = wmi_buf_alloc(wmi, len); 1215 if (!buf) 1216 return QDF_STATUS_E_NOMEM; 1217 1218 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1219 WMITLV_SET_HDR( 1220 &cmd->tlv_header, 1221 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1222 WMITLV_GET_STRUCT_TLVLEN 1223 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1224 cmd->vdev_id = param->vdev_id; 1225 1226 wmi_debug("vdev_id %d", cmd->vdev_id); 1227 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1228 if (wmi_unified_cmd_send(wmi, buf, len, 1229 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1230 wmi_err("Failed to send peer del all command"); 1231 wmi_buf_free(buf); 1232 return QDF_STATUS_E_FAILURE; 1233 } 1234 1235 return QDF_STATUS_SUCCESS; 1236 } 1237 1238 /** 1239 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1240 * to target id. 1241 * @peer_param_id: host param id. 1242 * 1243 * Return: Target param id. 1244 */ 1245 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1246 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1247 uint32_t peer_param_id) 1248 { 1249 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1250 return peer_param_tlv[peer_param_id]; 1251 return WMI_UNAVAILABLE_PARAM; 1252 } 1253 #else 1254 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1255 uint32_t peer_param_id) 1256 { 1257 return peer_param_id; 1258 } 1259 #endif 1260 1261 /** 1262 * send_peer_param_cmd_tlv() - set peer parameter in fw 1263 * @wmi: wmi handle 1264 * @peer_addr: peer mac address 1265 * @param : pointer to hold peer set parameter 1266 * 1267 * Return: QDF_STATUS_SUCCESS for success or error code 1268 */ 1269 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1270 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1271 struct peer_set_params *param) 1272 { 1273 wmi_peer_set_param_cmd_fixed_param *cmd; 1274 wmi_buf_t buf; 1275 int32_t err; 1276 uint32_t param_id; 1277 1278 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1279 if (param_id == WMI_UNAVAILABLE_PARAM) { 1280 wmi_err("Unavailable param %d", param->param_id); 1281 return QDF_STATUS_E_NOSUPPORT; 1282 } 1283 1284 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1285 if (!buf) 1286 return QDF_STATUS_E_NOMEM; 1287 1288 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1289 WMITLV_SET_HDR(&cmd->tlv_header, 1290 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1291 WMITLV_GET_STRUCT_TLVLEN 1292 (wmi_peer_set_param_cmd_fixed_param)); 1293 cmd->vdev_id = param->vdev_id; 1294 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1295 cmd->param_id = param_id; 1296 cmd->param_value = param->param_value; 1297 1298 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1299 cmd->vdev_id, 1300 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1301 cmd->param_value); 1302 1303 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1304 err = wmi_unified_cmd_send(wmi, buf, 1305 sizeof(wmi_peer_set_param_cmd_fixed_param), 1306 WMI_PEER_SET_PARAM_CMDID); 1307 if (err) { 1308 wmi_err("Failed to send set_param cmd"); 1309 wmi_buf_free(buf); 1310 return QDF_STATUS_E_FAILURE; 1311 } 1312 1313 return 0; 1314 } 1315 1316 /** 1317 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1318 * @wmi: wmi handle 1319 * @bssid: bssid 1320 * @vdev_up_params: pointer to hold vdev up parameter 1321 * 1322 * Return: QDF_STATUS_SUCCESS for success or error code 1323 */ 1324 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1325 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1326 struct vdev_up_params *params) 1327 { 1328 wmi_vdev_up_cmd_fixed_param *cmd; 1329 wmi_buf_t buf; 1330 int32_t len = sizeof(*cmd); 1331 1332 wmi_debug("VDEV_UP"); 1333 wmi_debug("vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT, 1334 params->vdev_id, params->assoc_id, QDF_MAC_ADDR_REF(bssid)); 1335 buf = wmi_buf_alloc(wmi, len); 1336 if (!buf) 1337 return QDF_STATUS_E_NOMEM; 1338 1339 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1340 WMITLV_SET_HDR(&cmd->tlv_header, 1341 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1342 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1343 cmd->vdev_id = params->vdev_id; 1344 cmd->vdev_assoc_id = params->assoc_id; 1345 cmd->profile_idx = params->profile_idx; 1346 cmd->profile_num = params->profile_num; 1347 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1348 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1349 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1350 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1351 wmi_err("Failed to send vdev up command"); 1352 wmi_buf_free(buf); 1353 return QDF_STATUS_E_FAILURE; 1354 } 1355 1356 return 0; 1357 } 1358 1359 /** 1360 * send_peer_create_cmd_tlv() - send peer create command to fw 1361 * @wmi: wmi handle 1362 * @peer_addr: peer mac address 1363 * @peer_type: peer type 1364 * @vdev_id: vdev id 1365 * 1366 * Return: QDF_STATUS_SUCCESS for success or error code 1367 */ 1368 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1369 struct peer_create_params *param) 1370 { 1371 wmi_peer_create_cmd_fixed_param *cmd; 1372 wmi_buf_t buf; 1373 int32_t len = sizeof(*cmd); 1374 1375 buf = wmi_buf_alloc(wmi, len); 1376 if (!buf) 1377 return QDF_STATUS_E_NOMEM; 1378 1379 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1380 WMITLV_SET_HDR(&cmd->tlv_header, 1381 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1382 WMITLV_GET_STRUCT_TLVLEN 1383 (wmi_peer_create_cmd_fixed_param)); 1384 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1385 cmd->peer_type = param->peer_type; 1386 cmd->vdev_id = param->vdev_id; 1387 1388 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1389 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1390 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1391 wmi_buf_free(buf); 1392 return QDF_STATUS_E_FAILURE; 1393 } 1394 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1395 QDF_MAC_ADDR_REF(param->peer_addr), 1396 param->vdev_id); 1397 1398 return 0; 1399 } 1400 1401 /** 1402 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1403 * command to fw 1404 * @wmi: wmi handle 1405 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 1406 * 1407 * Return: 0 for success or error code 1408 */ 1409 static 1410 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1411 struct rx_reorder_queue_setup_params *param) 1412 { 1413 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1414 wmi_buf_t buf; 1415 int32_t len = sizeof(*cmd); 1416 1417 buf = wmi_buf_alloc(wmi, len); 1418 if (!buf) 1419 return QDF_STATUS_E_NOMEM; 1420 1421 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1422 WMITLV_SET_HDR(&cmd->tlv_header, 1423 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1424 WMITLV_GET_STRUCT_TLVLEN 1425 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1426 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1427 cmd->vdev_id = param->vdev_id; 1428 cmd->tid = param->tid; 1429 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1430 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1431 cmd->queue_no = param->queue_no; 1432 cmd->ba_window_size_valid = param->ba_window_size_valid; 1433 cmd->ba_window_size = param->ba_window_size; 1434 1435 1436 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1437 if (wmi_unified_cmd_send(wmi, buf, len, 1438 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1439 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 1440 wmi_buf_free(buf); 1441 return QDF_STATUS_E_FAILURE; 1442 } 1443 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 1444 QDF_MAC_ADDR_REF(param->peer_macaddr), 1445 param->vdev_id, param->tid); 1446 1447 return QDF_STATUS_SUCCESS; 1448 } 1449 1450 /** 1451 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1452 * command to fw 1453 * @wmi: wmi handle 1454 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 1455 * 1456 * Return: 0 for success or error code 1457 */ 1458 static 1459 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 1460 struct rx_reorder_queue_remove_params *param) 1461 { 1462 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 1463 wmi_buf_t buf; 1464 int32_t len = sizeof(*cmd); 1465 1466 buf = wmi_buf_alloc(wmi, len); 1467 if (!buf) 1468 return QDF_STATUS_E_NOMEM; 1469 1470 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 1471 wmi_buf_data(buf); 1472 WMITLV_SET_HDR(&cmd->tlv_header, 1473 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 1474 WMITLV_GET_STRUCT_TLVLEN 1475 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 1476 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1477 cmd->vdev_id = param->vdev_id; 1478 cmd->tid_mask = param->peer_tid_bitmap; 1479 1480 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 1481 if (wmi_unified_cmd_send(wmi, buf, len, 1482 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 1483 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 1484 wmi_buf_free(buf); 1485 return QDF_STATUS_E_FAILURE; 1486 } 1487 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 1488 QDF_MAC_ADDR_REF(param->peer_macaddr), 1489 param->vdev_id, param->peer_tid_bitmap); 1490 1491 return QDF_STATUS_SUCCESS; 1492 } 1493 1494 #ifdef WLAN_SUPPORT_GREEN_AP 1495 /** 1496 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1497 * @wmi_handle: wmi handle 1498 * @value: value 1499 * @pdev_id: pdev id to have radio context 1500 * 1501 * Return: QDF_STATUS_SUCCESS for success or error code 1502 */ 1503 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1504 uint32_t value, uint8_t pdev_id) 1505 { 1506 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1507 wmi_buf_t buf; 1508 int32_t len = sizeof(*cmd); 1509 1510 wmi_debug("Set Green AP PS val %d", value); 1511 1512 buf = wmi_buf_alloc(wmi_handle, len); 1513 if (!buf) 1514 return QDF_STATUS_E_NOMEM; 1515 1516 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1517 WMITLV_SET_HDR(&cmd->tlv_header, 1518 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1519 WMITLV_GET_STRUCT_TLVLEN 1520 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1521 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1522 wmi_handle, 1523 pdev_id); 1524 cmd->enable = value; 1525 1526 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 1527 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1528 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1529 wmi_err("Set Green AP PS param Failed val %d", value); 1530 wmi_buf_free(buf); 1531 return QDF_STATUS_E_FAILURE; 1532 } 1533 1534 return 0; 1535 } 1536 #endif 1537 1538 /** 1539 * send_pdev_utf_cmd_tlv() - send utf command to fw 1540 * @wmi_handle: wmi handle 1541 * @param: pointer to pdev_utf_params 1542 * @mac_id: mac id to have radio context 1543 * 1544 * Return: QDF_STATUS_SUCCESS for success or error code 1545 */ 1546 static QDF_STATUS 1547 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1548 struct pdev_utf_params *param, 1549 uint8_t mac_id) 1550 { 1551 wmi_buf_t buf; 1552 uint8_t *cmd; 1553 /* if param->len is 0 no data is sent, return error */ 1554 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1555 static uint8_t msgref = 1; 1556 uint8_t segNumber = 0, segInfo, numSegments; 1557 uint16_t chunk_len, total_bytes; 1558 uint8_t *bufpos; 1559 struct seg_hdr_info segHdrInfo; 1560 1561 bufpos = param->utf_payload; 1562 total_bytes = param->len; 1563 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1564 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1565 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1566 1567 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1568 numSegments++; 1569 1570 while (param->len) { 1571 if (param->len > MAX_WMI_UTF_LEN) 1572 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 1573 else 1574 chunk_len = param->len; 1575 1576 buf = wmi_buf_alloc(wmi_handle, 1577 (chunk_len + sizeof(segHdrInfo) + 1578 WMI_TLV_HDR_SIZE)); 1579 if (!buf) 1580 return QDF_STATUS_E_NOMEM; 1581 1582 cmd = (uint8_t *) wmi_buf_data(buf); 1583 1584 segHdrInfo.len = total_bytes; 1585 segHdrInfo.msgref = msgref; 1586 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1587 segHdrInfo.segmentInfo = segInfo; 1588 segHdrInfo.pad = 0; 1589 1590 wmi_debug("segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1591 " segHdrInfo.segmentInfo = %d", 1592 segHdrInfo.len, segHdrInfo.msgref, 1593 segHdrInfo.segmentInfo); 1594 1595 wmi_debug("total_bytes %d segNumber %d totalSegments %d" 1596 " chunk len %d", total_bytes, segNumber, 1597 numSegments, chunk_len); 1598 1599 segNumber++; 1600 1601 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1602 (chunk_len + sizeof(segHdrInfo))); 1603 cmd += WMI_TLV_HDR_SIZE; 1604 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1605 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len); 1606 1607 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 1608 ret = wmi_unified_cmd_send(wmi_handle, buf, 1609 (chunk_len + sizeof(segHdrInfo) + 1610 WMI_TLV_HDR_SIZE), 1611 WMI_PDEV_UTF_CMDID); 1612 1613 if (QDF_IS_STATUS_ERROR(ret)) { 1614 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 1615 wmi_buf_free(buf); 1616 break; 1617 } 1618 1619 param->len -= chunk_len; 1620 bufpos += chunk_len; 1621 } 1622 1623 msgref++; 1624 1625 return ret; 1626 } 1627 1628 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1629 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1630 { 1631 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 1632 return pdev_param_tlv[host_param]; 1633 return WMI_UNAVAILABLE_PARAM; 1634 } 1635 #else 1636 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1637 { 1638 return host_param; 1639 } 1640 #endif 1641 1642 /** 1643 * send_pdev_param_cmd_tlv() - set pdev parameters 1644 * @wmi_handle: wmi handle 1645 * @param: pointer to pdev parameter 1646 * @mac_id: radio context 1647 * 1648 * Return: 0 on success, errno on failure 1649 */ 1650 static QDF_STATUS 1651 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1652 struct pdev_params *param, 1653 uint8_t mac_id) 1654 { 1655 QDF_STATUS ret; 1656 wmi_pdev_set_param_cmd_fixed_param *cmd; 1657 wmi_buf_t buf; 1658 uint16_t len = sizeof(*cmd); 1659 uint32_t pdev_param; 1660 1661 pdev_param = convert_host_pdev_param_tlv(param->param_id); 1662 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1663 wmi_err("Unavailable param %d", param->param_id); 1664 return QDF_STATUS_E_INVAL; 1665 } 1666 1667 buf = wmi_buf_alloc(wmi_handle, len); 1668 if (!buf) 1669 return QDF_STATUS_E_NOMEM; 1670 1671 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1672 WMITLV_SET_HDR(&cmd->tlv_header, 1673 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1674 WMITLV_GET_STRUCT_TLVLEN 1675 (wmi_pdev_set_param_cmd_fixed_param)); 1676 if (param->is_host_pdev_id) 1677 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 1678 wmi_handle, 1679 mac_id); 1680 else 1681 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1682 wmi_handle, 1683 mac_id); 1684 cmd->param_id = pdev_param; 1685 cmd->param_value = param->param_value; 1686 wmi_debug("Setting pdev param = %x, value = %u", param->param_id, 1687 param->param_value); 1688 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 1689 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1690 WMI_PDEV_SET_PARAM_CMDID); 1691 if (QDF_IS_STATUS_ERROR(ret)) { 1692 wmi_err("Failed to send set param command ret = %d", ret); 1693 wmi_buf_free(buf); 1694 } 1695 return ret; 1696 } 1697 1698 /** 1699 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 1700 * @wmi_handle: wmi handle 1701 * @msg: Structure containing the following parameters 1702 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 1703 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 1704 * 1705 * Provides notification to the WLAN firmware that host driver is requesting a 1706 * HardWare (HW) Mode change. This command is needed to support iHelium in the 1707 * configurations that include the Dual Band Simultaneous (DBS) feature. 1708 * 1709 * Return: Success if the cmd is sent successfully to the firmware 1710 */ 1711 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 1712 uint32_t hw_mode_index) 1713 { 1714 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 1715 wmi_buf_t buf; 1716 uint32_t len; 1717 1718 len = sizeof(*cmd); 1719 1720 buf = wmi_buf_alloc(wmi_handle, len); 1721 if (!buf) 1722 return QDF_STATUS_E_NOMEM; 1723 1724 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 1725 WMITLV_SET_HDR(&cmd->tlv_header, 1726 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 1727 WMITLV_GET_STRUCT_TLVLEN( 1728 wmi_pdev_set_hw_mode_cmd_fixed_param)); 1729 1730 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1731 wmi_handle, 1732 WMI_HOST_PDEV_ID_SOC); 1733 cmd->hw_mode_index = hw_mode_index; 1734 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 1735 1736 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 1737 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1738 WMI_PDEV_SET_HW_MODE_CMDID)) { 1739 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 1740 wmi_buf_free(buf); 1741 return QDF_STATUS_E_FAILURE; 1742 } 1743 1744 return QDF_STATUS_SUCCESS; 1745 } 1746 1747 /** 1748 * send_suspend_cmd_tlv() - WMI suspend function 1749 * @param wmi_handle : handle to WMI. 1750 * @param param : pointer to hold suspend parameter 1751 * @mac_id: radio context 1752 * 1753 * Return 0 on success and -ve on failure. 1754 */ 1755 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1756 struct suspend_params *param, 1757 uint8_t mac_id) 1758 { 1759 wmi_pdev_suspend_cmd_fixed_param *cmd; 1760 wmi_buf_t wmibuf; 1761 uint32_t len = sizeof(*cmd); 1762 int32_t ret; 1763 1764 /* 1765 * send the command to Target to ignore the 1766 * PCIE reset so as to ensure that Host and target 1767 * states are in sync 1768 */ 1769 wmibuf = wmi_buf_alloc(wmi_handle, len); 1770 if (!wmibuf) 1771 return QDF_STATUS_E_NOMEM; 1772 1773 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1774 WMITLV_SET_HDR(&cmd->tlv_header, 1775 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1776 WMITLV_GET_STRUCT_TLVLEN 1777 (wmi_pdev_suspend_cmd_fixed_param)); 1778 if (param->disable_target_intr) 1779 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1780 else 1781 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1782 1783 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1784 wmi_handle, 1785 mac_id); 1786 1787 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 1788 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1789 WMI_PDEV_SUSPEND_CMDID); 1790 if (ret) { 1791 wmi_buf_free(wmibuf); 1792 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1793 } 1794 1795 return ret; 1796 } 1797 1798 /** 1799 * send_resume_cmd_tlv() - WMI resume function 1800 * @param wmi_handle : handle to WMI. 1801 * @mac_id: radio context 1802 * 1803 * Return: 0 on success and -ve on failure. 1804 */ 1805 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1806 uint8_t mac_id) 1807 { 1808 wmi_buf_t wmibuf; 1809 wmi_pdev_resume_cmd_fixed_param *cmd; 1810 QDF_STATUS ret; 1811 1812 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1813 if (!wmibuf) 1814 return QDF_STATUS_E_NOMEM; 1815 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1816 WMITLV_SET_HDR(&cmd->tlv_header, 1817 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1818 WMITLV_GET_STRUCT_TLVLEN 1819 (wmi_pdev_resume_cmd_fixed_param)); 1820 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1821 wmi_handle, 1822 mac_id); 1823 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 1824 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1825 WMI_PDEV_RESUME_CMDID); 1826 if (QDF_IS_STATUS_ERROR(ret)) { 1827 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 1828 wmi_buf_free(wmibuf); 1829 } 1830 1831 return ret; 1832 } 1833 1834 /** 1835 * send_wow_enable_cmd_tlv() - WMI wow enable function 1836 * @param wmi_handle : handle to WMI. 1837 * @param param : pointer to hold wow enable parameter 1838 * @mac_id: radio context 1839 * 1840 * Return: 0 on success and -ve on failure. 1841 */ 1842 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1843 struct wow_cmd_params *param, 1844 uint8_t mac_id) 1845 { 1846 wmi_wow_enable_cmd_fixed_param *cmd; 1847 wmi_buf_t buf; 1848 int32_t len; 1849 int32_t ret; 1850 1851 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1852 1853 buf = wmi_buf_alloc(wmi_handle, len); 1854 if (!buf) 1855 return QDF_STATUS_E_NOMEM; 1856 1857 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1858 WMITLV_SET_HDR(&cmd->tlv_header, 1859 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1860 WMITLV_GET_STRUCT_TLVLEN 1861 (wmi_wow_enable_cmd_fixed_param)); 1862 cmd->enable = param->enable; 1863 if (param->can_suspend_link) 1864 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1865 else 1866 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1867 cmd->flags = param->flags; 1868 1869 wmi_debug("suspend type: %s flag is 0x%x", 1870 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1871 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 1872 cmd->flags); 1873 1874 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 1875 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1876 WMI_WOW_ENABLE_CMDID); 1877 if (ret) 1878 wmi_buf_free(buf); 1879 1880 return ret; 1881 } 1882 1883 /** 1884 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1885 * @wmi_handle: wmi handle 1886 * @peer_addr: peer mac address 1887 * @param: pointer to ap_ps parameter structure 1888 * 1889 * Return: QDF_STATUS_SUCCESS for success or error code 1890 */ 1891 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1892 uint8_t *peer_addr, 1893 struct ap_ps_params *param) 1894 { 1895 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1896 wmi_buf_t buf; 1897 int32_t err; 1898 1899 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1900 if (!buf) 1901 return QDF_STATUS_E_NOMEM; 1902 1903 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1904 WMITLV_SET_HDR(&cmd->tlv_header, 1905 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 1906 WMITLV_GET_STRUCT_TLVLEN 1907 (wmi_ap_ps_peer_cmd_fixed_param)); 1908 cmd->vdev_id = param->vdev_id; 1909 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1910 cmd->param = param->param; 1911 cmd->value = param->value; 1912 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 1913 err = wmi_unified_cmd_send(wmi_handle, buf, 1914 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 1915 if (err) { 1916 wmi_err("Failed to send set_ap_ps_param cmd"); 1917 wmi_buf_free(buf); 1918 return QDF_STATUS_E_FAILURE; 1919 } 1920 1921 return 0; 1922 } 1923 1924 /** 1925 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 1926 * @wmi_handle: wmi handle 1927 * @peer_addr: peer mac address 1928 * @param: pointer to sta_ps parameter structure 1929 * 1930 * Return: QDF_STATUS_SUCCESS for success or error code 1931 */ 1932 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1933 struct sta_ps_params *param) 1934 { 1935 wmi_sta_powersave_param_cmd_fixed_param *cmd; 1936 wmi_buf_t buf; 1937 int32_t len = sizeof(*cmd); 1938 1939 buf = wmi_buf_alloc(wmi_handle, len); 1940 if (!buf) 1941 return QDF_STATUS_E_NOMEM; 1942 1943 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 1944 WMITLV_SET_HDR(&cmd->tlv_header, 1945 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 1946 WMITLV_GET_STRUCT_TLVLEN 1947 (wmi_sta_powersave_param_cmd_fixed_param)); 1948 cmd->vdev_id = param->vdev_id; 1949 cmd->param = param->param_id; 1950 cmd->value = param->value; 1951 1952 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 1953 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1954 WMI_STA_POWERSAVE_PARAM_CMDID)) { 1955 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 1956 param->vdev_id, param->param_id, param->value); 1957 wmi_buf_free(buf); 1958 return QDF_STATUS_E_FAILURE; 1959 } 1960 1961 return 0; 1962 } 1963 1964 /** 1965 * send_crash_inject_cmd_tlv() - inject fw crash 1966 * @wmi_handle: wmi handle 1967 * @param: ponirt to crash inject parameter structure 1968 * 1969 * Return: QDF_STATUS_SUCCESS for success or return error 1970 */ 1971 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 1972 struct crash_inject *param) 1973 { 1974 int32_t ret = 0; 1975 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 1976 uint16_t len = sizeof(*cmd); 1977 wmi_buf_t buf; 1978 1979 buf = wmi_buf_alloc(wmi_handle, len); 1980 if (!buf) 1981 return QDF_STATUS_E_NOMEM; 1982 1983 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 1984 WMITLV_SET_HDR(&cmd->tlv_header, 1985 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 1986 WMITLV_GET_STRUCT_TLVLEN 1987 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 1988 cmd->type = param->type; 1989 cmd->delay_time_ms = param->delay_time_ms; 1990 1991 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 1992 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1993 WMI_FORCE_FW_HANG_CMDID); 1994 if (ret) { 1995 wmi_err("Failed to send set param command, ret = %d", ret); 1996 wmi_buf_free(buf); 1997 } 1998 1999 return ret; 2000 } 2001 2002 /** 2003 * send_dbglog_cmd_tlv() - set debug log level 2004 * @param wmi_handle : handle to WMI. 2005 * @param param : pointer to hold dbglog level parameter 2006 * 2007 * Return: 0 on success and -ve on failure. 2008 */ 2009 static QDF_STATUS 2010 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2011 struct dbglog_params *dbglog_param) 2012 { 2013 wmi_buf_t buf; 2014 wmi_debug_log_config_cmd_fixed_param *configmsg; 2015 QDF_STATUS status; 2016 int32_t i; 2017 int32_t len; 2018 int8_t *buf_ptr; 2019 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 2020 2021 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2022 2023 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2024 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2025 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2026 buf = wmi_buf_alloc(wmi_handle, len); 2027 if (!buf) 2028 return QDF_STATUS_E_NOMEM; 2029 2030 configmsg = 2031 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2032 buf_ptr = (int8_t *) configmsg; 2033 WMITLV_SET_HDR(&configmsg->tlv_header, 2034 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2035 WMITLV_GET_STRUCT_TLVLEN 2036 (wmi_debug_log_config_cmd_fixed_param)); 2037 configmsg->dbg_log_param = dbglog_param->param; 2038 configmsg->value = dbglog_param->val; 2039 /* Filling in the data part of second tlv -- should 2040 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2041 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2042 sizeof 2043 (wmi_debug_log_config_cmd_fixed_param) 2044 + WMI_TLV_HDR_SIZE); 2045 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2046 WMITLV_TAG_ARRAY_UINT32, 2047 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2048 if (dbglog_param->module_id_bitmap) { 2049 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2050 module_id_bitmap_array[i] = 2051 dbglog_param->module_id_bitmap[i]; 2052 } 2053 } 2054 2055 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2056 status = wmi_unified_cmd_send(wmi_handle, buf, 2057 len, WMI_DBGLOG_CFG_CMDID); 2058 2059 if (status != QDF_STATUS_SUCCESS) 2060 wmi_buf_free(buf); 2061 2062 return status; 2063 } 2064 2065 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2066 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2067 { 2068 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2069 return vdev_param_tlv[host_param]; 2070 return WMI_UNAVAILABLE_PARAM; 2071 } 2072 #else 2073 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2074 { 2075 return host_param; 2076 } 2077 #endif 2078 2079 /** 2080 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2081 * @param wmi_handle : handle to WMI. 2082 * @param macaddr : MAC address 2083 * @param param : pointer to hold vdev set parameter 2084 * 2085 * Return: 0 on success and -ve on failure. 2086 */ 2087 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2088 struct vdev_set_params *param) 2089 { 2090 QDF_STATUS ret; 2091 wmi_vdev_set_param_cmd_fixed_param *cmd; 2092 wmi_buf_t buf; 2093 uint16_t len = sizeof(*cmd); 2094 uint32_t vdev_param; 2095 2096 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2097 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2098 wmi_err("Vdev param %d not available", param->param_id); 2099 return QDF_STATUS_E_INVAL; 2100 2101 } 2102 2103 buf = wmi_buf_alloc(wmi_handle, len); 2104 if (!buf) 2105 return QDF_STATUS_E_NOMEM; 2106 2107 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2108 WMITLV_SET_HDR(&cmd->tlv_header, 2109 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2110 WMITLV_GET_STRUCT_TLVLEN 2111 (wmi_vdev_set_param_cmd_fixed_param)); 2112 cmd->vdev_id = param->vdev_id; 2113 cmd->param_id = vdev_param; 2114 cmd->param_value = param->param_value; 2115 wmi_debug("Setting vdev %d param = %x, value = %u", 2116 cmd->vdev_id, cmd->param_id, cmd->param_value); 2117 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2118 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2119 WMI_VDEV_SET_PARAM_CMDID); 2120 if (QDF_IS_STATUS_ERROR(ret)) { 2121 wmi_err("Failed to send set param command ret = %d", ret); 2122 wmi_buf_free(buf); 2123 } 2124 2125 return ret; 2126 } 2127 2128 /** 2129 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 2130 * @wmi_handle: handle to WMI. 2131 * @macaddr: Peer mac address to be filter 2132 * @mac_id: mac id to have radio context 2133 * @enb_dsb: Enable MAC based filtering or Disable 2134 * 2135 * Return: QDF_STATUS 2136 */ 2137 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 2138 uint8_t *macaddr, 2139 uint8_t mac_id, 2140 uint8_t enb_dsb) 2141 { 2142 int32_t ret; 2143 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 2144 wmi_pdev_pktlog_filter_info *mac_info; 2145 wmi_buf_t buf; 2146 uint8_t *buf_ptr; 2147 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 2148 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 2149 2150 buf = wmi_buf_alloc(wmi_handle, len); 2151 if (!buf) 2152 return QDF_STATUS_E_NOMEM; 2153 2154 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2155 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 2156 WMITLV_SET_HDR(&cmd->tlv_header, 2157 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 2158 WMITLV_GET_STRUCT_TLVLEN 2159 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 2160 cmd->pdev_id = mac_id; 2161 cmd->enable = enb_dsb; 2162 cmd->num_of_mac_addresses = 1; 2163 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 2164 2165 buf_ptr += sizeof(*cmd); 2166 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2167 sizeof(wmi_pdev_pktlog_filter_info)); 2168 buf_ptr += WMI_TLV_HDR_SIZE; 2169 2170 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 2171 2172 WMITLV_SET_HDR(&mac_info->tlv_header, 2173 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 2174 WMITLV_GET_STRUCT_TLVLEN 2175 (wmi_pdev_pktlog_filter_info)); 2176 2177 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 2178 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2179 WMI_PDEV_PKTLOG_FILTER_CMDID); 2180 if (ret) { 2181 wmi_err("Failed to send peer based pktlog command to FW =%d" 2182 , ret); 2183 wmi_buf_free(buf); 2184 } 2185 2186 return ret; 2187 } 2188 2189 /** 2190 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 2191 * @param wmi_handle : handle to WMI. 2192 * @param PKTLOG_EVENT : packet log event 2193 * @mac_id: mac id to have radio context 2194 * 2195 * Return: 0 on success and -ve on failure. 2196 */ 2197 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 2198 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 2199 { 2200 int32_t ret, idx, max_idx; 2201 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 2202 wmi_buf_t buf; 2203 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 2204 2205 buf = wmi_buf_alloc(wmi_handle, len); 2206 if (!buf) 2207 return -QDF_STATUS_E_NOMEM; 2208 2209 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 2210 WMITLV_SET_HDR(&cmd->tlv_header, 2211 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 2212 WMITLV_GET_STRUCT_TLVLEN 2213 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 2214 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 2215 cmd->evlist = 0; 2216 for (idx = 0; idx < max_idx; idx++) { 2217 if (PKTLOG_EVENT & (1 << idx)) 2218 cmd->evlist |= pktlog_event_tlv[idx]; 2219 } 2220 cmd->pdev_id = mac_id; 2221 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 2222 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2223 WMI_PDEV_PKTLOG_ENABLE_CMDID); 2224 if (ret) { 2225 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 2226 wmi_buf_free(buf); 2227 } 2228 2229 return ret; 2230 } 2231 2232 /** 2233 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 2234 * @param wmi_handle : handle to WMI. 2235 * @mac_id: mac id to have radio context 2236 * 2237 * Return: 0 on success and -ve on failure. 2238 */ 2239 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 2240 uint8_t mac_id) 2241 { 2242 int32_t ret; 2243 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 2244 wmi_buf_t buf; 2245 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 2246 2247 buf = wmi_buf_alloc(wmi_handle, len); 2248 if (!buf) 2249 return -QDF_STATUS_E_NOMEM; 2250 2251 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 2252 WMITLV_SET_HDR(&cmd->tlv_header, 2253 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 2254 WMITLV_GET_STRUCT_TLVLEN 2255 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 2256 cmd->pdev_id = mac_id; 2257 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 2258 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2259 WMI_PDEV_PKTLOG_DISABLE_CMDID); 2260 if (ret) { 2261 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 2262 wmi_buf_free(buf); 2263 } 2264 2265 return ret; 2266 } 2267 2268 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 2269 /** 2270 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 2271 * sync time between bwtween host and firmware 2272 * @param wmi_handle : handle to WMI. 2273 * 2274 * Return: None 2275 */ 2276 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 2277 { 2278 wmi_buf_t buf; 2279 QDF_STATUS status = QDF_STATUS_SUCCESS; 2280 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 2281 int32_t len; 2282 qdf_time_t time_ms; 2283 2284 len = sizeof(*time_stamp); 2285 buf = wmi_buf_alloc(wmi_handle, len); 2286 2287 if (!buf) 2288 return; 2289 2290 time_stamp = 2291 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 2292 (wmi_buf_data(buf)); 2293 WMITLV_SET_HDR(&time_stamp->tlv_header, 2294 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 2295 WMITLV_GET_STRUCT_TLVLEN( 2296 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 2297 2298 time_ms = qdf_get_time_of_the_day_ms(); 2299 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 2300 time_stamp->time_stamp_low = time_ms & 2301 WMI_FW_TIME_STAMP_LOW_MASK; 2302 /* 2303 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 2304 * wont exceed 27 bit 2305 */ 2306 time_stamp->time_stamp_high = 0; 2307 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 2308 time_stamp->mode, time_stamp->time_stamp_low, 2309 time_stamp->time_stamp_high); 2310 2311 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 2312 status = wmi_unified_cmd_send(wmi_handle, buf, 2313 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 2314 if (status) { 2315 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 2316 wmi_buf_free(buf); 2317 } 2318 2319 } 2320 2321 /** 2322 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 2323 * @param wmi_handle : handle to WMI. 2324 * @param param : pointer to hold FILS Discovery send cmd parameter 2325 * 2326 * Return: 0 on success and -ve on failure. 2327 */ 2328 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 2329 struct fils_discovery_tmpl_params *param) 2330 { 2331 int32_t ret; 2332 wmi_fd_tmpl_cmd_fixed_param *cmd; 2333 wmi_buf_t wmi_buf; 2334 uint8_t *buf_ptr; 2335 uint32_t wmi_buf_len; 2336 2337 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 2338 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 2339 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2340 if (!wmi_buf) 2341 return QDF_STATUS_E_NOMEM; 2342 2343 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2344 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 2345 WMITLV_SET_HDR(&cmd->tlv_header, 2346 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 2347 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 2348 cmd->vdev_id = param->vdev_id; 2349 cmd->buf_len = param->tmpl_len; 2350 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 2351 2352 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2353 buf_ptr += WMI_TLV_HDR_SIZE; 2354 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2355 2356 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 2357 ret = wmi_unified_cmd_send(wmi_handle, 2358 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 2359 2360 if (ret) { 2361 wmi_err("Failed to send fd tmpl: %d", ret); 2362 wmi_buf_free(wmi_buf); 2363 return ret; 2364 } 2365 2366 return 0; 2367 } 2368 2369 /** 2370 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2371 * @param wmi_handle : handle to WMI. 2372 * @param param : pointer to hold beacon send cmd parameter 2373 * 2374 * Return: 0 on success and -ve on failure. 2375 */ 2376 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2377 struct beacon_tmpl_params *param) 2378 { 2379 int32_t ret; 2380 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2381 wmi_bcn_prb_info *bcn_prb_info; 2382 wmi_buf_t wmi_buf; 2383 uint8_t *buf_ptr; 2384 uint32_t wmi_buf_len; 2385 2386 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2387 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2388 param->tmpl_len_aligned; 2389 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2390 if (!wmi_buf) 2391 return QDF_STATUS_E_NOMEM; 2392 2393 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2394 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2395 WMITLV_SET_HDR(&cmd->tlv_header, 2396 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2397 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2398 cmd->vdev_id = param->vdev_id; 2399 cmd->tim_ie_offset = param->tim_ie_offset; 2400 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 2401 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2402 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2403 cmd->esp_ie_offset = param->esp_ie_offset; 2404 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 2405 cmd->ema_params = param->ema_params; 2406 cmd->buf_len = param->tmpl_len; 2407 2408 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 2409 param->enable_bigtk); 2410 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2411 2412 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2413 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2414 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2415 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2416 bcn_prb_info->caps = 0; 2417 bcn_prb_info->erp = 0; 2418 buf_ptr += sizeof(wmi_bcn_prb_info); 2419 2420 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2421 buf_ptr += WMI_TLV_HDR_SIZE; 2422 2423 /* for big endian host, copy engine byte_swap is enabled 2424 * But the frame content is in network byte order 2425 * Need to byte swap the frame content - so when copy engine 2426 * does byte_swap - target gets frame content in the correct order 2427 */ 2428 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 2429 param->tmpl_len); 2430 2431 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 2432 ret = wmi_unified_cmd_send(wmi_handle, 2433 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2434 if (ret) { 2435 wmi_err("Failed to send bcn tmpl: %d", ret); 2436 wmi_buf_free(wmi_buf); 2437 } 2438 2439 return 0; 2440 } 2441 2442 static inline void copy_peer_flags_tlv( 2443 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2444 struct peer_assoc_params *param) 2445 { 2446 /* 2447 * The target only needs a subset of the flags maintained in the host. 2448 * Just populate those flags and send it down 2449 */ 2450 cmd->peer_flags = 0; 2451 2452 /* 2453 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2454 */ 2455 if (param->is_wme_set) { 2456 2457 if (param->qos_flag) 2458 cmd->peer_flags |= WMI_PEER_QOS; 2459 if (param->apsd_flag) 2460 cmd->peer_flags |= WMI_PEER_APSD; 2461 if (param->ht_flag) 2462 cmd->peer_flags |= WMI_PEER_HT; 2463 if (param->bw_40) 2464 cmd->peer_flags |= WMI_PEER_40MHZ; 2465 if (param->bw_80) 2466 cmd->peer_flags |= WMI_PEER_80MHZ; 2467 if (param->bw_160) 2468 cmd->peer_flags |= WMI_PEER_160MHZ; 2469 2470 /* Typically if STBC is enabled for VHT it should be enabled 2471 * for HT as well 2472 **/ 2473 if (param->stbc_flag) 2474 cmd->peer_flags |= WMI_PEER_STBC; 2475 2476 /* Typically if LDPC is enabled for VHT it should be enabled 2477 * for HT as well 2478 **/ 2479 if (param->ldpc_flag) 2480 cmd->peer_flags |= WMI_PEER_LDPC; 2481 2482 if (param->static_mimops_flag) 2483 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2484 if (param->dynamic_mimops_flag) 2485 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2486 if (param->spatial_mux_flag) 2487 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2488 if (param->vht_flag) 2489 cmd->peer_flags |= WMI_PEER_VHT; 2490 if (param->he_flag) 2491 cmd->peer_flags |= WMI_PEER_HE; 2492 if (param->p2p_capable_sta) 2493 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 2494 } 2495 2496 if (param->is_pmf_enabled) 2497 cmd->peer_flags |= WMI_PEER_PMF; 2498 /* 2499 * Suppress authorization for all AUTH modes that need 4-way handshake 2500 * (during re-association). 2501 * Authorization will be done for these modes on key installation. 2502 */ 2503 if (param->auth_flag) 2504 cmd->peer_flags |= WMI_PEER_AUTH; 2505 if (param->need_ptk_4_way) 2506 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2507 else 2508 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2509 if (param->need_gtk_2_way) 2510 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2511 /* safe mode bypass the 4-way handshake */ 2512 if (param->safe_mode_enabled) 2513 cmd->peer_flags &= 2514 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2515 /* inter BSS peer */ 2516 if (param->inter_bss_peer) 2517 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 2518 /* Disable AMSDU for station transmit, if user configures it */ 2519 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2520 * it 2521 * if (param->amsdu_disable) Add after FW support 2522 **/ 2523 2524 /* Target asserts if node is marked HT and all MCS is set to 0. 2525 * Mark the node as non-HT if all the mcs rates are disabled through 2526 * iwpriv 2527 **/ 2528 if (param->peer_ht_rates.num_rates == 0) 2529 cmd->peer_flags &= ~WMI_PEER_HT; 2530 2531 if (param->twt_requester) 2532 cmd->peer_flags |= WMI_PEER_TWT_REQ; 2533 2534 if (param->twt_responder) 2535 cmd->peer_flags |= WMI_PEER_TWT_RESP; 2536 } 2537 2538 static inline void copy_peer_mac_addr_tlv( 2539 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2540 struct peer_assoc_params *param) 2541 { 2542 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2543 } 2544 2545 /** 2546 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2547 * @param wmi_handle : handle to WMI. 2548 * @param param : pointer to peer assoc parameter 2549 * 2550 * Return: 0 on success and -ve on failure. 2551 */ 2552 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2553 struct peer_assoc_params *param) 2554 { 2555 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2556 wmi_vht_rate_set *mcs; 2557 wmi_he_rate_set *he_mcs; 2558 wmi_buf_t buf; 2559 int32_t len; 2560 uint8_t *buf_ptr; 2561 QDF_STATUS ret; 2562 uint32_t peer_legacy_rates_align; 2563 uint32_t peer_ht_rates_align; 2564 int32_t i; 2565 2566 2567 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2568 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2569 2570 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2571 (peer_legacy_rates_align * sizeof(uint8_t)) + 2572 WMI_TLV_HDR_SIZE + 2573 (peer_ht_rates_align * sizeof(uint8_t)) + 2574 sizeof(wmi_vht_rate_set) + 2575 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2576 + WMI_TLV_HDR_SIZE); 2577 2578 buf = wmi_buf_alloc(wmi_handle, len); 2579 if (!buf) 2580 return QDF_STATUS_E_NOMEM; 2581 2582 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2583 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2584 WMITLV_SET_HDR(&cmd->tlv_header, 2585 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2586 WMITLV_GET_STRUCT_TLVLEN 2587 (wmi_peer_assoc_complete_cmd_fixed_param)); 2588 2589 cmd->vdev_id = param->vdev_id; 2590 2591 cmd->peer_new_assoc = param->peer_new_assoc; 2592 cmd->peer_associd = param->peer_associd; 2593 2594 copy_peer_flags_tlv(cmd, param); 2595 copy_peer_mac_addr_tlv(cmd, param); 2596 2597 cmd->peer_rate_caps = param->peer_rate_caps; 2598 cmd->peer_caps = param->peer_caps; 2599 cmd->peer_listen_intval = param->peer_listen_intval; 2600 cmd->peer_ht_caps = param->peer_ht_caps; 2601 cmd->peer_max_mpdu = param->peer_max_mpdu; 2602 cmd->peer_mpdu_density = param->peer_mpdu_density; 2603 cmd->peer_vht_caps = param->peer_vht_caps; 2604 cmd->peer_phymode = param->peer_phymode; 2605 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 2606 2607 /* Update 11ax capabilities */ 2608 cmd->peer_he_cap_info = 2609 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 2610 cmd->peer_he_cap_info_ext = 2611 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 2612 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 2613 cmd->peer_he_ops = param->peer_he_ops; 2614 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2615 sizeof(param->peer_he_cap_phyinfo)); 2616 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2617 sizeof(param->peer_ppet)); 2618 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 2619 2620 /* Update peer legacy rate information */ 2621 buf_ptr += sizeof(*cmd); 2622 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2623 peer_legacy_rates_align); 2624 buf_ptr += WMI_TLV_HDR_SIZE; 2625 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2626 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2627 param->peer_legacy_rates.num_rates); 2628 2629 /* Update peer HT rate information */ 2630 buf_ptr += peer_legacy_rates_align; 2631 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2632 peer_ht_rates_align); 2633 buf_ptr += WMI_TLV_HDR_SIZE; 2634 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2635 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2636 param->peer_ht_rates.num_rates); 2637 2638 /* VHT Rates */ 2639 buf_ptr += peer_ht_rates_align; 2640 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2641 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2642 2643 cmd->peer_nss = param->peer_nss; 2644 2645 /* Update bandwidth-NSS mapping */ 2646 cmd->peer_bw_rxnss_override = 0; 2647 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2648 2649 mcs = (wmi_vht_rate_set *) buf_ptr; 2650 if (param->vht_capable) { 2651 mcs->rx_max_rate = param->rx_max_rate; 2652 mcs->rx_mcs_set = param->rx_mcs_set; 2653 mcs->tx_max_rate = param->tx_max_rate; 2654 mcs->tx_mcs_set = param->tx_mcs_set; 2655 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 2656 } 2657 2658 /* HE Rates */ 2659 cmd->min_data_rate = param->min_data_rate; 2660 cmd->peer_he_mcs = param->peer_he_mcs_count; 2661 buf_ptr += sizeof(wmi_vht_rate_set); 2662 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2663 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2664 buf_ptr += WMI_TLV_HDR_SIZE; 2665 2666 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 2667 /* Loop through the HE rate set */ 2668 for (i = 0; i < param->peer_he_mcs_count; i++) { 2669 he_mcs = (wmi_he_rate_set *) buf_ptr; 2670 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2671 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2672 2673 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2674 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2675 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 2676 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2677 buf_ptr += sizeof(wmi_he_rate_set); 2678 } 2679 2680 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 2681 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 2682 == WMI_HOST_HE_INVALID_MCSNSSMAP || 2683 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 2684 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 2685 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 2686 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2687 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 2688 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2689 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 2690 QDF_MAC_ADDR_REF(param->peer_mac)); 2691 } 2692 2693 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 2694 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2695 "nss %d phymode %d peer_mpdu_density %d " 2696 "cmd->peer_vht_caps %x " 2697 "HE cap_info %x ops %x " 2698 "HE cap_info_ext %x " 2699 "HE phy %x %x %x " 2700 "peer_bw_rxnss_override %x", 2701 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2702 cmd->peer_rate_caps, cmd->peer_caps, 2703 cmd->peer_listen_intval, cmd->peer_ht_caps, 2704 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2705 cmd->peer_mpdu_density, 2706 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2707 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 2708 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 2709 cmd->peer_he_cap_phy[2], 2710 cmd->peer_bw_rxnss_override); 2711 2712 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 2713 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2714 WMI_PEER_ASSOC_CMDID); 2715 if (QDF_IS_STATUS_ERROR(ret)) { 2716 wmi_err("Failed to send peer assoc command ret = %d", ret); 2717 wmi_buf_free(buf); 2718 } 2719 2720 return ret; 2721 } 2722 2723 /* copy_scan_notify_events() - Helper routine to copy scan notify events 2724 */ 2725 static inline void copy_scan_event_cntrl_flags( 2726 wmi_start_scan_cmd_fixed_param * cmd, 2727 struct scan_req_params *param) 2728 { 2729 2730 /* Scan events subscription */ 2731 if (param->scan_ev_started) 2732 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 2733 if (param->scan_ev_completed) 2734 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 2735 if (param->scan_ev_bss_chan) 2736 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 2737 if (param->scan_ev_foreign_chan) 2738 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 2739 if (param->scan_ev_dequeued) 2740 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 2741 if (param->scan_ev_preempted) 2742 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 2743 if (param->scan_ev_start_failed) 2744 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 2745 if (param->scan_ev_restarted) 2746 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 2747 if (param->scan_ev_foreign_chn_exit) 2748 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 2749 if (param->scan_ev_suspended) 2750 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 2751 if (param->scan_ev_resumed) 2752 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 2753 2754 /** Set scan control flags */ 2755 cmd->scan_ctrl_flags = 0; 2756 if (param->scan_f_passive) 2757 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 2758 if (param->scan_f_strict_passive_pch) 2759 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2760 if (param->scan_f_promisc_mode) 2761 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 2762 if (param->scan_f_capture_phy_err) 2763 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2764 if (param->scan_f_half_rate) 2765 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2766 if (param->scan_f_quarter_rate) 2767 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2768 if (param->scan_f_cck_rates) 2769 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2770 if (param->scan_f_ofdm_rates) 2771 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2772 if (param->scan_f_chan_stat_evnt) 2773 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2774 if (param->scan_f_filter_prb_req) 2775 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2776 if (param->scan_f_bcast_probe) 2777 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2778 if (param->scan_f_offchan_mgmt_tx) 2779 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2780 if (param->scan_f_offchan_data_tx) 2781 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2782 if (param->scan_f_force_active_dfs_chn) 2783 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2784 if (param->scan_f_add_tpc_ie_in_probe) 2785 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2786 if (param->scan_f_add_ds_ie_in_probe) 2787 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2788 if (param->scan_f_add_spoofed_mac_in_probe) 2789 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 2790 if (param->scan_f_add_rand_seq_in_probe) 2791 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2792 if (param->scan_f_en_ie_whitelist_in_probe) 2793 cmd->scan_ctrl_flags |= 2794 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2795 2796 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2797 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2798 param->adaptive_dwell_time_mode); 2799 } 2800 2801 /* scan_copy_ie_buffer() - Copy scan ie_data */ 2802 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 2803 struct scan_req_params *params) 2804 { 2805 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 2806 } 2807 2808 /** 2809 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 2810 * @mac: random mac addr 2811 * @mask: random mac mask 2812 * @mac_addr: wmi random mac 2813 * @mac_mask: wmi random mac mask 2814 * 2815 * Return None. 2816 */ 2817 static inline 2818 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 2819 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 2820 { 2821 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 2822 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 2823 } 2824 2825 /* 2826 * wmi_fill_vendor_oui() - fill vendor OUIs 2827 * @buf_ptr: pointer to wmi tlv buffer 2828 * @num_vendor_oui: number of vendor OUIs to be filled 2829 * @param_voui: pointer to OUI buffer 2830 * 2831 * This function populates the wmi tlv buffer when vendor specific OUIs are 2832 * present. 2833 * 2834 * Return: None 2835 */ 2836 static inline 2837 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 2838 uint32_t *pvoui) 2839 { 2840 wmi_vendor_oui *voui = NULL; 2841 uint32_t i; 2842 2843 voui = (wmi_vendor_oui *)buf_ptr; 2844 2845 for (i = 0; i < num_vendor_oui; i++) { 2846 WMITLV_SET_HDR(&voui[i].tlv_header, 2847 WMITLV_TAG_STRUC_wmi_vendor_oui, 2848 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 2849 voui[i].oui_type_subtype = pvoui[i]; 2850 } 2851 } 2852 2853 /* 2854 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 2855 * @ie_bitmap: output pointer to ie bit map in cmd 2856 * @num_vendor_oui: output pointer to num vendor OUIs 2857 * @ie_whitelist: input parameter 2858 * 2859 * This function populates the IE whitelist attrs of scan, pno and 2860 * scan oui commands for ie_whitelist parameter. 2861 * 2862 * Return: None 2863 */ 2864 static inline 2865 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 2866 uint32_t *num_vendor_oui, 2867 struct probe_req_whitelist_attr *ie_whitelist) 2868 { 2869 uint32_t i = 0; 2870 2871 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 2872 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 2873 2874 *num_vendor_oui = ie_whitelist->num_vendor_oui; 2875 } 2876 2877 /** 2878 * send_scan_start_cmd_tlv() - WMI scan start function 2879 * @param wmi_handle : handle to WMI. 2880 * @param param : pointer to hold scan start cmd parameter 2881 * 2882 * Return: 0 on success and -ve on failure. 2883 */ 2884 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 2885 struct scan_req_params *params) 2886 { 2887 int32_t ret = 0; 2888 int32_t i; 2889 wmi_buf_t wmi_buf; 2890 wmi_start_scan_cmd_fixed_param *cmd; 2891 uint8_t *buf_ptr; 2892 uint32_t *tmp_ptr; 2893 wmi_ssid *ssid = NULL; 2894 wmi_mac_addr *bssid; 2895 size_t len = sizeof(*cmd); 2896 uint16_t extraie_len_with_pad = 0; 2897 uint8_t phymode_roundup = 0; 2898 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 2899 wmi_hint_freq_short_ssid *s_ssid = NULL; 2900 wmi_hint_freq_bssid *hint_bssid = NULL; 2901 2902 /* Length TLV placeholder for array of uint32_t */ 2903 len += WMI_TLV_HDR_SIZE; 2904 /* calculate the length of buffer required */ 2905 if (params->chan_list.num_chan) 2906 len += params->chan_list.num_chan * sizeof(uint32_t); 2907 2908 /* Length TLV placeholder for array of wmi_ssid structures */ 2909 len += WMI_TLV_HDR_SIZE; 2910 if (params->num_ssids) 2911 len += params->num_ssids * sizeof(wmi_ssid); 2912 2913 /* Length TLV placeholder for array of wmi_mac_addr structures */ 2914 len += WMI_TLV_HDR_SIZE; 2915 if (params->num_bssid) 2916 len += sizeof(wmi_mac_addr) * params->num_bssid; 2917 2918 /* Length TLV placeholder for array of bytes */ 2919 len += WMI_TLV_HDR_SIZE; 2920 if (params->extraie.len) 2921 extraie_len_with_pad = 2922 roundup(params->extraie.len, sizeof(uint32_t)); 2923 len += extraie_len_with_pad; 2924 2925 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 2926 if (ie_whitelist->num_vendor_oui) 2927 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 2928 2929 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 2930 if (params->scan_f_wide_band) 2931 phymode_roundup = 2932 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 2933 sizeof(uint32_t)); 2934 len += phymode_roundup; 2935 2936 len += WMI_TLV_HDR_SIZE; 2937 if (params->num_hint_bssid) 2938 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 2939 2940 len += WMI_TLV_HDR_SIZE; 2941 if (params->num_hint_s_ssid) 2942 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 2943 2944 /* Allocate the memory */ 2945 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2946 if (!wmi_buf) 2947 return QDF_STATUS_E_FAILURE; 2948 2949 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2950 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 2951 WMITLV_SET_HDR(&cmd->tlv_header, 2952 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 2953 WMITLV_GET_STRUCT_TLVLEN 2954 (wmi_start_scan_cmd_fixed_param)); 2955 2956 cmd->scan_id = params->scan_id; 2957 cmd->scan_req_id = params->scan_req_id; 2958 cmd->vdev_id = params->vdev_id; 2959 cmd->scan_priority = params->scan_priority; 2960 2961 copy_scan_event_cntrl_flags(cmd, params); 2962 2963 cmd->dwell_time_active = params->dwell_time_active; 2964 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 2965 cmd->dwell_time_passive = params->dwell_time_passive; 2966 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 2967 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 2968 cmd->scan_start_offset = params->scan_offset_time; 2969 cmd->min_rest_time = params->min_rest_time; 2970 cmd->max_rest_time = params->max_rest_time; 2971 cmd->repeat_probe_time = params->repeat_probe_time; 2972 cmd->probe_spacing_time = params->probe_spacing_time; 2973 cmd->idle_time = params->idle_time; 2974 cmd->max_scan_time = params->max_scan_time; 2975 cmd->probe_delay = params->probe_delay; 2976 cmd->burst_duration = params->burst_duration; 2977 cmd->num_chan = params->chan_list.num_chan; 2978 cmd->num_bssid = params->num_bssid; 2979 cmd->num_ssids = params->num_ssids; 2980 cmd->ie_len = params->extraie.len; 2981 cmd->n_probes = params->n_probes; 2982 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 2983 2984 if (params->scan_random.randomize) 2985 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 2986 params->scan_random.mac_mask, 2987 &cmd->mac_addr, 2988 &cmd->mac_mask); 2989 2990 if (ie_whitelist->white_list) 2991 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 2992 &cmd->num_vendor_oui, 2993 ie_whitelist); 2994 2995 buf_ptr += sizeof(*cmd); 2996 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2997 for (i = 0; i < params->chan_list.num_chan; ++i) { 2998 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 2999 params->chan_list.chan[i].freq); 3000 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 3001 params->chan_list.chan[i].flags); 3002 } 3003 3004 WMITLV_SET_HDR(buf_ptr, 3005 WMITLV_TAG_ARRAY_UINT32, 3006 (params->chan_list.num_chan * sizeof(uint32_t))); 3007 buf_ptr += WMI_TLV_HDR_SIZE + 3008 (params->chan_list.num_chan * sizeof(uint32_t)); 3009 3010 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 3011 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 3012 goto error; 3013 } 3014 3015 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3016 (params->num_ssids * sizeof(wmi_ssid))); 3017 3018 if (params->num_ssids) { 3019 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 3020 for (i = 0; i < params->num_ssids; ++i) { 3021 ssid->ssid_len = params->ssid[i].length; 3022 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 3023 params->ssid[i].length); 3024 ssid++; 3025 } 3026 } 3027 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 3028 3029 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3030 (params->num_bssid * sizeof(wmi_mac_addr))); 3031 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 3032 3033 if (params->num_bssid) { 3034 for (i = 0; i < params->num_bssid; ++i) { 3035 WMI_CHAR_ARRAY_TO_MAC_ADDR( 3036 ¶ms->bssid_list[i].bytes[0], bssid); 3037 bssid++; 3038 } 3039 } 3040 3041 buf_ptr += WMI_TLV_HDR_SIZE + 3042 (params->num_bssid * sizeof(wmi_mac_addr)); 3043 3044 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 3045 if (params->extraie.len) 3046 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 3047 params); 3048 3049 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 3050 3051 /* probe req ie whitelisting */ 3052 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3053 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 3054 3055 buf_ptr += WMI_TLV_HDR_SIZE; 3056 3057 if (cmd->num_vendor_oui) { 3058 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 3059 ie_whitelist->voui); 3060 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 3061 } 3062 3063 /* Add phy mode TLV if it's a wide band scan */ 3064 if (params->scan_f_wide_band) { 3065 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 3066 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3067 for (i = 0; i < params->chan_list.num_chan; ++i) 3068 buf_ptr[i] = 3069 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 3070 buf_ptr += phymode_roundup; 3071 } else { 3072 /* Add ZERO legth phy mode TLV */ 3073 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 3074 buf_ptr += WMI_TLV_HDR_SIZE; 3075 } 3076 3077 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3078 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 3079 if (params->num_hint_s_ssid) { 3080 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3081 for (i = 0; i < params->num_hint_s_ssid; ++i) { 3082 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 3083 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 3084 s_ssid++; 3085 } 3086 } 3087 buf_ptr += WMI_TLV_HDR_SIZE + 3088 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 3089 3090 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3091 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 3092 if (params->num_hint_bssid) { 3093 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3094 for (i = 0; i < params->num_hint_bssid; ++i) { 3095 hint_bssid->freq_flags = 3096 params->hint_bssid[i].freq_flags; 3097 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 3098 &hint_bssid->bssid); 3099 hint_bssid++; 3100 } 3101 } 3102 3103 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 3104 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3105 len, WMI_START_SCAN_CMDID); 3106 if (ret) { 3107 wmi_err("Failed to start scan: %d", ret); 3108 wmi_buf_free(wmi_buf); 3109 } 3110 return ret; 3111 error: 3112 wmi_buf_free(wmi_buf); 3113 return QDF_STATUS_E_FAILURE; 3114 } 3115 3116 /** 3117 * send_scan_stop_cmd_tlv() - WMI scan start function 3118 * @param wmi_handle : handle to WMI. 3119 * @param param : pointer to hold scan cancel cmd parameter 3120 * 3121 * Return: 0 on success and -ve on failure. 3122 */ 3123 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 3124 struct scan_cancel_param *param) 3125 { 3126 wmi_stop_scan_cmd_fixed_param *cmd; 3127 int ret; 3128 int len = sizeof(*cmd); 3129 wmi_buf_t wmi_buf; 3130 3131 /* Allocate the memory */ 3132 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3133 if (!wmi_buf) { 3134 ret = QDF_STATUS_E_NOMEM; 3135 goto error; 3136 } 3137 3138 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 3139 WMITLV_SET_HDR(&cmd->tlv_header, 3140 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 3141 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 3142 cmd->vdev_id = param->vdev_id; 3143 cmd->requestor = param->requester; 3144 cmd->scan_id = param->scan_id; 3145 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3146 wmi_handle, 3147 param->pdev_id); 3148 /* stop the scan with the corresponding scan_id */ 3149 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 3150 /* Cancelling all scans */ 3151 cmd->req_type = WMI_SCAN_STOP_ALL; 3152 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 3153 /* Cancelling VAP scans */ 3154 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 3155 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 3156 /* Cancelling specific scan */ 3157 cmd->req_type = WMI_SCAN_STOP_ONE; 3158 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 3159 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 3160 } else { 3161 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 3162 wmi_buf_free(wmi_buf); 3163 return QDF_STATUS_E_INVAL; 3164 } 3165 3166 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 3167 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3168 len, WMI_STOP_SCAN_CMDID); 3169 if (ret) { 3170 wmi_err("Failed to send stop scan: %d", ret); 3171 wmi_buf_free(wmi_buf); 3172 } 3173 3174 error: 3175 return ret; 3176 } 3177 3178 #define WMI_MAX_CHAN_INFO_LOG 192 3179 3180 /** 3181 * wmi_scan_chanlist_dump() - Dump scan channel list info 3182 * @scan_chan_list: scan channel list 3183 * 3184 * Return: void 3185 */ 3186 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 3187 { 3188 uint32_t i; 3189 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 3190 uint32_t len = 0; 3191 struct channel_param *chan; 3192 int ret; 3193 3194 wmi_debug("Total chan %d", scan_chan_list->nallchans); 3195 for (i = 0; i < scan_chan_list->nallchans; i++) { 3196 chan = &scan_chan_list->ch_param[i]; 3197 ret = qdf_scnprintf(info + len, sizeof(info) - len, 3198 " %d[%d][%d]", chan->mhz, chan->maxregpower, 3199 chan->dfs_set); 3200 if (ret <= 0) 3201 break; 3202 len += ret; 3203 if (len >= (sizeof(info) - 20)) { 3204 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 3205 len = 0; 3206 } 3207 } 3208 if (len) 3209 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 3210 } 3211 3212 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 3213 struct scan_chan_list_params *chan_list) 3214 { 3215 wmi_buf_t buf; 3216 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 3217 wmi_scan_chan_list_cmd_fixed_param *cmd; 3218 int i; 3219 uint8_t *buf_ptr; 3220 wmi_channel *chan_info; 3221 struct channel_param *tchan_info; 3222 uint16_t len; 3223 uint16_t num_send_chans, num_sends = 0; 3224 3225 wmi_scan_chanlist_dump(chan_list); 3226 tchan_info = &chan_list->ch_param[0]; 3227 while (chan_list->nallchans) { 3228 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 3229 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 3230 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 3231 else 3232 num_send_chans = chan_list->nallchans; 3233 3234 chan_list->nallchans -= num_send_chans; 3235 len += sizeof(wmi_channel) * num_send_chans; 3236 buf = wmi_buf_alloc(wmi_handle, len); 3237 if (!buf) { 3238 qdf_status = QDF_STATUS_E_NOMEM; 3239 goto end; 3240 } 3241 3242 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3243 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 3244 WMITLV_SET_HDR(&cmd->tlv_header, 3245 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 3246 WMITLV_GET_STRUCT_TLVLEN 3247 (wmi_scan_chan_list_cmd_fixed_param)); 3248 3249 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 3250 3251 if (num_sends) 3252 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 3253 3254 if (chan_list->max_bw_support_present) 3255 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 3256 3257 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3258 wmi_handle, 3259 chan_list->pdev_id); 3260 3261 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 3262 3263 cmd->num_scan_chans = num_send_chans; 3264 WMITLV_SET_HDR((buf_ptr + 3265 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 3266 WMITLV_TAG_ARRAY_STRUC, 3267 sizeof(wmi_channel) * num_send_chans); 3268 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 3269 WMI_TLV_HDR_SIZE); 3270 3271 for (i = 0; i < num_send_chans; ++i) { 3272 WMITLV_SET_HDR(&chan_info->tlv_header, 3273 WMITLV_TAG_STRUC_wmi_channel, 3274 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 3275 chan_info->mhz = tchan_info->mhz; 3276 chan_info->band_center_freq1 = 3277 tchan_info->cfreq1; 3278 chan_info->band_center_freq2 = 3279 tchan_info->cfreq2; 3280 3281 if (tchan_info->is_chan_passive) 3282 WMI_SET_CHANNEL_FLAG(chan_info, 3283 WMI_CHAN_FLAG_PASSIVE); 3284 if (tchan_info->dfs_set) 3285 WMI_SET_CHANNEL_FLAG(chan_info, 3286 WMI_CHAN_FLAG_DFS); 3287 3288 if (tchan_info->dfs_set_cfreq2) 3289 WMI_SET_CHANNEL_FLAG(chan_info, 3290 WMI_CHAN_FLAG_DFS_CFREQ2); 3291 3292 if (tchan_info->allow_he) 3293 WMI_SET_CHANNEL_FLAG(chan_info, 3294 WMI_CHAN_FLAG_ALLOW_HE); 3295 3296 if (tchan_info->allow_vht) 3297 WMI_SET_CHANNEL_FLAG(chan_info, 3298 WMI_CHAN_FLAG_ALLOW_VHT); 3299 3300 if (tchan_info->allow_ht) 3301 WMI_SET_CHANNEL_FLAG(chan_info, 3302 WMI_CHAN_FLAG_ALLOW_HT); 3303 WMI_SET_CHANNEL_MODE(chan_info, 3304 tchan_info->phy_mode); 3305 3306 if (tchan_info->half_rate) 3307 WMI_SET_CHANNEL_FLAG(chan_info, 3308 WMI_CHAN_FLAG_HALF_RATE); 3309 3310 if (tchan_info->quarter_rate) 3311 WMI_SET_CHANNEL_FLAG(chan_info, 3312 WMI_CHAN_FLAG_QUARTER_RATE); 3313 3314 if (tchan_info->psc_channel) 3315 WMI_SET_CHANNEL_FLAG(chan_info, 3316 WMI_CHAN_FLAG_PSC); 3317 3318 if (tchan_info->nan_disabled) 3319 WMI_SET_CHANNEL_FLAG(chan_info, 3320 WMI_CHAN_FLAG_NAN_DISABLED); 3321 3322 /* also fill in power information */ 3323 WMI_SET_CHANNEL_MIN_POWER(chan_info, 3324 tchan_info->minpower); 3325 WMI_SET_CHANNEL_MAX_POWER(chan_info, 3326 tchan_info->maxpower); 3327 WMI_SET_CHANNEL_REG_POWER(chan_info, 3328 tchan_info->maxregpower); 3329 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 3330 tchan_info->antennamax); 3331 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 3332 tchan_info->reg_class_id); 3333 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 3334 tchan_info->maxregpower); 3335 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 3336 tchan_info->max_bw_supported); 3337 3338 tchan_info++; 3339 chan_info++; 3340 } 3341 3342 qdf_status = wmi_unified_cmd_send( 3343 wmi_handle, 3344 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 3345 3346 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3347 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 3348 wmi_buf_free(buf); 3349 goto end; 3350 } 3351 num_sends++; 3352 } 3353 3354 end: 3355 return qdf_status; 3356 } 3357 3358 /** 3359 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3360 * 3361 * @bufp: Pointer to buffer 3362 * @param: Pointer to tx param 3363 * 3364 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3365 */ 3366 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3367 struct tx_send_params param) 3368 { 3369 wmi_tx_send_params *tx_param; 3370 QDF_STATUS status = QDF_STATUS_SUCCESS; 3371 3372 if (!bufp) { 3373 status = QDF_STATUS_E_FAILURE; 3374 return status; 3375 } 3376 tx_param = (wmi_tx_send_params *)bufp; 3377 WMITLV_SET_HDR(&tx_param->tlv_header, 3378 WMITLV_TAG_STRUC_wmi_tx_send_params, 3379 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3380 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3381 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3382 param.mcs_mask); 3383 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3384 param.nss_mask); 3385 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3386 param.retry_limit); 3387 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3388 param.chain_mask); 3389 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3390 param.bw_mask); 3391 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3392 param.preamble_type); 3393 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3394 param.frame_type); 3395 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 3396 param.cfr_enable); 3397 3398 return status; 3399 } 3400 3401 #ifdef CONFIG_HL_SUPPORT 3402 /** 3403 * send_mgmt_cmd_tlv() - WMI scan start function 3404 * @wmi_handle : handle to WMI. 3405 * @param : pointer to hold mgmt cmd parameter 3406 * 3407 * Return: 0 on success and -ve on failure. 3408 */ 3409 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3410 struct wmi_mgmt_params *param) 3411 { 3412 wmi_buf_t buf; 3413 uint8_t *bufp; 3414 int32_t cmd_len; 3415 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3416 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3417 mgmt_tx_dl_frm_len; 3418 3419 if (param->frm_len > mgmt_tx_dl_frm_len) { 3420 wmi_err("mgmt frame len %u exceeds %u", 3421 param->frm_len, mgmt_tx_dl_frm_len); 3422 return QDF_STATUS_E_INVAL; 3423 } 3424 3425 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3426 WMI_TLV_HDR_SIZE + 3427 roundup(bufp_len, sizeof(uint32_t)); 3428 3429 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3430 if (!buf) 3431 return QDF_STATUS_E_NOMEM; 3432 3433 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3434 bufp = (uint8_t *) cmd; 3435 WMITLV_SET_HDR(&cmd->tlv_header, 3436 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3437 WMITLV_GET_STRUCT_TLVLEN 3438 (wmi_mgmt_tx_send_cmd_fixed_param)); 3439 3440 cmd->vdev_id = param->vdev_id; 3441 3442 cmd->desc_id = param->desc_id; 3443 cmd->chanfreq = param->chanfreq; 3444 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3445 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3446 sizeof(uint32_t))); 3447 bufp += WMI_TLV_HDR_SIZE; 3448 qdf_mem_copy(bufp, param->pdata, bufp_len); 3449 3450 cmd->frame_len = param->frm_len; 3451 cmd->buf_len = bufp_len; 3452 cmd->tx_params_valid = param->tx_params_valid; 3453 cmd->tx_flags = param->tx_flags; 3454 cmd->peer_rssi = param->peer_rssi; 3455 3456 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3457 bufp, cmd->vdev_id, cmd->chanfreq); 3458 3459 bufp += roundup(bufp_len, sizeof(uint32_t)); 3460 if (param->tx_params_valid) { 3461 if (populate_tx_send_params(bufp, param->tx_param) != 3462 QDF_STATUS_SUCCESS) { 3463 wmi_err("Populate TX send params failed"); 3464 goto free_buf; 3465 } 3466 cmd_len += sizeof(wmi_tx_send_params); 3467 } 3468 3469 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3470 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3471 WMI_MGMT_TX_SEND_CMDID)) { 3472 wmi_err("Failed to send mgmt Tx"); 3473 goto free_buf; 3474 } 3475 return QDF_STATUS_SUCCESS; 3476 3477 free_buf: 3478 wmi_buf_free(buf); 3479 return QDF_STATUS_E_FAILURE; 3480 } 3481 #else 3482 /** 3483 * send_mgmt_cmd_tlv() - WMI scan start function 3484 * @wmi_handle : handle to WMI. 3485 * @param : pointer to hold mgmt cmd parameter 3486 * 3487 * Return: 0 on success and -ve on failure. 3488 */ 3489 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3490 struct wmi_mgmt_params *param) 3491 { 3492 wmi_buf_t buf; 3493 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3494 int32_t cmd_len; 3495 uint64_t dma_addr; 3496 void *qdf_ctx = param->qdf_ctx; 3497 uint8_t *bufp; 3498 QDF_STATUS status = QDF_STATUS_SUCCESS; 3499 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3500 mgmt_tx_dl_frm_len; 3501 3502 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3503 WMI_TLV_HDR_SIZE + 3504 roundup(bufp_len, sizeof(uint32_t)); 3505 3506 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3507 if (!buf) 3508 return QDF_STATUS_E_NOMEM; 3509 3510 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3511 bufp = (uint8_t *) cmd; 3512 WMITLV_SET_HDR(&cmd->tlv_header, 3513 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3514 WMITLV_GET_STRUCT_TLVLEN 3515 (wmi_mgmt_tx_send_cmd_fixed_param)); 3516 3517 cmd->vdev_id = param->vdev_id; 3518 3519 cmd->desc_id = param->desc_id; 3520 cmd->chanfreq = param->chanfreq; 3521 cmd->peer_rssi = param->peer_rssi; 3522 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3523 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3524 sizeof(uint32_t))); 3525 bufp += WMI_TLV_HDR_SIZE; 3526 3527 /* for big endian host, copy engine byte_swap is enabled 3528 * But the frame content is in network byte order 3529 * Need to byte swap the frame content - so when copy engine 3530 * does byte_swap - target gets frame content in the correct order 3531 */ 3532 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 3533 3534 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 3535 QDF_DMA_TO_DEVICE); 3536 if (status != QDF_STATUS_SUCCESS) { 3537 wmi_err("wmi buf map failed"); 3538 goto free_buf; 3539 } 3540 3541 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3542 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3543 #if defined(HTT_PADDR64) 3544 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3545 #endif 3546 cmd->frame_len = param->frm_len; 3547 cmd->buf_len = bufp_len; 3548 cmd->tx_params_valid = param->tx_params_valid; 3549 cmd->tx_flags = param->tx_flags; 3550 3551 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3552 bufp, cmd->vdev_id, cmd->chanfreq); 3553 3554 bufp += roundup(bufp_len, sizeof(uint32_t)); 3555 if (param->tx_params_valid) { 3556 status = populate_tx_send_params(bufp, param->tx_param); 3557 if (status != QDF_STATUS_SUCCESS) { 3558 wmi_err("Populate TX send params failed"); 3559 goto unmap_tx_frame; 3560 } 3561 cmd_len += sizeof(wmi_tx_send_params); 3562 } 3563 3564 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3565 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3566 WMI_MGMT_TX_SEND_CMDID)) { 3567 wmi_err("Failed to send mgmt Tx"); 3568 goto unmap_tx_frame; 3569 } 3570 return QDF_STATUS_SUCCESS; 3571 3572 unmap_tx_frame: 3573 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3574 QDF_DMA_TO_DEVICE); 3575 free_buf: 3576 wmi_buf_free(buf); 3577 return QDF_STATUS_E_FAILURE; 3578 } 3579 #endif /* CONFIG_HL_SUPPORT */ 3580 3581 /** 3582 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3583 * @wmi_handle : handle to WMI. 3584 * @param : pointer to offchan data tx cmd parameter 3585 * 3586 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3587 */ 3588 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3589 struct wmi_offchan_data_tx_params *param) 3590 { 3591 wmi_buf_t buf; 3592 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3593 int32_t cmd_len; 3594 uint64_t dma_addr; 3595 void *qdf_ctx = param->qdf_ctx; 3596 uint8_t *bufp; 3597 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3598 param->frm_len : mgmt_tx_dl_frm_len; 3599 QDF_STATUS status = QDF_STATUS_SUCCESS; 3600 3601 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3602 WMI_TLV_HDR_SIZE + 3603 roundup(bufp_len, sizeof(uint32_t)); 3604 3605 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3606 if (!buf) 3607 return QDF_STATUS_E_NOMEM; 3608 3609 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3610 bufp = (uint8_t *) cmd; 3611 WMITLV_SET_HDR(&cmd->tlv_header, 3612 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3613 WMITLV_GET_STRUCT_TLVLEN 3614 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3615 3616 cmd->vdev_id = param->vdev_id; 3617 3618 cmd->desc_id = param->desc_id; 3619 cmd->chanfreq = param->chanfreq; 3620 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3621 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3622 sizeof(uint32_t))); 3623 bufp += WMI_TLV_HDR_SIZE; 3624 qdf_mem_copy(bufp, param->pdata, bufp_len); 3625 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3626 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3627 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3628 #if defined(HTT_PADDR64) 3629 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3630 #endif 3631 cmd->frame_len = param->frm_len; 3632 cmd->buf_len = bufp_len; 3633 cmd->tx_params_valid = param->tx_params_valid; 3634 3635 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3636 bufp, cmd->vdev_id, cmd->chanfreq); 3637 3638 bufp += roundup(bufp_len, sizeof(uint32_t)); 3639 if (param->tx_params_valid) { 3640 status = populate_tx_send_params(bufp, param->tx_param); 3641 if (status != QDF_STATUS_SUCCESS) { 3642 wmi_err("Populate TX send params failed"); 3643 goto err1; 3644 } 3645 cmd_len += sizeof(wmi_tx_send_params); 3646 } 3647 3648 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 3649 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3650 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3651 wmi_err("Failed to offchan data Tx"); 3652 goto err1; 3653 } 3654 3655 return QDF_STATUS_SUCCESS; 3656 3657 err1: 3658 wmi_buf_free(buf); 3659 return QDF_STATUS_E_FAILURE; 3660 } 3661 3662 /** 3663 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3664 * @wmi_handle: wmi handle 3665 * @param_value: parameter value 3666 * 3667 * Return: QDF_STATUS_SUCCESS for success or error code 3668 */ 3669 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3670 uint32_t param_value) 3671 { 3672 QDF_STATUS ret; 3673 wmi_modem_power_state_cmd_param *cmd; 3674 wmi_buf_t buf; 3675 uint16_t len = sizeof(*cmd); 3676 3677 buf = wmi_buf_alloc(wmi_handle, len); 3678 if (!buf) 3679 return QDF_STATUS_E_NOMEM; 3680 3681 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3682 WMITLV_SET_HDR(&cmd->tlv_header, 3683 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3684 WMITLV_GET_STRUCT_TLVLEN 3685 (wmi_modem_power_state_cmd_param)); 3686 cmd->modem_power_state = param_value; 3687 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 3688 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 3689 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3690 WMI_MODEM_POWER_STATE_CMDID); 3691 if (QDF_IS_STATUS_ERROR(ret)) { 3692 wmi_err("Failed to send notify cmd ret = %d", ret); 3693 wmi_buf_free(buf); 3694 } 3695 3696 return ret; 3697 } 3698 3699 /** 3700 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3701 * @wmi_handle: wmi handle 3702 * @vdev_id: vdev id 3703 * @val: value 3704 * 3705 * Return: QDF_STATUS_SUCCESS for success or error code. 3706 */ 3707 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 3708 uint32_t vdev_id, uint8_t val) 3709 { 3710 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 3711 wmi_buf_t buf; 3712 int32_t len = sizeof(*cmd); 3713 3714 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 3715 3716 buf = wmi_buf_alloc(wmi_handle, len); 3717 if (!buf) 3718 return QDF_STATUS_E_NOMEM; 3719 3720 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 3721 WMITLV_SET_HDR(&cmd->tlv_header, 3722 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 3723 WMITLV_GET_STRUCT_TLVLEN 3724 (wmi_sta_powersave_mode_cmd_fixed_param)); 3725 cmd->vdev_id = vdev_id; 3726 if (val) 3727 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 3728 else 3729 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 3730 3731 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 3732 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3733 WMI_STA_POWERSAVE_MODE_CMDID)) { 3734 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 3735 vdev_id, val); 3736 wmi_buf_free(buf); 3737 return QDF_STATUS_E_FAILURE; 3738 } 3739 return QDF_STATUS_SUCCESS; 3740 } 3741 3742 /** 3743 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 3744 * @wmi_handle: wmi handle 3745 * @vdev_id: vdev id 3746 * 3747 * Return: QDF_STATUS_SUCCESS for success or error code. 3748 */ 3749 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 3750 uint8_t val) 3751 { 3752 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 3753 wmi_buf_t buf; 3754 size_t len = sizeof(*cmd); 3755 3756 buf = wmi_buf_alloc(wmi_handle, len); 3757 if (!buf) 3758 return QDF_STATUS_E_NOMEM; 3759 3760 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 3761 WMITLV_SET_HDR(&cmd->tlv_header, 3762 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 3763 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 3764 3765 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 3766 WMI_IDLE_TRIGGER_MONITOR_OFF); 3767 3768 wmi_debug("val: %d", cmd->idle_trigger_monitor); 3769 3770 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3771 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 3772 wmi_buf_free(buf); 3773 return QDF_STATUS_E_FAILURE; 3774 } 3775 return QDF_STATUS_SUCCESS; 3776 } 3777 3778 /** 3779 * send_set_mimops_cmd_tlv() - set MIMO powersave 3780 * @wmi_handle: wmi handle 3781 * @vdev_id: vdev id 3782 * @value: value 3783 * 3784 * Return: QDF_STATUS_SUCCESS for success or error code. 3785 */ 3786 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 3787 uint8_t vdev_id, int value) 3788 { 3789 QDF_STATUS ret; 3790 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 3791 wmi_buf_t buf; 3792 uint16_t len = sizeof(*cmd); 3793 3794 buf = wmi_buf_alloc(wmi_handle, len); 3795 if (!buf) 3796 return QDF_STATUS_E_NOMEM; 3797 3798 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 3799 WMITLV_SET_HDR(&cmd->tlv_header, 3800 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 3801 WMITLV_GET_STRUCT_TLVLEN 3802 (wmi_sta_smps_force_mode_cmd_fixed_param)); 3803 3804 cmd->vdev_id = vdev_id; 3805 3806 /* WMI_SMPS_FORCED_MODE values do not directly map 3807 * to SM power save values defined in the specification. 3808 * Make sure to send the right mapping. 3809 */ 3810 switch (value) { 3811 case 0: 3812 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 3813 break; 3814 case 1: 3815 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 3816 break; 3817 case 2: 3818 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 3819 break; 3820 case 3: 3821 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 3822 break; 3823 default: 3824 wmi_err("INVALID MIMO PS CONFIG: %d", value); 3825 wmi_buf_free(buf); 3826 return QDF_STATUS_E_FAILURE; 3827 } 3828 3829 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 3830 3831 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 3832 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3833 WMI_STA_SMPS_FORCE_MODE_CMDID); 3834 if (QDF_IS_STATUS_ERROR(ret)) { 3835 wmi_err("Failed to send set Mimo PS ret = %d", ret); 3836 wmi_buf_free(buf); 3837 } 3838 3839 return ret; 3840 } 3841 3842 /** 3843 * send_set_smps_params_cmd_tlv() - set smps params 3844 * @wmi_handle: wmi handle 3845 * @vdev_id: vdev id 3846 * @value: value 3847 * 3848 * Return: QDF_STATUS_SUCCESS for success or error code. 3849 */ 3850 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 3851 int value) 3852 { 3853 QDF_STATUS ret; 3854 wmi_sta_smps_param_cmd_fixed_param *cmd; 3855 wmi_buf_t buf; 3856 uint16_t len = sizeof(*cmd); 3857 3858 buf = wmi_buf_alloc(wmi_handle, len); 3859 if (!buf) 3860 return QDF_STATUS_E_NOMEM; 3861 3862 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 3863 WMITLV_SET_HDR(&cmd->tlv_header, 3864 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 3865 WMITLV_GET_STRUCT_TLVLEN 3866 (wmi_sta_smps_param_cmd_fixed_param)); 3867 3868 cmd->vdev_id = vdev_id; 3869 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 3870 cmd->param = 3871 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 3872 3873 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 3874 cmd->param); 3875 3876 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 3877 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3878 WMI_STA_SMPS_PARAM_CMDID); 3879 if (QDF_IS_STATUS_ERROR(ret)) { 3880 wmi_err("Failed to send set Mimo PS ret = %d", ret); 3881 wmi_buf_free(buf); 3882 } 3883 3884 return ret; 3885 } 3886 3887 /** 3888 * send_get_temperature_cmd_tlv() - get pdev temperature req 3889 * @wmi_handle: wmi handle 3890 * 3891 * Return: QDF_STATUS_SUCCESS for success or error code. 3892 */ 3893 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 3894 { 3895 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 3896 wmi_buf_t wmi_buf; 3897 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 3898 uint8_t *buf_ptr; 3899 3900 if (!wmi_handle) { 3901 wmi_err("WMI is closed, can not issue cmd"); 3902 return QDF_STATUS_E_INVAL; 3903 } 3904 3905 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3906 if (!wmi_buf) 3907 return QDF_STATUS_E_NOMEM; 3908 3909 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3910 3911 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 3912 WMITLV_SET_HDR(&cmd->tlv_header, 3913 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 3914 WMITLV_GET_STRUCT_TLVLEN 3915 (wmi_pdev_get_temperature_cmd_fixed_param)); 3916 3917 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 3918 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 3919 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 3920 wmi_err("Failed to send get temperature command"); 3921 wmi_buf_free(wmi_buf); 3922 return QDF_STATUS_E_FAILURE; 3923 } 3924 3925 return QDF_STATUS_SUCCESS; 3926 } 3927 3928 /** 3929 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 3930 * @wmi_handle: wmi handle 3931 * @vdevid: vdev id 3932 * @peer_addr: peer mac address 3933 * @auto_triggerparam: auto trigger parameters 3934 * @num_ac: number of access category 3935 * 3936 * This function sets the trigger 3937 * uapsd params such as service interval, delay interval 3938 * and suspend interval which will be used by the firmware 3939 * to send trigger frames periodically when there is no 3940 * traffic on the transmit side. 3941 * 3942 * Return: QDF_STATUS_SUCCESS for success or error code. 3943 */ 3944 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 3945 struct sta_uapsd_trig_params *param) 3946 { 3947 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 3948 QDF_STATUS ret; 3949 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 3950 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 3951 uint32_t i; 3952 wmi_buf_t buf; 3953 uint8_t *buf_ptr; 3954 struct sta_uapsd_params *uapsd_param; 3955 wmi_sta_uapsd_auto_trig_param *trig_param; 3956 3957 buf = wmi_buf_alloc(wmi_handle, cmd_len); 3958 if (!buf) 3959 return QDF_STATUS_E_NOMEM; 3960 3961 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3962 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 3963 WMITLV_SET_HDR(&cmd->tlv_header, 3964 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 3965 WMITLV_GET_STRUCT_TLVLEN 3966 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 3967 cmd->vdev_id = param->vdevid; 3968 cmd->num_ac = param->num_ac; 3969 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 3970 3971 /* TLV indicating array of structures to follow */ 3972 buf_ptr += sizeof(*cmd); 3973 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 3974 3975 buf_ptr += WMI_TLV_HDR_SIZE; 3976 3977 /* 3978 * Update tag and length for uapsd auto trigger params (this will take 3979 * care of updating tag and length if it is not pre-filled by caller). 3980 */ 3981 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 3982 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 3983 for (i = 0; i < param->num_ac; i++) { 3984 WMITLV_SET_HDR((buf_ptr + 3985 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 3986 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 3987 WMITLV_GET_STRUCT_TLVLEN 3988 (wmi_sta_uapsd_auto_trig_param)); 3989 trig_param->wmm_ac = uapsd_param->wmm_ac; 3990 trig_param->user_priority = uapsd_param->user_priority; 3991 trig_param->service_interval = uapsd_param->service_interval; 3992 trig_param->suspend_interval = uapsd_param->suspend_interval; 3993 trig_param->delay_interval = uapsd_param->delay_interval; 3994 trig_param++; 3995 uapsd_param++; 3996 } 3997 3998 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 3999 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4000 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 4001 if (QDF_IS_STATUS_ERROR(ret)) { 4002 wmi_err("Failed to send set uapsd param ret = %d", ret); 4003 wmi_buf_free(buf); 4004 } 4005 4006 return ret; 4007 } 4008 4009 /** 4010 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4011 * @wmi_handle: Pointer to wmi handle 4012 * @thermal_info: Thermal command information 4013 * 4014 * This function sends the thermal management command 4015 * to the firmware 4016 * 4017 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4018 */ 4019 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4020 struct thermal_cmd_params *thermal_info) 4021 { 4022 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4023 wmi_buf_t buf = NULL; 4024 QDF_STATUS status; 4025 uint32_t len = 0; 4026 uint8_t action; 4027 4028 switch (thermal_info->thermal_action) { 4029 case THERMAL_MGMT_ACTION_DEFAULT: 4030 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 4031 break; 4032 4033 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 4034 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 4035 break; 4036 4037 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 4038 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 4039 break; 4040 4041 case THERMAL_MGMT_ACTION_CHAINSCALING: 4042 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 4043 break; 4044 4045 default: 4046 wmi_err("Invalid thermal_action code %d", 4047 thermal_info->thermal_action); 4048 return QDF_STATUS_E_FAILURE; 4049 } 4050 4051 len = sizeof(*cmd); 4052 4053 buf = wmi_buf_alloc(wmi_handle, len); 4054 if (!buf) 4055 return QDF_STATUS_E_FAILURE; 4056 4057 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4058 4059 WMITLV_SET_HDR(&cmd->tlv_header, 4060 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4061 WMITLV_GET_STRUCT_TLVLEN 4062 (wmi_thermal_mgmt_cmd_fixed_param)); 4063 4064 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4065 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4066 cmd->enable = thermal_info->thermal_enable; 4067 cmd->action = action; 4068 4069 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 4070 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 4071 cmd->enable, cmd->action); 4072 4073 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 4074 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4075 WMI_THERMAL_MGMT_CMDID); 4076 if (QDF_IS_STATUS_ERROR(status)) { 4077 wmi_buf_free(buf); 4078 wmi_err("Failed to send thermal mgmt command"); 4079 } 4080 4081 return status; 4082 } 4083 4084 /** 4085 * send_lro_config_cmd_tlv() - process the LRO config command 4086 * @wmi_handle: Pointer to WMI handle 4087 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4088 * 4089 * This function sends down the LRO configuration parameters to 4090 * the firmware to enable LRO, sets the TCP flags and sets the 4091 * seed values for the toeplitz hash generation 4092 * 4093 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4094 */ 4095 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4096 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4097 { 4098 wmi_lro_info_cmd_fixed_param *cmd; 4099 wmi_buf_t buf; 4100 QDF_STATUS status; 4101 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 4102 4103 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4104 if (!buf) 4105 return QDF_STATUS_E_FAILURE; 4106 4107 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4108 4109 WMITLV_SET_HDR(&cmd->tlv_header, 4110 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 4111 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 4112 4113 cmd->lro_enable = wmi_lro_cmd->lro_enable; 4114 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 4115 wmi_lro_cmd->tcp_flag); 4116 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 4117 wmi_lro_cmd->tcp_flag_mask); 4118 cmd->toeplitz_hash_ipv4_0_3 = 4119 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 4120 cmd->toeplitz_hash_ipv4_4_7 = 4121 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 4122 cmd->toeplitz_hash_ipv4_8_11 = 4123 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 4124 cmd->toeplitz_hash_ipv4_12_15 = 4125 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 4126 cmd->toeplitz_hash_ipv4_16 = 4127 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 4128 4129 cmd->toeplitz_hash_ipv6_0_3 = 4130 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 4131 cmd->toeplitz_hash_ipv6_4_7 = 4132 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 4133 cmd->toeplitz_hash_ipv6_8_11 = 4134 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 4135 cmd->toeplitz_hash_ipv6_12_15 = 4136 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 4137 cmd->toeplitz_hash_ipv6_16_19 = 4138 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 4139 cmd->toeplitz_hash_ipv6_20_23 = 4140 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 4141 cmd->toeplitz_hash_ipv6_24_27 = 4142 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 4143 cmd->toeplitz_hash_ipv6_28_31 = 4144 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 4145 cmd->toeplitz_hash_ipv6_32_35 = 4146 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 4147 cmd->toeplitz_hash_ipv6_36_39 = 4148 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 4149 cmd->toeplitz_hash_ipv6_40 = 4150 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 4151 4152 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4153 wmi_handle, 4154 pdev_id); 4155 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 4156 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 4157 4158 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 4159 status = wmi_unified_cmd_send(wmi_handle, buf, 4160 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 4161 if (QDF_IS_STATUS_ERROR(status)) { 4162 wmi_buf_free(buf); 4163 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 4164 } 4165 4166 return status; 4167 } 4168 4169 /** 4170 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 4171 * @wmi_handle: Pointer to wmi handle 4172 * @rate_report_params: Pointer to peer rate report parameters 4173 * 4174 * 4175 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4176 */ 4177 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 4178 struct wmi_peer_rate_report_params *rate_report_params) 4179 { 4180 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 4181 wmi_buf_t buf = NULL; 4182 QDF_STATUS status = 0; 4183 uint32_t len = 0; 4184 uint32_t i, j; 4185 4186 len = sizeof(*cmd); 4187 4188 buf = wmi_buf_alloc(wmi_handle, len); 4189 if (!buf) 4190 return QDF_STATUS_E_FAILURE; 4191 4192 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 4193 wmi_buf_data(buf); 4194 4195 WMITLV_SET_HDR( 4196 &cmd->tlv_header, 4197 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 4198 WMITLV_GET_STRUCT_TLVLEN( 4199 wmi_peer_set_rate_report_condition_fixed_param)); 4200 4201 cmd->enable_rate_report = rate_report_params->rate_report_enable; 4202 cmd->report_backoff_time = rate_report_params->backoff_time; 4203 cmd->report_timer_period = rate_report_params->timer_period; 4204 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 4205 cmd->cond_per_phy[i].val_cond_flags = 4206 rate_report_params->report_per_phy[i].cond_flags; 4207 cmd->cond_per_phy[i].rate_delta.min_delta = 4208 rate_report_params->report_per_phy[i].delta.delta_min; 4209 cmd->cond_per_phy[i].rate_delta.percentage = 4210 rate_report_params->report_per_phy[i].delta.percent; 4211 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 4212 cmd->cond_per_phy[i].rate_threshold[j] = 4213 rate_report_params->report_per_phy[i]. 4214 report_rate_threshold[j]; 4215 } 4216 } 4217 4218 wmi_debug("enable %d backoff_time %d period %d", 4219 cmd->enable_rate_report, 4220 cmd->report_backoff_time, cmd->report_timer_period); 4221 4222 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 4223 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4224 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 4225 if (QDF_IS_STATUS_ERROR(status)) { 4226 wmi_buf_free(buf); 4227 wmi_err("Failed to send peer_set_report_cond command"); 4228 } 4229 return status; 4230 } 4231 4232 /** 4233 * send_process_update_edca_param_cmd_tlv() - update EDCA params 4234 * @wmi_handle: wmi handle 4235 * @vdev_id: vdev id. 4236 * @wmm_vparams: edca parameters 4237 * 4238 * This function updates EDCA parameters to the target 4239 * 4240 * Return: CDF Status 4241 */ 4242 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 4243 uint8_t vdev_id, bool mu_edca_param, 4244 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 4245 { 4246 uint8_t *buf_ptr; 4247 wmi_buf_t buf; 4248 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 4249 wmi_wmm_vparams *wmm_param; 4250 struct wmi_host_wme_vparams *twmm_param; 4251 int len = sizeof(*cmd); 4252 int ac; 4253 4254 buf = wmi_buf_alloc(wmi_handle, len); 4255 4256 if (!buf) 4257 return QDF_STATUS_E_NOMEM; 4258 4259 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4260 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 4261 WMITLV_SET_HDR(&cmd->tlv_header, 4262 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4263 WMITLV_GET_STRUCT_TLVLEN 4264 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 4265 cmd->vdev_id = vdev_id; 4266 cmd->wmm_param_type = mu_edca_param; 4267 4268 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 4269 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 4270 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 4271 WMITLV_SET_HDR(&wmm_param->tlv_header, 4272 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4273 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 4274 wmm_param->cwmin = twmm_param->cwmin; 4275 wmm_param->cwmax = twmm_param->cwmax; 4276 wmm_param->aifs = twmm_param->aifs; 4277 if (mu_edca_param) 4278 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 4279 else 4280 wmm_param->txoplimit = twmm_param->txoplimit; 4281 wmm_param->acm = twmm_param->acm; 4282 wmm_param->no_ack = twmm_param->noackpolicy; 4283 } 4284 4285 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 4286 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4287 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 4288 goto fail; 4289 4290 return QDF_STATUS_SUCCESS; 4291 4292 fail: 4293 wmi_buf_free(buf); 4294 wmi_err("Failed to set WMM Parameters"); 4295 return QDF_STATUS_E_FAILURE; 4296 } 4297 4298 /** 4299 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 4300 * @wmi_handle: wmi handle 4301 * @vdev_id: vdev id 4302 * @probe_rsp_info: probe response info 4303 * 4304 * Return: QDF_STATUS_SUCCESS for success or error code 4305 */ 4306 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 4307 uint8_t vdev_id, 4308 struct wmi_probe_resp_params *probe_rsp_info) 4309 { 4310 wmi_prb_tmpl_cmd_fixed_param *cmd; 4311 wmi_bcn_prb_info *bcn_prb_info; 4312 wmi_buf_t wmi_buf; 4313 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 4314 uint8_t *buf_ptr; 4315 QDF_STATUS ret; 4316 4317 wmi_debug("Send probe response template for vdev %d", vdev_id); 4318 4319 tmpl_len = probe_rsp_info->prb_rsp_template_len; 4320 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 4321 4322 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 4323 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 4324 tmpl_len_aligned; 4325 4326 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 4327 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 4328 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 4329 return QDF_STATUS_E_INVAL; 4330 } 4331 4332 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 4333 if (!wmi_buf) 4334 return QDF_STATUS_E_NOMEM; 4335 4336 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4337 4338 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 4339 WMITLV_SET_HDR(&cmd->tlv_header, 4340 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 4341 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 4342 cmd->vdev_id = vdev_id; 4343 cmd->buf_len = tmpl_len; 4344 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 4345 4346 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 4347 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 4348 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 4349 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 4350 bcn_prb_info->caps = 0; 4351 bcn_prb_info->erp = 0; 4352 buf_ptr += sizeof(wmi_bcn_prb_info); 4353 4354 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 4355 buf_ptr += WMI_TLV_HDR_SIZE; 4356 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 4357 4358 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 4359 ret = wmi_unified_cmd_send(wmi_handle, 4360 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 4361 if (QDF_IS_STATUS_ERROR(ret)) { 4362 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 4363 wmi_buf_free(wmi_buf); 4364 } 4365 4366 return ret; 4367 } 4368 4369 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4370 #define WPI_IV_LEN 16 4371 4372 /** 4373 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 4374 * 4375 * @dest_tx: destination address of tsc key counter 4376 * @src_tx: source address of tsc key counter 4377 * @dest_rx: destination address of rsc key counter 4378 * @src_rx: source address of rsc key counter 4379 * 4380 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 4381 * 4382 * Return: None 4383 * 4384 */ 4385 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4386 uint8_t *dest_rx, uint8_t *src_rx) 4387 { 4388 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 4389 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 4390 } 4391 #else 4392 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4393 uint8_t *dest_rx, uint8_t *src_rx) 4394 { 4395 return; 4396 } 4397 #endif 4398 4399 /** 4400 * send_setup_install_key_cmd_tlv() - set key parameters 4401 * @wmi_handle: wmi handle 4402 * @key_params: key parameters 4403 * 4404 * This function fills structure from information 4405 * passed in key_params. 4406 * 4407 * Return: QDF_STATUS_SUCCESS - success 4408 * QDF_STATUS_E_FAILURE - failure 4409 * QDF_STATUS_E_NOMEM - not able to allocate buffer 4410 */ 4411 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 4412 struct set_key_params *key_params) 4413 { 4414 wmi_vdev_install_key_cmd_fixed_param *cmd; 4415 wmi_buf_t buf; 4416 uint8_t *buf_ptr; 4417 uint32_t len; 4418 uint8_t *key_data; 4419 QDF_STATUS status; 4420 4421 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 4422 WMI_TLV_HDR_SIZE; 4423 4424 buf = wmi_buf_alloc(wmi_handle, len); 4425 if (!buf) 4426 return QDF_STATUS_E_NOMEM; 4427 4428 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4429 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 4430 WMITLV_SET_HDR(&cmd->tlv_header, 4431 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 4432 WMITLV_GET_STRUCT_TLVLEN 4433 (wmi_vdev_install_key_cmd_fixed_param)); 4434 cmd->vdev_id = key_params->vdev_id; 4435 cmd->key_ix = key_params->key_idx; 4436 if (key_params->group_key_idx) { 4437 cmd->is_group_key_ix_valid = 1; 4438 cmd->group_key_ix = key_params->group_key_idx; 4439 } 4440 4441 4442 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 4443 cmd->key_flags |= key_params->key_flags; 4444 cmd->key_cipher = key_params->key_cipher; 4445 if ((key_params->key_txmic_len) && 4446 (key_params->key_rxmic_len)) { 4447 cmd->key_txmic_len = key_params->key_txmic_len; 4448 cmd->key_rxmic_len = key_params->key_rxmic_len; 4449 } 4450 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4451 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 4452 key_params->tx_iv, 4453 cmd->wpi_key_rsc_counter, 4454 key_params->rx_iv); 4455 #endif 4456 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 4457 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4458 roundup(key_params->key_len, sizeof(uint32_t))); 4459 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4460 qdf_mem_copy((void *)key_data, 4461 (const void *)key_params->key_data, key_params->key_len); 4462 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_ctr, 4463 sizeof(wmi_key_seq_counter)); 4464 cmd->key_len = key_params->key_len; 4465 4466 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 4467 sizeof(wmi_key_seq_counter)); 4468 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 4469 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4470 WMI_VDEV_INSTALL_KEY_CMDID); 4471 if (QDF_IS_STATUS_ERROR(status)) { 4472 qdf_mem_zero(wmi_buf_data(buf), len); 4473 wmi_buf_free(buf); 4474 } 4475 return status; 4476 } 4477 4478 /** 4479 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 4480 * @wmi_handle: wmi handle 4481 * @vdev_id: vdev id 4482 * @p2p_ie: p2p IE 4483 * 4484 * Return: QDF_STATUS_SUCCESS for success or error code 4485 */ 4486 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 4487 uint32_t vdev_id, uint8_t *p2p_ie) 4488 { 4489 QDF_STATUS ret; 4490 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 4491 wmi_buf_t wmi_buf; 4492 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 4493 uint8_t *buf_ptr; 4494 4495 ie_len = (uint32_t) (p2p_ie[1] + 2); 4496 4497 /* More than one P2P IE may be included in a single frame. 4498 If multiple P2P IEs are present, the complete P2P attribute 4499 data consists of the concatenation of the P2P Attribute 4500 fields of the P2P IEs. The P2P Attributes field of each 4501 P2P IE may be any length up to the maximum (251 octets). 4502 In this case host sends one P2P IE to firmware so the length 4503 should not exceed more than 251 bytes 4504 */ 4505 if (ie_len > 251) { 4506 wmi_err("Invalid p2p ie length %u", ie_len); 4507 return QDF_STATUS_E_INVAL; 4508 } 4509 4510 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 4511 4512 wmi_buf_len = 4513 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 4514 WMI_TLV_HDR_SIZE; 4515 4516 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 4517 if (!wmi_buf) 4518 return QDF_STATUS_E_NOMEM; 4519 4520 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4521 4522 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 4523 WMITLV_SET_HDR(&cmd->tlv_header, 4524 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 4525 WMITLV_GET_STRUCT_TLVLEN 4526 (wmi_p2p_go_set_beacon_ie_fixed_param)); 4527 cmd->vdev_id = vdev_id; 4528 cmd->ie_buf_len = ie_len; 4529 4530 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 4531 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 4532 buf_ptr += WMI_TLV_HDR_SIZE; 4533 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 4534 4535 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 4536 4537 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 4538 ret = wmi_unified_cmd_send(wmi_handle, 4539 wmi_buf, wmi_buf_len, 4540 WMI_P2P_GO_SET_BEACON_IE); 4541 if (QDF_IS_STATUS_ERROR(ret)) { 4542 wmi_err("Failed to send bcn tmpl: %d", ret); 4543 wmi_buf_free(wmi_buf); 4544 } 4545 4546 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 4547 return ret; 4548 } 4549 4550 /** 4551 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 4552 * @wmi_handle: wmi handle 4553 * @psetoui: OUI parameters 4554 * 4555 * set scan probe OUI parameters in firmware 4556 * 4557 * Return: CDF status 4558 */ 4559 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 4560 struct scan_mac_oui *psetoui) 4561 { 4562 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 4563 wmi_buf_t wmi_buf; 4564 uint32_t len; 4565 uint8_t *buf_ptr; 4566 uint32_t *oui_buf; 4567 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 4568 4569 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 4570 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 4571 4572 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4573 if (!wmi_buf) 4574 return QDF_STATUS_E_NOMEM; 4575 4576 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4577 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 4578 WMITLV_SET_HDR(&cmd->tlv_header, 4579 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 4580 WMITLV_GET_STRUCT_TLVLEN 4581 (wmi_scan_prob_req_oui_cmd_fixed_param)); 4582 4583 oui_buf = &cmd->prob_req_oui; 4584 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 4585 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 4586 | psetoui->oui[2]; 4587 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 4588 4589 cmd->vdev_id = psetoui->vdev_id; 4590 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 4591 if (psetoui->enb_probe_req_sno_randomization) 4592 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 4593 4594 if (ie_whitelist->white_list) { 4595 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 4596 &cmd->num_vendor_oui, 4597 ie_whitelist); 4598 cmd->flags |= 4599 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 4600 } 4601 4602 buf_ptr += sizeof(*cmd); 4603 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4604 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4605 buf_ptr += WMI_TLV_HDR_SIZE; 4606 4607 if (cmd->num_vendor_oui != 0) { 4608 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4609 ie_whitelist->voui); 4610 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4611 } 4612 4613 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 4614 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4615 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 4616 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 4617 wmi_buf_free(wmi_buf); 4618 return QDF_STATUS_E_FAILURE; 4619 } 4620 return QDF_STATUS_SUCCESS; 4621 } 4622 4623 #ifdef IPA_OFFLOAD 4624 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 4625 * @wmi_handle: wmi handle 4626 * @ipa_offload: ipa offload control parameter 4627 * 4628 * Returns: 0 on success, error number otherwise 4629 */ 4630 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 4631 struct ipa_uc_offload_control_params *ipa_offload) 4632 { 4633 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 4634 wmi_buf_t wmi_buf; 4635 uint32_t len; 4636 u_int8_t *buf_ptr; 4637 4638 len = sizeof(*cmd); 4639 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4640 if (!wmi_buf) 4641 return QDF_STATUS_E_NOMEM; 4642 4643 wmi_debug("offload_type=%d, enable=%d", 4644 ipa_offload->offload_type, ipa_offload->enable); 4645 4646 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 4647 4648 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 4649 WMITLV_SET_HDR(&cmd->tlv_header, 4650 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 4651 WMITLV_GET_STRUCT_TLVLEN( 4652 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 4653 4654 cmd->offload_type = ipa_offload->offload_type; 4655 cmd->vdev_id = ipa_offload->vdev_id; 4656 cmd->enable = ipa_offload->enable; 4657 4658 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 4659 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4660 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 4661 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 4662 wmi_buf_free(wmi_buf); 4663 return QDF_STATUS_E_FAILURE; 4664 } 4665 4666 return QDF_STATUS_SUCCESS; 4667 } 4668 #endif 4669 4670 /** 4671 * send_pno_stop_cmd_tlv() - PNO stop request 4672 * @wmi_handle: wmi handle 4673 * @vdev_id: vdev id 4674 * 4675 * This function request FW to stop ongoing PNO operation. 4676 * 4677 * Return: CDF status 4678 */ 4679 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 4680 { 4681 wmi_nlo_config_cmd_fixed_param *cmd; 4682 int32_t len = sizeof(*cmd); 4683 wmi_buf_t buf; 4684 uint8_t *buf_ptr; 4685 int ret; 4686 4687 /* 4688 * TLV place holder for array of structures nlo_configured_parameters 4689 * TLV place holder for array of uint32_t channel_list 4690 * TLV place holder for chnl prediction cfg 4691 */ 4692 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 4693 buf = wmi_buf_alloc(wmi_handle, len); 4694 if (!buf) 4695 return QDF_STATUS_E_NOMEM; 4696 4697 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 4698 buf_ptr = (uint8_t *) cmd; 4699 4700 WMITLV_SET_HDR(&cmd->tlv_header, 4701 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 4702 WMITLV_GET_STRUCT_TLVLEN 4703 (wmi_nlo_config_cmd_fixed_param)); 4704 4705 cmd->vdev_id = vdev_id; 4706 cmd->flags = WMI_NLO_CONFIG_STOP; 4707 buf_ptr += sizeof(*cmd); 4708 4709 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 4710 buf_ptr += WMI_TLV_HDR_SIZE; 4711 4712 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 4713 buf_ptr += WMI_TLV_HDR_SIZE; 4714 4715 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 4716 buf_ptr += WMI_TLV_HDR_SIZE; 4717 4718 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 4719 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4720 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 4721 if (ret) { 4722 wmi_err("Failed to send nlo wmi cmd"); 4723 wmi_buf_free(buf); 4724 return QDF_STATUS_E_FAILURE; 4725 } 4726 4727 return QDF_STATUS_SUCCESS; 4728 } 4729 4730 /** 4731 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 4732 * @buf_ptr: Buffer passed by upper layers 4733 * @pno: Buffer to be sent to the firmware 4734 * 4735 * Copy the PNO Channel prediction configuration parameters 4736 * passed by the upper layers to a WMI format TLV and send it 4737 * down to the firmware. 4738 * 4739 * Return: None 4740 */ 4741 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 4742 struct pno_scan_req_params *pno) 4743 { 4744 nlo_channel_prediction_cfg *channel_prediction_cfg = 4745 (nlo_channel_prediction_cfg *) buf_ptr; 4746 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 4747 WMITLV_TAG_ARRAY_BYTE, 4748 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 4749 #ifdef FEATURE_WLAN_SCAN_PNO 4750 channel_prediction_cfg->enable = pno->pno_channel_prediction; 4751 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 4752 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 4753 channel_prediction_cfg->full_scan_period_ms = 4754 pno->channel_prediction_full_scan; 4755 #endif 4756 buf_ptr += sizeof(nlo_channel_prediction_cfg); 4757 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 4758 channel_prediction_cfg->enable, 4759 channel_prediction_cfg->top_k_num, 4760 channel_prediction_cfg->stationary_threshold, 4761 channel_prediction_cfg->full_scan_period_ms); 4762 } 4763 4764 /** 4765 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 4766 * @buf_ptr: Buffer passed by upper layers 4767 * @buf_len: Length of passed buffer by upper layer 4768 * 4769 * Copy the buffer passed by the upper layers and send it 4770 * down to the firmware. 4771 * 4772 * Return: None 4773 */ 4774 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 4775 void *buf_ptr, uint32_t buf_len) 4776 { 4777 wmi_buf_t buf = NULL; 4778 QDF_STATUS status; 4779 int len; 4780 uint8_t *data_ptr; 4781 4782 len = buf_len; 4783 buf = wmi_buf_alloc(wmi_handle, len); 4784 if (!buf) 4785 return QDF_STATUS_E_NOMEM; 4786 4787 data_ptr = (uint8_t *)wmi_buf_data(buf); 4788 qdf_mem_copy(data_ptr, buf_ptr, len); 4789 4790 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 4791 status = wmi_unified_cmd_send(wmi_handle, buf, 4792 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 4793 4794 if (QDF_IS_STATUS_ERROR(status)) { 4795 wmi_buf_free(buf); 4796 return QDF_STATUS_E_FAILURE; 4797 } 4798 return QDF_STATUS_SUCCESS; 4799 } 4800 4801 /** 4802 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 4803 * @wmi_handle: wmi handle 4804 * @evt_buf: event buffer 4805 * @more_flag: buffer to populate more flag 4806 * 4807 * Return: status of operation 4808 */ 4809 static QDF_STATUS 4810 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi, void *evt_buf, 4811 uint32_t *more_flag) 4812 { 4813 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 4814 wmi_ctrl_path_stats_event_fixed_param *ev; 4815 4816 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 4817 if (!param_buf) 4818 return QDF_STATUS_E_FAILURE; 4819 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 4820 4821 *more_flag = ev->more; 4822 return QDF_STATUS_SUCCESS; 4823 } 4824 4825 /** 4826 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 4827 * @wmi_handle: wmi handle 4828 * @params: configuration parameters 4829 * 4830 * Return: QDF_STATUS 4831 */ 4832 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 4833 struct nlo_mawc_params *params) 4834 { 4835 wmi_buf_t buf = NULL; 4836 QDF_STATUS status; 4837 int len; 4838 uint8_t *buf_ptr; 4839 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 4840 4841 len = sizeof(*wmi_nlo_mawc_params); 4842 buf = wmi_buf_alloc(wmi_handle, len); 4843 if (!buf) 4844 return QDF_STATUS_E_NOMEM; 4845 4846 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4847 wmi_nlo_mawc_params = 4848 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 4849 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 4850 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 4851 WMITLV_GET_STRUCT_TLVLEN 4852 (wmi_nlo_configure_mawc_cmd_fixed_param)); 4853 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 4854 if (params->enable) 4855 wmi_nlo_mawc_params->enable = 1; 4856 else 4857 wmi_nlo_mawc_params->enable = 0; 4858 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 4859 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 4860 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 4861 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 4862 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 4863 wmi_nlo_mawc_params->exp_backoff_ratio, 4864 wmi_nlo_mawc_params->init_scan_interval, 4865 wmi_nlo_mawc_params->max_scan_interval); 4866 4867 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 4868 status = wmi_unified_cmd_send(wmi_handle, buf, 4869 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 4870 if (QDF_IS_STATUS_ERROR(status)) { 4871 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 4872 status); 4873 wmi_buf_free(buf); 4874 return QDF_STATUS_E_FAILURE; 4875 } 4876 4877 return QDF_STATUS_SUCCESS; 4878 } 4879 4880 /** 4881 * send_pno_start_cmd_tlv() - PNO start request 4882 * @wmi_handle: wmi handle 4883 * @pno: PNO request 4884 * 4885 * This function request FW to start PNO request. 4886 * Request: CDF status 4887 */ 4888 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 4889 struct pno_scan_req_params *pno) 4890 { 4891 wmi_nlo_config_cmd_fixed_param *cmd; 4892 nlo_configured_parameters *nlo_list; 4893 uint32_t *channel_list; 4894 int32_t len; 4895 wmi_buf_t buf; 4896 uint8_t *buf_ptr; 4897 uint8_t i; 4898 int ret; 4899 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 4900 connected_nlo_rssi_params *nlo_relative_rssi; 4901 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 4902 4903 /* 4904 * TLV place holder for array nlo_configured_parameters(nlo_list) 4905 * TLV place holder for array of uint32_t channel_list 4906 * TLV place holder for chnnl prediction cfg 4907 * TLV place holder for array of wmi_vendor_oui 4908 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 4909 */ 4910 len = sizeof(*cmd) + 4911 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 4912 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 4913 4914 len += sizeof(uint32_t) * pno->networks_list[0].channel_cnt; 4915 len += sizeof(nlo_configured_parameters) * 4916 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 4917 len += sizeof(nlo_channel_prediction_cfg); 4918 len += sizeof(enlo_candidate_score_params); 4919 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 4920 len += sizeof(connected_nlo_rssi_params); 4921 len += sizeof(connected_nlo_bss_band_rssi_pref); 4922 4923 buf = wmi_buf_alloc(wmi_handle, len); 4924 if (!buf) 4925 return QDF_STATUS_E_NOMEM; 4926 4927 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 4928 4929 buf_ptr = (uint8_t *) cmd; 4930 WMITLV_SET_HDR(&cmd->tlv_header, 4931 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 4932 WMITLV_GET_STRUCT_TLVLEN 4933 (wmi_nlo_config_cmd_fixed_param)); 4934 cmd->vdev_id = pno->vdev_id; 4935 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 4936 4937 #ifdef FEATURE_WLAN_SCAN_PNO 4938 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 4939 pno->adaptive_dwell_mode); 4940 #endif 4941 /* Current FW does not support min-max range for dwell time */ 4942 cmd->active_dwell_time = pno->active_dwell_time; 4943 cmd->passive_dwell_time = pno->passive_dwell_time; 4944 4945 if (pno->do_passive_scan) 4946 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 4947 /* Copy scan interval */ 4948 cmd->fast_scan_period = pno->fast_scan_period; 4949 cmd->slow_scan_period = pno->slow_scan_period; 4950 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 4951 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 4952 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 4953 4954 /* mac randomization attributes */ 4955 if (pno->scan_random.randomize) { 4956 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 4957 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 4958 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 4959 pno->scan_random.mac_mask, 4960 &cmd->mac_addr, 4961 &cmd->mac_mask); 4962 } 4963 4964 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 4965 4966 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 4967 4968 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4969 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 4970 buf_ptr += WMI_TLV_HDR_SIZE; 4971 4972 nlo_list = (nlo_configured_parameters *) buf_ptr; 4973 for (i = 0; i < cmd->no_of_ssids; i++) { 4974 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 4975 WMITLV_TAG_ARRAY_BYTE, 4976 WMITLV_GET_STRUCT_TLVLEN 4977 (nlo_configured_parameters)); 4978 /* Copy ssid and it's length */ 4979 nlo_list[i].ssid.valid = true; 4980 nlo_list[i].ssid.ssid.ssid_len = 4981 pno->networks_list[i].ssid.length; 4982 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 4983 pno->networks_list[i].ssid.ssid, 4984 nlo_list[i].ssid.ssid.ssid_len); 4985 4986 /* Copy rssi threshold */ 4987 if (pno->networks_list[i].rssi_thresh && 4988 pno->networks_list[i].rssi_thresh > 4989 WMI_RSSI_THOLD_DEFAULT) { 4990 nlo_list[i].rssi_cond.valid = true; 4991 nlo_list[i].rssi_cond.rssi = 4992 pno->networks_list[i].rssi_thresh; 4993 } 4994 nlo_list[i].bcast_nw_type.valid = true; 4995 nlo_list[i].bcast_nw_type.bcast_nw_type = 4996 pno->networks_list[i].bc_new_type; 4997 } 4998 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 4999 5000 /* Copy channel info */ 5001 cmd->num_of_channels = pno->networks_list[0].channel_cnt; 5002 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 5003 (cmd->num_of_channels * sizeof(uint32_t))); 5004 buf_ptr += WMI_TLV_HDR_SIZE; 5005 5006 channel_list = (uint32_t *) buf_ptr; 5007 for (i = 0; i < cmd->num_of_channels; i++) { 5008 channel_list[i] = pno->networks_list[0].channels[i]; 5009 5010 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 5011 channel_list[i] = 5012 wlan_chan_to_freq(pno-> 5013 networks_list[0].channels[i]); 5014 } 5015 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 5016 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5017 sizeof(nlo_channel_prediction_cfg)); 5018 buf_ptr += WMI_TLV_HDR_SIZE; 5019 wmi_set_pno_channel_prediction(buf_ptr, pno); 5020 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5021 /** TODO: Discrete firmware doesn't have command/option to configure 5022 * App IE which comes from wpa_supplicant as of part PNO start request. 5023 */ 5024 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 5025 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 5026 buf_ptr += sizeof(enlo_candidate_score_params); 5027 5028 if (ie_whitelist->white_list) { 5029 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5030 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 5031 &cmd->num_vendor_oui, 5032 ie_whitelist); 5033 } 5034 5035 /* ie white list */ 5036 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5037 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5038 buf_ptr += WMI_TLV_HDR_SIZE; 5039 if (cmd->num_vendor_oui != 0) { 5040 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5041 ie_whitelist->voui); 5042 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5043 } 5044 5045 if (pno->relative_rssi_set) 5046 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 5047 5048 /* 5049 * Firmware calculation using connected PNO params: 5050 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 5051 * deduction of rssi_pref for chosen band_pref and 5052 * addition of rssi_pref for remaining bands (other than chosen band). 5053 */ 5054 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 5055 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 5056 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 5057 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 5058 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 5059 buf_ptr += sizeof(*nlo_relative_rssi); 5060 5061 /* 5062 * As of now Kernel and Host supports one band and rssi preference. 5063 * Firmware supports array of band and rssi preferences 5064 */ 5065 cmd->num_cnlo_band_pref = 1; 5066 WMITLV_SET_HDR(buf_ptr, 5067 WMITLV_TAG_ARRAY_STRUC, 5068 cmd->num_cnlo_band_pref * 5069 sizeof(connected_nlo_bss_band_rssi_pref)); 5070 buf_ptr += WMI_TLV_HDR_SIZE; 5071 5072 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 5073 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 5074 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 5075 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 5076 WMITLV_GET_STRUCT_TLVLEN( 5077 connected_nlo_bss_band_rssi_pref)); 5078 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 5079 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 5080 } 5081 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 5082 5083 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5084 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5085 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5086 if (ret) { 5087 wmi_err("Failed to send nlo wmi cmd"); 5088 wmi_buf_free(buf); 5089 return QDF_STATUS_E_FAILURE; 5090 } 5091 5092 return QDF_STATUS_SUCCESS; 5093 } 5094 5095 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 5096 /** 5097 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 5098 * @wmi_handle: wmi handle 5099 * @clear_req: ll stats clear request command params 5100 * 5101 * Return: QDF_STATUS_SUCCESS for success or error code 5102 */ 5103 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 5104 const struct ll_stats_clear_params *clear_req) 5105 { 5106 wmi_clear_link_stats_cmd_fixed_param *cmd; 5107 int32_t len; 5108 wmi_buf_t buf; 5109 uint8_t *buf_ptr; 5110 int ret; 5111 5112 len = sizeof(*cmd); 5113 buf = wmi_buf_alloc(wmi_handle, len); 5114 5115 if (!buf) 5116 return QDF_STATUS_E_NOMEM; 5117 5118 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5119 qdf_mem_zero(buf_ptr, len); 5120 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 5121 5122 WMITLV_SET_HDR(&cmd->tlv_header, 5123 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 5124 WMITLV_GET_STRUCT_TLVLEN 5125 (wmi_clear_link_stats_cmd_fixed_param)); 5126 5127 cmd->stop_stats_collection_req = clear_req->stop_req; 5128 cmd->vdev_id = clear_req->vdev_id; 5129 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 5130 5131 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 5132 &cmd->peer_macaddr); 5133 5134 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 5135 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 5136 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 5137 cmd->stop_stats_collection_req, 5138 cmd->vdev_id, cmd->stats_clear_req_mask, 5139 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 5140 5141 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 5142 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5143 WMI_CLEAR_LINK_STATS_CMDID); 5144 if (ret) { 5145 wmi_err("Failed to send clear link stats req"); 5146 wmi_buf_free(buf); 5147 return QDF_STATUS_E_FAILURE; 5148 } 5149 5150 wmi_debug("Clear Link Layer Stats request sent successfully"); 5151 return QDF_STATUS_SUCCESS; 5152 } 5153 5154 /** 5155 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 5156 * @wmi_handle: wmi handle 5157 * @set_req: ll stats set request command params 5158 * 5159 * Return: QDF_STATUS_SUCCESS for success or error code 5160 */ 5161 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 5162 const struct ll_stats_set_params *set_req) 5163 { 5164 wmi_start_link_stats_cmd_fixed_param *cmd; 5165 int32_t len; 5166 wmi_buf_t buf; 5167 uint8_t *buf_ptr; 5168 int ret; 5169 5170 len = sizeof(*cmd); 5171 buf = wmi_buf_alloc(wmi_handle, len); 5172 5173 if (!buf) 5174 return QDF_STATUS_E_NOMEM; 5175 5176 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5177 qdf_mem_zero(buf_ptr, len); 5178 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 5179 5180 WMITLV_SET_HDR(&cmd->tlv_header, 5181 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 5182 WMITLV_GET_STRUCT_TLVLEN 5183 (wmi_start_link_stats_cmd_fixed_param)); 5184 5185 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 5186 cmd->aggressive_statistics_gathering = 5187 set_req->aggressive_statistics_gathering; 5188 5189 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 5190 cmd->mpdu_size_threshold, 5191 cmd->aggressive_statistics_gathering); 5192 5193 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 5194 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5195 WMI_START_LINK_STATS_CMDID); 5196 if (ret) { 5197 wmi_err("Failed to send set link stats request"); 5198 wmi_buf_free(buf); 5199 return QDF_STATUS_E_FAILURE; 5200 } 5201 5202 return QDF_STATUS_SUCCESS; 5203 } 5204 5205 /** 5206 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 5207 * @wmi_handle: wmi handle 5208 * @get_req: ll stats get request command params 5209 * 5210 * Return: QDF_STATUS_SUCCESS for success or error code 5211 */ 5212 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 5213 const struct ll_stats_get_params *get_req) 5214 { 5215 wmi_request_link_stats_cmd_fixed_param *cmd; 5216 int32_t len; 5217 wmi_buf_t buf; 5218 uint8_t *buf_ptr; 5219 int ret; 5220 5221 len = sizeof(*cmd); 5222 buf = wmi_buf_alloc(wmi_handle, len); 5223 5224 if (!buf) 5225 return QDF_STATUS_E_NOMEM; 5226 5227 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5228 qdf_mem_zero(buf_ptr, len); 5229 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 5230 5231 WMITLV_SET_HDR(&cmd->tlv_header, 5232 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 5233 WMITLV_GET_STRUCT_TLVLEN 5234 (wmi_request_link_stats_cmd_fixed_param)); 5235 5236 cmd->request_id = get_req->req_id; 5237 cmd->stats_type = get_req->param_id_mask; 5238 cmd->vdev_id = get_req->vdev_id; 5239 5240 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 5241 &cmd->peer_macaddr); 5242 5243 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 5244 cmd->request_id, cmd->stats_type, cmd->vdev_id, 5245 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 5246 5247 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 5248 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 5249 WMI_REQUEST_LINK_STATS_CMDID); 5250 if (ret) { 5251 wmi_buf_free(buf); 5252 return QDF_STATUS_E_FAILURE; 5253 } 5254 5255 return QDF_STATUS_SUCCESS; 5256 } 5257 5258 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 5259 /** 5260 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 5261 * station request 5262 * @wmi_handle: wmi handle 5263 * @get_req: ll stats get request command params 5264 * @is_always_over_qmi: flag to send stats request always over qmi 5265 * 5266 * Return: QDF_STATUS_SUCCESS for success or error code 5267 */ 5268 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 5269 wmi_unified_t wmi_handle, 5270 const struct ll_stats_get_params *get_req, 5271 bool is_always_over_qmi) 5272 { 5273 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 5274 int32_t len; 5275 wmi_buf_t buf; 5276 void *buf_ptr; 5277 QDF_STATUS ret; 5278 5279 len = sizeof(*unified_cmd); 5280 buf = wmi_buf_alloc(wmi_handle, len); 5281 5282 if (!buf) 5283 return QDF_STATUS_E_NOMEM; 5284 5285 buf_ptr = wmi_buf_data(buf); 5286 5287 unified_cmd = buf_ptr; 5288 WMITLV_SET_HDR( 5289 &unified_cmd->tlv_header, 5290 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 5291 WMITLV_GET_STRUCT_TLVLEN 5292 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 5293 5294 unified_cmd->link_stats_type = get_req->param_id_mask; 5295 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 5296 WMI_REQUEST_PEER_STAT | 5297 WMI_REQUEST_VDEV_STAT | 5298 WMI_REQUEST_PDEV_STAT | 5299 WMI_REQUEST_PEER_EXTD2_STAT | 5300 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 5301 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5302 wmi_handle, 5303 WMI_HOST_PDEV_ID_SOC); 5304 5305 unified_cmd->vdev_id = get_req->vdev_id; 5306 unified_cmd->request_id = get_req->req_id; 5307 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 5308 &unified_cmd->peer_macaddr); 5309 5310 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 5311 QDF_MAC_ADDR_FMT, 5312 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 5313 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 5314 5315 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 5316 5317 if (is_always_over_qmi && wmi_is_qmi_stats_enabled(wmi_handle)) { 5318 ret = wmi_unified_cmd_send_over_qmi( 5319 wmi_handle, buf, len, 5320 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 5321 } else { 5322 ret = wmi_unified_cmd_send_pm_chk( 5323 wmi_handle, buf, len, 5324 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 5325 } 5326 5327 if (QDF_IS_STATUS_ERROR(ret)) { 5328 wmi_buf_free(buf); 5329 return QDF_STATUS_E_FAILURE; 5330 } 5331 5332 return ret; 5333 } 5334 #endif 5335 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 5336 5337 /** 5338 * send_congestion_cmd_tlv() - send request to fw to get CCA 5339 * @wmi_handle: wmi handle 5340 * @vdev_id: vdev id 5341 * 5342 * Return: CDF status 5343 */ 5344 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 5345 uint8_t vdev_id) 5346 { 5347 wmi_buf_t buf; 5348 wmi_request_stats_cmd_fixed_param *cmd; 5349 uint8_t len; 5350 uint8_t *buf_ptr; 5351 5352 len = sizeof(*cmd); 5353 buf = wmi_buf_alloc(wmi_handle, len); 5354 if (!buf) 5355 return QDF_STATUS_E_FAILURE; 5356 5357 buf_ptr = wmi_buf_data(buf); 5358 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 5359 WMITLV_SET_HDR(&cmd->tlv_header, 5360 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5361 WMITLV_GET_STRUCT_TLVLEN 5362 (wmi_request_stats_cmd_fixed_param)); 5363 5364 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 5365 cmd->vdev_id = vdev_id; 5366 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 5367 cmd->vdev_id, cmd->stats_id); 5368 5369 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5370 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5371 WMI_REQUEST_STATS_CMDID)) { 5372 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 5373 wmi_buf_free(buf); 5374 return QDF_STATUS_E_FAILURE; 5375 } 5376 5377 return QDF_STATUS_SUCCESS; 5378 } 5379 5380 /** 5381 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 5382 * @wmi_handle: wmi handle 5383 * @rssi_req: get RSSI request 5384 * 5385 * Return: CDF status 5386 */ 5387 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 5388 { 5389 wmi_buf_t buf; 5390 wmi_request_stats_cmd_fixed_param *cmd; 5391 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5392 5393 buf = wmi_buf_alloc(wmi_handle, len); 5394 if (!buf) 5395 return QDF_STATUS_E_FAILURE; 5396 5397 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5398 WMITLV_SET_HDR(&cmd->tlv_header, 5399 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5400 WMITLV_GET_STRUCT_TLVLEN 5401 (wmi_request_stats_cmd_fixed_param)); 5402 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 5403 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5404 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5405 WMI_REQUEST_STATS_CMDID)) { 5406 wmi_err("Failed to send host stats request to fw"); 5407 wmi_buf_free(buf); 5408 return QDF_STATUS_E_FAILURE; 5409 } 5410 5411 return QDF_STATUS_SUCCESS; 5412 } 5413 5414 /** 5415 * send_snr_cmd_tlv() - get RSSI from fw 5416 * @wmi_handle: wmi handle 5417 * @vdev_id: vdev id 5418 * 5419 * Return: CDF status 5420 */ 5421 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 5422 { 5423 wmi_buf_t buf; 5424 wmi_request_stats_cmd_fixed_param *cmd; 5425 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5426 5427 buf = wmi_buf_alloc(wmi_handle, len); 5428 if (!buf) 5429 return QDF_STATUS_E_FAILURE; 5430 5431 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5432 cmd->vdev_id = vdev_id; 5433 5434 WMITLV_SET_HDR(&cmd->tlv_header, 5435 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5436 WMITLV_GET_STRUCT_TLVLEN 5437 (wmi_request_stats_cmd_fixed_param)); 5438 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 5439 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5440 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5441 WMI_REQUEST_STATS_CMDID)) { 5442 wmi_err("Failed to send host stats request to fw"); 5443 wmi_buf_free(buf); 5444 return QDF_STATUS_E_FAILURE; 5445 } 5446 5447 return QDF_STATUS_SUCCESS; 5448 } 5449 5450 /** 5451 * send_link_status_req_cmd_tlv() - process link status request from UMAC 5452 * @wmi_handle: wmi handle 5453 * @link_status: get link params 5454 * 5455 * Return: CDF status 5456 */ 5457 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 5458 struct link_status_params *link_status) 5459 { 5460 wmi_buf_t buf; 5461 wmi_request_stats_cmd_fixed_param *cmd; 5462 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5463 5464 buf = wmi_buf_alloc(wmi_handle, len); 5465 if (!buf) 5466 return QDF_STATUS_E_FAILURE; 5467 5468 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5469 WMITLV_SET_HDR(&cmd->tlv_header, 5470 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5471 WMITLV_GET_STRUCT_TLVLEN 5472 (wmi_request_stats_cmd_fixed_param)); 5473 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 5474 cmd->vdev_id = link_status->vdev_id; 5475 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5476 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5477 WMI_REQUEST_STATS_CMDID)) { 5478 wmi_err("Failed to send WMI link status request to fw"); 5479 wmi_buf_free(buf); 5480 return QDF_STATUS_E_FAILURE; 5481 } 5482 5483 return QDF_STATUS_SUCCESS; 5484 } 5485 5486 #ifdef WLAN_SUPPORT_GREEN_AP 5487 /** 5488 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 5489 * @wmi_handle: wmi handler 5490 * @egap_params: pointer to egap_params 5491 * 5492 * Return: 0 for success, otherwise appropriate error code 5493 */ 5494 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 5495 struct wlan_green_ap_egap_params *egap_params) 5496 { 5497 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 5498 wmi_buf_t buf; 5499 int32_t err; 5500 5501 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5502 if (!buf) 5503 return QDF_STATUS_E_NOMEM; 5504 5505 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 5506 WMITLV_SET_HDR(&cmd->tlv_header, 5507 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 5508 WMITLV_GET_STRUCT_TLVLEN( 5509 wmi_ap_ps_egap_param_cmd_fixed_param)); 5510 5511 cmd->enable = egap_params->host_enable_egap; 5512 cmd->inactivity_time = egap_params->egap_inactivity_time; 5513 cmd->wait_time = egap_params->egap_wait_time; 5514 cmd->flags = egap_params->egap_feature_flags; 5515 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 5516 err = wmi_unified_cmd_send(wmi_handle, buf, 5517 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 5518 if (err) { 5519 wmi_err("Failed to send ap_ps_egap cmd"); 5520 wmi_buf_free(buf); 5521 return QDF_STATUS_E_FAILURE; 5522 } 5523 5524 return QDF_STATUS_SUCCESS; 5525 } 5526 #endif 5527 5528 /** 5529 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 5530 * @wmi_handle: wmi handle 5531 * @vdev_id: vdev id 5532 * 5533 * Return: QDF_STATUS_SUCCESS for success or error code 5534 */ 5535 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 5536 uint8_t vdev_id) 5537 { 5538 wmi_csa_offload_enable_cmd_fixed_param *cmd; 5539 wmi_buf_t buf; 5540 int32_t len = sizeof(*cmd); 5541 5542 wmi_debug("vdev_id %d", vdev_id); 5543 buf = wmi_buf_alloc(wmi_handle, len); 5544 if (!buf) 5545 return QDF_STATUS_E_NOMEM; 5546 5547 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 5548 WMITLV_SET_HDR(&cmd->tlv_header, 5549 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 5550 WMITLV_GET_STRUCT_TLVLEN 5551 (wmi_csa_offload_enable_cmd_fixed_param)); 5552 cmd->vdev_id = vdev_id; 5553 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 5554 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 5555 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5556 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 5557 wmi_err("Failed to send CSA offload enable command"); 5558 wmi_buf_free(buf); 5559 return QDF_STATUS_E_FAILURE; 5560 } 5561 5562 return 0; 5563 } 5564 5565 #ifdef WLAN_FEATURE_CIF_CFR 5566 /** 5567 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 5568 * @wmi_handle: wmi handle 5569 * @data_len: len of dma cfg req 5570 * @data: dma cfg req 5571 * 5572 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 5573 */ 5574 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 5575 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 5576 { 5577 wmi_buf_t buf; 5578 uint8_t *cmd; 5579 QDF_STATUS ret; 5580 5581 WMITLV_SET_HDR(cfg, 5582 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 5583 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 5584 5585 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 5586 if (!buf) 5587 return QDF_STATUS_E_FAILURE; 5588 5589 cmd = (uint8_t *) wmi_buf_data(buf); 5590 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 5591 wmi_debug("Sending OEM Data Request to target, data len %lu"), 5592 sizeof(*cfg); 5593 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 5594 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 5595 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 5596 if (QDF_IS_STATUS_ERROR(ret)) { 5597 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 5598 wmi_buf_free(buf); 5599 } 5600 5601 return ret; 5602 } 5603 #endif 5604 5605 /** 5606 * send_start_11d_scan_cmd_tlv() - start 11d scan request 5607 * @wmi_handle: wmi handle 5608 * @start_11d_scan: 11d scan start request parameters 5609 * 5610 * This function request FW to start 11d scan. 5611 * 5612 * Return: QDF status 5613 */ 5614 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 5615 struct reg_start_11d_scan_req *start_11d_scan) 5616 { 5617 wmi_11d_scan_start_cmd_fixed_param *cmd; 5618 int32_t len; 5619 wmi_buf_t buf; 5620 int ret; 5621 5622 len = sizeof(*cmd); 5623 buf = wmi_buf_alloc(wmi_handle, len); 5624 if (!buf) 5625 return QDF_STATUS_E_NOMEM; 5626 5627 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 5628 5629 WMITLV_SET_HDR(&cmd->tlv_header, 5630 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 5631 WMITLV_GET_STRUCT_TLVLEN 5632 (wmi_11d_scan_start_cmd_fixed_param)); 5633 5634 cmd->vdev_id = start_11d_scan->vdev_id; 5635 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 5636 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 5637 5638 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 5639 5640 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 5641 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5642 WMI_11D_SCAN_START_CMDID); 5643 if (ret) { 5644 wmi_err("Failed to send start 11d scan wmi cmd"); 5645 wmi_buf_free(buf); 5646 return QDF_STATUS_E_FAILURE; 5647 } 5648 5649 return QDF_STATUS_SUCCESS; 5650 } 5651 5652 /** 5653 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 5654 * @wmi_handle: wmi handle 5655 * @start_11d_scan: 11d scan stop request parameters 5656 * 5657 * This function request FW to stop 11d scan. 5658 * 5659 * Return: QDF status 5660 */ 5661 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 5662 struct reg_stop_11d_scan_req *stop_11d_scan) 5663 { 5664 wmi_11d_scan_stop_cmd_fixed_param *cmd; 5665 int32_t len; 5666 wmi_buf_t buf; 5667 int ret; 5668 5669 len = sizeof(*cmd); 5670 buf = wmi_buf_alloc(wmi_handle, len); 5671 if (!buf) 5672 return QDF_STATUS_E_NOMEM; 5673 5674 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 5675 5676 WMITLV_SET_HDR(&cmd->tlv_header, 5677 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 5678 WMITLV_GET_STRUCT_TLVLEN 5679 (wmi_11d_scan_stop_cmd_fixed_param)); 5680 5681 cmd->vdev_id = stop_11d_scan->vdev_id; 5682 5683 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 5684 5685 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 5686 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5687 WMI_11D_SCAN_STOP_CMDID); 5688 if (ret) { 5689 wmi_err("Failed to send stop 11d scan wmi cmd"); 5690 wmi_buf_free(buf); 5691 return QDF_STATUS_E_FAILURE; 5692 } 5693 5694 return QDF_STATUS_SUCCESS; 5695 } 5696 5697 /** 5698 * send_start_oem_data_cmd_tlv() - start OEM data request to target 5699 * @wmi_handle: wmi handle 5700 * @data_len: the length of @data 5701 * @data: the pointer to data buf 5702 * 5703 * Return: CDF status 5704 */ 5705 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 5706 uint32_t data_len, 5707 uint8_t *data) 5708 { 5709 wmi_buf_t buf; 5710 uint8_t *cmd; 5711 QDF_STATUS ret; 5712 5713 buf = wmi_buf_alloc(wmi_handle, 5714 (data_len + WMI_TLV_HDR_SIZE)); 5715 if (!buf) 5716 return QDF_STATUS_E_FAILURE; 5717 5718 cmd = (uint8_t *) wmi_buf_data(buf); 5719 5720 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 5721 cmd += WMI_TLV_HDR_SIZE; 5722 qdf_mem_copy(cmd, data, 5723 data_len); 5724 5725 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 5726 5727 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 5728 ret = wmi_unified_cmd_send(wmi_handle, buf, 5729 (data_len + 5730 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 5731 5732 if (QDF_IS_STATUS_ERROR(ret)) { 5733 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 5734 wmi_buf_free(buf); 5735 } 5736 5737 return ret; 5738 } 5739 5740 #ifdef FEATURE_OEM_DATA 5741 /** 5742 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 5743 * @wmi_handle: wmi handle 5744 * @oem_data: the pointer to oem data 5745 * 5746 * Return: QDF status 5747 */ 5748 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 5749 struct oem_data *oem_data) 5750 { 5751 QDF_STATUS ret; 5752 wmi_oem_data_cmd_fixed_param *cmd; 5753 struct wmi_ops *ops; 5754 wmi_buf_t buf; 5755 uint16_t len = sizeof(*cmd); 5756 uint16_t oem_data_len_aligned; 5757 uint8_t *buf_ptr; 5758 uint32_t pdev_id; 5759 5760 if (!oem_data || !oem_data->data) { 5761 wmi_err_rl("oem data is not valid"); 5762 return QDF_STATUS_E_FAILURE; 5763 } 5764 5765 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 5766 if (oem_data_len_aligned < oem_data->data_len) { 5767 wmi_err_rl("integer overflow while rounding up data_len"); 5768 return QDF_STATUS_E_FAILURE; 5769 } 5770 5771 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 5772 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 5773 return QDF_STATUS_E_FAILURE; 5774 } 5775 5776 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 5777 buf = wmi_buf_alloc(wmi_handle, len); 5778 if (!buf) 5779 return QDF_STATUS_E_NOMEM; 5780 5781 buf_ptr = (uint8_t *)wmi_buf_data(buf); 5782 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 5783 WMITLV_SET_HDR(&cmd->tlv_header, 5784 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 5785 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 5786 5787 pdev_id = oem_data->pdev_id; 5788 if (oem_data->pdev_vdev_flag) { 5789 ops = wmi_handle->ops; 5790 if (oem_data->is_host_pdev_id) 5791 pdev_id = 5792 ops->convert_host_pdev_id_to_target(wmi_handle, 5793 pdev_id); 5794 else 5795 pdev_id = 5796 ops->convert_pdev_id_host_to_target(wmi_handle, 5797 pdev_id); 5798 } 5799 5800 cmd->vdev_id = oem_data->vdev_id; 5801 cmd->data_len = oem_data->data_len; 5802 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 5803 cmd->pdev_id = pdev_id; 5804 5805 buf_ptr += sizeof(*cmd); 5806 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 5807 buf_ptr += WMI_TLV_HDR_SIZE; 5808 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 5809 5810 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 5811 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 5812 if (QDF_IS_STATUS_ERROR(ret)) { 5813 wmi_err_rl("Failed with ret = %d", ret); 5814 wmi_buf_free(buf); 5815 } 5816 5817 return ret; 5818 } 5819 #endif 5820 5821 /** 5822 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 5823 * @wmi_handle: wmi handle 5824 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 5825 * 5826 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 5827 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 5828 * to firmware based on phyerr filtering 5829 * offload status. 5830 * 5831 * Return: 1 success, 0 failure 5832 */ 5833 static QDF_STATUS 5834 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 5835 bool dfs_phyerr_filter_offload) 5836 { 5837 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 5838 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 5839 wmi_buf_t buf; 5840 uint16_t len; 5841 QDF_STATUS ret; 5842 5843 5844 if (false == dfs_phyerr_filter_offload) { 5845 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 5846 len = sizeof(*disable_phyerr_offload_cmd); 5847 buf = wmi_buf_alloc(wmi_handle, len); 5848 if (!buf) 5849 return 0; 5850 5851 disable_phyerr_offload_cmd = 5852 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 5853 wmi_buf_data(buf); 5854 5855 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 5856 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 5857 WMITLV_GET_STRUCT_TLVLEN 5858 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 5859 5860 /* 5861 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 5862 * to the firmware to disable the phyerror 5863 * filtering offload. 5864 */ 5865 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 5866 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5867 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 5868 if (QDF_IS_STATUS_ERROR(ret)) { 5869 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 5870 ret); 5871 wmi_buf_free(buf); 5872 return QDF_STATUS_E_FAILURE; 5873 } 5874 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 5875 } else { 5876 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 5877 5878 len = sizeof(*enable_phyerr_offload_cmd); 5879 buf = wmi_buf_alloc(wmi_handle, len); 5880 if (!buf) 5881 return QDF_STATUS_E_FAILURE; 5882 5883 enable_phyerr_offload_cmd = 5884 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 5885 wmi_buf_data(buf); 5886 5887 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 5888 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 5889 WMITLV_GET_STRUCT_TLVLEN 5890 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 5891 5892 /* 5893 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 5894 * to the firmware to enable the phyerror 5895 * filtering offload. 5896 */ 5897 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 5898 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5899 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 5900 5901 if (QDF_IS_STATUS_ERROR(ret)) { 5902 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 5903 wmi_buf_free(buf); 5904 return QDF_STATUS_E_FAILURE; 5905 } 5906 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 5907 } 5908 5909 return QDF_STATUS_SUCCESS; 5910 } 5911 5912 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 5913 /** 5914 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 5915 * @wmi_handle: wmi handle 5916 * @pktlog_event: pktlog event 5917 * @cmd_id: pktlog cmd id 5918 * @user_triggered: user triggered input for PKTLOG enable mode 5919 * 5920 * Return: CDF status 5921 */ 5922 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 5923 WMI_PKTLOG_EVENT pktlog_event, 5924 WMI_CMD_ID cmd_id, uint8_t user_triggered) 5925 { 5926 WMI_PKTLOG_EVENT PKTLOG_EVENT; 5927 WMI_CMD_ID CMD_ID; 5928 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 5929 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 5930 int len = 0; 5931 wmi_buf_t buf; 5932 int32_t idx, max_idx; 5933 5934 PKTLOG_EVENT = pktlog_event; 5935 CMD_ID = cmd_id; 5936 5937 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 5938 switch (CMD_ID) { 5939 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 5940 len = sizeof(*cmd); 5941 buf = wmi_buf_alloc(wmi_handle, len); 5942 if (!buf) 5943 return QDF_STATUS_E_NOMEM; 5944 5945 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 5946 wmi_buf_data(buf); 5947 WMITLV_SET_HDR(&cmd->tlv_header, 5948 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 5949 WMITLV_GET_STRUCT_TLVLEN 5950 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 5951 cmd->evlist = 0; 5952 for (idx = 0; idx < max_idx; idx++) { 5953 if (PKTLOG_EVENT & (1 << idx)) 5954 cmd->evlist |= pktlog_event_tlv[idx]; 5955 } 5956 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 5957 : WMI_PKTLOG_ENABLE_AUTO; 5958 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5959 wmi_handle, 5960 WMI_HOST_PDEV_ID_SOC); 5961 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 5962 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5963 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 5964 wmi_err("Failed to send pktlog enable cmdid"); 5965 goto wmi_send_failed; 5966 } 5967 break; 5968 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 5969 len = sizeof(*disable_cmd); 5970 buf = wmi_buf_alloc(wmi_handle, len); 5971 if (!buf) 5972 return QDF_STATUS_E_NOMEM; 5973 5974 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 5975 wmi_buf_data(buf); 5976 WMITLV_SET_HDR(&disable_cmd->tlv_header, 5977 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 5978 WMITLV_GET_STRUCT_TLVLEN 5979 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 5980 disable_cmd->pdev_id = 5981 wmi_handle->ops->convert_pdev_id_host_to_target( 5982 wmi_handle, 5983 WMI_HOST_PDEV_ID_SOC); 5984 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 5985 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5986 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 5987 wmi_err("failed to send pktlog disable cmdid"); 5988 goto wmi_send_failed; 5989 } 5990 break; 5991 default: 5992 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 5993 break; 5994 } 5995 5996 return QDF_STATUS_SUCCESS; 5997 5998 wmi_send_failed: 5999 wmi_buf_free(buf); 6000 return QDF_STATUS_E_FAILURE; 6001 } 6002 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 6003 6004 /** 6005 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 6006 * @wmi_handle: wmi handle 6007 * @preq: stats ext params 6008 * 6009 * Return: CDF status 6010 */ 6011 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 6012 struct stats_ext_params *preq) 6013 { 6014 QDF_STATUS ret; 6015 wmi_req_stats_ext_cmd_fixed_param *cmd; 6016 wmi_buf_t buf; 6017 size_t len; 6018 uint8_t *buf_ptr; 6019 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 6020 6021 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 6022 sizeof(*cmd))) { 6023 wmi_err("Data length=%d is greater than max wmi msg size", 6024 preq->request_data_len); 6025 return QDF_STATUS_E_FAILURE; 6026 } 6027 6028 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 6029 6030 buf = wmi_buf_alloc(wmi_handle, len); 6031 if (!buf) 6032 return QDF_STATUS_E_NOMEM; 6033 6034 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6035 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 6036 6037 WMITLV_SET_HDR(&cmd->tlv_header, 6038 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 6039 WMITLV_GET_STRUCT_TLVLEN 6040 (wmi_req_stats_ext_cmd_fixed_param)); 6041 cmd->vdev_id = preq->vdev_id; 6042 cmd->data_len = preq->request_data_len; 6043 6044 wmi_debug("The data len value is %u and vdev id set is %u", 6045 preq->request_data_len, preq->vdev_id); 6046 6047 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 6048 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 6049 6050 buf_ptr += WMI_TLV_HDR_SIZE; 6051 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 6052 6053 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 6054 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6055 WMI_REQUEST_STATS_EXT_CMDID); 6056 if (QDF_IS_STATUS_ERROR(ret)) { 6057 wmi_err("Failed to send notify cmd ret = %d", ret); 6058 wmi_buf_free(buf); 6059 } 6060 6061 return ret; 6062 } 6063 6064 /** 6065 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 6066 * @wmi_handle: wmi handle 6067 * @params: DHCP server offload info 6068 * 6069 * Return: QDF_STATUS_SUCCESS for success or error code 6070 */ 6071 static QDF_STATUS 6072 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 6073 struct dhcp_offload_info_params *params) 6074 { 6075 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 6076 wmi_buf_t buf; 6077 QDF_STATUS status; 6078 6079 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 6080 if (!buf) 6081 return QDF_STATUS_E_NOMEM; 6082 6083 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 6084 6085 WMITLV_SET_HDR(&cmd->tlv_header, 6086 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 6087 WMITLV_GET_STRUCT_TLVLEN 6088 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 6089 cmd->vdev_id = params->vdev_id; 6090 cmd->enable = params->dhcp_offload_enabled; 6091 cmd->num_client = params->dhcp_client_num; 6092 cmd->srv_ipv4 = params->dhcp_srv_addr; 6093 cmd->start_lsb = 0; 6094 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 6095 status = wmi_unified_cmd_send(wmi_handle, buf, 6096 sizeof(*cmd), 6097 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 6098 if (QDF_IS_STATUS_ERROR(status)) { 6099 wmi_err("Failed to send set_dhcp_server_offload cmd"); 6100 wmi_buf_free(buf); 6101 return QDF_STATUS_E_FAILURE; 6102 } 6103 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 6104 6105 return status; 6106 } 6107 6108 /** 6109 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 6110 * @wmi_handle: wmi handle 6111 * @param: pointer to pdev regdomain params 6112 * 6113 * Return: 0 for success or error code 6114 */ 6115 static QDF_STATUS 6116 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 6117 struct pdev_set_regdomain_params *param) 6118 { 6119 wmi_buf_t buf; 6120 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 6121 int32_t len = sizeof(*cmd); 6122 6123 buf = wmi_buf_alloc(wmi_handle, len); 6124 if (!buf) 6125 return QDF_STATUS_E_NOMEM; 6126 6127 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 6128 WMITLV_SET_HDR(&cmd->tlv_header, 6129 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 6130 WMITLV_GET_STRUCT_TLVLEN 6131 (wmi_pdev_set_regdomain_cmd_fixed_param)); 6132 6133 cmd->reg_domain = param->currentRDinuse; 6134 cmd->reg_domain_2G = param->currentRD2G; 6135 cmd->reg_domain_5G = param->currentRD5G; 6136 cmd->conformance_test_limit_2G = param->ctl_2G; 6137 cmd->conformance_test_limit_5G = param->ctl_5G; 6138 cmd->dfs_domain = param->dfsDomain; 6139 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6140 wmi_handle, 6141 param->pdev_id); 6142 6143 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 6144 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6145 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 6146 wmi_err("Failed to send pdev set regdomain command"); 6147 wmi_buf_free(buf); 6148 return QDF_STATUS_E_FAILURE; 6149 } 6150 6151 return QDF_STATUS_SUCCESS; 6152 } 6153 6154 /** 6155 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 6156 * @wmi_handle: wmi handle 6157 * @reg_dmn: reg domain 6158 * @regdmn2G: 2G reg domain 6159 * @regdmn5G: 5G reg domain 6160 * @ctl2G: 2G test limit 6161 * @ctl5G: 5G test limit 6162 * 6163 * Return: none 6164 */ 6165 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 6166 uint32_t reg_dmn, uint16_t regdmn2G, 6167 uint16_t regdmn5G, uint8_t ctl2G, 6168 uint8_t ctl5G) 6169 { 6170 wmi_buf_t buf; 6171 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 6172 int32_t len = sizeof(*cmd); 6173 6174 6175 buf = wmi_buf_alloc(wmi_handle, len); 6176 if (!buf) 6177 return QDF_STATUS_E_NOMEM; 6178 6179 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 6180 WMITLV_SET_HDR(&cmd->tlv_header, 6181 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 6182 WMITLV_GET_STRUCT_TLVLEN 6183 (wmi_pdev_set_regdomain_cmd_fixed_param)); 6184 cmd->reg_domain = reg_dmn; 6185 cmd->reg_domain_2G = regdmn2G; 6186 cmd->reg_domain_5G = regdmn5G; 6187 cmd->conformance_test_limit_2G = ctl2G; 6188 cmd->conformance_test_limit_5G = ctl5G; 6189 6190 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 6191 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 6192 cmd->conformance_test_limit_2G, 6193 cmd->conformance_test_limit_5G); 6194 6195 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 6196 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6197 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 6198 wmi_err("Failed to send pdev set regdomain command"); 6199 wmi_buf_free(buf); 6200 return QDF_STATUS_E_FAILURE; 6201 } 6202 6203 return QDF_STATUS_SUCCESS; 6204 } 6205 6206 /** 6207 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 6208 * @param: param sent from the host side 6209 * @cmd: param to be sent to the fw side 6210 */ 6211 static inline void copy_custom_aggr_bitmap( 6212 struct set_custom_aggr_size_params *param, 6213 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 6214 { 6215 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 6216 param->ac); 6217 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 6218 param->aggr_type); 6219 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 6220 param->tx_aggr_size_disable); 6221 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 6222 param->rx_aggr_size_disable); 6223 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 6224 param->tx_ac_enable); 6225 } 6226 6227 /** 6228 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 6229 * @wmi_handle: wmi handle 6230 * @param: pointer to hold custom aggr size params 6231 * 6232 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6233 */ 6234 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 6235 wmi_unified_t wmi_handle, 6236 struct set_custom_aggr_size_params *param) 6237 { 6238 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 6239 wmi_buf_t buf; 6240 int32_t len = sizeof(*cmd); 6241 6242 buf = wmi_buf_alloc(wmi_handle, len); 6243 if (!buf) 6244 return QDF_STATUS_E_FAILURE; 6245 6246 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 6247 wmi_buf_data(buf); 6248 WMITLV_SET_HDR(&cmd->tlv_header, 6249 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 6250 WMITLV_GET_STRUCT_TLVLEN( 6251 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 6252 cmd->vdev_id = param->vdev_id; 6253 cmd->tx_aggr_size = param->tx_aggr_size; 6254 cmd->rx_aggr_size = param->rx_aggr_size; 6255 copy_custom_aggr_bitmap(param, cmd); 6256 6257 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 6258 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 6259 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 6260 "tx_ac_enable=0x%X", 6261 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 6262 param->ac, param->aggr_type, param->tx_aggr_size_disable, 6263 param->rx_aggr_size_disable, param->tx_ac_enable); 6264 6265 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 6266 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6267 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 6268 wmi_err("Setting custom aggregation size failed"); 6269 wmi_buf_free(buf); 6270 return QDF_STATUS_E_FAILURE; 6271 } 6272 6273 return QDF_STATUS_SUCCESS; 6274 } 6275 6276 /** 6277 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 6278 * @param wmi_handle : handle to WMI. 6279 * @param param : pointer to tx antenna param 6280 * 6281 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6282 */ 6283 6284 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 6285 struct set_qdepth_thresh_params *param) 6286 { 6287 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 6288 wmi_msduq_qdepth_thresh_update *cmd_update; 6289 wmi_buf_t buf; 6290 int32_t len = 0; 6291 int i; 6292 uint8_t *buf_ptr; 6293 QDF_STATUS ret; 6294 6295 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 6296 wmi_err("Invalid Update Count!"); 6297 return QDF_STATUS_E_INVAL; 6298 } 6299 6300 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 6301 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 6302 param->num_of_msduq_updates); 6303 buf = wmi_buf_alloc(wmi_handle, len); 6304 6305 if (!buf) 6306 return QDF_STATUS_E_NOMEM; 6307 6308 buf_ptr = (uint8_t *)wmi_buf_data(buf); 6309 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 6310 buf_ptr; 6311 6312 WMITLV_SET_HDR(&cmd->tlv_header, 6313 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 6314 , WMITLV_GET_STRUCT_TLVLEN( 6315 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 6316 6317 cmd->pdev_id = 6318 wmi_handle->ops->convert_pdev_id_host_to_target( 6319 wmi_handle, 6320 param->pdev_id); 6321 cmd->vdev_id = param->vdev_id; 6322 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 6323 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 6324 6325 buf_ptr += sizeof( 6326 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 6327 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6328 param->num_of_msduq_updates * 6329 sizeof(wmi_msduq_qdepth_thresh_update)); 6330 buf_ptr += WMI_TLV_HDR_SIZE; 6331 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 6332 6333 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 6334 WMITLV_SET_HDR(&cmd_update->tlv_header, 6335 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 6336 WMITLV_GET_STRUCT_TLVLEN( 6337 wmi_msduq_qdepth_thresh_update)); 6338 cmd_update->tid_num = param->update_params[i].tid_num; 6339 cmd_update->msduq_update_mask = 6340 param->update_params[i].msduq_update_mask; 6341 cmd_update->qdepth_thresh_value = 6342 param->update_params[i].qdepth_thresh_value; 6343 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 6344 "mac_addr_upper4=%X, mac_addr_lower2:%X," 6345 " update mask=0x%X thresh val=0x%X", 6346 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 6347 cmd->peer_mac_address.mac_addr31to0, 6348 cmd->peer_mac_address.mac_addr47to32, 6349 cmd_update->msduq_update_mask, 6350 cmd_update->qdepth_thresh_value); 6351 cmd_update++; 6352 } 6353 6354 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 6355 cmd->vdev_id, 0); 6356 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6357 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 6358 6359 if (ret != 0) { 6360 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 6361 wmi_buf_free(buf); 6362 } 6363 6364 return ret; 6365 } 6366 6367 /** 6368 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 6369 * @wmi_handle: wmi handle 6370 * @param: pointer to hold vap dscp tid map param 6371 * 6372 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6373 */ 6374 static QDF_STATUS 6375 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 6376 struct vap_dscp_tid_map_params *param) 6377 { 6378 wmi_buf_t buf; 6379 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 6380 int32_t len = sizeof(*cmd); 6381 6382 buf = wmi_buf_alloc(wmi_handle, len); 6383 if (!buf) 6384 return QDF_STATUS_E_FAILURE; 6385 6386 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 6387 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 6388 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 6389 6390 cmd->vdev_id = param->vdev_id; 6391 cmd->enable_override = 0; 6392 6393 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 6394 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 6395 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6396 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 6397 wmi_err("Failed to set dscp cmd"); 6398 wmi_buf_free(buf); 6399 return QDF_STATUS_E_FAILURE; 6400 } 6401 6402 return QDF_STATUS_SUCCESS; 6403 } 6404 6405 /** 6406 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 6407 * @wmi_handle: wmi handle 6408 * @param: pointer to hold fwtest param 6409 * 6410 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6411 */ 6412 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 6413 struct set_fwtest_params *param) 6414 { 6415 wmi_fwtest_set_param_cmd_fixed_param *cmd; 6416 wmi_buf_t buf; 6417 int32_t len = sizeof(*cmd); 6418 6419 buf = wmi_buf_alloc(wmi_handle, len); 6420 6421 if (!buf) 6422 return QDF_STATUS_E_FAILURE; 6423 6424 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 6425 WMITLV_SET_HDR(&cmd->tlv_header, 6426 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 6427 WMITLV_GET_STRUCT_TLVLEN( 6428 wmi_fwtest_set_param_cmd_fixed_param)); 6429 cmd->param_id = param->arg; 6430 cmd->param_value = param->value; 6431 6432 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 6433 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 6434 wmi_err("Setting FW test param failed"); 6435 wmi_buf_free(buf); 6436 return QDF_STATUS_E_FAILURE; 6437 } 6438 6439 return QDF_STATUS_SUCCESS; 6440 } 6441 6442 /** 6443 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 6444 * 6445 * @param wmi_handle : handle to WMI. 6446 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6447 */ 6448 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 6449 { 6450 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 6451 wmi_buf_t buf; 6452 QDF_STATUS ret; 6453 int32_t len; 6454 6455 len = sizeof(*cmd); 6456 6457 buf = wmi_buf_alloc(wmi_handle, len); 6458 if (!buf) 6459 return QDF_STATUS_E_FAILURE; 6460 6461 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 6462 WMITLV_SET_HDR(&cmd->tlv_header, 6463 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 6464 WMITLV_GET_STRUCT_TLVLEN( 6465 wmi_pdev_dfs_disable_cmd_fixed_param)); 6466 /* Filling it with WMI_PDEV_ID_SOC for now */ 6467 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6468 wmi_handle, 6469 WMI_HOST_PDEV_ID_SOC); 6470 6471 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 6472 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6473 WMI_PDEV_DFS_DISABLE_CMDID); 6474 6475 if (ret != 0) { 6476 wmi_err("Sending PDEV DFS disable cmd failed"); 6477 wmi_buf_free(buf); 6478 } 6479 6480 return ret; 6481 } 6482 6483 /** 6484 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 6485 * 6486 * @param wmi_handle : handle to WMI. 6487 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6488 */ 6489 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 6490 { 6491 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 6492 wmi_buf_t buf; 6493 QDF_STATUS ret; 6494 int32_t len; 6495 6496 len = sizeof(*cmd); 6497 6498 buf = wmi_buf_alloc(wmi_handle, len); 6499 if (!buf) 6500 return QDF_STATUS_E_FAILURE; 6501 6502 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 6503 WMITLV_SET_HDR(&cmd->tlv_header, 6504 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 6505 WMITLV_GET_STRUCT_TLVLEN( 6506 wmi_pdev_dfs_enable_cmd_fixed_param)); 6507 /* Reserved for future use */ 6508 cmd->reserved0 = 0; 6509 6510 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 6511 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6512 WMI_PDEV_DFS_ENABLE_CMDID); 6513 6514 if (ret != 0) { 6515 wmi_err("Sending PDEV DFS enable cmd failed"); 6516 wmi_buf_free(buf); 6517 } 6518 6519 return ret; 6520 } 6521 6522 /** 6523 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 6524 * to fw 6525 * @wmi_handle: wmi handle 6526 * @param: pointer to hold periodic chan stats param 6527 * 6528 * Return: 0 for success or error code 6529 */ 6530 static QDF_STATUS 6531 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 6532 struct periodic_chan_stats_params *param) 6533 { 6534 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 6535 wmi_buf_t buf; 6536 QDF_STATUS ret; 6537 int32_t len; 6538 6539 len = sizeof(*cmd); 6540 6541 buf = wmi_buf_alloc(wmi_handle, len); 6542 if (!buf) 6543 return QDF_STATUS_E_FAILURE; 6544 6545 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 6546 wmi_buf_data(buf); 6547 WMITLV_SET_HDR(&cmd->tlv_header, 6548 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 6549 WMITLV_GET_STRUCT_TLVLEN( 6550 wmi_set_periodic_channel_stats_config_fixed_param)); 6551 cmd->enable = param->enable; 6552 cmd->stats_period = param->stats_period; 6553 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6554 wmi_handle, 6555 param->pdev_id); 6556 6557 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 6558 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6559 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 6560 6561 if (ret != 0) { 6562 wmi_err("Sending periodic chan stats config failed"); 6563 wmi_buf_free(buf); 6564 } 6565 6566 return ret; 6567 } 6568 6569 #ifdef WLAN_IOT_SIM_SUPPORT 6570 /** 6571 * send_simulation_test_cmd_tlv() - send simulation test command to fw 6572 * 6573 * @wmi_handle: wmi handle 6574 * @param: pointer to hold simulation test parameter 6575 * 6576 * Return: 0 for success or error code 6577 */ 6578 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 6579 struct simulation_test_params 6580 *param) 6581 { 6582 wmi_simulation_test_cmd_fixed_param *cmd; 6583 u32 wmi_buf_len; 6584 wmi_buf_t buf; 6585 u8 *buf_ptr; 6586 u32 aligned_len = 0; 6587 6588 wmi_buf_len = sizeof(*cmd); 6589 if (param->buf_len) { 6590 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 6591 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 6592 } 6593 6594 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 6595 if (!buf) { 6596 wmi_err("wmi_buf_alloc failed"); 6597 return QDF_STATUS_E_NOMEM; 6598 } 6599 6600 buf_ptr = wmi_buf_data(buf); 6601 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 6602 WMITLV_SET_HDR(&cmd->tlv_header, 6603 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 6604 WMITLV_GET_STRUCT_TLVLEN( 6605 wmi_simulation_test_cmd_fixed_param)); 6606 cmd->pdev_id = param->pdev_id; 6607 cmd->vdev_id = param->vdev_id; 6608 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 6609 cmd->test_cmd_type = param->test_cmd_type; 6610 cmd->test_subcmd_type = param->test_subcmd_type; 6611 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 6612 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 6613 param->frame_subtype); 6614 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 6615 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 6616 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 6617 cmd->buf_len = param->buf_len; 6618 6619 if (param->buf_len) { 6620 buf_ptr += sizeof(*cmd); 6621 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 6622 buf_ptr += WMI_TLV_HDR_SIZE; 6623 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 6624 } 6625 6626 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 6627 WMI_SIMULATION_TEST_CMDID)) { 6628 wmi_err("Failed to send test simulation cmd"); 6629 wmi_buf_free(buf); 6630 return QDF_STATUS_E_FAILURE; 6631 } 6632 6633 return QDF_STATUS_SUCCESS; 6634 } 6635 #endif 6636 6637 /** 6638 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 6639 * command to fw 6640 * @wmi_handle: wmi handle 6641 * @param: pointer to hold spectral config parameter 6642 * 6643 * Return: 0 for success or error code 6644 */ 6645 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 6646 struct vdev_spectral_configure_params *param) 6647 { 6648 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 6649 wmi_buf_t buf; 6650 QDF_STATUS ret; 6651 int32_t len; 6652 6653 len = sizeof(*cmd); 6654 buf = wmi_buf_alloc(wmi_handle, len); 6655 if (!buf) 6656 return QDF_STATUS_E_FAILURE; 6657 6658 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 6659 WMITLV_SET_HDR(&cmd->tlv_header, 6660 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 6661 WMITLV_GET_STRUCT_TLVLEN( 6662 wmi_vdev_spectral_configure_cmd_fixed_param)); 6663 6664 cmd->vdev_id = param->vdev_id; 6665 cmd->spectral_scan_count = param->count; 6666 cmd->spectral_scan_period = param->period; 6667 cmd->spectral_scan_priority = param->spectral_pri; 6668 cmd->spectral_scan_fft_size = param->fft_size; 6669 cmd->spectral_scan_gc_ena = param->gc_enable; 6670 cmd->spectral_scan_restart_ena = param->restart_enable; 6671 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 6672 cmd->spectral_scan_init_delay = param->init_delay; 6673 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 6674 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 6675 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 6676 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 6677 cmd->spectral_scan_rssi_thr = param->rssi_thr; 6678 cmd->spectral_scan_pwr_format = param->pwr_format; 6679 cmd->spectral_scan_rpt_mode = param->rpt_mode; 6680 cmd->spectral_scan_bin_scale = param->bin_scale; 6681 cmd->spectral_scan_dBm_adj = param->dbm_adj; 6682 cmd->spectral_scan_chn_mask = param->chn_mask; 6683 cmd->spectral_scan_mode = param->mode; 6684 cmd->spectral_scan_center_freq1 = param->center_freq1; 6685 cmd->spectral_scan_center_freq2 = param->center_freq2; 6686 cmd->spectral_scan_chan_width = param->chan_width; 6687 /* Not used, fill with zeros */ 6688 cmd->spectral_scan_chan_freq = 0; 6689 6690 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 6691 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6692 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 6693 6694 if (ret != 0) { 6695 wmi_err("Sending set quiet cmd failed"); 6696 wmi_buf_free(buf); 6697 } 6698 6699 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 6700 wmi_debug("vdev_id: %u spectral_scan_count: %u", 6701 param->vdev_id, param->count); 6702 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 6703 param->period, param->spectral_pri); 6704 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 6705 param->fft_size, param->gc_enable); 6706 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 6707 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 6708 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 6709 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 6710 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 6711 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 6712 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 6713 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 6714 param->rssi_thr, param->pwr_format); 6715 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 6716 param->rpt_mode, param->bin_scale); 6717 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 6718 param->dbm_adj, param->chn_mask); 6719 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 6720 param->mode, param->center_freq1); 6721 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 6722 param->center_freq2, param->chan_freq); 6723 wmi_debug("spectral_scan_chan_width: %u Status: %d", 6724 param->chan_width, ret); 6725 6726 return ret; 6727 } 6728 6729 /** 6730 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 6731 * command to fw 6732 * @wmi_handle: wmi handle 6733 * @param: pointer to hold spectral enable parameter 6734 * 6735 * Return: 0 for success or error code 6736 */ 6737 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 6738 struct vdev_spectral_enable_params *param) 6739 { 6740 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 6741 wmi_buf_t buf; 6742 QDF_STATUS ret; 6743 int32_t len; 6744 6745 len = sizeof(*cmd); 6746 buf = wmi_buf_alloc(wmi_handle, len); 6747 if (!buf) 6748 return QDF_STATUS_E_FAILURE; 6749 6750 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 6751 WMITLV_SET_HDR(&cmd->tlv_header, 6752 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 6753 WMITLV_GET_STRUCT_TLVLEN( 6754 wmi_vdev_spectral_enable_cmd_fixed_param)); 6755 6756 cmd->vdev_id = param->vdev_id; 6757 6758 if (param->active_valid) { 6759 cmd->trigger_cmd = param->active ? 1 : 2; 6760 /* 1: Trigger, 2: Clear Trigger */ 6761 } else { 6762 cmd->trigger_cmd = 0; /* 0: Ignore */ 6763 } 6764 6765 if (param->enabled_valid) { 6766 cmd->enable_cmd = param->enabled ? 1 : 2; 6767 /* 1: Enable 2: Disable */ 6768 } else { 6769 cmd->enable_cmd = 0; /* 0: Ignore */ 6770 } 6771 cmd->spectral_scan_mode = param->mode; 6772 6773 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 6774 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 6775 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 6776 6777 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 6778 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6779 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 6780 6781 if (ret != 0) { 6782 wmi_err("Sending scan enable CMD failed"); 6783 wmi_buf_free(buf); 6784 } 6785 6786 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 6787 ret); 6788 6789 return ret; 6790 } 6791 6792 #ifdef WLAN_CONV_SPECTRAL_ENABLE 6793 static QDF_STATUS 6794 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 6795 wmi_unified_t wmi_handle, 6796 uint8_t *event, struct spectral_startscan_resp_params *param) 6797 { 6798 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 6799 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 6800 6801 if (!wmi_handle) { 6802 wmi_err("WMI handle is null"); 6803 return QDF_STATUS_E_INVAL; 6804 } 6805 6806 if (!event) { 6807 wmi_err("WMI event is null"); 6808 return QDF_STATUS_E_INVAL; 6809 } 6810 6811 if (!param) { 6812 wmi_err("Spectral startscan response params is null"); 6813 return QDF_STATUS_E_INVAL; 6814 } 6815 6816 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 6817 if (!param_buf) 6818 return QDF_STATUS_E_INVAL; 6819 6820 ev = param_buf->fixed_param; 6821 if (!ev) 6822 return QDF_STATUS_E_INVAL; 6823 6824 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 6825 wmi_handle, 6826 ev->pdev_id); 6827 param->smode = ev->spectral_scan_mode; 6828 param->num_fft_bin_index = param_buf->num_fft_bin_index; 6829 wmi_debug("pdev id %u scan mode %u num_fft_bin_index %u", 6830 param->pdev_id, param->smode, param->num_fft_bin_index); 6831 6832 return QDF_STATUS_SUCCESS; 6833 } 6834 6835 static QDF_STATUS 6836 extract_pdev_sscan_fft_bin_index_tlv( 6837 wmi_unified_t wmi_handle, uint8_t *event, 6838 struct spectral_fft_bin_markers_160_165mhz *param) 6839 { 6840 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 6841 wmi_pdev_sscan_fft_bin_index *ev; 6842 6843 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 6844 if (!param_buf) 6845 return QDF_STATUS_E_INVAL; 6846 6847 ev = param_buf->fft_bin_index; 6848 if (!ev) 6849 return QDF_STATUS_E_INVAL; 6850 6851 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 6852 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 6853 param->start_pri80 + 1; 6854 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 6855 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 6856 param->start_sec80 + 1; 6857 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 6858 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 6859 param->start_5mhz + 1; 6860 param->is_valid = true; 6861 6862 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 6863 param->start_pri80, param->num_pri80, 6864 param->start_sec80, param->num_sec80, 6865 param->start_5mhz, param->num_5mhz); 6866 6867 return QDF_STATUS_SUCCESS; 6868 } 6869 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 6870 6871 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 6872 static inline void 6873 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 6874 struct thermal_mitigation_params *param) 6875 { 6876 tt_conf->client_id = param->client_id; 6877 tt_conf->priority = param->priority; 6878 } 6879 #else 6880 static inline void 6881 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 6882 struct thermal_mitigation_params *param) 6883 { 6884 } 6885 #endif 6886 6887 /** 6888 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 6889 * @param wmi_handle : handle to WMI. 6890 * @param param : pointer to hold thermal mitigation param 6891 * 6892 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6893 */ 6894 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 6895 wmi_unified_t wmi_handle, 6896 struct thermal_mitigation_params *param) 6897 { 6898 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 6899 wmi_therm_throt_level_config_info *lvl_conf = NULL; 6900 wmi_buf_t buf = NULL; 6901 uint8_t *buf_ptr = NULL; 6902 int error; 6903 int32_t len; 6904 int i; 6905 6906 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 6907 param->num_thermal_conf * 6908 sizeof(wmi_therm_throt_level_config_info); 6909 6910 buf = wmi_buf_alloc(wmi_handle, len); 6911 if (!buf) 6912 return QDF_STATUS_E_NOMEM; 6913 6914 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 6915 6916 /* init fixed params */ 6917 WMITLV_SET_HDR(tt_conf, 6918 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 6919 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 6920 6921 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6922 wmi_handle, 6923 param->pdev_id); 6924 tt_conf->enable = param->enable; 6925 tt_conf->dc = param->dc; 6926 tt_conf->dc_per_event = param->dc_per_event; 6927 tt_conf->therm_throt_levels = param->num_thermal_conf; 6928 wmi_fill_client_id_priority(tt_conf, param); 6929 buf_ptr = (uint8_t *) ++tt_conf; 6930 /* init TLV params */ 6931 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6932 (param->num_thermal_conf * 6933 sizeof(wmi_therm_throt_level_config_info))); 6934 6935 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 6936 for (i = 0; i < param->num_thermal_conf; i++) { 6937 WMITLV_SET_HDR(&lvl_conf->tlv_header, 6938 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 6939 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 6940 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 6941 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 6942 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 6943 lvl_conf->prio = param->levelconf[i].priority; 6944 lvl_conf++; 6945 } 6946 6947 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 6948 error = wmi_unified_cmd_send(wmi_handle, buf, len, 6949 WMI_THERM_THROT_SET_CONF_CMDID); 6950 if (QDF_IS_STATUS_ERROR(error)) { 6951 wmi_buf_free(buf); 6952 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 6953 } 6954 6955 return error; 6956 } 6957 6958 /** 6959 * send_coex_config_cmd_tlv() - send coex config command to fw 6960 * @wmi_handle: wmi handle 6961 * @param: pointer to coex config param 6962 * 6963 * Return: 0 for success or error code 6964 */ 6965 static QDF_STATUS 6966 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 6967 struct coex_config_params *param) 6968 { 6969 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 6970 wmi_buf_t buf; 6971 QDF_STATUS ret; 6972 int32_t len; 6973 6974 len = sizeof(*cmd); 6975 buf = wmi_buf_alloc(wmi_handle, len); 6976 if (!buf) 6977 return QDF_STATUS_E_FAILURE; 6978 6979 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 6980 WMITLV_SET_HDR(&cmd->tlv_header, 6981 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 6982 WMITLV_GET_STRUCT_TLVLEN( 6983 WMI_COEX_CONFIG_CMD_fixed_param)); 6984 6985 cmd->vdev_id = param->vdev_id; 6986 cmd->config_type = param->config_type; 6987 cmd->config_arg1 = param->config_arg1; 6988 cmd->config_arg2 = param->config_arg2; 6989 cmd->config_arg3 = param->config_arg3; 6990 cmd->config_arg4 = param->config_arg4; 6991 cmd->config_arg5 = param->config_arg5; 6992 cmd->config_arg6 = param->config_arg6; 6993 6994 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 6995 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6996 WMI_COEX_CONFIG_CMDID); 6997 6998 if (ret != 0) { 6999 wmi_err("Sending COEX CONFIG CMD failed"); 7000 wmi_buf_free(buf); 7001 } 7002 7003 return ret; 7004 } 7005 7006 #ifdef WLAN_SUPPORT_TWT 7007 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 7008 target_resource_config *tgt_res_cfg) 7009 { 7010 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 7011 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 7012 } 7013 #else 7014 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 7015 target_resource_config *tgt_res_cfg) 7016 { 7017 resource_cfg->twt_ap_pdev_count = 0; 7018 resource_cfg->twt_ap_sta_count = 0; 7019 } 7020 #endif 7021 7022 static 7023 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 7024 target_resource_config *tgt_res_cfg) 7025 { 7026 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 7027 resource_cfg->num_peers = tgt_res_cfg->num_peers; 7028 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 7029 resource_cfg->num_offload_reorder_buffs = 7030 tgt_res_cfg->num_offload_reorder_buffs; 7031 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 7032 resource_cfg->num_tids = tgt_res_cfg->num_tids; 7033 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 7034 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 7035 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 7036 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 7037 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 7038 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 7039 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 7040 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 7041 resource_cfg->scan_max_pending_req = 7042 tgt_res_cfg->scan_max_pending_req; 7043 resource_cfg->bmiss_offload_max_vdev = 7044 tgt_res_cfg->bmiss_offload_max_vdev; 7045 resource_cfg->roam_offload_max_vdev = 7046 tgt_res_cfg->roam_offload_max_vdev; 7047 resource_cfg->roam_offload_max_ap_profiles = 7048 tgt_res_cfg->roam_offload_max_ap_profiles; 7049 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 7050 resource_cfg->num_mcast_table_elems = 7051 tgt_res_cfg->num_mcast_table_elems; 7052 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 7053 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 7054 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 7055 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 7056 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 7057 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 7058 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 7059 resource_cfg->vow_config = tgt_res_cfg->vow_config; 7060 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 7061 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 7062 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 7063 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 7064 resource_cfg->num_tdls_conn_table_entries = 7065 tgt_res_cfg->num_tdls_conn_table_entries; 7066 resource_cfg->beacon_tx_offload_max_vdev = 7067 tgt_res_cfg->beacon_tx_offload_max_vdev; 7068 resource_cfg->num_multicast_filter_entries = 7069 tgt_res_cfg->num_multicast_filter_entries; 7070 resource_cfg->num_wow_filters = 7071 tgt_res_cfg->num_wow_filters; 7072 resource_cfg->num_keep_alive_pattern = 7073 tgt_res_cfg->num_keep_alive_pattern; 7074 resource_cfg->keep_alive_pattern_size = 7075 tgt_res_cfg->keep_alive_pattern_size; 7076 resource_cfg->max_tdls_concurrent_sleep_sta = 7077 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 7078 resource_cfg->max_tdls_concurrent_buffer_sta = 7079 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 7080 resource_cfg->wmi_send_separate = 7081 tgt_res_cfg->wmi_send_separate; 7082 resource_cfg->num_ocb_vdevs = 7083 tgt_res_cfg->num_ocb_vdevs; 7084 resource_cfg->num_ocb_channels = 7085 tgt_res_cfg->num_ocb_channels; 7086 resource_cfg->num_ocb_schedules = 7087 tgt_res_cfg->num_ocb_schedules; 7088 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 7089 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 7090 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 7091 resource_cfg->max_num_dbs_scan_duty_cycle = 7092 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 7093 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 7094 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 7095 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 7096 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 7097 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 7098 /* Deferred AI: Max rnr neighbors supported in multisoc case 7099 * where in SoC can support 6ghz. During WMI init of a SoC 7100 * currently there is no way to figure if another SOC is plugged in 7101 * and it can support 6Ghz. 7102 */ 7103 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 7104 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 7105 resource_cfg->ema_max_profile_period = 7106 tgt_res_cfg->ema_max_profile_period; 7107 7108 if (tgt_res_cfg->max_ndp_sessions) 7109 resource_cfg->max_ndp_sessions = 7110 tgt_res_cfg->max_ndp_sessions; 7111 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 7112 7113 if (tgt_res_cfg->atf_config) 7114 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 7115 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 7116 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 7117 resource_cfg->flag1, 1); 7118 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 7119 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 7120 resource_cfg->flag1, 1); 7121 if (tgt_res_cfg->cce_disable) 7122 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 7123 if (tgt_res_cfg->eapol_minrate_set) { 7124 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 7125 resource_cfg->flag1, 1); 7126 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 7127 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 7128 resource_cfg->flag1, 1); 7129 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 7130 resource_cfg->flag1, 7131 tgt_res_cfg->eapol_minrate_ac_set); 7132 } 7133 } 7134 if (tgt_res_cfg->new_htt_msg_format) { 7135 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 7136 resource_cfg->flag1, 1); 7137 } 7138 7139 if (tgt_res_cfg->peer_unmap_conf_support) 7140 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 7141 resource_cfg->flag1, 1); 7142 7143 if (tgt_res_cfg->tstamp64_en) 7144 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 7145 resource_cfg->flag1, 1); 7146 7147 if (tgt_res_cfg->three_way_coex_config_legacy_en) 7148 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 7149 resource_cfg->flag1, 1); 7150 if (tgt_res_cfg->pktcapture_support) 7151 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 7152 resource_cfg->flag1, 1); 7153 7154 /* 7155 * Control padding using config param/ini of iphdr_pad_config 7156 */ 7157 if (tgt_res_cfg->iphdr_pad_config) 7158 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 7159 resource_cfg->flag1, 1); 7160 7161 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 7162 tgt_res_cfg->ipa_disable); 7163 7164 if (tgt_res_cfg->time_sync_ftm) 7165 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 7166 1); 7167 7168 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 7169 resource_cfg->peer_map_unmap_v2_support = 7170 tgt_res_cfg->peer_map_unmap_v2; 7171 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 7172 if (tgt_res_cfg->re_ul_resp) 7173 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 7174 tgt_res_cfg->re_ul_resp); 7175 7176 7177 /* 7178 * Enable ast flow override per peer 7179 */ 7180 resource_cfg->msdu_flow_override_config0 = 0; 7181 WMI_MSDU_FLOW_AST_ENABLE_SET( 7182 resource_cfg->msdu_flow_override_config0, 7183 WMI_CONFIG_MSDU_AST_INDEX_1, 7184 tgt_res_cfg->ast_1_valid_mask_enable); 7185 7186 WMI_MSDU_FLOW_AST_ENABLE_SET( 7187 resource_cfg->msdu_flow_override_config0, 7188 WMI_CONFIG_MSDU_AST_INDEX_2, 7189 tgt_res_cfg->ast_2_valid_mask_enable); 7190 7191 WMI_MSDU_FLOW_AST_ENABLE_SET( 7192 resource_cfg->msdu_flow_override_config0, 7193 WMI_CONFIG_MSDU_AST_INDEX_3, 7194 tgt_res_cfg->ast_3_valid_mask_enable); 7195 7196 /* 7197 * Enable ast flow mask and TID valid mask configurations 7198 */ 7199 resource_cfg->msdu_flow_override_config1 = 0; 7200 7201 /*Enable UDP flow for Ast index 0*/ 7202 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7203 resource_cfg->msdu_flow_override_config1, 7204 WMI_CONFIG_MSDU_AST_INDEX_0, 7205 tgt_res_cfg->ast_0_flow_mask_enable); 7206 7207 /*Enable Non UDP flow for Ast index 1*/ 7208 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7209 resource_cfg->msdu_flow_override_config1, 7210 WMI_CONFIG_MSDU_AST_INDEX_1, 7211 tgt_res_cfg->ast_1_flow_mask_enable); 7212 7213 /*Enable Hi-Priority flow for Ast index 2*/ 7214 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7215 resource_cfg->msdu_flow_override_config1, 7216 WMI_CONFIG_MSDU_AST_INDEX_2, 7217 tgt_res_cfg->ast_2_flow_mask_enable); 7218 7219 /*Enable Low-Priority flow for Ast index 3*/ 7220 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7221 resource_cfg->msdu_flow_override_config1, 7222 WMI_CONFIG_MSDU_AST_INDEX_3, 7223 tgt_res_cfg->ast_3_flow_mask_enable); 7224 7225 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 7226 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 7227 resource_cfg->msdu_flow_override_config1, 7228 tgt_res_cfg->ast_tid_high_mask_enable); 7229 7230 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 7231 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 7232 resource_cfg->msdu_flow_override_config1, 7233 tgt_res_cfg->ast_tid_low_mask_enable); 7234 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 7235 resource_cfg->host_service_flags, 7236 tgt_res_cfg->nan_separate_iface_support); 7237 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 7238 resource_cfg->host_service_flags, 1); 7239 7240 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 7241 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 7242 } 7243 7244 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 7245 * @wmi_handle: pointer to wmi handle 7246 * @buf_ptr: pointer to current position in init command buffer 7247 * @len: pointer to length. This will be updated with current length of cmd 7248 * @param: point host parameters for init command 7249 * 7250 * Return: Updated pointer of buf_ptr. 7251 */ 7252 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 7253 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 7254 { 7255 uint16_t idx; 7256 7257 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 7258 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 7259 wmi_pdev_band_to_mac *band_to_mac; 7260 7261 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 7262 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 7263 sizeof(wmi_resource_config) + 7264 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 7265 sizeof(wlan_host_memory_chunk))); 7266 7267 WMITLV_SET_HDR(&hw_mode->tlv_header, 7268 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 7269 (WMITLV_GET_STRUCT_TLVLEN 7270 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 7271 7272 hw_mode->hw_mode_index = param->hw_mode_id; 7273 hw_mode->num_band_to_mac = param->num_band_to_mac; 7274 7275 buf_ptr = (uint8_t *) (hw_mode + 1); 7276 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 7277 WMI_TLV_HDR_SIZE); 7278 for (idx = 0; idx < param->num_band_to_mac; idx++) { 7279 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 7280 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 7281 WMITLV_GET_STRUCT_TLVLEN 7282 (wmi_pdev_band_to_mac)); 7283 band_to_mac[idx].pdev_id = 7284 wmi_handle->ops->convert_pdev_id_host_to_target( 7285 wmi_handle, 7286 param->band_to_mac[idx].pdev_id); 7287 band_to_mac[idx].start_freq = 7288 param->band_to_mac[idx].start_freq; 7289 band_to_mac[idx].end_freq = 7290 param->band_to_mac[idx].end_freq; 7291 } 7292 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 7293 (param->num_band_to_mac * 7294 sizeof(wmi_pdev_band_to_mac)) + 7295 WMI_TLV_HDR_SIZE; 7296 7297 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7298 (param->num_band_to_mac * 7299 sizeof(wmi_pdev_band_to_mac))); 7300 } 7301 7302 return buf_ptr; 7303 } 7304 7305 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 7306 wmi_init_cmd_fixed_param *cmd) 7307 { 7308 int num_whitelist; 7309 wmi_abi_version my_vers; 7310 7311 num_whitelist = sizeof(version_whitelist) / 7312 sizeof(wmi_whitelist_version_info); 7313 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 7314 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 7315 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 7316 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 7317 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 7318 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 7319 7320 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 7321 &my_vers, 7322 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 7323 &cmd->host_abi_vers); 7324 7325 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 7326 __func__, 7327 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 7328 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 7329 cmd->host_abi_vers.abi_version_ns_0, 7330 cmd->host_abi_vers.abi_version_ns_1, 7331 cmd->host_abi_vers.abi_version_ns_2, 7332 cmd->host_abi_vers.abi_version_ns_3); 7333 7334 /* Save version sent from host - 7335 * Will be used to check ready event 7336 */ 7337 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 7338 sizeof(wmi_abi_version)); 7339 } 7340 7341 /* 7342 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 7343 * @wmi_handle: Pointer to WMi handle 7344 * @ie_data: Pointer for ie data 7345 * 7346 * This function sends action frame tb ppdu cfg to FW 7347 * 7348 * Return: QDF_STATUS_SUCCESS for success otherwise failure 7349 * 7350 */ 7351 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 7352 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 7353 { 7354 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 7355 wmi_buf_t buf; 7356 uint8_t *buf_ptr; 7357 uint32_t len, frm_len_aligned; 7358 QDF_STATUS ret; 7359 7360 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 7361 /* Allocate memory for the WMI command */ 7362 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 7363 7364 buf = wmi_buf_alloc(wmi_handle, len); 7365 if (!buf) 7366 return QDF_STATUS_E_NOMEM; 7367 7368 buf_ptr = wmi_buf_data(buf); 7369 qdf_mem_zero(buf_ptr, len); 7370 7371 /* Populate the WMI command */ 7372 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 7373 7374 WMITLV_SET_HDR(&cmd->tlv_header, 7375 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 7376 WMITLV_GET_STRUCT_TLVLEN( 7377 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 7378 cmd->enable = cfg_msg->cfg; 7379 cmd->data_len = cfg_msg->frm_len; 7380 7381 buf_ptr += sizeof(*cmd); 7382 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 7383 buf_ptr += WMI_TLV_HDR_SIZE; 7384 7385 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 7386 7387 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7388 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 7389 if (QDF_IS_STATUS_ERROR(ret)) { 7390 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 7391 wmi_buf_free(buf); 7392 } 7393 7394 return ret; 7395 } 7396 7397 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 7398 { 7399 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 7400 wmi_service_ready_event_fixed_param *ev; 7401 7402 7403 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 7404 7405 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 7406 if (!ev) 7407 return QDF_STATUS_E_FAILURE; 7408 7409 /*Save fw version from service ready message */ 7410 /*This will be used while sending INIT message */ 7411 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 7412 sizeof(wmi_handle->fw_abi_version)); 7413 7414 return QDF_STATUS_SUCCESS; 7415 } 7416 7417 /** 7418 * wmi_unified_save_fw_version_cmd() - save fw version 7419 * @wmi_handle: pointer to wmi handle 7420 * @res_cfg: resource config 7421 * @num_mem_chunks: no of mem chunck 7422 * @mem_chunk: pointer to mem chunck structure 7423 * 7424 * This function sends IE information to firmware 7425 * 7426 * Return: QDF_STATUS_SUCCESS for success otherwise failure 7427 * 7428 */ 7429 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 7430 void *evt_buf) 7431 { 7432 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 7433 wmi_ready_event_fixed_param *ev = NULL; 7434 7435 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 7436 ev = param_buf->fixed_param; 7437 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 7438 &wmi_handle->final_abi_vers, 7439 &ev->fw_abi_vers)) { 7440 /* 7441 * Error: Our host version and the given firmware version 7442 * are incompatible. 7443 **/ 7444 wmi_debug("Error: Incompatible WMI version." 7445 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 7446 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 7447 abi_version_0), 7448 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 7449 abi_version_0), 7450 wmi_handle->final_abi_vers.abi_version_ns_0, 7451 wmi_handle->final_abi_vers.abi_version_ns_1, 7452 wmi_handle->final_abi_vers.abi_version_ns_2, 7453 wmi_handle->final_abi_vers.abi_version_ns_3, 7454 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 7455 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 7456 ev->fw_abi_vers.abi_version_ns_0, 7457 ev->fw_abi_vers.abi_version_ns_1, 7458 ev->fw_abi_vers.abi_version_ns_2, 7459 ev->fw_abi_vers.abi_version_ns_3); 7460 7461 return QDF_STATUS_E_FAILURE; 7462 } 7463 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 7464 sizeof(wmi_abi_version)); 7465 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 7466 sizeof(wmi_abi_version)); 7467 7468 return QDF_STATUS_SUCCESS; 7469 } 7470 7471 /** 7472 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 7473 * @handle: wmi handle 7474 * @event: Event received from FW 7475 * @len: Length of the event 7476 * 7477 * Enables the low frequency events and disables the high frequency 7478 * events. Bit 17 indicates if the event if low/high frequency. 7479 * 1 - high frequency, 0 - low frequency 7480 * 7481 * Return: 0 on successfully enabling/disabling the events 7482 */ 7483 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 7484 uint8_t *event, 7485 uint32_t len) 7486 { 7487 uint32_t num_of_diag_events_logs; 7488 wmi_diag_event_log_config_fixed_param *cmd; 7489 wmi_buf_t buf; 7490 uint8_t *buf_ptr; 7491 uint32_t *cmd_args, *evt_args; 7492 uint32_t buf_len, i; 7493 7494 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 7495 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 7496 7497 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 7498 7499 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 7500 if (!param_buf) { 7501 wmi_err("Invalid log supported event buffer"); 7502 return QDF_STATUS_E_INVAL; 7503 } 7504 wmi_event = param_buf->fixed_param; 7505 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 7506 7507 if (num_of_diag_events_logs > 7508 param_buf->num_diag_events_logs_list) { 7509 wmi_err("message number of events %d is more than tlv hdr content %d", 7510 num_of_diag_events_logs, 7511 param_buf->num_diag_events_logs_list); 7512 return QDF_STATUS_E_INVAL; 7513 } 7514 7515 evt_args = param_buf->diag_events_logs_list; 7516 if (!evt_args) { 7517 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 7518 num_of_diag_events_logs); 7519 return QDF_STATUS_E_INVAL; 7520 } 7521 7522 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 7523 7524 /* Free any previous allocation */ 7525 if (wmi_handle->events_logs_list) { 7526 qdf_mem_free(wmi_handle->events_logs_list); 7527 wmi_handle->events_logs_list = NULL; 7528 } 7529 7530 if (num_of_diag_events_logs > 7531 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 7532 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 7533 QDF_ASSERT(0); 7534 return QDF_STATUS_E_INVAL; 7535 } 7536 /* Store the event list for run time enable/disable */ 7537 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 7538 sizeof(uint32_t)); 7539 if (!wmi_handle->events_logs_list) 7540 return QDF_STATUS_E_NOMEM; 7541 7542 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 7543 7544 /* Prepare the send buffer */ 7545 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 7546 (num_of_diag_events_logs * sizeof(uint32_t)); 7547 7548 buf = wmi_buf_alloc(wmi_handle, buf_len); 7549 if (!buf) { 7550 qdf_mem_free(wmi_handle->events_logs_list); 7551 wmi_handle->events_logs_list = NULL; 7552 return QDF_STATUS_E_NOMEM; 7553 } 7554 7555 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 7556 buf_ptr = (uint8_t *) cmd; 7557 7558 WMITLV_SET_HDR(&cmd->tlv_header, 7559 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 7560 WMITLV_GET_STRUCT_TLVLEN( 7561 wmi_diag_event_log_config_fixed_param)); 7562 7563 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 7564 7565 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 7566 7567 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7568 (num_of_diag_events_logs * sizeof(uint32_t))); 7569 7570 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 7571 7572 /* Populate the events */ 7573 for (i = 0; i < num_of_diag_events_logs; i++) { 7574 /* Low freq (0) - Enable (1) the event 7575 * High freq (1) - Disable (0) the event 7576 */ 7577 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 7578 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 7579 /* Set the event ID */ 7580 WMI_DIAG_ID_SET(cmd_args[i], 7581 WMI_DIAG_ID_GET(evt_args[i])); 7582 /* Set the type */ 7583 WMI_DIAG_TYPE_SET(cmd_args[i], 7584 WMI_DIAG_TYPE_GET(evt_args[i])); 7585 /* Storing the event/log list in WMI */ 7586 wmi_handle->events_logs_list[i] = evt_args[i]; 7587 } 7588 7589 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 7590 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 7591 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 7592 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 7593 wmi_buf_free(buf); 7594 /* Not clearing events_logs_list, though wmi cmd failed. 7595 * Host can still have this list 7596 */ 7597 return QDF_STATUS_E_INVAL; 7598 } 7599 7600 return 0; 7601 } 7602 7603 /** 7604 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 7605 * @wmi_handle: wmi handle 7606 * @start_log: Start logging related parameters 7607 * 7608 * Send the command to the FW based on which specific logging of diag 7609 * event/log id can be started/stopped 7610 * 7611 * Return: None 7612 */ 7613 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 7614 struct wmi_wifi_start_log *start_log) 7615 { 7616 wmi_diag_event_log_config_fixed_param *cmd; 7617 wmi_buf_t buf; 7618 uint8_t *buf_ptr; 7619 uint32_t len, count, log_level, i; 7620 uint32_t *cmd_args; 7621 uint32_t total_len; 7622 count = 0; 7623 7624 if (!wmi_handle->events_logs_list) { 7625 wmi_debug("Not received event/log list from FW, yet"); 7626 return QDF_STATUS_E_NOMEM; 7627 } 7628 /* total_len stores the number of events where BITS 17 and 18 are set. 7629 * i.e., events of high frequency (17) and for extended debugging (18) 7630 */ 7631 total_len = 0; 7632 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 7633 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 7634 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 7635 total_len++; 7636 } 7637 7638 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 7639 (total_len * sizeof(uint32_t)); 7640 7641 buf = wmi_buf_alloc(wmi_handle, len); 7642 if (!buf) 7643 return QDF_STATUS_E_NOMEM; 7644 7645 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 7646 buf_ptr = (uint8_t *) cmd; 7647 7648 WMITLV_SET_HDR(&cmd->tlv_header, 7649 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 7650 WMITLV_GET_STRUCT_TLVLEN( 7651 wmi_diag_event_log_config_fixed_param)); 7652 7653 cmd->num_of_diag_events_logs = total_len; 7654 7655 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 7656 7657 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7658 (total_len * sizeof(uint32_t))); 7659 7660 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 7661 7662 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 7663 log_level = 1; 7664 else 7665 log_level = 0; 7666 7667 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 7668 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 7669 uint32_t val = wmi_handle->events_logs_list[i]; 7670 if ((WMI_DIAG_FREQUENCY_GET(val)) && 7671 (WMI_DIAG_EXT_FEATURE_GET(val))) { 7672 7673 WMI_DIAG_ID_SET(cmd_args[count], 7674 WMI_DIAG_ID_GET(val)); 7675 WMI_DIAG_TYPE_SET(cmd_args[count], 7676 WMI_DIAG_TYPE_GET(val)); 7677 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 7678 log_level); 7679 wmi_debug("Idx:%d, val:%x", i, val); 7680 count++; 7681 } 7682 } 7683 7684 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 7685 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7686 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 7687 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 7688 wmi_buf_free(buf); 7689 return QDF_STATUS_E_INVAL; 7690 } 7691 7692 return QDF_STATUS_SUCCESS; 7693 } 7694 7695 /** 7696 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 7697 * @wmi_handle: WMI handle 7698 * 7699 * This function is used to send the flush command to the FW, 7700 * that will flush the fw logs that are residue in the FW 7701 * 7702 * Return: None 7703 */ 7704 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 7705 { 7706 wmi_debug_mesg_flush_fixed_param *cmd; 7707 wmi_buf_t buf; 7708 int len = sizeof(*cmd); 7709 QDF_STATUS ret; 7710 7711 buf = wmi_buf_alloc(wmi_handle, len); 7712 if (!buf) 7713 return QDF_STATUS_E_NOMEM; 7714 7715 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 7716 WMITLV_SET_HDR(&cmd->tlv_header, 7717 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 7718 WMITLV_GET_STRUCT_TLVLEN( 7719 wmi_debug_mesg_flush_fixed_param)); 7720 cmd->reserved0 = 0; 7721 7722 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 7723 ret = wmi_unified_cmd_send(wmi_handle, 7724 buf, 7725 len, 7726 WMI_DEBUG_MESG_FLUSH_CMDID); 7727 if (QDF_IS_STATUS_ERROR(ret)) { 7728 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 7729 wmi_buf_free(buf); 7730 return QDF_STATUS_E_INVAL; 7731 } 7732 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 7733 7734 return ret; 7735 } 7736 7737 #ifdef BIG_ENDIAN_HOST 7738 /** 7739 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 7740 * @param data_len - data length 7741 * @param data - pointer to data 7742 * 7743 * Return: QDF_STATUS - success or error status 7744 */ 7745 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 7746 struct fips_params *param) 7747 { 7748 unsigned char *key_unaligned, *data_unaligned; 7749 int c; 7750 u_int8_t *key_aligned = NULL; 7751 u_int8_t *data_aligned = NULL; 7752 7753 /* Assigning unaligned space to copy the key */ 7754 key_unaligned = qdf_mem_malloc( 7755 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 7756 data_unaligned = qdf_mem_malloc( 7757 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 7758 7759 /* Checking if kmalloc is successful to allocate space */ 7760 if (!key_unaligned) 7761 return QDF_STATUS_SUCCESS; 7762 /* Checking if space is aligned */ 7763 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 7764 /* align to 4 */ 7765 key_aligned = 7766 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 7767 FIPS_ALIGN); 7768 } else { 7769 key_aligned = (u_int8_t *)key_unaligned; 7770 } 7771 7772 /* memset and copy content from key to key aligned */ 7773 OS_MEMSET(key_aligned, 0, param->key_len); 7774 OS_MEMCPY(key_aligned, param->key, param->key_len); 7775 7776 /* print a hexdump for host debug */ 7777 print_hex_dump(KERN_DEBUG, 7778 "\t Aligned and Copied Key:@@@@ ", 7779 DUMP_PREFIX_NONE, 7780 16, 1, key_aligned, param->key_len, true); 7781 7782 /* Checking if kmalloc is successful to allocate space */ 7783 if (!data_unaligned) 7784 return QDF_STATUS_SUCCESS; 7785 /* Checking of space is aligned */ 7786 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 7787 /* align to 4 */ 7788 data_aligned = 7789 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 7790 FIPS_ALIGN); 7791 } else { 7792 data_aligned = (u_int8_t *)data_unaligned; 7793 } 7794 7795 /* memset and copy content from data to data aligned */ 7796 OS_MEMSET(data_aligned, 0, param->data_len); 7797 OS_MEMCPY(data_aligned, param->data, param->data_len); 7798 7799 /* print a hexdump for host debug */ 7800 print_hex_dump(KERN_DEBUG, 7801 "\t Properly Aligned and Copied Data:@@@@ ", 7802 DUMP_PREFIX_NONE, 7803 16, 1, data_aligned, param->data_len, true); 7804 7805 /* converting to little Endian both key_aligned and 7806 * data_aligned*/ 7807 for (c = 0; c < param->key_len/4; c++) { 7808 *((u_int32_t *)key_aligned+c) = 7809 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 7810 } 7811 for (c = 0; c < param->data_len/4; c++) { 7812 *((u_int32_t *)data_aligned+c) = 7813 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 7814 } 7815 7816 /* update endian data to key and data vectors */ 7817 OS_MEMCPY(param->key, key_aligned, param->key_len); 7818 OS_MEMCPY(param->data, data_aligned, param->data_len); 7819 7820 /* clean up allocated spaces */ 7821 qdf_mem_free(key_unaligned); 7822 key_unaligned = NULL; 7823 key_aligned = NULL; 7824 7825 qdf_mem_free(data_unaligned); 7826 data_unaligned = NULL; 7827 data_aligned = NULL; 7828 7829 return QDF_STATUS_SUCCESS; 7830 } 7831 #else 7832 /** 7833 * fips_align_data_be() - DUMMY for LE platform 7834 * 7835 * Return: QDF_STATUS - success 7836 */ 7837 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 7838 struct fips_params *param) 7839 { 7840 return QDF_STATUS_SUCCESS; 7841 } 7842 #endif 7843 7844 #ifdef WLAN_FEATURE_DISA 7845 /** 7846 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 7847 * @wmi_handle: wmi handle 7848 * @params: encrypt/decrypt params 7849 * 7850 * Return: QDF_STATUS_SUCCESS for success or error code 7851 */ 7852 static QDF_STATUS 7853 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 7854 struct disa_encrypt_decrypt_req_params 7855 *encrypt_decrypt_params) 7856 { 7857 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 7858 wmi_buf_t wmi_buf; 7859 uint8_t *buf_ptr; 7860 QDF_STATUS ret; 7861 uint32_t len; 7862 7863 wmi_debug("Send encrypt decrypt cmd"); 7864 7865 len = sizeof(*cmd) + 7866 encrypt_decrypt_params->data_len + 7867 WMI_TLV_HDR_SIZE; 7868 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7869 if (!wmi_buf) 7870 return QDF_STATUS_E_NOMEM; 7871 7872 buf_ptr = wmi_buf_data(wmi_buf); 7873 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 7874 7875 WMITLV_SET_HDR(&cmd->tlv_header, 7876 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 7877 WMITLV_GET_STRUCT_TLVLEN( 7878 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 7879 7880 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 7881 cmd->key_flag = encrypt_decrypt_params->key_flag; 7882 cmd->key_idx = encrypt_decrypt_params->key_idx; 7883 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 7884 cmd->key_len = encrypt_decrypt_params->key_len; 7885 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 7886 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 7887 7888 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 7889 encrypt_decrypt_params->key_len); 7890 7891 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 7892 MAX_MAC_HEADER_LEN); 7893 7894 cmd->data_len = encrypt_decrypt_params->data_len; 7895 7896 if (cmd->data_len) { 7897 buf_ptr += sizeof(*cmd); 7898 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 7899 roundup(encrypt_decrypt_params->data_len, 7900 sizeof(uint32_t))); 7901 buf_ptr += WMI_TLV_HDR_SIZE; 7902 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 7903 encrypt_decrypt_params->data_len); 7904 } 7905 7906 /* This conversion is to facilitate data to FW in little endian */ 7907 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 7908 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 7909 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 7910 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 7911 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 7912 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 7913 7914 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 7915 ret = wmi_unified_cmd_send(wmi_handle, 7916 wmi_buf, len, 7917 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 7918 if (QDF_IS_STATUS_ERROR(ret)) { 7919 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 7920 wmi_buf_free(wmi_buf); 7921 } 7922 7923 return ret; 7924 } 7925 #endif /* WLAN_FEATURE_DISA */ 7926 7927 /** 7928 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 7929 * @wmi_handle: wmi handle 7930 * @param: pointer to hold pdev fips param 7931 * 7932 * Return: 0 for success or error code 7933 */ 7934 static QDF_STATUS 7935 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 7936 struct fips_params *param) 7937 { 7938 wmi_pdev_fips_cmd_fixed_param *cmd; 7939 wmi_buf_t buf; 7940 uint8_t *buf_ptr; 7941 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 7942 QDF_STATUS retval = QDF_STATUS_SUCCESS; 7943 7944 /* Length TLV placeholder for array of bytes */ 7945 len += WMI_TLV_HDR_SIZE; 7946 if (param->data_len) 7947 len += (param->data_len*sizeof(uint8_t)); 7948 7949 /* 7950 * Data length must be multiples of 16 bytes - checked against 0xF - 7951 * and must be less than WMI_SVC_MSG_SIZE - static size of 7952 * wmi_pdev_fips_cmd structure 7953 */ 7954 7955 /* do sanity on the input */ 7956 if (!(((param->data_len & 0xF) == 0) && 7957 ((param->data_len > 0) && 7958 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 7959 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 7960 return QDF_STATUS_E_INVAL; 7961 } 7962 7963 buf = wmi_buf_alloc(wmi_handle, len); 7964 if (!buf) 7965 return QDF_STATUS_E_FAILURE; 7966 7967 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7968 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 7969 WMITLV_SET_HDR(&cmd->tlv_header, 7970 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 7971 WMITLV_GET_STRUCT_TLVLEN 7972 (wmi_pdev_fips_cmd_fixed_param)); 7973 7974 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7975 wmi_handle, 7976 param->pdev_id); 7977 if (param->key && param->data) { 7978 cmd->key_len = param->key_len; 7979 cmd->data_len = param->data_len; 7980 cmd->fips_cmd = !!(param->op); 7981 7982 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 7983 return QDF_STATUS_E_FAILURE; 7984 7985 qdf_mem_copy(cmd->key, param->key, param->key_len); 7986 7987 if (param->mode == FIPS_ENGINE_AES_CTR || 7988 param->mode == FIPS_ENGINE_AES_MIC) { 7989 cmd->mode = param->mode; 7990 } else { 7991 cmd->mode = FIPS_ENGINE_AES_CTR; 7992 } 7993 qdf_print("Key len = %d, Data len = %d", 7994 cmd->key_len, cmd->data_len); 7995 7996 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 7997 cmd->key, cmd->key_len, true); 7998 buf_ptr += sizeof(*cmd); 7999 8000 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 8001 8002 buf_ptr += WMI_TLV_HDR_SIZE; 8003 if (param->data_len) 8004 qdf_mem_copy(buf_ptr, 8005 (uint8_t *) param->data, param->data_len); 8006 8007 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 8008 16, 1, buf_ptr, cmd->data_len, true); 8009 8010 buf_ptr += param->data_len; 8011 8012 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 8013 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 8014 WMI_PDEV_FIPS_CMDID); 8015 qdf_print("%s return value %d", __func__, retval); 8016 } else { 8017 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 8018 wmi_buf_free(buf); 8019 retval = -QDF_STATUS_E_BADMSG; 8020 } 8021 8022 return retval; 8023 } 8024 8025 /** 8026 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 8027 * to fw 8028 * @wmi_handle: wmi handle 8029 * @param: pointer to wlan profile param 8030 * 8031 * Return: 0 for success or error code 8032 */ 8033 static QDF_STATUS 8034 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 8035 struct wlan_profile_params *param) 8036 { 8037 wmi_buf_t buf; 8038 uint16_t len; 8039 QDF_STATUS ret; 8040 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 8041 8042 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 8043 buf = wmi_buf_alloc(wmi_handle, len); 8044 if (!buf) { 8045 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 8046 return QDF_STATUS_E_NOMEM; 8047 } 8048 8049 profile_enable_cmd = 8050 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 8051 wmi_buf_data(buf); 8052 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 8053 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 8054 WMITLV_GET_STRUCT_TLVLEN 8055 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 8056 8057 profile_enable_cmd->profile_id = param->profile_id; 8058 profile_enable_cmd->enable = param->enable; 8059 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 8060 NO_SESSION, 0); 8061 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8062 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 8063 if (ret) { 8064 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 8065 wmi_buf_free(buf); 8066 } 8067 return ret; 8068 } 8069 8070 /** 8071 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 8072 * to fw 8073 * @wmi_handle: wmi handle 8074 * @param: pointer to wlan profile param 8075 * 8076 * Return: 0 for success or error code 8077 */ 8078 static QDF_STATUS 8079 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 8080 struct wlan_profile_params *param) 8081 { 8082 wmi_buf_t buf; 8083 uint16_t len; 8084 QDF_STATUS ret; 8085 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 8086 8087 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 8088 buf = wmi_buf_alloc(wmi_handle, len); 8089 if (!buf) { 8090 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 8091 return QDF_STATUS_E_NOMEM; 8092 } 8093 8094 prof_trig_cmd = 8095 (wmi_wlan_profile_trigger_cmd_fixed_param *) 8096 wmi_buf_data(buf); 8097 8098 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 8099 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 8100 WMITLV_GET_STRUCT_TLVLEN 8101 (wmi_wlan_profile_trigger_cmd_fixed_param)); 8102 8103 prof_trig_cmd->enable = param->enable; 8104 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 8105 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8106 WMI_WLAN_PROFILE_TRIGGER_CMDID); 8107 if (ret) { 8108 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 8109 wmi_buf_free(buf); 8110 } 8111 return ret; 8112 } 8113 8114 /** 8115 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 8116 * to fw 8117 * @wmi_handle: wmi handle 8118 * @param: pointer to wlan profile param 8119 * 8120 * Return: 0 for success or error code 8121 */ 8122 static QDF_STATUS 8123 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 8124 struct wlan_profile_params *param) 8125 { 8126 wmi_buf_t buf; 8127 int32_t len = 0; 8128 QDF_STATUS ret; 8129 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 8130 8131 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 8132 buf = wmi_buf_alloc(wmi_handle, len); 8133 if (!buf) { 8134 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 8135 return QDF_STATUS_E_NOMEM; 8136 } 8137 8138 hist_intvl_cmd = 8139 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 8140 wmi_buf_data(buf); 8141 8142 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 8143 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 8144 WMITLV_GET_STRUCT_TLVLEN 8145 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 8146 8147 hist_intvl_cmd->profile_id = param->profile_id; 8148 hist_intvl_cmd->value = param->enable; 8149 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 8150 NO_SESSION, 0); 8151 8152 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8153 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 8154 if (ret) { 8155 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 8156 wmi_buf_free(buf); 8157 } 8158 return ret; 8159 } 8160 8161 /** 8162 * send_fw_test_cmd_tlv() - send fw test command to fw. 8163 * @wmi_handle: wmi handle 8164 * @wmi_fwtest: fw test command 8165 * 8166 * This function sends fw test command to fw. 8167 * 8168 * Return: CDF STATUS 8169 */ 8170 static 8171 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 8172 struct set_fwtest_params *wmi_fwtest) 8173 { 8174 wmi_fwtest_set_param_cmd_fixed_param *cmd; 8175 wmi_buf_t wmi_buf; 8176 uint16_t len; 8177 8178 len = sizeof(*cmd); 8179 8180 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8181 if (!wmi_buf) 8182 return QDF_STATUS_E_NOMEM; 8183 8184 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 8185 WMITLV_SET_HDR(&cmd->tlv_header, 8186 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 8187 WMITLV_GET_STRUCT_TLVLEN( 8188 wmi_fwtest_set_param_cmd_fixed_param)); 8189 cmd->param_id = wmi_fwtest->arg; 8190 cmd->param_value = wmi_fwtest->value; 8191 8192 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 8193 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8194 WMI_FWTEST_CMDID)) { 8195 wmi_err("Failed to send fw test command"); 8196 wmi_buf_free(wmi_buf); 8197 return QDF_STATUS_E_FAILURE; 8198 } 8199 8200 return QDF_STATUS_SUCCESS; 8201 } 8202 8203 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 8204 { 8205 uint16_t len = 0; 8206 8207 if (config == WFA_CONFIG_RXNE) 8208 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 8209 else 8210 len += WMI_TLV_HDR_SIZE; 8211 8212 if (config == WFA_CONFIG_CSA) 8213 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 8214 else 8215 len += WMI_TLV_HDR_SIZE; 8216 8217 if (config == WFA_CONFIG_OCV) 8218 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 8219 else 8220 len += WMI_TLV_HDR_SIZE; 8221 8222 if (config == WFA_CONFIG_SA_QUERY) 8223 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 8224 else 8225 len += WMI_TLV_HDR_SIZE; 8226 8227 return len; 8228 } 8229 8230 /** 8231 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 8232 * @host_frmtype: Host defined OCV frame type 8233 * @ocv_frmtype: Pointer to hold WMI OCV frame type 8234 * 8235 * This function converts and fills host defined OCV frame type into WMI OCV 8236 * frame type. 8237 * 8238 * Return: CDF STATUS 8239 */ 8240 static QDF_STATUS 8241 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 8242 { 8243 switch (host_frmtype) { 8244 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 8245 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 8246 break; 8247 8248 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 8249 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 8250 break; 8251 8252 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 8253 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 8254 break; 8255 8256 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 8257 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 8258 break; 8259 8260 default: 8261 wmi_err("Invalid command type cmd %d", host_frmtype); 8262 return QDF_STATUS_E_FAILURE; 8263 } 8264 8265 return QDF_STATUS_SUCCESS; 8266 } 8267 8268 /** 8269 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 8270 * @wmi_handle: wmi handle 8271 * @wmi_wfatest: wfa test command 8272 * 8273 * This function sends wfa test command to fw. 8274 * 8275 * Return: CDF STATUS 8276 */ 8277 static 8278 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 8279 struct set_wfatest_params *wmi_wfatest) 8280 { 8281 wmi_wfa_config_cmd_fixed_param *cmd; 8282 wmi_wfa_config_rsnxe *rxne; 8283 wmi_wfa_config_csa *csa; 8284 wmi_wfa_config_ocv *ocv; 8285 wmi_wfa_config_saquery *saquery; 8286 wmi_buf_t wmi_buf; 8287 uint16_t len = sizeof(*cmd); 8288 uint8_t *buf_ptr; 8289 8290 len += wfa_config_param_len(wmi_wfatest->cmd); 8291 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8292 if (!wmi_buf) 8293 return QDF_STATUS_E_NOMEM; 8294 8295 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 8296 WMITLV_SET_HDR(&cmd->tlv_header, 8297 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 8298 WMITLV_GET_STRUCT_TLVLEN( 8299 wmi_wfa_config_cmd_fixed_param)); 8300 8301 cmd->vdev_id = wmi_wfatest->vdev_id; 8302 buf_ptr = (uint8_t *)(cmd + 1); 8303 8304 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 8305 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8306 sizeof(wmi_wfa_config_rsnxe)); 8307 buf_ptr += WMI_TLV_HDR_SIZE; 8308 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 8309 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 8310 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 8311 rxne->rsnxe_param = wmi_wfatest->value; 8312 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 8313 } else { 8314 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8315 buf_ptr += WMI_TLV_HDR_SIZE; 8316 } 8317 8318 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 8319 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8320 sizeof(wmi_wfa_config_csa)); 8321 buf_ptr += WMI_TLV_HDR_SIZE; 8322 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 8323 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 8324 csa = (wmi_wfa_config_csa *)buf_ptr; 8325 csa->ignore_csa = wmi_wfatest->value; 8326 buf_ptr += sizeof(wmi_wfa_config_csa); 8327 } else { 8328 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8329 buf_ptr += WMI_TLV_HDR_SIZE; 8330 } 8331 8332 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 8333 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8334 sizeof(wmi_wfa_config_ocv)); 8335 buf_ptr += WMI_TLV_HDR_SIZE; 8336 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 8337 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 8338 ocv = (wmi_wfa_config_ocv *)buf_ptr; 8339 8340 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 8341 &ocv->frame_types)) 8342 goto error; 8343 8344 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 8345 buf_ptr += sizeof(wmi_wfa_config_ocv); 8346 } else { 8347 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8348 buf_ptr += WMI_TLV_HDR_SIZE; 8349 } 8350 8351 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 8352 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8353 sizeof(wmi_wfa_config_saquery)); 8354 buf_ptr += WMI_TLV_HDR_SIZE; 8355 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 8356 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 8357 8358 saquery = (wmi_wfa_config_saquery *)buf_ptr; 8359 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 8360 } else { 8361 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8362 buf_ptr += WMI_TLV_HDR_SIZE; 8363 } 8364 8365 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 8366 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8367 WMI_WFA_CONFIG_CMDID)) { 8368 wmi_err("Failed to send wfa test command"); 8369 goto error; 8370 } 8371 8372 return QDF_STATUS_SUCCESS; 8373 8374 error: 8375 wmi_buf_free(wmi_buf); 8376 return QDF_STATUS_E_FAILURE; 8377 } 8378 8379 /** 8380 * send_unit_test_cmd_tlv() - send unit test command to fw. 8381 * @wmi_handle: wmi handle 8382 * @wmi_utest: unit test command 8383 * 8384 * This function send unit test command to fw. 8385 * 8386 * Return: CDF STATUS 8387 */ 8388 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 8389 struct wmi_unit_test_cmd *wmi_utest) 8390 { 8391 wmi_unit_test_cmd_fixed_param *cmd; 8392 wmi_buf_t wmi_buf; 8393 uint8_t *buf_ptr; 8394 int i; 8395 uint16_t len, args_tlv_len; 8396 uint32_t *unit_test_cmd_args; 8397 8398 args_tlv_len = 8399 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 8400 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 8401 8402 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8403 if (!wmi_buf) 8404 return QDF_STATUS_E_NOMEM; 8405 8406 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 8407 buf_ptr = (uint8_t *) cmd; 8408 WMITLV_SET_HDR(&cmd->tlv_header, 8409 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 8410 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 8411 cmd->vdev_id = wmi_utest->vdev_id; 8412 cmd->module_id = wmi_utest->module_id; 8413 cmd->num_args = wmi_utest->num_args; 8414 cmd->diag_token = wmi_utest->diag_token; 8415 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 8416 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8417 (wmi_utest->num_args * sizeof(uint32_t))); 8418 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8419 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 8420 cmd->vdev_id, cmd->module_id, cmd->diag_token); 8421 wmi_debug("%d num of args = ", wmi_utest->num_args); 8422 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 8423 unit_test_cmd_args[i] = wmi_utest->args[i]; 8424 wmi_debug("%d,", wmi_utest->args[i]); 8425 } 8426 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 8427 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8428 WMI_UNIT_TEST_CMDID)) { 8429 wmi_err("Failed to send unit test command"); 8430 wmi_buf_free(wmi_buf); 8431 return QDF_STATUS_E_FAILURE; 8432 } 8433 8434 return QDF_STATUS_SUCCESS; 8435 } 8436 8437 /** 8438 * send_power_dbg_cmd_tlv() - send power debug commands 8439 * @wmi_handle: wmi handle 8440 * @param: wmi power debug parameter 8441 * 8442 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 8443 * 8444 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 8445 */ 8446 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 8447 struct wmi_power_dbg_params *param) 8448 { 8449 wmi_buf_t buf = NULL; 8450 QDF_STATUS status; 8451 int len, args_tlv_len; 8452 uint8_t *buf_ptr; 8453 uint8_t i; 8454 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 8455 uint32_t *cmd_args; 8456 8457 /* Prepare and send power debug cmd parameters */ 8458 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 8459 len = sizeof(*cmd) + args_tlv_len; 8460 buf = wmi_buf_alloc(wmi_handle, len); 8461 if (!buf) 8462 return QDF_STATUS_E_NOMEM; 8463 8464 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8465 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 8466 WMITLV_SET_HDR(&cmd->tlv_header, 8467 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 8468 WMITLV_GET_STRUCT_TLVLEN 8469 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 8470 8471 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8472 wmi_handle, 8473 param->pdev_id); 8474 cmd->module_id = param->module_id; 8475 cmd->num_args = param->num_args; 8476 buf_ptr += sizeof(*cmd); 8477 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8478 (param->num_args * sizeof(uint32_t))); 8479 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8480 wmi_debug("%d num of args = ", param->num_args); 8481 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 8482 cmd_args[i] = param->args[i]; 8483 wmi_debug("%d,", param->args[i]); 8484 } 8485 8486 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 8487 status = wmi_unified_cmd_send(wmi_handle, buf, 8488 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 8489 if (QDF_IS_STATUS_ERROR(status)) { 8490 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 8491 status); 8492 goto error; 8493 } 8494 8495 return QDF_STATUS_SUCCESS; 8496 error: 8497 wmi_buf_free(buf); 8498 8499 return status; 8500 } 8501 8502 /** 8503 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 8504 * @wmi_handle: wmi handle 8505 * @pdev_id: pdev id 8506 * 8507 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 8508 * 8509 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 8510 */ 8511 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 8512 uint32_t pdev_id) 8513 { 8514 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 8515 wmi_buf_t buf; 8516 uint16_t len; 8517 QDF_STATUS ret; 8518 8519 len = sizeof(*cmd); 8520 buf = wmi_buf_alloc(wmi_handle, len); 8521 8522 wmi_debug("pdev_id=%d", pdev_id); 8523 8524 if (!buf) 8525 return QDF_STATUS_E_NOMEM; 8526 8527 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 8528 wmi_buf_data(buf); 8529 8530 WMITLV_SET_HDR(&cmd->tlv_header, 8531 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 8532 WMITLV_GET_STRUCT_TLVLEN( 8533 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 8534 8535 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8536 wmi_handle, 8537 pdev_id); 8538 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 8539 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8540 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 8541 if (QDF_IS_STATUS_ERROR(ret)) { 8542 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 8543 ret, pdev_id); 8544 wmi_buf_free(buf); 8545 return QDF_STATUS_E_FAILURE; 8546 } 8547 8548 return QDF_STATUS_SUCCESS; 8549 } 8550 8551 /** 8552 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 8553 * @wmi_handle: wmi handle 8554 * @pdev_id: pdev id 8555 * 8556 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 8557 * 8558 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 8559 */ 8560 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 8561 uint32_t pdev_id) 8562 { 8563 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 8564 wmi_buf_t buf; 8565 uint16_t len; 8566 QDF_STATUS ret; 8567 8568 len = sizeof(*cmd); 8569 buf = wmi_buf_alloc(wmi_handle, len); 8570 8571 wmi_debug("pdev_id=%d", pdev_id); 8572 8573 if (!buf) 8574 return QDF_STATUS_E_NOMEM; 8575 8576 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 8577 wmi_buf_data(buf); 8578 8579 WMITLV_SET_HDR(&cmd->tlv_header, 8580 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 8581 WMITLV_GET_STRUCT_TLVLEN( 8582 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 8583 8584 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8585 wmi_handle, 8586 pdev_id); 8587 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 8588 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8589 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 8590 if (QDF_IS_STATUS_ERROR(ret)) { 8591 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 8592 ret, pdev_id); 8593 wmi_buf_free(buf); 8594 return QDF_STATUS_E_FAILURE; 8595 } 8596 8597 return QDF_STATUS_SUCCESS; 8598 } 8599 8600 #ifdef QCA_SUPPORT_AGILE_DFS 8601 static 8602 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 8603 struct vdev_adfs_ch_cfg_params *param) 8604 { 8605 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 8606 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 8607 wmi_buf_t buf; 8608 QDF_STATUS ret; 8609 uint16_t len; 8610 8611 len = sizeof(*cmd); 8612 buf = wmi_buf_alloc(wmi_handle, len); 8613 8614 if (!buf) { 8615 wmi_err("wmi_buf_alloc failed"); 8616 return QDF_STATUS_E_NOMEM; 8617 } 8618 8619 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 8620 wmi_buf_data(buf); 8621 8622 WMITLV_SET_HDR(&cmd->tlv_header, 8623 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 8624 WMITLV_GET_STRUCT_TLVLEN 8625 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 8626 8627 cmd->vdev_id = param->vdev_id; 8628 cmd->ocac_mode = param->ocac_mode; 8629 cmd->center_freq1 = param->center_freq1; 8630 cmd->center_freq2 = param->center_freq2; 8631 cmd->chan_freq = param->chan_freq; 8632 cmd->chan_width = param->chan_width; 8633 cmd->min_duration_ms = param->min_duration_ms; 8634 cmd->max_duration_ms = param->max_duration_ms; 8635 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 8636 cmd->vdev_id, cmd->ocac_mode, 8637 cmd->center_freq); 8638 8639 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 8640 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8641 WMI_VDEV_ADFS_CH_CFG_CMDID); 8642 8643 if (QDF_IS_STATUS_ERROR(ret)) { 8644 wmi_err("Failed to send cmd to fw, ret=%d", ret); 8645 wmi_buf_free(buf); 8646 return QDF_STATUS_E_FAILURE; 8647 } 8648 8649 return QDF_STATUS_SUCCESS; 8650 } 8651 8652 static 8653 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 8654 struct vdev_adfs_abort_params *param) 8655 { 8656 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 8657 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 8658 wmi_buf_t buf; 8659 QDF_STATUS ret; 8660 uint16_t len; 8661 8662 len = sizeof(*cmd); 8663 buf = wmi_buf_alloc(wmi_handle, len); 8664 8665 if (!buf) { 8666 wmi_err("wmi_buf_alloc failed"); 8667 return QDF_STATUS_E_NOMEM; 8668 } 8669 8670 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 8671 wmi_buf_data(buf); 8672 8673 WMITLV_SET_HDR 8674 (&cmd->tlv_header, 8675 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 8676 WMITLV_GET_STRUCT_TLVLEN 8677 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 8678 8679 cmd->vdev_id = param->vdev_id; 8680 8681 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 8682 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8683 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 8684 8685 if (QDF_IS_STATUS_ERROR(ret)) { 8686 wmi_err("Failed to send cmd to fw, ret=%d", ret); 8687 wmi_buf_free(buf); 8688 return QDF_STATUS_E_FAILURE; 8689 } 8690 8691 return QDF_STATUS_SUCCESS; 8692 } 8693 #endif 8694 8695 /** 8696 * is_service_enabled_tlv() - Check if service enabled 8697 * @param wmi_handle: wmi handle 8698 * @param service_id: service identifier 8699 * 8700 * Return: 1 enabled, 0 disabled 8701 */ 8702 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 8703 uint32_t service_id) 8704 { 8705 struct wmi_soc *soc = wmi_handle->soc; 8706 8707 if (!soc->wmi_service_bitmap) { 8708 wmi_err("WMI service bit map is not saved yet"); 8709 return false; 8710 } 8711 8712 /* if wmi_service_enabled was received with extended2 bitmap, 8713 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 8714 */ 8715 if (soc->wmi_ext2_service_bitmap) { 8716 if (!soc->wmi_ext_service_bitmap) { 8717 wmi_err("WMI service ext bit map is not saved yet"); 8718 return false; 8719 } 8720 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 8721 soc->wmi_ext_service_bitmap, 8722 soc->wmi_ext2_service_bitmap, 8723 service_id); 8724 } 8725 8726 if (service_id >= WMI_MAX_EXT_SERVICE) { 8727 wmi_err("Service id %d but WMI ext2 service bitmap is NULL", 8728 service_id); 8729 return false; 8730 } 8731 /* if wmi_service_enabled was received with extended bitmap, 8732 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 8733 */ 8734 if (soc->wmi_ext_service_bitmap) 8735 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 8736 soc->wmi_ext_service_bitmap, 8737 service_id); 8738 8739 if (service_id >= WMI_MAX_SERVICE) { 8740 wmi_err("Service id %d but WMI ext service bitmap is NULL", 8741 service_id); 8742 return false; 8743 } 8744 8745 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 8746 service_id); 8747 } 8748 8749 /** 8750 * init_cmd_send_tlv() - send initialization cmd to fw 8751 * @wmi_handle: wmi handle 8752 * @param param: pointer to wmi init param 8753 * 8754 * Return: QDF_STATUS_SUCCESS for success or error code 8755 */ 8756 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 8757 struct wmi_init_cmd_param *param) 8758 { 8759 wmi_buf_t buf; 8760 wmi_init_cmd_fixed_param *cmd; 8761 uint8_t *buf_ptr; 8762 wmi_resource_config *resource_cfg; 8763 wlan_host_memory_chunk *host_mem_chunks; 8764 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 8765 uint16_t idx; 8766 int len; 8767 QDF_STATUS ret; 8768 8769 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 8770 WMI_TLV_HDR_SIZE; 8771 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 8772 8773 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 8774 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 8775 WMI_TLV_HDR_SIZE + 8776 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 8777 8778 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 8779 if (!buf) 8780 return QDF_STATUS_E_FAILURE; 8781 8782 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8783 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 8784 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 8785 8786 host_mem_chunks = (wlan_host_memory_chunk *) 8787 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 8788 + WMI_TLV_HDR_SIZE); 8789 8790 WMITLV_SET_HDR(&cmd->tlv_header, 8791 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 8792 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 8793 wmi_copy_resource_config(resource_cfg, param->res_cfg); 8794 WMITLV_SET_HDR(&resource_cfg->tlv_header, 8795 WMITLV_TAG_STRUC_wmi_resource_config, 8796 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 8797 8798 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 8799 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 8800 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 8801 WMITLV_GET_STRUCT_TLVLEN 8802 (wlan_host_memory_chunk)); 8803 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 8804 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 8805 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 8806 if (is_service_enabled_tlv(wmi_handle, 8807 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 8808 host_mem_chunks[idx].ptr_high = 8809 qdf_get_upper_32_bits( 8810 param->mem_chunks[idx].paddr); 8811 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 8812 "chunk %d len %d requested ,ptr 0x%x ", 8813 idx, host_mem_chunks[idx].size, 8814 host_mem_chunks[idx].ptr); 8815 } 8816 cmd->num_host_mem_chunks = param->num_mem_chunks; 8817 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 8818 8819 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 8820 WMITLV_TAG_ARRAY_STRUC, 8821 (sizeof(wlan_host_memory_chunk) * 8822 param->num_mem_chunks)); 8823 8824 /* Fill hw mode id config */ 8825 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 8826 8827 /* Fill fw_abi_vers */ 8828 copy_fw_abi_version_tlv(wmi_handle, cmd); 8829 8830 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 8831 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 8832 if (QDF_IS_STATUS_ERROR(ret)) { 8833 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 8834 ret); 8835 wmi_buf_free(buf); 8836 } 8837 8838 return ret; 8839 8840 } 8841 8842 /** 8843 * send_addba_send_cmd_tlv() - send addba send command to fw 8844 * @wmi_handle: wmi handle 8845 * @param: pointer to delba send params 8846 * @macaddr: peer mac address 8847 * 8848 * Send WMI_ADDBA_SEND_CMDID command to firmware 8849 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 8850 */ 8851 static QDF_STATUS 8852 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 8853 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 8854 struct addba_send_params *param) 8855 { 8856 wmi_addba_send_cmd_fixed_param *cmd; 8857 wmi_buf_t buf; 8858 uint16_t len; 8859 QDF_STATUS ret; 8860 8861 len = sizeof(*cmd); 8862 8863 buf = wmi_buf_alloc(wmi_handle, len); 8864 if (!buf) 8865 return QDF_STATUS_E_NOMEM; 8866 8867 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 8868 8869 WMITLV_SET_HDR(&cmd->tlv_header, 8870 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 8871 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 8872 8873 cmd->vdev_id = param->vdev_id; 8874 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 8875 cmd->tid = param->tidno; 8876 cmd->buffersize = param->buffersize; 8877 8878 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 8879 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 8880 if (QDF_IS_STATUS_ERROR(ret)) { 8881 wmi_err("Failed to send cmd to fw, ret=%d", ret); 8882 wmi_buf_free(buf); 8883 return QDF_STATUS_E_FAILURE; 8884 } 8885 8886 return QDF_STATUS_SUCCESS; 8887 } 8888 8889 /** 8890 * send_delba_send_cmd_tlv() - send delba send command to fw 8891 * @wmi_handle: wmi handle 8892 * @param: pointer to delba send params 8893 * @macaddr: peer mac address 8894 * 8895 * Send WMI_DELBA_SEND_CMDID command to firmware 8896 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 8897 */ 8898 static QDF_STATUS 8899 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 8900 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 8901 struct delba_send_params *param) 8902 { 8903 wmi_delba_send_cmd_fixed_param *cmd; 8904 wmi_buf_t buf; 8905 uint16_t len; 8906 QDF_STATUS ret; 8907 8908 len = sizeof(*cmd); 8909 8910 buf = wmi_buf_alloc(wmi_handle, len); 8911 if (!buf) 8912 return QDF_STATUS_E_NOMEM; 8913 8914 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 8915 8916 WMITLV_SET_HDR(&cmd->tlv_header, 8917 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 8918 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 8919 8920 cmd->vdev_id = param->vdev_id; 8921 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 8922 cmd->tid = param->tidno; 8923 cmd->initiator = param->initiator; 8924 cmd->reasoncode = param->reasoncode; 8925 8926 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 8927 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 8928 if (QDF_IS_STATUS_ERROR(ret)) { 8929 wmi_err("Failed to send cmd to fw, ret=%d", ret); 8930 wmi_buf_free(buf); 8931 return QDF_STATUS_E_FAILURE; 8932 } 8933 8934 return QDF_STATUS_SUCCESS; 8935 } 8936 8937 /** 8938 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 8939 * to fw 8940 * @wmi_handle: wmi handle 8941 * @param: pointer to addba clearresp params 8942 * @macaddr: peer mac address 8943 * Return: 0 for success or error code 8944 */ 8945 static QDF_STATUS 8946 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 8947 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 8948 struct addba_clearresponse_params *param) 8949 { 8950 wmi_addba_clear_resp_cmd_fixed_param *cmd; 8951 wmi_buf_t buf; 8952 uint16_t len; 8953 QDF_STATUS ret; 8954 8955 len = sizeof(*cmd); 8956 8957 buf = wmi_buf_alloc(wmi_handle, len); 8958 if (!buf) 8959 return QDF_STATUS_E_FAILURE; 8960 8961 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 8962 8963 WMITLV_SET_HDR(&cmd->tlv_header, 8964 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 8965 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 8966 8967 cmd->vdev_id = param->vdev_id; 8968 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 8969 8970 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 8971 ret = wmi_unified_cmd_send(wmi_handle, 8972 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 8973 if (QDF_IS_STATUS_ERROR(ret)) { 8974 wmi_err("Failed to send cmd to fw, ret=%d", ret); 8975 wmi_buf_free(buf); 8976 return QDF_STATUS_E_FAILURE; 8977 } 8978 8979 return QDF_STATUS_SUCCESS; 8980 } 8981 8982 #ifdef OBSS_PD 8983 /** 8984 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 8985 * def thresh to fw 8986 * @wmi_handle: wmi handle 8987 * @thresh: pointer to obss_spatial_reuse_def_thresh 8988 * 8989 * Return: QDF_STATUS_SUCCESS for success or error code 8990 */ 8991 static 8992 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 8993 wmi_unified_t wmi_handle, 8994 struct wmi_host_obss_spatial_reuse_set_def_thresh 8995 *thresh) 8996 { 8997 wmi_buf_t buf; 8998 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 8999 QDF_STATUS ret; 9000 uint32_t cmd_len; 9001 uint32_t tlv_len; 9002 9003 cmd_len = sizeof(*cmd); 9004 9005 buf = wmi_buf_alloc(wmi_handle, cmd_len); 9006 if (!buf) 9007 return QDF_STATUS_E_NOMEM; 9008 9009 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 9010 wmi_buf_data(buf); 9011 9012 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 9013 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 9014 9015 WMITLV_SET_HDR(&cmd->tlv_header, 9016 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 9017 tlv_len); 9018 9019 cmd->obss_min = thresh->obss_min; 9020 cmd->obss_max = thresh->obss_max; 9021 cmd->vdev_type = thresh->vdev_type; 9022 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 9023 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 9024 if (QDF_IS_STATUS_ERROR(ret)) 9025 wmi_buf_free(buf); 9026 9027 return ret; 9028 } 9029 9030 /** 9031 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 9032 * @wmi_handle: wmi handle 9033 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 9034 * 9035 * Return: QDF_STATUS_SUCCESS for success or error code 9036 */ 9037 static 9038 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 9039 struct wmi_host_obss_spatial_reuse_set_param 9040 *obss_spatial_reuse_param) 9041 { 9042 wmi_buf_t buf; 9043 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 9044 QDF_STATUS ret; 9045 uint32_t len; 9046 9047 len = sizeof(*cmd); 9048 9049 buf = wmi_buf_alloc(wmi_handle, len); 9050 if (!buf) 9051 return QDF_STATUS_E_FAILURE; 9052 9053 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 9054 WMITLV_SET_HDR(&cmd->tlv_header, 9055 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 9056 WMITLV_GET_STRUCT_TLVLEN 9057 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 9058 9059 cmd->enable = obss_spatial_reuse_param->enable; 9060 cmd->obss_min = obss_spatial_reuse_param->obss_min; 9061 cmd->obss_max = obss_spatial_reuse_param->obss_max; 9062 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 9063 9064 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9065 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 9066 9067 if (QDF_IS_STATUS_ERROR(ret)) { 9068 wmi_err( 9069 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 9070 ret); 9071 wmi_buf_free(buf); 9072 } 9073 9074 return ret; 9075 } 9076 9077 /** 9078 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 9079 * to be used by SRG based Spatial Reuse feature to the FW 9080 * @wmi_handle: wmi handle 9081 * @bitmap_0: lower 32 bits in BSS color bitmap 9082 * @bitmap_1: upper 32 bits in BSS color bitmap 9083 * @pdev_id: pdev ID 9084 * 9085 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9086 */ 9087 static QDF_STATUS 9088 send_self_srg_bss_color_bitmap_set_cmd_tlv( 9089 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9090 uint32_t bitmap_1, uint8_t pdev_id) 9091 { 9092 wmi_buf_t buf; 9093 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 9094 QDF_STATUS ret; 9095 uint32_t len; 9096 9097 len = sizeof(*cmd); 9098 9099 buf = wmi_buf_alloc(wmi_handle, len); 9100 if (!buf) 9101 return QDF_STATUS_E_FAILURE; 9102 9103 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 9104 wmi_buf_data(buf); 9105 9106 WMITLV_SET_HDR( 9107 &cmd->tlv_header, 9108 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 9109 WMITLV_GET_STRUCT_TLVLEN 9110 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 9111 9112 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9113 wmi_handle, pdev_id); 9114 cmd->srg_bss_color_bitmap[0] = bitmap_0; 9115 cmd->srg_bss_color_bitmap[1] = bitmap_1; 9116 9117 ret = wmi_unified_cmd_send( 9118 wmi_handle, buf, len, 9119 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 9120 9121 if (QDF_IS_STATUS_ERROR(ret)) { 9122 wmi_err( 9123 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 9124 ret); 9125 wmi_buf_free(buf); 9126 } 9127 9128 return ret; 9129 } 9130 9131 /** 9132 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 9133 * bitmap to be used by SRG based Spatial Reuse feature to the FW 9134 * @wmi_handle: wmi handle 9135 * @bitmap_0: lower 32 bits in partial BSSID bitmap 9136 * @bitmap_1: upper 32 bits in partial BSSID bitmap 9137 * @pdev_id: pdev ID 9138 * 9139 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9140 */ 9141 static QDF_STATUS 9142 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 9143 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9144 uint32_t bitmap_1, uint8_t pdev_id) 9145 { 9146 wmi_buf_t buf; 9147 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 9148 QDF_STATUS ret; 9149 uint32_t len; 9150 9151 len = sizeof(*cmd); 9152 9153 buf = wmi_buf_alloc(wmi_handle, len); 9154 if (!buf) 9155 return QDF_STATUS_E_FAILURE; 9156 9157 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 9158 wmi_buf_data(buf); 9159 9160 WMITLV_SET_HDR( 9161 &cmd->tlv_header, 9162 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 9163 WMITLV_GET_STRUCT_TLVLEN 9164 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 9165 9166 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9167 wmi_handle, pdev_id); 9168 9169 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 9170 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 9171 9172 ret = wmi_unified_cmd_send( 9173 wmi_handle, buf, len, 9174 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 9175 9176 if (QDF_IS_STATUS_ERROR(ret)) { 9177 wmi_err( 9178 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 9179 ret); 9180 wmi_buf_free(buf); 9181 } 9182 9183 return ret; 9184 } 9185 9186 /** 9187 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 9188 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 9189 * @wmi_handle: wmi handle 9190 * @bitmap_0: lower 32 bits in BSS color enable bitmap 9191 * @bitmap_1: upper 32 bits in BSS color enable bitmap 9192 * @pdev_id: pdev ID 9193 * 9194 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9195 */ 9196 static QDF_STATUS 9197 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 9198 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9199 uint32_t bitmap_1, uint8_t pdev_id) 9200 { 9201 wmi_buf_t buf; 9202 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 9203 QDF_STATUS ret; 9204 uint32_t len; 9205 9206 len = sizeof(*cmd); 9207 9208 buf = wmi_buf_alloc(wmi_handle, len); 9209 if (!buf) 9210 return QDF_STATUS_E_FAILURE; 9211 9212 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 9213 wmi_buf_data(buf); 9214 9215 WMITLV_SET_HDR( 9216 &cmd->tlv_header, 9217 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 9218 WMITLV_GET_STRUCT_TLVLEN 9219 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 9220 9221 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9222 wmi_handle, pdev_id); 9223 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 9224 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 9225 9226 ret = wmi_unified_cmd_send( 9227 wmi_handle, buf, len, 9228 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 9229 9230 if (QDF_IS_STATUS_ERROR(ret)) { 9231 wmi_err( 9232 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 9233 ret); 9234 wmi_buf_free(buf); 9235 } 9236 9237 return ret; 9238 } 9239 9240 /** 9241 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 9242 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 9243 * @wmi_handle: wmi handle 9244 * @bitmap_0: lower 32 bits in BSSID enable bitmap 9245 * @bitmap_1: upper 32 bits in BSSID enable bitmap 9246 * @pdev_id: pdev ID 9247 * 9248 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9249 */ 9250 static QDF_STATUS 9251 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 9252 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9253 uint32_t bitmap_1, uint8_t pdev_id) 9254 { 9255 wmi_buf_t buf; 9256 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 9257 QDF_STATUS ret; 9258 uint32_t len; 9259 9260 len = sizeof(*cmd); 9261 9262 buf = wmi_buf_alloc(wmi_handle, len); 9263 if (!buf) 9264 return QDF_STATUS_E_FAILURE; 9265 9266 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 9267 wmi_buf_data(buf); 9268 9269 WMITLV_SET_HDR( 9270 &cmd->tlv_header, 9271 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 9272 WMITLV_GET_STRUCT_TLVLEN 9273 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 9274 9275 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9276 wmi_handle, pdev_id); 9277 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 9278 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 9279 9280 ret = wmi_unified_cmd_send( 9281 wmi_handle, buf, len, 9282 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 9283 9284 if (QDF_IS_STATUS_ERROR(ret)) { 9285 wmi_err( 9286 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 9287 ret); 9288 wmi_buf_free(buf); 9289 } 9290 9291 return ret; 9292 } 9293 9294 /** 9295 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 9296 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 9297 * @wmi_handle: wmi handle 9298 * @bitmap_0: lower 32 bits in BSS color enable bitmap 9299 * @bitmap_1: upper 32 bits in BSS color enable bitmap 9300 * @pdev_id: pdev ID 9301 * 9302 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9303 */ 9304 static QDF_STATUS 9305 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 9306 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9307 uint32_t bitmap_1, uint8_t pdev_id) 9308 { 9309 wmi_buf_t buf; 9310 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 9311 QDF_STATUS ret; 9312 uint32_t len; 9313 9314 len = sizeof(*cmd); 9315 9316 buf = wmi_buf_alloc(wmi_handle, len); 9317 if (!buf) 9318 return QDF_STATUS_E_FAILURE; 9319 9320 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 9321 wmi_buf_data(buf); 9322 9323 WMITLV_SET_HDR( 9324 &cmd->tlv_header, 9325 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 9326 WMITLV_GET_STRUCT_TLVLEN 9327 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 9328 9329 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9330 wmi_handle, pdev_id); 9331 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 9332 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 9333 9334 ret = wmi_unified_cmd_send( 9335 wmi_handle, buf, len, 9336 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 9337 9338 if (QDF_IS_STATUS_ERROR(ret)) { 9339 wmi_err( 9340 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 9341 ret); 9342 wmi_buf_free(buf); 9343 } 9344 9345 return ret; 9346 } 9347 9348 /** 9349 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 9350 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 9351 * @wmi_handle: wmi handle 9352 * @bitmap_0: lower 32 bits in BSSID enable bitmap 9353 * @bitmap_1: upper 32 bits in BSSID enable bitmap 9354 * @pdev_id: pdev ID 9355 * 9356 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9357 */ 9358 static QDF_STATUS 9359 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 9360 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9361 uint32_t bitmap_1, uint8_t pdev_id) 9362 { 9363 wmi_buf_t buf; 9364 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 9365 QDF_STATUS ret; 9366 uint32_t len; 9367 9368 len = sizeof(*cmd); 9369 9370 buf = wmi_buf_alloc(wmi_handle, len); 9371 if (!buf) 9372 return QDF_STATUS_E_FAILURE; 9373 9374 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 9375 wmi_buf_data(buf); 9376 9377 WMITLV_SET_HDR( 9378 &cmd->tlv_header, 9379 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 9380 WMITLV_GET_STRUCT_TLVLEN 9381 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 9382 9383 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9384 wmi_handle, pdev_id); 9385 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 9386 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 9387 9388 ret = wmi_unified_cmd_send( 9389 wmi_handle, buf, len, 9390 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 9391 9392 if (QDF_IS_STATUS_ERROR(ret)) { 9393 wmi_err( 9394 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 9395 ret); 9396 wmi_buf_free(buf); 9397 } 9398 9399 return ret; 9400 } 9401 #endif 9402 9403 static 9404 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 9405 struct wmi_host_injector_frame_params *inject_config_params) 9406 { 9407 wmi_buf_t buf; 9408 wmi_frame_inject_cmd_fixed_param *cmd; 9409 QDF_STATUS ret; 9410 uint32_t len; 9411 9412 len = sizeof(*cmd); 9413 9414 buf = wmi_buf_alloc(wmi_handle, len); 9415 if (!buf) 9416 return QDF_STATUS_E_NOMEM; 9417 9418 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 9419 WMITLV_SET_HDR(&cmd->tlv_header, 9420 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 9421 WMITLV_GET_STRUCT_TLVLEN 9422 (wmi_frame_inject_cmd_fixed_param)); 9423 9424 cmd->vdev_id = inject_config_params->vdev_id; 9425 cmd->enable = inject_config_params->enable; 9426 cmd->frame_type = inject_config_params->frame_type; 9427 cmd->frame_inject_period = inject_config_params->frame_inject_period; 9428 cmd->fc_duration = inject_config_params->frame_duration; 9429 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 9430 &cmd->frame_addr1); 9431 9432 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9433 WMI_PDEV_FRAME_INJECT_CMDID); 9434 9435 if (QDF_IS_STATUS_ERROR(ret)) { 9436 wmi_err( 9437 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 9438 ret); 9439 wmi_buf_free(buf); 9440 } 9441 9442 return ret; 9443 } 9444 #ifdef QCA_SUPPORT_CP_STATS 9445 /** 9446 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 9447 * @wmi_handle: wma handle 9448 * @evt_buf: event buffer 9449 * @out_buff: buffer to populated after stats extraction 9450 * 9451 * Return: status of operation 9452 */ 9453 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 9454 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 9455 { 9456 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9457 wmi_congestion_stats *congestion_stats; 9458 9459 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 9460 congestion_stats = param_buf->congestion_stats; 9461 if (!congestion_stats) 9462 return QDF_STATUS_E_INVAL; 9463 9464 out_buff->vdev_id = congestion_stats->vdev_id; 9465 out_buff->congestion = congestion_stats->congestion; 9466 9467 wmi_debug("cca stats event processed"); 9468 return QDF_STATUS_SUCCESS; 9469 } 9470 #endif /* QCA_SUPPORT_CP_STATS */ 9471 9472 /** 9473 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 9474 * event 9475 * @wmi_handle: wmi handle 9476 * @param evt_buf: pointer to event buffer 9477 * @param param: Pointer to hold peer ctl data 9478 * 9479 * Return: QDF_STATUS_SUCCESS for success or error code 9480 */ 9481 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 9482 wmi_unified_t wmi_handle, 9483 void *evt_buf, 9484 struct wmi_host_pdev_ctl_failsafe_event *param) 9485 { 9486 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 9487 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 9488 9489 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 9490 if (!param_buf) { 9491 wmi_err("Invalid ctl_failsafe event buffer"); 9492 return QDF_STATUS_E_INVAL; 9493 } 9494 9495 fix_param = param_buf->fixed_param; 9496 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 9497 9498 return QDF_STATUS_SUCCESS; 9499 } 9500 9501 /** 9502 * save_service_bitmap_tlv() - save service bitmap 9503 * @wmi_handle: wmi handle 9504 * @param evt_buf: pointer to event buffer 9505 * @param bitmap_buf: bitmap buffer, for converged legacy support 9506 * 9507 * Return: QDF_STATUS 9508 */ 9509 static 9510 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 9511 void *bitmap_buf) 9512 { 9513 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9514 struct wmi_soc *soc = wmi_handle->soc; 9515 9516 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9517 9518 /* If it is already allocated, use that buffer. This can happen 9519 * during target stop/start scenarios where host allocation is skipped. 9520 */ 9521 if (!soc->wmi_service_bitmap) { 9522 soc->wmi_service_bitmap = 9523 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 9524 if (!soc->wmi_service_bitmap) 9525 return QDF_STATUS_E_NOMEM; 9526 } 9527 9528 qdf_mem_copy(soc->wmi_service_bitmap, 9529 param_buf->wmi_service_bitmap, 9530 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 9531 9532 if (bitmap_buf) 9533 qdf_mem_copy(bitmap_buf, 9534 param_buf->wmi_service_bitmap, 9535 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 9536 9537 return QDF_STATUS_SUCCESS; 9538 } 9539 9540 /** 9541 * save_ext_service_bitmap_tlv() - save extendend service bitmap 9542 * @wmi_handle: wmi handle 9543 * @param evt_buf: pointer to event buffer 9544 * @param bitmap_buf: bitmap buffer, for converged legacy support 9545 * 9546 * Return: QDF_STATUS 9547 */ 9548 static 9549 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 9550 void *bitmap_buf) 9551 { 9552 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 9553 wmi_service_available_event_fixed_param *ev; 9554 struct wmi_soc *soc = wmi_handle->soc; 9555 uint32_t i = 0; 9556 9557 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 9558 9559 ev = param_buf->fixed_param; 9560 9561 /* If it is already allocated, use that buffer. This can happen 9562 * during target stop/start scenarios where host allocation is skipped. 9563 */ 9564 if (!soc->wmi_ext_service_bitmap) { 9565 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 9566 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 9567 if (!soc->wmi_ext_service_bitmap) 9568 return QDF_STATUS_E_NOMEM; 9569 } 9570 9571 qdf_mem_copy(soc->wmi_ext_service_bitmap, 9572 ev->wmi_service_segment_bitmap, 9573 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 9574 9575 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 9576 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 9577 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 9578 9579 if (bitmap_buf) 9580 qdf_mem_copy(bitmap_buf, 9581 soc->wmi_ext_service_bitmap, 9582 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 9583 9584 if (!param_buf->wmi_service_ext_bitmap) { 9585 wmi_debug("wmi_service_ext_bitmap not available"); 9586 return QDF_STATUS_SUCCESS; 9587 } 9588 9589 if (!soc->wmi_ext2_service_bitmap) { 9590 soc->wmi_ext2_service_bitmap = 9591 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 9592 sizeof(uint32_t)); 9593 if (!soc->wmi_ext2_service_bitmap) 9594 return QDF_STATUS_E_NOMEM; 9595 } 9596 9597 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 9598 param_buf->wmi_service_ext_bitmap, 9599 (param_buf->num_wmi_service_ext_bitmap * 9600 sizeof(uint32_t))); 9601 9602 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 9603 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 9604 i, soc->wmi_ext2_service_bitmap[i]); 9605 } 9606 9607 return QDF_STATUS_SUCCESS; 9608 } 9609 9610 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 9611 struct wlan_psoc_target_capability_info *cap) 9612 { 9613 /* except LDPC all flags are common betwen legacy and here 9614 * also IBFEER is not defined for TLV 9615 */ 9616 cap->ht_cap_info |= ev_target_cap & ( 9617 WMI_HT_CAP_ENABLED 9618 | WMI_HT_CAP_HT20_SGI 9619 | WMI_HT_CAP_DYNAMIC_SMPS 9620 | WMI_HT_CAP_TX_STBC 9621 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 9622 | WMI_HT_CAP_RX_STBC 9623 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 9624 | WMI_HT_CAP_LDPC 9625 | WMI_HT_CAP_L_SIG_TXOP_PROT 9626 | WMI_HT_CAP_MPDU_DENSITY 9627 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 9628 | WMI_HT_CAP_HT40_SGI); 9629 if (ev_target_cap & WMI_HT_CAP_LDPC) 9630 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 9631 WMI_HOST_HT_CAP_TX_LDPC; 9632 } 9633 /** 9634 * extract_service_ready_tlv() - extract service ready event 9635 * @wmi_handle: wmi handle 9636 * @param evt_buf: pointer to received event buffer 9637 * @param cap: pointer to hold target capability information extracted from even 9638 * 9639 * Return: QDF_STATUS_SUCCESS for success or error code 9640 */ 9641 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 9642 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 9643 { 9644 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9645 wmi_service_ready_event_fixed_param *ev; 9646 9647 9648 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9649 9650 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 9651 if (!ev) { 9652 qdf_print("%s: wmi_buf_alloc failed", __func__); 9653 return QDF_STATUS_E_FAILURE; 9654 } 9655 9656 cap->phy_capability = ev->phy_capability; 9657 cap->max_frag_entry = ev->max_frag_entry; 9658 cap->num_rf_chains = ev->num_rf_chains; 9659 copy_ht_cap_info(ev->ht_cap_info, cap); 9660 cap->vht_cap_info = ev->vht_cap_info; 9661 cap->vht_supp_mcs = ev->vht_supp_mcs; 9662 cap->hw_min_tx_power = ev->hw_min_tx_power; 9663 cap->hw_max_tx_power = ev->hw_max_tx_power; 9664 cap->sys_cap_info = ev->sys_cap_info; 9665 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 9666 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 9667 cap->max_num_scan_channels = ev->max_num_scan_channels; 9668 cap->max_supported_macs = ev->max_supported_macs; 9669 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 9670 cap->txrx_chainmask = ev->txrx_chainmask; 9671 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 9672 cap->num_msdu_desc = ev->num_msdu_desc; 9673 cap->fw_version = ev->fw_build_vers; 9674 /* fw_version_1 is not available in TLV. */ 9675 cap->fw_version_1 = 0; 9676 9677 return QDF_STATUS_SUCCESS; 9678 } 9679 9680 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 9681 * to host internal WMI_HOST_REGDMN_MODE values. 9682 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 9683 * host currently. Add this in the future if required. 9684 * 11AX (Phase II) : 11ax related values are not currently 9685 * advertised separately by FW. As part of phase II regulatory bring-up, 9686 * finalize the advertisement mechanism. 9687 * @target_wireless_mode: target wireless mode received in message 9688 * 9689 * Return: returns the host internal wireless mode. 9690 */ 9691 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 9692 { 9693 9694 uint32_t wireless_modes = 0; 9695 9696 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 9697 9698 if (target_wireless_mode & REGDMN_MODE_11A) 9699 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 9700 9701 if (target_wireless_mode & REGDMN_MODE_TURBO) 9702 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 9703 9704 if (target_wireless_mode & REGDMN_MODE_11B) 9705 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 9706 9707 if (target_wireless_mode & REGDMN_MODE_PUREG) 9708 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 9709 9710 if (target_wireless_mode & REGDMN_MODE_11G) 9711 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 9712 9713 if (target_wireless_mode & REGDMN_MODE_108G) 9714 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 9715 9716 if (target_wireless_mode & REGDMN_MODE_108A) 9717 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 9718 9719 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 9720 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20_2G; 9721 9722 if (target_wireless_mode & REGDMN_MODE_XR) 9723 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 9724 9725 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 9726 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 9727 9728 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 9729 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 9730 9731 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 9732 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 9733 9734 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 9735 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 9736 9737 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 9738 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 9739 9740 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 9741 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 9742 9743 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 9744 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 9745 9746 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 9747 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 9748 9749 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 9750 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 9751 9752 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 9753 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 9754 9755 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 9756 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 9757 9758 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 9759 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 9760 9761 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 9762 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 9763 9764 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 9765 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 9766 9767 return wireless_modes; 9768 } 9769 9770 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 9771 * target to host internal REGULATORY_PHYMODE values. 9772 * 9773 * @target_target_phybitmap: target phybitmap received in the message. 9774 * 9775 * Return: returns the host internal REGULATORY_PHYMODE. 9776 */ 9777 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 9778 { 9779 uint32_t phybitmap = 0; 9780 9781 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 9782 9783 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 9784 phybitmap |= REGULATORY_PHYMODE_NO11A; 9785 9786 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 9787 phybitmap |= REGULATORY_PHYMODE_NO11B; 9788 9789 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 9790 phybitmap |= REGULATORY_PHYMODE_NO11G; 9791 9792 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 9793 phybitmap |= REGULATORY_CHAN_NO11N; 9794 9795 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 9796 phybitmap |= REGULATORY_PHYMODE_NO11AC; 9797 9798 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 9799 phybitmap |= REGULATORY_PHYMODE_NO11AX; 9800 9801 return phybitmap; 9802 } 9803 9804 static inline uint32_t convert_wireless_modes_ext_tlv( 9805 uint32_t target_wireless_modes_ext) 9806 { 9807 uint32_t wireless_modes_ext = 0; 9808 9809 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 9810 9811 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 9812 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXG_HE20; 9813 9814 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 9815 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXG_HE40PLUS; 9816 9817 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 9818 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXG_HE40MINUS; 9819 9820 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 9821 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE20; 9822 9823 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 9824 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE40PLUS; 9825 9826 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 9827 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE40MINUS; 9828 9829 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 9830 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE80; 9831 9832 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 9833 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE160; 9834 9835 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 9836 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE80_80; 9837 9838 return wireless_modes_ext; 9839 } 9840 9841 /** 9842 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 9843 * @wmi_handle: wmi handle 9844 * @param evt_buf: Pointer to event buffer 9845 * @param cap: pointer to hold HAL reg capabilities 9846 * 9847 * Return: QDF_STATUS_SUCCESS for success or error code 9848 */ 9849 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 9850 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 9851 { 9852 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9853 9854 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9855 if (!param_buf || !param_buf->hal_reg_capabilities) { 9856 wmi_err("Invalid arguments"); 9857 return QDF_STATUS_E_FAILURE; 9858 } 9859 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 9860 sizeof(uint32_t)), 9861 sizeof(struct wlan_psoc_hal_reg_capability)); 9862 9863 cap->wireless_modes = convert_wireless_modes_tlv( 9864 param_buf->hal_reg_capabilities->wireless_modes); 9865 9866 return QDF_STATUS_SUCCESS; 9867 } 9868 9869 /** 9870 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 9871 * @wmi_handle: wmi handle 9872 * @param evt_buf: Pointer to event buffer 9873 * @param cap: pointer to hold HAL reg capabilities 9874 * 9875 * Return: QDF_STATUS_SUCCESS for success or error code 9876 */ 9877 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 9878 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 9879 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 9880 { 9881 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 9882 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 9883 9884 if (!evt_buf) { 9885 wmi_err("null evt_buf"); 9886 return QDF_STATUS_E_INVAL; 9887 } 9888 9889 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 9890 9891 if (!param_buf->num_hal_reg_caps) 9892 return QDF_STATUS_SUCCESS; 9893 9894 if (phy_idx >= param_buf->num_hal_reg_caps) 9895 return QDF_STATUS_E_INVAL; 9896 9897 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 9898 9899 param->phy_id = reg_caps->phy_id; 9900 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 9901 reg_caps->wireless_modes_ext); 9902 9903 return QDF_STATUS_SUCCESS; 9904 } 9905 9906 /** 9907 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 9908 * @wmi_handle: wmi handle 9909 * @evt_buf: pointer to event buffer 9910 * 9911 * Return: Number of entries requested 9912 */ 9913 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 9914 void *evt_buf) 9915 { 9916 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9917 wmi_service_ready_event_fixed_param *ev; 9918 9919 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9920 9921 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 9922 if (!ev) { 9923 qdf_print("%s: wmi_buf_alloc failed", __func__); 9924 return 0; 9925 } 9926 9927 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 9928 wmi_err("Invalid num_mem_reqs %d:%d", 9929 ev->num_mem_reqs, param_buf->num_mem_reqs); 9930 return 0; 9931 } 9932 9933 return ev->num_mem_reqs; 9934 } 9935 9936 /** 9937 * extract_host_mem_req_tlv() - Extract host memory required from 9938 * service ready event 9939 * @wmi_handle: wmi handle 9940 * @evt_buf: pointer to event buffer 9941 * @mem_reqs: pointer to host memory request structure 9942 * @num_active_peers: number of active peers for peer cache 9943 * @num_peers: number of peers 9944 * @fw_prio: FW priority 9945 * @idx: index for memory request 9946 * 9947 * Return: Host memory request parameters requested by target 9948 */ 9949 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 9950 void *evt_buf, 9951 host_mem_req *mem_reqs, 9952 uint32_t num_active_peers, 9953 uint32_t num_peers, 9954 enum wmi_fw_mem_prio fw_prio, 9955 uint16_t idx) 9956 { 9957 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9958 9959 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 9960 9961 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 9962 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 9963 mem_reqs->num_unit_info = 9964 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 9965 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 9966 mem_reqs->tgt_num_units = 0; 9967 9968 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 9969 (mem_reqs->num_unit_info & 9970 REQ_TO_HOST_FOR_CONT_MEMORY)) || 9971 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 9972 (!(mem_reqs->num_unit_info & 9973 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 9974 /* First allocate the memory that requires contiguous memory */ 9975 mem_reqs->tgt_num_units = mem_reqs->num_units; 9976 if (mem_reqs->num_unit_info) { 9977 if (mem_reqs->num_unit_info & 9978 NUM_UNITS_IS_NUM_PEERS) { 9979 /* 9980 * number of units allocated is equal to number 9981 * of peers, 1 extra for self peer on target. 9982 * this needs to be fixed, host and target can 9983 * get out of sync 9984 */ 9985 mem_reqs->tgt_num_units = num_peers + 1; 9986 } 9987 if (mem_reqs->num_unit_info & 9988 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 9989 /* 9990 * Requesting allocation of memory using 9991 * num_active_peers in qcache. if qcache is 9992 * disabled in host, then it should allocate 9993 * memory for num_peers instead of 9994 * num_active_peers. 9995 */ 9996 if (num_active_peers) 9997 mem_reqs->tgt_num_units = 9998 num_active_peers + 1; 9999 else 10000 mem_reqs->tgt_num_units = 10001 num_peers + 1; 10002 } 10003 } 10004 10005 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 10006 "unit size %d actual units %d", 10007 idx, mem_reqs->req_id, 10008 mem_reqs->num_units, 10009 mem_reqs->num_unit_info, 10010 mem_reqs->unit_size, 10011 mem_reqs->tgt_num_units); 10012 } 10013 10014 return QDF_STATUS_SUCCESS; 10015 } 10016 10017 /** 10018 * save_fw_version_in_service_ready_tlv() - Save fw version in service 10019 * ready function 10020 * @wmi_handle: wmi handle 10021 * @param evt_buf: pointer to event buffer 10022 * 10023 * Return: QDF_STATUS_SUCCESS for success or error code 10024 */ 10025 static QDF_STATUS 10026 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 10027 { 10028 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10029 wmi_service_ready_event_fixed_param *ev; 10030 10031 10032 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10033 10034 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 10035 if (!ev) { 10036 qdf_print("%s: wmi_buf_alloc failed", __func__); 10037 return QDF_STATUS_E_FAILURE; 10038 } 10039 10040 /*Save fw version from service ready message */ 10041 /*This will be used while sending INIT message */ 10042 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10043 sizeof(wmi_handle->fw_abi_version)); 10044 10045 return QDF_STATUS_SUCCESS; 10046 } 10047 10048 /** 10049 * ready_extract_init_status_tlv() - Extract init status from ready event 10050 * @wmi_handle: wmi handle 10051 * @param evt_buf: Pointer to event buffer 10052 * 10053 * Return: ready status 10054 */ 10055 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 10056 void *evt_buf) 10057 { 10058 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10059 wmi_ready_event_fixed_param *ev = NULL; 10060 10061 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10062 ev = param_buf->fixed_param; 10063 10064 qdf_print("%s:%d", __func__, ev->status); 10065 10066 return ev->status; 10067 } 10068 10069 /** 10070 * ready_extract_mac_addr_tlv() - extract mac address from ready event 10071 * @wmi_handle: wmi handle 10072 * @param evt_buf: pointer to event buffer 10073 * @param macaddr: Pointer to hold MAC address 10074 * 10075 * Return: QDF_STATUS_SUCCESS for success or error code 10076 */ 10077 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 10078 void *evt_buf, uint8_t *macaddr) 10079 { 10080 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10081 wmi_ready_event_fixed_param *ev = NULL; 10082 10083 10084 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10085 ev = param_buf->fixed_param; 10086 10087 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 10088 10089 return QDF_STATUS_SUCCESS; 10090 } 10091 10092 /** 10093 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 10094 * @wmi_handle: wmi handle 10095 * @param evt_buf: pointer to event buffer 10096 * @param macaddr: Pointer to hold number of MAC addresses 10097 * 10098 * Return: Pointer to addr list 10099 */ 10100 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 10101 void *evt_buf, uint8_t *num_mac) 10102 { 10103 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10104 wmi_ready_event_fixed_param *ev = NULL; 10105 10106 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10107 ev = param_buf->fixed_param; 10108 10109 *num_mac = ev->num_extra_mac_addr; 10110 10111 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 10112 } 10113 10114 /** 10115 * extract_ready_params_tlv() - Extract data from ready event apart from 10116 * status, macaddr and version. 10117 * @wmi_handle: Pointer to WMI handle. 10118 * @evt_buf: Pointer to Ready event buffer. 10119 * @ev_param: Pointer to host defined struct to copy the data from event. 10120 * 10121 * Return: QDF_STATUS_SUCCESS on success. 10122 */ 10123 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 10124 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 10125 { 10126 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10127 wmi_ready_event_fixed_param *ev = NULL; 10128 10129 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10130 ev = param_buf->fixed_param; 10131 10132 ev_param->status = ev->status; 10133 ev_param->num_dscp_table = ev->num_dscp_table; 10134 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 10135 ev_param->num_total_peer = ev->num_total_peers; 10136 ev_param->num_extra_peer = ev->num_extra_peers; 10137 /* Agile_capability in ready event is supported in TLV target, 10138 * as per aDFS FR 10139 */ 10140 ev_param->max_ast_index = ev->max_ast_index; 10141 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 10142 ev_param->agile_capability = 1; 10143 10144 return QDF_STATUS_SUCCESS; 10145 } 10146 10147 /** 10148 * extract_dbglog_data_len_tlv() - extract debuglog data length 10149 * @wmi_handle: wmi handle 10150 * @param evt_buf: pointer to event buffer 10151 * 10152 * Return: length 10153 */ 10154 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 10155 void *evt_buf, uint32_t *len) 10156 { 10157 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 10158 10159 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 10160 10161 *len = param_buf->num_bufp; 10162 10163 return param_buf->bufp; 10164 } 10165 10166 10167 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 10168 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 10169 #else 10170 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 10171 ((_status) & WMI_RXERR_DECRYPT) 10172 #endif 10173 10174 /** 10175 * extract_mgmt_rx_params_tlv() - extract management rx params from event 10176 * @wmi_handle: wmi handle 10177 * @param evt_buf: pointer to event buffer 10178 * @param hdr: Pointer to hold header 10179 * @param bufp: Pointer to hold pointer to rx param buffer 10180 * 10181 * Return: QDF_STATUS_SUCCESS for success or error code 10182 */ 10183 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 10184 void *evt_buf, struct mgmt_rx_event_params *hdr, 10185 uint8_t **bufp) 10186 { 10187 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 10188 wmi_mgmt_rx_hdr *ev_hdr = NULL; 10189 int i; 10190 10191 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 10192 if (!param_tlvs) { 10193 wmi_err("Get NULL point message from FW"); 10194 return QDF_STATUS_E_INVAL; 10195 } 10196 10197 ev_hdr = param_tlvs->hdr; 10198 if (!hdr) { 10199 wmi_err("Rx event is NULL"); 10200 return QDF_STATUS_E_INVAL; 10201 } 10202 10203 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 10204 wmi_err("RX mgmt frame decrypt error, discard it"); 10205 return QDF_STATUS_E_INVAL; 10206 } 10207 10208 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 10209 wmi_handle, 10210 ev_hdr->pdev_id); 10211 hdr->chan_freq = ev_hdr->chan_freq; 10212 hdr->channel = ev_hdr->channel; 10213 hdr->snr = ev_hdr->snr; 10214 hdr->rate = ev_hdr->rate; 10215 hdr->phy_mode = ev_hdr->phy_mode; 10216 hdr->buf_len = ev_hdr->buf_len; 10217 hdr->status = ev_hdr->status; 10218 hdr->flags = ev_hdr->flags; 10219 hdr->rssi = ev_hdr->rssi; 10220 hdr->tsf_delta = ev_hdr->tsf_delta; 10221 for (i = 0; i < ATH_MAX_ANTENNA; i++) 10222 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 10223 10224 *bufp = param_tlvs->bufp; 10225 10226 return QDF_STATUS_SUCCESS; 10227 } 10228 10229 /** 10230 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 10231 * @wmi_handle: wmi handle 10232 * @param evt_buf: pointer to event buffer 10233 * @param param: Pointer to hold roam param 10234 * 10235 * Return: QDF_STATUS_SUCCESS for success or error code 10236 */ 10237 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 10238 void *evt_buf, wmi_host_roam_event *param) 10239 { 10240 WMI_ROAM_EVENTID_param_tlvs *param_buf; 10241 wmi_roam_event_fixed_param *evt; 10242 10243 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 10244 if (!param_buf) { 10245 wmi_err("Invalid roam event buffer"); 10246 return QDF_STATUS_E_INVAL; 10247 } 10248 10249 evt = param_buf->fixed_param; 10250 qdf_mem_zero(param, sizeof(*param)); 10251 10252 param->vdev_id = evt->vdev_id; 10253 param->reason = evt->reason; 10254 param->rssi = evt->rssi; 10255 10256 return QDF_STATUS_SUCCESS; 10257 } 10258 10259 /** 10260 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 10261 * @wmi_handle: wmi handle 10262 * @param evt_buf: pointer to event buffer 10263 * @param param: Pointer to hold vdev scan param 10264 * 10265 * Return: QDF_STATUS_SUCCESS for success or error code 10266 */ 10267 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 10268 void *evt_buf, struct scan_event *param) 10269 { 10270 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 10271 wmi_scan_event_fixed_param *evt = NULL; 10272 10273 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 10274 evt = param_buf->fixed_param; 10275 10276 qdf_mem_zero(param, sizeof(*param)); 10277 10278 switch (evt->event) { 10279 case WMI_SCAN_EVENT_STARTED: 10280 param->type = SCAN_EVENT_TYPE_STARTED; 10281 break; 10282 case WMI_SCAN_EVENT_COMPLETED: 10283 param->type = SCAN_EVENT_TYPE_COMPLETED; 10284 break; 10285 case WMI_SCAN_EVENT_BSS_CHANNEL: 10286 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 10287 break; 10288 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 10289 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 10290 break; 10291 case WMI_SCAN_EVENT_DEQUEUED: 10292 param->type = SCAN_EVENT_TYPE_DEQUEUED; 10293 break; 10294 case WMI_SCAN_EVENT_PREEMPTED: 10295 param->type = SCAN_EVENT_TYPE_PREEMPTED; 10296 break; 10297 case WMI_SCAN_EVENT_START_FAILED: 10298 param->type = SCAN_EVENT_TYPE_START_FAILED; 10299 break; 10300 case WMI_SCAN_EVENT_RESTARTED: 10301 param->type = SCAN_EVENT_TYPE_RESTARTED; 10302 break; 10303 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 10304 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 10305 break; 10306 case WMI_SCAN_EVENT_MAX: 10307 default: 10308 param->type = SCAN_EVENT_TYPE_MAX; 10309 break; 10310 }; 10311 10312 switch (evt->reason) { 10313 case WMI_SCAN_REASON_NONE: 10314 param->reason = SCAN_REASON_NONE; 10315 break; 10316 case WMI_SCAN_REASON_COMPLETED: 10317 param->reason = SCAN_REASON_COMPLETED; 10318 break; 10319 case WMI_SCAN_REASON_CANCELLED: 10320 param->reason = SCAN_REASON_CANCELLED; 10321 break; 10322 case WMI_SCAN_REASON_PREEMPTED: 10323 param->reason = SCAN_REASON_PREEMPTED; 10324 break; 10325 case WMI_SCAN_REASON_TIMEDOUT: 10326 param->reason = SCAN_REASON_TIMEDOUT; 10327 break; 10328 case WMI_SCAN_REASON_INTERNAL_FAILURE: 10329 param->reason = SCAN_REASON_INTERNAL_FAILURE; 10330 break; 10331 case WMI_SCAN_REASON_SUSPENDED: 10332 param->reason = SCAN_REASON_SUSPENDED; 10333 break; 10334 case WMI_SCAN_REASON_DFS_VIOLATION: 10335 param->reason = SCAN_REASON_DFS_VIOLATION; 10336 break; 10337 case WMI_SCAN_REASON_MAX: 10338 param->reason = SCAN_REASON_MAX; 10339 break; 10340 default: 10341 param->reason = SCAN_REASON_MAX; 10342 break; 10343 }; 10344 10345 param->chan_freq = evt->channel_freq; 10346 param->requester = evt->requestor; 10347 param->scan_id = evt->scan_id; 10348 param->vdev_id = evt->vdev_id; 10349 param->timestamp = evt->tsf_timestamp; 10350 10351 return QDF_STATUS_SUCCESS; 10352 } 10353 10354 #ifdef FEATURE_WLAN_SCAN_PNO 10355 /** 10356 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 10357 * @wmi_handle: pointer to WMI handle 10358 * @evt_buf: pointer to WMI event buffer 10359 * @param: pointer to scan event param for NLO match 10360 * 10361 * Return: QDF_STATUS_SUCCESS for success or error code 10362 */ 10363 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 10364 void *evt_buf, 10365 struct scan_event *param) 10366 { 10367 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 10368 wmi_nlo_event *evt = param_buf->fixed_param; 10369 10370 qdf_mem_zero(param, sizeof(*param)); 10371 10372 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 10373 param->vdev_id = evt->vdev_id; 10374 10375 return QDF_STATUS_SUCCESS; 10376 } 10377 10378 /** 10379 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 10380 * @wmi_handle: pointer to WMI handle 10381 * @evt_buf: pointer to WMI event buffer 10382 * @param: pointer to scan event param for NLO complete 10383 * 10384 * Return: QDF_STATUS_SUCCESS for success or error code 10385 */ 10386 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 10387 void *evt_buf, 10388 struct scan_event *param) 10389 { 10390 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 10391 wmi_nlo_event *evt = param_buf->fixed_param; 10392 10393 qdf_mem_zero(param, sizeof(*param)); 10394 10395 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 10396 param->vdev_id = evt->vdev_id; 10397 10398 return QDF_STATUS_SUCCESS; 10399 } 10400 #endif 10401 10402 /** 10403 * extract_unit_test_tlv() - extract unit test data 10404 * @wmi_handle: wmi handle 10405 * @param evt_buf: pointer to event buffer 10406 * @param unit_test: pointer to hold unit test data 10407 * @param maxspace: Amount of space in evt_buf 10408 * 10409 * Return: QDF_STATUS_SUCCESS for success or error code 10410 */ 10411 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 10412 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 10413 { 10414 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 10415 wmi_unit_test_event_fixed_param *ev_param; 10416 uint32_t num_bufp; 10417 uint32_t copy_size; 10418 uint8_t *bufp; 10419 10420 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 10421 ev_param = param_buf->fixed_param; 10422 bufp = param_buf->bufp; 10423 num_bufp = param_buf->num_bufp; 10424 unit_test->vdev_id = ev_param->vdev_id; 10425 unit_test->module_id = ev_param->module_id; 10426 unit_test->diag_token = ev_param->diag_token; 10427 unit_test->flag = ev_param->flag; 10428 unit_test->payload_len = ev_param->payload_len; 10429 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 10430 ev_param->vdev_id, 10431 ev_param->module_id, 10432 ev_param->diag_token, 10433 ev_param->flag); 10434 wmi_debug("Unit-test data given below %d", num_bufp); 10435 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10436 bufp, num_bufp); 10437 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 10438 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 10439 unit_test->buffer_len = copy_size; 10440 10441 return QDF_STATUS_SUCCESS; 10442 } 10443 10444 /** 10445 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 10446 * @wmi_handle: wmi handle 10447 * @param evt_buf: pointer to event buffer 10448 * @param index: Index into extended pdev stats 10449 * @param pdev_ext_stats: Pointer to hold extended pdev stats 10450 * 10451 * Return: QDF_STATUS_SUCCESS for success or error code 10452 */ 10453 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 10454 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 10455 { 10456 return QDF_STATUS_SUCCESS; 10457 } 10458 10459 /** 10460 * extract_bcn_stats_tlv() - extract bcn stats from event 10461 * @wmi_handle: wmi handle 10462 * @param evt_buf: pointer to event buffer 10463 * @param index: Index into vdev stats 10464 * @param bcn_stats: Pointer to hold bcn stats 10465 * 10466 * Return: QDF_STATUS_SUCCESS for success or error code 10467 */ 10468 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 10469 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 10470 { 10471 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10472 wmi_stats_event_fixed_param *ev_param; 10473 uint8_t *data; 10474 10475 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 10476 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 10477 data = (uint8_t *) param_buf->data; 10478 10479 if (index < ev_param->num_bcn_stats) { 10480 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 10481 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 10482 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 10483 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 10484 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 10485 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 10486 (index * sizeof(wmi_bcn_stats))); 10487 10488 bcn_stats->vdev_id = ev->vdev_id; 10489 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 10490 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 10491 } 10492 10493 return QDF_STATUS_SUCCESS; 10494 } 10495 10496 /** 10497 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 10498 * stats from event 10499 * @wmi_handle: wmi handle 10500 * @param evt_buf: pointer to event buffer 10501 * @param index: Index into vdev stats 10502 * @param vdev_prb_fd_stats: Pointer to hold vdev probe and fils stats 10503 * 10504 * Return: QDF_STATUS_SUCCESS for success or error code 10505 */ 10506 static QDF_STATUS 10507 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 10508 void *evt_buf, uint32_t index, 10509 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 10510 { 10511 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10512 wmi_vdev_extd_stats *ev; 10513 10514 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 10515 10516 if (param_buf->vdev_extd_stats) { 10517 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 10518 index); 10519 vdev_stats->vdev_id = ev->vdev_id; 10520 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 10521 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 10522 vdev_stats->unsolicited_prb_succ_cnt = 10523 ev->unsolicited_prb_succ_cnt; 10524 vdev_stats->unsolicited_prb_fail_cnt = 10525 ev->unsolicited_prb_fail_cnt; 10526 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 10527 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 10528 ev->unsolicited_prb_succ_cnt, 10529 ev->unsolicited_prb_fail_cnt); 10530 } 10531 10532 return QDF_STATUS_SUCCESS; 10533 } 10534 10535 /** 10536 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 10537 * @wmi_handle: wmi handle 10538 * @param evt_buf: pointer to event buffer 10539 * @param index: Index into bcn fault stats 10540 * @param bcnflt_stats: Pointer to hold bcn fault stats 10541 * 10542 * Return: QDF_STATUS_SUCCESS for success or error code 10543 */ 10544 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 10545 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 10546 { 10547 return QDF_STATUS_SUCCESS; 10548 } 10549 10550 /** 10551 * extract_chan_stats_tlv() - extract chan stats from event 10552 * @wmi_handle: wmi handle 10553 * @param evt_buf: pointer to event buffer 10554 * @param index: Index into chan stats 10555 * @param vdev_extd_stats: Pointer to hold chan stats 10556 * 10557 * Return: QDF_STATUS_SUCCESS for success or error code 10558 */ 10559 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 10560 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 10561 { 10562 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10563 wmi_stats_event_fixed_param *ev_param; 10564 uint8_t *data; 10565 10566 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 10567 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 10568 data = (uint8_t *) param_buf->data; 10569 10570 if (index < ev_param->num_chan_stats) { 10571 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 10572 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 10573 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 10574 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 10575 (index * sizeof(wmi_chan_stats))); 10576 10577 10578 /* Non-TLV doesn't have num_chan_stats */ 10579 chan_stats->chan_mhz = ev->chan_mhz; 10580 chan_stats->sampling_period_us = ev->sampling_period_us; 10581 chan_stats->rx_clear_count = ev->rx_clear_count; 10582 chan_stats->tx_duration_us = ev->tx_duration_us; 10583 chan_stats->rx_duration_us = ev->rx_duration_us; 10584 } 10585 10586 return QDF_STATUS_SUCCESS; 10587 } 10588 10589 /** 10590 * extract_profile_ctx_tlv() - extract profile context from event 10591 * @wmi_handle: wmi handle 10592 * @param evt_buf: pointer to event buffer 10593 * @idx: profile stats index to extract 10594 * @param profile_ctx: Pointer to hold profile context 10595 * 10596 * Return: QDF_STATUS_SUCCESS for success or error code 10597 */ 10598 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 10599 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 10600 { 10601 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 10602 10603 wmi_wlan_profile_ctx_t *ev; 10604 10605 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 10606 if (!param_buf) { 10607 wmi_err("Invalid profile data event buf"); 10608 return QDF_STATUS_E_INVAL; 10609 } 10610 10611 ev = param_buf->profile_ctx; 10612 10613 profile_ctx->tot = ev->tot; 10614 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 10615 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 10616 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 10617 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 10618 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 10619 profile_ctx->bin_count = ev->bin_count; 10620 10621 return QDF_STATUS_SUCCESS; 10622 } 10623 10624 /** 10625 * extract_profile_data_tlv() - extract profile data from event 10626 * @wmi_handle: wmi handle 10627 * @param evt_buf: pointer to event buffer 10628 * @param profile_data: Pointer to hold profile data 10629 * 10630 * Return: QDF_STATUS_SUCCESS for success or error code 10631 */ 10632 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 10633 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 10634 { 10635 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 10636 wmi_wlan_profile_t *ev; 10637 uint8_t *buf_ptr; 10638 10639 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 10640 if (!param_buf) { 10641 wmi_err("Invalid profile data event buf"); 10642 return QDF_STATUS_E_INVAL; 10643 } 10644 10645 buf_ptr = (uint8_t *)param_buf->profile_ctx; 10646 buf_ptr = buf_ptr + sizeof(wmi_wlan_profile_ctx_t) + WMI_TLV_HDR_SIZE; 10647 10648 buf_ptr = buf_ptr + (sizeof(wmi_wlan_profile_t) * idx); 10649 ev = (wmi_wlan_profile_t *)buf_ptr; 10650 10651 profile_data->id = ev->id; 10652 profile_data->cnt = ev->cnt; 10653 profile_data->tot = ev->tot; 10654 profile_data->min = ev->min; 10655 profile_data->max = ev->max; 10656 profile_data->hist_intvl = ev->hist_intvl; 10657 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 10658 10659 return QDF_STATUS_SUCCESS; 10660 } 10661 10662 /** 10663 * extract_pdev_utf_event_tlv() - extract UTF data info from event 10664 * @wmi_handle: WMI handle 10665 * @param evt_buf: Pointer to event buffer 10666 * @param param: Pointer to hold data 10667 * 10668 * Return : QDF_STATUS_SUCCESS for success or error code 10669 */ 10670 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 10671 uint8_t *evt_buf, 10672 struct wmi_host_pdev_utf_event *event) 10673 { 10674 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 10675 struct wmi_host_utf_seg_header_info *seg_hdr; 10676 10677 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 10678 event->data = param_buf->data; 10679 event->datalen = param_buf->num_data; 10680 10681 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 10682 wmi_err("Invalid datalen: %d", event->datalen); 10683 return QDF_STATUS_E_INVAL; 10684 } 10685 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 10686 /* Set pdev_id=1 until FW adds support to include pdev_id */ 10687 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 10688 wmi_handle, 10689 seg_hdr->pdev_id); 10690 10691 return QDF_STATUS_SUCCESS; 10692 } 10693 10694 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 10695 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 10696 uint8_t *event, 10697 uint32_t *num_rf_characterization_entries) 10698 { 10699 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 10700 10701 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 10702 if (!param_buf) 10703 return QDF_STATUS_E_INVAL; 10704 10705 *num_rf_characterization_entries = 10706 param_buf->num_wmi_chan_rf_characterization_info; 10707 10708 return QDF_STATUS_SUCCESS; 10709 } 10710 10711 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 10712 uint8_t *event, 10713 uint32_t num_rf_characterization_entries, 10714 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 10715 { 10716 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 10717 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 10718 uint8_t ix; 10719 10720 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 10721 if (!param_buf) 10722 return QDF_STATUS_E_INVAL; 10723 10724 wmi_rf_characterization_entry = 10725 param_buf->wmi_chan_rf_characterization_info; 10726 if (!wmi_rf_characterization_entry) 10727 return QDF_STATUS_E_INVAL; 10728 10729 /* 10730 * Using num_wmi_chan_rf_characterization instead of param_buf value 10731 * since memory for rf_characterization_entries was allocated using 10732 * the former. 10733 */ 10734 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 10735 rf_characterization_entries[ix].freq = 10736 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 10737 &wmi_rf_characterization_entry[ix]); 10738 10739 rf_characterization_entries[ix].bw = 10740 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 10741 &wmi_rf_characterization_entry[ix]); 10742 10743 rf_characterization_entries[ix].chan_metric = 10744 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 10745 &wmi_rf_characterization_entry[ix]); 10746 10747 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 10748 "bw: %u, chan_metric: %u", 10749 ix, rf_characterization_entries[ix].freq, 10750 rf_characterization_entries[ix].bw, 10751 rf_characterization_entries[ix].chan_metric); 10752 } 10753 10754 return QDF_STATUS_SUCCESS; 10755 } 10756 #endif 10757 10758 /** 10759 * extract_chainmask_tables_tlv() - extract chain mask tables from event 10760 * @wmi_handle: wmi handle 10761 * @param evt_buf: pointer to event buffer 10762 * @param param: Pointer to hold evt buf 10763 * 10764 * Return: QDF_STATUS_SUCCESS for success or error code 10765 */ 10766 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 10767 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 10768 { 10769 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 10770 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 10771 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 10772 uint8_t i = 0, j = 0; 10773 uint32_t num_mac_phy_chainmask_caps = 0; 10774 10775 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 10776 if (!param_buf) 10777 return QDF_STATUS_E_INVAL; 10778 10779 hw_caps = param_buf->soc_hw_mode_caps; 10780 if (!hw_caps) 10781 return QDF_STATUS_E_INVAL; 10782 10783 if ((!hw_caps->num_chainmask_tables) || 10784 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 10785 (hw_caps->num_chainmask_tables > 10786 param_buf->num_mac_phy_chainmask_combo)) 10787 return QDF_STATUS_E_INVAL; 10788 10789 chainmask_caps = param_buf->mac_phy_chainmask_caps; 10790 10791 if (!chainmask_caps) 10792 return QDF_STATUS_E_INVAL; 10793 10794 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 10795 if (chainmask_table[i].num_valid_chainmasks > 10796 (UINT_MAX - num_mac_phy_chainmask_caps)) { 10797 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 10798 num_mac_phy_chainmask_caps, i, 10799 chainmask_table[i].num_valid_chainmasks); 10800 return QDF_STATUS_E_INVAL; 10801 } 10802 num_mac_phy_chainmask_caps += 10803 chainmask_table[i].num_valid_chainmasks; 10804 } 10805 10806 if (num_mac_phy_chainmask_caps > 10807 param_buf->num_mac_phy_chainmask_caps) { 10808 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 10809 num_mac_phy_chainmask_caps, 10810 param_buf->num_mac_phy_chainmask_caps); 10811 return QDF_STATUS_E_INVAL; 10812 } 10813 10814 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 10815 10816 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 10817 i); 10818 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 10819 10820 chainmask_table[i].cap_list[j].chainmask = 10821 chainmask_caps->chainmask; 10822 10823 chainmask_table[i].cap_list[j].supports_chan_width_20 = 10824 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 10825 10826 chainmask_table[i].cap_list[j].supports_chan_width_40 = 10827 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 10828 10829 chainmask_table[i].cap_list[j].supports_chan_width_80 = 10830 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 10831 10832 chainmask_table[i].cap_list[j].supports_chan_width_160 = 10833 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 10834 10835 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 10836 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 10837 10838 chainmask_table[i].cap_list[j].chain_mask_2G = 10839 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 10840 10841 chainmask_table[i].cap_list[j].chain_mask_5G = 10842 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 10843 10844 chainmask_table[i].cap_list[j].chain_mask_tx = 10845 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 10846 10847 chainmask_table[i].cap_list[j].chain_mask_rx = 10848 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 10849 10850 chainmask_table[i].cap_list[j].supports_aDFS = 10851 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 10852 10853 chainmask_table[i].cap_list[j].supports_aSpectral = 10854 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 10855 10856 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 10857 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 10858 10859 chainmask_table[i].cap_list[j].supports_aDFS_160 = 10860 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 10861 10862 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 10863 chainmask_caps->supported_flags, 10864 chainmask_caps->chainmask); 10865 chainmask_caps++; 10866 } 10867 } 10868 10869 return QDF_STATUS_SUCCESS; 10870 } 10871 10872 /** 10873 * extract_service_ready_ext_tlv() - extract basic extended service ready params 10874 * from event 10875 * @wmi_handle: wmi handle 10876 * @param evt_buf: pointer to event buffer 10877 * @param param: Pointer to hold evt buf 10878 * 10879 * Return: QDF_STATUS_SUCCESS for success or error code 10880 */ 10881 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 10882 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 10883 { 10884 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 10885 wmi_service_ready_ext_event_fixed_param *ev; 10886 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 10887 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 10888 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 10889 uint8_t i = 0; 10890 10891 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 10892 if (!param_buf) 10893 return QDF_STATUS_E_INVAL; 10894 10895 ev = param_buf->fixed_param; 10896 if (!ev) 10897 return QDF_STATUS_E_INVAL; 10898 10899 /* Move this to host based bitmap */ 10900 param->default_conc_scan_config_bits = 10901 ev->default_conc_scan_config_bits; 10902 param->default_fw_config_bits = ev->default_fw_config_bits; 10903 param->he_cap_info = ev->he_cap_info; 10904 param->mpdu_density = ev->mpdu_density; 10905 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 10906 param->fw_build_vers_ext = ev->fw_build_vers_ext; 10907 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 10908 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 10909 param->max_bssid_indicator = ev->max_bssid_indicator; 10910 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 10911 10912 hw_caps = param_buf->soc_hw_mode_caps; 10913 if (hw_caps) 10914 param->num_hw_modes = hw_caps->num_hw_modes; 10915 else 10916 param->num_hw_modes = 0; 10917 10918 reg_caps = param_buf->soc_hal_reg_caps; 10919 if (reg_caps) 10920 param->num_phy = reg_caps->num_phy; 10921 else 10922 param->num_phy = 0; 10923 10924 if (hw_caps) { 10925 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 10926 wmi_nofl_debug("Num chain mask tables: %d", 10927 hw_caps->num_chainmask_tables); 10928 } else 10929 param->num_chainmask_tables = 0; 10930 10931 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 10932 param->num_chainmask_tables > 10933 param_buf->num_mac_phy_chainmask_combo) { 10934 wmi_err_rl("num_chainmask_tables is OOB: %u", 10935 param->num_chainmask_tables); 10936 return QDF_STATUS_E_INVAL; 10937 } 10938 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 10939 10940 if (!chain_mask_combo) 10941 return QDF_STATUS_SUCCESS; 10942 10943 wmi_nofl_debug("Dumping chain mask combo data"); 10944 10945 for (i = 0; i < param->num_chainmask_tables; i++) { 10946 10947 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 10948 chain_mask_combo->chainmask_table_id, 10949 chain_mask_combo->num_valid_chainmask); 10950 10951 param->chainmask_table[i].table_id = 10952 chain_mask_combo->chainmask_table_id; 10953 param->chainmask_table[i].num_valid_chainmasks = 10954 chain_mask_combo->num_valid_chainmask; 10955 chain_mask_combo++; 10956 } 10957 wmi_nofl_debug("chain mask combo end"); 10958 10959 return QDF_STATUS_SUCCESS; 10960 } 10961 10962 /** 10963 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 10964 * event 10965 * @wmi_handle: wmi handle 10966 * @event: pointer to event buffer 10967 * @param: Pointer to hold the params 10968 * 10969 * Return: QDF_STATUS_SUCCESS for success or error code 10970 */ 10971 static QDF_STATUS 10972 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 10973 struct wlan_psoc_host_service_ext2_param *param) 10974 { 10975 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 10976 wmi_service_ready_ext2_event_fixed_param *ev; 10977 10978 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 10979 if (!param_buf) 10980 return QDF_STATUS_E_INVAL; 10981 10982 ev = param_buf->fixed_param; 10983 if (!ev) 10984 return QDF_STATUS_E_INVAL; 10985 10986 param->reg_db_version_major = 10987 WMI_REG_DB_VERSION_MAJOR_GET( 10988 ev->reg_db_version); 10989 param->reg_db_version_minor = 10990 WMI_REG_DB_VERSION_MINOR_GET( 10991 ev->reg_db_version); 10992 param->bdf_reg_db_version_major = 10993 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 10994 ev->reg_db_version); 10995 param->bdf_reg_db_version_minor = 10996 WMI_BDF_REG_DB_VERSION_MINOR_GET( 10997 ev->reg_db_version); 10998 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 10999 11000 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 11001 11002 if (param_buf->nan_cap) 11003 param->max_ndp_sessions = 11004 param_buf->nan_cap->max_ndp_sessions; 11005 else 11006 param->max_ndp_sessions = 0; 11007 11008 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 11009 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 11010 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 11011 ev->max_user_per_ppdu_ofdma); 11012 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 11013 ev->max_user_per_ppdu_ofdma); 11014 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 11015 ev->max_user_per_ppdu_mumimo); 11016 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 11017 ev->max_user_per_ppdu_mumimo); 11018 11019 return QDF_STATUS_SUCCESS; 11020 } 11021 11022 /** 11023 * extract_sar_cap_service_ready_ext_tlv() - 11024 * extract SAR cap from service ready event 11025 * @wmi_handle: wmi handle 11026 * @event: pointer to event buffer 11027 * @ext_param: extended target info 11028 * 11029 * Return: QDF_STATUS_SUCCESS for success or error code 11030 */ 11031 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 11032 wmi_unified_t wmi_handle, 11033 uint8_t *event, 11034 struct wlan_psoc_host_service_ext_param *ext_param) 11035 { 11036 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11037 WMI_SAR_CAPABILITIES *sar_caps; 11038 11039 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 11040 11041 if (!param_buf) 11042 return QDF_STATUS_E_INVAL; 11043 11044 sar_caps = param_buf->sar_caps; 11045 if (sar_caps) 11046 ext_param->sar_version = sar_caps->active_version; 11047 else 11048 ext_param->sar_version = 0; 11049 11050 return QDF_STATUS_SUCCESS; 11051 } 11052 11053 /** 11054 * extract_hw_mode_cap_service_ready_ext_tlv() - 11055 * extract HW mode cap from service ready event 11056 * @wmi_handle: wmi handle 11057 * @param evt_buf: pointer to event buffer 11058 * @param param: Pointer to hold evt buf 11059 * @param hw_mode_idx: hw mode idx should be less than num_mode 11060 * 11061 * Return: QDF_STATUS_SUCCESS for success or error code 11062 */ 11063 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 11064 wmi_unified_t wmi_handle, 11065 uint8_t *event, uint8_t hw_mode_idx, 11066 struct wlan_psoc_host_hw_mode_caps *param) 11067 { 11068 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11069 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 11070 11071 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11072 if (!param_buf) 11073 return QDF_STATUS_E_INVAL; 11074 11075 hw_caps = param_buf->soc_hw_mode_caps; 11076 if (!hw_caps) 11077 return QDF_STATUS_E_INVAL; 11078 11079 if (!hw_caps->num_hw_modes || 11080 !param_buf->hw_mode_caps || 11081 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 11082 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 11083 return QDF_STATUS_E_INVAL; 11084 11085 if (hw_mode_idx >= hw_caps->num_hw_modes) 11086 return QDF_STATUS_E_INVAL; 11087 11088 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 11089 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 11090 11091 param->hw_mode_config_type = 11092 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 11093 11094 return QDF_STATUS_SUCCESS; 11095 } 11096 11097 /** 11098 * extract_mac_phy_cap_service_ready_ext_tlv() - 11099 * extract MAC phy cap from service ready event 11100 * @wmi_handle: wmi handle 11101 * @param evt_buf: pointer to event buffer 11102 * @param param: Pointer to hold evt buf 11103 * @param hw_mode_idx: hw mode idx should be less than num_mode 11104 * @param phy_id: phy id within hw_mode 11105 * 11106 * Return: QDF_STATUS_SUCCESS for success or error code 11107 */ 11108 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 11109 wmi_unified_t wmi_handle, 11110 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 11111 struct wlan_psoc_host_mac_phy_caps *param) 11112 { 11113 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11114 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 11115 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 11116 uint32_t phy_map; 11117 uint8_t hw_idx, phy_idx = 0; 11118 11119 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11120 if (!param_buf) 11121 return QDF_STATUS_E_INVAL; 11122 11123 hw_caps = param_buf->soc_hw_mode_caps; 11124 if (!hw_caps) 11125 return QDF_STATUS_E_INVAL; 11126 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 11127 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 11128 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 11129 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 11130 return QDF_STATUS_E_INVAL; 11131 } 11132 11133 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 11134 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 11135 break; 11136 11137 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 11138 while (phy_map) { 11139 phy_map >>= 1; 11140 phy_idx++; 11141 } 11142 } 11143 11144 if (hw_idx == hw_caps->num_hw_modes) 11145 return QDF_STATUS_E_INVAL; 11146 11147 phy_idx += phy_id; 11148 if (phy_idx >= param_buf->num_mac_phy_caps) 11149 return QDF_STATUS_E_INVAL; 11150 11151 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 11152 11153 param->hw_mode_id = mac_phy_caps->hw_mode_id; 11154 param->phy_idx = phy_idx; 11155 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11156 wmi_handle, 11157 mac_phy_caps->pdev_id); 11158 param->tgt_pdev_id = mac_phy_caps->pdev_id; 11159 param->phy_id = mac_phy_caps->phy_id; 11160 param->supports_11b = 11161 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 11162 param->supports_11g = 11163 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 11164 param->supports_11a = 11165 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 11166 param->supports_11n = 11167 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 11168 param->supports_11ac = 11169 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 11170 param->supports_11ax = 11171 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 11172 11173 param->supported_bands = mac_phy_caps->supported_bands; 11174 param->ampdu_density = mac_phy_caps->ampdu_density; 11175 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 11176 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 11177 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 11178 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 11179 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 11180 mac_phy_caps->he_cap_info_2G; 11181 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 11182 mac_phy_caps->he_cap_info_2G_ext; 11183 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 11184 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 11185 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 11186 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 11187 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 11188 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 11189 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 11190 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 11191 mac_phy_caps->he_cap_info_5G; 11192 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 11193 mac_phy_caps->he_cap_info_5G_ext; 11194 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 11195 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 11196 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 11197 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 11198 qdf_mem_copy(¶m->he_cap_phy_info_2G, 11199 &mac_phy_caps->he_cap_phy_info_2G, 11200 sizeof(param->he_cap_phy_info_2G)); 11201 qdf_mem_copy(¶m->he_cap_phy_info_5G, 11202 &mac_phy_caps->he_cap_phy_info_5G, 11203 sizeof(param->he_cap_phy_info_5G)); 11204 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 11205 sizeof(param->he_ppet2G)); 11206 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 11207 sizeof(param->he_ppet5G)); 11208 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 11209 param->lmac_id = mac_phy_caps->lmac_id; 11210 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 11211 (mac_phy_caps->wireless_modes); 11212 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 11213 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 11214 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 11215 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 11216 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 11217 mac_phy_caps->nss_ratio); 11218 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 11219 11220 return QDF_STATUS_SUCCESS; 11221 } 11222 11223 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 11224 wmi_unified_t wmi_handle, 11225 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 11226 uint8_t phy_idx, 11227 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 11228 { 11229 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 11230 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 11231 11232 if (!event) { 11233 wmi_err("null evt_buf"); 11234 return QDF_STATUS_E_INVAL; 11235 } 11236 11237 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 11238 11239 if (!param_buf->num_mac_phy_caps) 11240 return QDF_STATUS_SUCCESS; 11241 11242 if (phy_idx >= param_buf->num_mac_phy_caps) 11243 return QDF_STATUS_E_INVAL; 11244 11245 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 11246 11247 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 11248 (phy_id != mac_phy_caps->phy_id)) 11249 return QDF_STATUS_E_INVAL; 11250 11251 param->hw_mode_id = mac_phy_caps->hw_mode_id; 11252 param->phy_id = mac_phy_caps->phy_id; 11253 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11254 wmi_handle, mac_phy_caps->pdev_id); 11255 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 11256 mac_phy_caps->wireless_modes_ext); 11257 11258 return QDF_STATUS_SUCCESS; 11259 } 11260 11261 /** 11262 * extract_reg_cap_service_ready_ext_tlv() - 11263 * extract REG cap from service ready event 11264 * @wmi_handle: wmi handle 11265 * @param evt_buf: pointer to event buffer 11266 * @param param: Pointer to hold evt buf 11267 * @param phy_idx: phy idx should be less than num_mode 11268 * 11269 * Return: QDF_STATUS_SUCCESS for success or error code 11270 */ 11271 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 11272 wmi_unified_t wmi_handle, 11273 uint8_t *event, uint8_t phy_idx, 11274 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 11275 { 11276 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11277 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 11278 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 11279 11280 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11281 if (!param_buf) 11282 return QDF_STATUS_E_INVAL; 11283 11284 reg_caps = param_buf->soc_hal_reg_caps; 11285 if (!reg_caps) 11286 return QDF_STATUS_E_INVAL; 11287 11288 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 11289 return QDF_STATUS_E_INVAL; 11290 11291 if (phy_idx >= reg_caps->num_phy) 11292 return QDF_STATUS_E_INVAL; 11293 11294 if (!param_buf->hal_reg_caps) 11295 return QDF_STATUS_E_INVAL; 11296 11297 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 11298 11299 param->phy_id = ext_reg_cap->phy_id; 11300 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 11301 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 11302 param->regcap1 = ext_reg_cap->regcap1; 11303 param->regcap2 = ext_reg_cap->regcap2; 11304 param->wireless_modes = convert_wireless_modes_tlv( 11305 ext_reg_cap->wireless_modes); 11306 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 11307 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 11308 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 11309 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 11310 11311 return QDF_STATUS_SUCCESS; 11312 } 11313 11314 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 11315 uint8_t num_dma_ring_caps) 11316 { 11317 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 11318 if (!num_dma_ring_caps) { 11319 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 11320 return QDF_STATUS_E_INVAL; 11321 } 11322 if (idx >= num_dma_ring_caps) { 11323 wmi_err("Index %d exceeds range", idx); 11324 return QDF_STATUS_E_INVAL; 11325 } 11326 return QDF_STATUS_SUCCESS; 11327 } 11328 11329 static void 11330 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 11331 struct wlan_psoc_host_dbr_ring_caps *param, 11332 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 11333 { 11334 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 11335 wmi_handle, 11336 dbr_ring_caps->pdev_id); 11337 param->mod_id = dbr_ring_caps->mod_id; 11338 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 11339 param->min_buf_size = dbr_ring_caps->min_buf_size; 11340 param->min_buf_align = dbr_ring_caps->min_buf_align; 11341 } 11342 11343 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 11344 wmi_unified_t wmi_handle, 11345 uint8_t *event, uint8_t idx, 11346 struct wlan_psoc_host_dbr_ring_caps *param) 11347 { 11348 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11349 QDF_STATUS status; 11350 11351 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 11352 if (!param_buf) 11353 return QDF_STATUS_E_INVAL; 11354 11355 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 11356 if (status != QDF_STATUS_SUCCESS) 11357 return status; 11358 11359 populate_dbr_ring_cap_elems(wmi_handle, param, 11360 ¶m_buf->dma_ring_caps[idx]); 11361 return QDF_STATUS_SUCCESS; 11362 } 11363 11364 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 11365 wmi_unified_t wmi_handle, 11366 uint8_t *event, uint8_t idx, 11367 struct wlan_psoc_host_dbr_ring_caps *param) 11368 { 11369 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 11370 QDF_STATUS status; 11371 11372 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 11373 if (!param_buf) 11374 return QDF_STATUS_E_INVAL; 11375 11376 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 11377 if (status != QDF_STATUS_SUCCESS) 11378 return status; 11379 11380 populate_dbr_ring_cap_elems(wmi_handle, param, 11381 ¶m_buf->dma_ring_caps[idx]); 11382 return QDF_STATUS_SUCCESS; 11383 } 11384 11385 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 11386 wmi_unified_t wmi_handle, 11387 uint8_t *event, uint8_t idx, 11388 struct wlan_psoc_host_scan_radio_caps *param) 11389 { 11390 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 11391 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 11392 11393 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 11394 if (!param_buf) 11395 return QDF_STATUS_E_INVAL; 11396 11397 if (idx >= param_buf->num_wmi_scan_radio_caps) 11398 return QDF_STATUS_E_INVAL; 11399 11400 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 11401 param->phy_id = scan_radio_caps->phy_id; 11402 param->scan_radio_supported = 11403 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 11404 param->dfs_en = 11405 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 11406 11407 return QDF_STATUS_SUCCESS; 11408 } 11409 11410 /** 11411 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 11412 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 11413 * 11414 * Return: host thermal throt level 11415 */ 11416 static enum thermal_throttle_level 11417 wmi_tgt_thermal_level_to_host(uint32_t level) 11418 { 11419 switch (level) { 11420 case WMI_THERMAL_FULLPERF: 11421 return THERMAL_FULLPERF; 11422 case WMI_THERMAL_MITIGATION: 11423 return THERMAL_MITIGATION; 11424 case WMI_THERMAL_SHUTOFF: 11425 return THERMAL_SHUTOFF; 11426 default: 11427 return THERMAL_UNKNOWN; 11428 } 11429 } 11430 11431 /** 11432 * extract_thermal_stats_tlv() - extract thermal stats from event 11433 * @wmi_handle: wmi handle 11434 * @param evt_buf: Pointer to event buffer 11435 * @param temp: Pointer to hold extracted temperature 11436 * @param level: Pointer to hold extracted level in host enum 11437 * 11438 * Return: 0 for success or error code 11439 */ 11440 static QDF_STATUS 11441 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 11442 void *evt_buf, uint32_t *temp, 11443 enum thermal_throttle_level *level, uint32_t *pdev_id) 11444 { 11445 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 11446 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 11447 11448 param_buf = 11449 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 11450 if (!param_buf) 11451 return QDF_STATUS_E_INVAL; 11452 11453 tt_stats_event = param_buf->fixed_param; 11454 wmi_debug("thermal temperature %d level %d", 11455 tt_stats_event->temp, tt_stats_event->level); 11456 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11457 wmi_handle, 11458 tt_stats_event->pdev_id); 11459 *temp = tt_stats_event->temp; 11460 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 11461 11462 return QDF_STATUS_SUCCESS; 11463 } 11464 11465 /** 11466 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 11467 * @wmi_handle: wmi handle 11468 * @param evt_buf: pointer to event buffer 11469 * @param idx: Index to level stats 11470 * @param levelcount: Pointer to hold levelcount 11471 * @param dccount: Pointer to hold dccount 11472 * 11473 * Return: 0 for success or error code 11474 */ 11475 static QDF_STATUS 11476 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 11477 void *evt_buf, uint8_t idx, uint32_t *levelcount, 11478 uint32_t *dccount) 11479 { 11480 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 11481 wmi_therm_throt_level_stats_info *tt_level_info; 11482 11483 param_buf = 11484 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 11485 if (!param_buf) 11486 return QDF_STATUS_E_INVAL; 11487 11488 tt_level_info = param_buf->therm_throt_level_stats_info; 11489 11490 if (idx < THERMAL_LEVELS) { 11491 *levelcount = tt_level_info[idx].level_count; 11492 *dccount = tt_level_info[idx].dc_count; 11493 return QDF_STATUS_SUCCESS; 11494 } 11495 11496 return QDF_STATUS_E_FAILURE; 11497 } 11498 #ifdef BIG_ENDIAN_HOST 11499 /** 11500 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 11501 * @param data_len - data length 11502 * @param data - pointer to data 11503 * 11504 * Return: QDF_STATUS - success or error status 11505 */ 11506 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 11507 { 11508 uint8_t *data_aligned = NULL; 11509 int c; 11510 unsigned char *data_unaligned; 11511 11512 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 11513 FIPS_ALIGN)); 11514 /* Assigning unaligned space to copy the data */ 11515 /* Checking if kmalloc does successful allocation */ 11516 if (!data_unaligned) 11517 return QDF_STATUS_E_FAILURE; 11518 11519 /* Checking if space is alligned */ 11520 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 11521 /* align the data space */ 11522 data_aligned = 11523 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 11524 } else { 11525 data_aligned = (u_int8_t *)data_unaligned; 11526 } 11527 11528 /* memset and copy content from data to data aligned */ 11529 OS_MEMSET(data_aligned, 0, data_len); 11530 OS_MEMCPY(data_aligned, data, data_len); 11531 /* Endianness to LE */ 11532 for (c = 0; c < data_len/4; c++) { 11533 *((u_int32_t *)data_aligned + c) = 11534 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 11535 } 11536 11537 /* Copy content to event->data */ 11538 OS_MEMCPY(data, data_aligned, data_len); 11539 11540 /* clean up allocated space */ 11541 qdf_mem_free(data_unaligned); 11542 data_aligned = NULL; 11543 data_unaligned = NULL; 11544 11545 /*************************************************************/ 11546 11547 return QDF_STATUS_SUCCESS; 11548 } 11549 #else 11550 /** 11551 * fips_conv_data_be() - DUMMY for LE platform 11552 * 11553 * Return: QDF_STATUS - success 11554 */ 11555 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 11556 { 11557 return QDF_STATUS_SUCCESS; 11558 } 11559 #endif 11560 11561 /** 11562 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 11563 * @wmi_handle - wmi handle 11564 * @params - PN request params for peer 11565 * 11566 * Return: QDF_STATUS - success or error status 11567 */ 11568 static QDF_STATUS 11569 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 11570 struct peer_request_pn_param *params) 11571 { 11572 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 11573 wmi_buf_t buf; 11574 uint8_t *buf_ptr; 11575 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 11576 11577 buf = wmi_buf_alloc(wmi_handle, len); 11578 if (!buf) { 11579 wmi_err("wmi_buf_alloc failed"); 11580 return QDF_STATUS_E_FAILURE; 11581 } 11582 11583 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11584 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 11585 11586 WMITLV_SET_HDR(&cmd->tlv_header, 11587 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 11588 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 11589 11590 cmd->vdev_id = params->vdev_id; 11591 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 11592 cmd->key_type = params->key_type; 11593 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11594 WMI_PEER_TX_PN_REQUEST_CMDID)) { 11595 wmi_err("Failed to send WMI command"); 11596 wmi_buf_free(buf); 11597 return QDF_STATUS_E_FAILURE; 11598 } 11599 return QDF_STATUS_SUCCESS; 11600 } 11601 11602 /** 11603 * extract_get_pn_data_tlv() - extract pn resp 11604 * @wmi_handle - wmi handle 11605 * @params - PN response params for peer 11606 * 11607 * Return: QDF_STATUS - success or error status 11608 */ 11609 static QDF_STATUS 11610 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 11611 struct wmi_host_get_pn_event *param) 11612 { 11613 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 11614 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 11615 11616 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 11617 event = 11618 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 11619 11620 param->vdev_id = event->vdev_id; 11621 param->key_type = event->key_type; 11622 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 11623 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 11624 11625 return QDF_STATUS_SUCCESS; 11626 } 11627 11628 /** 11629 * extract_fips_event_data_tlv() - extract fips event data 11630 * @wmi_handle: wmi handle 11631 * @param evt_buf: pointer to event buffer 11632 * @param param: pointer FIPS event params 11633 * 11634 * Return: 0 for success or error code 11635 */ 11636 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 11637 void *evt_buf, struct wmi_host_fips_event_param *param) 11638 { 11639 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 11640 wmi_pdev_fips_event_fixed_param *event; 11641 11642 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 11643 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 11644 11645 if (fips_conv_data_be(event->data_len, param_buf->data) != 11646 QDF_STATUS_SUCCESS) 11647 return QDF_STATUS_E_FAILURE; 11648 11649 param->data = (uint32_t *)param_buf->data; 11650 param->data_len = event->data_len; 11651 param->error_status = event->error_status; 11652 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11653 wmi_handle, 11654 event->pdev_id); 11655 11656 return QDF_STATUS_SUCCESS; 11657 } 11658 11659 #ifdef WLAN_FEATURE_DISA 11660 /** 11661 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 11662 * params from event 11663 * @wmi_handle: wmi handle 11664 * @evt_buf: pointer to event buffer 11665 * @resp: Pointer to hold resp parameters 11666 * 11667 * Return: QDF_STATUS_SUCCESS for success or error code 11668 */ 11669 static QDF_STATUS 11670 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 11671 void *evt_buf, 11672 struct disa_encrypt_decrypt_resp_params 11673 *resp) 11674 { 11675 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 11676 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 11677 11678 param_buf = evt_buf; 11679 if (!param_buf) { 11680 wmi_err("encrypt decrypt resp evt_buf is NULL"); 11681 return QDF_STATUS_E_INVAL; 11682 } 11683 11684 data_event = param_buf->fixed_param; 11685 11686 resp->vdev_id = data_event->vdev_id; 11687 resp->status = data_event->status; 11688 11689 if ((data_event->data_length > param_buf->num_enc80211_frame) || 11690 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 11691 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 11692 wmi_err("FW msg data_len %d more than TLV hdr %d", 11693 data_event->data_length, 11694 param_buf->num_enc80211_frame); 11695 return QDF_STATUS_E_INVAL; 11696 } 11697 11698 resp->data_len = data_event->data_length; 11699 11700 if (resp->data_len) 11701 resp->data = (uint8_t *)param_buf->enc80211_frame; 11702 11703 return QDF_STATUS_SUCCESS; 11704 } 11705 #endif /* WLAN_FEATURE_DISA */ 11706 11707 static bool is_management_record_tlv(uint32_t cmd_id) 11708 { 11709 switch (cmd_id) { 11710 case WMI_MGMT_TX_SEND_CMDID: 11711 case WMI_MGMT_TX_COMPLETION_EVENTID: 11712 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 11713 case WMI_MGMT_RX_EVENTID: 11714 return true; 11715 default: 11716 return false; 11717 } 11718 } 11719 11720 static bool is_diag_event_tlv(uint32_t event_id) 11721 { 11722 if (WMI_DIAG_EVENTID == event_id) 11723 return true; 11724 11725 return false; 11726 } 11727 11728 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 11729 { 11730 uint16_t tag = 0; 11731 11732 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 11733 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 11734 __func__); 11735 return tag; 11736 } 11737 11738 if (wmi_handle->tag_crash_inject) 11739 tag = HTC_TX_PACKET_TAG_AUTO_PM; 11740 11741 wmi_handle->tag_crash_inject = false; 11742 return tag; 11743 } 11744 11745 /** 11746 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 11747 * @wmi_handle: WMI handle 11748 * @buf: WMI buffer 11749 * @cmd_id: WMI command Id 11750 * 11751 * Return htc_tx_tag 11752 */ 11753 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 11754 wmi_buf_t buf, 11755 uint32_t cmd_id) 11756 { 11757 uint16_t htc_tx_tag = 0; 11758 11759 switch (cmd_id) { 11760 case WMI_WOW_ENABLE_CMDID: 11761 case WMI_PDEV_SUSPEND_CMDID: 11762 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 11763 case WMI_PDEV_RESUME_CMDID: 11764 case WMI_HB_SET_ENABLE_CMDID: 11765 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 11766 #ifdef FEATURE_WLAN_D0WOW 11767 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 11768 #endif 11769 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 11770 break; 11771 case WMI_FORCE_FW_HANG_CMDID: 11772 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 11773 break; 11774 default: 11775 break; 11776 } 11777 11778 return htc_tx_tag; 11779 } 11780 11781 static struct cur_reg_rule 11782 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 11783 wmi_regulatory_rule_struct *wmi_reg_rule) 11784 { 11785 struct cur_reg_rule *reg_rule_ptr; 11786 uint32_t count; 11787 11788 if (!num_reg_rules) 11789 return NULL; 11790 11791 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 11792 sizeof(*reg_rule_ptr)); 11793 11794 if (!reg_rule_ptr) 11795 return NULL; 11796 11797 for (count = 0; count < num_reg_rules; count++) { 11798 reg_rule_ptr[count].start_freq = 11799 WMI_REG_RULE_START_FREQ_GET( 11800 wmi_reg_rule[count].freq_info); 11801 reg_rule_ptr[count].end_freq = 11802 WMI_REG_RULE_END_FREQ_GET( 11803 wmi_reg_rule[count].freq_info); 11804 reg_rule_ptr[count].max_bw = 11805 WMI_REG_RULE_MAX_BW_GET( 11806 wmi_reg_rule[count].bw_pwr_info); 11807 reg_rule_ptr[count].reg_power = 11808 WMI_REG_RULE_REG_POWER_GET( 11809 wmi_reg_rule[count].bw_pwr_info); 11810 reg_rule_ptr[count].ant_gain = 11811 WMI_REG_RULE_ANTENNA_GAIN_GET( 11812 wmi_reg_rule[count].bw_pwr_info); 11813 reg_rule_ptr[count].flags = 11814 WMI_REG_RULE_FLAGS_GET( 11815 wmi_reg_rule[count].flag_info); 11816 } 11817 11818 return reg_rule_ptr; 11819 } 11820 11821 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 11822 wmi_unified_t wmi_handle, uint8_t *evt_buf, 11823 struct cur_regulatory_info *reg_info, uint32_t len) 11824 { 11825 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 11826 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 11827 wmi_regulatory_rule_struct *wmi_reg_rule; 11828 uint32_t num_2g_reg_rules, num_5g_reg_rules; 11829 11830 wmi_debug("processing regulatory channel list"); 11831 11832 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 11833 if (!param_buf) { 11834 wmi_err("invalid channel list event buf"); 11835 return QDF_STATUS_E_FAILURE; 11836 } 11837 11838 chan_list_event_hdr = param_buf->fixed_param; 11839 11840 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 11841 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 11842 num_2g_reg_rules = reg_info->num_2g_reg_rules; 11843 num_5g_reg_rules = reg_info->num_5g_reg_rules; 11844 if ((num_2g_reg_rules > MAX_REG_RULES) || 11845 (num_5g_reg_rules > MAX_REG_RULES) || 11846 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 11847 (num_2g_reg_rules + num_5g_reg_rules != 11848 param_buf->num_reg_rule_array)) { 11849 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 11850 num_2g_reg_rules, num_5g_reg_rules); 11851 return QDF_STATUS_E_FAILURE; 11852 } 11853 if (param_buf->num_reg_rule_array > 11854 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 11855 sizeof(*wmi_reg_rule)) { 11856 wmi_err_rl("Invalid num_reg_rule_array: %u", 11857 param_buf->num_reg_rule_array); 11858 return QDF_STATUS_E_FAILURE; 11859 } 11860 11861 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 11862 REG_ALPHA2_LEN); 11863 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 11864 reg_info->phybitmap = convert_phybitmap_tlv( 11865 chan_list_event_hdr->phybitmap); 11866 reg_info->offload_enabled = true; 11867 reg_info->num_phy = chan_list_event_hdr->num_phy; 11868 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 11869 wmi_handle, chan_list_event_hdr->phy_id); 11870 reg_info->ctry_code = chan_list_event_hdr->country_id; 11871 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 11872 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 11873 reg_info->status_code = REG_SET_CC_STATUS_PASS; 11874 else if (chan_list_event_hdr->status_code == 11875 WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 11876 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 11877 else if (chan_list_event_hdr->status_code == 11878 WMI_REG_INIT_ALPHA2_NOT_FOUND) 11879 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 11880 else if (chan_list_event_hdr->status_code == 11881 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 11882 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 11883 else if (chan_list_event_hdr->status_code == 11884 WMI_REG_SET_CC_STATUS_NO_MEMORY) 11885 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 11886 else if (chan_list_event_hdr->status_code == 11887 WMI_REG_SET_CC_STATUS_FAIL) 11888 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 11889 11890 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 11891 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 11892 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 11893 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 11894 11895 wmi_debug("num_phys = %u and phy_id = %u", 11896 reg_info->num_phy, reg_info->phy_id); 11897 11898 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 11899 reg_info->alpha2, reg_info->dfs_region, 11900 reg_info->min_bw_2g, reg_info->max_bw_2g, 11901 reg_info->min_bw_5g, reg_info->max_bw_5g); 11902 11903 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 11904 num_2g_reg_rules, num_5g_reg_rules); 11905 wmi_reg_rule = 11906 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 11907 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 11908 + WMI_TLV_HDR_SIZE); 11909 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 11910 wmi_reg_rule); 11911 wmi_reg_rule += num_2g_reg_rules; 11912 11913 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 11914 wmi_reg_rule); 11915 11916 wmi_debug("processed regulatory channel list"); 11917 11918 return QDF_STATUS_SUCCESS; 11919 } 11920 11921 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 11922 wmi_unified_t wmi_handle, uint8_t *evt_buf, 11923 struct reg_11d_new_country *reg_11d_country, uint32_t len) 11924 { 11925 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 11926 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 11927 11928 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 11929 if (!param_buf) { 11930 wmi_err("invalid 11d country event buf"); 11931 return QDF_STATUS_E_FAILURE; 11932 } 11933 11934 reg_11d_country_event = param_buf->fixed_param; 11935 11936 qdf_mem_copy(reg_11d_country->alpha2, 11937 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 11938 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 11939 11940 wmi_debug("processed 11d country event, new cc %s", 11941 reg_11d_country->alpha2); 11942 11943 return QDF_STATUS_SUCCESS; 11944 } 11945 11946 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 11947 wmi_unified_t wmi_handle, uint8_t *evt_buf, 11948 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 11949 { 11950 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 11951 wmi_avoid_freq_range_desc *afr_desc; 11952 uint32_t num_freq_ranges, freq_range_idx; 11953 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 11954 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 11955 11956 if (!param_buf) { 11957 wmi_err("Invalid channel avoid event buffer"); 11958 return QDF_STATUS_E_INVAL; 11959 } 11960 11961 afr_fixed_param = param_buf->fixed_param; 11962 if (!afr_fixed_param) { 11963 wmi_err("Invalid channel avoid event fixed param buffer"); 11964 return QDF_STATUS_E_INVAL; 11965 } 11966 11967 if (!ch_avoid_ind) { 11968 wmi_err("Invalid channel avoid indication buffer"); 11969 return QDF_STATUS_E_INVAL; 11970 } 11971 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 11972 wmi_err("no.of freq ranges exceeded the limit"); 11973 return QDF_STATUS_E_INVAL; 11974 } 11975 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 11976 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 11977 afr_fixed_param->num_freq_ranges; 11978 11979 wmi_debug("Channel avoid event received with %d ranges", 11980 num_freq_ranges); 11981 11982 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 11983 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 11984 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 11985 freq_range_idx++) { 11986 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 11987 afr_desc->start_freq; 11988 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 11989 afr_desc->end_freq; 11990 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 11991 freq_range_idx, afr_desc->tlv_header, 11992 afr_desc->start_freq, afr_desc->end_freq); 11993 afr_desc++; 11994 } 11995 11996 return QDF_STATUS_SUCCESS; 11997 } 11998 11999 #ifdef DFS_COMPONENT_ENABLE 12000 /** 12001 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 12002 * @wmi_handle: wma handle 12003 * @evt_buf: event buffer 12004 * @vdev_id: vdev id 12005 * @len: length of buffer 12006 * 12007 * Return: 0 for success or error code 12008 */ 12009 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 12010 uint8_t *evt_buf, 12011 uint32_t *vdev_id, 12012 uint32_t len) 12013 { 12014 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 12015 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 12016 12017 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 12018 if (!param_tlvs) { 12019 wmi_err("invalid cac complete event buf"); 12020 return QDF_STATUS_E_FAILURE; 12021 } 12022 12023 cac_event = param_tlvs->fixed_param; 12024 *vdev_id = cac_event->vdev_id; 12025 wmi_debug("processed cac complete event vdev %d", *vdev_id); 12026 12027 return QDF_STATUS_SUCCESS; 12028 } 12029 12030 /** 12031 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 12032 * @wmi_handle: wma handle 12033 * @evt_buf: event buffer 12034 * @vdev_id: vdev id 12035 * @len: length of buffer 12036 * 12037 * Return: 0 for success or error code 12038 */ 12039 static QDF_STATUS 12040 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 12041 uint8_t *evt_buf, 12042 struct vdev_adfs_complete_status *param) 12043 { 12044 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 12045 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 12046 12047 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 12048 if (!param_tlvs) { 12049 wmi_err("invalid ocac complete event buf"); 12050 return QDF_STATUS_E_FAILURE; 12051 } 12052 12053 if (!param_tlvs->fixed_param) { 12054 wmi_err("invalid param_tlvs->fixed_param"); 12055 return QDF_STATUS_E_FAILURE; 12056 } 12057 12058 ocac_complete_status = param_tlvs->fixed_param; 12059 param->vdev_id = ocac_complete_status->vdev_id; 12060 param->chan_freq = ocac_complete_status->chan_freq; 12061 param->center_freq1 = ocac_complete_status->center_freq1; 12062 param->center_freq2 = ocac_complete_status->center_freq2; 12063 param->ocac_status = ocac_complete_status->status; 12064 param->chan_width = ocac_complete_status->chan_width; 12065 wmi_debug("processed ocac complete event vdev %d" 12066 " agile chan %d %d width %d status %d", 12067 param->vdev_id, 12068 param->center_freq1, 12069 param->center_freq2, 12070 param->chan_width, 12071 param->ocac_status); 12072 12073 return QDF_STATUS_SUCCESS; 12074 } 12075 12076 /** 12077 * extract_dfs_radar_detection_event_tlv() - extract radar found event 12078 * @wmi_handle: wma handle 12079 * @evt_buf: event buffer 12080 * @radar_found: radar found event info 12081 * @len: length of buffer 12082 * 12083 * Return: 0 for success or error code 12084 */ 12085 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 12086 wmi_unified_t wmi_handle, 12087 uint8_t *evt_buf, 12088 struct radar_found_info *radar_found, 12089 uint32_t len) 12090 { 12091 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 12092 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 12093 12094 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 12095 if (!param_tlv) { 12096 wmi_err("invalid radar detection event buf"); 12097 return QDF_STATUS_E_FAILURE; 12098 } 12099 12100 radar_event = param_tlv->fixed_param; 12101 12102 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 12103 wmi_handle, 12104 radar_event->pdev_id); 12105 12106 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 12107 return QDF_STATUS_E_FAILURE; 12108 12109 radar_found->detection_mode = radar_event->detection_mode; 12110 radar_found->chan_freq = radar_event->chan_freq; 12111 radar_found->chan_width = radar_event->chan_width; 12112 radar_found->detector_id = radar_event->detector_id; 12113 radar_found->segment_id = radar_event->segment_id; 12114 radar_found->timestamp = radar_event->timestamp; 12115 radar_found->is_chirp = radar_event->is_chirp; 12116 radar_found->freq_offset = radar_event->freq_offset; 12117 radar_found->sidx = radar_event->sidx; 12118 12119 wmi_debug("processed radar found event pdev %d," 12120 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 12121 "chan_width (RSSI) %d,detector_id (false_radar) %d," 12122 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 12123 "is_chirp %d,detection mode %d", 12124 radar_event->pdev_id, radar_found->pdev_id, 12125 radar_event->timestamp, radar_event->chan_freq, 12126 radar_event->chan_width, radar_event->detector_id, 12127 radar_event->freq_offset, radar_event->segment_id, 12128 radar_event->sidx, radar_event->is_chirp, 12129 radar_event->detection_mode); 12130 12131 return QDF_STATUS_SUCCESS; 12132 } 12133 12134 #ifdef QCA_MCL_DFS_SUPPORT 12135 /** 12136 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 12137 * @wmi_handle: wma handle 12138 * @evt_buf: event buffer 12139 * @wlan_radar_event: Pointer to struct radar_event_info 12140 * @len: length of buffer 12141 * 12142 * Return: QDF_STATUS 12143 */ 12144 static QDF_STATUS extract_wlan_radar_event_info_tlv( 12145 wmi_unified_t wmi_handle, 12146 uint8_t *evt_buf, 12147 struct radar_event_info *wlan_radar_event, 12148 uint32_t len) 12149 { 12150 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 12151 wmi_dfs_radar_event_fixed_param *radar_event; 12152 12153 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 12154 if (!param_tlv) { 12155 wmi_err("invalid wlan radar event buf"); 12156 return QDF_STATUS_E_FAILURE; 12157 } 12158 12159 radar_event = param_tlv->fixed_param; 12160 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 12161 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 12162 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 12163 wlan_radar_event->rssi = radar_event->rssi; 12164 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 12165 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 12166 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 12167 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 12168 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 12169 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 12170 if (radar_event->pulse_flags & 12171 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 12172 wlan_radar_event->is_psidx_diff_valid = true; 12173 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 12174 } else { 12175 wlan_radar_event->is_psidx_diff_valid = false; 12176 } 12177 12178 wlan_radar_event->pdev_id = radar_event->pdev_id; 12179 12180 return QDF_STATUS_SUCCESS; 12181 } 12182 #else 12183 static QDF_STATUS extract_wlan_radar_event_info_tlv( 12184 wmi_unified_t wmi_handle, 12185 uint8_t *evt_buf, 12186 struct radar_event_info *wlan_radar_event, 12187 uint32_t len) 12188 { 12189 return QDF_STATUS_SUCCESS; 12190 } 12191 #endif 12192 #endif 12193 12194 /** 12195 * send_get_rcpi_cmd_tlv() - send request for rcpi value 12196 * @wmi_handle: wmi handle 12197 * @get_rcpi_param: rcpi params 12198 * 12199 * Return: QDF status 12200 */ 12201 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 12202 struct rcpi_req *get_rcpi_param) 12203 { 12204 wmi_buf_t buf; 12205 wmi_request_rcpi_cmd_fixed_param *cmd; 12206 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 12207 12208 buf = wmi_buf_alloc(wmi_handle, len); 12209 if (!buf) 12210 return QDF_STATUS_E_NOMEM; 12211 12212 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 12213 WMITLV_SET_HDR(&cmd->tlv_header, 12214 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 12215 WMITLV_GET_STRUCT_TLVLEN 12216 (wmi_request_rcpi_cmd_fixed_param)); 12217 12218 cmd->vdev_id = get_rcpi_param->vdev_id; 12219 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 12220 &cmd->peer_macaddr); 12221 12222 switch (get_rcpi_param->measurement_type) { 12223 12224 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 12225 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 12226 break; 12227 12228 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 12229 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 12230 break; 12231 12232 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 12233 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 12234 break; 12235 12236 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 12237 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 12238 break; 12239 12240 default: 12241 /* 12242 * invalid rcpi measurement type, fall back to 12243 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 12244 */ 12245 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 12246 break; 12247 } 12248 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 12249 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 12250 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12251 WMI_REQUEST_RCPI_CMDID)) { 12252 12253 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 12254 wmi_buf_free(buf); 12255 return QDF_STATUS_E_FAILURE; 12256 } 12257 12258 return QDF_STATUS_SUCCESS; 12259 } 12260 12261 /** 12262 * extract_rcpi_response_event_tlv() - Extract RCPI event params 12263 * @wmi_handle: wmi handle 12264 * @evt_buf: pointer to event buffer 12265 * @res: pointer to hold rcpi response from firmware 12266 * 12267 * Return: QDF_STATUS_SUCCESS for successful event parse 12268 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 12269 */ 12270 static QDF_STATUS 12271 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 12272 void *evt_buf, struct rcpi_res *res) 12273 { 12274 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 12275 wmi_update_rcpi_event_fixed_param *event; 12276 12277 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 12278 if (!param_buf) { 12279 wmi_err("Invalid rcpi event"); 12280 return QDF_STATUS_E_INVAL; 12281 } 12282 12283 event = param_buf->fixed_param; 12284 res->vdev_id = event->vdev_id; 12285 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 12286 12287 switch (event->measurement_type) { 12288 12289 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 12290 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 12291 break; 12292 12293 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 12294 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 12295 break; 12296 12297 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 12298 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 12299 break; 12300 12301 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 12302 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 12303 break; 12304 12305 default: 12306 wmi_err("Invalid rcpi measurement type from firmware"); 12307 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 12308 return QDF_STATUS_E_FAILURE; 12309 } 12310 12311 if (event->status) 12312 return QDF_STATUS_E_FAILURE; 12313 else 12314 return QDF_STATUS_SUCCESS; 12315 } 12316 12317 /** 12318 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 12319 * host to target defines. For legacy there is not conversion 12320 * required. Just return pdev_id as it is. 12321 * @param pdev_id: host pdev_id to be converted. 12322 * Return: target pdev_id after conversion. 12323 */ 12324 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 12325 wmi_unified_t wmi_handle, 12326 uint32_t pdev_id) 12327 { 12328 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 12329 return WMI_PDEV_ID_SOC; 12330 12331 /*No conversion required*/ 12332 return pdev_id; 12333 } 12334 12335 /** 12336 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 12337 * target to host defines. For legacy there is not conversion 12338 * required. Just return pdev_id as it is. 12339 * @param pdev_id: target pdev_id to be converted. 12340 * Return: host pdev_id after conversion. 12341 */ 12342 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 12343 wmi_unified_t wmi_handle, 12344 uint32_t pdev_id) 12345 { 12346 /*No conversion required*/ 12347 return pdev_id; 12348 } 12349 12350 /** 12351 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 12352 * host to target defines. For legacy there is not conversion 12353 * required. Just return phy_id as it is. 12354 * @param pdev_id: host phy_id to be converted. 12355 * Return: target phy_id after conversion. 12356 */ 12357 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 12358 wmi_unified_t wmi_handle, 12359 uint32_t phy_id) 12360 { 12361 /*No conversion required*/ 12362 return phy_id; 12363 } 12364 12365 /** 12366 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 12367 * target to host defines. For legacy there is not conversion 12368 * required. Just return phy_id as it is. 12369 * @param pdev_id: target phy_id to be converted. 12370 * Return: host phy_id after conversion. 12371 */ 12372 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 12373 wmi_unified_t wmi_handle, 12374 uint32_t phy_id) 12375 { 12376 /*No conversion required*/ 12377 return phy_id; 12378 } 12379 12380 /** 12381 * send_set_country_cmd_tlv() - WMI scan channel list function 12382 * @param wmi_handle : handle to WMI. 12383 * @param param : pointer to hold scan channel list parameter 12384 * 12385 * Return: 0 on success and -ve on failure. 12386 */ 12387 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 12388 struct set_country *params) 12389 { 12390 wmi_buf_t buf; 12391 QDF_STATUS qdf_status; 12392 wmi_set_current_country_cmd_fixed_param *cmd; 12393 uint16_t len = sizeof(*cmd); 12394 uint8_t pdev_id = params->pdev_id; 12395 12396 buf = wmi_buf_alloc(wmi_handle, len); 12397 if (!buf) { 12398 qdf_status = QDF_STATUS_E_NOMEM; 12399 goto end; 12400 } 12401 12402 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 12403 WMITLV_SET_HDR(&cmd->tlv_header, 12404 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 12405 WMITLV_GET_STRUCT_TLVLEN 12406 (wmi_set_current_country_cmd_fixed_param)); 12407 12408 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 12409 wmi_handle, 12410 pdev_id); 12411 wmi_debug("setting current country to %s and target pdev_id = %u", 12412 params->country, cmd->pdev_id); 12413 12414 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 12415 12416 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 12417 qdf_status = wmi_unified_cmd_send(wmi_handle, 12418 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 12419 12420 if (QDF_IS_STATUS_ERROR(qdf_status)) { 12421 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 12422 wmi_buf_free(buf); 12423 } 12424 12425 end: 12426 return qdf_status; 12427 } 12428 12429 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 12430 WMI_SET_BITS(alpha, 0, 8, val0); \ 12431 WMI_SET_BITS(alpha, 8, 8, val1); \ 12432 WMI_SET_BITS(alpha, 16, 8, val2); \ 12433 } while (0) 12434 12435 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 12436 uint8_t pdev_id, struct cc_regdmn_s *rd) 12437 { 12438 wmi_set_init_country_cmd_fixed_param *cmd; 12439 uint16_t len; 12440 wmi_buf_t buf; 12441 int ret; 12442 12443 len = sizeof(wmi_set_init_country_cmd_fixed_param); 12444 buf = wmi_buf_alloc(wmi_handle, len); 12445 if (!buf) 12446 return QDF_STATUS_E_NOMEM; 12447 12448 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 12449 WMITLV_SET_HDR(&cmd->tlv_header, 12450 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 12451 WMITLV_GET_STRUCT_TLVLEN 12452 (wmi_set_init_country_cmd_fixed_param)); 12453 12454 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12455 wmi_handle, 12456 pdev_id); 12457 12458 if (rd->flags == CC_IS_SET) { 12459 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 12460 cmd->country_code.country_id = rd->cc.country_code; 12461 } else if (rd->flags == ALPHA_IS_SET) { 12462 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 12463 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 12464 rd->cc.alpha[0], 12465 rd->cc.alpha[1], 12466 rd->cc.alpha[2]); 12467 } else if (rd->flags == REGDMN_IS_SET) { 12468 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 12469 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 12470 rd->cc.regdmn.reg_2g_5g_pair_id); 12471 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 12472 rd->cc.regdmn.sixg_superdmn_id); 12473 } 12474 12475 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 12476 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12477 WMI_SET_INIT_COUNTRY_CMDID); 12478 if (ret) { 12479 wmi_err("Failed to config wow wakeup event"); 12480 wmi_buf_free(buf); 12481 return QDF_STATUS_E_FAILURE; 12482 } 12483 12484 return QDF_STATUS_SUCCESS; 12485 } 12486 12487 /** 12488 * send_obss_detection_cfg_cmd_tlv() - send obss detection 12489 * configurations to firmware. 12490 * @wmi_handle: wmi handle 12491 * @obss_cfg_param: obss detection configurations 12492 * 12493 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 12494 * 12495 * Return: QDF_STATUS 12496 */ 12497 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 12498 struct wmi_obss_detection_cfg_param *obss_cfg_param) 12499 { 12500 wmi_buf_t buf; 12501 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 12502 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 12503 12504 buf = wmi_buf_alloc(wmi_handle, len); 12505 if (!buf) 12506 return QDF_STATUS_E_NOMEM; 12507 12508 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 12509 WMITLV_SET_HDR(&cmd->tlv_header, 12510 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 12511 WMITLV_GET_STRUCT_TLVLEN 12512 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 12513 12514 cmd->vdev_id = obss_cfg_param->vdev_id; 12515 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 12516 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 12517 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 12518 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 12519 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 12520 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 12521 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 12522 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 12523 12524 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 12525 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12526 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 12527 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 12528 wmi_buf_free(buf); 12529 return QDF_STATUS_E_FAILURE; 12530 } 12531 12532 return QDF_STATUS_SUCCESS; 12533 } 12534 12535 /** 12536 * extract_obss_detection_info_tlv() - Extract obss detection info 12537 * received from firmware. 12538 * @evt_buf: pointer to event buffer 12539 * @obss_detection: Pointer to hold obss detection info 12540 * 12541 * Return: QDF_STATUS 12542 */ 12543 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 12544 struct wmi_obss_detect_info 12545 *obss_detection) 12546 { 12547 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 12548 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 12549 12550 if (!obss_detection) { 12551 wmi_err("Invalid obss_detection event buffer"); 12552 return QDF_STATUS_E_INVAL; 12553 } 12554 12555 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 12556 if (!param_buf) { 12557 wmi_err("Invalid evt_buf"); 12558 return QDF_STATUS_E_INVAL; 12559 } 12560 12561 fix_param = param_buf->fixed_param; 12562 obss_detection->vdev_id = fix_param->vdev_id; 12563 obss_detection->matched_detection_masks = 12564 fix_param->matched_detection_masks; 12565 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 12566 &obss_detection->matched_bssid_addr[0]); 12567 switch (fix_param->reason) { 12568 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 12569 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 12570 break; 12571 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 12572 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 12573 break; 12574 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 12575 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 12576 break; 12577 default: 12578 wmi_err("Invalid reason: %d", fix_param->reason); 12579 return QDF_STATUS_E_INVAL; 12580 } 12581 12582 return QDF_STATUS_SUCCESS; 12583 } 12584 12585 /** 12586 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 12587 * @wmi_handle: wmi handle 12588 * @params: pointer to request structure 12589 * 12590 * Return: QDF_STATUS 12591 */ 12592 static QDF_STATUS 12593 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 12594 struct wmi_roam_scan_stats_req *params) 12595 { 12596 wmi_buf_t buf; 12597 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 12598 WMITLV_TAG_ID tag; 12599 uint32_t size; 12600 uint32_t len = sizeof(*cmd); 12601 12602 buf = wmi_buf_alloc(wmi_handle, len); 12603 if (!buf) 12604 return QDF_STATUS_E_FAILURE; 12605 12606 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 12607 12608 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 12609 size = WMITLV_GET_STRUCT_TLVLEN( 12610 wmi_request_roam_scan_stats_cmd_fixed_param); 12611 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 12612 12613 cmd->vdev_id = params->vdev_id; 12614 12615 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 12616 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12617 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 12618 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 12619 wmi_buf_free(buf); 12620 return QDF_STATUS_E_FAILURE; 12621 } 12622 12623 return QDF_STATUS_SUCCESS; 12624 } 12625 12626 /** 12627 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 12628 * channel list from firmware 12629 * @wmi_handle: wmi handler 12630 * @vdev_id: vdev id 12631 * 12632 * Return: QDF_STATUS 12633 */ 12634 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 12635 uint32_t vdev_id) 12636 { 12637 wmi_buf_t buf; 12638 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 12639 uint16_t len = sizeof(*cmd); 12640 int ret; 12641 12642 buf = wmi_buf_alloc(wmi_handle, len); 12643 if (!buf) { 12644 wmi_err("Failed to allocate wmi buffer"); 12645 return QDF_STATUS_E_NOMEM; 12646 } 12647 12648 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 12649 wmi_buf_data(buf); 12650 WMITLV_SET_HDR(&cmd->tlv_header, 12651 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 12652 WMITLV_GET_STRUCT_TLVLEN( 12653 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 12654 cmd->vdev_id = vdev_id; 12655 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 12656 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12657 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 12658 if (QDF_IS_STATUS_ERROR(ret)) { 12659 wmi_err("Failed to send get roam scan channels request = %d", 12660 ret); 12661 wmi_buf_free(buf); 12662 } 12663 return ret; 12664 } 12665 12666 /** 12667 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 12668 * @wmi_handle: wmi handle 12669 * @evt_buf: pointer to event buffer 12670 * @vdev_id: output pointer to hold vdev id 12671 * @res_param: output pointer to hold the allocated response 12672 * 12673 * Return: QDF_STATUS 12674 */ 12675 static QDF_STATUS 12676 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12677 uint32_t *vdev_id, 12678 struct wmi_roam_scan_stats_res **res_param) 12679 { 12680 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 12681 wmi_roam_scan_stats_event_fixed_param *fixed_param; 12682 uint32_t *client_id = NULL; 12683 wmi_roaming_timestamp *timestamp = NULL; 12684 uint32_t *num_channels = NULL; 12685 uint32_t *chan_info = NULL; 12686 wmi_mac_addr *old_bssid = NULL; 12687 uint32_t *is_roaming_success = NULL; 12688 wmi_mac_addr *new_bssid = NULL; 12689 uint32_t *num_roam_candidates = NULL; 12690 wmi_roam_scan_trigger_reason *roam_reason = NULL; 12691 wmi_mac_addr *bssid = NULL; 12692 uint32_t *score = NULL; 12693 uint32_t *channel = NULL; 12694 uint32_t *rssi = NULL; 12695 int chan_idx = 0, cand_idx = 0; 12696 uint32_t total_len; 12697 struct wmi_roam_scan_stats_res *res; 12698 uint32_t i, j; 12699 uint32_t num_scans, scan_param_size; 12700 12701 *res_param = NULL; 12702 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 12703 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 12704 if (!param_buf) { 12705 wmi_err("Invalid roam scan stats event"); 12706 return QDF_STATUS_E_INVAL; 12707 } 12708 12709 fixed_param = param_buf->fixed_param; 12710 12711 num_scans = fixed_param->num_roam_scans; 12712 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 12713 *vdev_id = fixed_param->vdev_id; 12714 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 12715 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 12716 num_scans, WMI_ROAM_SCAN_STATS_MAX); 12717 return QDF_STATUS_E_INVAL; 12718 } 12719 12720 total_len = sizeof(*res) + num_scans * scan_param_size; 12721 12722 res = qdf_mem_malloc(total_len); 12723 if (!res) 12724 return QDF_STATUS_E_NOMEM; 12725 12726 if (!num_scans) { 12727 *res_param = res; 12728 return QDF_STATUS_SUCCESS; 12729 } 12730 12731 if (param_buf->client_id && 12732 param_buf->num_client_id == num_scans) 12733 client_id = param_buf->client_id; 12734 12735 if (param_buf->timestamp && 12736 param_buf->num_timestamp == num_scans) 12737 timestamp = param_buf->timestamp; 12738 12739 if (param_buf->old_bssid && 12740 param_buf->num_old_bssid == num_scans) 12741 old_bssid = param_buf->old_bssid; 12742 12743 if (param_buf->new_bssid && 12744 param_buf->num_new_bssid == num_scans) 12745 new_bssid = param_buf->new_bssid; 12746 12747 if (param_buf->is_roaming_success && 12748 param_buf->num_is_roaming_success == num_scans) 12749 is_roaming_success = param_buf->is_roaming_success; 12750 12751 if (param_buf->roam_reason && 12752 param_buf->num_roam_reason == num_scans) 12753 roam_reason = param_buf->roam_reason; 12754 12755 if (param_buf->num_channels && 12756 param_buf->num_num_channels == num_scans) { 12757 uint32_t count, chan_info_sum = 0; 12758 12759 num_channels = param_buf->num_channels; 12760 for (count = 0; count < param_buf->num_num_channels; count++) { 12761 if (param_buf->num_channels[count] > 12762 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 12763 wmi_err_rl("%u exceeded max scan channels %u", 12764 param_buf->num_channels[count], 12765 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 12766 goto error; 12767 } 12768 chan_info_sum += param_buf->num_channels[count]; 12769 } 12770 12771 if (param_buf->chan_info && 12772 param_buf->num_chan_info == chan_info_sum) 12773 chan_info = param_buf->chan_info; 12774 } 12775 12776 if (param_buf->num_roam_candidates && 12777 param_buf->num_num_roam_candidates == num_scans) { 12778 uint32_t cnt, roam_cand_sum = 0; 12779 12780 num_roam_candidates = param_buf->num_roam_candidates; 12781 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 12782 if (param_buf->num_roam_candidates[cnt] > 12783 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 12784 wmi_err_rl("%u exceeded max scan cand %u", 12785 param_buf->num_roam_candidates[cnt], 12786 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 12787 goto error; 12788 } 12789 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 12790 } 12791 12792 if (param_buf->bssid && 12793 param_buf->num_bssid == roam_cand_sum) 12794 bssid = param_buf->bssid; 12795 12796 if (param_buf->score && 12797 param_buf->num_score == roam_cand_sum) 12798 score = param_buf->score; 12799 12800 if (param_buf->channel && 12801 param_buf->num_channel == roam_cand_sum) 12802 channel = param_buf->channel; 12803 12804 if (param_buf->rssi && 12805 param_buf->num_rssi == roam_cand_sum) 12806 rssi = param_buf->rssi; 12807 } 12808 12809 res->num_roam_scans = num_scans; 12810 for (i = 0; i < num_scans; i++) { 12811 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 12812 12813 if (timestamp) 12814 roam->time_stamp = timestamp[i].lower32bit | 12815 (timestamp[i].upper32bit << 31); 12816 12817 if (client_id) 12818 roam->client_id = client_id[i]; 12819 12820 if (num_channels) { 12821 roam->num_scan_chans = num_channels[i]; 12822 if (chan_info) { 12823 for (j = 0; j < num_channels[i]; j++) 12824 roam->scan_freqs[j] = 12825 chan_info[chan_idx++]; 12826 } 12827 } 12828 12829 if (is_roaming_success) 12830 roam->is_roam_successful = is_roaming_success[i]; 12831 12832 if (roam_reason) { 12833 roam->trigger_id = roam_reason[i].trigger_id; 12834 roam->trigger_value = roam_reason[i].trigger_value; 12835 } 12836 12837 if (num_roam_candidates) { 12838 roam->num_roam_candidates = num_roam_candidates[i]; 12839 12840 for (j = 0; j < num_roam_candidates[i]; j++) { 12841 if (score) 12842 roam->cand[j].score = score[cand_idx]; 12843 if (rssi) 12844 roam->cand[j].rssi = rssi[cand_idx]; 12845 if (channel) 12846 roam->cand[j].freq = 12847 channel[cand_idx]; 12848 12849 if (bssid) 12850 WMI_MAC_ADDR_TO_CHAR_ARRAY( 12851 &bssid[cand_idx], 12852 roam->cand[j].bssid); 12853 12854 cand_idx++; 12855 } 12856 } 12857 12858 if (old_bssid) 12859 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 12860 roam->old_bssid); 12861 12862 if (new_bssid) 12863 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 12864 roam->new_bssid); 12865 } 12866 12867 *res_param = res; 12868 12869 return QDF_STATUS_SUCCESS; 12870 error: 12871 qdf_mem_free(res); 12872 return QDF_STATUS_E_FAILURE; 12873 } 12874 12875 /** 12876 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 12877 * @wmi_handle: wmi handle 12878 * @evt_buf: pointer to event buffer 12879 * @vdev_id: output pointer to hold vdev id 12880 * @tx_status: output pointer to hold the tx_status 12881 * 12882 * Return: QDF_STATUS 12883 */ 12884 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 12885 void *evt_buf, 12886 uint32_t *vdev_id, 12887 uint32_t *tx_status) { 12888 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 12889 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 12890 12891 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 12892 if (!param_buf) { 12893 wmi_err("Invalid offload bcn tx status event buffer"); 12894 return QDF_STATUS_E_INVAL; 12895 } 12896 12897 bcn_tx_status_event = param_buf->fixed_param; 12898 *vdev_id = bcn_tx_status_event->vdev_id; 12899 *tx_status = bcn_tx_status_event->tx_status; 12900 12901 return QDF_STATUS_SUCCESS; 12902 } 12903 12904 #ifdef WLAN_SUPPORT_GREEN_AP 12905 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 12906 uint8_t *evt_buf, 12907 struct wlan_green_ap_egap_status_info *egap_status_info_params) 12908 { 12909 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 12910 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 12911 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 12912 12913 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 12914 if (!param_buf) { 12915 wmi_err("Invalid EGAP Info status event buffer"); 12916 return QDF_STATUS_E_INVAL; 12917 } 12918 12919 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 12920 param_buf->fixed_param; 12921 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 12922 param_buf->chainmask_list; 12923 12924 if (!egap_info_event || !chainmask_event) { 12925 wmi_err("Invalid EGAP Info event or chainmask event"); 12926 return QDF_STATUS_E_INVAL; 12927 } 12928 12929 egap_status_info_params->status = egap_info_event->status; 12930 egap_status_info_params->mac_id = chainmask_event->mac_id; 12931 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 12932 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 12933 12934 return QDF_STATUS_SUCCESS; 12935 } 12936 #endif 12937 12938 /* 12939 * extract_comb_phyerr_tlv() - extract comb phy error from event 12940 * @wmi_handle: wmi handle 12941 * @evt_buf: pointer to event buffer 12942 * @datalen: data length of event buffer 12943 * @buf_offset: Pointer to hold value of current event buffer offset 12944 * post extraction 12945 * @phyerr: Pointer to hold phyerr 12946 * 12947 * Return: QDF_STATUS 12948 */ 12949 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 12950 void *evt_buf, 12951 uint16_t datalen, 12952 uint16_t *buf_offset, 12953 wmi_host_phyerr_t *phyerr) 12954 { 12955 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 12956 wmi_comb_phyerr_rx_hdr *pe_hdr; 12957 12958 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 12959 if (!param_tlvs) { 12960 wmi_debug("Received null data from FW"); 12961 return QDF_STATUS_E_FAILURE; 12962 } 12963 12964 pe_hdr = param_tlvs->hdr; 12965 if (!pe_hdr) { 12966 wmi_debug("Received Data PE Header is NULL"); 12967 return QDF_STATUS_E_FAILURE; 12968 } 12969 12970 /* Ensure it's at least the size of the header */ 12971 if (datalen < sizeof(*pe_hdr)) { 12972 wmi_debug("Expected minimum size %zu, received %d", 12973 sizeof(*pe_hdr), datalen); 12974 return QDF_STATUS_E_FAILURE; 12975 } 12976 12977 phyerr->pdev_id = wmi_handle->ops-> 12978 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 12979 phyerr->tsf64 = pe_hdr->tsf_l32; 12980 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 12981 phyerr->bufp = param_tlvs->bufp; 12982 12983 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 12984 wmi_debug("Invalid buf_len %d, num_bufp %d", 12985 pe_hdr->buf_len, param_tlvs->num_bufp); 12986 return QDF_STATUS_E_FAILURE; 12987 } 12988 12989 phyerr->buf_len = pe_hdr->buf_len; 12990 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 12991 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 12992 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 12993 12994 return QDF_STATUS_SUCCESS; 12995 } 12996 12997 /** 12998 * extract_single_phyerr_tlv() - extract single phy error from event 12999 * @wmi_handle: wmi handle 13000 * @evt_buf: pointer to event buffer 13001 * @datalen: data length of event buffer 13002 * @buf_offset: Pointer to hold value of current event buffer offset 13003 * post extraction 13004 * @phyerr: Pointer to hold phyerr 13005 * 13006 * Return: QDF_STATUS 13007 */ 13008 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 13009 void *evt_buf, 13010 uint16_t datalen, 13011 uint16_t *buf_offset, 13012 wmi_host_phyerr_t *phyerr) 13013 { 13014 wmi_single_phyerr_rx_event *ev; 13015 uint16_t n = *buf_offset; 13016 uint8_t *data = (uint8_t *)evt_buf; 13017 13018 if (n < datalen) { 13019 if ((datalen - n) < sizeof(ev->hdr)) { 13020 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 13021 datalen, n, sizeof(ev->hdr)); 13022 return QDF_STATUS_E_FAILURE; 13023 } 13024 13025 /* 13026 * Obtain a pointer to the beginning of the current event. 13027 * data[0] is the beginning of the WMI payload. 13028 */ 13029 ev = (wmi_single_phyerr_rx_event *)&data[n]; 13030 13031 /* 13032 * Sanity check the buffer length of the event against 13033 * what we currently have. 13034 * 13035 * Since buf_len is 32 bits, we check if it overflows 13036 * a large 32 bit value. It's not 0x7fffffff because 13037 * we increase n by (buf_len + sizeof(hdr)), which would 13038 * in itself cause n to overflow. 13039 * 13040 * If "int" is 64 bits then this becomes a moot point. 13041 */ 13042 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 13043 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 13044 return QDF_STATUS_E_FAILURE; 13045 } 13046 13047 if ((n + ev->hdr.buf_len) > datalen) { 13048 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 13049 n, ev->hdr.buf_len, datalen); 13050 return QDF_STATUS_E_FAILURE; 13051 } 13052 13053 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 13054 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 13055 phyerr->bufp = &ev->bufp[0]; 13056 phyerr->buf_len = ev->hdr.buf_len; 13057 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 13058 13059 /* 13060 * Advance the buffer pointer to the next PHY error. 13061 * buflen is the length of this payload, so we need to 13062 * advance past the current header _AND_ the payload. 13063 */ 13064 n += sizeof(*ev) + ev->hdr.buf_len; 13065 } 13066 *buf_offset = n; 13067 13068 return QDF_STATUS_SUCCESS; 13069 } 13070 13071 /** 13072 * extract_esp_estimation_ev_param_tlv() - extract air time from event 13073 * @wmi_handle: wmi handle 13074 * @evt_buf: pointer to event buffer 13075 * @param: Pointer to hold esp event 13076 * 13077 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 13078 */ 13079 static QDF_STATUS 13080 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 13081 void *evt_buf, 13082 struct esp_estimation_event *param) 13083 { 13084 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 13085 wmi_esp_estimate_event_fixed_param *esp_event; 13086 13087 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 13088 if (!param_buf) { 13089 wmi_err("Invalid ESP Estimate Event buffer"); 13090 return QDF_STATUS_E_INVAL; 13091 } 13092 esp_event = param_buf->fixed_param; 13093 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 13094 13095 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 13096 wmi_handle, 13097 esp_event->pdev_id); 13098 13099 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 13100 return QDF_STATUS_E_FAILURE; 13101 13102 return QDF_STATUS_SUCCESS; 13103 } 13104 13105 /* 13106 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 13107 * updating bss color change within firmware when AP announces bss color change. 13108 * @wmi_handle: wmi handle 13109 * @vdev_id: vdev ID 13110 * @enable: enable bss color change within firmware 13111 * 13112 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 13113 * 13114 * Return: QDF_STATUS 13115 */ 13116 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 13117 uint32_t vdev_id, 13118 bool enable) 13119 { 13120 wmi_buf_t buf; 13121 wmi_bss_color_change_enable_fixed_param *cmd; 13122 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 13123 13124 buf = wmi_buf_alloc(wmi_handle, len); 13125 if (!buf) 13126 return QDF_STATUS_E_NOMEM; 13127 13128 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 13129 WMITLV_SET_HDR(&cmd->tlv_header, 13130 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 13131 WMITLV_GET_STRUCT_TLVLEN 13132 (wmi_bss_color_change_enable_fixed_param)); 13133 cmd->vdev_id = vdev_id; 13134 cmd->enable = enable; 13135 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 13136 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13137 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 13138 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 13139 wmi_buf_free(buf); 13140 return QDF_STATUS_E_FAILURE; 13141 } 13142 13143 return QDF_STATUS_SUCCESS; 13144 } 13145 13146 /** 13147 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 13148 * configurations to firmware. 13149 * @wmi_handle: wmi handle 13150 * @cfg_param: obss detection configurations 13151 * 13152 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 13153 * 13154 * Return: QDF_STATUS 13155 */ 13156 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 13157 wmi_unified_t wmi_handle, 13158 struct wmi_obss_color_collision_cfg_param *cfg_param) 13159 { 13160 wmi_buf_t buf; 13161 wmi_obss_color_collision_det_config_fixed_param *cmd; 13162 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 13163 13164 buf = wmi_buf_alloc(wmi_handle, len); 13165 if (!buf) 13166 return QDF_STATUS_E_NOMEM; 13167 13168 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 13169 buf); 13170 WMITLV_SET_HDR(&cmd->tlv_header, 13171 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 13172 WMITLV_GET_STRUCT_TLVLEN 13173 (wmi_obss_color_collision_det_config_fixed_param)); 13174 cmd->vdev_id = cfg_param->vdev_id; 13175 cmd->flags = cfg_param->flags; 13176 cmd->current_bss_color = cfg_param->current_bss_color; 13177 cmd->detection_period_ms = cfg_param->detection_period_ms; 13178 cmd->scan_period_ms = cfg_param->scan_period_ms; 13179 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 13180 13181 switch (cfg_param->evt_type) { 13182 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 13183 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 13184 break; 13185 case OBSS_COLOR_COLLISION_DETECTION: 13186 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 13187 break; 13188 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 13189 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 13190 break; 13191 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 13192 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 13193 break; 13194 default: 13195 wmi_err("Invalid event type: %d", cfg_param->evt_type); 13196 wmi_buf_free(buf); 13197 return QDF_STATUS_E_FAILURE; 13198 } 13199 13200 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 13201 "detection_period_ms: %d scan_period_ms: %d " 13202 "free_slot_expiry_timer_ms: %d", 13203 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 13204 cmd->detection_period_ms, cmd->scan_period_ms, 13205 cmd->free_slot_expiry_time_ms); 13206 13207 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 13208 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13209 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 13210 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 13211 cfg_param->vdev_id); 13212 wmi_buf_free(buf); 13213 return QDF_STATUS_E_FAILURE; 13214 } 13215 13216 return QDF_STATUS_SUCCESS; 13217 } 13218 13219 /** 13220 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 13221 * received from firmware. 13222 * @evt_buf: pointer to event buffer 13223 * @info: Pointer to hold bss collision info 13224 * 13225 * Return: QDF_STATUS 13226 */ 13227 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 13228 struct wmi_obss_color_collision_info *info) 13229 { 13230 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 13231 wmi_obss_color_collision_evt_fixed_param *fix_param; 13232 13233 if (!info) { 13234 wmi_err("Invalid obss color buffer"); 13235 return QDF_STATUS_E_INVAL; 13236 } 13237 13238 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 13239 evt_buf; 13240 if (!param_buf) { 13241 wmi_err("Invalid evt_buf"); 13242 return QDF_STATUS_E_INVAL; 13243 } 13244 13245 fix_param = param_buf->fixed_param; 13246 info->vdev_id = fix_param->vdev_id; 13247 info->obss_color_bitmap_bit0to31 = 13248 fix_param->bss_color_bitmap_bit0to31; 13249 info->obss_color_bitmap_bit32to63 = 13250 fix_param->bss_color_bitmap_bit32to63; 13251 13252 switch (fix_param->evt_type) { 13253 case WMI_BSS_COLOR_COLLISION_DISABLE: 13254 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 13255 break; 13256 case WMI_BSS_COLOR_COLLISION_DETECTION: 13257 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 13258 break; 13259 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 13260 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 13261 break; 13262 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 13263 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 13264 break; 13265 default: 13266 wmi_err("Invalid event type: %d, vdev_id: %d", 13267 fix_param->evt_type, fix_param->vdev_id); 13268 return QDF_STATUS_E_FAILURE; 13269 } 13270 13271 return QDF_STATUS_SUCCESS; 13272 } 13273 13274 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 13275 { 13276 struct wmi_ops *ops = wmi_handle->ops; 13277 13278 ops->send_obss_color_collision_cfg_cmd = 13279 send_obss_color_collision_cfg_cmd_tlv; 13280 ops->extract_obss_color_collision_info = 13281 extract_obss_color_collision_info_tlv; 13282 } 13283 13284 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 13285 static QDF_STATUS 13286 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 13287 struct config_fils_params *param) 13288 { 13289 wmi_buf_t buf; 13290 wmi_enable_fils_cmd_fixed_param *cmd; 13291 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 13292 13293 buf = wmi_buf_alloc(wmi_handle, len); 13294 if (!buf) 13295 return QDF_STATUS_E_NOMEM; 13296 13297 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 13298 buf); 13299 WMITLV_SET_HDR(&cmd->tlv_header, 13300 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 13301 WMITLV_GET_STRUCT_TLVLEN 13302 (wmi_enable_fils_cmd_fixed_param)); 13303 cmd->vdev_id = param->vdev_id; 13304 cmd->fd_period = param->fd_period; 13305 if (param->send_prb_rsp_frame) 13306 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 13307 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 13308 cmd->vdev_id, cmd->fd_period, cmd->flags); 13309 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 13310 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13311 WMI_ENABLE_FILS_CMDID)) { 13312 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 13313 wmi_buf_free(buf); 13314 return QDF_STATUS_E_FAILURE; 13315 } 13316 13317 return QDF_STATUS_SUCCESS; 13318 } 13319 #endif 13320 13321 #ifdef WLAN_MWS_INFO_DEBUGFS 13322 /** 13323 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 13324 * 13325 * @wmi_handle: wmi handle 13326 * @vdev_id: vdev id 13327 * @cmd_id: Coex command id 13328 * 13329 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 13330 * 13331 * Return: QDF_STATUS 13332 */ 13333 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 13334 uint32_t vdev_id, 13335 uint32_t cmd_id) 13336 { 13337 wmi_buf_t buf; 13338 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 13339 uint16_t len = sizeof(*cmd); 13340 int ret; 13341 13342 buf = wmi_buf_alloc(wmi_handle, len); 13343 if (!buf) { 13344 wmi_err("Failed to allocate wmi buffer"); 13345 return QDF_STATUS_E_NOMEM; 13346 } 13347 13348 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 13349 WMITLV_SET_HDR(&cmd->tlv_header, 13350 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 13351 WMITLV_GET_STRUCT_TLVLEN 13352 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 13353 cmd->vdev_id = vdev_id; 13354 cmd->cmd_id = cmd_id; 13355 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 13356 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13357 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 13358 if (QDF_IS_STATUS_ERROR(ret)) { 13359 wmi_err("Failed to send set param command ret = %d", ret); 13360 wmi_buf_free(buf); 13361 } 13362 return ret; 13363 } 13364 #endif 13365 13366 #ifdef WIFI_POS_CONVERGED 13367 /** 13368 * extract_oem_response_param_tlv() - Extract oem response params 13369 * @wmi_handle: wmi handle 13370 * @resp_buf: response buffer 13371 * @oem_resp_param: pointer to hold oem response params 13372 * 13373 * Return: QDF_STATUS_SUCCESS on success or proper error code. 13374 */ 13375 static QDF_STATUS 13376 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 13377 struct wmi_oem_response_param *oem_resp_param) 13378 { 13379 uint64_t temp_addr; 13380 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 13381 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 13382 13383 if (!param_buf) { 13384 wmi_err("Invalid OEM response"); 13385 return QDF_STATUS_E_INVAL; 13386 } 13387 13388 if (param_buf->num_data) { 13389 oem_resp_param->num_data1 = param_buf->num_data; 13390 oem_resp_param->data_1 = param_buf->data; 13391 } 13392 13393 if (param_buf->num_data2) { 13394 oem_resp_param->num_data2 = param_buf->num_data2; 13395 oem_resp_param->data_2 = param_buf->data2; 13396 } 13397 13398 if (param_buf->indirect_data) { 13399 oem_resp_param->indirect_data.pdev_id = 13400 param_buf->indirect_data->pdev_id; 13401 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 13402 oem_resp_param->indirect_data.addr = 13403 param_buf->indirect_data->addr_lo + 13404 ((uint64_t)temp_addr << 32); 13405 oem_resp_param->indirect_data.len = 13406 param_buf->indirect_data->len; 13407 } 13408 13409 return QDF_STATUS_SUCCESS; 13410 } 13411 #endif /* WIFI_POS_CONVERGED */ 13412 13413 /** 13414 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 13415 * @wmi_handle: wmi handle 13416 * @event_buf: pointer to event buffer 13417 * @cmd_status: status of HW mode change command 13418 * 13419 * Return QDF_STATUS_SUCCESS on success or proper error code. 13420 */ 13421 static QDF_STATUS 13422 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13423 uint32_t *cmd_status) 13424 { 13425 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 13426 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 13427 13428 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 13429 if (!param_buf) { 13430 wmi_err("Invalid mode change event buffer"); 13431 return QDF_STATUS_E_INVAL; 13432 } 13433 13434 fixed_param = param_buf->fixed_param; 13435 if (!fixed_param) { 13436 wmi_err("Invalid fixed param"); 13437 return QDF_STATUS_E_INVAL; 13438 } 13439 13440 *cmd_status = fixed_param->status; 13441 return QDF_STATUS_SUCCESS; 13442 } 13443 13444 #ifdef FEATURE_ANI_LEVEL_REQUEST 13445 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 13446 uint32_t *freqs, 13447 uint8_t num_freqs) 13448 { 13449 wmi_buf_t buf; 13450 wmi_get_channel_ani_cmd_fixed_param *cmd; 13451 QDF_STATUS ret; 13452 uint32_t len; 13453 A_UINT32 *chan_list; 13454 uint8_t i, *buf_ptr; 13455 13456 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 13457 WMI_TLV_HDR_SIZE + 13458 num_freqs * sizeof(A_UINT32); 13459 13460 buf = wmi_buf_alloc(wmi_handle, len); 13461 if (!buf) 13462 return QDF_STATUS_E_FAILURE; 13463 13464 buf_ptr = (uint8_t *)wmi_buf_data(buf); 13465 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 13466 WMITLV_SET_HDR(&cmd->tlv_header, 13467 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 13468 WMITLV_GET_STRUCT_TLVLEN( 13469 wmi_get_channel_ani_cmd_fixed_param)); 13470 13471 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 13472 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13473 (num_freqs * sizeof(A_UINT32))); 13474 13475 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 13476 for (i = 0; i < num_freqs; i++) { 13477 chan_list[i] = freqs[i]; 13478 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 13479 } 13480 13481 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13482 WMI_GET_CHANNEL_ANI_CMDID); 13483 13484 if (QDF_IS_STATUS_ERROR(ret)) { 13485 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 13486 wmi_buf_free(buf); 13487 } 13488 13489 return ret; 13490 } 13491 13492 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 13493 struct wmi_host_ani_level_event **info, 13494 uint32_t *num_freqs) 13495 { 13496 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 13497 wmi_get_channel_ani_event_fixed_param *fixed_param; 13498 wmi_channel_ani_info_tlv_param *tlv_params; 13499 uint8_t *buf_ptr, i; 13500 13501 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 13502 if (!param_buf) { 13503 wmi_err("Invalid ani level event buffer"); 13504 return QDF_STATUS_E_INVAL; 13505 } 13506 13507 fixed_param = 13508 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 13509 if (!fixed_param) { 13510 wmi_err("Invalid fixed param"); 13511 return QDF_STATUS_E_INVAL; 13512 } 13513 13514 buf_ptr = (uint8_t *)fixed_param; 13515 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 13516 buf_ptr += WMI_TLV_HDR_SIZE; 13517 13518 *num_freqs = param_buf->num_ani_info; 13519 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 13520 wmi_err("Invalid number of freqs received"); 13521 return QDF_STATUS_E_INVAL; 13522 } 13523 13524 *info = qdf_mem_malloc(*num_freqs * 13525 sizeof(struct wmi_host_ani_level_event)); 13526 if (!(*info)) 13527 return QDF_STATUS_E_NOMEM; 13528 13529 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 13530 for (i = 0; i < param_buf->num_ani_info; i++) { 13531 (*info)[i].ani_level = tlv_params->ani_level; 13532 (*info)[i].chan_freq = tlv_params->chan_freq; 13533 tlv_params++; 13534 } 13535 13536 return QDF_STATUS_SUCCESS; 13537 } 13538 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 13539 13540 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 13541 /** 13542 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 13543 * from the WMI_ROAM_STATS_EVENTID 13544 * @wmi_handle: wmi handle 13545 * @evt_buf: Pointer to the event buffer 13546 * @trig: Pointer to destination structure to fill data 13547 * @idx: TLV id 13548 */ 13549 static QDF_STATUS 13550 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13551 struct wmi_roam_trigger_info *trig, uint8_t idx) 13552 { 13553 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 13554 wmi_roam_trigger_reason *src_data = NULL; 13555 13556 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 13557 if (!param_buf || !param_buf->roam_trigger_reason) 13558 return QDF_STATUS_E_FAILURE; 13559 13560 src_data = ¶m_buf->roam_trigger_reason[idx]; 13561 13562 trig->present = true; 13563 trig->trigger_reason = src_data->trigger_reason; 13564 trig->trigger_sub_reason = src_data->trigger_sub_reason; 13565 trig->current_rssi = src_data->current_rssi; 13566 trig->timestamp = src_data->timestamp; 13567 13568 switch (trig->trigger_reason) { 13569 case WMI_ROAM_TRIGGER_REASON_PER: 13570 case WMI_ROAM_TRIGGER_REASON_BMISS: 13571 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 13572 case WMI_ROAM_TRIGGER_REASON_MAWC: 13573 case WMI_ROAM_TRIGGER_REASON_DENSE: 13574 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 13575 case WMI_ROAM_TRIGGER_REASON_IDLE: 13576 case WMI_ROAM_TRIGGER_REASON_FORCED: 13577 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 13578 return QDF_STATUS_SUCCESS; 13579 13580 case WMI_ROAM_TRIGGER_REASON_BTM: 13581 trig->btm_trig_data.btm_request_mode = 13582 src_data->btm_request_mode; 13583 trig->btm_trig_data.disassoc_timer = 13584 src_data->disassoc_imminent_timer; 13585 trig->btm_trig_data.validity_interval = 13586 src_data->validity_internal; 13587 trig->btm_trig_data.candidate_list_count = 13588 src_data->candidate_list_count; 13589 trig->btm_trig_data.btm_resp_status = 13590 src_data->btm_response_status_code; 13591 trig->btm_trig_data.btm_bss_termination_timeout = 13592 src_data->btm_bss_termination_timeout; 13593 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 13594 src_data->btm_mbo_assoc_retry_timeout; 13595 return QDF_STATUS_SUCCESS; 13596 13597 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 13598 trig->cu_trig_data.cu_load = src_data->cu_load; 13599 return QDF_STATUS_SUCCESS; 13600 13601 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 13602 trig->deauth_trig_data.type = src_data->deauth_type; 13603 trig->deauth_trig_data.reason = src_data->deauth_reason; 13604 return QDF_STATUS_SUCCESS; 13605 13606 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 13607 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 13608 trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold; 13609 return QDF_STATUS_SUCCESS; 13610 13611 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 13612 trig->wtc_btm_trig_data.roaming_mode = 13613 src_data->vendor_specific1[0]; 13614 trig->wtc_btm_trig_data.vsie_trigger_reason = 13615 src_data->vendor_specific1[1]; 13616 trig->wtc_btm_trig_data.sub_code = 13617 src_data->vendor_specific1[2]; 13618 trig->wtc_btm_trig_data.wtc_mode = 13619 src_data->vendor_specific1[3]; 13620 trig->wtc_btm_trig_data.wtc_scan_mode = 13621 src_data->vendor_specific1[4]; 13622 trig->wtc_btm_trig_data.wtc_rssi_th = 13623 src_data->vendor_specific1[5]; 13624 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 13625 src_data->vendor_specific1[6]; 13626 return QDF_STATUS_SUCCESS; 13627 default: 13628 return QDF_STATUS_SUCCESS; 13629 } 13630 13631 return QDF_STATUS_SUCCESS; 13632 } 13633 13634 /** 13635 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 13636 * from the WMI_ROAM_STATS_EVENTID 13637 * @wmi_handle: wmi handle 13638 * @evt_buf: Pointer to the event buffer 13639 * @dst: Pointer to destination structure to fill data 13640 * @ap_idx: TLV index for this roam scan 13641 * @num_cand: number of candidates list in the roam scan 13642 */ 13643 static QDF_STATUS 13644 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13645 struct wmi_roam_candidate_info *dst, 13646 uint8_t ap_idx, uint16_t num_cand) 13647 { 13648 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 13649 wmi_roam_ap_info *src = NULL; 13650 uint8_t i; 13651 13652 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 13653 if (!param_buf) { 13654 wmi_err("Param buf is NULL"); 13655 return QDF_STATUS_E_FAILURE; 13656 } 13657 13658 if (ap_idx >= param_buf->num_roam_ap_info) { 13659 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 13660 ap_idx, param_buf->num_roam_ap_info); 13661 return QDF_STATUS_E_FAILURE; 13662 } 13663 13664 src = ¶m_buf->roam_ap_info[ap_idx]; 13665 13666 for (i = 0; i < num_cand; i++) { 13667 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 13668 dst->type = src->candidate_type; 13669 dst->freq = src->channel; 13670 dst->etp = src->etp; 13671 dst->rssi = src->rssi; 13672 dst->rssi_score = src->rssi_score; 13673 dst->cu_load = src->cu_load; 13674 dst->cu_score = src->cu_score; 13675 dst->total_score = src->total_score; 13676 dst->timestamp = src->timestamp; 13677 dst->bl_reason = src->bl_reason; 13678 dst->bl_source = src->bl_source; 13679 dst->bl_timestamp = src->bl_timestamp; 13680 dst->bl_original_timeout = src->bl_original_timeout; 13681 13682 src++; 13683 dst++; 13684 } 13685 13686 return QDF_STATUS_SUCCESS; 13687 } 13688 13689 /** 13690 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 13691 * from the WMI_ROAM_STATS_EVENTID 13692 * @wmi_handle: wmi handle 13693 * @evt_buf: Pointer to the event buffer 13694 * @dst: Pointer to destination structure to fill data 13695 * @idx: TLV id 13696 * @chan_idx: Index of the channel tlv for the current roam trigger 13697 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 13698 */ 13699 static QDF_STATUS 13700 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13701 struct wmi_roam_scan_data *dst, uint8_t idx, 13702 uint8_t chan_idx, uint8_t ap_idx) 13703 { 13704 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 13705 wmi_roam_scan_info *src_data = NULL; 13706 wmi_roam_scan_channel_info *src_chan = NULL; 13707 QDF_STATUS status; 13708 uint8_t i; 13709 13710 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 13711 if (!param_buf || !param_buf->roam_scan_info || 13712 idx >= param_buf->num_roam_scan_info) 13713 return QDF_STATUS_E_FAILURE; 13714 13715 src_data = ¶m_buf->roam_scan_info[idx]; 13716 13717 dst->present = true; 13718 dst->type = src_data->roam_scan_type; 13719 dst->num_chan = src_data->roam_scan_channel_count; 13720 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 13721 13722 /* Read the channel data only for dst->type is 0 (partial scan) */ 13723 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 13724 chan_idx < param_buf->num_roam_scan_chan_info) { 13725 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 13726 dst->num_chan = MAX_ROAM_SCAN_CHAN; 13727 13728 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 13729 for (i = 0; i < dst->num_chan; i++) { 13730 dst->chan_freq[i] = src_chan->channel; 13731 src_chan++; 13732 } 13733 } 13734 13735 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 13736 return QDF_STATUS_SUCCESS; 13737 13738 dst->num_ap = src_data->roam_ap_count; 13739 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 13740 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 13741 13742 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 13743 ap_idx, dst->num_ap); 13744 if (QDF_IS_STATUS_ERROR(status)) { 13745 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 13746 return status; 13747 } 13748 13749 return QDF_STATUS_SUCCESS; 13750 } 13751 13752 /** 13753 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 13754 * from the WMI_ROAM_STATS_EVENTID 13755 * @wmi_handle: wmi handle 13756 * @evt_buf: Pointer to the event buffer 13757 * @dst: Pointer to destination structure to fill data 13758 * @idx: TLV id 13759 */ 13760 static QDF_STATUS 13761 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13762 struct wmi_roam_result *dst, uint8_t idx) 13763 { 13764 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 13765 wmi_roam_result *src_data = NULL; 13766 13767 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 13768 if (!param_buf || !param_buf->roam_result || 13769 idx >= param_buf->num_roam_result) 13770 return QDF_STATUS_E_FAILURE; 13771 13772 src_data = ¶m_buf->roam_result[idx]; 13773 13774 dst->present = true; 13775 dst->status = src_data->roam_status; 13776 dst->timestamp = src_data->timestamp; 13777 dst->fail_reason = src_data->roam_fail_reason; 13778 13779 return QDF_STATUS_SUCCESS; 13780 } 13781 13782 /** 13783 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 13784 * from the WMI_ROAM_STATS_EVENTID 13785 * @wmi_handle: wmi handle 13786 * @evt_buf: Pointer to the event buffer 13787 * @dst: Pointer to destination structure to fill data 13788 * @idx: TLV id 13789 * @rpt_idx: Neighbor report Channel index 13790 */ 13791 static QDF_STATUS 13792 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13793 struct wmi_neighbor_report_data *dst, 13794 uint8_t idx, uint8_t rpt_idx) 13795 { 13796 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 13797 wmi_roam_neighbor_report_info *src_data = NULL; 13798 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 13799 uint8_t i; 13800 13801 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 13802 if (!param_buf || !param_buf->roam_neighbor_report_info || 13803 !param_buf->num_roam_neighbor_report_info || 13804 idx >= param_buf->num_roam_neighbor_report_info) { 13805 wmi_debug("Invalid 1kv param buf"); 13806 return QDF_STATUS_E_FAILURE; 13807 } 13808 13809 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 13810 13811 dst->present = true; 13812 dst->req_type = src_data->request_type; 13813 dst->num_freq = src_data->neighbor_report_channel_count; 13814 dst->req_time = src_data->neighbor_report_request_timestamp; 13815 dst->resp_time = src_data->neighbor_report_response_timestamp; 13816 13817 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 13818 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 13819 return QDF_STATUS_SUCCESS; 13820 13821 if (!param_buf->roam_neighbor_report_chan_info) { 13822 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 13823 dst->num_freq); 13824 dst->num_freq = 0; 13825 /* return success as its optional tlv and we can print neighbor 13826 * report received info 13827 */ 13828 return QDF_STATUS_SUCCESS; 13829 } 13830 13831 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 13832 13833 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 13834 dst->num_freq = MAX_ROAM_SCAN_CHAN; 13835 13836 for (i = 0; i < dst->num_freq; i++) { 13837 dst->freq[i] = src_freq->channel; 13838 src_freq++; 13839 } 13840 13841 return QDF_STATUS_SUCCESS; 13842 } 13843 #else 13844 static inline QDF_STATUS 13845 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13846 struct wmi_roam_trigger_info *trig, uint8_t idx) 13847 { 13848 return QDF_STATUS_E_NOSUPPORT; 13849 } 13850 13851 static inline QDF_STATUS 13852 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13853 struct wmi_roam_result *dst, uint8_t idx) 13854 { 13855 return QDF_STATUS_E_NOSUPPORT; 13856 } 13857 13858 static QDF_STATUS 13859 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13860 struct wmi_neighbor_report_data *dst, 13861 uint8_t idx, uint8_t rpt_idx) 13862 { 13863 return QDF_STATUS_E_NOSUPPORT; 13864 } 13865 13866 static QDF_STATUS 13867 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13868 struct wmi_roam_scan_data *dst, uint8_t idx, 13869 uint8_t chan_idx, uint8_t ap_idx) 13870 { 13871 return QDF_STATUS_E_NOSUPPORT; 13872 } 13873 #endif 13874 13875 #ifdef WLAN_FEATURE_PKT_CAPTURE 13876 static QDF_STATUS 13877 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 13878 struct mgmt_offload_event_params *params) 13879 { 13880 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 13881 wmi_mgmt_hdr *hdr; 13882 13883 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 13884 if (!param_tlvs) 13885 return QDF_STATUS_E_INVAL; 13886 13887 hdr = param_tlvs->fixed_param; 13888 if (!hdr) 13889 return QDF_STATUS_E_INVAL; 13890 13891 if (hdr->buf_len > param_tlvs->num_bufp) 13892 return QDF_STATUS_E_INVAL; 13893 13894 params->tsf_l32 = hdr->tsf_l32; 13895 params->chan_freq = hdr->chan_freq; 13896 params->rate_kbps = hdr->rate_kbps; 13897 params->rssi = hdr->rssi; 13898 params->buf_len = hdr->buf_len; 13899 params->tx_status = hdr->tx_status; 13900 params->buf = param_tlvs->bufp; 13901 params->tx_retry_cnt = hdr->tx_retry_cnt; 13902 return QDF_STATUS_SUCCESS; 13903 } 13904 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 13905 13906 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 13907 /** 13908 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 13909 * 13910 * @wmi: wmi handle 13911 * @vdev_id: vdev id 13912 * @burst_mode: Indicates whether relation derived using FTM is needed for 13913 * each FTM frame or only aggregated result is required. 13914 * 13915 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 13916 * 13917 * Return: QDF_STATUS 13918 */ 13919 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 13920 uint32_t vdev_id, 13921 bool burst_mode) 13922 { 13923 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 13924 wmi_buf_t buf; 13925 int32_t len = sizeof(*cmd); 13926 13927 buf = wmi_buf_alloc(wmi, len); 13928 if (!buf) { 13929 wmi_err("wmi_buf_alloc failed"); 13930 return QDF_STATUS_E_NOMEM; 13931 } 13932 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 13933 WMITLV_SET_HDR(&cmd->tlv_header, 13934 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 13935 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 13936 cmd->vdev_id = vdev_id; 13937 cmd->agg_relation = burst_mode ? false : true; 13938 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 13939 wmi_err("Failed to send audio sync trigger cmd"); 13940 wmi_buf_free(buf); 13941 return QDF_STATUS_E_FAILURE; 13942 } 13943 13944 return QDF_STATUS_SUCCESS; 13945 } 13946 13947 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 13948 uint32_t vdev_id, 13949 uint64_t lpass_ts) 13950 { 13951 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 13952 wmi_buf_t buf; 13953 int32_t len = sizeof(*cmd); 13954 13955 buf = wmi_buf_alloc(wmi, len); 13956 if (!buf) { 13957 wmi_err("wmi_buf_alloc failed"); 13958 return QDF_STATUS_E_NOMEM; 13959 } 13960 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 13961 WMITLV_SET_HDR(&cmd->tlv_header, 13962 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 13963 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 13964 cmd->vdev_id = vdev_id; 13965 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 13966 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 13967 13968 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 13969 wmi_err("Failed to send audio qtime command"); 13970 wmi_buf_free(buf); 13971 return QDF_STATUS_E_FAILURE; 13972 } 13973 13974 return QDF_STATUS_SUCCESS; 13975 } 13976 13977 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 13978 wmi_unified_t wmi, void *buf, 13979 struct ftm_time_sync_start_stop_params *param) 13980 { 13981 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 13982 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 13983 13984 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 13985 if (!param_buf) { 13986 wmi_err("Invalid audio sync start stop event buffer"); 13987 return QDF_STATUS_E_FAILURE; 13988 } 13989 13990 resp_event = param_buf->fixed_param; 13991 if (!resp_event) { 13992 wmi_err("Invalid audio sync start stop fixed param buffer"); 13993 return QDF_STATUS_E_FAILURE; 13994 } 13995 13996 param->vdev_id = resp_event->vdev_id; 13997 param->timer_interval = resp_event->periodicity; 13998 param->num_reads = resp_event->reads_needed; 13999 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 14000 resp_event->qtimer_l32; 14001 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 14002 resp_event->mac_timer_l32; 14003 14004 wmi_debug("FTM time sync time_interval %d, num_reads %d", 14005 param->timer_interval, param->num_reads); 14006 14007 return QDF_STATUS_SUCCESS; 14008 } 14009 14010 static QDF_STATUS 14011 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 14012 struct ftm_time_sync_offset *param) 14013 { 14014 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 14015 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 14016 wmi_audio_sync_q_master_slave_times *q_pair; 14017 int iter; 14018 14019 param_buf = 14020 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 14021 if (!param_buf) { 14022 wmi_err("Invalid timesync ftm offset event buffer"); 14023 return QDF_STATUS_E_FAILURE; 14024 } 14025 14026 resp_event = param_buf->fixed_param; 14027 if (!resp_event) { 14028 wmi_err("Invalid timesync ftm offset fixed param buffer"); 14029 return QDF_STATUS_E_FAILURE; 14030 } 14031 14032 param->vdev_id = resp_event->vdev_id; 14033 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 14034 q_pair = param_buf->audio_sync_q_master_slave_times; 14035 if (!q_pair) { 14036 wmi_err("Invalid q_master_slave_times buffer"); 14037 return QDF_STATUS_E_FAILURE; 14038 } 14039 14040 for (iter = 0; iter < param->num_qtime; iter++) { 14041 param->pairs[iter].qtime_master = ( 14042 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 14043 q_pair[iter].qmaster_l32; 14044 param->pairs[iter].qtime_slave = ( 14045 (uint64_t)q_pair[iter].qslave_u32 << 32) | 14046 q_pair[iter].qslave_l32; 14047 } 14048 return QDF_STATUS_SUCCESS; 14049 } 14050 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 14051 14052 /** 14053 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 14054 * @wmi: wmi handle 14055 * @vdev_id: vdev id 14056 * 14057 * TSF_TSTAMP_READ_VALUE is the only operation supported 14058 * Return: QDF_STATUS_SUCCESS for success or erro code 14059 */ 14060 static QDF_STATUS 14061 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 14062 { 14063 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 14064 wmi_buf_t buf; 14065 int32_t len = sizeof(*cmd); 14066 14067 buf = wmi_buf_alloc(wmi, len); 14068 if (!buf) 14069 return QDF_STATUS_E_NOMEM; 14070 14071 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 14072 WMITLV_SET_HDR(&cmd->tlv_header, 14073 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 14074 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 14075 cmd->vdev_id = vdev_id; 14076 cmd->tsf_action = TSF_TSTAMP_READ_VALUE; 14077 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 14078 if (wmi_unified_cmd_send(wmi, buf, len, 14079 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 14080 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 14081 __func__); 14082 wmi_buf_free(buf); 14083 return QDF_STATUS_E_FAILURE; 14084 } 14085 14086 return QDF_STATUS_SUCCESS; 14087 } 14088 14089 /** 14090 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 14091 * @wmi_handle: wmi handle 14092 * @param evt_buf: pointer to event buffer 14093 * @wmi_host_tsf_event param: Pointer to struct to hold event info 14094 * 14095 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 14096 */ 14097 static QDF_STATUS 14098 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 14099 struct wmi_host_tsf_event *param) 14100 { 14101 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 14102 wmi_vdev_tsf_report_event_fixed_param *evt; 14103 14104 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 14105 if (!param_buf) { 14106 wmi_err("Invalid tsf report event buffer"); 14107 return QDF_STATUS_E_INVAL; 14108 } 14109 14110 evt = param_buf->fixed_param; 14111 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 14112 param->vdev_id = evt->vdev_id; 14113 14114 return QDF_STATUS_SUCCESS; 14115 } 14116 14117 /** 14118 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 14119 * status tlv 14120 * @wmi_handle: wmi handle 14121 * @param evt_buf: pointer to event buffer 14122 * @param param: Pointer to hold csa switch count status event param 14123 * 14124 * Return: QDF_STATUS_SUCCESS for success or error code 14125 */ 14126 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 14127 wmi_unified_t wmi_handle, 14128 void *evt_buf, 14129 struct pdev_csa_switch_count_status *param) 14130 { 14131 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 14132 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 14133 14134 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 14135 evt_buf; 14136 if (!param_buf) { 14137 wmi_err("Invalid CSA status event"); 14138 return QDF_STATUS_E_INVAL; 14139 } 14140 14141 csa_status = param_buf->fixed_param; 14142 14143 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14144 wmi_handle, 14145 csa_status->pdev_id); 14146 param->current_switch_count = csa_status->current_switch_count; 14147 param->num_vdevs = csa_status->num_vdevs; 14148 param->vdev_ids = param_buf->vdev_ids; 14149 14150 return QDF_STATUS_SUCCESS; 14151 } 14152 14153 struct wmi_ops tlv_ops = { 14154 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 14155 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 14156 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 14157 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 14158 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 14159 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 14160 .send_peer_param_cmd = send_peer_param_cmd_tlv, 14161 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 14162 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 14163 .send_peer_create_cmd = send_peer_create_cmd_tlv, 14164 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 14165 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 14166 .send_peer_rx_reorder_queue_setup_cmd = 14167 send_peer_rx_reorder_queue_setup_cmd_tlv, 14168 .send_peer_rx_reorder_queue_remove_cmd = 14169 send_peer_rx_reorder_queue_remove_cmd_tlv, 14170 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 14171 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 14172 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 14173 .send_suspend_cmd = send_suspend_cmd_tlv, 14174 .send_resume_cmd = send_resume_cmd_tlv, 14175 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 14176 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 14177 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 14178 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 14179 .send_dbglog_cmd = send_dbglog_cmd_tlv, 14180 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 14181 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 14182 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 14183 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 14184 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 14185 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 14186 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 14187 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 14188 .send_scan_start_cmd = send_scan_start_cmd_tlv, 14189 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 14190 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 14191 .send_mgmt_cmd = send_mgmt_cmd_tlv, 14192 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 14193 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 14194 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 14195 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 14196 .send_set_sta_uapsd_auto_trig_cmd = 14197 send_set_sta_uapsd_auto_trig_cmd_tlv, 14198 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 14199 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 14200 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 14201 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 14202 .send_lro_config_cmd = send_lro_config_cmd_tlv, 14203 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 14204 .send_probe_rsp_tmpl_send_cmd = 14205 send_probe_rsp_tmpl_send_cmd_tlv, 14206 .send_p2p_go_set_beacon_ie_cmd = 14207 send_p2p_go_set_beacon_ie_cmd_tlv, 14208 .send_setup_install_key_cmd = 14209 send_setup_install_key_cmd_tlv, 14210 .send_scan_probe_setoui_cmd = 14211 send_scan_probe_setoui_cmd_tlv, 14212 #ifdef IPA_OFFLOAD 14213 .send_ipa_offload_control_cmd = 14214 send_ipa_offload_control_cmd_tlv, 14215 #endif 14216 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 14217 .send_pno_start_cmd = send_pno_start_cmd_tlv, 14218 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 14219 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 14220 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 14221 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 14222 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 14223 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 14224 .send_unified_ll_stats_get_sta_cmd = 14225 send_unified_ll_stats_get_sta_cmd_tlv, 14226 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 14227 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 14228 .send_congestion_cmd = send_congestion_cmd_tlv, 14229 .send_snr_request_cmd = send_snr_request_cmd_tlv, 14230 .send_snr_cmd = send_snr_cmd_tlv, 14231 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 14232 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 14233 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 14234 #endif 14235 #ifdef WLAN_SUPPORT_GREEN_AP 14236 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 14237 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 14238 .extract_green_ap_egap_status_info = 14239 extract_green_ap_egap_status_info_tlv, 14240 #endif 14241 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 14242 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 14243 #ifdef FEATURE_OEM_DATA 14244 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 14245 #endif 14246 #ifdef WLAN_FEATURE_CIF_CFR 14247 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 14248 #endif 14249 .send_dfs_phyerr_filter_offload_en_cmd = 14250 send_dfs_phyerr_filter_offload_en_cmd_tlv, 14251 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 14252 .send_process_dhcpserver_offload_cmd = 14253 send_process_dhcpserver_offload_cmd_tlv, 14254 .send_pdev_set_regdomain_cmd = 14255 send_pdev_set_regdomain_cmd_tlv, 14256 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 14257 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 14258 .save_fw_version_cmd = save_fw_version_cmd_tlv, 14259 .check_and_update_fw_version = 14260 check_and_update_fw_version_cmd_tlv, 14261 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 14262 .send_enable_specific_fw_logs_cmd = 14263 send_enable_specific_fw_logs_cmd_tlv, 14264 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 14265 .send_unit_test_cmd = send_unit_test_cmd_tlv, 14266 #ifdef FEATURE_WLAN_APF 14267 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 14268 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 14269 .send_apf_write_work_memory_cmd = 14270 wmi_send_apf_write_work_memory_cmd_tlv, 14271 .send_apf_read_work_memory_cmd = 14272 wmi_send_apf_read_work_memory_cmd_tlv, 14273 .extract_apf_read_memory_resp_event = 14274 wmi_extract_apf_read_memory_resp_event_tlv, 14275 #endif /* FEATURE_WLAN_APF */ 14276 .init_cmd_send = init_cmd_send_tlv, 14277 .send_vdev_set_custom_aggr_size_cmd = 14278 send_vdev_set_custom_aggr_size_cmd_tlv, 14279 .send_vdev_set_qdepth_thresh_cmd = 14280 send_vdev_set_qdepth_thresh_cmd_tlv, 14281 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 14282 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 14283 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 14284 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 14285 .send_periodic_chan_stats_config_cmd = 14286 send_periodic_chan_stats_config_cmd_tlv, 14287 #ifdef WLAN_IOT_SIM_SUPPORT 14288 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 14289 #endif 14290 .send_vdev_spectral_configure_cmd = 14291 send_vdev_spectral_configure_cmd_tlv, 14292 .send_vdev_spectral_enable_cmd = 14293 send_vdev_spectral_enable_cmd_tlv, 14294 #ifdef WLAN_CONV_SPECTRAL_ENABLE 14295 .extract_pdev_sscan_fw_cmd_fixed_param = 14296 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 14297 .extract_pdev_sscan_fft_bin_index = 14298 extract_pdev_sscan_fft_bin_index_tlv, 14299 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 14300 .send_thermal_mitigation_param_cmd = 14301 send_thermal_mitigation_param_cmd_tlv, 14302 .send_process_update_edca_param_cmd = 14303 send_process_update_edca_param_cmd_tlv, 14304 .send_bss_color_change_enable_cmd = 14305 send_bss_color_change_enable_cmd_tlv, 14306 .send_coex_config_cmd = send_coex_config_cmd_tlv, 14307 .send_set_country_cmd = send_set_country_cmd_tlv, 14308 .send_addba_send_cmd = send_addba_send_cmd_tlv, 14309 .send_delba_send_cmd = send_delba_send_cmd_tlv, 14310 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 14311 .get_target_cap_from_service_ready = extract_service_ready_tlv, 14312 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 14313 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 14314 .extract_host_mem_req = extract_host_mem_req_tlv, 14315 .save_service_bitmap = save_service_bitmap_tlv, 14316 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 14317 .is_service_enabled = is_service_enabled_tlv, 14318 .save_fw_version = save_fw_version_in_service_ready_tlv, 14319 .ready_extract_init_status = ready_extract_init_status_tlv, 14320 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 14321 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 14322 .extract_ready_event_params = extract_ready_event_params_tlv, 14323 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 14324 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 14325 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 14326 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 14327 #ifdef FEATURE_WLAN_SCAN_PNO 14328 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 14329 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 14330 #endif 14331 .extract_unit_test = extract_unit_test_tlv, 14332 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 14333 .extract_bcn_stats = extract_bcn_stats_tlv, 14334 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 14335 .extract_chan_stats = extract_chan_stats_tlv, 14336 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 14337 .extract_profile_ctx = extract_profile_ctx_tlv, 14338 .extract_profile_data = extract_profile_data_tlv, 14339 .send_fw_test_cmd = send_fw_test_cmd_tlv, 14340 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 14341 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 14342 .extract_service_ready_ext = extract_service_ready_ext_tlv, 14343 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 14344 .extract_hw_mode_cap_service_ready_ext = 14345 extract_hw_mode_cap_service_ready_ext_tlv, 14346 .extract_mac_phy_cap_service_ready_ext = 14347 extract_mac_phy_cap_service_ready_ext_tlv, 14348 .extract_mac_phy_cap_service_ready_ext2 = 14349 extract_mac_phy_cap_service_ready_ext2_tlv, 14350 .extract_reg_cap_service_ready_ext = 14351 extract_reg_cap_service_ready_ext_tlv, 14352 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 14353 .extract_dbr_ring_cap_service_ready_ext = 14354 extract_dbr_ring_cap_service_ready_ext_tlv, 14355 .extract_dbr_ring_cap_service_ready_ext2 = 14356 extract_dbr_ring_cap_service_ready_ext2_tlv, 14357 .extract_scan_radio_cap_service_ready_ext2 = 14358 extract_scan_radio_cap_service_ready_ext2_tlv, 14359 .extract_sar_cap_service_ready_ext = 14360 extract_sar_cap_service_ready_ext_tlv, 14361 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 14362 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 14363 .extract_fips_event_data = extract_fips_event_data_tlv, 14364 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 14365 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 14366 #endif 14367 #ifdef WLAN_FEATURE_DISA 14368 .extract_encrypt_decrypt_resp_event = 14369 extract_encrypt_decrypt_resp_event_tlv, 14370 #endif 14371 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 14372 .extract_get_pn_data = extract_get_pn_data_tlv, 14373 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 14374 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 14375 #ifdef WLAN_FEATURE_DISA 14376 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 14377 #endif 14378 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 14379 .send_wlan_profile_hist_intvl_cmd = 14380 send_wlan_profile_hist_intvl_cmd_tlv, 14381 .is_management_record = is_management_record_tlv, 14382 .is_diag_event = is_diag_event_tlv, 14383 #ifdef WLAN_FEATURE_ACTION_OUI 14384 .send_action_oui_cmd = send_action_oui_cmd_tlv, 14385 #endif 14386 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 14387 #ifdef QCA_SUPPORT_AGILE_DFS 14388 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 14389 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 14390 #endif 14391 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 14392 .extract_reg_chan_list_update_event = 14393 extract_reg_chan_list_update_event_tlv, 14394 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 14395 .extract_num_rf_characterization_entries = 14396 extract_num_rf_characterization_entries_tlv, 14397 .extract_rf_characterization_entries = 14398 extract_rf_characterization_entries_tlv, 14399 #endif 14400 .extract_chainmask_tables = 14401 extract_chainmask_tables_tlv, 14402 .extract_thermal_stats = extract_thermal_stats_tlv, 14403 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 14404 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 14405 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 14406 #ifdef DFS_COMPONENT_ENABLE 14407 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 14408 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 14409 .extract_dfs_radar_detection_event = 14410 extract_dfs_radar_detection_event_tlv, 14411 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 14412 #endif 14413 .convert_pdev_id_host_to_target = 14414 convert_host_pdev_id_to_target_pdev_id_legacy, 14415 .convert_pdev_id_target_to_host = 14416 convert_target_pdev_id_to_host_pdev_id_legacy, 14417 14418 .convert_host_pdev_id_to_target = 14419 convert_host_pdev_id_to_target_pdev_id, 14420 .convert_target_pdev_id_to_host = 14421 convert_target_pdev_id_to_host_pdev_id, 14422 14423 .convert_phy_id_host_to_target = 14424 convert_host_phy_id_to_target_phy_id_legacy, 14425 .convert_phy_id_target_to_host = 14426 convert_target_phy_id_to_host_phy_id_legacy, 14427 14428 .convert_host_phy_id_to_target = 14429 convert_host_phy_id_to_target_phy_id, 14430 .convert_target_phy_id_to_host = 14431 convert_target_phy_id_to_host_phy_id, 14432 14433 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 14434 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 14435 .extract_reg_11d_new_country_event = 14436 extract_reg_11d_new_country_event_tlv, 14437 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 14438 .extract_reg_ch_avoid_event = 14439 extract_reg_ch_avoid_event_tlv, 14440 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 14441 .extract_obss_detection_info = extract_obss_detection_info_tlv, 14442 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 14443 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 14444 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 14445 .wmi_check_command_params = wmitlv_check_command_tlv_params, 14446 .extract_comb_phyerr = extract_comb_phyerr_tlv, 14447 .extract_single_phyerr = extract_single_phyerr_tlv, 14448 #ifdef QCA_SUPPORT_CP_STATS 14449 .extract_cca_stats = extract_cca_stats_tlv, 14450 #endif 14451 .extract_esp_estimation_ev_param = 14452 extract_esp_estimation_ev_param_tlv, 14453 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 14454 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 14455 #ifdef OBSS_PD 14456 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 14457 .send_obss_spatial_reuse_set_def_thresh = 14458 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 14459 .send_self_srg_bss_color_bitmap_set = 14460 send_self_srg_bss_color_bitmap_set_cmd_tlv, 14461 .send_self_srg_partial_bssid_bitmap_set = 14462 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 14463 .send_self_srg_obss_color_enable_bitmap = 14464 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 14465 .send_self_srg_obss_bssid_enable_bitmap = 14466 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 14467 .send_self_non_srg_obss_color_enable_bitmap = 14468 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 14469 .send_self_non_srg_obss_bssid_enable_bitmap = 14470 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 14471 #endif 14472 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 14473 .extract_ctl_failsafe_check_ev_param = 14474 extract_ctl_failsafe_check_ev_param_tlv, 14475 #ifdef WIFI_POS_CONVERGED 14476 .extract_oem_response_param = extract_oem_response_param_tlv, 14477 #endif /* WIFI_POS_CONVERGED */ 14478 #ifdef WLAN_MWS_INFO_DEBUGFS 14479 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 14480 #endif 14481 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 14482 #ifdef FEATURE_ANI_LEVEL_REQUEST 14483 .send_ani_level_cmd = send_ani_level_cmd_tlv, 14484 .extract_ani_level = extract_ani_level_tlv, 14485 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 14486 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 14487 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 14488 .extract_roam_result_stats = extract_roam_result_stats_tlv, 14489 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 14490 #ifdef WLAN_FEATURE_PKT_CAPTURE 14491 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 14492 #endif 14493 14494 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 14495 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 14496 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 14497 .extract_time_sync_ftm_start_stop_event = 14498 extract_time_sync_ftm_start_stop_event_tlv, 14499 .extract_time_sync_ftm_offset_event = 14500 extract_time_sync_ftm_offset_event_tlv, 14501 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 14502 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 14503 .send_injector_config_cmd = send_injector_config_cmd_tlv, 14504 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 14505 .extract_cp_stats_more_pending = 14506 extract_cp_stats_more_pending_tlv, 14507 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 14508 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 14509 .extract_pdev_csa_switch_count_status = 14510 extract_pdev_csa_switch_count_status_tlv, 14511 }; 14512 14513 /** 14514 * populate_tlv_event_id() - populates wmi event ids 14515 * 14516 * @param event_ids: Pointer to hold event ids 14517 * Return: None 14518 */ 14519 static void populate_tlv_events_id(uint32_t *event_ids) 14520 { 14521 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 14522 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 14523 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 14524 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 14525 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 14526 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 14527 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 14528 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 14529 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 14530 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 14531 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 14532 event_ids[wmi_service_ready_ext_event_id] = 14533 WMI_SERVICE_READY_EXT_EVENTID; 14534 event_ids[wmi_service_ready_ext2_event_id] = 14535 WMI_SERVICE_READY_EXT2_EVENTID; 14536 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 14537 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 14538 event_ids[wmi_vdev_install_key_complete_event_id] = 14539 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 14540 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 14541 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 14542 14543 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 14544 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 14545 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 14546 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 14547 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 14548 event_ids[wmi_peer_estimated_linkspeed_event_id] = 14549 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 14550 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 14551 event_ids[wmi_peer_create_conf_event_id] = 14552 WMI_PEER_CREATE_CONF_EVENTID; 14553 event_ids[wmi_peer_delete_response_event_id] = 14554 WMI_PEER_DELETE_RESP_EVENTID; 14555 event_ids[wmi_peer_delete_all_response_event_id] = 14556 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 14557 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 14558 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 14559 event_ids[wmi_tbttoffset_update_event_id] = 14560 WMI_TBTTOFFSET_UPDATE_EVENTID; 14561 event_ids[wmi_ext_tbttoffset_update_event_id] = 14562 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 14563 event_ids[wmi_offload_bcn_tx_status_event_id] = 14564 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 14565 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 14566 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 14567 event_ids[wmi_mgmt_tx_completion_event_id] = 14568 WMI_MGMT_TX_COMPLETION_EVENTID; 14569 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 14570 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 14571 event_ids[wmi_tx_delba_complete_event_id] = 14572 WMI_TX_DELBA_COMPLETE_EVENTID; 14573 event_ids[wmi_tx_addba_complete_event_id] = 14574 WMI_TX_ADDBA_COMPLETE_EVENTID; 14575 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 14576 14577 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 14578 14579 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 14580 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 14581 14582 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 14583 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 14584 14585 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 14586 14587 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 14588 event_ids[wmi_p2p_lo_stop_event_id] = 14589 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 14590 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 14591 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 14592 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 14593 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 14594 event_ids[wmi_d0_wow_disable_ack_event_id] = 14595 WMI_D0_WOW_DISABLE_ACK_EVENTID; 14596 event_ids[wmi_wow_initial_wakeup_event_id] = 14597 WMI_WOW_INITIAL_WAKEUP_EVENTID; 14598 14599 event_ids[wmi_rtt_meas_report_event_id] = 14600 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 14601 event_ids[wmi_tsf_meas_report_event_id] = 14602 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 14603 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 14604 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 14605 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 14606 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 14607 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 14608 event_ids[wmi_diag_event_id_log_supported_event_id] = 14609 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 14610 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 14611 event_ids[wmi_nlo_scan_complete_event_id] = 14612 WMI_NLO_SCAN_COMPLETE_EVENTID; 14613 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 14614 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 14615 14616 event_ids[wmi_gtk_offload_status_event_id] = 14617 WMI_GTK_OFFLOAD_STATUS_EVENTID; 14618 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 14619 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 14620 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 14621 14622 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 14623 14624 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 14625 14626 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 14627 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 14628 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 14629 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 14630 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 14631 event_ids[wmi_wlan_profile_data_event_id] = 14632 WMI_WLAN_PROFILE_DATA_EVENTID; 14633 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 14634 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 14635 event_ids[wmi_vdev_get_keepalive_event_id] = 14636 WMI_VDEV_GET_KEEPALIVE_EVENTID; 14637 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 14638 14639 event_ids[wmi_diag_container_event_id] = 14640 WMI_DIAG_DATA_CONTAINER_EVENTID; 14641 14642 event_ids[wmi_host_auto_shutdown_event_id] = 14643 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 14644 14645 event_ids[wmi_update_whal_mib_stats_event_id] = 14646 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 14647 14648 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 14649 event_ids[wmi_update_vdev_rate_stats_event_id] = 14650 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 14651 14652 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 14653 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 14654 14655 /** Set OCB Sched Response, deprecated */ 14656 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 14657 14658 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 14659 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 14660 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 14661 14662 /* GPIO Event */ 14663 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 14664 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 14665 14666 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 14667 event_ids[wmi_rfkill_state_change_event_id] = 14668 WMI_RFKILL_STATE_CHANGE_EVENTID; 14669 14670 /* TDLS Event */ 14671 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 14672 14673 event_ids[wmi_batch_scan_enabled_event_id] = 14674 WMI_BATCH_SCAN_ENABLED_EVENTID; 14675 event_ids[wmi_batch_scan_result_event_id] = 14676 WMI_BATCH_SCAN_RESULT_EVENTID; 14677 /* OEM Event */ 14678 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 14679 event_ids[wmi_oem_meas_report_event_id] = 14680 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 14681 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 14682 14683 /* NAN Event */ 14684 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 14685 14686 /* LPI Event */ 14687 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 14688 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 14689 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 14690 14691 /* ExtScan events */ 14692 event_ids[wmi_extscan_start_stop_event_id] = 14693 WMI_EXTSCAN_START_STOP_EVENTID; 14694 event_ids[wmi_extscan_operation_event_id] = 14695 WMI_EXTSCAN_OPERATION_EVENTID; 14696 event_ids[wmi_extscan_table_usage_event_id] = 14697 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 14698 event_ids[wmi_extscan_cached_results_event_id] = 14699 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 14700 event_ids[wmi_extscan_wlan_change_results_event_id] = 14701 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 14702 event_ids[wmi_extscan_hotlist_match_event_id] = 14703 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 14704 event_ids[wmi_extscan_capabilities_event_id] = 14705 WMI_EXTSCAN_CAPABILITIES_EVENTID; 14706 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 14707 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 14708 14709 /* mDNS offload events */ 14710 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 14711 14712 /* SAP Authentication offload events */ 14713 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 14714 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 14715 14716 /** Out-of-context-of-bss (OCB) events */ 14717 event_ids[wmi_ocb_set_config_resp_event_id] = 14718 WMI_OCB_SET_CONFIG_RESP_EVENTID; 14719 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 14720 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 14721 event_ids[wmi_dcc_get_stats_resp_event_id] = 14722 WMI_DCC_GET_STATS_RESP_EVENTID; 14723 event_ids[wmi_dcc_update_ndl_resp_event_id] = 14724 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 14725 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 14726 /* System-On-Chip events */ 14727 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 14728 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 14729 event_ids[wmi_soc_hw_mode_transition_event_id] = 14730 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 14731 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 14732 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 14733 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 14734 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 14735 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 14736 event_ids[wmi_vdev_ocac_complete_event_id] = 14737 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 14738 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 14739 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 14740 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 14741 event_ids[wmi_peer_sta_ps_statechg_event_id] = 14742 WMI_PEER_STA_PS_STATECHG_EVENTID; 14743 event_ids[wmi_pdev_channel_hopping_event_id] = 14744 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 14745 event_ids[wmi_offchan_data_tx_completion_event] = 14746 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 14747 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 14748 event_ids[wmi_dfs_radar_detection_event_id] = 14749 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 14750 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 14751 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 14752 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 14753 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 14754 event_ids[wmi_service_available_event_id] = 14755 WMI_SERVICE_AVAILABLE_EVENTID; 14756 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 14757 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 14758 /* NDP events */ 14759 event_ids[wmi_ndp_initiator_rsp_event_id] = 14760 WMI_NDP_INITIATOR_RSP_EVENTID; 14761 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 14762 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 14763 event_ids[wmi_ndp_responder_rsp_event_id] = 14764 WMI_NDP_RESPONDER_RSP_EVENTID; 14765 event_ids[wmi_ndp_end_indication_event_id] = 14766 WMI_NDP_END_INDICATION_EVENTID; 14767 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 14768 event_ids[wmi_ndl_schedule_update_event_id] = 14769 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 14770 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 14771 14772 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 14773 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 14774 event_ids[wmi_pdev_chip_power_stats_event_id] = 14775 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 14776 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 14777 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 14778 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 14779 event_ids[wmi_apf_capability_info_event_id] = 14780 WMI_BPF_CAPABILIY_INFO_EVENTID; 14781 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 14782 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 14783 event_ids[wmi_report_rx_aggr_failure_event_id] = 14784 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 14785 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 14786 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 14787 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 14788 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 14789 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 14790 event_ids[wmi_pdev_hw_mode_transition_event_id] = 14791 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 14792 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 14793 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 14794 event_ids[wmi_coex_bt_activity_event_id] = 14795 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 14796 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 14797 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 14798 event_ids[wmi_radio_tx_power_level_stats_event_id] = 14799 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 14800 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 14801 event_ids[wmi_dma_buf_release_event_id] = 14802 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 14803 event_ids[wmi_sap_obss_detection_report_event_id] = 14804 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 14805 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 14806 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 14807 event_ids[wmi_obss_color_collision_report_event_id] = 14808 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 14809 event_ids[wmi_pdev_div_rssi_antid_event_id] = 14810 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 14811 #ifdef WLAN_SUPPORT_TWT 14812 event_ids[wmi_twt_enable_complete_event_id] = 14813 WMI_TWT_ENABLE_COMPLETE_EVENTID; 14814 event_ids[wmi_twt_disable_complete_event_id] = 14815 WMI_TWT_DISABLE_COMPLETE_EVENTID; 14816 event_ids[wmi_twt_add_dialog_complete_event_id] = 14817 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 14818 event_ids[wmi_twt_del_dialog_complete_event_id] = 14819 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 14820 event_ids[wmi_twt_pause_dialog_complete_event_id] = 14821 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 14822 event_ids[wmi_twt_resume_dialog_complete_event_id] = 14823 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 14824 event_ids[wmi_twt_session_stats_event_id] = 14825 WMI_TWT_SESSION_STATS_EVENTID; 14826 #endif 14827 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 14828 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 14829 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 14830 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 14831 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 14832 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 14833 event_ids[wmi_pdev_interop_issues_ap_event_id] = 14834 WMI_PDEV_RAP_INFO_EVENTID; 14835 #endif 14836 #ifdef AST_HKV1_WORKAROUND 14837 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 14838 #endif 14839 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 14840 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 14841 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 14842 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 14843 event_ids[wmi_roam_blacklist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 14844 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 14845 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 14846 event_ids[wmi_pdev_cold_boot_cal_event_id] = 14847 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 14848 #ifdef WLAN_MWS_INFO_DEBUGFS 14849 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 14850 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 14851 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 14852 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 14853 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 14854 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 14855 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 14856 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 14857 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 14858 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 14859 #endif 14860 event_ids[wmi_coex_report_antenna_isolation_event_id] = 14861 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 14862 event_ids[wmi_peer_ratecode_list_event_id] = 14863 WMI_PEER_RATECODE_LIST_EVENTID; 14864 event_ids[wmi_chan_rf_characterization_info_event_id] = 14865 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 14866 event_ids[wmi_roam_auth_offload_event_id] = 14867 WMI_ROAM_PREAUTH_START_EVENTID; 14868 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 14869 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 14870 event_ids[wmi_motion_det_base_line_host_eventid] = 14871 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 14872 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 14873 event_ids[wmi_peer_tx_pn_response_event_id] = 14874 WMI_PEER_TX_PN_RESPONSE_EVENTID; 14875 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 14876 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 14877 event_ids[wmi_mgmt_offload_data_event_id] = 14878 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 14879 event_ids[wmi_nan_dmesg_event_id] = 14880 WMI_NAN_DMESG_EVENTID; 14881 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 14882 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 14883 event_ids[wmi_roam_pmkid_request_event_id] = 14884 WMI_ROAM_PMKID_REQUEST_EVENTID; 14885 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 14886 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 14887 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 14888 event_ids[wmi_wlan_time_sync_q_master_slave_offset_eventid] = 14889 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 14890 #endif 14891 event_ids[wmi_roam_scan_chan_list_id] = 14892 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 14893 event_ids[wmi_muedca_params_config_eventid] = 14894 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 14895 event_ids[wmi_pdev_sscan_fw_param_eventid] = 14896 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 14897 event_ids[wmi_roam_cap_report_event_id] = 14898 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 14899 event_ids[wmi_vdev_bcn_latency_event_id] = 14900 WMI_VDEV_BCN_LATENCY_EVENTID; 14901 event_ids[wmi_vdev_disconnect_event_id] = 14902 WMI_VDEV_DISCONNECT_EVENTID; 14903 event_ids[wmi_peer_create_conf_event_id] = 14904 WMI_PEER_CREATE_CONF_EVENTID; 14905 event_ids[wmi_pdev_cp_fwstats_eventid] = 14906 WMI_CTRL_PATH_STATS_EVENTID; 14907 } 14908 14909 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 14910 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 14911 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 14912 { 14913 wmi_service[wmi_service_get_station_in_ll_stats_req] = 14914 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 14915 } 14916 14917 #else 14918 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 14919 { 14920 } 14921 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 14922 #else 14923 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 14924 { 14925 } 14926 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 14927 14928 /** 14929 * populate_tlv_service() - populates wmi services 14930 * 14931 * @param wmi_service: Pointer to hold wmi_service 14932 * Return: None 14933 */ 14934 static void populate_tlv_service(uint32_t *wmi_service) 14935 { 14936 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 14937 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 14938 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 14939 wmi_service[wmi_service_roam_scan_offload] = 14940 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 14941 wmi_service[wmi_service_bcn_miss_offload] = 14942 WMI_SERVICE_BCN_MISS_OFFLOAD; 14943 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 14944 wmi_service[wmi_service_sta_advanced_pwrsave] = 14945 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 14946 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 14947 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 14948 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 14949 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 14950 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 14951 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 14952 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 14953 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 14954 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 14955 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 14956 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 14957 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 14958 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 14959 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 14960 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 14961 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 14962 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 14963 wmi_service[wmi_service_packet_power_save] = 14964 WMI_SERVICE_PACKET_POWER_SAVE; 14965 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 14966 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 14967 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 14968 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 14969 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 14970 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 14971 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 14972 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 14973 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 14974 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 14975 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 14976 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 14977 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 14978 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 14979 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 14980 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 14981 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 14982 wmi_service[wmi_service_mcc_bcn_interval_change] = 14983 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 14984 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 14985 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 14986 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 14987 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 14988 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 14989 wmi_service[wmi_service_lte_ant_share_support] = 14990 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 14991 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 14992 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 14993 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 14994 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 14995 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 14996 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 14997 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 14998 wmi_service[wmi_service_bcn_txrate_override] = 14999 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 15000 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 15001 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 15002 wmi_service[wmi_service_estimate_linkspeed] = 15003 WMI_SERVICE_ESTIMATE_LINKSPEED; 15004 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 15005 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 15006 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 15007 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 15008 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 15009 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 15010 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 15011 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 15012 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 15013 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 15014 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 15015 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 15016 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 15017 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 15018 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 15019 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 15020 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 15021 wmi_service[wmi_service_sap_auth_offload] = 15022 WMI_SERVICE_SAP_AUTH_OFFLOAD; 15023 wmi_service[wmi_service_dual_band_simultaneous_support] = 15024 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 15025 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 15026 wmi_service[wmi_service_ap_arpns_offload] = 15027 WMI_SERVICE_AP_ARPNS_OFFLOAD; 15028 wmi_service[wmi_service_per_band_chainmask_support] = 15029 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 15030 wmi_service[wmi_service_packet_filter_offload] = 15031 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 15032 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 15033 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 15034 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 15035 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 15036 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 15037 wmi_service[wmi_service_multiple_vdev_restart] = 15038 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 15039 wmi_service[wmi_service_smart_antenna_sw_support] = 15040 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 15041 wmi_service[wmi_service_smart_antenna_hw_support] = 15042 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 15043 15044 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 15045 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 15046 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 15047 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 15048 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 15049 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 15050 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 15051 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 15052 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 15053 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 15054 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 15055 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 15056 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 15057 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 15058 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 15059 wmi_service[wmi_service_periodic_chan_stat_support] = 15060 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 15061 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 15062 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 15063 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 15064 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 15065 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 15066 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 15067 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 15068 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 15069 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 15070 wmi_service[wmi_service_unified_wow_capability] = 15071 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 15072 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 15073 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 15074 wmi_service[wmi_service_sync_delete_cmds] = 15075 WMI_SERVICE_SYNC_DELETE_CMDS; 15076 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 15077 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 15078 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 15079 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 15080 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 15081 wmi_service[wmi_service_deprecated_replace] = 15082 WMI_SERVICE_DEPRECATED_REPLACE; 15083 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 15084 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 15085 wmi_service[wmi_service_enhanced_mcast_filter] = 15086 WMI_SERVICE_ENHANCED_MCAST_FILTER; 15087 wmi_service[wmi_service_half_rate_quarter_rate_support] = 15088 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 15089 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 15090 wmi_service[wmi_service_p2p_listen_offload_support] = 15091 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 15092 wmi_service[wmi_service_mark_first_wakeup_packet] = 15093 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 15094 wmi_service[wmi_service_multiple_mcast_filter_set] = 15095 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 15096 wmi_service[wmi_service_host_managed_rx_reorder] = 15097 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 15098 wmi_service[wmi_service_flash_rdwr_support] = 15099 WMI_SERVICE_FLASH_RDWR_SUPPORT; 15100 wmi_service[wmi_service_wlan_stats_report] = 15101 WMI_SERVICE_WLAN_STATS_REPORT; 15102 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 15103 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 15104 wmi_service[wmi_service_dfs_phyerr_offload] = 15105 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 15106 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 15107 wmi_service[wmi_service_fw_mem_dump_support] = 15108 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 15109 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 15110 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 15111 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 15112 wmi_service[wmi_service_hw_data_filtering] = 15113 WMI_SERVICE_HW_DATA_FILTERING; 15114 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 15115 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 15116 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 15117 wmi_service[wmi_service_extended_nss_support] = 15118 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 15119 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 15120 wmi_service[wmi_service_bcn_offload_start_stop_support] = 15121 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 15122 wmi_service[wmi_service_offchan_data_tid_support] = 15123 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 15124 wmi_service[wmi_service_support_dma] = 15125 WMI_SERVICE_SUPPORT_DIRECT_DMA; 15126 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 15127 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 15128 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 15129 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 15130 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 15131 wmi_service[wmi_service_11k_neighbour_report_support] = 15132 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 15133 wmi_service[wmi_service_ap_obss_detection_offload] = 15134 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 15135 wmi_service[wmi_service_bss_color_offload] = 15136 WMI_SERVICE_BSS_COLOR_OFFLOAD; 15137 wmi_service[wmi_service_gmac_offload_support] = 15138 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 15139 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 15140 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 15141 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 15142 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 15143 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 15144 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 15145 wmi_service[wmi_service_listen_interval_offload_support] = 15146 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 15147 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 15148 wmi_service[wmi_service_obss_spatial_reuse] = 15149 WMI_SERVICE_OBSS_SPATIAL_REUSE; 15150 wmi_service[wmi_service_per_vdev_chain_support] = 15151 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 15152 wmi_service[wmi_service_new_htt_msg_format] = 15153 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 15154 wmi_service[wmi_service_peer_unmap_cnf_support] = 15155 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 15156 wmi_service[wmi_service_beacon_reception_stats] = 15157 WMI_SERVICE_BEACON_RECEPTION_STATS; 15158 wmi_service[wmi_service_vdev_latency_config] = 15159 WMI_SERVICE_VDEV_LATENCY_CONFIG; 15160 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 15161 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 15162 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 15163 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 15164 wmi_service[wmi_service_nan_disable_support] = 15165 WMI_SERVICE_NAN_DISABLE_SUPPORT; 15166 wmi_service[wmi_service_sta_plus_sta_support] = 15167 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 15168 wmi_service[wmi_service_hw_db2dbm_support] = 15169 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 15170 wmi_service[wmi_service_wlm_stats_support] = 15171 WMI_SERVICE_WLM_STATS_REQUEST; 15172 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 15173 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 15174 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 15175 wmi_service[wmi_service_cfr_capture_support] = 15176 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 15177 wmi_service[wmi_service_bcast_twt_support] = 15178 WMI_SERVICE_BROADCAST_TWT; 15179 wmi_service[wmi_service_wpa3_ft_sae_support] = 15180 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 15181 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 15182 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 15183 wmi_service[wmi_service_ft_fils] = 15184 WMI_SERVICE_WPA3_FT_FILS; 15185 wmi_service[wmi_service_adaptive_11r_support] = 15186 WMI_SERVICE_ADAPTIVE_11R_ROAM; 15187 wmi_service[wmi_service_tx_compl_tsf64] = 15188 WMI_SERVICE_TX_COMPL_TSF64; 15189 wmi_service[wmi_service_data_stall_recovery_support] = 15190 WMI_SERVICE_DSM_ROAM_FILTER; 15191 wmi_service[wmi_service_vdev_delete_all_peer] = 15192 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 15193 wmi_service[wmi_service_three_way_coex_config_legacy] = 15194 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 15195 wmi_service[wmi_service_rx_fse_support] = 15196 WMI_SERVICE_RX_FSE_SUPPORT; 15197 wmi_service[wmi_service_sae_roam_support] = 15198 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 15199 wmi_service[wmi_service_owe_roam_support] = 15200 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 15201 wmi_service[wmi_service_6ghz_support] = 15202 WMI_SERVICE_6GHZ_SUPPORT; 15203 wmi_service[wmi_service_bw_165mhz_support] = 15204 WMI_SERVICE_BW_165MHZ_SUPPORT; 15205 wmi_service[wmi_service_bw_restricted_80p80_support] = 15206 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 15207 wmi_service[wmi_service_packet_capture_support] = 15208 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 15209 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 15210 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 15211 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 15212 wmi_service[wmi_service_multiple_vdev_restart_ext] = 15213 WMI_SERVICE_UNAVAILABLE; 15214 wmi_service[wmi_service_time_sync_ftm] = 15215 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 15216 wmi_service[wmi_service_nss_ratio_to_host_support] = 15217 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 15218 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 15219 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 15220 wmi_service[wmi_beacon_protection_support] = 15221 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 15222 wmi_service[wmi_service_sta_nan_ndi_four_port] = 15223 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 15224 wmi_service[wmi_service_host_scan_stop_vdev_all] = 15225 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 15226 wmi_service[wmi_support_extend_address] = 15227 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 15228 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 15229 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 15230 wmi_service[wmi_service_suiteb_roam_support] = 15231 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 15232 wmi_service[wmi_service_no_interband_mcc_support] = 15233 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 15234 wmi_service[wmi_service_dual_sta_roam_support] = 15235 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 15236 wmi_service[wmi_service_peer_create_conf] = 15237 WMI_SERVICE_PEER_CREATE_CONF; 15238 wmi_service[wmi_service_configure_roam_trigger_param_support] = 15239 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 15240 wmi_service[wmi_service_5dot9_ghz_support] = 15241 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 15242 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 15243 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 15244 wmi_service[wmi_service_cfr_capture_count_support] = 15245 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 15246 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 15247 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 15248 wmi_service[wmi_service_thermal_multi_client_support] = 15249 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 15250 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 15251 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 15252 wmi_service[wmi_service_fse_cmem_alloc_support] = 15253 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 15254 wmi_service[wmi_service_scan_conf_per_ch_support] = 15255 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 15256 wmi_service[wmi_service_csa_beacon_template] = 15257 WMI_SERVICE_CSA_BEACON_TEMPLATE; 15258 15259 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 15260 } 15261 15262 /** 15263 * wmi_ocb_ut_attach() - Attach OCB test framework 15264 * @wmi_handle: wmi handle 15265 * 15266 * Return: None 15267 */ 15268 #ifdef WLAN_OCB_UT 15269 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 15270 #else 15271 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 15272 { 15273 return; 15274 } 15275 #endif 15276 15277 /** 15278 * wmi_tlv_attach() - Attach TLV APIs 15279 * 15280 * Return: None 15281 */ 15282 void wmi_tlv_attach(wmi_unified_t wmi_handle) 15283 { 15284 wmi_handle->ops = &tlv_ops; 15285 wmi_ocb_ut_attach(wmi_handle); 15286 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 15287 #ifdef WMI_INTERFACE_EVENT_LOGGING 15288 /* Skip saving WMI_CMD_HDR and TLV HDR */ 15289 wmi_handle->soc->buf_offset_command = 8; 15290 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 15291 wmi_handle->soc->buf_offset_event = 4; 15292 #endif 15293 populate_tlv_events_id(wmi_handle->wmi_events); 15294 populate_tlv_service(wmi_handle->services); 15295 wmi_twt_attach_tlv(wmi_handle); 15296 wmi_extscan_attach_tlv(wmi_handle); 15297 wmi_smart_ant_attach_tlv(wmi_handle); 15298 wmi_dbr_attach_tlv(wmi_handle); 15299 wmi_atf_attach_tlv(wmi_handle); 15300 wmi_ap_attach_tlv(wmi_handle); 15301 wmi_bcn_attach_tlv(wmi_handle); 15302 wmi_ocb_attach_tlv(wmi_handle); 15303 wmi_nan_attach_tlv(wmi_handle); 15304 wmi_p2p_attach_tlv(wmi_handle); 15305 wmi_interop_issues_ap_attach_tlv(wmi_handle); 15306 wmi_dcs_attach_tlv(wmi_handle); 15307 wmi_roam_attach_tlv(wmi_handle); 15308 wmi_concurrency_attach_tlv(wmi_handle); 15309 wmi_pmo_attach_tlv(wmi_handle); 15310 wmi_sta_attach_tlv(wmi_handle); 15311 wmi_11ax_bss_color_attach_tlv(wmi_handle); 15312 wmi_fwol_attach_tlv(wmi_handle); 15313 wmi_vdev_attach_tlv(wmi_handle); 15314 wmi_cfr_attach_tlv(wmi_handle); 15315 wmi_cp_stats_attach_tlv(wmi_handle); 15316 wmi_gpio_attach_tlv(wmi_handle); 15317 } 15318 qdf_export_symbol(wmi_tlv_attach); 15319 15320 /** 15321 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 15322 * 15323 * Return: None 15324 */ 15325 void wmi_tlv_init(void) 15326 { 15327 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 15328 } 15329