xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_tlv.c (revision fed4bfb04901bc53e8f21d8cfd8d4a151e546d11)
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, &param->peer_he_cap_phyinfo,
2604 				sizeof(param->peer_he_cap_phyinfo));
2605 	qdf_mem_copy(&cmd->peer_ppet, &param->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 = &params->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 				&params->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(&params->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(&param->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 = &param_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(&param->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(&param->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(&param->he_ppet2G, &mac_phy_caps->he_ppet2G,
10521 				 sizeof(param->he_ppet2G));
10522 	qdf_mem_copy(&param->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 = &param_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 				    &param_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 				    &param_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 			&reg_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 = &param_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 = &param_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 = &param_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 = &param_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 = &param_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 = &param_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 = &param_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