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