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