xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_tlv.c (revision dae10a5fbc53d54c53c4ba24fa018ad8b1e7c008)
1 /*
2  * Copyright (c) 2016-2018 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 <htc_services.h>
27 #ifdef FEATURE_WLAN_APF
28 #include "wmi_unified_apf_tlv.h"
29 #endif
30 #ifdef WLAN_FEATURE_ACTION_OUI
31 #include "wmi_unified_action_oui_tlv.h"
32 #endif
33 #ifdef CONVERGED_P2P_ENABLE
34 #include "wlan_p2p_public_struct.h"
35 #endif
36 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
37 #include "wlan_pmo_hw_filter_public_struct.h"
38 #endif
39 #include <wlan_utility.h>
40 #ifdef WLAN_SUPPORT_GREEN_AP
41 #include "wlan_green_ap_api.h"
42 #endif
43 
44 #ifdef WLAN_FEATURE_NAN_CONVERGENCE
45 #include "nan_public_structs.h"
46 #endif
47 #include "wmi_unified_twt_api.h"
48 
49 #ifdef WLAN_POLICY_MGR_ENABLE
50 #include "wlan_policy_mgr_public_struct.h"
51 #endif
52 
53 #ifdef FEATURE_WLAN_TDLS
54 #include "wlan_tdls_public_structs.h"
55 #endif
56 
57 /* HTC service ids for WMI for multi-radio */
58 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC,
59 				WMI_CONTROL_SVC_WMAC1,
60 				WMI_CONTROL_SVC_WMAC2};
61 
62 /**
63  * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from
64  *           host to target defines.
65  * @param pdev_id: host pdev_id to be converted.
66  * Return: target pdev_id after conversion.
67  */
68 static uint32_t convert_host_pdev_id_to_target_pdev_id(uint32_t pdev_id)
69 {
70 	switch (pdev_id) {
71 	case WMI_HOST_PDEV_ID_SOC:
72 		return WMI_PDEV_ID_SOC;
73 	case WMI_HOST_PDEV_ID_0:
74 		return WMI_PDEV_ID_1ST;
75 	case WMI_HOST_PDEV_ID_1:
76 		return WMI_PDEV_ID_2ND;
77 	case WMI_HOST_PDEV_ID_2:
78 		return WMI_PDEV_ID_3RD;
79 	}
80 
81 	QDF_ASSERT(0);
82 
83 	return WMI_PDEV_ID_SOC;
84 }
85 
86 /**
87  * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from
88  *           target to host defines.
89  * @param pdev_id: target pdev_id to be converted.
90  * Return: host pdev_id after conversion.
91  */
92 static uint32_t convert_target_pdev_id_to_host_pdev_id(uint32_t pdev_id)
93 {
94 	switch (pdev_id) {
95 	case WMI_PDEV_ID_SOC:
96 		return WMI_HOST_PDEV_ID_SOC;
97 	case WMI_PDEV_ID_1ST:
98 		return WMI_HOST_PDEV_ID_0;
99 	case WMI_PDEV_ID_2ND:
100 		return WMI_HOST_PDEV_ID_1;
101 	case WMI_PDEV_ID_3RD:
102 		return WMI_HOST_PDEV_ID_2;
103 	}
104 
105 	QDF_ASSERT(0);
106 
107 	return WMI_HOST_PDEV_ID_SOC;
108 }
109 
110 /**
111  * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion
112  *
113  * Return None.
114  */
115 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle)
116 {
117 	wmi_handle->ops->convert_pdev_id_host_to_target =
118 		convert_host_pdev_id_to_target_pdev_id;
119 	wmi_handle->ops->convert_pdev_id_target_to_host =
120 		convert_target_pdev_id_to_host_pdev_id;
121 }
122 
123 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command
124  *                              buffer.
125  * @wmi_handle: pointer to wmi_handle
126  * @cmd: pointer target vdev create command buffer
127  * @param: pointer host params for vdev create
128  *
129  * Return: None
130  */
131 #ifdef CONFIG_MCL
132 static inline void copy_vdev_create_pdev_id(
133 		struct wmi_unified *wmi_handle,
134 		wmi_vdev_create_cmd_fixed_param * cmd,
135 		struct vdev_create_params *param)
136 {
137 	cmd->pdev_id = WMI_PDEV_ID_SOC;
138 }
139 #else
140 static inline void copy_vdev_create_pdev_id(
141 		struct wmi_unified *wmi_handle,
142 		wmi_vdev_create_cmd_fixed_param * cmd,
143 		struct vdev_create_params *param)
144 {
145 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
146 							param->pdev_id);
147 }
148 #endif
149 
150 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data)
151 {
152 	uint16_t mtrace_message_id;
153 
154 	mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) |
155 		(QDF_WMI_MTRACE_GRP_ID(message_id) <<
156 						QDF_WMI_MTRACE_CMD_NUM_BITS);
157 	qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET,
158 		   mtrace_message_id, vdev_id, data);
159 }
160 
161 qdf_export_symbol(wmi_mtrace);
162 
163 /**
164  * send_vdev_create_cmd_tlv() - send VDEV create command to fw
165  * @wmi_handle: wmi handle
166  * @param: pointer to hold vdev create parameter
167  * @macaddr: vdev mac address
168  *
169  * Return: QDF_STATUS_SUCCESS for success or error code
170  */
171 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle,
172 				 uint8_t macaddr[IEEE80211_ADDR_LEN],
173 				 struct vdev_create_params *param)
174 {
175 	wmi_vdev_create_cmd_fixed_param *cmd;
176 	wmi_buf_t buf;
177 	int32_t len = sizeof(*cmd);
178 	QDF_STATUS ret;
179 	int num_bands = 2;
180 	uint8_t *buf_ptr;
181 	wmi_vdev_txrx_streams *txrx_streams;
182 
183 	len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE);
184 	buf = wmi_buf_alloc(wmi_handle, len);
185 	if (!buf) {
186 		WMI_LOGP("%s:wmi_buf_alloc failed", __func__);
187 		return QDF_STATUS_E_NOMEM;
188 	}
189 	cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf);
190 	WMITLV_SET_HDR(&cmd->tlv_header,
191 		       WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param,
192 		       WMITLV_GET_STRUCT_TLVLEN
193 			       (wmi_vdev_create_cmd_fixed_param));
194 	cmd->vdev_id = param->if_id;
195 	cmd->vdev_type = param->type;
196 	cmd->vdev_subtype = param->subtype;
197 	cmd->flags = param->mbssid_flags;
198 	cmd->vdevid_trans = param->vdevid_trans;
199 	cmd->num_cfg_txrx_streams = num_bands;
200 	copy_vdev_create_pdev_id(wmi_handle, cmd, param);
201 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr);
202 	WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x",
203 		 __func__, param->if_id, cmd->pdev_id,
204 		 macaddr[0], macaddr[1], macaddr[2],
205 		 macaddr[3], macaddr[4], macaddr[5]);
206 	buf_ptr = (uint8_t *)cmd + sizeof(*cmd);
207 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
208 			(num_bands * sizeof(wmi_vdev_txrx_streams)));
209 	buf_ptr += WMI_TLV_HDR_SIZE;
210 
211 	WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__,
212 			param->type, param->subtype,
213 			param->nss_2g, param->nss_5g);
214 	txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr;
215 	txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G;
216 	txrx_streams->supported_tx_streams = param->nss_2g;
217 	txrx_streams->supported_rx_streams = param->nss_2g;
218 	WMITLV_SET_HDR(&txrx_streams->tlv_header,
219 		       WMITLV_TAG_STRUC_wmi_vdev_txrx_streams,
220 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams));
221 
222 	txrx_streams++;
223 	txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G;
224 	txrx_streams->supported_tx_streams = param->nss_5g;
225 	txrx_streams->supported_rx_streams = param->nss_5g;
226 	WMITLV_SET_HDR(&txrx_streams->tlv_header,
227 		       WMITLV_TAG_STRUC_wmi_vdev_txrx_streams,
228 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams));
229 	wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0);
230 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID);
231 	if (QDF_IS_STATUS_ERROR(ret)) {
232 		WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID");
233 		wmi_buf_free(buf);
234 	}
235 
236 	return ret;
237 }
238 
239 /**
240  * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw
241  * @wmi_handle: wmi handle
242  * @if_id: vdev id
243  *
244  * Return: QDF_STATUS_SUCCESS for success or error code
245  */
246 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle,
247 					  uint8_t if_id)
248 {
249 	wmi_vdev_delete_cmd_fixed_param *cmd;
250 	wmi_buf_t buf;
251 	QDF_STATUS ret;
252 
253 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
254 	if (!buf) {
255 		WMI_LOGP("%s:wmi_buf_alloc failed", __func__);
256 		return QDF_STATUS_E_NOMEM;
257 	}
258 
259 	cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf);
260 	WMITLV_SET_HDR(&cmd->tlv_header,
261 		       WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param,
262 		       WMITLV_GET_STRUCT_TLVLEN
263 			       (wmi_vdev_delete_cmd_fixed_param));
264 	cmd->vdev_id = if_id;
265 	wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0);
266 	ret = wmi_unified_cmd_send(wmi_handle, buf,
267 				   sizeof(wmi_vdev_delete_cmd_fixed_param),
268 				   WMI_VDEV_DELETE_CMDID);
269 	if (QDF_IS_STATUS_ERROR(ret)) {
270 		WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID");
271 		wmi_buf_free(buf);
272 	}
273 	WMI_LOGD("%s:vdev id = %d", __func__, if_id);
274 
275 	return ret;
276 }
277 
278 /**
279  * send_vdev_stop_cmd_tlv() - send vdev stop command to fw
280  * @wmi: wmi handle
281  * @vdev_id: vdev id
282  *
283  * Return: QDF_STATUS_SUCCESS for success or erro code
284  */
285 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi,
286 					uint8_t vdev_id)
287 {
288 	wmi_vdev_stop_cmd_fixed_param *cmd;
289 	wmi_buf_t buf;
290 	int32_t len = sizeof(*cmd);
291 
292 	buf = wmi_buf_alloc(wmi, len);
293 	if (!buf) {
294 		WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
295 		return QDF_STATUS_E_NOMEM;
296 	}
297 	cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf);
298 	WMITLV_SET_HDR(&cmd->tlv_header,
299 		       WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param,
300 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param));
301 	cmd->vdev_id = vdev_id;
302 	wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0);
303 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) {
304 		WMI_LOGP("%s: Failed to send vdev stop command", __func__);
305 		wmi_buf_free(buf);
306 		return QDF_STATUS_E_FAILURE;
307 	}
308 	WMI_LOGD("%s:vdev id = %d", __func__, vdev_id);
309 
310 	return 0;
311 }
312 
313 /**
314  * send_vdev_down_cmd_tlv() - send vdev down command to fw
315  * @wmi: wmi handle
316  * @vdev_id: vdev id
317  *
318  * Return: QDF_STATUS_SUCCESS for success or error code
319  */
320 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id)
321 {
322 	wmi_vdev_down_cmd_fixed_param *cmd;
323 	wmi_buf_t buf;
324 	int32_t len = sizeof(*cmd);
325 
326 	buf = wmi_buf_alloc(wmi, len);
327 	if (!buf) {
328 		WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
329 		return QDF_STATUS_E_NOMEM;
330 	}
331 	cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf);
332 	WMITLV_SET_HDR(&cmd->tlv_header,
333 		       WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param,
334 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param));
335 	cmd->vdev_id = vdev_id;
336 	wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0);
337 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) {
338 		WMI_LOGP("%s: Failed to send vdev down", __func__);
339 		wmi_buf_free(buf);
340 		return QDF_STATUS_E_FAILURE;
341 	}
342 	WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
343 
344 	return 0;
345 }
346 
347 #ifdef CONFIG_MCL
348 static inline void copy_channel_info(
349 		wmi_vdev_start_request_cmd_fixed_param * cmd,
350 		wmi_channel *chan,
351 		struct vdev_start_params *req)
352 {
353 	chan->mhz = req->chan_freq;
354 
355 	WMI_SET_CHANNEL_MODE(chan, req->chan_mode);
356 
357 	chan->band_center_freq1 = req->band_center_freq1;
358 	chan->band_center_freq2 = req->band_center_freq2;
359 
360 	if (req->is_half_rate)
361 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
362 	else if (req->is_quarter_rate)
363 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
364 
365 	if (req->is_dfs && req->flag_dfs) {
366 		WMI_SET_CHANNEL_FLAG(chan, req->flag_dfs);
367 		cmd->disable_hw_ack = req->dis_hw_ack;
368 	}
369 
370 	WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow);
371 	WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->max_txpow);
372 
373 }
374 #else
375 static inline void copy_channel_info(
376 		wmi_vdev_start_request_cmd_fixed_param * cmd,
377 		wmi_channel *chan,
378 		struct vdev_start_params *req)
379 {
380 	chan->mhz = req->channel.mhz;
381 
382 	WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode);
383 
384 	chan->band_center_freq1 = req->channel.cfreq1;
385 	chan->band_center_freq2 = req->channel.cfreq2;
386 	WMI_LOGI("%s: req->channel.phy_mode: %d ", req->channel.phy_mode);
387 
388 	if (req->channel.half_rate)
389 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
390 	else if (req->channel.quarter_rate)
391 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
392 
393 	WMI_LOGI("%s: req->channel.dfs_set: %d ", req->channel.dfs_set);
394 
395 	if (req->channel.dfs_set) {
396 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS);
397 		cmd->disable_hw_ack = req->disable_hw_ack;
398 	}
399 
400 	if (req->channel.dfs_set_cfreq2)
401 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2);
402 
403 	/* According to firmware both reg power and max tx power
404 	 * on set channel power is used and set it to max reg
405 	 * power from regulatory.
406 	 */
407 	WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower);
408 	WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower);
409 	WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower);
410 	WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax);
411 	WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id);
412 	WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower);
413 
414 }
415 #endif
416 /**
417  * send_vdev_start_cmd_tlv() - send vdev start request to fw
418  * @wmi_handle: wmi handle
419  * @req: vdev start params
420  *
421  * Return: QDF status
422  */
423 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle,
424 			  struct vdev_start_params *req)
425 {
426 	wmi_vdev_start_request_cmd_fixed_param *cmd;
427 	wmi_buf_t buf;
428 	wmi_channel *chan;
429 	int32_t len, ret;
430 	uint8_t *buf_ptr;
431 
432 	len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE;
433 	buf = wmi_buf_alloc(wmi_handle, len);
434 	if (!buf) {
435 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
436 		return QDF_STATUS_E_NOMEM;
437 	}
438 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
439 	cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr;
440 	chan = (wmi_channel *) (buf_ptr + sizeof(*cmd));
441 	WMITLV_SET_HDR(&cmd->tlv_header,
442 		       WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param,
443 		       WMITLV_GET_STRUCT_TLVLEN
444 			       (wmi_vdev_start_request_cmd_fixed_param));
445 	WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel,
446 		       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
447 	cmd->vdev_id = req->vdev_id;
448 
449 	/* Fill channel info */
450 	copy_channel_info(cmd, chan, req);
451 
452 	cmd->beacon_interval = req->beacon_intval;
453 	cmd->dtim_period = req->dtim_period;
454 
455 	cmd->bcn_tx_rate = req->bcn_tx_rate_code;
456 	if (req->bcn_tx_rate_code)
457 		cmd->flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT;
458 
459 	if (!req->is_restart) {
460 		cmd->beacon_interval = req->beacon_intval;
461 		cmd->dtim_period = req->dtim_period;
462 
463 		/* Copy the SSID */
464 		if (req->ssid.length) {
465 			if (req->ssid.length < sizeof(cmd->ssid.ssid))
466 				cmd->ssid.ssid_len = req->ssid.length;
467 			else
468 				cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid);
469 			qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid,
470 				     cmd->ssid.ssid_len);
471 		}
472 
473 		if (req->hidden_ssid)
474 			cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
475 
476 		if (req->pmf_enabled)
477 			cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED;
478 	}
479 
480 	cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED;
481 	cmd->num_noa_descriptors = req->num_noa_descriptors;
482 	cmd->preferred_rx_streams = req->preferred_rx_streams;
483 	cmd->preferred_tx_streams = req->preferred_tx_streams;
484 	cmd->cac_duration_ms = req->cac_duration_ms;
485 	cmd->regdomain = req->regdomain;
486 	cmd->he_ops = req->he_ops;
487 
488 	buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) +
489 			       sizeof(wmi_channel));
490 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
491 		       cmd->num_noa_descriptors *
492 		       sizeof(wmi_p2p_noa_descriptor));
493 	WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d "
494 		"beacon interval %d dtim %d center_chan %d center_freq2 %d "
495 		"reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x "
496 		"Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d"
497 		"req->dis_hw_ack: %d ", __func__, req->vdev_id,
498 		chan->mhz, req->chan_mode, chan->info,
499 		req->is_dfs, req->beacon_intval, cmd->dtim_period,
500 		chan->band_center_freq1, chan->band_center_freq2,
501 		chan->reg_info_1, chan->reg_info_2, req->max_txpow,
502 		req->preferred_tx_streams, req->preferred_rx_streams,
503 		req->ldpc_rx_enabled, req->cac_duration_ms,
504 		req->regdomain, req->he_ops,
505 		req->dis_hw_ack);
506 
507 	if (req->is_restart) {
508 		wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0);
509 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
510 					   WMI_VDEV_RESTART_REQUEST_CMDID);
511 	} else {
512 		wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0);
513 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
514 					   WMI_VDEV_START_REQUEST_CMDID);
515 	}
516 	if (ret) {
517 		WMI_LOGP("%s: Failed to send vdev start command", __func__);
518 		wmi_buf_free(buf);
519 		return QDF_STATUS_E_FAILURE;
520 	 }
521 
522 	return QDF_STATUS_SUCCESS;
523 }
524 
525 /**
526  * send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid
527  * @wmi_handle: wmi handle
528  * @restart_params: vdev restart params
529  *
530  * Return: QDF_STATUS_SUCCESS for success or error code
531  */
532 static QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle,
533 			struct hidden_ssid_vdev_restart_params *restart_params)
534 {
535 	wmi_vdev_start_request_cmd_fixed_param *cmd;
536 	wmi_buf_t buf;
537 	wmi_channel *chan;
538 	int32_t len;
539 	uint8_t *buf_ptr;
540 	QDF_STATUS ret = 0;
541 
542 	len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE;
543 	buf = wmi_buf_alloc(wmi_handle, len);
544 	if (!buf) {
545 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
546 		return QDF_STATUS_E_NOMEM;
547 	}
548 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
549 	cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr;
550 	chan = (wmi_channel *) (buf_ptr + sizeof(*cmd));
551 
552 	WMITLV_SET_HDR(&cmd->tlv_header,
553 		       WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param,
554 		       WMITLV_GET_STRUCT_TLVLEN
555 			       (wmi_vdev_start_request_cmd_fixed_param));
556 
557 	WMITLV_SET_HDR(&chan->tlv_header,
558 		       WMITLV_TAG_STRUC_wmi_channel,
559 		       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
560 
561 	cmd->vdev_id = restart_params->session_id;
562 	cmd->ssid.ssid_len = restart_params->ssid_len;
563 	qdf_mem_copy(cmd->ssid.ssid,
564 		     restart_params->ssid,
565 		     cmd->ssid.ssid_len);
566 	cmd->flags = restart_params->flags;
567 	cmd->requestor_id = restart_params->requestor_id;
568 	cmd->disable_hw_ack = restart_params->disable_hw_ack;
569 
570 	chan->mhz = restart_params->mhz;
571 	chan->band_center_freq1 =
572 			restart_params->band_center_freq1;
573 	chan->band_center_freq2 =
574 			restart_params->band_center_freq2;
575 	chan->info = restart_params->info;
576 	chan->reg_info_1 = restart_params->reg_info_1;
577 	chan->reg_info_2 = restart_params->reg_info_2;
578 
579 	cmd->num_noa_descriptors = 0;
580 	buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) +
581 			       sizeof(wmi_channel));
582 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
583 		       cmd->num_noa_descriptors *
584 		       sizeof(wmi_p2p_noa_descriptor));
585 
586 	wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0);
587 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
588 				   WMI_VDEV_RESTART_REQUEST_CMDID);
589 	if (QDF_IS_STATUS_ERROR(ret)) {
590 		wmi_buf_free(buf);
591 		return QDF_STATUS_E_FAILURE;
592 	}
593 	return QDF_STATUS_SUCCESS;
594 }
595 
596 
597 /**
598  * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw
599  * @wmi: wmi handle
600  * @peer_addr: peer mac address
601  * @param: pointer to hold peer flush tid parameter
602  *
603  * Return: 0 for success or error code
604  */
605 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi,
606 					 uint8_t peer_addr[IEEE80211_ADDR_LEN],
607 					 struct peer_flush_params *param)
608 {
609 	wmi_peer_flush_tids_cmd_fixed_param *cmd;
610 	wmi_buf_t buf;
611 	int32_t len = sizeof(*cmd);
612 
613 	buf = wmi_buf_alloc(wmi, len);
614 	if (!buf) {
615 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
616 		return QDF_STATUS_E_NOMEM;
617 	}
618 	cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf);
619 	WMITLV_SET_HDR(&cmd->tlv_header,
620 		       WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param,
621 		       WMITLV_GET_STRUCT_TLVLEN
622 			       (wmi_peer_flush_tids_cmd_fixed_param));
623 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
624 	cmd->peer_tid_bitmap = param->peer_tid_bitmap;
625 	cmd->vdev_id = param->vdev_id;
626 	WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__,
627 				peer_addr, param->vdev_id,
628 				param->peer_tid_bitmap);
629 	wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0);
630 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) {
631 		WMI_LOGP("%s: Failed to send flush tid command", __func__);
632 		wmi_buf_free(buf);
633 		return QDF_STATUS_E_FAILURE;
634 	}
635 
636 	return 0;
637 }
638 
639 /**
640  * send_peer_delete_cmd_tlv() - send PEER delete command to fw
641  * @wmi: wmi handle
642  * @peer_addr: peer mac addr
643  * @vdev_id: vdev id
644  *
645  * Return: QDF_STATUS_SUCCESS for success or error code
646  */
647 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi,
648 				 uint8_t peer_addr[IEEE80211_ADDR_LEN],
649 				 uint8_t vdev_id)
650 {
651 	wmi_peer_delete_cmd_fixed_param *cmd;
652 	wmi_buf_t buf;
653 	int32_t len = sizeof(*cmd);
654 	buf = wmi_buf_alloc(wmi, len);
655 	if (!buf) {
656 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
657 		return QDF_STATUS_E_NOMEM;
658 	}
659 	cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf);
660 	WMITLV_SET_HDR(&cmd->tlv_header,
661 		       WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param,
662 		       WMITLV_GET_STRUCT_TLVLEN
663 			       (wmi_peer_delete_cmd_fixed_param));
664 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
665 	cmd->vdev_id = vdev_id;
666 
667 	WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id);
668 	wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0);
669 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) {
670 		WMI_LOGP("%s: Failed to send peer delete command", __func__);
671 		wmi_buf_free(buf);
672 		return QDF_STATUS_E_FAILURE;
673 	}
674 
675 	return 0;
676 }
677 
678 /**
679  * convert_host_peer_id_to_target_id_tlv - convert host peer param_id
680  * to target id.
681  * @targ_paramid: Target parameter id to hold the result.
682  * @peer_param_id: host param id.
683  *
684  * Return: QDF_STATUS_SUCCESS for success
685  *         QDF_STATUS_E_NOSUPPORT when the param_id in not supported in tareget
686  */
687 #ifdef CONFIG_MCL
688 static QDF_STATUS convert_host_peer_id_to_target_id_tlv(
689 		uint32_t *targ_paramid,
690 		uint32_t peer_param_id)
691 {
692 	*targ_paramid = peer_param_id;
693 	return QDF_STATUS_SUCCESS;
694 }
695 
696 /**
697  * crash_on_send_peer_rx_reorder_queue_remove_cmd() - crash on reorder queue cmd
698  *
699  * On MCL side, we are suspecting this cmd to trigger drop of ARP
700  * response frames from REO by the FW. This function causes a crash if this
701  * command is sent out by the host, so we can track this issue. Ideally no one
702  * should be calling this API from the MCL side
703  *
704  * Return: None
705  */
706 static void crash_on_send_peer_rx_reorder_queue_remove_cmd(void)
707 {
708 	QDF_BUG(0);
709 }
710 #else
711 static QDF_STATUS convert_host_peer_id_to_target_id_tlv(
712 		uint32_t *targ_paramid,
713 		uint32_t peer_param_id)
714 {
715 	switch (peer_param_id) {
716 	case WMI_HOST_PEER_MIMO_PS_STATE:
717 		*targ_paramid = WMI_PEER_MIMO_PS_STATE;
718 		break;
719 	case WMI_HOST_PEER_AMPDU:
720 		*targ_paramid = WMI_PEER_AMPDU;
721 		break;
722 	case WMI_HOST_PEER_AUTHORIZE:
723 		*targ_paramid = WMI_PEER_AUTHORIZE;
724 		break;
725 	case WMI_HOST_PEER_CHWIDTH:
726 		*targ_paramid = WMI_PEER_CHWIDTH;
727 		break;
728 	case WMI_HOST_PEER_NSS:
729 		*targ_paramid = WMI_PEER_NSS;
730 		break;
731 	case WMI_HOST_PEER_USE_4ADDR:
732 		*targ_paramid = WMI_PEER_USE_4ADDR;
733 		break;
734 	case WMI_HOST_PEER_MEMBERSHIP:
735 		*targ_paramid = WMI_PEER_MEMBERSHIP;
736 		break;
737 	case WMI_HOST_PEER_USERPOS:
738 		*targ_paramid = WMI_PEER_USERPOS;
739 		break;
740 	case WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED:
741 		*targ_paramid = WMI_PEER_CRIT_PROTO_HINT_ENABLED;
742 		break;
743 	case WMI_HOST_PEER_TX_FAIL_CNT_THR:
744 		*targ_paramid = WMI_PEER_TX_FAIL_CNT_THR;
745 		break;
746 	case WMI_HOST_PEER_SET_HW_RETRY_CTS2S:
747 		*targ_paramid = WMI_PEER_SET_HW_RETRY_CTS2S;
748 		break;
749 	case WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH:
750 		*targ_paramid = WMI_PEER_IBSS_ATIM_WINDOW_LENGTH;
751 		break;
752 	case WMI_HOST_PEER_PHYMODE:
753 		*targ_paramid = WMI_PEER_PHYMODE;
754 		break;
755 	case WMI_HOST_PEER_USE_FIXED_PWR:
756 		*targ_paramid = WMI_PEER_USE_FIXED_PWR;
757 		break;
758 	case WMI_HOST_PEER_PARAM_FIXED_RATE:
759 		*targ_paramid = WMI_PEER_PARAM_FIXED_RATE;
760 		break;
761 	case WMI_HOST_PEER_SET_MU_WHITELIST:
762 		*targ_paramid = WMI_PEER_SET_MU_WHITELIST;
763 		break;
764 	case WMI_HOST_PEER_SET_MAC_TX_RATE:
765 		*targ_paramid = WMI_PEER_SET_MAX_TX_RATE;
766 		break;
767 	case WMI_HOST_PEER_SET_MIN_TX_RATE:
768 		*targ_paramid = WMI_PEER_SET_MIN_TX_RATE;
769 		break;
770 	case WMI_HOST_PEER_SET_DEFAULT_ROUTING:
771 		*targ_paramid = WMI_PEER_SET_DEFAULT_ROUTING;
772 		break;
773 	case WMI_HOST_PEER_NSS_VHT160:
774 		*targ_paramid = WMI_PEER_NSS_VHT160;
775 		break;
776 	case WMI_HOST_PEER_NSS_VHT80_80:
777 		*targ_paramid = WMI_PEER_NSS_VHT80_80;
778 		break;
779 	case WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL:
780 		*targ_paramid = WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL;
781 		break;
782 	case WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL:
783 		*targ_paramid = WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL;
784 		break;
785 	case WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE:
786 		*targ_paramid = WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE;
787 		break;
788 	case WMI_HOST_PEER_PARAM_MU_ENABLE:
789 		*targ_paramid = WMI_PEER_PARAM_MU_ENABLE;
790 		break;
791 	case WMI_HOST_PEER_PARAM_OFDMA_ENABLE:
792 		*targ_paramid = WMI_PEER_PARAM_OFDMA_ENABLE;
793 		break;
794 	default:
795 		return QDF_STATUS_E_NOSUPPORT;
796 	}
797 
798 	return QDF_STATUS_SUCCESS;
799 }
800 
801 static void crash_on_send_peer_rx_reorder_queue_remove_cmd(void)
802 {
803 	/* No-OP */
804 }
805 
806 #endif
807 /**
808  * send_peer_param_cmd_tlv() - set peer parameter in fw
809  * @wmi: wmi handle
810  * @peer_addr: peer mac address
811  * @param    : pointer to hold peer set parameter
812  *
813  * Return: QDF_STATUS_SUCCESS for success or error code
814  */
815 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi,
816 				uint8_t peer_addr[IEEE80211_ADDR_LEN],
817 				struct peer_set_params *param)
818 {
819 	wmi_peer_set_param_cmd_fixed_param *cmd;
820 	wmi_buf_t buf;
821 	int32_t err;
822 	uint32_t param_id;
823 
824 	if (convert_host_peer_id_to_target_id_tlv(&param_id,
825 				param->param_id) != QDF_STATUS_SUCCESS)
826 		return QDF_STATUS_E_NOSUPPORT;
827 
828 	buf = wmi_buf_alloc(wmi, sizeof(*cmd));
829 	if (!buf) {
830 		WMI_LOGE("Failed to allocate buffer to send set_param cmd");
831 		return QDF_STATUS_E_NOMEM;
832 	}
833 	cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf);
834 	WMITLV_SET_HDR(&cmd->tlv_header,
835 		       WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
836 		       WMITLV_GET_STRUCT_TLVLEN
837 				(wmi_peer_set_param_cmd_fixed_param));
838 	cmd->vdev_id = param->vdev_id;
839 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
840 	cmd->param_id = param_id;
841 	cmd->param_value = param->param_value;
842 	wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0);
843 	err = wmi_unified_cmd_send(wmi, buf,
844 				   sizeof(wmi_peer_set_param_cmd_fixed_param),
845 				   WMI_PEER_SET_PARAM_CMDID);
846 	if (err) {
847 		WMI_LOGE("Failed to send set_param cmd");
848 		wmi_buf_free(buf);
849 		return QDF_STATUS_E_FAILURE;
850 	}
851 
852 	return 0;
853 }
854 
855 /**
856  * send_vdev_up_cmd_tlv() - send vdev up command in fw
857  * @wmi: wmi handle
858  * @bssid: bssid
859  * @vdev_up_params: pointer to hold vdev up parameter
860  *
861  * Return: QDF_STATUS_SUCCESS for success or error code
862  */
863 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi,
864 			     uint8_t bssid[IEEE80211_ADDR_LEN],
865 				 struct vdev_up_params *params)
866 {
867 	wmi_vdev_up_cmd_fixed_param *cmd;
868 	wmi_buf_t buf;
869 	int32_t len = sizeof(*cmd);
870 
871 	WMI_LOGD("%s: VDEV_UP", __func__);
872 	WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__,
873 		 params->vdev_id, params->assoc_id, bssid);
874 	buf = wmi_buf_alloc(wmi, len);
875 	if (!buf) {
876 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
877 		return QDF_STATUS_E_NOMEM;
878 	}
879 	cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf);
880 	WMITLV_SET_HDR(&cmd->tlv_header,
881 		       WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param,
882 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param));
883 	cmd->vdev_id = params->vdev_id;
884 	cmd->vdev_assoc_id = params->assoc_id;
885 	cmd->profile_idx = params->profile_idx;
886 	cmd->profile_num = params->profile_num;
887 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid);
888 	WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid);
889 	wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0);
890 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) {
891 		WMI_LOGP("%s: Failed to send vdev up command", __func__);
892 		wmi_buf_free(buf);
893 		return QDF_STATUS_E_FAILURE;
894 	}
895 
896 	return 0;
897 }
898 
899 /**
900  * send_peer_create_cmd_tlv() - send peer create command to fw
901  * @wmi: wmi handle
902  * @peer_addr: peer mac address
903  * @peer_type: peer type
904  * @vdev_id: vdev id
905  *
906  * Return: QDF_STATUS_SUCCESS for success or error code
907  */
908 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi,
909 					struct peer_create_params *param)
910 {
911 	wmi_peer_create_cmd_fixed_param *cmd;
912 	wmi_buf_t buf;
913 	int32_t len = sizeof(*cmd);
914 
915 	buf = wmi_buf_alloc(wmi, len);
916 	if (!buf) {
917 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
918 		return QDF_STATUS_E_NOMEM;
919 	}
920 	cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf);
921 	WMITLV_SET_HDR(&cmd->tlv_header,
922 		       WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param,
923 		       WMITLV_GET_STRUCT_TLVLEN
924 			       (wmi_peer_create_cmd_fixed_param));
925 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
926 	cmd->peer_type = param->peer_type;
927 	cmd->vdev_id = param->vdev_id;
928 
929 	wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0);
930 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) {
931 		WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__);
932 		wmi_buf_free(buf);
933 		return QDF_STATUS_E_FAILURE;
934 	}
935 	WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr,
936 			param->vdev_id);
937 
938 	return 0;
939 }
940 
941 /**
942  * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup
943  * 	command to fw
944  * @wmi: wmi handle
945  * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters
946  *
947  * Return: 0 for success or error code
948  */
949 static
950 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi,
951 		struct rx_reorder_queue_setup_params *param)
952 {
953 	wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd;
954 	wmi_buf_t buf;
955 	int32_t len = sizeof(*cmd);
956 
957 	buf = wmi_buf_alloc(wmi, len);
958 	if (!buf) {
959 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
960 		return QDF_STATUS_E_NOMEM;
961 	}
962 	cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf);
963 	WMITLV_SET_HDR(&cmd->tlv_header,
964 		WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param,
965 		WMITLV_GET_STRUCT_TLVLEN
966 			(wmi_peer_reorder_queue_setup_cmd_fixed_param));
967 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr);
968 	cmd->vdev_id = param->vdev_id;
969 	cmd->tid = param->tid;
970 	cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo;
971 	cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi;
972 	cmd->queue_no = param->queue_no;
973 	cmd->ba_window_size_valid = param->ba_window_size_valid;
974 	cmd->ba_window_size = param->ba_window_size;
975 
976 
977 	wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0);
978 	if (wmi_unified_cmd_send(wmi, buf, len,
979 			WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) {
980 		WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID",
981 			__func__);
982 		wmi_buf_free(buf);
983 		return QDF_STATUS_E_FAILURE;
984 	}
985 	WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d\n", __func__,
986 		param->peer_macaddr, param->vdev_id, param->tid);
987 
988 	return QDF_STATUS_SUCCESS;
989 }
990 
991 /**
992  * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove
993  * 	command to fw
994  * @wmi: wmi handle
995  * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters
996  *
997  * Return: 0 for success or error code
998  */
999 static
1000 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi,
1001 		struct rx_reorder_queue_remove_params *param)
1002 {
1003 	wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd;
1004 	wmi_buf_t buf;
1005 	int32_t len = sizeof(*cmd);
1006 
1007 	crash_on_send_peer_rx_reorder_queue_remove_cmd();
1008 
1009 	buf = wmi_buf_alloc(wmi, len);
1010 	if (!buf) {
1011 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
1012 		return QDF_STATUS_E_NOMEM;
1013 	}
1014 	cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *)
1015 			wmi_buf_data(buf);
1016 	WMITLV_SET_HDR(&cmd->tlv_header,
1017 		WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param,
1018 		WMITLV_GET_STRUCT_TLVLEN
1019 			(wmi_peer_reorder_queue_remove_cmd_fixed_param));
1020 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr);
1021 	cmd->vdev_id = param->vdev_id;
1022 	cmd->tid_mask = param->peer_tid_bitmap;
1023 
1024 	wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0);
1025 	if (wmi_unified_cmd_send(wmi, buf, len,
1026 			WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) {
1027 		WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID",
1028 			__func__);
1029 		wmi_buf_free(buf);
1030 		return QDF_STATUS_E_FAILURE;
1031 	}
1032 	WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__,
1033 		param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap);
1034 
1035 	return QDF_STATUS_SUCCESS;
1036 }
1037 
1038 /**
1039  * send_peer_add_wds_entry_cmd_tlv() - send peer add command to fw
1040  * @wmi_handle: wmi handle
1041  * @param: pointer holding peer details
1042  *
1043  * Return: 0 for success or error code
1044  */
1045 static QDF_STATUS send_peer_add_wds_entry_cmd_tlv(wmi_unified_t wmi_handle,
1046 					struct peer_add_wds_entry_params *param)
1047 {
1048 	wmi_peer_add_wds_entry_cmd_fixed_param *cmd;
1049 	wmi_buf_t buf;
1050 	int len = sizeof(*cmd);
1051 
1052 	buf = wmi_buf_alloc(wmi_handle, len);
1053 	if (!buf) {
1054 		qdf_print("%s: wmi_buf_alloc failed", __func__);
1055 		return QDF_STATUS_E_FAILURE;
1056 	}
1057 	cmd = (wmi_peer_add_wds_entry_cmd_fixed_param *) wmi_buf_data(buf);
1058 	WMITLV_SET_HDR(&cmd->tlv_header,
1059 			WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param,
1060 			WMITLV_GET_STRUCT_TLVLEN
1061 				(wmi_peer_add_wds_entry_cmd_fixed_param));
1062 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr);
1063 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
1064 	cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0;
1065 	cmd->vdev_id = param->vdev_id;
1066 
1067 	wmi_mtrace(WMI_PEER_ADD_WDS_ENTRY_CMDID, cmd->vdev_id, 0);
1068 	return wmi_unified_cmd_send(wmi_handle, buf, len,
1069 			WMI_PEER_ADD_WDS_ENTRY_CMDID);
1070 }
1071 
1072 /**
1073  * send_peer_del_wds_entry_cmd_tlv() - send peer delete command to fw
1074  * @wmi_handle: wmi handle
1075  * @param: pointer holding peer details
1076  *
1077  * Return: 0 for success or error code
1078  */
1079 static QDF_STATUS send_peer_del_wds_entry_cmd_tlv(wmi_unified_t wmi_handle,
1080 					struct peer_del_wds_entry_params *param)
1081 {
1082 	wmi_peer_remove_wds_entry_cmd_fixed_param *cmd;
1083 	wmi_buf_t buf;
1084 	int len = sizeof(*cmd);
1085 
1086 	buf = wmi_buf_alloc(wmi_handle, len);
1087 	if (!buf) {
1088 		qdf_print("%s: wmi_buf_alloc failed", __func__);
1089 		return QDF_STATUS_E_NOMEM;
1090 	}
1091 	cmd = (wmi_peer_remove_wds_entry_cmd_fixed_param *)wmi_buf_data(buf);
1092 	WMITLV_SET_HDR(&cmd->tlv_header,
1093 			WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param,
1094 			WMITLV_GET_STRUCT_TLVLEN
1095 				(wmi_peer_remove_wds_entry_cmd_fixed_param));
1096 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr);
1097 	cmd->vdev_id = param->vdev_id;
1098 	wmi_mtrace(WMI_PEER_REMOVE_WDS_ENTRY_CMDID, cmd->vdev_id, 0);
1099 	return wmi_unified_cmd_send(wmi_handle, buf, len,
1100 			WMI_PEER_REMOVE_WDS_ENTRY_CMDID);
1101 }
1102 
1103 /**
1104  * send_peer_update_wds_entry_cmd_non_tlv() - send peer update command to fw
1105  * @wmi_handle: wmi handle
1106  * @param: pointer holding peer details
1107  *
1108  * Return: 0 for success or error code
1109  */
1110 static QDF_STATUS send_peer_update_wds_entry_cmd_tlv(wmi_unified_t wmi_handle,
1111 				struct peer_update_wds_entry_params *param)
1112 {
1113 	wmi_peer_update_wds_entry_cmd_fixed_param *cmd;
1114 	wmi_buf_t buf;
1115 	int len = sizeof(*cmd);
1116 
1117 	buf = wmi_buf_alloc(wmi_handle, len);
1118 	if (!buf) {
1119 		qdf_print("%s: wmi_buf_alloc failed", __func__);
1120 		return QDF_STATUS_E_NOMEM;
1121 	}
1122 
1123 	/* wmi_buf_alloc returns zeroed command buffer */
1124 	cmd = (wmi_peer_update_wds_entry_cmd_fixed_param *)wmi_buf_data(buf);
1125 	WMITLV_SET_HDR(&cmd->tlv_header,
1126 			WMITLV_TAG_STRUC_wmi_peer_update_wds_entry_cmd_fixed_param,
1127 			WMITLV_GET_STRUCT_TLVLEN
1128 				(wmi_peer_update_wds_entry_cmd_fixed_param));
1129 	cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0;
1130 	cmd->vdev_id = param->vdev_id;
1131 	if (param->wds_macaddr)
1132 		WMI_CHAR_ARRAY_TO_MAC_ADDR(param->wds_macaddr,
1133 				&cmd->wds_macaddr);
1134 	if (param->peer_macaddr)
1135 		WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr,
1136 				&cmd->peer_macaddr);
1137 	wmi_mtrace(WMI_PEER_UPDATE_WDS_ENTRY_CMDID, cmd->vdev_id, 0);
1138 	return wmi_unified_cmd_send(wmi_handle, buf, len,
1139 			WMI_PEER_UPDATE_WDS_ENTRY_CMDID);
1140 }
1141 
1142 /**
1143  * send_pdev_get_tpc_config_cmd_tlv() - send get tpc config command to fw
1144  * @wmi_handle: wmi handle
1145  * @param: pointer to get tpc config params
1146  *
1147  * Return: 0 for success or error code
1148  */
1149 static QDF_STATUS
1150 send_pdev_get_tpc_config_cmd_tlv(wmi_unified_t wmi_handle,
1151 				uint32_t param)
1152 {
1153 	wmi_pdev_get_tpc_config_cmd_fixed_param *cmd;
1154 	wmi_buf_t buf;
1155 	int32_t len = sizeof(wmi_pdev_get_tpc_config_cmd_fixed_param);
1156 
1157 	buf = wmi_buf_alloc(wmi_handle, len);
1158 	if (!buf) {
1159 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
1160 		return QDF_STATUS_E_NOMEM;
1161 	}
1162 	cmd = (wmi_pdev_get_tpc_config_cmd_fixed_param *)wmi_buf_data(buf);
1163 	WMITLV_SET_HDR(&cmd->tlv_header,
1164 		WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param,
1165 		WMITLV_GET_STRUCT_TLVLEN
1166 		(wmi_pdev_get_tpc_config_cmd_fixed_param));
1167 
1168 	cmd->param = param;
1169 	wmi_mtrace(WMI_PDEV_GET_TPC_CONFIG_CMDID, NO_SESSION, 0);
1170 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1171 				 WMI_PDEV_GET_TPC_CONFIG_CMDID)) {
1172 		WMI_LOGE("Send pdev get tpc config cmd failed");
1173 		wmi_buf_free(buf);
1174 		return QDF_STATUS_E_FAILURE;
1175 
1176 	}
1177 	WMI_LOGD("%s:send success", __func__);
1178 
1179 	return QDF_STATUS_SUCCESS;
1180 }
1181 
1182 #ifdef WLAN_SUPPORT_GREEN_AP
1183 /**
1184  * send_green_ap_ps_cmd_tlv() - enable green ap powersave command
1185  * @wmi_handle: wmi handle
1186  * @value: value
1187  * @pdev_id: pdev id to have radio context
1188  *
1189  * Return: QDF_STATUS_SUCCESS for success or error code
1190  */
1191 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle,
1192 						uint32_t value, uint8_t pdev_id)
1193 {
1194 	wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd;
1195 	wmi_buf_t buf;
1196 	int32_t len = sizeof(*cmd);
1197 
1198 	WMI_LOGD("Set Green AP PS val %d", value);
1199 
1200 	buf = wmi_buf_alloc(wmi_handle, len);
1201 	if (!buf) {
1202 		WMI_LOGP("%s: Green AP PS Mem Alloc Failed", __func__);
1203 		return QDF_STATUS_E_NOMEM;
1204 	}
1205 
1206 	cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf);
1207 	WMITLV_SET_HDR(&cmd->tlv_header,
1208 		   WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param,
1209 		   WMITLV_GET_STRUCT_TLVLEN
1210 			       (wmi_pdev_green_ap_ps_enable_cmd_fixed_param));
1211 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
1212 	cmd->enable = value;
1213 
1214 	wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0);
1215 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1216 				 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) {
1217 		WMI_LOGE("Set Green AP PS param Failed val %d", value);
1218 		wmi_buf_free(buf);
1219 		return QDF_STATUS_E_FAILURE;
1220 	}
1221 
1222 	return 0;
1223 }
1224 #endif
1225 
1226 /**
1227  * send_pdev_utf_cmd_tlv() - send utf command to fw
1228  * @wmi_handle: wmi handle
1229  * @param: pointer to pdev_utf_params
1230  * @mac_id: mac id to have radio context
1231  *
1232  * Return: QDF_STATUS_SUCCESS for success or error code
1233  */
1234 static QDF_STATUS
1235 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle,
1236 				struct pdev_utf_params *param,
1237 				uint8_t mac_id)
1238 {
1239 	wmi_buf_t buf;
1240 	uint8_t *cmd;
1241 	/* if param->len is 0 no data is sent, return error */
1242 	QDF_STATUS ret = QDF_STATUS_E_INVAL;
1243 	static uint8_t msgref = 1;
1244 	uint8_t segNumber = 0, segInfo, numSegments;
1245 	uint16_t chunk_len, total_bytes;
1246 	uint8_t *bufpos;
1247 	struct seg_hdr_info segHdrInfo;
1248 
1249 	bufpos = param->utf_payload;
1250 	total_bytes = param->len;
1251 	ASSERT(total_bytes / MAX_WMI_UTF_LEN ==
1252 	       (uint8_t) (total_bytes / MAX_WMI_UTF_LEN));
1253 	numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN);
1254 
1255 	if (param->len - (numSegments * MAX_WMI_UTF_LEN))
1256 		numSegments++;
1257 
1258 	while (param->len) {
1259 		if (param->len > MAX_WMI_UTF_LEN)
1260 			chunk_len = MAX_WMI_UTF_LEN;    /* MAX message */
1261 		else
1262 			chunk_len = param->len;
1263 
1264 		buf = wmi_buf_alloc(wmi_handle,
1265 				    (chunk_len + sizeof(segHdrInfo) +
1266 				     WMI_TLV_HDR_SIZE));
1267 		if (!buf) {
1268 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
1269 			return QDF_STATUS_E_NOMEM;
1270 		}
1271 
1272 		cmd = (uint8_t *) wmi_buf_data(buf);
1273 
1274 		segHdrInfo.len = total_bytes;
1275 		segHdrInfo.msgref = msgref;
1276 		segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF);
1277 		segHdrInfo.segmentInfo = segInfo;
1278 		segHdrInfo.pad = 0;
1279 
1280 		WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d,"
1281 			 " segHdrInfo.segmentInfo = %d",
1282 			 __func__, segHdrInfo.len, segHdrInfo.msgref,
1283 			 segHdrInfo.segmentInfo);
1284 
1285 		WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d"
1286 			 "chunk len %d", __func__, total_bytes, segNumber,
1287 			 numSegments, chunk_len);
1288 
1289 		segNumber++;
1290 
1291 		WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE,
1292 			       (chunk_len + sizeof(segHdrInfo)));
1293 		cmd += WMI_TLV_HDR_SIZE;
1294 		memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo));   /* 4 bytes */
1295 		memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len);
1296 
1297 		wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0);
1298 		ret = wmi_unified_cmd_send(wmi_handle, buf,
1299 					   (chunk_len + sizeof(segHdrInfo) +
1300 					    WMI_TLV_HDR_SIZE),
1301 					   WMI_PDEV_UTF_CMDID);
1302 
1303 		if (QDF_IS_STATUS_ERROR(ret)) {
1304 			WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command");
1305 			wmi_buf_free(buf);
1306 			break;
1307 		}
1308 
1309 		param->len -= chunk_len;
1310 		bufpos += chunk_len;
1311 	}
1312 
1313 	msgref++;
1314 
1315 	return ret;
1316 }
1317 #ifdef CONFIG_MCL
1318 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle,
1319 				uint32_t host_param)
1320 {
1321 	return host_param;
1322 }
1323 #else
1324 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle,
1325 				uint32_t host_param)
1326 {
1327 	if (host_param < wmi_pdev_param_max)
1328 		return wmi_handle->pdev_param[host_param];
1329 
1330 	return WMI_UNAVAILABLE_PARAM;
1331 }
1332 #endif
1333 /**
1334  * send_pdev_param_cmd_tlv() - set pdev parameters
1335  * @wmi_handle: wmi handle
1336  * @param: pointer to pdev parameter
1337  * @mac_id: radio context
1338  *
1339  * Return: 0 on success, errno on failure
1340  */
1341 static QDF_STATUS
1342 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle,
1343 			   struct pdev_params *param,
1344 				uint8_t mac_id)
1345 {
1346 	QDF_STATUS ret;
1347 	wmi_pdev_set_param_cmd_fixed_param *cmd;
1348 	wmi_buf_t buf;
1349 	uint16_t len = sizeof(*cmd);
1350 	uint32_t pdev_param;
1351 
1352 	pdev_param = convert_host_pdev_param_tlv(wmi_handle, param->param_id);
1353 	if (pdev_param == WMI_UNAVAILABLE_PARAM) {
1354 		WMI_LOGW("%s: Unavailable param %d\n",
1355 				__func__, param->param_id);
1356 		return QDF_STATUS_E_INVAL;
1357 	}
1358 
1359 	buf = wmi_buf_alloc(wmi_handle, len);
1360 	if (!buf) {
1361 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
1362 		return QDF_STATUS_E_NOMEM;
1363 	}
1364 	cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
1365 	WMITLV_SET_HDR(&cmd->tlv_header,
1366 		       WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param,
1367 		       WMITLV_GET_STRUCT_TLVLEN
1368 			       (wmi_pdev_set_param_cmd_fixed_param));
1369 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
1370 	cmd->param_id = pdev_param;
1371 	cmd->param_value = param->param_value;
1372 	WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id,
1373 				param->param_value);
1374 	wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0);
1375 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1376 				   WMI_PDEV_SET_PARAM_CMDID);
1377 	if (QDF_IS_STATUS_ERROR(ret)) {
1378 		WMI_LOGE("Failed to send set param command ret = %d", ret);
1379 		wmi_buf_free(buf);
1380 	}
1381 	return ret;
1382 }
1383 
1384 /**
1385  * send_suspend_cmd_tlv() - WMI suspend function
1386  * @param wmi_handle      : handle to WMI.
1387  * @param param    : pointer to hold suspend parameter
1388  * @mac_id: radio context
1389  *
1390  * Return 0  on success and -ve on failure.
1391  */
1392 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle,
1393 				struct suspend_params *param,
1394 				uint8_t mac_id)
1395 {
1396 	wmi_pdev_suspend_cmd_fixed_param *cmd;
1397 	wmi_buf_t wmibuf;
1398 	uint32_t len = sizeof(*cmd);
1399 	int32_t ret;
1400 
1401 	/*
1402 	 * send the command to Target to ignore the
1403 	 * PCIE reset so as to ensure that Host and target
1404 	 * states are in sync
1405 	 */
1406 	wmibuf = wmi_buf_alloc(wmi_handle, len);
1407 	if (wmibuf == NULL)
1408 		return QDF_STATUS_E_NOMEM;
1409 
1410 	cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf);
1411 	WMITLV_SET_HDR(&cmd->tlv_header,
1412 		       WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param,
1413 		       WMITLV_GET_STRUCT_TLVLEN
1414 			       (wmi_pdev_suspend_cmd_fixed_param));
1415 	if (param->disable_target_intr)
1416 		cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR;
1417 	else
1418 		cmd->suspend_opt = WMI_PDEV_SUSPEND;
1419 
1420 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
1421 
1422 	wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0);
1423 	ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len,
1424 				 WMI_PDEV_SUSPEND_CMDID);
1425 	if (ret) {
1426 		wmi_buf_free(wmibuf);
1427 		WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command");
1428 	}
1429 
1430 	return ret;
1431 }
1432 
1433 /**
1434  * send_resume_cmd_tlv() - WMI resume function
1435  * @param wmi_handle      : handle to WMI.
1436  * @mac_id: radio context
1437  *
1438  * Return: 0  on success and -ve on failure.
1439  */
1440 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle,
1441 				uint8_t mac_id)
1442 {
1443 	wmi_buf_t wmibuf;
1444 	wmi_pdev_resume_cmd_fixed_param *cmd;
1445 	QDF_STATUS ret;
1446 
1447 	wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
1448 	if (wmibuf == NULL)
1449 		return QDF_STATUS_E_NOMEM;
1450 	cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf);
1451 	WMITLV_SET_HDR(&cmd->tlv_header,
1452 		       WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param,
1453 		       WMITLV_GET_STRUCT_TLVLEN
1454 			       (wmi_pdev_resume_cmd_fixed_param));
1455 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
1456 	wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0);
1457 	ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd),
1458 				   WMI_PDEV_RESUME_CMDID);
1459 	if (QDF_IS_STATUS_ERROR(ret)) {
1460 		WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command");
1461 		wmi_buf_free(wmibuf);
1462 	}
1463 
1464 	return ret;
1465 }
1466 
1467 #ifdef FEATURE_WLAN_D0WOW
1468 /**
1469  *  send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function
1470  *  @param wmi_handle: handle to WMI.
1471  *  @mac_id: radio context
1472  *
1473  *  Return: 0  on success  and  error code on failure.
1474  */
1475 static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle,
1476 				uint8_t mac_id)
1477 {
1478 	wmi_d0_wow_enable_disable_cmd_fixed_param *cmd;
1479 	wmi_buf_t buf;
1480 	int32_t len;
1481 	QDF_STATUS status;
1482 
1483 	len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param);
1484 
1485 	buf = wmi_buf_alloc(wmi_handle, len);
1486 	if (!buf) {
1487 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
1488 		return QDF_STATUS_E_NOMEM;
1489 	}
1490 	cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf);
1491 	WMITLV_SET_HDR(&cmd->tlv_header,
1492 		WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param,
1493 		WMITLV_GET_STRUCT_TLVLEN
1494 		(wmi_d0_wow_enable_disable_cmd_fixed_param));
1495 
1496 	cmd->enable = true;
1497 
1498 	wmi_mtrace(WMI_D0_WOW_ENABLE_DISABLE_CMDID, NO_SESSION, 0);
1499 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
1500 			WMI_D0_WOW_ENABLE_DISABLE_CMDID);
1501 	if (QDF_IS_STATUS_ERROR(status))
1502 		wmi_buf_free(buf);
1503 
1504 	return status;
1505 }
1506 
1507 /**
1508  *  send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function
1509  *  @param wmi_handle: handle to WMI.
1510  *  @mac_id: radio context
1511  *
1512  *  Return: 0  on success  and  error code on failure.
1513  */
1514 static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle,
1515 				uint8_t mac_id)
1516 {
1517 	wmi_d0_wow_enable_disable_cmd_fixed_param *cmd;
1518 	wmi_buf_t buf;
1519 	int32_t len;
1520 	QDF_STATUS status;
1521 
1522 	len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param);
1523 
1524 	buf = wmi_buf_alloc(wmi_handle, len);
1525 	if (!buf) {
1526 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
1527 		return QDF_STATUS_E_NOMEM;
1528 	}
1529 	cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf);
1530 	WMITLV_SET_HDR(&cmd->tlv_header,
1531 		WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param,
1532 		WMITLV_GET_STRUCT_TLVLEN
1533 		(wmi_d0_wow_enable_disable_cmd_fixed_param));
1534 
1535 	cmd->enable = false;
1536 
1537 	wmi_mtrace(WMI_D0_WOW_ENABLE_DISABLE_CMDID, NO_SESSION, 0);
1538 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
1539 			WMI_D0_WOW_ENABLE_DISABLE_CMDID);
1540 	if (QDF_IS_STATUS_ERROR(status))
1541 		wmi_buf_free(buf);
1542 
1543 	return status;
1544 }
1545 #endif
1546 
1547 /**
1548  *  send_wow_enable_cmd_tlv() - WMI wow enable function
1549  *  @param wmi_handle      : handle to WMI.
1550  *  @param param    : pointer to hold wow enable parameter
1551  *  @mac_id: radio context
1552  *
1553  *  Return: 0  on success and -ve on failure.
1554  */
1555 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle,
1556 				struct wow_cmd_params *param,
1557 				uint8_t mac_id)
1558 {
1559 	wmi_wow_enable_cmd_fixed_param *cmd;
1560 	wmi_buf_t buf;
1561 	int32_t len;
1562 	int32_t ret;
1563 
1564 	len = sizeof(wmi_wow_enable_cmd_fixed_param);
1565 
1566 	buf = wmi_buf_alloc(wmi_handle, len);
1567 	if (!buf) {
1568 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
1569 		return QDF_STATUS_E_NOMEM;
1570 	}
1571 	cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf);
1572 	WMITLV_SET_HDR(&cmd->tlv_header,
1573 		       WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param,
1574 		       WMITLV_GET_STRUCT_TLVLEN
1575 			       (wmi_wow_enable_cmd_fixed_param));
1576 	cmd->enable = param->enable;
1577 	if (param->can_suspend_link)
1578 		cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED;
1579 	else
1580 		cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED;
1581 	cmd->flags = param->flags;
1582 
1583 	WMI_LOGI("suspend type: %s",
1584 		cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ?
1585 		"WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED");
1586 
1587 	wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0);
1588 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1589 				   WMI_WOW_ENABLE_CMDID);
1590 	if (ret)
1591 		wmi_buf_free(buf);
1592 
1593 	return ret;
1594 }
1595 
1596 /**
1597  * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters
1598  * @wmi_handle: wmi handle
1599  * @peer_addr: peer mac address
1600  * @param: pointer to ap_ps parameter structure
1601  *
1602  * Return: QDF_STATUS_SUCCESS for success or error code
1603  */
1604 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle,
1605 					   uint8_t *peer_addr,
1606 					   struct ap_ps_params *param)
1607 {
1608 	wmi_ap_ps_peer_cmd_fixed_param *cmd;
1609 	wmi_buf_t buf;
1610 	int32_t err;
1611 
1612 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
1613 	if (!buf) {
1614 		WMI_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd");
1615 		return QDF_STATUS_E_NOMEM;
1616 	}
1617 	cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf);
1618 	WMITLV_SET_HDR(&cmd->tlv_header,
1619 		       WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param,
1620 		       WMITLV_GET_STRUCT_TLVLEN
1621 			       (wmi_ap_ps_peer_cmd_fixed_param));
1622 	cmd->vdev_id = param->vdev_id;
1623 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
1624 	cmd->param = param->param;
1625 	cmd->value = param->value;
1626 	wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0);
1627 	err = wmi_unified_cmd_send(wmi_handle, buf,
1628 				   sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID);
1629 	if (err) {
1630 		WMI_LOGE("Failed to send set_ap_ps_param cmd");
1631 		wmi_buf_free(buf);
1632 		return QDF_STATUS_E_FAILURE;
1633 	}
1634 
1635 	return 0;
1636 }
1637 
1638 /**
1639  * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters
1640  * @wmi_handle: wmi handle
1641  * @peer_addr: peer mac address
1642  * @param: pointer to sta_ps parameter structure
1643  *
1644  * Return: QDF_STATUS_SUCCESS for success or error code
1645  */
1646 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle,
1647 					   struct sta_ps_params *param)
1648 {
1649 	wmi_sta_powersave_param_cmd_fixed_param *cmd;
1650 	wmi_buf_t buf;
1651 	int32_t len = sizeof(*cmd);
1652 
1653 	buf = wmi_buf_alloc(wmi_handle, len);
1654 	if (!buf) {
1655 		WMI_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__);
1656 		return QDF_STATUS_E_NOMEM;
1657 	}
1658 
1659 	cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf);
1660 	WMITLV_SET_HDR(&cmd->tlv_header,
1661 		       WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param,
1662 		       WMITLV_GET_STRUCT_TLVLEN
1663 			       (wmi_sta_powersave_param_cmd_fixed_param));
1664 	cmd->vdev_id = param->vdev_id;
1665 	cmd->param = param->param;
1666 	cmd->value = param->value;
1667 
1668 	wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0);
1669 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1670 				 WMI_STA_POWERSAVE_PARAM_CMDID)) {
1671 		WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d",
1672 			 param->vdev_id, param->param, param->value);
1673 		wmi_buf_free(buf);
1674 		return QDF_STATUS_E_FAILURE;
1675 	}
1676 
1677 	return 0;
1678 }
1679 
1680 /**
1681  * send_crash_inject_cmd_tlv() - inject fw crash
1682  * @wmi_handle: wmi handle
1683  * @param: ponirt to crash inject parameter structure
1684  *
1685  * Return: QDF_STATUS_SUCCESS for success or return error
1686  */
1687 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle,
1688 			 struct crash_inject *param)
1689 {
1690 	int32_t ret = 0;
1691 	WMI_FORCE_FW_HANG_CMD_fixed_param *cmd;
1692 	uint16_t len = sizeof(*cmd);
1693 	wmi_buf_t buf;
1694 
1695 	buf = wmi_buf_alloc(wmi_handle, len);
1696 	if (!buf) {
1697 		WMI_LOGE("%s: wmi_buf_alloc failed!", __func__);
1698 		return QDF_STATUS_E_NOMEM;
1699 	}
1700 
1701 	cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf);
1702 	WMITLV_SET_HDR(&cmd->tlv_header,
1703 		       WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param,
1704 		       WMITLV_GET_STRUCT_TLVLEN
1705 			       (WMI_FORCE_FW_HANG_CMD_fixed_param));
1706 	cmd->type = param->type;
1707 	cmd->delay_time_ms = param->delay_time_ms;
1708 
1709 	wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0);
1710 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1711 		WMI_FORCE_FW_HANG_CMDID);
1712 	if (ret) {
1713 		WMI_LOGE("%s: Failed to send set param command, ret = %d",
1714 			 __func__, ret);
1715 		wmi_buf_free(buf);
1716 	}
1717 
1718 	return ret;
1719 }
1720 
1721 #ifdef FEATURE_FW_LOG_PARSING
1722 /**
1723  *  send_dbglog_cmd_tlv() - set debug log level
1724  *  @param wmi_handle      : handle to WMI.
1725  *  @param param    : pointer to hold dbglog level parameter
1726  *
1727  *  Return: 0  on success and -ve on failure.
1728  */
1729  static QDF_STATUS
1730 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle,
1731 				struct dbglog_params *dbglog_param)
1732 {
1733 	wmi_buf_t buf;
1734 	wmi_debug_log_config_cmd_fixed_param *configmsg;
1735 	QDF_STATUS status;
1736 	int32_t i;
1737 	int32_t len;
1738 	int8_t *buf_ptr;
1739 	int32_t *module_id_bitmap_array;     /* Used to fomr the second tlv */
1740 
1741 	ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS);
1742 
1743 	/* Allocate size for 2 tlvs - including tlv hdr space for second tlv */
1744 	len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE +
1745 	      (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS);
1746 	buf = wmi_buf_alloc(wmi_handle, len);
1747 	if (buf == NULL)
1748 		return QDF_STATUS_E_NOMEM;
1749 
1750 	configmsg =
1751 		(wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf));
1752 	buf_ptr = (int8_t *) configmsg;
1753 	WMITLV_SET_HDR(&configmsg->tlv_header,
1754 		       WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param,
1755 		       WMITLV_GET_STRUCT_TLVLEN
1756 			       (wmi_debug_log_config_cmd_fixed_param));
1757 	configmsg->dbg_log_param = dbglog_param->param;
1758 	configmsg->value = dbglog_param->val;
1759 	/* Filling in the data part of second tlv -- should
1760 	 * follow first tlv _ WMI_TLV_HDR_SIZE */
1761 	module_id_bitmap_array = (uint32_t *) (buf_ptr +
1762 				       sizeof
1763 				       (wmi_debug_log_config_cmd_fixed_param)
1764 				       + WMI_TLV_HDR_SIZE);
1765 	WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param),
1766 		       WMITLV_TAG_ARRAY_UINT32,
1767 		       sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS);
1768 	if (dbglog_param->module_id_bitmap) {
1769 		for (i = 0; i < dbglog_param->bitmap_len; ++i) {
1770 			module_id_bitmap_array[i] =
1771 					dbglog_param->module_id_bitmap[i];
1772 		}
1773 	}
1774 
1775 	wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0);
1776 	status = wmi_unified_cmd_send(wmi_handle, buf,
1777 				      len, WMI_DBGLOG_CFG_CMDID);
1778 
1779 	if (status != QDF_STATUS_SUCCESS)
1780 		wmi_buf_free(buf);
1781 
1782 	return status;
1783 }
1784 #endif
1785 
1786 #ifdef CONFIG_MCL
1787 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle,
1788 				uint32_t host_param)
1789 {
1790 	return host_param;
1791 }
1792 #else
1793 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle,
1794 				uint32_t host_param)
1795 {
1796 	if (host_param < wmi_vdev_param_max)
1797 		return wmi_handle->vdev_param[host_param];
1798 
1799 	return WMI_UNAVAILABLE_PARAM;
1800 }
1801 #endif
1802 /**
1803  *  send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function
1804  *  @param wmi_handle      : handle to WMI.
1805  *  @param macaddr        : MAC address
1806  *  @param param    : pointer to hold vdev set parameter
1807  *
1808  *  Return: 0  on success and -ve on failure.
1809  */
1810 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle,
1811 				struct vdev_set_params *param)
1812 {
1813 	QDF_STATUS ret;
1814 	wmi_vdev_set_param_cmd_fixed_param *cmd;
1815 	wmi_buf_t buf;
1816 	uint16_t len = sizeof(*cmd);
1817 	uint32_t vdev_param;
1818 
1819 	vdev_param = convert_host_vdev_param_tlv(wmi_handle, param->param_id);
1820 	if (vdev_param == WMI_UNAVAILABLE_PARAM) {
1821 		WMI_LOGW("%s:Vdev param %d not available", __func__,
1822 				param->param_id);
1823 		return QDF_STATUS_E_INVAL;
1824 
1825 	}
1826 
1827 	buf = wmi_buf_alloc(wmi_handle, len);
1828 	if (!buf) {
1829 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
1830 		return QDF_STATUS_E_NOMEM;
1831 	}
1832 	cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
1833 	WMITLV_SET_HDR(&cmd->tlv_header,
1834 		       WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param,
1835 		       WMITLV_GET_STRUCT_TLVLEN
1836 			       (wmi_vdev_set_param_cmd_fixed_param));
1837 	cmd->vdev_id = param->if_id;
1838 	cmd->param_id = vdev_param;
1839 	cmd->param_value = param->param_value;
1840 	WMI_LOGD("Setting vdev %d param = %x, value = %u",
1841 		 cmd->vdev_id, cmd->param_id, cmd->param_value);
1842 	wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0);
1843 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1844 				   WMI_VDEV_SET_PARAM_CMDID);
1845 	if (QDF_IS_STATUS_ERROR(ret)) {
1846 		WMI_LOGE("Failed to send set param command ret = %d", ret);
1847 		wmi_buf_free(buf);
1848 	}
1849 
1850 	return ret;
1851 }
1852 
1853 /**
1854  *  send_stats_request_cmd_tlv() - WMI request stats function
1855  *  @param wmi_handle      : handle to WMI.
1856  *  @param macaddr        : MAC address
1857  *  @param param    : pointer to hold stats request parameter
1858  *
1859  *  Return: 0  on success and -ve on failure.
1860  */
1861 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle,
1862 				uint8_t macaddr[IEEE80211_ADDR_LEN],
1863 				struct stats_request_params *param)
1864 {
1865 	int32_t ret;
1866 	wmi_request_stats_cmd_fixed_param *cmd;
1867 	wmi_buf_t buf;
1868 	uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param);
1869 
1870 	buf = wmi_buf_alloc(wmi_handle, len);
1871 	if (!buf) {
1872 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
1873 		return -QDF_STATUS_E_NOMEM;
1874 	}
1875 
1876 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
1877 	WMITLV_SET_HDR(&cmd->tlv_header,
1878 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
1879 		       WMITLV_GET_STRUCT_TLVLEN
1880 			       (wmi_request_stats_cmd_fixed_param));
1881 	cmd->stats_id = param->stats_id;
1882 	cmd->vdev_id = param->vdev_id;
1883 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
1884 							param->pdev_id);
1885 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
1886 
1887 	WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->",
1888 				cmd->stats_id, cmd->vdev_id, cmd->pdev_id);
1889 
1890 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
1891 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1892 					 WMI_REQUEST_STATS_CMDID);
1893 
1894 	if (ret) {
1895 		WMI_LOGE("Failed to send status request to fw =%d", ret);
1896 		wmi_buf_free(buf);
1897 	}
1898 
1899 	return ret;
1900 }
1901 
1902 #ifdef CONFIG_WIN
1903 /**
1904  *  send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log
1905  *  @param wmi_handle      : handle to WMI.
1906  *  @param PKTLOG_EVENT	: packet log event
1907  *  @mac_id: mac id to have radio context
1908  *
1909  *  Return: 0  on success and -ve on failure.
1910  */
1911 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle,
1912 			WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id)
1913 {
1914 	int32_t ret;
1915 	wmi_pdev_pktlog_enable_cmd_fixed_param *cmd;
1916 	wmi_buf_t buf;
1917 	uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param);
1918 
1919 	buf = wmi_buf_alloc(wmi_handle, len);
1920 	if (!buf) {
1921 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
1922 		return -QDF_STATUS_E_NOMEM;
1923 	}
1924 
1925 	cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf);
1926 	WMITLV_SET_HDR(&cmd->tlv_header,
1927 		       WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param,
1928 		       WMITLV_GET_STRUCT_TLVLEN
1929 			       (wmi_pdev_pktlog_enable_cmd_fixed_param));
1930 	cmd->evlist = PKTLOG_EVENT;
1931 	cmd->pdev_id = mac_id;
1932 	wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0);
1933 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1934 					 WMI_PDEV_PKTLOG_ENABLE_CMDID);
1935 	if (ret) {
1936 		WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret);
1937 		wmi_buf_free(buf);
1938 	}
1939 
1940 	return ret;
1941 }
1942 
1943 /**
1944  *  send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log
1945  *  @param wmi_handle      : handle to WMI.
1946  *  @mac_id: mac id to have radio context
1947  *
1948  *  Return: 0  on success and -ve on failure.
1949  */
1950 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle,
1951 			uint8_t mac_id)
1952 {
1953 	int32_t ret;
1954 	wmi_pdev_pktlog_disable_cmd_fixed_param *cmd;
1955 	wmi_buf_t buf;
1956 	uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param);
1957 
1958 	buf = wmi_buf_alloc(wmi_handle, len);
1959 	if (!buf) {
1960 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
1961 		return -QDF_STATUS_E_NOMEM;
1962 	}
1963 
1964 	cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf);
1965 	WMITLV_SET_HDR(&cmd->tlv_header,
1966 		       WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param,
1967 		       WMITLV_GET_STRUCT_TLVLEN
1968 			       (wmi_pdev_pktlog_disable_cmd_fixed_param));
1969 	cmd->pdev_id = mac_id;
1970 	wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0);
1971 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1972 					 WMI_PDEV_PKTLOG_DISABLE_CMDID);
1973 	if (ret) {
1974 		WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret);
1975 		wmi_buf_free(buf);
1976 	}
1977 
1978 	return ret;
1979 }
1980 #else
1981 /**
1982  *  send_packet_log_enable_cmd_tlv() - Send WMI command to enable
1983  *  packet-log
1984  *  @param wmi_handle      : handle to WMI.
1985  *  @param macaddr        : MAC address
1986  *  @param param    : pointer to hold stats request parameter
1987  *
1988  *  Return: 0  on success and -ve on failure.
1989  */
1990 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle,
1991 				uint8_t macaddr[IEEE80211_ADDR_LEN],
1992 				struct packet_enable_params *param)
1993 {
1994 	return 0;
1995 }
1996 /**
1997  *  send_packet_log_disable_cmd_tlv() - Send WMI command to disable
1998  *  packet-log
1999  *  @param wmi_handle      : handle to WMI.
2000  *  @mac_id: mac id to have radio context
2001  *
2002  *  Return: 0  on success and -ve on failure.
2003  */
2004 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle,
2005 				uint8_t mac_id)
2006 {
2007 	return 0;
2008 }
2009 #endif
2010 
2011 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff
2012 /**
2013  *  send_time_stamp_sync_cmd_tlv() - Send WMI command to
2014  *  sync time between bwtween host and firmware
2015  *  @param wmi_handle      : handle to WMI.
2016  *
2017  *  Return: None
2018  */
2019 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle)
2020 {
2021 	wmi_buf_t buf;
2022 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2023 	WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp;
2024 	int32_t len;
2025 	qdf_time_t time_ms;
2026 
2027 	len = sizeof(*time_stamp);
2028 	buf = wmi_buf_alloc(wmi_handle, len);
2029 
2030 	if (!buf) {
2031 		WMI_LOGP(FL("wmi_buf_alloc failed"));
2032 		return;
2033 	}
2034 	time_stamp =
2035 		(WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *)
2036 			(wmi_buf_data(buf));
2037 	WMITLV_SET_HDR(&time_stamp->tlv_header,
2038 		WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param,
2039 		WMITLV_GET_STRUCT_TLVLEN(
2040 		WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param));
2041 
2042 	time_ms = qdf_get_time_of_the_day_ms();
2043 	time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS;
2044 	time_stamp->time_stamp_low = time_ms &
2045 		WMI_FW_TIME_STAMP_LOW_MASK;
2046 	/*
2047 	 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms
2048 	 * wont exceed 27 bit
2049 	 */
2050 	time_stamp->time_stamp_high = 0;
2051 	WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"),
2052 		time_stamp->mode, time_stamp->time_stamp_low,
2053 		time_stamp->time_stamp_high);
2054 
2055 	wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0);
2056 	status = wmi_unified_cmd_send(wmi_handle, buf,
2057 				      len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID);
2058 	if (status) {
2059 		WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command");
2060 		wmi_buf_free(buf);
2061 	}
2062 
2063 }
2064 
2065 #ifdef WLAN_SUPPORT_FILS
2066 /**
2067  * extract_swfda_vdev_id_tlv() - extract swfda vdev id from event
2068  * @wmi_handle: wmi handle
2069  * @evt_buf: pointer to event buffer
2070  * @vdev_id: pointer to hold vdev id
2071  *
2072  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure
2073  */
2074 static QDF_STATUS
2075 extract_swfda_vdev_id_tlv(wmi_unified_t wmi_handle,
2076 			  void *evt_buf, uint32_t *vdev_id)
2077 {
2078 	WMI_HOST_SWFDA_EVENTID_param_tlvs *param_buf;
2079 	wmi_host_swfda_event_fixed_param *swfda_event;
2080 
2081 	param_buf = (WMI_HOST_SWFDA_EVENTID_param_tlvs *)evt_buf;
2082 	if (!param_buf) {
2083 		WMI_LOGE("Invalid swfda event buffer");
2084 		return QDF_STATUS_E_INVAL;
2085 	}
2086 	swfda_event = param_buf->fixed_param;
2087 	*vdev_id = swfda_event->vdev_id;
2088 
2089 	return QDF_STATUS_SUCCESS;
2090 }
2091 
2092 /**
2093  * send_vdev_fils_enable_cmd_tlv() - enable/Disable FD Frame command to fw
2094  * @wmi_handle: wmi handle
2095  * @param: pointer to hold FILS discovery enable param
2096  *
2097  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE on failure
2098  */
2099 static QDF_STATUS
2100 send_vdev_fils_enable_cmd_tlv(wmi_unified_t wmi_handle,
2101 			      struct config_fils_params *param)
2102 {
2103 	wmi_enable_fils_cmd_fixed_param *cmd;
2104 	wmi_buf_t buf;
2105 	QDF_STATUS status;
2106 	uint32_t len = sizeof(wmi_enable_fils_cmd_fixed_param);
2107 
2108 	buf = wmi_buf_alloc(wmi_handle, len);
2109 	if (!buf) {
2110 		WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__);
2111 		return QDF_STATUS_E_NOMEM;
2112 	}
2113 	cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data(buf);
2114 	WMITLV_SET_HDR(&cmd->tlv_header,
2115 		       WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param,
2116 		       WMITLV_GET_STRUCT_TLVLEN(
2117 		       wmi_enable_fils_cmd_fixed_param));
2118 	cmd->vdev_id = param->vdev_id;
2119 	cmd->fd_period = param->fd_period;
2120 	WMI_LOGI("Setting FD period to %d vdev id : %d\n",
2121 		 param->fd_period, param->vdev_id);
2122 
2123 	wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, 0);
2124 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
2125 				      WMI_ENABLE_FILS_CMDID);
2126 	if (status != QDF_STATUS_SUCCESS) {
2127 		wmi_buf_free(buf);
2128 		return QDF_STATUS_E_FAILURE;
2129 	}
2130 
2131 	return QDF_STATUS_SUCCESS;
2132 }
2133 
2134 /**
2135  * send_fils_discovery_send_cmd_tlv() - WMI FILS Discovery send function
2136  * @wmi_handle: wmi handle
2137  * @param: pointer to hold FD send cmd parameter
2138  *
2139  * Return : QDF_STATUS_SUCCESS on success and QDF_STATUS_E_NOMEM on failure.
2140  */
2141 static QDF_STATUS
2142 send_fils_discovery_send_cmd_tlv(wmi_unified_t wmi_handle,
2143 				 struct fd_params *param)
2144 {
2145 	QDF_STATUS ret;
2146 	wmi_fd_send_from_host_cmd_fixed_param *cmd;
2147 	wmi_buf_t wmi_buf;
2148 	qdf_dma_addr_t dma_addr;
2149 
2150 	wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
2151 	if (!wmi_buf) {
2152 		WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__);
2153 		return QDF_STATUS_E_NOMEM;
2154 	}
2155 	cmd = (wmi_fd_send_from_host_cmd_fixed_param *)wmi_buf_data(wmi_buf);
2156 	WMITLV_SET_HDR(&cmd->tlv_header,
2157 		       WMITLV_TAG_STRUC_wmi_fd_send_from_host_cmd_fixed_param,
2158 		       WMITLV_GET_STRUCT_TLVLEN(
2159 		       wmi_fd_send_from_host_cmd_fixed_param));
2160 	cmd->vdev_id = param->vdev_id;
2161 	cmd->data_len = qdf_nbuf_len(param->wbuf);
2162 	dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0);
2163 	qdf_dmaaddr_to_32s(dma_addr, &cmd->frag_ptr_lo, &cmd->frag_ptr_hi);
2164 	cmd->frame_ctrl = param->frame_ctrl;
2165 
2166 	wmi_mtrace(WMI_PDEV_SEND_FD_CMDID, cmd->vdev_id, 0);
2167 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd),
2168 				   WMI_PDEV_SEND_FD_CMDID);
2169 	if (ret != QDF_STATUS_SUCCESS) {
2170 		WMI_LOGE("%s: Failed to send fils discovery frame: %d",
2171 			 __func__, ret);
2172 		wmi_buf_free(wmi_buf);
2173 	}
2174 
2175 	return ret;
2176 }
2177 #endif /* WLAN_SUPPORT_FILS */
2178 
2179 static QDF_STATUS send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle,
2180 				struct beacon_params *param)
2181 {
2182 	QDF_STATUS ret;
2183 	wmi_bcn_send_from_host_cmd_fixed_param *cmd;
2184 	wmi_buf_t wmi_buf;
2185 	qdf_dma_addr_t dma_addr;
2186 	uint32_t dtim_flag = 0;
2187 
2188 	wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
2189 	if (!wmi_buf) {
2190 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
2191 		return QDF_STATUS_E_NOMEM;
2192 	}
2193 	if (param->is_dtim_count_zero) {
2194 		dtim_flag |= WMI_BCN_SEND_DTIM_ZERO;
2195 		if (param->is_bitctl_reqd) {
2196 			/* deliver CAB traffic in next DTIM beacon */
2197 			dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET;
2198 		}
2199 	}
2200 	cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf);
2201 	WMITLV_SET_HDR(&cmd->tlv_header,
2202 		WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param,
2203 		WMITLV_GET_STRUCT_TLVLEN
2204 				(wmi_bcn_send_from_host_cmd_fixed_param));
2205 	cmd->vdev_id = param->vdev_id;
2206 	cmd->data_len = qdf_nbuf_len(param->wbuf);
2207 	cmd->frame_ctrl = param->frame_ctrl;
2208 	cmd->dtim_flag = dtim_flag;
2209 	dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0);
2210 	cmd->frag_ptr_lo = qdf_get_lower_32_bits(dma_addr);
2211 #if defined(HTT_PADDR64)
2212 	cmd->frag_ptr_hi = qdf_get_upper_32_bits(dma_addr) & 0x1F;
2213 #endif
2214 	cmd->bcn_antenna = param->bcn_txant;
2215 
2216 	wmi_mtrace(WMI_PDEV_SEND_BCN_CMDID, cmd->vdev_id, 0);
2217 	ret = wmi_unified_cmd_send(wmi_handle,
2218 			wmi_buf, sizeof(*cmd), WMI_PDEV_SEND_BCN_CMDID);
2219 	if (ret != QDF_STATUS_SUCCESS) {
2220 		WMI_LOGE("%s: Failed to send bcn: %d", __func__, ret);
2221 		wmi_buf_free(wmi_buf);
2222 	}
2223 
2224 	return ret;
2225 }
2226 
2227 /**
2228  *  send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function
2229  *  @param wmi_handle      : handle to WMI.
2230  *  @param param    : pointer to hold beacon send cmd parameter
2231  *
2232  *  Return: 0  on success and -ve on failure.
2233  */
2234 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle,
2235 				struct beacon_tmpl_params *param)
2236 {
2237 	int32_t ret;
2238 	wmi_bcn_tmpl_cmd_fixed_param *cmd;
2239 	wmi_bcn_prb_info *bcn_prb_info;
2240 	wmi_buf_t wmi_buf;
2241 	uint8_t *buf_ptr;
2242 	uint32_t wmi_buf_len;
2243 
2244 	wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) +
2245 		      sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE +
2246 		      param->tmpl_len_aligned;
2247 	wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
2248 	if (!wmi_buf) {
2249 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
2250 		return QDF_STATUS_E_NOMEM;
2251 	}
2252 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
2253 	cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr;
2254 	WMITLV_SET_HDR(&cmd->tlv_header,
2255 		       WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param,
2256 		       WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param));
2257 	cmd->vdev_id = param->vdev_id;
2258 	cmd->tim_ie_offset = param->tim_ie_offset;
2259 	cmd->mbssid_ie_offset = param->mbssid_ie_offset;
2260 	cmd->csa_switch_count_offset = param->csa_switch_count_offset;
2261 	cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset;
2262 	cmd->esp_ie_offset = param->esp_ie_offset;
2263 	cmd->buf_len = param->tmpl_len;
2264 	buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param);
2265 
2266 	bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr;
2267 	WMITLV_SET_HDR(&bcn_prb_info->tlv_header,
2268 		       WMITLV_TAG_STRUC_wmi_bcn_prb_info,
2269 		       WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info));
2270 	bcn_prb_info->caps = 0;
2271 	bcn_prb_info->erp = 0;
2272 	buf_ptr += sizeof(wmi_bcn_prb_info);
2273 
2274 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned);
2275 	buf_ptr += WMI_TLV_HDR_SIZE;
2276 	qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len);
2277 
2278 	wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0);
2279 	ret = wmi_unified_cmd_send(wmi_handle,
2280 				   wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID);
2281 	if (ret) {
2282 		WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret);
2283 		wmi_buf_free(wmi_buf);
2284 	}
2285 
2286 	return 0;
2287 }
2288 
2289 #ifdef CONFIG_MCL
2290 static inline void copy_peer_flags_tlv(
2291 			wmi_peer_assoc_complete_cmd_fixed_param * cmd,
2292 			struct peer_assoc_params *param)
2293 {
2294 	cmd->peer_flags = param->peer_flags;
2295 }
2296 #else
2297 static inline void copy_peer_flags_tlv(
2298 			wmi_peer_assoc_complete_cmd_fixed_param * cmd,
2299 			struct peer_assoc_params *param)
2300 {
2301 	/*
2302 	 * The target only needs a subset of the flags maintained in the host.
2303 	 * Just populate those flags and send it down
2304 	 */
2305 	cmd->peer_flags = 0;
2306 
2307 	/*
2308 	 * Do not enable HT/VHT if WMM/wme is disabled for vap.
2309 	 */
2310 	if (param->is_wme_set) {
2311 
2312 		if (param->qos_flag)
2313 			cmd->peer_flags |= WMI_PEER_QOS;
2314 		if (param->apsd_flag)
2315 			cmd->peer_flags |= WMI_PEER_APSD;
2316 		if (param->ht_flag)
2317 			cmd->peer_flags |= WMI_PEER_HT;
2318 		if (param->bw_40)
2319 			cmd->peer_flags |= WMI_PEER_40MHZ;
2320 		if (param->bw_80)
2321 			cmd->peer_flags |= WMI_PEER_80MHZ;
2322 		if (param->bw_160)
2323 			cmd->peer_flags |= WMI_PEER_160MHZ;
2324 
2325 		/* Typically if STBC is enabled for VHT it should be enabled
2326 		 * for HT as well
2327 		 **/
2328 		if (param->stbc_flag)
2329 			cmd->peer_flags |= WMI_PEER_STBC;
2330 
2331 		/* Typically if LDPC is enabled for VHT it should be enabled
2332 		 * for HT as well
2333 		 **/
2334 		if (param->ldpc_flag)
2335 			cmd->peer_flags |= WMI_PEER_LDPC;
2336 
2337 		if (param->static_mimops_flag)
2338 			cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS;
2339 		if (param->dynamic_mimops_flag)
2340 			cmd->peer_flags |= WMI_PEER_DYN_MIMOPS;
2341 		if (param->spatial_mux_flag)
2342 			cmd->peer_flags |= WMI_PEER_SPATIAL_MUX;
2343 		if (param->vht_flag)
2344 			cmd->peer_flags |= WMI_PEER_VHT;
2345 		if (param->he_flag)
2346 			cmd->peer_flags |= WMI_PEER_HE;
2347 	}
2348 
2349 	if (param->is_pmf_enabled)
2350 		cmd->peer_flags |= WMI_PEER_PMF;
2351 	/*
2352 	 * Suppress authorization for all AUTH modes that need 4-way handshake
2353 	 * (during re-association).
2354 	 * Authorization will be done for these modes on key installation.
2355 	 */
2356 	if (param->auth_flag)
2357 		cmd->peer_flags |= WMI_PEER_AUTH;
2358 	if (param->need_ptk_4_way)
2359 		cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
2360 	else
2361 		cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY;
2362 	if (param->need_gtk_2_way)
2363 		cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
2364 	/* safe mode bypass the 4-way handshake */
2365 	if (param->safe_mode_enabled)
2366 		cmd->peer_flags &=
2367 		    ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY);
2368 	/* Disable AMSDU for station transmit, if user configures it */
2369 	/* Disable AMSDU for AP transmit to 11n Stations, if user configures
2370 	 * it
2371 	 * if (param->amsdu_disable) Add after FW support
2372 	 **/
2373 
2374 	/* Target asserts if node is marked HT and all MCS is set to 0.
2375 	 * Mark the node as non-HT if all the mcs rates are disabled through
2376 	 * iwpriv
2377 	 **/
2378 	if (param->peer_ht_rates.num_rates == 0)
2379 		cmd->peer_flags &= ~WMI_PEER_HT;
2380 
2381 	if (param->twt_requester)
2382 		cmd->peer_flags |= WMI_PEER_TWT_REQ;
2383 
2384 	if (param->twt_responder)
2385 		cmd->peer_flags |= WMI_PEER_TWT_RESP;
2386 }
2387 #endif
2388 
2389 #ifdef CONFIG_MCL
2390 static inline void copy_peer_mac_addr_tlv(
2391 		wmi_peer_assoc_complete_cmd_fixed_param * cmd,
2392 		struct peer_assoc_params *param)
2393 {
2394 	qdf_mem_copy(&cmd->peer_macaddr, &param->peer_macaddr,
2395 			sizeof(param->peer_macaddr));
2396 }
2397 #else
2398 static inline void copy_peer_mac_addr_tlv(
2399 		wmi_peer_assoc_complete_cmd_fixed_param * cmd,
2400 		struct peer_assoc_params *param)
2401 {
2402 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr);
2403 }
2404 #endif
2405 
2406 /**
2407  *  send_peer_assoc_cmd_tlv() - WMI peer assoc function
2408  *  @param wmi_handle      : handle to WMI.
2409  *  @param param    : pointer to peer assoc parameter
2410  *
2411  *  Return: 0  on success and -ve on failure.
2412  */
2413 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle,
2414 				struct peer_assoc_params *param)
2415 {
2416 	wmi_peer_assoc_complete_cmd_fixed_param *cmd;
2417 	wmi_vht_rate_set *mcs;
2418 	wmi_he_rate_set *he_mcs;
2419 	wmi_buf_t buf;
2420 	int32_t len;
2421 	uint8_t *buf_ptr;
2422 	QDF_STATUS ret;
2423 	uint32_t peer_legacy_rates_align;
2424 	uint32_t peer_ht_rates_align;
2425 	int32_t i;
2426 
2427 
2428 	peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates);
2429 	peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates);
2430 
2431 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
2432 		(peer_legacy_rates_align * sizeof(uint8_t)) +
2433 		WMI_TLV_HDR_SIZE +
2434 		(peer_ht_rates_align * sizeof(uint8_t)) +
2435 		sizeof(wmi_vht_rate_set) +
2436 		(sizeof(wmi_he_rate_set) * param->peer_he_mcs_count
2437 		+ WMI_TLV_HDR_SIZE);
2438 
2439 	buf = wmi_buf_alloc(wmi_handle, len);
2440 	if (!buf) {
2441 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
2442 		return QDF_STATUS_E_NOMEM;
2443 	}
2444 
2445 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
2446 	cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr;
2447 	WMITLV_SET_HDR(&cmd->tlv_header,
2448 		       WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param,
2449 		       WMITLV_GET_STRUCT_TLVLEN
2450 			       (wmi_peer_assoc_complete_cmd_fixed_param));
2451 
2452 	cmd->vdev_id = param->vdev_id;
2453 
2454 	cmd->peer_new_assoc = param->peer_new_assoc;
2455 	cmd->peer_associd = param->peer_associd;
2456 
2457 	copy_peer_flags_tlv(cmd, param);
2458 	copy_peer_mac_addr_tlv(cmd, param);
2459 
2460 	cmd->peer_rate_caps = param->peer_rate_caps;
2461 	cmd->peer_caps = param->peer_caps;
2462 	cmd->peer_listen_intval = param->peer_listen_intval;
2463 	cmd->peer_ht_caps = param->peer_ht_caps;
2464 	cmd->peer_max_mpdu = param->peer_max_mpdu;
2465 	cmd->peer_mpdu_density = param->peer_mpdu_density;
2466 	cmd->peer_vht_caps = param->peer_vht_caps;
2467 	cmd->peer_phymode = param->peer_phymode;
2468 
2469 	/* Update 11ax capabilities */
2470 	cmd->peer_he_cap_info =
2471 		param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1];
2472 	cmd->peer_he_cap_info_ext =
2473 		param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2];
2474 	cmd->peer_he_ops = param->peer_he_ops;
2475 	qdf_mem_copy(&cmd->peer_he_cap_phy, &param->peer_he_cap_phyinfo,
2476 				sizeof(param->peer_he_cap_phyinfo));
2477 	qdf_mem_copy(&cmd->peer_ppet, &param->peer_ppet,
2478 				sizeof(param->peer_ppet));
2479 
2480 	/* Update peer legacy rate information */
2481 	buf_ptr += sizeof(*cmd);
2482 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
2483 				peer_legacy_rates_align);
2484 	buf_ptr += WMI_TLV_HDR_SIZE;
2485 	cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates;
2486 	qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates,
2487 		     param->peer_legacy_rates.num_rates);
2488 
2489 	/* Update peer HT rate information */
2490 	buf_ptr += peer_legacy_rates_align;
2491 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
2492 			  peer_ht_rates_align);
2493 	buf_ptr += WMI_TLV_HDR_SIZE;
2494 	cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates;
2495 	qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates,
2496 				 param->peer_ht_rates.num_rates);
2497 
2498 	/* VHT Rates */
2499 	buf_ptr += peer_ht_rates_align;
2500 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set,
2501 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set));
2502 
2503 	cmd->peer_nss = param->peer_nss;
2504 
2505 	/* Update bandwidth-NSS mapping */
2506 	cmd->peer_bw_rxnss_override = 0;
2507 	cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override;
2508 
2509 	mcs = (wmi_vht_rate_set *) buf_ptr;
2510 	if (param->vht_capable) {
2511 		mcs->rx_max_rate = param->rx_max_rate;
2512 		mcs->rx_mcs_set = param->rx_mcs_set;
2513 		mcs->tx_max_rate = param->tx_max_rate;
2514 		mcs->tx_mcs_set = param->tx_mcs_set;
2515 	}
2516 
2517 	/* HE Rates */
2518 	cmd->peer_he_mcs = param->peer_he_mcs_count;
2519 	buf_ptr += sizeof(wmi_vht_rate_set);
2520 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2521 		(param->peer_he_mcs_count * sizeof(wmi_he_rate_set)));
2522 	buf_ptr += WMI_TLV_HDR_SIZE;
2523 
2524 	/* Loop through the HE rate set */
2525 	for (i = 0; i < param->peer_he_mcs_count; i++) {
2526 		he_mcs = (wmi_he_rate_set *) buf_ptr;
2527 		WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set,
2528 			WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set));
2529 
2530 		he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i];
2531 		he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i];
2532 		WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__,
2533 			i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set);
2534 		buf_ptr += sizeof(wmi_he_rate_set);
2535 	}
2536 
2537 
2538 	WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x "
2539 		 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d "
2540 		 "nss %d phymode %d peer_mpdu_density %d "
2541 		 "cmd->peer_vht_caps %x "
2542 		 "HE cap_info %x ops %x "
2543 		 "HE cap_info_ext %x "
2544 		 "HE phy %x  %x  %x  "
2545 		 "peer_bw_rxnss_override %x", __func__,
2546 		 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags,
2547 		 cmd->peer_rate_caps, cmd->peer_caps,
2548 		 cmd->peer_listen_intval, cmd->peer_ht_caps,
2549 		 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode,
2550 		 cmd->peer_mpdu_density,
2551 		 cmd->peer_vht_caps, cmd->peer_he_cap_info,
2552 		 cmd->peer_he_ops, cmd->peer_he_cap_info_ext,
2553 		 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1],
2554 		 cmd->peer_he_cap_phy[2],
2555 		 cmd->peer_bw_rxnss_override);
2556 
2557 	wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0);
2558 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2559 				   WMI_PEER_ASSOC_CMDID);
2560 	if (QDF_IS_STATUS_ERROR(ret)) {
2561 		WMI_LOGP("%s: Failed to send peer assoc command ret = %d",
2562 			 __func__, ret);
2563 		wmi_buf_free(buf);
2564 	}
2565 
2566 	return ret;
2567 }
2568 
2569 /* copy_scan_notify_events() - Helper routine to copy scan notify events
2570  */
2571 static inline void copy_scan_event_cntrl_flags(
2572 		wmi_start_scan_cmd_fixed_param * cmd,
2573 		struct scan_req_params *param)
2574 {
2575 
2576 	/* Scan events subscription */
2577 	if (param->scan_ev_started)
2578 		cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED;
2579 	if (param->scan_ev_completed)
2580 		cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED;
2581 	if (param->scan_ev_bss_chan)
2582 		cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL;
2583 	if (param->scan_ev_foreign_chan)
2584 		cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL;
2585 	if (param->scan_ev_dequeued)
2586 		cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED;
2587 	if (param->scan_ev_preempted)
2588 		cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED;
2589 	if (param->scan_ev_start_failed)
2590 		cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED;
2591 	if (param->scan_ev_restarted)
2592 		cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED;
2593 	if (param->scan_ev_foreign_chn_exit)
2594 		cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT;
2595 	if (param->scan_ev_suspended)
2596 		cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED;
2597 	if (param->scan_ev_resumed)
2598 		cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED;
2599 
2600 	/** Set scan control flags */
2601 	cmd->scan_ctrl_flags = 0;
2602 	if (param->scan_f_passive)
2603 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
2604 	if (param->scan_f_strict_passive_pch)
2605 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN;
2606 	if (param->scan_f_promisc_mode)
2607 		cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS;
2608 	if (param->scan_f_capture_phy_err)
2609 		cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR;
2610 	if (param->scan_f_half_rate)
2611 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT;
2612 	if (param->scan_f_quarter_rate)
2613 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT;
2614 	if (param->scan_f_cck_rates)
2615 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES;
2616 	if (param->scan_f_ofdm_rates)
2617 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES;
2618 	if (param->scan_f_chan_stat_evnt)
2619 		cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT;
2620 	if (param->scan_f_filter_prb_req)
2621 		cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
2622 	if (param->scan_f_bcast_probe)
2623 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ;
2624 	if (param->scan_f_offchan_mgmt_tx)
2625 		cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX;
2626 	if (param->scan_f_offchan_data_tx)
2627 		cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX;
2628 	if (param->scan_f_force_active_dfs_chn)
2629 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS;
2630 	if (param->scan_f_add_tpc_ie_in_probe)
2631 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ;
2632 	if (param->scan_f_add_ds_ie_in_probe)
2633 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
2634 	if (param->scan_f_add_spoofed_mac_in_probe)
2635 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ;
2636 	if (param->scan_f_add_rand_seq_in_probe)
2637 		cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ;
2638 	if (param->scan_f_en_ie_whitelist_in_probe)
2639 		cmd->scan_ctrl_flags |=
2640 			WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ;
2641 
2642 	/* for adaptive scan mode using 3 bits (21 - 23 bits) */
2643 	WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags,
2644 		param->adaptive_dwell_time_mode);
2645 }
2646 
2647 /* scan_copy_ie_buffer() - Copy scan ie_data */
2648 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr,
2649 				struct scan_req_params *params)
2650 {
2651 	qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len);
2652 }
2653 
2654 /**
2655  * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer
2656  * @mac: random mac addr
2657  * @mask: random mac mask
2658  * @mac_addr: wmi random mac
2659  * @mac_mask: wmi random mac mask
2660  *
2661  * Return None.
2662  */
2663 static inline
2664 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask,
2665 			      wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask)
2666 {
2667 	WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr);
2668 	WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask);
2669 }
2670 
2671 /*
2672  * wmi_fill_vendor_oui() - fill vendor OUIs
2673  * @buf_ptr: pointer to wmi tlv buffer
2674  * @num_vendor_oui: number of vendor OUIs to be filled
2675  * @param_voui: pointer to OUI buffer
2676  *
2677  * This function populates the wmi tlv buffer when vendor specific OUIs are
2678  * present.
2679  *
2680  * Return: None
2681  */
2682 static inline
2683 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui,
2684 			 uint32_t *pvoui)
2685 {
2686 	wmi_vendor_oui *voui = NULL;
2687 	uint32_t i;
2688 
2689 	voui = (wmi_vendor_oui *)buf_ptr;
2690 
2691 	for (i = 0; i < num_vendor_oui; i++) {
2692 		WMITLV_SET_HDR(&voui[i].tlv_header,
2693 			       WMITLV_TAG_STRUC_wmi_vendor_oui,
2694 			       WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui));
2695 		voui[i].oui_type_subtype = pvoui[i];
2696 	}
2697 }
2698 
2699 /*
2700  * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs
2701  * @ie_bitmap: output pointer to ie bit map in cmd
2702  * @num_vendor_oui: output pointer to num vendor OUIs
2703  * @ie_whitelist: input parameter
2704  *
2705  * This function populates the IE whitelist attrs of scan, pno and
2706  * scan oui commands for ie_whitelist parameter.
2707  *
2708  * Return: None
2709  */
2710 static inline
2711 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap,
2712 				 uint32_t *num_vendor_oui,
2713 				 struct probe_req_whitelist_attr *ie_whitelist)
2714 {
2715 	uint32_t i = 0;
2716 
2717 	for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++)
2718 		ie_bitmap[i] = ie_whitelist->ie_bitmap[i];
2719 
2720 	*num_vendor_oui = ie_whitelist->num_vendor_oui;
2721 }
2722 
2723 /**
2724  *  send_scan_start_cmd_tlv() - WMI scan start function
2725  *  @param wmi_handle      : handle to WMI.
2726  *  @param param    : pointer to hold scan start cmd parameter
2727  *
2728  *  Return: 0  on success and -ve on failure.
2729  */
2730 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle,
2731 				struct scan_req_params *params)
2732 {
2733 	int32_t ret = 0;
2734 	int32_t i;
2735 	wmi_buf_t wmi_buf;
2736 	wmi_start_scan_cmd_fixed_param *cmd;
2737 	uint8_t *buf_ptr;
2738 	uint32_t *tmp_ptr;
2739 	wmi_ssid *ssid = NULL;
2740 	wmi_mac_addr *bssid;
2741 	int len = sizeof(*cmd);
2742 	uint8_t extraie_len_with_pad = 0;
2743 	uint8_t phymode_roundup = 0;
2744 	struct probe_req_whitelist_attr *ie_whitelist = &params->ie_whitelist;
2745 
2746 	/* Length TLV placeholder for array of uint32_t */
2747 	len += WMI_TLV_HDR_SIZE;
2748 	/* calculate the length of buffer required */
2749 	if (params->chan_list.num_chan)
2750 		len += params->chan_list.num_chan * sizeof(uint32_t);
2751 
2752 	/* Length TLV placeholder for array of wmi_ssid structures */
2753 	len += WMI_TLV_HDR_SIZE;
2754 	if (params->num_ssids)
2755 		len += params->num_ssids * sizeof(wmi_ssid);
2756 
2757 	/* Length TLV placeholder for array of wmi_mac_addr structures */
2758 	len += WMI_TLV_HDR_SIZE;
2759 	if (params->num_bssid)
2760 		len += sizeof(wmi_mac_addr) * params->num_bssid;
2761 
2762 	/* Length TLV placeholder for array of bytes */
2763 	len += WMI_TLV_HDR_SIZE;
2764 	if (params->extraie.len)
2765 		extraie_len_with_pad =
2766 		roundup(params->extraie.len, sizeof(uint32_t));
2767 	len += extraie_len_with_pad;
2768 
2769 	len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */
2770 	if (ie_whitelist->num_vendor_oui)
2771 		len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui);
2772 
2773 	len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */
2774 	if (params->scan_f_wide_band)
2775 		phymode_roundup =
2776 			qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t),
2777 					sizeof(uint32_t));
2778 	len += phymode_roundup;
2779 
2780 	/* Allocate the memory */
2781 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
2782 	if (!wmi_buf) {
2783 		WMI_LOGP("%s: failed to allocate memory for start scan cmd",
2784 			 __func__);
2785 		return QDF_STATUS_E_FAILURE;
2786 	}
2787 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
2788 	cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr;
2789 	WMITLV_SET_HDR(&cmd->tlv_header,
2790 		       WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
2791 		       WMITLV_GET_STRUCT_TLVLEN
2792 			       (wmi_start_scan_cmd_fixed_param));
2793 
2794 	cmd->scan_id = params->scan_id;
2795 	cmd->scan_req_id = params->scan_req_id;
2796 	cmd->vdev_id = params->vdev_id;
2797 	cmd->scan_priority = params->scan_priority;
2798 
2799 	copy_scan_event_cntrl_flags(cmd, params);
2800 
2801 	cmd->dwell_time_active = params->dwell_time_active;
2802 	cmd->dwell_time_active_2g = params->dwell_time_active_2g;
2803 	cmd->dwell_time_passive = params->dwell_time_passive;
2804 	cmd->min_rest_time = params->min_rest_time;
2805 	cmd->max_rest_time = params->max_rest_time;
2806 	cmd->repeat_probe_time = params->repeat_probe_time;
2807 	cmd->probe_spacing_time = params->probe_spacing_time;
2808 	cmd->idle_time = params->idle_time;
2809 	cmd->max_scan_time = params->max_scan_time;
2810 	cmd->probe_delay = params->probe_delay;
2811 	cmd->burst_duration = params->burst_duration;
2812 	cmd->num_chan = params->chan_list.num_chan;
2813 	cmd->num_bssid = params->num_bssid;
2814 	cmd->num_ssids = params->num_ssids;
2815 	cmd->ie_len = params->extraie.len;
2816 	cmd->n_probes = params->n_probes;
2817 	cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext;
2818 
2819 	WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext);
2820 
2821 	if (params->scan_random.randomize)
2822 		wmi_copy_scan_random_mac(params->scan_random.mac_addr,
2823 					 params->scan_random.mac_mask,
2824 					 &cmd->mac_addr,
2825 					 &cmd->mac_mask);
2826 
2827 	if (ie_whitelist->white_list)
2828 		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
2829 					    &cmd->num_vendor_oui,
2830 					    ie_whitelist);
2831 
2832 	buf_ptr += sizeof(*cmd);
2833 	tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
2834 	for (i = 0; i < params->chan_list.num_chan; ++i)
2835 		tmp_ptr[i] = params->chan_list.chan[i].freq;
2836 
2837 	WMITLV_SET_HDR(buf_ptr,
2838 		       WMITLV_TAG_ARRAY_UINT32,
2839 		       (params->chan_list.num_chan * sizeof(uint32_t)));
2840 	buf_ptr += WMI_TLV_HDR_SIZE +
2841 			(params->chan_list.num_chan * sizeof(uint32_t));
2842 
2843 	if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) {
2844 		WMI_LOGE("Invalid value for numSsid");
2845 		goto error;
2846 	}
2847 
2848 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
2849 	       (params->num_ssids * sizeof(wmi_ssid)));
2850 
2851 	if (params->num_ssids) {
2852 		ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE);
2853 		for (i = 0; i < params->num_ssids; ++i) {
2854 			ssid->ssid_len = params->ssid[i].length;
2855 			qdf_mem_copy(ssid->ssid, params->ssid[i].ssid,
2856 				     params->ssid[i].length);
2857 			ssid++;
2858 		}
2859 	}
2860 	buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid));
2861 
2862 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
2863 		       (params->num_bssid * sizeof(wmi_mac_addr)));
2864 	bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE);
2865 
2866 	if (params->num_bssid) {
2867 		for (i = 0; i < params->num_bssid; ++i) {
2868 			WMI_CHAR_ARRAY_TO_MAC_ADDR(
2869 				&params->bssid_list[i].bytes[0], bssid);
2870 			bssid++;
2871 		}
2872 	}
2873 
2874 	buf_ptr += WMI_TLV_HDR_SIZE +
2875 		(params->num_bssid * sizeof(wmi_mac_addr));
2876 
2877 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad);
2878 	if (params->extraie.len)
2879 		scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE,
2880 			     params);
2881 
2882 	buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad;
2883 
2884 	/* probe req ie whitelisting */
2885 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2886 		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
2887 
2888 	buf_ptr += WMI_TLV_HDR_SIZE;
2889 
2890 	if (cmd->num_vendor_oui) {
2891 		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
2892 				    ie_whitelist->voui);
2893 		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
2894 	}
2895 
2896 	/* Add phy mode TLV if it's a wide band scan */
2897 	if (params->scan_f_wide_band) {
2898 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup);
2899 		buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
2900 		for (i = 0; i < params->chan_list.num_chan; ++i)
2901 			buf_ptr[i] =
2902 				WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode);
2903 		buf_ptr += phymode_roundup;
2904 	} else {
2905 		/* Add ZERO legth phy mode TLV */
2906 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0);
2907 	}
2908 
2909 	wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0);
2910 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf,
2911 				   len, WMI_START_SCAN_CMDID);
2912 	if (ret) {
2913 		WMI_LOGE("%s: Failed to start scan: %d", __func__, ret);
2914 		wmi_buf_free(wmi_buf);
2915 	}
2916 	return ret;
2917 error:
2918 	wmi_buf_free(wmi_buf);
2919 	return QDF_STATUS_E_FAILURE;
2920 }
2921 
2922 /**
2923  *  send_scan_stop_cmd_tlv() - WMI scan start function
2924  *  @param wmi_handle      : handle to WMI.
2925  *  @param param    : pointer to hold scan cancel cmd parameter
2926  *
2927  *  Return: 0  on success and -ve on failure.
2928  */
2929 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle,
2930 				struct scan_cancel_param *param)
2931 {
2932 	wmi_stop_scan_cmd_fixed_param *cmd;
2933 	int ret;
2934 	int len = sizeof(*cmd);
2935 	wmi_buf_t wmi_buf;
2936 
2937 	/* Allocate the memory */
2938 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
2939 	if (!wmi_buf) {
2940 		WMI_LOGP("%s: failed to allocate memory for stop scan cmd",
2941 			 __func__);
2942 		ret = QDF_STATUS_E_NOMEM;
2943 		goto error;
2944 	}
2945 
2946 	cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf);
2947 	WMITLV_SET_HDR(&cmd->tlv_header,
2948 		       WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param,
2949 		       WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param));
2950 	cmd->vdev_id = param->vdev_id;
2951 	cmd->requestor = param->requester;
2952 	cmd->scan_id = param->scan_id;
2953 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
2954 								param->pdev_id);
2955 	/* stop the scan with the corresponding scan_id */
2956 	if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) {
2957 		/* Cancelling all scans */
2958 		cmd->req_type = WMI_SCAN_STOP_ALL;
2959 	} else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) {
2960 		/* Cancelling VAP scans */
2961 		cmd->req_type = WMI_SCN_STOP_VAP_ALL;
2962 	} else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) {
2963 		/* Cancelling specific scan */
2964 		cmd->req_type = WMI_SCAN_STOP_ONE;
2965 	} else {
2966 		WMI_LOGE("%s: Invalid Command : ", __func__);
2967 		wmi_buf_free(wmi_buf);
2968 		return QDF_STATUS_E_INVAL;
2969 	}
2970 
2971 	wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0);
2972 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf,
2973 				   len, WMI_STOP_SCAN_CMDID);
2974 	if (ret) {
2975 		WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret);
2976 		wmi_buf_free(wmi_buf);
2977 	}
2978 
2979 error:
2980 	return ret;
2981 }
2982 
2983 #ifdef CONFIG_MCL
2984 /**
2985  *  send_scan_chan_list_cmd_tlv() - WMI scan channel list function
2986  *  @param wmi_handle      : handle to WMI.
2987  *  @param param    : pointer to hold scan channel list parameter
2988  *
2989  *  Return: 0  on success and -ve on failure.
2990  */
2991 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
2992 				struct scan_chan_list_params *chan_list)
2993 {
2994 	wmi_buf_t buf;
2995 	QDF_STATUS qdf_status;
2996 	wmi_scan_chan_list_cmd_fixed_param *cmd;
2997 	int i;
2998 	uint8_t *buf_ptr;
2999 	wmi_channel_param *chan_info, *tchan_info;
3000 	uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
3001 
3002 	len += sizeof(wmi_channel) * chan_list->num_scan_chans;
3003 	buf = wmi_buf_alloc(wmi_handle, len);
3004 	if (!buf) {
3005 		WMI_LOGE("Failed to allocate memory");
3006 		qdf_status = QDF_STATUS_E_NOMEM;
3007 		goto end;
3008 	}
3009 
3010 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3011 	cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr;
3012 	WMITLV_SET_HDR(&cmd->tlv_header,
3013 		       WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param,
3014 		       WMITLV_GET_STRUCT_TLVLEN
3015 			       (wmi_scan_chan_list_cmd_fixed_param));
3016 
3017 	WMI_LOGD("no of channels = %d, len = %d", chan_list->num_scan_chans, len);
3018 
3019 	cmd->num_scan_chans = chan_list->num_scan_chans;
3020 	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)),
3021 		       WMITLV_TAG_ARRAY_STRUC,
3022 		       sizeof(wmi_channel) * chan_list->num_scan_chans);
3023 	chan_info = (wmi_channel_param *)
3024 			(buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE);
3025 	tchan_info = chan_list->chan_info;
3026 
3027 	for (i = 0; i < chan_list->num_scan_chans; ++i) {
3028 		WMITLV_SET_HDR(&chan_info->tlv_header,
3029 			       WMITLV_TAG_STRUC_wmi_channel,
3030 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
3031 		chan_info->mhz = tchan_info->mhz;
3032 		chan_info->band_center_freq1 =
3033 				 tchan_info->band_center_freq1;
3034 		chan_info->band_center_freq2 =
3035 				tchan_info->band_center_freq2;
3036 		chan_info->info = tchan_info->info;
3037 		chan_info->reg_info_1 = tchan_info->reg_info_1;
3038 		chan_info->reg_info_2 = tchan_info->reg_info_2;
3039 		WMI_LOGD("chan[%d] = %u", i, chan_info->mhz);
3040 
3041 		/*TODO: Set WMI_SET_CHANNEL_MIN_POWER */
3042 		/*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */
3043 		/*TODO: WMI_SET_CHANNEL_REG_CLASSID */
3044 		tchan_info++;
3045 		chan_info++;
3046 	}
3047 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
3048 							chan_list->pdev_id);
3049 
3050 	wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, NO_SESSION, 0);
3051 	qdf_status = wmi_unified_cmd_send(wmi_handle,
3052 			buf, len, WMI_SCAN_CHAN_LIST_CMDID);
3053 
3054 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
3055 		WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
3056 		wmi_buf_free(buf);
3057 	}
3058 
3059 end:
3060 	return qdf_status;
3061 }
3062 #else
3063 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
3064 				struct scan_chan_list_params *chan_list)
3065 {
3066 	wmi_buf_t buf;
3067 	QDF_STATUS qdf_status;
3068 	wmi_scan_chan_list_cmd_fixed_param *cmd;
3069 	int i;
3070 	uint8_t *buf_ptr;
3071 	wmi_channel *chan_info;
3072 	struct channel_param *tchan_info;
3073 	uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
3074 
3075 	len += sizeof(wmi_channel) * chan_list->nallchans;
3076 	buf = wmi_buf_alloc(wmi_handle, len);
3077 	if (!buf) {
3078 		WMI_LOGE("Failed to allocate memory");
3079 		qdf_status = QDF_STATUS_E_NOMEM;
3080 		goto end;
3081 	}
3082 
3083 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3084 	cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr;
3085 	WMITLV_SET_HDR(&cmd->tlv_header,
3086 		       WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param,
3087 		       WMITLV_GET_STRUCT_TLVLEN
3088 			       (wmi_scan_chan_list_cmd_fixed_param));
3089 
3090 	WMI_LOGD("no of channels = %d, len = %d", chan_list->nallchans, len);
3091 
3092 	if (chan_list->append)
3093 		cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST;
3094 
3095 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
3096 							chan_list->pdev_id);
3097 	cmd->num_scan_chans = chan_list->nallchans;
3098 	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)),
3099 		       WMITLV_TAG_ARRAY_STRUC,
3100 		       sizeof(wmi_channel) * chan_list->nallchans);
3101 	chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE);
3102 	tchan_info = &(chan_list->ch_param[0]);
3103 
3104 	for (i = 0; i < chan_list->nallchans; ++i) {
3105 		WMITLV_SET_HDR(&chan_info->tlv_header,
3106 			       WMITLV_TAG_STRUC_wmi_channel,
3107 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
3108 		chan_info->mhz = tchan_info->mhz;
3109 		chan_info->band_center_freq1 =
3110 				 tchan_info->cfreq1;
3111 		chan_info->band_center_freq2 =
3112 				tchan_info->cfreq2;
3113 
3114 		if (tchan_info->is_chan_passive)
3115 			WMI_SET_CHANNEL_FLAG(chan_info,
3116 					WMI_CHAN_FLAG_PASSIVE);
3117 
3118 		if (tchan_info->allow_vht)
3119 			WMI_SET_CHANNEL_FLAG(chan_info,
3120 					WMI_CHAN_FLAG_ALLOW_VHT);
3121 		else  if (tchan_info->allow_ht)
3122 			WMI_SET_CHANNEL_FLAG(chan_info,
3123 					WMI_CHAN_FLAG_ALLOW_HT);
3124 		WMI_SET_CHANNEL_MODE(chan_info,
3125 				tchan_info->phy_mode);
3126 
3127 		if (tchan_info->half_rate)
3128 			WMI_SET_CHANNEL_FLAG(chan_info,
3129 					WMI_CHAN_FLAG_HALF_RATE);
3130 
3131 		if (tchan_info->quarter_rate)
3132 			WMI_SET_CHANNEL_FLAG(chan_info,
3133 					WMI_CHAN_FLAG_QUARTER_RATE);
3134 
3135 		/* also fill in power information */
3136 		WMI_SET_CHANNEL_MIN_POWER(chan_info,
3137 				tchan_info->minpower);
3138 		WMI_SET_CHANNEL_MAX_POWER(chan_info,
3139 				tchan_info->maxpower);
3140 		WMI_SET_CHANNEL_REG_POWER(chan_info,
3141 				tchan_info->maxregpower);
3142 		WMI_SET_CHANNEL_ANTENNA_MAX(chan_info,
3143 				tchan_info->antennamax);
3144 		WMI_SET_CHANNEL_REG_CLASSID(chan_info,
3145 				tchan_info->reg_class_id);
3146 		WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
3147 				tchan_info->maxregpower);
3148 
3149 		WMI_LOGD("chan[%d] = %u", i, chan_info->mhz);
3150 
3151 		tchan_info++;
3152 		chan_info++;
3153 	}
3154 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
3155 							chan_list->pdev_id);
3156 
3157 	wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0);
3158 	qdf_status = wmi_unified_cmd_send(
3159 			wmi_handle,
3160 			buf, len, WMI_SCAN_CHAN_LIST_CMDID);
3161 
3162 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
3163 		WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
3164 		wmi_buf_free(buf);
3165 	}
3166 
3167 end:
3168 	return qdf_status;
3169 }
3170 #endif
3171 
3172 /**
3173  * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx
3174  *
3175  * @bufp: Pointer to buffer
3176  * @param: Pointer to tx param
3177  *
3178  * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure
3179  */
3180 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp,
3181 					 struct tx_send_params param)
3182 {
3183 	wmi_tx_send_params *tx_param;
3184 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3185 
3186 	if (!bufp) {
3187 		status = QDF_STATUS_E_FAILURE;
3188 		return status;
3189 	}
3190 	tx_param = (wmi_tx_send_params *)bufp;
3191 	WMITLV_SET_HDR(&tx_param->tlv_header,
3192 		       WMITLV_TAG_STRUC_wmi_tx_send_params,
3193 		       WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params));
3194 	WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr);
3195 	WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0,
3196 				       param.mcs_mask);
3197 	WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0,
3198 				       param.nss_mask);
3199 	WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0,
3200 					  param.retry_limit);
3201 	WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1,
3202 					 param.chain_mask);
3203 	WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1,
3204 				      param.bw_mask);
3205 	WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1,
3206 				       param.preamble_type);
3207 	WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1,
3208 					 param.frame_type);
3209 
3210 	return status;
3211 }
3212 
3213 #ifdef CONFIG_HL_SUPPORT
3214 /**
3215  *  send_mgmt_cmd_tlv() - WMI scan start function
3216  *  @wmi_handle      : handle to WMI.
3217  *  @param    : pointer to hold mgmt cmd parameter
3218  *
3219  *  Return: 0  on success and -ve on failure.
3220  */
3221 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
3222 				struct wmi_mgmt_params *param)
3223 {
3224 	wmi_buf_t buf;
3225 	uint8_t *bufp;
3226 	int32_t cmd_len;
3227 	wmi_mgmt_tx_send_cmd_fixed_param *cmd;
3228 	int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len :
3229 		mgmt_tx_dl_frm_len;
3230 
3231 	if (param->frm_len > mgmt_tx_dl_frm_len) {
3232 		WMI_LOGE("%s:mgmt frame len %u exceeds %u",
3233 			 __func__, param->frm_len, mgmt_tx_dl_frm_len);
3234 		return QDF_STATUS_E_INVAL;
3235 	}
3236 
3237 	cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) +
3238 		  WMI_TLV_HDR_SIZE +
3239 		  roundup(bufp_len, sizeof(uint32_t));
3240 
3241 	buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len);
3242 	if (!buf) {
3243 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3244 		return QDF_STATUS_E_NOMEM;
3245 	}
3246 
3247 	cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf);
3248 	bufp = (uint8_t *) cmd;
3249 	WMITLV_SET_HDR(&cmd->tlv_header,
3250 		WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param,
3251 		WMITLV_GET_STRUCT_TLVLEN
3252 		(wmi_mgmt_tx_send_cmd_fixed_param));
3253 
3254 	cmd->vdev_id = param->vdev_id;
3255 
3256 	cmd->desc_id = param->desc_id;
3257 	cmd->chanfreq = param->chanfreq;
3258 	bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param);
3259 	WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
3260 							    sizeof(uint32_t)));
3261 	bufp += WMI_TLV_HDR_SIZE;
3262 	qdf_mem_copy(bufp, param->pdata, bufp_len);
3263 
3264 	cmd->frame_len = param->frm_len;
3265 	cmd->buf_len = bufp_len;
3266 	cmd->tx_params_valid = param->tx_params_valid;
3267 
3268 	wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID,
3269 			bufp, cmd->vdev_id, cmd->chanfreq);
3270 
3271 	bufp += roundup(bufp_len, sizeof(uint32_t));
3272 	if (param->tx_params_valid) {
3273 		if (populate_tx_send_params(bufp, param->tx_param) !=
3274 		    QDF_STATUS_SUCCESS) {
3275 			WMI_LOGE("%s: Populate TX send params failed",
3276 				 __func__);
3277 			goto free_buf;
3278 		}
3279 		cmd_len += sizeof(wmi_tx_send_params);
3280 	}
3281 
3282 	wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0);
3283 	if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
3284 				      WMI_MGMT_TX_SEND_CMDID)) {
3285 		WMI_LOGE("%s: Failed to send mgmt Tx", __func__);
3286 		goto free_buf;
3287 	}
3288 	return QDF_STATUS_SUCCESS;
3289 
3290 free_buf:
3291 	wmi_buf_free(buf);
3292 	return QDF_STATUS_E_FAILURE;
3293 }
3294 #else
3295 /**
3296  *  send_mgmt_cmd_tlv() - WMI scan start function
3297  *  @wmi_handle      : handle to WMI.
3298  *  @param    : pointer to hold mgmt cmd parameter
3299  *
3300  *  Return: 0  on success and -ve on failure.
3301  */
3302 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
3303 				struct wmi_mgmt_params *param)
3304 {
3305 	wmi_buf_t buf;
3306 	wmi_mgmt_tx_send_cmd_fixed_param *cmd;
3307 	int32_t cmd_len;
3308 	uint64_t dma_addr;
3309 	void *qdf_ctx = param->qdf_ctx;
3310 	uint8_t *bufp;
3311 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3312 	int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len :
3313 		mgmt_tx_dl_frm_len;
3314 
3315 	cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) +
3316 		  WMI_TLV_HDR_SIZE +
3317 		  roundup(bufp_len, sizeof(uint32_t));
3318 
3319 	buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len);
3320 	if (!buf) {
3321 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3322 		return QDF_STATUS_E_NOMEM;
3323 	}
3324 
3325 	cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf);
3326 	bufp = (uint8_t *) cmd;
3327 	WMITLV_SET_HDR(&cmd->tlv_header,
3328 		WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param,
3329 		WMITLV_GET_STRUCT_TLVLEN
3330 		(wmi_mgmt_tx_send_cmd_fixed_param));
3331 
3332 	cmd->vdev_id = param->vdev_id;
3333 
3334 	cmd->desc_id = param->desc_id;
3335 	cmd->chanfreq = param->chanfreq;
3336 	bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param);
3337 	WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
3338 							    sizeof(uint32_t)));
3339 	bufp += WMI_TLV_HDR_SIZE;
3340 	qdf_mem_copy(bufp, param->pdata, bufp_len);
3341 
3342 	status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame,
3343 				     QDF_DMA_TO_DEVICE);
3344 	if (status != QDF_STATUS_SUCCESS) {
3345 		WMI_LOGE("%s: wmi buf map failed", __func__);
3346 		goto free_buf;
3347 	}
3348 
3349 	dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0);
3350 	cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff);
3351 #if defined(HTT_PADDR64)
3352 	cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F);
3353 #endif
3354 	cmd->frame_len = param->frm_len;
3355 	cmd->buf_len = bufp_len;
3356 	cmd->tx_params_valid = param->tx_params_valid;
3357 
3358 	wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID,
3359 			bufp, cmd->vdev_id, cmd->chanfreq);
3360 
3361 	bufp += roundup(bufp_len, sizeof(uint32_t));
3362 	if (param->tx_params_valid) {
3363 		status = populate_tx_send_params(bufp, param->tx_param);
3364 		if (status != QDF_STATUS_SUCCESS) {
3365 			WMI_LOGE("%s: Populate TX send params failed",
3366 				 __func__);
3367 			goto unmap_tx_frame;
3368 		}
3369 		cmd_len += sizeof(wmi_tx_send_params);
3370 	}
3371 
3372 	wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0);
3373 	if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
3374 				      WMI_MGMT_TX_SEND_CMDID)) {
3375 		WMI_LOGE("%s: Failed to send mgmt Tx", __func__);
3376 		goto unmap_tx_frame;
3377 	}
3378 	return QDF_STATUS_SUCCESS;
3379 
3380 unmap_tx_frame:
3381 	qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame,
3382 				     QDF_DMA_TO_DEVICE);
3383 free_buf:
3384 	wmi_buf_free(buf);
3385 	return QDF_STATUS_E_FAILURE;
3386 }
3387 #endif /* CONFIG_HL_SUPPORT */
3388 
3389 /**
3390  *  send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data
3391  *  @wmi_handle      : handle to WMI.
3392  *  @param    : pointer to offchan data tx cmd parameter
3393  *
3394  *  Return: QDF_STATUS_SUCCESS  on success and error on failure.
3395  */
3396 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle,
3397 				struct wmi_offchan_data_tx_params *param)
3398 {
3399 	wmi_buf_t buf;
3400 	wmi_offchan_data_tx_send_cmd_fixed_param *cmd;
3401 	int32_t cmd_len;
3402 	uint64_t dma_addr;
3403 	void *qdf_ctx = param->qdf_ctx;
3404 	uint8_t *bufp;
3405 	int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ?
3406 					param->frm_len : mgmt_tx_dl_frm_len;
3407 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3408 
3409 	cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) +
3410 		  WMI_TLV_HDR_SIZE +
3411 		  roundup(bufp_len, sizeof(uint32_t));
3412 
3413 	buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len);
3414 	if (!buf) {
3415 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3416 		return QDF_STATUS_E_NOMEM;
3417 	}
3418 
3419 	cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf);
3420 	bufp = (uint8_t *) cmd;
3421 	WMITLV_SET_HDR(&cmd->tlv_header,
3422 		WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param,
3423 		WMITLV_GET_STRUCT_TLVLEN
3424 		(wmi_offchan_data_tx_send_cmd_fixed_param));
3425 
3426 	cmd->vdev_id = param->vdev_id;
3427 
3428 	cmd->desc_id = param->desc_id;
3429 	cmd->chanfreq = param->chanfreq;
3430 	bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param);
3431 	WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
3432 							    sizeof(uint32_t)));
3433 	bufp += WMI_TLV_HDR_SIZE;
3434 	qdf_mem_copy(bufp, param->pdata, bufp_len);
3435 	qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE);
3436 	dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0);
3437 	cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff);
3438 #if defined(HTT_PADDR64)
3439 	cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F);
3440 #endif
3441 	cmd->frame_len = param->frm_len;
3442 	cmd->buf_len = bufp_len;
3443 	cmd->tx_params_valid = param->tx_params_valid;
3444 
3445 	wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID,
3446 			bufp, cmd->vdev_id, cmd->chanfreq);
3447 
3448 	bufp += roundup(bufp_len, sizeof(uint32_t));
3449 	if (param->tx_params_valid) {
3450 		status = populate_tx_send_params(bufp, param->tx_param);
3451 		if (status != QDF_STATUS_SUCCESS) {
3452 			WMI_LOGE("%s: Populate TX send params failed",
3453 				 __func__);
3454 			goto err1;
3455 		}
3456 		cmd_len += sizeof(wmi_tx_send_params);
3457 	}
3458 
3459 	wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0);
3460 	if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
3461 				WMI_OFFCHAN_DATA_TX_SEND_CMDID)) {
3462 		WMI_LOGE("%s: Failed to offchan data Tx", __func__);
3463 		goto err1;
3464 	}
3465 
3466 	return QDF_STATUS_SUCCESS;
3467 
3468 err1:
3469 	wmi_buf_free(buf);
3470 	return QDF_STATUS_E_FAILURE;
3471 }
3472 
3473 /**
3474  * send_modem_power_state_cmd_tlv() - set modem power state to fw
3475  * @wmi_handle: wmi handle
3476  * @param_value: parameter value
3477  *
3478  * Return: QDF_STATUS_SUCCESS for success or error code
3479  */
3480 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle,
3481 		uint32_t param_value)
3482 {
3483 	QDF_STATUS ret;
3484 	wmi_modem_power_state_cmd_param *cmd;
3485 	wmi_buf_t buf;
3486 	uint16_t len = sizeof(*cmd);
3487 
3488 	buf = wmi_buf_alloc(wmi_handle, len);
3489 	if (!buf) {
3490 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3491 		return QDF_STATUS_E_NOMEM;
3492 	}
3493 	cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf);
3494 	WMITLV_SET_HDR(&cmd->tlv_header,
3495 		       WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param,
3496 		       WMITLV_GET_STRUCT_TLVLEN
3497 			       (wmi_modem_power_state_cmd_param));
3498 	cmd->modem_power_state = param_value;
3499 	WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__,
3500 		 param_value);
3501 	wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0);
3502 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3503 				     WMI_MODEM_POWER_STATE_CMDID);
3504 	if (QDF_IS_STATUS_ERROR(ret)) {
3505 		WMI_LOGE("Failed to send notify cmd ret = %d", ret);
3506 		wmi_buf_free(buf);
3507 	}
3508 
3509 	return ret;
3510 }
3511 
3512 /**
3513  * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw
3514  * @wmi_handle: wmi handle
3515  * @vdev_id: vdev id
3516  * @val: value
3517  *
3518  * Return: QDF_STATUS_SUCCESS for success or error code.
3519  */
3520 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle,
3521 			       uint32_t vdev_id, uint8_t val)
3522 {
3523 	wmi_sta_powersave_mode_cmd_fixed_param *cmd;
3524 	wmi_buf_t buf;
3525 	int32_t len = sizeof(*cmd);
3526 
3527 	WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val);
3528 
3529 	buf = wmi_buf_alloc(wmi_handle, len);
3530 	if (!buf) {
3531 		WMI_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__);
3532 		return QDF_STATUS_E_NOMEM;
3533 	}
3534 	cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf);
3535 	WMITLV_SET_HDR(&cmd->tlv_header,
3536 		       WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param,
3537 		       WMITLV_GET_STRUCT_TLVLEN
3538 			       (wmi_sta_powersave_mode_cmd_fixed_param));
3539 	cmd->vdev_id = vdev_id;
3540 	if (val)
3541 		cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED;
3542 	else
3543 		cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED;
3544 
3545 	wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0);
3546 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
3547 				 WMI_STA_POWERSAVE_MODE_CMDID)) {
3548 		WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d",
3549 			 vdev_id, val);
3550 		wmi_buf_free(buf);
3551 		return QDF_STATUS_E_FAILURE;
3552 	}
3553 	return 0;
3554 }
3555 
3556 /**
3557  * send_set_mimops_cmd_tlv() - set MIMO powersave
3558  * @wmi_handle: wmi handle
3559  * @vdev_id: vdev id
3560  * @value: value
3561  *
3562  * Return: QDF_STATUS_SUCCESS for success or error code.
3563  */
3564 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle,
3565 			uint8_t vdev_id, int value)
3566 {
3567 	QDF_STATUS ret;
3568 	wmi_sta_smps_force_mode_cmd_fixed_param *cmd;
3569 	wmi_buf_t buf;
3570 	uint16_t len = sizeof(*cmd);
3571 
3572 	buf = wmi_buf_alloc(wmi_handle, len);
3573 	if (!buf) {
3574 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3575 		return QDF_STATUS_E_NOMEM;
3576 	}
3577 	cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf);
3578 	WMITLV_SET_HDR(&cmd->tlv_header,
3579 		       WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param,
3580 		       WMITLV_GET_STRUCT_TLVLEN
3581 			       (wmi_sta_smps_force_mode_cmd_fixed_param));
3582 
3583 	cmd->vdev_id = vdev_id;
3584 
3585 	/* WMI_SMPS_FORCED_MODE values do not directly map
3586 	 * to SM power save values defined in the specification.
3587 	 * Make sure to send the right mapping.
3588 	 */
3589 	switch (value) {
3590 	case 0:
3591 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE;
3592 		break;
3593 	case 1:
3594 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED;
3595 		break;
3596 	case 2:
3597 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC;
3598 		break;
3599 	case 3:
3600 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC;
3601 		break;
3602 	default:
3603 		WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__);
3604 		wmi_buf_free(buf);
3605 		return QDF_STATUS_E_FAILURE;
3606 	}
3607 
3608 	WMI_LOGD("Setting vdev %d value = %u", vdev_id, value);
3609 
3610 	wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0);
3611 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3612 				   WMI_STA_SMPS_FORCE_MODE_CMDID);
3613 	if (QDF_IS_STATUS_ERROR(ret)) {
3614 		WMI_LOGE("Failed to send set Mimo PS ret = %d", ret);
3615 		wmi_buf_free(buf);
3616 	}
3617 
3618 	return ret;
3619 }
3620 
3621 /**
3622  * send_set_smps_params_cmd_tlv() - set smps params
3623  * @wmi_handle: wmi handle
3624  * @vdev_id: vdev id
3625  * @value: value
3626  *
3627  * Return: QDF_STATUS_SUCCESS for success or error code.
3628  */
3629 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
3630 			       int value)
3631 {
3632 	QDF_STATUS ret;
3633 	wmi_sta_smps_param_cmd_fixed_param *cmd;
3634 	wmi_buf_t buf;
3635 	uint16_t len = sizeof(*cmd);
3636 
3637 	buf = wmi_buf_alloc(wmi_handle, len);
3638 	if (!buf) {
3639 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3640 		return QDF_STATUS_E_NOMEM;
3641 	}
3642 	cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf);
3643 	WMITLV_SET_HDR(&cmd->tlv_header,
3644 		       WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param,
3645 		       WMITLV_GET_STRUCT_TLVLEN
3646 			       (wmi_sta_smps_param_cmd_fixed_param));
3647 
3648 	cmd->vdev_id = vdev_id;
3649 	cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS;
3650 	cmd->param =
3651 		(value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS;
3652 
3653 	WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value,
3654 		 cmd->param);
3655 
3656 	wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0);
3657 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3658 				   WMI_STA_SMPS_PARAM_CMDID);
3659 	if (QDF_IS_STATUS_ERROR(ret)) {
3660 		WMI_LOGE("Failed to send set Mimo PS ret = %d", ret);
3661 		wmi_buf_free(buf);
3662 	}
3663 
3664 	return ret;
3665 }
3666 
3667 /**
3668  * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw
3669  * @wmi_handle: wmi handle
3670  * @noa: p2p power save parameters
3671  *
3672  * Return: CDF status
3673  */
3674 static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle,
3675 			struct p2p_ps_params *noa)
3676 {
3677 	wmi_p2p_set_noa_cmd_fixed_param *cmd;
3678 	wmi_p2p_noa_descriptor *noa_discriptor;
3679 	wmi_buf_t buf;
3680 	uint8_t *buf_ptr;
3681 	uint16_t len;
3682 	QDF_STATUS status;
3683 	uint32_t duration;
3684 
3685 	WMI_LOGD("%s: Enter", __func__);
3686 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor);
3687 	buf = wmi_buf_alloc(wmi_handle, len);
3688 	if (!buf) {
3689 		WMI_LOGE("Failed to allocate memory");
3690 		status = QDF_STATUS_E_FAILURE;
3691 		goto end;
3692 	}
3693 
3694 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3695 	cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr;
3696 	WMITLV_SET_HDR(&cmd->tlv_header,
3697 		       WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param,
3698 		       WMITLV_GET_STRUCT_TLVLEN
3699 			       (wmi_p2p_set_noa_cmd_fixed_param));
3700 	duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration;
3701 	cmd->vdev_id = noa->session_id;
3702 	cmd->enable = (duration) ? true : false;
3703 	cmd->num_noa = 1;
3704 
3705 	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)),
3706 		       WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor));
3707 	noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr +
3708 						     sizeof
3709 						     (wmi_p2p_set_noa_cmd_fixed_param)
3710 						     + WMI_TLV_HDR_SIZE);
3711 	WMITLV_SET_HDR(&noa_discriptor->tlv_header,
3712 		       WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor,
3713 		       WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor));
3714 	noa_discriptor->type_count = noa->count;
3715 	noa_discriptor->duration = duration;
3716 	noa_discriptor->interval = noa->interval;
3717 	noa_discriptor->start_time = 0;
3718 
3719 	WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d",
3720 		 cmd->vdev_id, noa->count, noa_discriptor->duration,
3721 		 noa->interval);
3722 	wmi_mtrace(WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID, cmd->vdev_id, 0);
3723 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
3724 				      WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID);
3725 	if (QDF_IS_STATUS_ERROR(status)) {
3726 		WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID");
3727 		wmi_buf_free(buf);
3728 	}
3729 
3730 end:
3731 	WMI_LOGD("%s: Exit", __func__);
3732 	return status;
3733 }
3734 
3735 
3736 /**
3737  * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw
3738  * @wmi_handle: wmi handle
3739  * @noa: p2p opp power save parameters
3740  *
3741  * Return: CDF status
3742  */
3743 static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle,
3744 		struct p2p_ps_params *oppps)
3745 {
3746 	wmi_p2p_set_oppps_cmd_fixed_param *cmd;
3747 	wmi_buf_t buf;
3748 	QDF_STATUS status;
3749 
3750 	WMI_LOGD("%s: Enter", __func__);
3751 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
3752 	if (!buf) {
3753 		WMI_LOGE("Failed to allocate memory");
3754 		status = QDF_STATUS_E_FAILURE;
3755 		goto end;
3756 	}
3757 
3758 	cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf);
3759 	WMITLV_SET_HDR(&cmd->tlv_header,
3760 		       WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param,
3761 		       WMITLV_GET_STRUCT_TLVLEN
3762 			       (wmi_p2p_set_oppps_cmd_fixed_param));
3763 	cmd->vdev_id = oppps->session_id;
3764 	if (oppps->ctwindow)
3765 		WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd);
3766 
3767 	WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow);
3768 	WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d",
3769 		 cmd->vdev_id, oppps->ctwindow);
3770 	wmi_mtrace(WMI_P2P_SET_OPPPS_PARAM_CMDID, cmd->vdev_id, 0);
3771 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
3772 				      WMI_P2P_SET_OPPPS_PARAM_CMDID);
3773 	if (QDF_IS_STATUS_ERROR(status)) {
3774 		WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID");
3775 		wmi_buf_free(buf);
3776 	}
3777 
3778 end:
3779 	WMI_LOGD("%s: Exit", __func__);
3780 	return status;
3781 }
3782 
3783 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
3784 /**
3785  * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw
3786  * @wmi_handle: wmi handle
3787  * @param: p2p listen offload start parameters
3788  *
3789  * Return: QDF status
3790  */
3791 static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle,
3792 	struct p2p_lo_start *param)
3793 {
3794 	wmi_buf_t buf;
3795 	wmi_p2p_lo_start_cmd_fixed_param *cmd;
3796 	int32_t len = sizeof(*cmd);
3797 	uint8_t *buf_ptr;
3798 	QDF_STATUS status;
3799 	int device_types_len_aligned;
3800 	int probe_resp_len_aligned;
3801 
3802 	if (!param) {
3803 		WMI_LOGE("lo start param is null");
3804 		return QDF_STATUS_E_INVAL;
3805 	}
3806 
3807 	WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id);
3808 
3809 	device_types_len_aligned =
3810 		qdf_roundup(param->dev_types_len,
3811 			sizeof(uint32_t));
3812 	probe_resp_len_aligned =
3813 		qdf_roundup(param->probe_resp_len,
3814 			sizeof(uint32_t));
3815 
3816 	len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned +
3817 			probe_resp_len_aligned;
3818 
3819 	buf = wmi_buf_alloc(wmi_handle, len);
3820 	if (!buf) {
3821 		WMI_LOGE("%s: Failed to allocate memory for p2p lo start",
3822 			__func__);
3823 		return QDF_STATUS_E_NOMEM;
3824 	}
3825 
3826 	cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf);
3827 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3828 
3829 	WMITLV_SET_HDR(&cmd->tlv_header,
3830 		 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param,
3831 		 WMITLV_GET_STRUCT_TLVLEN(
3832 			wmi_p2p_lo_start_cmd_fixed_param));
3833 
3834 	cmd->vdev_id = param->vdev_id;
3835 	cmd->ctl_flags = param->ctl_flags;
3836 	cmd->channel = param->freq;
3837 	cmd->period = param->period;
3838 	cmd->interval = param->interval;
3839 	cmd->count = param->count;
3840 	cmd->device_types_len = param->dev_types_len;
3841 	cmd->prob_resp_len = param->probe_resp_len;
3842 
3843 	buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param);
3844 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
3845 				device_types_len_aligned);
3846 	buf_ptr += WMI_TLV_HDR_SIZE;
3847 	qdf_mem_copy(buf_ptr, param->device_types,
3848 			param->dev_types_len);
3849 
3850 	buf_ptr += device_types_len_aligned;
3851 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
3852 			probe_resp_len_aligned);
3853 	buf_ptr += WMI_TLV_HDR_SIZE;
3854 	qdf_mem_copy(buf_ptr, param->probe_resp_tmplt,
3855 			param->probe_resp_len);
3856 
3857 	WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__,
3858 	cmd->channel, cmd->period, cmd->interval, cmd->count);
3859 
3860 	wmi_mtrace(WMI_P2P_LISTEN_OFFLOAD_START_CMDID, cmd->vdev_id, 0);
3861 	status = wmi_unified_cmd_send(wmi_handle,
3862 				buf, len,
3863 				WMI_P2P_LISTEN_OFFLOAD_START_CMDID);
3864 	if (status != QDF_STATUS_SUCCESS) {
3865 		WMI_LOGE("%s: Failed to send p2p lo start: %d",
3866 			__func__, status);
3867 		wmi_buf_free(buf);
3868 		return status;
3869 	}
3870 
3871 	WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__);
3872 
3873 	return QDF_STATUS_SUCCESS;
3874 }
3875 
3876 /**
3877  * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw
3878  * @wmi_handle: wmi handle
3879  * @param: p2p listen offload stop parameters
3880  *
3881  * Return: QDF status
3882  */
3883 static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle,
3884 	uint8_t vdev_id)
3885 {
3886 	wmi_buf_t buf;
3887 	wmi_p2p_lo_stop_cmd_fixed_param *cmd;
3888 	int32_t len;
3889 	QDF_STATUS status;
3890 
3891 	WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id);
3892 
3893 	len = sizeof(*cmd);
3894 	buf = wmi_buf_alloc(wmi_handle, len);
3895 	if (!buf) {
3896 		qdf_print("%s: Failed to allocate memory for p2p lo stop",
3897 			__func__);
3898 		return QDF_STATUS_E_NOMEM;
3899 	}
3900 	cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf);
3901 
3902 	WMITLV_SET_HDR(&cmd->tlv_header,
3903 		WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param,
3904 		WMITLV_GET_STRUCT_TLVLEN(
3905 			wmi_p2p_lo_stop_cmd_fixed_param));
3906 
3907 	cmd->vdev_id = vdev_id;
3908 
3909 	WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__);
3910 
3911 	wmi_mtrace(WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID, cmd->vdev_id, 0);
3912 	status = wmi_unified_cmd_send(wmi_handle,
3913 				buf, len,
3914 				WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID);
3915 	if (status != QDF_STATUS_SUCCESS) {
3916 		WMI_LOGE("%s: Failed to send p2p lo stop: %d",
3917 			__func__, status);
3918 		wmi_buf_free(buf);
3919 		return status;
3920 	}
3921 
3922 	WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__);
3923 
3924 	return QDF_STATUS_SUCCESS;
3925 }
3926 #endif /* End of FEATURE_P2P_LISTEN_OFFLOAD */
3927 
3928 /**
3929  * send_get_temperature_cmd_tlv() - get pdev temperature req
3930  * @wmi_handle: wmi handle
3931  *
3932  * Return: QDF_STATUS_SUCCESS for success or error code.
3933  */
3934 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle)
3935 {
3936 	wmi_pdev_get_temperature_cmd_fixed_param *cmd;
3937 	wmi_buf_t wmi_buf;
3938 	uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param);
3939 	uint8_t *buf_ptr;
3940 
3941 	if (!wmi_handle) {
3942 		WMI_LOGE(FL("WMI is closed, can not issue cmd"));
3943 		return QDF_STATUS_E_INVAL;
3944 	}
3945 
3946 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
3947 	if (!wmi_buf) {
3948 		WMI_LOGE(FL("wmi_buf_alloc failed"));
3949 		return QDF_STATUS_E_NOMEM;
3950 	}
3951 
3952 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
3953 
3954 	cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr;
3955 	WMITLV_SET_HDR(&cmd->tlv_header,
3956 		       WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param,
3957 		       WMITLV_GET_STRUCT_TLVLEN
3958 			       (wmi_pdev_get_temperature_cmd_fixed_param));
3959 
3960 	wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0);
3961 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
3962 				 WMI_PDEV_GET_TEMPERATURE_CMDID)) {
3963 		WMI_LOGE(FL("failed to send get temperature command"));
3964 		wmi_buf_free(wmi_buf);
3965 		return QDF_STATUS_E_FAILURE;
3966 	}
3967 
3968 	return QDF_STATUS_SUCCESS;
3969 }
3970 
3971 /**
3972  * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command
3973  * @wmi_handle: wmi handle
3974  * @vdevid: vdev id
3975  * @peer_addr: peer mac address
3976  * @auto_triggerparam: auto trigger parameters
3977  * @num_ac: number of access category
3978  *
3979  * This function sets the trigger
3980  * uapsd params such as service interval, delay interval
3981  * and suspend interval which will be used by the firmware
3982  * to send trigger frames periodically when there is no
3983  * traffic on the transmit side.
3984  *
3985  * Return: QDF_STATUS_SUCCESS for success or error code.
3986  */
3987 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle,
3988 				struct sta_uapsd_trig_params *param)
3989 {
3990 	wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd;
3991 	QDF_STATUS ret;
3992 	uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param);
3993 	uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE;
3994 	uint32_t i;
3995 	wmi_buf_t buf;
3996 	uint8_t *buf_ptr;
3997 	struct sta_uapsd_params *uapsd_param;
3998 	wmi_sta_uapsd_auto_trig_param *trig_param;
3999 
4000 	buf = wmi_buf_alloc(wmi_handle, cmd_len);
4001 	if (!buf) {
4002 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
4003 		return QDF_STATUS_E_NOMEM;
4004 	}
4005 
4006 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
4007 	cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr;
4008 	WMITLV_SET_HDR(&cmd->tlv_header,
4009 		       WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param,
4010 		       WMITLV_GET_STRUCT_TLVLEN
4011 			       (wmi_sta_uapsd_auto_trig_cmd_fixed_param));
4012 	cmd->vdev_id = param->vdevid;
4013 	cmd->num_ac = param->num_ac;
4014 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
4015 
4016 	/* TLV indicating array of structures to follow */
4017 	buf_ptr += sizeof(*cmd);
4018 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len);
4019 
4020 	buf_ptr += WMI_TLV_HDR_SIZE;
4021 
4022 	/*
4023 	 * Update tag and length for uapsd auto trigger params (this will take
4024 	 * care of updating tag and length if it is not pre-filled by caller).
4025 	 */
4026 	uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam;
4027 	trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr;
4028 	for (i = 0; i < param->num_ac; i++) {
4029 		WMITLV_SET_HDR((buf_ptr +
4030 				(i * sizeof(wmi_sta_uapsd_auto_trig_param))),
4031 			       WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param,
4032 			       WMITLV_GET_STRUCT_TLVLEN
4033 				       (wmi_sta_uapsd_auto_trig_param));
4034 		trig_param->wmm_ac = uapsd_param->wmm_ac;
4035 		trig_param->user_priority = uapsd_param->user_priority;
4036 		trig_param->service_interval = uapsd_param->service_interval;
4037 		trig_param->suspend_interval = uapsd_param->suspend_interval;
4038 		trig_param->delay_interval = uapsd_param->delay_interval;
4039 		trig_param++;
4040 		uapsd_param++;
4041 	}
4042 
4043 	wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0);
4044 	ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
4045 				   WMI_STA_UAPSD_AUTO_TRIG_CMDID);
4046 	if (QDF_IS_STATUS_ERROR(ret)) {
4047 		WMI_LOGE("Failed to send set uapsd param ret = %d", ret);
4048 		wmi_buf_free(buf);
4049 	}
4050 
4051 	return ret;
4052 }
4053 
4054 #ifdef WLAN_FEATURE_DSRC
4055 /**
4056  * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware
4057  * @wmi_handle: pointer to the wmi handle
4058  * @utc: pointer to the UTC time struct
4059  *
4060  * Return: 0 on succes
4061  */
4062 static QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle,
4063 				struct ocb_utc_param *utc)
4064 {
4065 	QDF_STATUS ret;
4066 	wmi_ocb_set_utc_time_cmd_fixed_param *cmd;
4067 	uint8_t *buf_ptr;
4068 	uint32_t len, i;
4069 	wmi_buf_t buf;
4070 
4071 	len = sizeof(*cmd);
4072 	buf = wmi_buf_alloc(wmi_handle, len);
4073 	if (!buf) {
4074 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4075 		return QDF_STATUS_E_NOMEM;
4076 	}
4077 
4078 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4079 	cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr;
4080 	WMITLV_SET_HDR(&cmd->tlv_header,
4081 		WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param,
4082 		WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param));
4083 	cmd->vdev_id = utc->vdev_id;
4084 
4085 	for (i = 0; i < SIZE_UTC_TIME; i++)
4086 		WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]);
4087 
4088 	for (i = 0; i < SIZE_UTC_TIME_ERROR; i++)
4089 		WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]);
4090 
4091 	wmi_mtrace(WMI_OCB_SET_UTC_TIME_CMDID, cmd->vdev_id, 0);
4092 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4093 				   WMI_OCB_SET_UTC_TIME_CMDID);
4094 	if (QDF_IS_STATUS_ERROR(ret)) {
4095 		WMI_LOGE(FL("Failed to set OCB UTC time"));
4096 		wmi_buf_free(buf);
4097 	}
4098 
4099 	return ret;
4100 }
4101 
4102 /**
4103  * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement
4104  *				   frames on a channel
4105  * @wmi_handle: pointer to the wmi handle
4106  * @timing_advert: pointer to the timing advertisement struct
4107  *
4108  * Return: 0 on succes
4109  */
4110 static QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
4111 	struct ocb_timing_advert_param *timing_advert)
4112 {
4113 	QDF_STATUS ret;
4114 	wmi_ocb_start_timing_advert_cmd_fixed_param *cmd;
4115 	uint8_t *buf_ptr;
4116 	uint32_t len, len_template;
4117 	wmi_buf_t buf;
4118 
4119 	len = sizeof(*cmd) +
4120 		     WMI_TLV_HDR_SIZE;
4121 
4122 	len_template = timing_advert->template_length;
4123 	/* Add padding to the template if needed */
4124 	if (len_template % 4 != 0)
4125 		len_template += 4 - (len_template % 4);
4126 	len += len_template;
4127 
4128 	buf = wmi_buf_alloc(wmi_handle, len);
4129 	if (!buf) {
4130 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4131 		return QDF_STATUS_E_NOMEM;
4132 	}
4133 
4134 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4135 	cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr;
4136 	WMITLV_SET_HDR(&cmd->tlv_header,
4137 		WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param,
4138 		WMITLV_GET_STRUCT_TLVLEN(
4139 			wmi_ocb_start_timing_advert_cmd_fixed_param));
4140 	cmd->vdev_id = timing_advert->vdev_id;
4141 	cmd->repeat_rate = timing_advert->repeat_rate;
4142 	cmd->channel_freq = timing_advert->chan_freq;
4143 	cmd->timestamp_offset = timing_advert->timestamp_offset;
4144 	cmd->time_value_offset = timing_advert->time_value_offset;
4145 	cmd->timing_advert_template_length = timing_advert->template_length;
4146 	buf_ptr += sizeof(*cmd);
4147 
4148 	/* Add the timing advert template */
4149 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
4150 		       len_template);
4151 	qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
4152 		     (uint8_t *)timing_advert->template_value,
4153 		     timing_advert->template_length);
4154 
4155 	wmi_mtrace(WMI_OCB_START_TIMING_ADVERT_CMDID, cmd->vdev_id, 0);
4156 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4157 				   WMI_OCB_START_TIMING_ADVERT_CMDID);
4158 	if (QDF_IS_STATUS_ERROR(ret)) {
4159 		WMI_LOGE(FL("Failed to start OCB timing advert"));
4160 		wmi_buf_free(buf);
4161 	}
4162 
4163 	return ret;
4164 }
4165 
4166 /**
4167  * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames
4168  *				  on a channel
4169  * @wmi_handle: pointer to the wmi handle
4170  * @timing_advert: pointer to the timing advertisement struct
4171  *
4172  * Return: 0 on succes
4173  */
4174 static QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
4175 	struct ocb_timing_advert_param *timing_advert)
4176 {
4177 	QDF_STATUS ret;
4178 	wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd;
4179 	uint8_t *buf_ptr;
4180 	uint32_t len;
4181 	wmi_buf_t buf;
4182 
4183 	len = sizeof(*cmd);
4184 	buf = wmi_buf_alloc(wmi_handle, len);
4185 	if (!buf) {
4186 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4187 		return QDF_STATUS_E_NOMEM;
4188 	}
4189 
4190 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4191 	cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr;
4192 	WMITLV_SET_HDR(&cmd->tlv_header,
4193 		WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param,
4194 		WMITLV_GET_STRUCT_TLVLEN(
4195 			wmi_ocb_stop_timing_advert_cmd_fixed_param));
4196 	cmd->vdev_id = timing_advert->vdev_id;
4197 	cmd->channel_freq = timing_advert->chan_freq;
4198 
4199 	wmi_mtrace(WMI_OCB_STOP_TIMING_ADVERT_CMDID, cmd->vdev_id, 0);
4200 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4201 				   WMI_OCB_STOP_TIMING_ADVERT_CMDID);
4202 	if (QDF_IS_STATUS_ERROR(ret)) {
4203 		WMI_LOGE(FL("Failed to stop OCB timing advert"));
4204 		wmi_buf_free(buf);
4205 	}
4206 
4207 	return ret;
4208 }
4209 
4210 /**
4211  * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val
4212  * @wmi_handle: pointer to the wmi handle
4213  * @request: pointer to the request
4214  *
4215  * Return: 0 on succes
4216  */
4217 static QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle,
4218 			  uint8_t vdev_id)
4219 {
4220 	QDF_STATUS ret;
4221 	wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd;
4222 	uint8_t *buf_ptr;
4223 	wmi_buf_t buf;
4224 	int32_t len;
4225 
4226 	len = sizeof(*cmd);
4227 	buf = wmi_buf_alloc(wmi_handle, len);
4228 	if (!buf) {
4229 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4230 		return QDF_STATUS_E_NOMEM;
4231 	}
4232 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4233 
4234 	cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr;
4235 	qdf_mem_zero(cmd, len);
4236 	WMITLV_SET_HDR(&cmd->tlv_header,
4237 		WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param,
4238 		WMITLV_GET_STRUCT_TLVLEN(
4239 			wmi_ocb_get_tsf_timer_cmd_fixed_param));
4240 	cmd->vdev_id = vdev_id;
4241 
4242 	/* Send the WMI command */
4243 	wmi_mtrace(WMI_OCB_GET_TSF_TIMER_CMDID, cmd->vdev_id, 0);
4244 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4245 				   WMI_OCB_GET_TSF_TIMER_CMDID);
4246 	/* If there is an error, set the completion event */
4247 	if (QDF_IS_STATUS_ERROR(ret)) {
4248 		WMI_LOGE(FL("Failed to send WMI message: %d"), ret);
4249 		wmi_buf_free(buf);
4250 	}
4251 
4252 	return ret;
4253 }
4254 
4255 /**
4256  * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats
4257  * @wmi_handle: pointer to the wmi handle
4258  * @get_stats_param: pointer to the dcc stats
4259  *
4260  * Return: 0 on succes
4261  */
4262 static QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle,
4263 		     struct ocb_dcc_get_stats_param *get_stats_param)
4264 {
4265 	QDF_STATUS ret;
4266 	wmi_dcc_get_stats_cmd_fixed_param *cmd;
4267 	wmi_dcc_channel_stats_request *channel_stats_array;
4268 	wmi_buf_t buf;
4269 	uint8_t *buf_ptr;
4270 	uint32_t len;
4271 	uint32_t i;
4272 
4273 	/* Validate the input */
4274 	if (get_stats_param->request_array_len !=
4275 	    get_stats_param->channel_count * sizeof(*channel_stats_array)) {
4276 		WMI_LOGE(FL("Invalid parameter"));
4277 		return QDF_STATUS_E_INVAL;
4278 	}
4279 
4280 	/* Allocate memory for the WMI command */
4281 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
4282 		get_stats_param->request_array_len;
4283 
4284 	buf = wmi_buf_alloc(wmi_handle, len);
4285 	if (!buf) {
4286 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4287 		return QDF_STATUS_E_NOMEM;
4288 	}
4289 
4290 	buf_ptr = wmi_buf_data(buf);
4291 	qdf_mem_zero(buf_ptr, len);
4292 
4293 	/* Populate the WMI command */
4294 	cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr;
4295 	buf_ptr += sizeof(*cmd);
4296 
4297 	WMITLV_SET_HDR(&cmd->tlv_header,
4298 		       WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param,
4299 		       WMITLV_GET_STRUCT_TLVLEN(
4300 			   wmi_dcc_get_stats_cmd_fixed_param));
4301 	cmd->vdev_id = get_stats_param->vdev_id;
4302 	cmd->num_channels = get_stats_param->channel_count;
4303 
4304 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4305 		       get_stats_param->request_array_len);
4306 	buf_ptr += WMI_TLV_HDR_SIZE;
4307 
4308 	channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr;
4309 	qdf_mem_copy(channel_stats_array, get_stats_param->request_array,
4310 		     get_stats_param->request_array_len);
4311 	for (i = 0; i < cmd->num_channels; i++)
4312 		WMITLV_SET_HDR(&channel_stats_array[i].tlv_header,
4313 			WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request,
4314 			WMITLV_GET_STRUCT_TLVLEN(
4315 			    wmi_dcc_channel_stats_request));
4316 
4317 	/* Send the WMI command */
4318 	wmi_mtrace(WMI_DCC_GET_STATS_CMDID, cmd->vdev_id, 0);
4319 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4320 				   WMI_DCC_GET_STATS_CMDID);
4321 
4322 	if (QDF_IS_STATUS_ERROR(ret)) {
4323 		WMI_LOGE(FL("Failed to send WMI message: %d"), ret);
4324 		wmi_buf_free(buf);
4325 	}
4326 
4327 	return ret;
4328 }
4329 
4330 /**
4331  * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats
4332  * @wmi_handle: pointer to the wmi handle
4333  * @vdev_id: vdev id
4334  * @dcc_stats_bitmap: dcc status bitmap
4335  *
4336  * Return: 0 on succes
4337  */
4338 static QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle,
4339 				uint32_t vdev_id, uint32_t dcc_stats_bitmap)
4340 {
4341 	QDF_STATUS ret;
4342 	wmi_dcc_clear_stats_cmd_fixed_param *cmd;
4343 	wmi_buf_t buf;
4344 	uint8_t *buf_ptr;
4345 	uint32_t len;
4346 
4347 	/* Allocate memory for the WMI command */
4348 	len = sizeof(*cmd);
4349 
4350 	buf = wmi_buf_alloc(wmi_handle, len);
4351 	if (!buf) {
4352 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4353 		return QDF_STATUS_E_NOMEM;
4354 	}
4355 
4356 	buf_ptr = wmi_buf_data(buf);
4357 	qdf_mem_zero(buf_ptr, len);
4358 
4359 	/* Populate the WMI command */
4360 	cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr;
4361 
4362 	WMITLV_SET_HDR(&cmd->tlv_header,
4363 		       WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param,
4364 		       WMITLV_GET_STRUCT_TLVLEN(
4365 			   wmi_dcc_clear_stats_cmd_fixed_param));
4366 	cmd->vdev_id = vdev_id;
4367 	cmd->dcc_stats_bitmap = dcc_stats_bitmap;
4368 
4369 	/* Send the WMI command */
4370 	wmi_mtrace(WMI_DCC_CLEAR_STATS_CMDID, cmd->vdev_id, 0);
4371 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4372 				   WMI_DCC_CLEAR_STATS_CMDID);
4373 	if (QDF_IS_STATUS_ERROR(ret)) {
4374 		WMI_LOGE(FL("Failed to send the WMI command"));
4375 		wmi_buf_free(buf);
4376 	}
4377 
4378 	return ret;
4379 }
4380 
4381 /**
4382  * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data
4383  * @wmi_handle: pointer to the wmi handle
4384  * @update_ndl_param: pointer to the request parameters
4385  *
4386  * Return: 0 on success
4387  */
4388 static QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle,
4389 		       struct ocb_dcc_update_ndl_param *update_ndl_param)
4390 {
4391 	QDF_STATUS qdf_status;
4392 	wmi_dcc_update_ndl_cmd_fixed_param *cmd;
4393 	wmi_dcc_ndl_chan *ndl_chan_array;
4394 	wmi_dcc_ndl_active_state_config *ndl_active_state_array;
4395 	uint32_t active_state_count;
4396 	wmi_buf_t buf;
4397 	uint8_t *buf_ptr;
4398 	uint32_t len;
4399 	uint32_t i;
4400 
4401 	/* validate the input */
4402 	if (update_ndl_param->dcc_ndl_chan_list_len !=
4403 	    update_ndl_param->channel_count * sizeof(*ndl_chan_array)) {
4404 		WMI_LOGE(FL("Invalid parameter"));
4405 		return QDF_STATUS_E_INVAL;
4406 	}
4407 	active_state_count = 0;
4408 	ndl_chan_array = update_ndl_param->dcc_ndl_chan_list;
4409 	for (i = 0; i < update_ndl_param->channel_count; i++)
4410 		active_state_count +=
4411 			WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]);
4412 	if (update_ndl_param->dcc_ndl_active_state_list_len !=
4413 	    active_state_count * sizeof(*ndl_active_state_array)) {
4414 		WMI_LOGE(FL("Invalid parameter"));
4415 		return QDF_STATUS_E_INVAL;
4416 	}
4417 
4418 	/* Allocate memory for the WMI command */
4419 	len = sizeof(*cmd) +
4420 		WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len +
4421 		WMI_TLV_HDR_SIZE +
4422 		update_ndl_param->dcc_ndl_active_state_list_len;
4423 
4424 	buf = wmi_buf_alloc(wmi_handle, len);
4425 	if (!buf) {
4426 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4427 		return QDF_STATUS_E_NOMEM;
4428 	}
4429 
4430 	buf_ptr = wmi_buf_data(buf);
4431 	qdf_mem_zero(buf_ptr, len);
4432 
4433 	/* Populate the WMI command */
4434 	cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr;
4435 	buf_ptr += sizeof(*cmd);
4436 
4437 	WMITLV_SET_HDR(&cmd->tlv_header,
4438 		       WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param,
4439 		       WMITLV_GET_STRUCT_TLVLEN(
4440 			   wmi_dcc_update_ndl_cmd_fixed_param));
4441 	cmd->vdev_id = update_ndl_param->vdev_id;
4442 	cmd->num_channel = update_ndl_param->channel_count;
4443 
4444 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4445 		       update_ndl_param->dcc_ndl_chan_list_len);
4446 	buf_ptr += WMI_TLV_HDR_SIZE;
4447 
4448 	ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr;
4449 	qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list,
4450 		     update_ndl_param->dcc_ndl_chan_list_len);
4451 	for (i = 0; i < cmd->num_channel; i++)
4452 		WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header,
4453 			WMITLV_TAG_STRUC_wmi_dcc_ndl_chan,
4454 			WMITLV_GET_STRUCT_TLVLEN(
4455 			    wmi_dcc_ndl_chan));
4456 	buf_ptr += update_ndl_param->dcc_ndl_chan_list_len;
4457 
4458 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4459 		       update_ndl_param->dcc_ndl_active_state_list_len);
4460 	buf_ptr += WMI_TLV_HDR_SIZE;
4461 
4462 	ndl_active_state_array = (wmi_dcc_ndl_active_state_config *) buf_ptr;
4463 	qdf_mem_copy(ndl_active_state_array,
4464 		     update_ndl_param->dcc_ndl_active_state_list,
4465 		     update_ndl_param->dcc_ndl_active_state_list_len);
4466 	for (i = 0; i < active_state_count; i++) {
4467 		WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header,
4468 			WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config,
4469 			WMITLV_GET_STRUCT_TLVLEN(
4470 			    wmi_dcc_ndl_active_state_config));
4471 	}
4472 	buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len;
4473 
4474 	/* Send the WMI command */
4475 	wmi_mtrace(WMI_DCC_UPDATE_NDL_CMDID, cmd->vdev_id, 0);
4476 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
4477 				   WMI_DCC_UPDATE_NDL_CMDID);
4478 	/* If there is an error, set the completion event */
4479 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4480 		WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status);
4481 		wmi_buf_free(buf);
4482 	}
4483 
4484 	return qdf_status;
4485 }
4486 
4487 /**
4488  * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW
4489  * @wmi_handle: pointer to the wmi handle
4490  * @config: the OCB configuration
4491  *
4492  * Return: 0 on success
4493  */
4494 static QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle,
4495 				struct ocb_config *config)
4496 {
4497 	QDF_STATUS ret;
4498 	wmi_ocb_set_config_cmd_fixed_param *cmd;
4499 	wmi_channel *chan;
4500 	wmi_ocb_channel *ocb_chan;
4501 	wmi_qos_parameter *qos_param;
4502 	wmi_dcc_ndl_chan *ndl_chan;
4503 	wmi_dcc_ndl_active_state_config *ndl_active_config;
4504 	wmi_ocb_schedule_element *sched_elem;
4505 	uint8_t *buf_ptr;
4506 	wmi_buf_t buf;
4507 	int32_t len;
4508 	int32_t i, j, active_state_count;
4509 
4510 	/*
4511 	 * Validate the dcc_ndl_chan_list_len and count the number of active
4512 	 * states. Validate dcc_ndl_active_state_list_len.
4513 	 */
4514 	active_state_count = 0;
4515 	if (config->dcc_ndl_chan_list_len) {
4516 		if (!config->dcc_ndl_chan_list ||
4517 			config->dcc_ndl_chan_list_len !=
4518 			config->channel_count * sizeof(wmi_dcc_ndl_chan)) {
4519 			WMI_LOGE(FL("NDL channel is invalid. List len: %d"),
4520 				 config->dcc_ndl_chan_list_len);
4521 			return QDF_STATUS_E_INVAL;
4522 		}
4523 
4524 		for (i = 0, ndl_chan = config->dcc_ndl_chan_list;
4525 				i < config->channel_count; ++i, ++ndl_chan)
4526 			active_state_count +=
4527 				WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan);
4528 
4529 		if (active_state_count) {
4530 			if (!config->dcc_ndl_active_state_list ||
4531 				config->dcc_ndl_active_state_list_len !=
4532 				active_state_count *
4533 				sizeof(wmi_dcc_ndl_active_state_config)) {
4534 				WMI_LOGE(FL("NDL active state is invalid."));
4535 				return QDF_STATUS_E_INVAL;
4536 			}
4537 		}
4538 	}
4539 
4540 	len = sizeof(*cmd) +
4541 		WMI_TLV_HDR_SIZE + config->channel_count *
4542 			sizeof(wmi_channel) +
4543 		WMI_TLV_HDR_SIZE + config->channel_count *
4544 			sizeof(wmi_ocb_channel) +
4545 		WMI_TLV_HDR_SIZE + config->channel_count *
4546 			sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC +
4547 		WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len +
4548 		WMI_TLV_HDR_SIZE + active_state_count *
4549 			sizeof(wmi_dcc_ndl_active_state_config) +
4550 		WMI_TLV_HDR_SIZE + config->schedule_size *
4551 			sizeof(wmi_ocb_schedule_element);
4552 	buf = wmi_buf_alloc(wmi_handle, len);
4553 	if (!buf) {
4554 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4555 		return QDF_STATUS_E_NOMEM;
4556 	}
4557 
4558 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4559 	cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr;
4560 	WMITLV_SET_HDR(&cmd->tlv_header,
4561 		WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param,
4562 		WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param));
4563 	cmd->vdev_id = config->vdev_id;
4564 	cmd->channel_count = config->channel_count;
4565 	cmd->schedule_size = config->schedule_size;
4566 	cmd->flags = config->flags;
4567 	buf_ptr += sizeof(*cmd);
4568 
4569 	/* Add the wmi_channel info */
4570 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4571 		       config->channel_count*sizeof(wmi_channel));
4572 	buf_ptr += WMI_TLV_HDR_SIZE;
4573 	for (i = 0; i < config->channel_count; i++) {
4574 		chan = (wmi_channel *)buf_ptr;
4575 		WMITLV_SET_HDR(&chan->tlv_header,
4576 				WMITLV_TAG_STRUC_wmi_channel,
4577 				WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
4578 		chan->mhz = config->channels[i].chan_freq;
4579 		chan->band_center_freq1 = config->channels[i].chan_freq;
4580 		chan->band_center_freq2 = 0;
4581 		chan->info = 0;
4582 
4583 		WMI_SET_CHANNEL_MODE(chan, config->channels[i].ch_mode);
4584 		WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr);
4585 		WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr);
4586 		WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr);
4587 		WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr);
4588 		WMI_SET_CHANNEL_ANTENNA_MAX(chan,
4589 					    config->channels[i].antenna_max);
4590 
4591 		if (config->channels[i].bandwidth < 10)
4592 			WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
4593 		else if (config->channels[i].bandwidth < 20)
4594 			WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
4595 		buf_ptr += sizeof(*chan);
4596 	}
4597 
4598 	/* Add the wmi_ocb_channel info */
4599 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4600 		       config->channel_count*sizeof(wmi_ocb_channel));
4601 	buf_ptr += WMI_TLV_HDR_SIZE;
4602 	for (i = 0; i < config->channel_count; i++) {
4603 		ocb_chan = (wmi_ocb_channel *)buf_ptr;
4604 		WMITLV_SET_HDR(&ocb_chan->tlv_header,
4605 			       WMITLV_TAG_STRUC_wmi_ocb_channel,
4606 			       WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel));
4607 		ocb_chan->bandwidth = config->channels[i].bandwidth;
4608 		WMI_CHAR_ARRAY_TO_MAC_ADDR(
4609 					config->channels[i].mac_address.bytes,
4610 					&ocb_chan->mac_address);
4611 		buf_ptr += sizeof(*ocb_chan);
4612 	}
4613 
4614 	/* Add the wmi_qos_parameter info */
4615 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4616 		config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC);
4617 	buf_ptr += WMI_TLV_HDR_SIZE;
4618 	/* WMI_MAX_NUM_AC parameters for each channel */
4619 	for (i = 0; i < config->channel_count; i++) {
4620 		for (j = 0; j < WMI_MAX_NUM_AC; j++) {
4621 			qos_param = (wmi_qos_parameter *)buf_ptr;
4622 			WMITLV_SET_HDR(&qos_param->tlv_header,
4623 				WMITLV_TAG_STRUC_wmi_qos_parameter,
4624 				WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter));
4625 			qos_param->aifsn =
4626 				config->channels[i].qos_params[j].aifsn;
4627 			qos_param->cwmin =
4628 				config->channels[i].qos_params[j].cwmin;
4629 			qos_param->cwmax =
4630 				config->channels[i].qos_params[j].cwmax;
4631 			buf_ptr += sizeof(*qos_param);
4632 		}
4633 	}
4634 
4635 	/* Add the wmi_dcc_ndl_chan (per channel) */
4636 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4637 		       config->dcc_ndl_chan_list_len);
4638 	buf_ptr += WMI_TLV_HDR_SIZE;
4639 	if (config->dcc_ndl_chan_list_len) {
4640 		ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr;
4641 		qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list,
4642 			     config->dcc_ndl_chan_list_len);
4643 		for (i = 0; i < config->channel_count; i++)
4644 			WMITLV_SET_HDR(&(ndl_chan[i].tlv_header),
4645 				WMITLV_TAG_STRUC_wmi_dcc_ndl_chan,
4646 				WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan));
4647 		buf_ptr += config->dcc_ndl_chan_list_len;
4648 	}
4649 
4650 	/* Add the wmi_dcc_ndl_active_state_config */
4651 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count *
4652 		       sizeof(wmi_dcc_ndl_active_state_config));
4653 	buf_ptr += WMI_TLV_HDR_SIZE;
4654 	if (active_state_count) {
4655 		ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr;
4656 		qdf_mem_copy(ndl_active_config,
4657 			config->dcc_ndl_active_state_list,
4658 			active_state_count * sizeof(*ndl_active_config));
4659 		for (i = 0; i < active_state_count; ++i)
4660 			WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header),
4661 			  WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config,
4662 			  WMITLV_GET_STRUCT_TLVLEN(
4663 				wmi_dcc_ndl_active_state_config));
4664 		buf_ptr += active_state_count *
4665 			sizeof(*ndl_active_config);
4666 	}
4667 
4668 	/* Add the wmi_ocb_schedule_element info */
4669 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4670 		config->schedule_size * sizeof(wmi_ocb_schedule_element));
4671 	buf_ptr += WMI_TLV_HDR_SIZE;
4672 	for (i = 0; i < config->schedule_size; i++) {
4673 		sched_elem = (wmi_ocb_schedule_element *)buf_ptr;
4674 		WMITLV_SET_HDR(&sched_elem->tlv_header,
4675 			WMITLV_TAG_STRUC_wmi_ocb_schedule_element,
4676 			WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element));
4677 		sched_elem->channel_freq = config->schedule[i].chan_freq;
4678 		sched_elem->total_duration = config->schedule[i].total_duration;
4679 		sched_elem->guard_interval = config->schedule[i].guard_interval;
4680 		buf_ptr += sizeof(*sched_elem);
4681 	}
4682 
4683 
4684 	wmi_mtrace(WMI_OCB_SET_CONFIG_CMDID, cmd->vdev_id, 0);
4685 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4686 				   WMI_OCB_SET_CONFIG_CMDID);
4687 	if (QDF_IS_STATUS_ERROR(ret)) {
4688 		WMI_LOGE("Failed to set OCB config");
4689 		wmi_buf_free(buf);
4690 	}
4691 
4692 	return ret;
4693 }
4694 
4695 /**
4696  * extract_ocb_channel_config_resp_tlv() - extract ocb channel config resp
4697  * @wmi_handle: wmi handle
4698  * @evt_buf: wmi event buffer
4699  * @status: status buffer
4700  *
4701  * Return: QDF_STATUS_SUCCESS on success
4702  */
4703 static QDF_STATUS extract_ocb_channel_config_resp_tlv(wmi_unified_t wmi_handle,
4704 						      void *evt_buf,
4705 						      uint32_t *status)
4706 {
4707 	WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs;
4708 	wmi_ocb_set_config_resp_event_fixed_param *fix_param;
4709 
4710 	param_tlvs = evt_buf;
4711 	fix_param = param_tlvs->fixed_param;
4712 
4713 	*status = fix_param->status;
4714 	return QDF_STATUS_SUCCESS;
4715 }
4716 
4717 /**
4718  * extract_ocb_tsf_timer_tlv() - extract TSF timer from event buffer
4719  * @wmi_handle: wmi handle
4720  * @evt_buf: wmi event buffer
4721  * @resp: response buffer
4722  *
4723  * Return: QDF_STATUS_SUCCESS on success
4724  */
4725 static QDF_STATUS extract_ocb_tsf_timer_tlv(wmi_unified_t wmi_handle,
4726 			void *evt_buf, struct ocb_get_tsf_timer_response *resp)
4727 {
4728 	WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs;
4729 	wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param;
4730 
4731 	param_tlvs = evt_buf;
4732 	fix_param = param_tlvs->fixed_param;
4733 	resp->vdev_id = fix_param->vdev_id;
4734 	resp->timer_high = fix_param->tsf_timer_high;
4735 	resp->timer_low = fix_param->tsf_timer_low;
4736 
4737 	return QDF_STATUS_SUCCESS;
4738 }
4739 
4740 /**
4741  * extract_ocb_ndl_resp_tlv() - extract TSF timer from event buffer
4742  * @wmi_handle: wmi handle
4743  * @evt_buf: wmi event buffer
4744  * @resp: response buffer
4745  *
4746  * Return: QDF_STATUS_SUCCESS on success
4747  */
4748 static QDF_STATUS extract_ocb_ndl_resp_tlv(wmi_unified_t wmi_handle,
4749 		void *evt_buf, struct ocb_dcc_update_ndl_response *resp)
4750 {
4751 	WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs;
4752 	wmi_dcc_update_ndl_resp_event_fixed_param *fix_param;
4753 
4754 	param_tlvs = evt_buf;
4755 	fix_param = param_tlvs->fixed_param;
4756 	resp->vdev_id = fix_param->vdev_id;
4757 	resp->status = fix_param->status;
4758 	return QDF_STATUS_SUCCESS;
4759 }
4760 
4761 /**
4762  * extract_ocb_dcc_stats_tlv() - extract DCC stats from event buffer
4763  * @wmi_handle: wmi handle
4764  * @evt_buf: wmi event buffer
4765  * @resp: response buffer
4766  *
4767  * Since length of stats is variable, buffer for DCC stats will be allocated
4768  * in this function. The caller must free the buffer.
4769  *
4770  * Return: QDF_STATUS_SUCCESS on success
4771  */
4772 static QDF_STATUS extract_ocb_dcc_stats_tlv(wmi_unified_t wmi_handle,
4773 		void *evt_buf, struct ocb_dcc_get_stats_response **resp)
4774 {
4775 	struct ocb_dcc_get_stats_response *response;
4776 	WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs;
4777 	wmi_dcc_get_stats_resp_event_fixed_param *fix_param;
4778 
4779 	param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)evt_buf;
4780 	fix_param = param_tlvs->fixed_param;
4781 
4782 	/* Allocate and populate the response */
4783 	if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE -
4784 	    sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) {
4785 		WMI_LOGE("%s: too many channels:%d", __func__,
4786 			 fix_param->num_channels);
4787 		QDF_ASSERT(0);
4788 		*resp = NULL;
4789 		return QDF_STATUS_E_INVAL;
4790 	}
4791 	response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels *
4792 		sizeof(wmi_dcc_ndl_stats_per_channel));
4793 	*resp = response;
4794 	if (!response)
4795 		return  QDF_STATUS_E_NOMEM;
4796 
4797 	response->vdev_id = fix_param->vdev_id;
4798 	response->num_channels = fix_param->num_channels;
4799 	response->channel_stats_array_len =
4800 		fix_param->num_channels *
4801 		sizeof(wmi_dcc_ndl_stats_per_channel);
4802 	response->channel_stats_array = ((uint8_t *)response) +
4803 					sizeof(*response);
4804 	qdf_mem_copy(response->channel_stats_array,
4805 		     param_tlvs->stats_per_channel_list,
4806 		     response->channel_stats_array_len);
4807 
4808 	return QDF_STATUS_SUCCESS;
4809 }
4810 #endif
4811 
4812 /**
4813  * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable mcc scheduler
4814  * @wmi_handle: wmi handle
4815  * @mcc_adaptive_scheduler: enable/disable
4816  *
4817  * This function enable/disable mcc adaptive scheduler in fw.
4818  *
4819  * Return: QDF_STATUS_SUCCESS for success or error code
4820  */
4821 static QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv(
4822 		wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler,
4823 		uint32_t pdev_id)
4824 {
4825 	QDF_STATUS ret;
4826 	wmi_buf_t buf = 0;
4827 	wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL;
4828 	uint16_t len =
4829 		sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param);
4830 
4831 	buf = wmi_buf_alloc(wmi_handle, len);
4832 	if (!buf) {
4833 		WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
4834 		return QDF_STATUS_E_NOMEM;
4835 	}
4836 	cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *)
4837 		wmi_buf_data(buf);
4838 
4839 	WMITLV_SET_HDR(&cmd->tlv_header,
4840 		       WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param,
4841 		       WMITLV_GET_STRUCT_TLVLEN
4842 			       (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param));
4843 	cmd->enable = mcc_adaptive_scheduler;
4844 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
4845 
4846 	wmi_mtrace(WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID, NO_SESSION, 0);
4847 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4848 				   WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID);
4849 	if (QDF_IS_STATUS_ERROR(ret)) {
4850 		WMI_LOGP("%s: Failed to send enable/disable MCC"
4851 			 " adaptive scheduler command", __func__);
4852 		wmi_buf_free(buf);
4853 	}
4854 
4855 	return ret;
4856 }
4857 
4858 /**
4859  * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency
4860  * @wmi: wmi handle
4861  * @mcc_channel: mcc channel
4862  * @mcc_channel_time_latency: MCC channel time latency.
4863  *
4864  * Currently used to set time latency for an MCC vdev/adapter using operating
4865  * channel of it and channel number. The info is provided run time using
4866  * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>.
4867  *
4868  * Return: CDF status
4869  */
4870 static QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(wmi_unified_t wmi_handle,
4871 	uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency)
4872 {
4873 	QDF_STATUS ret;
4874 	wmi_buf_t buf = 0;
4875 	wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL;
4876 	uint16_t len = 0;
4877 	uint8_t *buf_ptr = NULL;
4878 	wmi_resmgr_chan_latency chan_latency;
4879 	/* Note: we only support MCC time latency for a single channel */
4880 	uint32_t num_channels = 1;
4881 	uint32_t chan1_freq = mcc_channel_freq;
4882 	uint32_t latency_chan1 = mcc_channel_time_latency;
4883 
4884 
4885 	/* If 0ms latency is provided, then FW will set to a default.
4886 	 * Otherwise, latency must be at least 30ms.
4887 	 */
4888 	if ((latency_chan1 > 0) &&
4889 	    (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) {
4890 		WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms "
4891 			 "Minimum is 30ms (or 0 to use default value by "
4892 			 "firmware)", __func__, latency_chan1);
4893 		return QDF_STATUS_E_INVAL;
4894 	}
4895 
4896 	/*   Set WMI CMD for channel time latency here */
4897 	len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) +
4898 	      WMI_TLV_HDR_SIZE +  /*Place holder for chan_time_latency array */
4899 	      num_channels * sizeof(wmi_resmgr_chan_latency);
4900 	buf = wmi_buf_alloc(wmi_handle, len);
4901 	if (!buf) {
4902 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
4903 		return QDF_STATUS_E_NOMEM;
4904 	}
4905 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
4906 	cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *)
4907 		wmi_buf_data(buf);
4908 	WMITLV_SET_HDR(&cmdTL->tlv_header,
4909 		WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param,
4910 		       WMITLV_GET_STRUCT_TLVLEN
4911 		       (wmi_resmgr_set_chan_latency_cmd_fixed_param));
4912 	cmdTL->num_chans = num_channels;
4913 	/* Update channel time latency information for home channel(s) */
4914 	buf_ptr += sizeof(*cmdTL);
4915 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
4916 		       num_channels * sizeof(wmi_resmgr_chan_latency));
4917 	buf_ptr += WMI_TLV_HDR_SIZE;
4918 	chan_latency.chan_mhz = chan1_freq;
4919 	chan_latency.latency = latency_chan1;
4920 	qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency));
4921 	wmi_mtrace(WMI_RESMGR_SET_CHAN_LATENCY_CMDID, NO_SESSION, 0);
4922 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4923 				   WMI_RESMGR_SET_CHAN_LATENCY_CMDID);
4924 	if (QDF_IS_STATUS_ERROR(ret)) {
4925 		WMI_LOGE("%s: Failed to send MCC Channel Time Latency command",
4926 			 __func__);
4927 		wmi_buf_free(buf);
4928 		QDF_ASSERT(0);
4929 	}
4930 
4931 	return ret;
4932 }
4933 
4934 /**
4935  * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota
4936  * @wmi: wmi handle
4937  * @adapter_1_chan_number: adapter 1 channel number
4938  * @adapter_1_quota: adapter 1 quota
4939  * @adapter_2_chan_number: adapter 2 channel number
4940  *
4941  * Return: CDF status
4942  */
4943 static QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(wmi_unified_t wmi_handle,
4944 	uint32_t adapter_1_chan_freq,
4945 	uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq)
4946 {
4947 	QDF_STATUS ret;
4948 	wmi_buf_t buf = 0;
4949 	uint16_t len = 0;
4950 	uint8_t *buf_ptr = NULL;
4951 	wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL;
4952 	wmi_resmgr_chan_time_quota chan_quota;
4953 	uint32_t quota_chan1 = adapter_1_quota;
4954 	/* Knowing quota of 1st chan., derive quota for 2nd chan. */
4955 	uint32_t quota_chan2 = 100 - quota_chan1;
4956 	/* Note: setting time quota for MCC requires info for 2 channels */
4957 	uint32_t num_channels = 2;
4958 	uint32_t chan1_freq = adapter_1_chan_freq;
4959 	uint32_t chan2_freq = adapter_2_chan_freq;
4960 
4961 	WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, "
4962 		 "freq2:%dMHz, Quota2:%dms", __func__,
4963 		 chan1_freq, quota_chan1, chan2_freq,
4964 		 quota_chan2);
4965 
4966 	/*
4967 	 * Perform sanity check on time quota values provided.
4968 	 */
4969 	if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA ||
4970 	    quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) {
4971 		WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum "
4972 			 "is 20ms & maximum is 80ms", __func__, quota_chan1);
4973 		return QDF_STATUS_E_INVAL;
4974 	}
4975 	/* Set WMI CMD for channel time quota here */
4976 	len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) +
4977 	      WMI_TLV_HDR_SIZE +       /* Place holder for chan_time_quota array */
4978 	      num_channels * sizeof(wmi_resmgr_chan_time_quota);
4979 	buf = wmi_buf_alloc(wmi_handle, len);
4980 	if (!buf) {
4981 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
4982 		QDF_ASSERT(0);
4983 		return QDF_STATUS_E_NOMEM;
4984 	}
4985 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
4986 	cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *)
4987 		wmi_buf_data(buf);
4988 	WMITLV_SET_HDR(&cmdTQ->tlv_header,
4989 		       WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param,
4990 		       WMITLV_GET_STRUCT_TLVLEN
4991 			       (wmi_resmgr_set_chan_time_quota_cmd_fixed_param));
4992 	cmdTQ->num_chans = num_channels;
4993 
4994 	/* Update channel time quota information for home channel(s) */
4995 	buf_ptr += sizeof(*cmdTQ);
4996 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
4997 		       num_channels * sizeof(wmi_resmgr_chan_time_quota));
4998 	buf_ptr += WMI_TLV_HDR_SIZE;
4999 	chan_quota.chan_mhz = chan1_freq;
5000 	chan_quota.channel_time_quota = quota_chan1;
5001 	qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
5002 	/* Construct channel and quota record for the 2nd MCC mode. */
5003 	buf_ptr += sizeof(chan_quota);
5004 	chan_quota.chan_mhz = chan2_freq;
5005 	chan_quota.channel_time_quota = quota_chan2;
5006 	qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
5007 
5008 	wmi_mtrace(WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID, NO_SESSION, 0);
5009 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5010 				   WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID);
5011 	if (QDF_IS_STATUS_ERROR(ret)) {
5012 		WMI_LOGE("Failed to send MCC Channel Time Quota command");
5013 		wmi_buf_free(buf);
5014 		QDF_ASSERT(0);
5015 	}
5016 
5017 	return ret;
5018 }
5019 
5020 /**
5021  * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw
5022  * @wmi_handle: Pointer to wmi handle
5023  * @thermal_info: Thermal command information
5024  *
5025  * This function sends the thermal management command
5026  * to the firmware
5027  *
5028  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5029  */
5030 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
5031 				struct thermal_cmd_params *thermal_info)
5032 {
5033 	wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL;
5034 	wmi_buf_t buf = NULL;
5035 	QDF_STATUS status;
5036 	uint32_t len = 0;
5037 
5038 	len = sizeof(*cmd);
5039 
5040 	buf = wmi_buf_alloc(wmi_handle, len);
5041 	if (!buf) {
5042 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
5043 		return QDF_STATUS_E_FAILURE;
5044 	}
5045 
5046 	cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf);
5047 
5048 	WMITLV_SET_HDR(&cmd->tlv_header,
5049 		       WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param,
5050 		       WMITLV_GET_STRUCT_TLVLEN
5051 			       (wmi_thermal_mgmt_cmd_fixed_param));
5052 
5053 	cmd->lower_thresh_degreeC = thermal_info->min_temp;
5054 	cmd->upper_thresh_degreeC = thermal_info->max_temp;
5055 	cmd->enable = thermal_info->thermal_enable;
5056 
5057 	WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d",
5058 		cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable);
5059 
5060 	wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0);
5061 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
5062 				      WMI_THERMAL_MGMT_CMDID);
5063 	if (QDF_IS_STATUS_ERROR(status)) {
5064 		wmi_buf_free(buf);
5065 		WMI_LOGE("%s:Failed to send thermal mgmt command", __func__);
5066 	}
5067 
5068 	return status;
5069 }
5070 
5071 
5072 /**
5073  * send_lro_config_cmd_tlv() - process the LRO config command
5074  * @wmi_handle: Pointer to WMI handle
5075  * @wmi_lro_cmd: Pointer to LRO configuration parameters
5076  *
5077  * This function sends down the LRO configuration parameters to
5078  * the firmware to enable LRO, sets the TCP flags and sets the
5079  * seed values for the toeplitz hash generation
5080  *
5081  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5082  */
5083 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle,
5084 	 struct wmi_lro_config_cmd_t *wmi_lro_cmd)
5085 {
5086 	wmi_lro_info_cmd_fixed_param *cmd;
5087 	wmi_buf_t buf;
5088 	QDF_STATUS status;
5089 
5090 
5091 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
5092 	if (!buf) {
5093 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
5094 		return QDF_STATUS_E_FAILURE;
5095 	}
5096 
5097 	cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf);
5098 
5099 	WMITLV_SET_HDR(&cmd->tlv_header,
5100 		 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param,
5101 		 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param));
5102 
5103 	cmd->lro_enable = wmi_lro_cmd->lro_enable;
5104 	WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32,
5105 		 wmi_lro_cmd->tcp_flag);
5106 	WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32,
5107 		 wmi_lro_cmd->tcp_flag_mask);
5108 	cmd->toeplitz_hash_ipv4_0_3 =
5109 		 wmi_lro_cmd->toeplitz_hash_ipv4[0];
5110 	cmd->toeplitz_hash_ipv4_4_7 =
5111 		 wmi_lro_cmd->toeplitz_hash_ipv4[1];
5112 	cmd->toeplitz_hash_ipv4_8_11 =
5113 		 wmi_lro_cmd->toeplitz_hash_ipv4[2];
5114 	cmd->toeplitz_hash_ipv4_12_15 =
5115 		 wmi_lro_cmd->toeplitz_hash_ipv4[3];
5116 	cmd->toeplitz_hash_ipv4_16 =
5117 		 wmi_lro_cmd->toeplitz_hash_ipv4[4];
5118 
5119 	cmd->toeplitz_hash_ipv6_0_3 =
5120 		 wmi_lro_cmd->toeplitz_hash_ipv6[0];
5121 	cmd->toeplitz_hash_ipv6_4_7 =
5122 		 wmi_lro_cmd->toeplitz_hash_ipv6[1];
5123 	cmd->toeplitz_hash_ipv6_8_11 =
5124 		 wmi_lro_cmd->toeplitz_hash_ipv6[2];
5125 	cmd->toeplitz_hash_ipv6_12_15 =
5126 		 wmi_lro_cmd->toeplitz_hash_ipv6[3];
5127 	cmd->toeplitz_hash_ipv6_16_19 =
5128 		 wmi_lro_cmd->toeplitz_hash_ipv6[4];
5129 	cmd->toeplitz_hash_ipv6_20_23 =
5130 		 wmi_lro_cmd->toeplitz_hash_ipv6[5];
5131 	cmd->toeplitz_hash_ipv6_24_27 =
5132 		 wmi_lro_cmd->toeplitz_hash_ipv6[6];
5133 	cmd->toeplitz_hash_ipv6_28_31 =
5134 		 wmi_lro_cmd->toeplitz_hash_ipv6[7];
5135 	cmd->toeplitz_hash_ipv6_32_35 =
5136 		 wmi_lro_cmd->toeplitz_hash_ipv6[8];
5137 	cmd->toeplitz_hash_ipv6_36_39 =
5138 		 wmi_lro_cmd->toeplitz_hash_ipv6[9];
5139 	cmd->toeplitz_hash_ipv6_40 =
5140 		 wmi_lro_cmd->toeplitz_hash_ipv6[10];
5141 
5142 	WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x",
5143 		cmd->lro_enable, cmd->tcp_flag_u32);
5144 
5145 	wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0);
5146 	status = wmi_unified_cmd_send(wmi_handle, buf,
5147 		 sizeof(*cmd), WMI_LRO_CONFIG_CMDID);
5148 	if (QDF_IS_STATUS_ERROR(status)) {
5149 		wmi_buf_free(buf);
5150 		WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__);
5151 	}
5152 
5153 	return status;
5154 }
5155 
5156 /**
5157  * send_peer_rate_report_cmd_tlv() - process the peer rate report command
5158  * @wmi_handle: Pointer to wmi handle
5159  * @rate_report_params: Pointer to peer rate report parameters
5160  *
5161  *
5162  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5163  */
5164 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle,
5165 	 struct wmi_peer_rate_report_params *rate_report_params)
5166 {
5167 	wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL;
5168 	wmi_buf_t buf = NULL;
5169 	QDF_STATUS status = 0;
5170 	uint32_t len = 0;
5171 	uint32_t i, j;
5172 
5173 	len = sizeof(*cmd);
5174 
5175 	buf = wmi_buf_alloc(wmi_handle, len);
5176 	if (!buf) {
5177 		WMI_LOGE("Failed to alloc buf to peer_set_condition cmd\n");
5178 		return QDF_STATUS_E_FAILURE;
5179 	}
5180 
5181 	cmd = (wmi_peer_set_rate_report_condition_fixed_param *)
5182 		wmi_buf_data(buf);
5183 
5184 	WMITLV_SET_HDR(
5185 	&cmd->tlv_header,
5186 	WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param,
5187 	WMITLV_GET_STRUCT_TLVLEN(
5188 		wmi_peer_set_rate_report_condition_fixed_param));
5189 
5190 	cmd->enable_rate_report  = rate_report_params->rate_report_enable;
5191 	cmd->report_backoff_time = rate_report_params->backoff_time;
5192 	cmd->report_timer_period = rate_report_params->timer_period;
5193 	for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) {
5194 		cmd->cond_per_phy[i].val_cond_flags        =
5195 			rate_report_params->report_per_phy[i].cond_flags;
5196 		cmd->cond_per_phy[i].rate_delta.min_delta  =
5197 			rate_report_params->report_per_phy[i].delta.delta_min;
5198 		cmd->cond_per_phy[i].rate_delta.percentage =
5199 			rate_report_params->report_per_phy[i].delta.percent;
5200 		for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) {
5201 			cmd->cond_per_phy[i].rate_threshold[j] =
5202 			rate_report_params->report_per_phy[i].
5203 						report_rate_threshold[j];
5204 		}
5205 	}
5206 
5207 	WMI_LOGE("%s enable %d backoff_time %d period %d\n", __func__,
5208 		 cmd->enable_rate_report,
5209 		 cmd->report_backoff_time, cmd->report_timer_period);
5210 
5211 	wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0);
5212 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
5213 			WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID);
5214 	if (QDF_IS_STATUS_ERROR(status)) {
5215 		wmi_buf_free(buf);
5216 		WMI_LOGE("%s:Failed to send peer_set_report_cond command",
5217 			 __func__);
5218 	}
5219 	return status;
5220 }
5221 
5222 /**
5223  * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL
5224  * @wmi_handle: wmi handle
5225  * @param: bcn ll cmd parameter
5226  *
5227  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5228  */
5229 static QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle,
5230 			wmi_bcn_send_from_host_cmd_fixed_param *param)
5231 {
5232 	wmi_bcn_send_from_host_cmd_fixed_param *cmd;
5233 	wmi_buf_t wmi_buf;
5234 	QDF_STATUS ret;
5235 
5236 	wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
5237 	if (!wmi_buf) {
5238 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
5239 		return QDF_STATUS_E_FAILURE;
5240 	}
5241 
5242 	cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf);
5243 	WMITLV_SET_HDR(&cmd->tlv_header,
5244 		       WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param,
5245 		       WMITLV_GET_STRUCT_TLVLEN
5246 			       (wmi_bcn_send_from_host_cmd_fixed_param));
5247 	cmd->vdev_id = param->vdev_id;
5248 	cmd->data_len = param->data_len;
5249 	cmd->frame_ctrl = param->frame_ctrl;
5250 	cmd->frag_ptr = param->frag_ptr;
5251 	cmd->dtim_flag = param->dtim_flag;
5252 
5253 	wmi_mtrace(WMI_PDEV_SEND_BCN_CMDID, cmd->vdev_id, 0);
5254 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd),
5255 				      WMI_PDEV_SEND_BCN_CMDID);
5256 
5257 	if (QDF_IS_STATUS_ERROR(ret)) {
5258 		WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command");
5259 		wmi_buf_free(wmi_buf);
5260 	}
5261 
5262 	return ret;
5263 }
5264 
5265 /**
5266  * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters
5267  * @wmi_handle: wmi handle
5268  * @vdev_id: vdev id
5269  * @max_retries: max retries
5270  * @retry_interval: retry interval
5271  * This function sets sta query related parameters in fw.
5272  *
5273  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5274  */
5275 
5276 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle,
5277 				       uint8_t vdev_id, uint32_t max_retries,
5278 					   uint32_t retry_interval)
5279 {
5280 	wmi_buf_t buf;
5281 	WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd;
5282 	int len;
5283 
5284 	len = sizeof(*cmd);
5285 	buf = wmi_buf_alloc(wmi_handle, len);
5286 	if (!buf) {
5287 		WMI_LOGE(FL("wmi_buf_alloc failed"));
5288 		return QDF_STATUS_E_FAILURE;
5289 	}
5290 
5291 	cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf);
5292 	WMITLV_SET_HDR(&cmd->tlv_header,
5293 		WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param,
5294 		WMITLV_GET_STRUCT_TLVLEN
5295 		(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param));
5296 
5297 
5298 	cmd->vdev_id = vdev_id;
5299 	cmd->sa_query_max_retry_count = max_retries;
5300 	cmd->sa_query_retry_interval = retry_interval;
5301 
5302 	WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"),
5303 		 vdev_id, retry_interval, max_retries);
5304 
5305 	wmi_mtrace(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID, cmd->vdev_id, 0);
5306 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
5307 				 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) {
5308 		WMI_LOGE(FL("Failed to offload STA SA Query"));
5309 		wmi_buf_free(buf);
5310 		return QDF_STATUS_E_FAILURE;
5311 	}
5312 
5313 	WMI_LOGD(FL("Exit :"));
5314 	return 0;
5315 }
5316 
5317 /**
5318  * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters
5319  * @wmi_handle: wmi handle
5320  * @params: sta keep alive parameter
5321  *
5322  * This function sets keep alive related parameters in fw.
5323  *
5324  * Return: CDF status
5325  */
5326 static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle,
5327 				struct sta_params *params)
5328 {
5329 	wmi_buf_t buf;
5330 	WMI_STA_KEEPALIVE_CMD_fixed_param *cmd;
5331 	WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp;
5332 	uint8_t *buf_ptr;
5333 	int len;
5334 	QDF_STATUS ret;
5335 
5336 	WMI_LOGD("%s: Enter", __func__);
5337 
5338 	len = sizeof(*cmd) + sizeof(*arp_rsp);
5339 	buf = wmi_buf_alloc(wmi_handle, len);
5340 	if (!buf) {
5341 		WMI_LOGE("wmi_buf_alloc failed");
5342 		return QDF_STATUS_E_FAILURE;
5343 	}
5344 
5345 	cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf);
5346 	buf_ptr = (uint8_t *) cmd;
5347 	WMITLV_SET_HDR(&cmd->tlv_header,
5348 		       WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param,
5349 		       WMITLV_GET_STRUCT_TLVLEN
5350 			       (WMI_STA_KEEPALIVE_CMD_fixed_param));
5351 	cmd->interval = params->timeperiod;
5352 	cmd->enable = (params->timeperiod) ? 1 : 0;
5353 	cmd->vdev_id = params->vdev_id;
5354 	WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id,
5355 		 params->timeperiod, params->method);
5356 	arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd));
5357 	WMITLV_SET_HDR(&arp_rsp->tlv_header,
5358 		       WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE,
5359 		       WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE));
5360 
5361 	if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) ||
5362 	    (params->method ==
5363 	     WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) {
5364 		if ((NULL == params->hostv4addr) ||
5365 			(NULL == params->destv4addr) ||
5366 			(NULL == params->destmac)) {
5367 			WMI_LOGE("%s: received null pointer, hostv4addr:%pK "
5368 			   "destv4addr:%pK destmac:%pK ", __func__,
5369 			   params->hostv4addr, params->destv4addr, params->destmac);
5370 			wmi_buf_free(buf);
5371 			return QDF_STATUS_E_FAILURE;
5372 		}
5373 		cmd->method = params->method;
5374 		qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr,
5375 			     WMI_IPV4_ADDR_LEN);
5376 		qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr,
5377 			     WMI_IPV4_ADDR_LEN);
5378 		WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr);
5379 	} else {
5380 		cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
5381 	}
5382 
5383 	wmi_mtrace(WMI_STA_KEEPALIVE_CMDID, cmd->vdev_id, 0);
5384 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5385 				 WMI_STA_KEEPALIVE_CMDID);
5386 	if (QDF_IS_STATUS_ERROR(ret)) {
5387 		WMI_LOGE("Failed to set KeepAlive");
5388 		wmi_buf_free(buf);
5389 	}
5390 
5391 	WMI_LOGD("%s: Exit", __func__);
5392 	return ret;
5393 }
5394 
5395 /**
5396  * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params
5397  * @wmi_handle: wmi handle
5398  * @if_id: vdev id
5399  * @gtx_info: GTX config params
5400  *
5401  * This function set GTX related params in firmware.
5402  *
5403  * Return: QDF_STATUS_SUCCESS for success or error code
5404  */
5405 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id,
5406 				  struct wmi_gtx_config *gtx_info)
5407 {
5408 	wmi_vdev_set_gtx_params_cmd_fixed_param *cmd;
5409 	wmi_buf_t buf;
5410 	QDF_STATUS ret;
5411 	int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param);
5412 
5413 	buf = wmi_buf_alloc(wmi_handle, len);
5414 	if (!buf) {
5415 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
5416 		return QDF_STATUS_E_NOMEM;
5417 	}
5418 	cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf);
5419 	WMITLV_SET_HDR(&cmd->tlv_header,
5420 		       WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param,
5421 		       WMITLV_GET_STRUCT_TLVLEN
5422 			       (wmi_vdev_set_gtx_params_cmd_fixed_param));
5423 	cmd->vdev_id = if_id;
5424 
5425 	cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0];
5426 	cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1];
5427 	cmd->userGtxMask = gtx_info->gtx_usrcfg;
5428 	cmd->gtxPERThreshold = gtx_info->gtx_threshold;
5429 	cmd->gtxPERMargin = gtx_info->gtx_margin;
5430 	cmd->gtxTPCstep = gtx_info->gtx_tpcstep;
5431 	cmd->gtxTPCMin = gtx_info->gtx_tpcmin;
5432 	cmd->gtxBWMask = gtx_info->gtx_bwmask;
5433 
5434 	WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \
5435 		gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \
5436 		gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1],
5437 		 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin,
5438 		 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask);
5439 
5440 	wmi_mtrace(WMI_VDEV_SET_GTX_PARAMS_CMDID, cmd->vdev_id, 0);
5441 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5442 				    WMI_VDEV_SET_GTX_PARAMS_CMDID);
5443 	if (QDF_IS_STATUS_ERROR(ret)) {
5444 		WMI_LOGE("Failed to set GTX PARAMS");
5445 		wmi_buf_free(buf);
5446 	}
5447 	return ret;
5448 }
5449 
5450 /**
5451  * send_process_update_edca_param_cmd_tlv() - update EDCA params
5452  * @wmi_handle: wmi handle
5453  * @vdev_id: vdev id.
5454  * @wmm_vparams: edca parameters
5455  *
5456  * This function updates EDCA parameters to the target
5457  *
5458  * Return: CDF Status
5459  */
5460 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle,
5461 				    uint8_t vdev_id, bool mu_edca_param,
5462 				    struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC])
5463 {
5464 	uint8_t *buf_ptr;
5465 	wmi_buf_t buf;
5466 	wmi_vdev_set_wmm_params_cmd_fixed_param *cmd;
5467 	wmi_wmm_vparams *wmm_param;
5468 	struct wmi_host_wme_vparams *twmm_param;
5469 	int len = sizeof(*cmd);
5470 	int ac;
5471 
5472 	buf = wmi_buf_alloc(wmi_handle, len);
5473 
5474 	if (!buf) {
5475 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
5476 		return QDF_STATUS_E_NOMEM;
5477 	}
5478 
5479 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
5480 	cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr;
5481 	WMITLV_SET_HDR(&cmd->tlv_header,
5482 		       WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param,
5483 		       WMITLV_GET_STRUCT_TLVLEN
5484 			       (wmi_vdev_set_wmm_params_cmd_fixed_param));
5485 	cmd->vdev_id = vdev_id;
5486 	cmd->wmm_param_type = mu_edca_param;
5487 
5488 	for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) {
5489 		wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]);
5490 		twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]);
5491 		WMITLV_SET_HDR(&wmm_param->tlv_header,
5492 			       WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param,
5493 			       WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams));
5494 		wmm_param->cwmin = twmm_param->cwmin;
5495 		wmm_param->cwmax = twmm_param->cwmax;
5496 		wmm_param->aifs = twmm_param->aifs;
5497 		if (mu_edca_param)
5498 			wmm_param->mu_edca_timer = twmm_param->mu_edca_timer;
5499 		else
5500 			wmm_param->txoplimit = twmm_param->txoplimit;
5501 		wmm_param->acm = twmm_param->acm;
5502 		wmm_param->no_ack = twmm_param->noackpolicy;
5503 	}
5504 
5505 	wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0);
5506 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
5507 				 WMI_VDEV_SET_WMM_PARAMS_CMDID))
5508 		goto fail;
5509 
5510 	return QDF_STATUS_SUCCESS;
5511 
5512 fail:
5513 	wmi_buf_free(buf);
5514 	WMI_LOGE("%s: Failed to set WMM Paremeters", __func__);
5515 	return QDF_STATUS_E_FAILURE;
5516 }
5517 
5518 /**
5519  * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw
5520  * @wmi_handle: wmi handle
5521  * @vdev_id: vdev id
5522  * @probe_rsp_info: probe response info
5523  *
5524  * Return: QDF_STATUS_SUCCESS for success or error code
5525  */
5526 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle,
5527 				   uint8_t vdev_id,
5528 				   struct wmi_probe_resp_params *probe_rsp_info)
5529 {
5530 	wmi_prb_tmpl_cmd_fixed_param *cmd;
5531 	wmi_bcn_prb_info *bcn_prb_info;
5532 	wmi_buf_t wmi_buf;
5533 	uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len;
5534 	uint8_t *buf_ptr;
5535 	QDF_STATUS ret;
5536 
5537 	WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id);
5538 
5539 	tmpl_len = probe_rsp_info->prb_rsp_template_len;
5540 	tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t));
5541 
5542 	wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) +
5543 			sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE +
5544 			tmpl_len_aligned;
5545 
5546 	if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) {
5547 		WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"),
5548 		wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE);
5549 		return QDF_STATUS_E_INVAL;
5550 	}
5551 
5552 	wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
5553 	if (!wmi_buf) {
5554 		WMI_LOGE(FL("wmi_buf_alloc failed"));
5555 		return QDF_STATUS_E_NOMEM;
5556 	}
5557 
5558 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
5559 
5560 	cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr;
5561 	WMITLV_SET_HDR(&cmd->tlv_header,
5562 		       WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param,
5563 		       WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param));
5564 	cmd->vdev_id = vdev_id;
5565 	cmd->buf_len = tmpl_len;
5566 	buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param);
5567 
5568 	bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr;
5569 	WMITLV_SET_HDR(&bcn_prb_info->tlv_header,
5570 		       WMITLV_TAG_STRUC_wmi_bcn_prb_info,
5571 		       WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info));
5572 	bcn_prb_info->caps = 0;
5573 	bcn_prb_info->erp = 0;
5574 	buf_ptr += sizeof(wmi_bcn_prb_info);
5575 
5576 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned);
5577 	buf_ptr += WMI_TLV_HDR_SIZE;
5578 	qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len);
5579 
5580 	wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0);
5581 	ret = wmi_unified_cmd_send(wmi_handle,
5582 				   wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID);
5583 	if (QDF_IS_STATUS_ERROR(ret)) {
5584 		WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret);
5585 		wmi_buf_free(wmi_buf);
5586 	}
5587 
5588 	return ret;
5589 }
5590 
5591 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI)
5592 #define WPI_IV_LEN 16
5593 
5594 /**
5595  * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters
5596  *
5597  * @dest_tx: destination address of tsc key counter
5598  * @src_tx: source address of tsc key counter
5599  * @dest_rx: destination address of rsc key counter
5600  * @src_rx: source address of rsc key counter
5601  *
5602  * This function copies WAPI tsc and rsc key counters in the wmi buffer.
5603  *
5604  * Return: None
5605  *
5606  */
5607 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx,
5608 					uint8_t *dest_rx, uint8_t *src_rx)
5609 {
5610 	qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN);
5611 	qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN);
5612 }
5613 #else
5614 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx,
5615 					uint8_t *dest_rx, uint8_t *src_rx)
5616 {
5617 	return;
5618 }
5619 #endif
5620 
5621 /**
5622  * send_setup_install_key_cmd_tlv() - set key parameters
5623  * @wmi_handle: wmi handle
5624  * @key_params: key parameters
5625  *
5626  * This function fills structure from information
5627  * passed in key_params.
5628  *
5629  * Return: QDF_STATUS_SUCCESS - success
5630  *         QDF_STATUS_E_FAILURE - failure
5631  *         QDF_STATUS_E_NOMEM - not able to allocate buffer
5632  */
5633 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle,
5634 					   struct set_key_params *key_params)
5635 {
5636 	wmi_vdev_install_key_cmd_fixed_param *cmd;
5637 	wmi_buf_t buf;
5638 	uint8_t *buf_ptr;
5639 	uint32_t len;
5640 	uint8_t *key_data;
5641 	QDF_STATUS status;
5642 
5643 	len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) +
5644 	       WMI_TLV_HDR_SIZE;
5645 
5646 	buf = wmi_buf_alloc(wmi_handle, len);
5647 	if (!buf) {
5648 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
5649 		return QDF_STATUS_E_NOMEM;
5650 	}
5651 
5652 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
5653 	cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr;
5654 	WMITLV_SET_HDR(&cmd->tlv_header,
5655 		       WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param,
5656 		       WMITLV_GET_STRUCT_TLVLEN
5657 			       (wmi_vdev_install_key_cmd_fixed_param));
5658 	cmd->vdev_id = key_params->vdev_id;
5659 	cmd->key_ix = key_params->key_idx;
5660 
5661 
5662 	WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr);
5663 	cmd->key_flags |= key_params->key_flags;
5664 	cmd->key_cipher = key_params->key_cipher;
5665 	if ((key_params->key_txmic_len) &&
5666 			(key_params->key_rxmic_len)) {
5667 		cmd->key_txmic_len = key_params->key_txmic_len;
5668 		cmd->key_rxmic_len = key_params->key_rxmic_len;
5669 	}
5670 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI)
5671 	wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter,
5672 				   key_params->tx_iv,
5673 				   cmd->wpi_key_rsc_counter,
5674 				   key_params->rx_iv);
5675 #endif
5676 	buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param);
5677 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5678 		       roundup(key_params->key_len, sizeof(uint32_t)));
5679 	key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
5680 	qdf_mem_copy((void *)key_data,
5681 		     (const void *)key_params->key_data, key_params->key_len);
5682 	if (key_params->key_rsc_counter)
5683 	    qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter,
5684 			 sizeof(wmi_key_seq_counter));
5685 	cmd->key_len = key_params->key_len;
5686 
5687 	wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0);
5688 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
5689 					      WMI_VDEV_INSTALL_KEY_CMDID);
5690 	if (QDF_IS_STATUS_ERROR(status))
5691 		wmi_buf_free(buf);
5692 
5693 	return status;
5694 }
5695 
5696 /**
5697  * send_sar_limit_cmd_tlv() - send sar limit cmd to fw
5698  * @wmi_handle: wmi handle
5699  * @params: sar limit params
5700  *
5701  * Return: QDF_STATUS_SUCCESS for success or error code
5702  */
5703 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle,
5704 		struct sar_limit_cmd_params *sar_limit_params)
5705 {
5706 	wmi_buf_t buf;
5707 	QDF_STATUS qdf_status;
5708 	wmi_sar_limits_cmd_fixed_param *cmd;
5709 	int i;
5710 	uint8_t *buf_ptr;
5711 	wmi_sar_limit_cmd_row *wmi_sar_rows_list;
5712 	struct sar_limit_cmd_row *sar_rows_list;
5713 	uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
5714 
5715 	len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows;
5716 	buf = wmi_buf_alloc(wmi_handle, len);
5717 	if (!buf) {
5718 		WMI_LOGE("Failed to allocate memory");
5719 		qdf_status = QDF_STATUS_E_NOMEM;
5720 		goto end;
5721 	}
5722 
5723 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
5724 	cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr;
5725 	WMITLV_SET_HDR(&cmd->tlv_header,
5726 		       WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param,
5727 		       WMITLV_GET_STRUCT_TLVLEN
5728 		       (wmi_sar_limits_cmd_fixed_param));
5729 	cmd->sar_enable = sar_limit_params->sar_enable;
5730 	cmd->commit_limits = sar_limit_params->commit_limits;
5731 	cmd->num_limit_rows = sar_limit_params->num_limit_rows;
5732 
5733 	WMI_LOGD("no of sar rows = %d, len = %d",
5734 		 sar_limit_params->num_limit_rows, len);
5735 	buf_ptr += sizeof(*cmd);
5736 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5737 		       sizeof(wmi_sar_limit_cmd_row) *
5738 			       sar_limit_params->num_limit_rows);
5739 	if (cmd->num_limit_rows == 0)
5740 		goto send_sar_limits;
5741 
5742 	wmi_sar_rows_list = (wmi_sar_limit_cmd_row *)
5743 			(buf_ptr + WMI_TLV_HDR_SIZE);
5744 	sar_rows_list = sar_limit_params->sar_limit_row_list;
5745 
5746 	for (i = 0; i < sar_limit_params->num_limit_rows; i++) {
5747 		WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header,
5748 			       WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row,
5749 			       WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row));
5750 		wmi_sar_rows_list->band_id = sar_rows_list->band_id;
5751 		wmi_sar_rows_list->chain_id = sar_rows_list->chain_id;
5752 		wmi_sar_rows_list->mod_id = sar_rows_list->mod_id;
5753 		wmi_sar_rows_list->limit_value = sar_rows_list->limit_value;
5754 		wmi_sar_rows_list->validity_bitmap =
5755 						sar_rows_list->validity_bitmap;
5756 		WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d",
5757 			 i, wmi_sar_rows_list->band_id,
5758 			 wmi_sar_rows_list->chain_id,
5759 			 wmi_sar_rows_list->mod_id,
5760 			 wmi_sar_rows_list->limit_value,
5761 			 wmi_sar_rows_list->validity_bitmap);
5762 		sar_rows_list++;
5763 		wmi_sar_rows_list++;
5764 	}
5765 send_sar_limits:
5766 	wmi_mtrace(WMI_SAR_LIMITS_CMDID, NO_SESSION, 0);
5767 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
5768 				      WMI_SAR_LIMITS_CMDID);
5769 
5770 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
5771 		WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID");
5772 		wmi_buf_free(buf);
5773 	}
5774 
5775 end:
5776 	return qdf_status;
5777 }
5778 
5779 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle)
5780 {
5781 	wmi_sar_get_limits_cmd_fixed_param *cmd;
5782 	wmi_buf_t wmi_buf;
5783 	uint32_t len;
5784 	QDF_STATUS status;
5785 
5786 	WMI_LOGD(FL("Enter"));
5787 
5788 	len = sizeof(*cmd);
5789 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
5790 	if (!wmi_buf) {
5791 		WMI_LOGP(FL("failed to allocate memory for msg"));
5792 		return QDF_STATUS_E_NOMEM;
5793 	}
5794 
5795 	cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf);
5796 
5797 	WMITLV_SET_HDR(&cmd->tlv_header,
5798 		       WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param,
5799 		       WMITLV_GET_STRUCT_TLVLEN
5800 				(wmi_sar_get_limits_cmd_fixed_param));
5801 
5802 	cmd->reserved = 0;
5803 
5804 	wmi_mtrace(WMI_SAR_GET_LIMITS_CMDID, NO_SESSION, 0);
5805 	status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
5806 				      WMI_SAR_GET_LIMITS_CMDID);
5807 	if (QDF_IS_STATUS_ERROR(status)) {
5808 		WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status);
5809 		wmi_buf_free(wmi_buf);
5810 	}
5811 
5812 	WMI_LOGD(FL("Exit"));
5813 
5814 	return status;
5815 }
5816 
5817 /**
5818  * wmi_sar2_result_string() - return string conversion of sar2 result
5819  * @result: sar2 result value
5820  *
5821  * This utility function helps log string conversion of sar2 result.
5822  *
5823  * Return: string conversion of sar 2 result, if match found;
5824  *	   "Unknown response" otherwise.
5825  */
5826 static const char *wmi_sar2_result_string(uint32_t result)
5827 {
5828 	switch (result) {
5829 	CASE_RETURN_STRING(WMI_SAR2_SUCCESS);
5830 	CASE_RETURN_STRING(WMI_SAR2_INVALID_ANTENNA_INDEX);
5831 	CASE_RETURN_STRING(WMI_SAR2_INVALID_TABLE_INDEX);
5832 	CASE_RETURN_STRING(WMI_SAR2_STATE_ERROR);
5833 	CASE_RETURN_STRING(WMI_SAR2_BDF_NO_TABLE);
5834 	default:
5835 		return "Unknown response";
5836 	}
5837 }
5838 
5839 /**
5840  * extract_sar2_result_event_tlv() -  process sar response event from FW.
5841  * @handle: wma handle
5842  * @event: event buffer
5843  * @len: buffer length
5844  *
5845  * Return: 0 for success or error code
5846  */
5847 static QDF_STATUS extract_sar2_result_event_tlv(void *handle,
5848 						uint8_t *event,
5849 						uint32_t len)
5850 {
5851 	wmi_sar2_result_event_fixed_param *sar2_fixed_param;
5852 
5853 	WMI_SAR2_RESULT_EVENTID_param_tlvs *param_buf =
5854 		(WMI_SAR2_RESULT_EVENTID_param_tlvs *)event;
5855 
5856 	if (!param_buf) {
5857 		WMI_LOGI("Invalid sar2 result event buffer");
5858 		return QDF_STATUS_E_INVAL;
5859 	}
5860 
5861 	sar2_fixed_param = param_buf->fixed_param;
5862 	if (!sar2_fixed_param) {
5863 		WMI_LOGI("Invalid sar2 result event fixed param buffer");
5864 		return QDF_STATUS_E_INVAL;
5865 	}
5866 
5867 	WMI_LOGI("SAR2 result: %s",
5868 		 wmi_sar2_result_string(sar2_fixed_param->result));
5869 
5870 	return QDF_STATUS_SUCCESS;
5871 }
5872 
5873 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle,
5874 					      uint8_t *evt_buf,
5875 					      struct sar_limit_event *event)
5876 {
5877 	wmi_sar_get_limits_event_fixed_param *fixed_param;
5878 	WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf;
5879 	wmi_sar_get_limit_event_row *row_in;
5880 	struct sar_limit_event_row *row_out;
5881 	uint32_t row;
5882 
5883 	if (!evt_buf) {
5884 		WMI_LOGE(FL("input event is NULL"));
5885 		return QDF_STATUS_E_INVAL;
5886 	}
5887 	if (!event) {
5888 		WMI_LOGE(FL("output event is NULL"));
5889 		return QDF_STATUS_E_INVAL;
5890 	}
5891 
5892 	param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf;
5893 
5894 	fixed_param = param_buf->fixed_param;
5895 	if (!fixed_param) {
5896 		WMI_LOGE(FL("Invalid fixed param"));
5897 		return QDF_STATUS_E_INVAL;
5898 	}
5899 
5900 	event->sar_enable = fixed_param->sar_enable;
5901 	event->num_limit_rows = fixed_param->num_limit_rows;
5902 
5903 	if (event->num_limit_rows > param_buf->num_sar_get_limits) {
5904 		WMI_LOGE(FL("Num rows %d exceeds sar_get_limits rows len %d"),
5905 			 event->num_limit_rows, param_buf->num_sar_get_limits);
5906 		return QDF_STATUS_E_INVAL;
5907 	}
5908 
5909 	if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) {
5910 		QDF_ASSERT(0);
5911 		WMI_LOGE(FL("Num rows %d exceeds max of %d"),
5912 			 event->num_limit_rows,
5913 			 MAX_SAR_LIMIT_ROWS_SUPPORTED);
5914 		event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED;
5915 	}
5916 
5917 	row_in = param_buf->sar_get_limits;
5918 	row_out = &event->sar_limit_row[0];
5919 	for (row = 0; row < event->num_limit_rows; row++) {
5920 		row_out->band_id = row_in->band_id;
5921 		row_out->chain_id = row_in->chain_id;
5922 		row_out->mod_id = row_in->mod_id;
5923 		row_out->limit_value = row_in->limit_value;
5924 		row_out++;
5925 		row_in++;
5926 	}
5927 
5928 	return QDF_STATUS_SUCCESS;
5929 }
5930 
5931 #ifdef WLAN_FEATURE_DISA
5932 /**
5933  * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw
5934  * @wmi_handle: wmi handle
5935  * @params: encrypt/decrypt params
5936  *
5937  * Return: QDF_STATUS_SUCCESS for success or error code
5938  */
5939 static
5940 QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle,
5941 		struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params)
5942 {
5943 	wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd;
5944 	wmi_buf_t wmi_buf;
5945 	uint8_t *buf_ptr;
5946 	QDF_STATUS ret;
5947 	uint32_t len;
5948 
5949 	WMI_LOGD(FL("Send encrypt decrypt cmd"));
5950 
5951 	len = sizeof(*cmd) +
5952 		roundup(encrypt_decrypt_params->data_len, sizeof(uint32_t)) +
5953 		WMI_TLV_HDR_SIZE;
5954 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
5955 	if (!wmi_buf) {
5956 		WMI_LOGP("%s: failed to allocate memory for encrypt/decrypt msg",
5957 			 __func__);
5958 		return QDF_STATUS_E_NOMEM;
5959 	}
5960 
5961 	buf_ptr = wmi_buf_data(wmi_buf);
5962 	cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr;
5963 
5964 	WMITLV_SET_HDR(&cmd->tlv_header,
5965 		WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param,
5966 		WMITLV_GET_STRUCT_TLVLEN(
5967 			wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param));
5968 
5969 	cmd->vdev_id = encrypt_decrypt_params->vdev_id;
5970 	cmd->key_flag = encrypt_decrypt_params->key_flag;
5971 	cmd->key_idx = encrypt_decrypt_params->key_idx;
5972 	cmd->key_cipher = encrypt_decrypt_params->key_cipher;
5973 	cmd->key_len = encrypt_decrypt_params->key_len;
5974 	cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len;
5975 	cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len;
5976 
5977 	qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data,
5978 				encrypt_decrypt_params->key_len);
5979 
5980 	qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header,
5981 				MAX_MAC_HEADER_LEN);
5982 
5983 	cmd->data_len = encrypt_decrypt_params->data_len;
5984 
5985 	if (cmd->data_len) {
5986 		buf_ptr += sizeof(*cmd);
5987 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5988 				roundup(encrypt_decrypt_params->data_len,
5989 					sizeof(uint32_t)));
5990 		buf_ptr += WMI_TLV_HDR_SIZE;
5991 		qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data,
5992 					encrypt_decrypt_params->data_len);
5993 	}
5994 
5995 	/* This conversion is to facilitate data to FW in little endian */
5996 	cmd->pn[5] = encrypt_decrypt_params->pn[0];
5997 	cmd->pn[4] = encrypt_decrypt_params->pn[1];
5998 	cmd->pn[3] = encrypt_decrypt_params->pn[2];
5999 	cmd->pn[2] = encrypt_decrypt_params->pn[3];
6000 	cmd->pn[1] = encrypt_decrypt_params->pn[4];
6001 	cmd->pn[0] = encrypt_decrypt_params->pn[5];
6002 
6003 	wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0);
6004 	ret = wmi_unified_cmd_send(wmi_handle,
6005 				   wmi_buf, len,
6006 				   WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID);
6007 	if (QDF_IS_STATUS_ERROR(ret)) {
6008 		WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret);
6009 		wmi_buf_free(wmi_buf);
6010 	}
6011 
6012 	return ret;
6013 }
6014 
6015 /**
6016  * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp
6017  *	params from event
6018  * @wmi_handle: wmi handle
6019  * @evt_buf: pointer to event buffer
6020  * @resp: Pointer to hold resp parameters
6021  *
6022  * Return: QDF_STATUS_SUCCESS for success or error code
6023  */
6024 static
6025 QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle,
6026 	void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp)
6027 {
6028 	WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf;
6029 	wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event;
6030 
6031 	param_buf = evt_buf;
6032 	if (!param_buf) {
6033 		WMI_LOGE("encrypt decrypt resp evt_buf is NULL");
6034 		return QDF_STATUS_E_INVAL;
6035 	}
6036 
6037 	data_event = param_buf->fixed_param;
6038 
6039 	resp->vdev_id = data_event->vdev_id;
6040 	resp->status = data_event->status;
6041 
6042 	if ((data_event->data_length > param_buf->num_enc80211_frame) ||
6043 	    (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE -
6044 	     sizeof(*data_event))) {
6045 		WMI_LOGE("FW msg data_len %d more than TLV hdr %d",
6046 			 data_event->data_length,
6047 			 param_buf->num_enc80211_frame);
6048 		return QDF_STATUS_E_INVAL;
6049 	}
6050 
6051 	resp->data_len = data_event->data_length;
6052 
6053 	if (resp->data_len)
6054 		resp->data = (uint8_t *)param_buf->enc80211_frame;
6055 
6056 	return QDF_STATUS_SUCCESS;
6057 }
6058 #endif
6059 
6060 /**
6061  * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go
6062  * @wmi_handle: wmi handle
6063  * @vdev_id: vdev id
6064  * @p2p_ie: p2p IE
6065  *
6066  * Return: QDF_STATUS_SUCCESS for success or error code
6067  */
6068 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle,
6069 				    uint32_t vdev_id, uint8_t *p2p_ie)
6070 {
6071 	QDF_STATUS ret;
6072 	wmi_p2p_go_set_beacon_ie_fixed_param *cmd;
6073 	wmi_buf_t wmi_buf;
6074 	uint32_t ie_len, ie_len_aligned, wmi_buf_len;
6075 	uint8_t *buf_ptr;
6076 
6077 	ie_len = (uint32_t) (p2p_ie[1] + 2);
6078 
6079 	/* More than one P2P IE may be included in a single frame.
6080 	   If multiple P2P IEs are present, the complete P2P attribute
6081 	   data consists of the concatenation of the P2P Attribute
6082 	   fields of the P2P IEs. The P2P Attributes field of each
6083 	   P2P IE may be any length up to the maximum (251 octets).
6084 	   In this case host sends one P2P IE to firmware so the length
6085 	   should not exceed more than 251 bytes
6086 	 */
6087 	if (ie_len > 251) {
6088 		WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len);
6089 		return QDF_STATUS_E_INVAL;
6090 	}
6091 
6092 	ie_len_aligned = roundup(ie_len, sizeof(uint32_t));
6093 
6094 	wmi_buf_len =
6095 		sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned +
6096 		WMI_TLV_HDR_SIZE;
6097 
6098 	wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
6099 	if (!wmi_buf) {
6100 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6101 		return QDF_STATUS_E_NOMEM;
6102 	}
6103 
6104 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
6105 
6106 	cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr;
6107 	WMITLV_SET_HDR(&cmd->tlv_header,
6108 		       WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param,
6109 		       WMITLV_GET_STRUCT_TLVLEN
6110 			       (wmi_p2p_go_set_beacon_ie_fixed_param));
6111 	cmd->vdev_id = vdev_id;
6112 	cmd->ie_buf_len = ie_len;
6113 
6114 	buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param);
6115 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
6116 	buf_ptr += WMI_TLV_HDR_SIZE;
6117 	qdf_mem_copy(buf_ptr, p2p_ie, ie_len);
6118 
6119 	WMI_LOGD("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__);
6120 
6121 	wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0);
6122 	ret = wmi_unified_cmd_send(wmi_handle,
6123 				   wmi_buf, wmi_buf_len,
6124 				   WMI_P2P_GO_SET_BEACON_IE);
6125 	if (QDF_IS_STATUS_ERROR(ret)) {
6126 		WMI_LOGE("Failed to send bcn tmpl: %d", ret);
6127 		wmi_buf_free(wmi_buf);
6128 	}
6129 
6130 	WMI_LOGD("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__);
6131 	return ret;
6132 }
6133 
6134 /**
6135  * send_set_gateway_params_cmd_tlv() - set gateway parameters
6136  * @wmi_handle: wmi handle
6137  * @req: gateway parameter update request structure
6138  *
6139  * This function reads the incoming @req and fill in the destination
6140  * WMI structure and sends down the gateway configs down to the firmware
6141  *
6142  * Return: QDF_STATUS
6143  */
6144 static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle,
6145 				struct gateway_update_req_param *req)
6146 {
6147 	wmi_roam_subnet_change_config_fixed_param *cmd;
6148 	wmi_buf_t buf;
6149 	QDF_STATUS ret;
6150 	int len = sizeof(*cmd);
6151 
6152 	buf = wmi_buf_alloc(wmi_handle, len);
6153 	if (!buf) {
6154 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
6155 		return QDF_STATUS_E_NOMEM;
6156 	}
6157 
6158 	cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf);
6159 	WMITLV_SET_HDR(&cmd->tlv_header,
6160 		WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param,
6161 		WMITLV_GET_STRUCT_TLVLEN(
6162 			wmi_roam_subnet_change_config_fixed_param));
6163 
6164 	cmd->vdev_id = req->session_id;
6165 	qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr,
6166 		QDF_IPV4_ADDR_SIZE);
6167 	qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr,
6168 		QDF_IPV6_ADDR_SIZE);
6169 	WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes,
6170 		&cmd->inet_gw_mac_addr);
6171 	cmd->max_retries = req->max_retries;
6172 	cmd->timeout = req->timeout;
6173 	cmd->num_skip_subnet_change_detection_bssid_list = 0;
6174 	cmd->flag = 0;
6175 	if (req->ipv4_addr_type)
6176 		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag);
6177 
6178 	if (req->ipv6_addr_type)
6179 		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag);
6180 
6181 	wmi_mtrace(WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID, cmd->vdev_id, 0);
6182 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6183 				WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID);
6184 	if (QDF_IS_STATUS_ERROR(ret)) {
6185 		WMI_LOGE("Failed to send gw config parameter to fw, ret: %d",
6186 			ret);
6187 		wmi_buf_free(buf);
6188 	}
6189 
6190 	return ret;
6191 }
6192 
6193 /**
6194  * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring
6195  * @wmi_handle: wmi handle
6196  * @req: rssi monitoring request structure
6197  *
6198  * This function reads the incoming @req and fill in the destination
6199  * WMI structure and send down the rssi monitoring configs down to the firmware
6200  *
6201  * Return: 0 on success; error number otherwise
6202  */
6203 static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle,
6204 					struct rssi_monitor_param *req)
6205 {
6206 	wmi_rssi_breach_monitor_config_fixed_param *cmd;
6207 	wmi_buf_t buf;
6208 	QDF_STATUS ret;
6209 	uint32_t len = sizeof(*cmd);
6210 
6211 	buf = wmi_buf_alloc(wmi_handle, len);
6212 	if (!buf) {
6213 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
6214 		return QDF_STATUS_E_NOMEM;
6215 	}
6216 
6217 	cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf);
6218 	WMITLV_SET_HDR(&cmd->tlv_header,
6219 		WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param,
6220 		WMITLV_GET_STRUCT_TLVLEN(
6221 			wmi_rssi_breach_monitor_config_fixed_param));
6222 
6223 	cmd->vdev_id = req->session_id;
6224 	cmd->request_id = req->request_id;
6225 	cmd->lo_rssi_reenable_hysteresis = 0;
6226 	cmd->hi_rssi_reenable_histeresis = 0;
6227 	cmd->min_report_interval = 0;
6228 	cmd->max_num_report = 1;
6229 	if (req->control) {
6230 		/* enable one threshold for each min/max */
6231 		cmd->enabled_bitmap = 0x09;
6232 		cmd->low_rssi_breach_threshold[0] = req->min_rssi;
6233 		cmd->hi_rssi_breach_threshold[0] = req->max_rssi;
6234 	} else {
6235 		cmd->enabled_bitmap = 0;
6236 		cmd->low_rssi_breach_threshold[0] = 0;
6237 		cmd->hi_rssi_breach_threshold[0] = 0;
6238 	}
6239 
6240 	wmi_mtrace(WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID, cmd->vdev_id, 0);
6241 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6242 				   WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID);
6243 	if (QDF_IS_STATUS_ERROR(ret)) {
6244 		WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID");
6245 		wmi_buf_free(buf);
6246 	}
6247 
6248 	WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW");
6249 
6250 	return ret;
6251 }
6252 
6253 /**
6254  * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI
6255  * @wmi_handle: wmi handle
6256  * @psetoui: OUI parameters
6257  *
6258  * set scan probe OUI parameters in firmware
6259  *
6260  * Return: CDF status
6261  */
6262 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle,
6263 			  struct scan_mac_oui *psetoui)
6264 {
6265 	wmi_scan_prob_req_oui_cmd_fixed_param *cmd;
6266 	wmi_buf_t wmi_buf;
6267 	uint32_t len;
6268 	uint8_t *buf_ptr;
6269 	uint32_t *oui_buf;
6270 	struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist;
6271 
6272 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
6273 		ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui);
6274 
6275 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
6276 	if (!wmi_buf) {
6277 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
6278 		return QDF_STATUS_E_NOMEM;
6279 	}
6280 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
6281 	cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr;
6282 	WMITLV_SET_HDR(&cmd->tlv_header,
6283 		       WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param,
6284 		       WMITLV_GET_STRUCT_TLVLEN
6285 			       (wmi_scan_prob_req_oui_cmd_fixed_param));
6286 
6287 	oui_buf = &cmd->prob_req_oui;
6288 	qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui));
6289 	*oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8
6290 		   | psetoui->oui[2];
6291 	WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__,
6292 		 cmd->prob_req_oui);
6293 
6294 	cmd->vdev_id = psetoui->vdev_id;
6295 	cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ;
6296 	if (psetoui->enb_probe_req_sno_randomization)
6297 		cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ;
6298 
6299 	if (ie_whitelist->white_list) {
6300 		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
6301 					    &cmd->num_vendor_oui,
6302 					    ie_whitelist);
6303 		cmd->flags |=
6304 			WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ;
6305 	}
6306 
6307 	buf_ptr += sizeof(*cmd);
6308 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6309 		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
6310 	buf_ptr += WMI_TLV_HDR_SIZE;
6311 
6312 	if (cmd->num_vendor_oui != 0) {
6313 		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
6314 				    ie_whitelist->voui);
6315 		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
6316 	}
6317 
6318 	wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0);
6319 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
6320 				 WMI_SCAN_PROB_REQ_OUI_CMDID)) {
6321 		WMI_LOGE("%s: failed to send command", __func__);
6322 		wmi_buf_free(wmi_buf);
6323 		return QDF_STATUS_E_FAILURE;
6324 	}
6325 	return QDF_STATUS_SUCCESS;
6326 }
6327 
6328 #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
6329 /**
6330  * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command
6331  * @wmi_handle: wmi handle
6332  * @roam_req: Roam scan offload params
6333  * @buf_ptr: command buffer to send
6334  * @fils_tlv_len: fils tlv length
6335  *
6336  * Return: Updated buffer pointer
6337  */
6338 static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
6339 			     struct roam_offload_scan_params *roam_req,
6340 			     uint8_t *buf_ptr, uint32_t fils_tlv_len)
6341 {
6342 	wmi_roam_fils_offload_tlv_param *fils_tlv;
6343 	wmi_erp_info *erp_info;
6344 	struct roam_fils_params *roam_fils_params;
6345 
6346 	if (!roam_req->add_fils_tlv)
6347 		return buf_ptr;
6348 
6349 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6350 			sizeof(*fils_tlv));
6351 	buf_ptr += WMI_TLV_HDR_SIZE;
6352 
6353 	fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr;
6354 	WMITLV_SET_HDR(&fils_tlv->tlv_header,
6355 			WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param,
6356 			WMITLV_GET_STRUCT_TLVLEN
6357 				(wmi_roam_fils_offload_tlv_param));
6358 
6359 	roam_fils_params = &roam_req->roam_fils_params;
6360 	erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info);
6361 
6362 	erp_info->username_length = roam_fils_params->username_length;
6363 	qdf_mem_copy(erp_info->username, roam_fils_params->username,
6364 				erp_info->username_length);
6365 
6366 	erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num;
6367 
6368 	erp_info->rRk_length = roam_fils_params->rrk_length;
6369 	qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk,
6370 				erp_info->rRk_length);
6371 
6372 	erp_info->rIk_length = roam_fils_params->rik_length;
6373 	qdf_mem_copy(erp_info->rIk, roam_fils_params->rik,
6374 				erp_info->rIk_length);
6375 
6376 	erp_info->realm_len = roam_fils_params->realm_len;
6377 	qdf_mem_copy(erp_info->realm, roam_fils_params->realm,
6378 				erp_info->realm_len);
6379 
6380 	buf_ptr += sizeof(*fils_tlv);
6381 	return buf_ptr;
6382 }
6383 #else
6384 static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
6385 				struct roam_offload_scan_params *roam_req,
6386 				uint8_t *buf_ptr, uint32_t fils_tlv_len)
6387 {
6388 	return buf_ptr;
6389 }
6390 #endif
6391 /**
6392  * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw
6393  * @wmi_handle: wmi handle
6394  * @scan_cmd_fp: start scan command ptr
6395  * @roam_req: roam request param
6396  *
6397  * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
6398  * of WMI_ROAM_SCAN_MODE.
6399  *
6400  * Return: QDF status
6401  */
6402 static QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle,
6403 				      wmi_start_scan_cmd_fixed_param *
6404 				      scan_cmd_fp,
6405 				      struct roam_offload_scan_params *roam_req)
6406 {
6407 	wmi_buf_t buf = NULL;
6408 	QDF_STATUS status;
6409 	int len;
6410 	uint8_t *buf_ptr;
6411 	wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp;
6412 
6413 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6414 	int auth_mode = roam_req->auth_mode;
6415 	roam_offload_param *req_offload_params =
6416 		&roam_req->roam_offload_params;
6417 	wmi_roam_offload_tlv_param *roam_offload_params;
6418 	wmi_roam_11i_offload_tlv_param *roam_offload_11i;
6419 	wmi_roam_11r_offload_tlv_param *roam_offload_11r;
6420 	wmi_roam_ese_offload_tlv_param *roam_offload_ese;
6421 	wmi_tlv_buf_len_param *assoc_ies;
6422 	uint32_t fils_tlv_len = 0;
6423 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6424 	/* Need to create a buf with roam_scan command at
6425 	 * front and piggyback with scan command */
6426 	len = sizeof(wmi_roam_scan_mode_fixed_param) +
6427 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6428 	      (2 * WMI_TLV_HDR_SIZE) +
6429 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6430 	      sizeof(wmi_start_scan_cmd_fixed_param);
6431 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6432 	WMI_LOGD("auth_mode = %d", auth_mode);
6433 		if (roam_req->is_roam_req_valid &&
6434 				roam_req->roam_offload_enabled) {
6435 			len += sizeof(wmi_roam_offload_tlv_param);
6436 			len += WMI_TLV_HDR_SIZE;
6437 			if ((auth_mode != WMI_AUTH_NONE) &&
6438 				((auth_mode != WMI_AUTH_OPEN) ||
6439 				 (auth_mode == WMI_AUTH_OPEN &&
6440 				  roam_req->mdid.mdie_present &&
6441 				  roam_req->is_11r_assoc) ||
6442 				  roam_req->is_ese_assoc)) {
6443 				len += WMI_TLV_HDR_SIZE;
6444 				if (roam_req->is_ese_assoc)
6445 					len +=
6446 					sizeof(wmi_roam_ese_offload_tlv_param);
6447 				else if (auth_mode == WMI_AUTH_FT_RSNA ||
6448 					 auth_mode == WMI_AUTH_FT_RSNA_PSK ||
6449 					 (auth_mode == WMI_AUTH_OPEN &&
6450 					  roam_req->mdid.mdie_present &&
6451 					  roam_req->is_11r_assoc))
6452 					len +=
6453 					sizeof(wmi_roam_11r_offload_tlv_param);
6454 				else
6455 					len +=
6456 					sizeof(wmi_roam_11i_offload_tlv_param);
6457 			} else {
6458 				len += WMI_TLV_HDR_SIZE;
6459 			}
6460 
6461 			len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE)
6462 					+ roundup(roam_req->assoc_ie_length,
6463 					sizeof(uint32_t)));
6464 
6465 			if (roam_req->add_fils_tlv) {
6466 				fils_tlv_len = sizeof(
6467 					wmi_roam_fils_offload_tlv_param);
6468 				len += WMI_TLV_HDR_SIZE + fils_tlv_len;
6469 			}
6470 		} else {
6471 			if (roam_req->is_roam_req_valid)
6472 				WMI_LOGD("%s : roam offload = %d",
6473 				     __func__, roam_req->roam_offload_enabled);
6474 			else
6475 				WMI_LOGD("%s : roam_req is NULL", __func__);
6476 			len += (4 * WMI_TLV_HDR_SIZE);
6477 		}
6478 		if (roam_req->is_roam_req_valid &&
6479 				roam_req->roam_offload_enabled) {
6480 			roam_req->mode = roam_req->mode |
6481 				WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
6482 		}
6483 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6484 
6485 	if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE
6486 				|WMI_ROAM_SCAN_MODE_ROAMOFFLOAD))
6487 		len = sizeof(wmi_roam_scan_mode_fixed_param);
6488 
6489 	buf = wmi_buf_alloc(wmi_handle, len);
6490 	if (!buf) {
6491 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6492 		return QDF_STATUS_E_NOMEM;
6493 	}
6494 
6495 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6496 	roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr;
6497 	WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header,
6498 		       WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param,
6499 		       WMITLV_GET_STRUCT_TLVLEN
6500 			       (wmi_roam_scan_mode_fixed_param));
6501 
6502 	roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask =
6503 			roam_req->roam_trigger_reason_bitmask;
6504 	roam_scan_mode_fp->min_delay_btw_scans =
6505 			WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans);
6506 	roam_scan_mode_fp->roam_scan_mode = roam_req->mode;
6507 	roam_scan_mode_fp->vdev_id = roam_req->vdev_id;
6508 	if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE |
6509 			WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) {
6510 		roam_scan_mode_fp->flags |=
6511 			WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS;
6512 		goto send_roam_scan_mode_cmd;
6513 	}
6514 
6515 	/* Fill in scan parameters suitable for roaming scan */
6516 	buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param);
6517 
6518 	qdf_mem_copy(buf_ptr, scan_cmd_fp,
6519 		     sizeof(wmi_start_scan_cmd_fixed_param));
6520 	/* Ensure there is no additional IEs */
6521 	scan_cmd_fp->ie_len = 0;
6522 	WMITLV_SET_HDR(buf_ptr,
6523 		       WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
6524 		       WMITLV_GET_STRUCT_TLVLEN
6525 			       (wmi_start_scan_cmd_fixed_param));
6526 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6527 	buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param);
6528 	if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) {
6529 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6530 			       sizeof(wmi_roam_offload_tlv_param));
6531 		buf_ptr += WMI_TLV_HDR_SIZE;
6532 		roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr;
6533 		WMITLV_SET_HDR(buf_ptr,
6534 			       WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param,
6535 			       WMITLV_GET_STRUCT_TLVLEN
6536 				       (wmi_roam_offload_tlv_param));
6537 		roam_offload_params->prefer_5g = roam_req->prefer_5ghz;
6538 		roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap;
6539 		roam_offload_params->select_5g_margin =
6540 			roam_req->select_5ghz_margin;
6541 		roam_offload_params->handoff_delay_for_rx =
6542 			req_offload_params->ho_delay_for_rx;
6543 		roam_offload_params->max_mlme_sw_retries =
6544 			req_offload_params->roam_preauth_retry_count;
6545 		roam_offload_params->no_ack_timeout =
6546 			req_offload_params->roam_preauth_no_ack_timeout;
6547 		roam_offload_params->reassoc_failure_timeout =
6548 			roam_req->reassoc_failure_timeout;
6549 
6550 		/* Fill the capabilities */
6551 		roam_offload_params->capability =
6552 				req_offload_params->capability;
6553 		roam_offload_params->ht_caps_info =
6554 				req_offload_params->ht_caps_info;
6555 		roam_offload_params->ampdu_param =
6556 				req_offload_params->ampdu_param;
6557 		roam_offload_params->ht_ext_cap =
6558 				req_offload_params->ht_ext_cap;
6559 		roam_offload_params->ht_txbf = req_offload_params->ht_txbf;
6560 		roam_offload_params->asel_cap = req_offload_params->asel_cap;
6561 		roam_offload_params->qos_caps = req_offload_params->qos_caps;
6562 		roam_offload_params->qos_enabled =
6563 				req_offload_params->qos_enabled;
6564 		roam_offload_params->wmm_caps = req_offload_params->wmm_caps;
6565 		qdf_mem_copy((uint8_t *)roam_offload_params->mcsset,
6566 				(uint8_t *)req_offload_params->mcsset,
6567 				ROAM_OFFLOAD_NUM_MCS_SET);
6568 
6569 		buf_ptr += sizeof(wmi_roam_offload_tlv_param);
6570 		/* The TLV's are in the order of 11i, 11R, ESE. Hence,
6571 		 * they are filled in the same order.Depending on the
6572 		 * authentication type, the other mode TLV's are nullified
6573 		 * and only headers are filled.*/
6574 		if ((auth_mode != WMI_AUTH_NONE) &&
6575 		    ((auth_mode != WMI_AUTH_OPEN) ||
6576 		     (auth_mode == WMI_AUTH_OPEN
6577 		      && roam_req->mdid.mdie_present &&
6578 		      roam_req->is_11r_assoc) ||
6579 			roam_req->is_ese_assoc)) {
6580 			if (roam_req->is_ese_assoc) {
6581 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6582 					       WMITLV_GET_STRUCT_TLVLEN(0));
6583 				buf_ptr += WMI_TLV_HDR_SIZE;
6584 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6585 					       WMITLV_GET_STRUCT_TLVLEN(0));
6586 				buf_ptr += WMI_TLV_HDR_SIZE;
6587 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6588 					sizeof(wmi_roam_ese_offload_tlv_param));
6589 				buf_ptr += WMI_TLV_HDR_SIZE;
6590 				roam_offload_ese =
6591 				    (wmi_roam_ese_offload_tlv_param *) buf_ptr;
6592 				qdf_mem_copy(roam_offload_ese->krk,
6593 					     roam_req->krk,
6594 					     sizeof(roam_req->krk));
6595 				qdf_mem_copy(roam_offload_ese->btk,
6596 					     roam_req->btk,
6597 					     sizeof(roam_req->btk));
6598 				WMITLV_SET_HDR(&roam_offload_ese->tlv_header,
6599 				WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param,
6600 				WMITLV_GET_STRUCT_TLVLEN
6601 				(wmi_roam_ese_offload_tlv_param));
6602 				buf_ptr +=
6603 					sizeof(wmi_roam_ese_offload_tlv_param);
6604 			} else if (auth_mode == WMI_AUTH_FT_RSNA
6605 				   || auth_mode == WMI_AUTH_FT_RSNA_PSK
6606 				   || (auth_mode == WMI_AUTH_OPEN
6607 				       && roam_req->mdid.mdie_present &&
6608 				       roam_req->is_11r_assoc)) {
6609 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6610 					       0);
6611 				buf_ptr += WMI_TLV_HDR_SIZE;
6612 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6613 					sizeof(wmi_roam_11r_offload_tlv_param));
6614 				buf_ptr += WMI_TLV_HDR_SIZE;
6615 				roam_offload_11r =
6616 				    (wmi_roam_11r_offload_tlv_param *) buf_ptr;
6617 				roam_offload_11r->r0kh_id_len =
6618 					roam_req->rokh_id_length;
6619 				qdf_mem_copy(roam_offload_11r->r0kh_id,
6620 					     roam_req->rokh_id,
6621 					     roam_offload_11r->r0kh_id_len);
6622 				qdf_mem_copy(roam_offload_11r->psk_msk,
6623 					     roam_req->psk_pmk,
6624 					     sizeof(roam_req->psk_pmk));
6625 				roam_offload_11r->psk_msk_len =
6626 					roam_req->pmk_len;
6627 				roam_offload_11r->mdie_present =
6628 					roam_req->mdid.mdie_present;
6629 				roam_offload_11r->mdid =
6630 					roam_req->mdid.mobility_domain;
6631 				if (auth_mode == WMI_AUTH_OPEN) {
6632 					/* If FT-Open ensure pmk length
6633 					   and r0khid len are zero */
6634 					roam_offload_11r->r0kh_id_len = 0;
6635 					roam_offload_11r->psk_msk_len = 0;
6636 				}
6637 				WMITLV_SET_HDR(&roam_offload_11r->tlv_header,
6638 				WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param,
6639 				WMITLV_GET_STRUCT_TLVLEN
6640 				(wmi_roam_11r_offload_tlv_param));
6641 				buf_ptr +=
6642 					sizeof(wmi_roam_11r_offload_tlv_param);
6643 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6644 					       WMITLV_GET_STRUCT_TLVLEN(0));
6645 				buf_ptr += WMI_TLV_HDR_SIZE;
6646 				WMI_LOGD("psk_msk_len = %d",
6647 					roam_offload_11r->psk_msk_len);
6648 				if (roam_offload_11r->psk_msk_len)
6649 					QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
6650 						QDF_TRACE_LEVEL_DEBUG,
6651 						roam_offload_11r->psk_msk,
6652 						roam_offload_11r->psk_msk_len);
6653 			} else {
6654 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6655 					sizeof(wmi_roam_11i_offload_tlv_param));
6656 				buf_ptr += WMI_TLV_HDR_SIZE;
6657 				roam_offload_11i =
6658 				     (wmi_roam_11i_offload_tlv_param *) buf_ptr;
6659 
6660 				if (roam_req->roam_key_mgmt_offload_enabled &&
6661 				    roam_req->fw_okc) {
6662 					WMI_SET_ROAM_OFFLOAD_OKC_ENABLED
6663 						(roam_offload_11i->flags);
6664 					WMI_LOGI("LFR3:OKC enabled");
6665 				} else {
6666 					WMI_SET_ROAM_OFFLOAD_OKC_DISABLED
6667 						(roam_offload_11i->flags);
6668 					WMI_LOGI("LFR3:OKC disabled");
6669 				}
6670 				if (roam_req->roam_key_mgmt_offload_enabled &&
6671 				    roam_req->fw_pmksa_cache) {
6672 					WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED
6673 						(roam_offload_11i->flags);
6674 					WMI_LOGI("LFR3:PMKSA caching enabled");
6675 				} else {
6676 					WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED
6677 						(roam_offload_11i->flags);
6678 					WMI_LOGI("LFR3:PMKSA caching disabled");
6679 				}
6680 
6681 				qdf_mem_copy(roam_offload_11i->pmk,
6682 					     roam_req->psk_pmk,
6683 					     sizeof(roam_req->psk_pmk));
6684 				roam_offload_11i->pmk_len = roam_req->pmk_len;
6685 				WMITLV_SET_HDR(&roam_offload_11i->tlv_header,
6686 				WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param,
6687 				WMITLV_GET_STRUCT_TLVLEN
6688 				(wmi_roam_11i_offload_tlv_param));
6689 				buf_ptr +=
6690 					sizeof(wmi_roam_11i_offload_tlv_param);
6691 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6692 					       0);
6693 				buf_ptr += WMI_TLV_HDR_SIZE;
6694 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6695 					       0);
6696 				buf_ptr += WMI_TLV_HDR_SIZE;
6697 				WMI_LOGD("pmk_len = %d",
6698 					roam_offload_11i->pmk_len);
6699 				if (roam_offload_11i->pmk_len)
6700 					QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
6701 						QDF_TRACE_LEVEL_DEBUG,
6702 						roam_offload_11i->pmk,
6703 						roam_offload_11i->pmk_len);
6704 			}
6705 		} else {
6706 			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6707 				       WMITLV_GET_STRUCT_TLVLEN(0));
6708 			buf_ptr += WMI_TLV_HDR_SIZE;
6709 			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6710 				       WMITLV_GET_STRUCT_TLVLEN(0));
6711 			buf_ptr += WMI_TLV_HDR_SIZE;
6712 			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6713 				       WMITLV_GET_STRUCT_TLVLEN(0));
6714 			buf_ptr += WMI_TLV_HDR_SIZE;
6715 		}
6716 
6717 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6718 					sizeof(*assoc_ies));
6719 		buf_ptr += WMI_TLV_HDR_SIZE;
6720 
6721 		assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr;
6722 		WMITLV_SET_HDR(&assoc_ies->tlv_header,
6723 			WMITLV_TAG_STRUC_wmi_tlv_buf_len_param,
6724 			WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param));
6725 		assoc_ies->buf_len = roam_req->assoc_ie_length;
6726 
6727 		buf_ptr += sizeof(*assoc_ies);
6728 
6729 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
6730 				roundup(assoc_ies->buf_len, sizeof(uint32_t)));
6731 		buf_ptr += WMI_TLV_HDR_SIZE;
6732 
6733 		if (assoc_ies->buf_len != 0) {
6734 			qdf_mem_copy(buf_ptr, roam_req->assoc_ie,
6735 					assoc_ies->buf_len);
6736 		}
6737 		buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t));
6738 		buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req,
6739 						buf_ptr, fils_tlv_len);
6740 	} else {
6741 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6742 			       WMITLV_GET_STRUCT_TLVLEN(0));
6743 		buf_ptr += WMI_TLV_HDR_SIZE;
6744 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6745 			       WMITLV_GET_STRUCT_TLVLEN(0));
6746 		buf_ptr += WMI_TLV_HDR_SIZE;
6747 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6748 			       WMITLV_GET_STRUCT_TLVLEN(0));
6749 		buf_ptr += WMI_TLV_HDR_SIZE;
6750 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6751 			       WMITLV_GET_STRUCT_TLVLEN(0));
6752 		buf_ptr += WMI_TLV_HDR_SIZE;
6753 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6754 				WMITLV_GET_STRUCT_TLVLEN(0));
6755 		buf_ptr += WMI_TLV_HDR_SIZE;
6756 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
6757 				WMITLV_GET_STRUCT_TLVLEN(0));
6758 	}
6759 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6760 
6761 send_roam_scan_mode_cmd:
6762 	wmi_mtrace(WMI_ROAM_SCAN_MODE, NO_SESSION, 0);
6763 	status = wmi_unified_cmd_send(wmi_handle, buf,
6764 				      len, WMI_ROAM_SCAN_MODE);
6765 	if (QDF_IS_STATUS_ERROR(status)) {
6766 		WMI_LOGE(
6767 		    "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d",
6768 			status);
6769 		wmi_buf_free(buf);
6770 	}
6771 
6772 	return status;
6773 }
6774 
6775 static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle,
6776 		struct wmi_mawc_roam_params *params)
6777 {
6778 	wmi_buf_t buf = NULL;
6779 	QDF_STATUS status;
6780 	int len;
6781 	uint8_t *buf_ptr;
6782 	wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params;
6783 
6784 	len = sizeof(*wmi_roam_mawc_params);
6785 	buf = wmi_buf_alloc(wmi_handle, len);
6786 	if (!buf) {
6787 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6788 		return QDF_STATUS_E_NOMEM;
6789 	}
6790 
6791 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6792 	wmi_roam_mawc_params =
6793 		(wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr;
6794 	WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header,
6795 		       WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param,
6796 		       WMITLV_GET_STRUCT_TLVLEN
6797 			       (wmi_roam_configure_mawc_cmd_fixed_param));
6798 	wmi_roam_mawc_params->vdev_id = params->vdev_id;
6799 	if (params->enable)
6800 		wmi_roam_mawc_params->enable = 1;
6801 	else
6802 		wmi_roam_mawc_params->enable = 0;
6803 	wmi_roam_mawc_params->traffic_load_threshold =
6804 		params->traffic_load_threshold;
6805 	wmi_roam_mawc_params->best_ap_rssi_threshold =
6806 		params->best_ap_rssi_threshold;
6807 	wmi_roam_mawc_params->rssi_stationary_high_adjust =
6808 		params->rssi_stationary_high_adjust;
6809 	wmi_roam_mawc_params->rssi_stationary_low_adjust =
6810 		params->rssi_stationary_low_adjust;
6811 	WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"),
6812 		wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id,
6813 		wmi_roam_mawc_params->traffic_load_threshold,
6814 		wmi_roam_mawc_params->best_ap_rssi_threshold,
6815 		wmi_roam_mawc_params->rssi_stationary_high_adjust,
6816 		wmi_roam_mawc_params->rssi_stationary_low_adjust);
6817 
6818 	wmi_mtrace(WMI_ROAM_CONFIGURE_MAWC_CMDID, NO_SESSION, 0);
6819 	status = wmi_unified_cmd_send(wmi_handle, buf,
6820 				      len, WMI_ROAM_CONFIGURE_MAWC_CMDID);
6821 	if (QDF_IS_STATUS_ERROR(status)) {
6822 		WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d",
6823 			status);
6824 		wmi_buf_free(buf);
6825 		return status;
6826 	}
6827 
6828 	return QDF_STATUS_SUCCESS;
6829 }
6830 
6831 /**
6832  * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload
6833  *                                                rssi threashold
6834  * @wmi_handle: wmi handle
6835  * @roam_req:   Roaming request buffer
6836  *
6837  * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
6838  *
6839  * Return: QDF status
6840  */
6841 static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle,
6842 				struct roam_offload_scan_rssi_params *roam_req)
6843 {
6844 	wmi_buf_t buf = NULL;
6845 	QDF_STATUS status;
6846 	int len;
6847 	uint8_t *buf_ptr;
6848 	wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp;
6849 	wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL;
6850 	wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL;
6851 	wmi_roam_dense_thres_param *dense_thresholds = NULL;
6852 	wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL;
6853 
6854 	len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
6855 	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
6856 	len += sizeof(wmi_roam_scan_extended_threshold_param);
6857 	len += WMI_TLV_HDR_SIZE;
6858 	len += sizeof(wmi_roam_earlystop_rssi_thres_param);
6859 	len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/
6860 	len += sizeof(wmi_roam_dense_thres_param);
6861 	len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/
6862 	len += sizeof(wmi_roam_bg_scan_roaming_param);
6863 	buf = wmi_buf_alloc(wmi_handle, len);
6864 	if (!buf) {
6865 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6866 		return QDF_STATUS_E_NOMEM;
6867 	}
6868 
6869 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6870 	rssi_threshold_fp =
6871 		(wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr;
6872 	WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header,
6873 		      WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param,
6874 		      WMITLV_GET_STRUCT_TLVLEN
6875 			       (wmi_roam_scan_rssi_threshold_fixed_param));
6876 	/* fill in threshold values */
6877 	rssi_threshold_fp->vdev_id = roam_req->session_id;
6878 	rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh;
6879 	rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff;
6880 	rssi_threshold_fp->hirssi_scan_max_count =
6881 			roam_req->hi_rssi_scan_max_count;
6882 	rssi_threshold_fp->hirssi_scan_delta =
6883 			roam_req->hi_rssi_scan_rssi_delta;
6884 	rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub;
6885 	rssi_threshold_fp->rssi_thresh_offset_5g =
6886 		roam_req->rssi_thresh_offset_5g;
6887 
6888 	buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
6889 	WMITLV_SET_HDR(buf_ptr,
6890 			WMITLV_TAG_ARRAY_STRUC,
6891 			sizeof(wmi_roam_scan_extended_threshold_param));
6892 	buf_ptr += WMI_TLV_HDR_SIZE;
6893 	ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr;
6894 
6895 	ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g;
6896 	if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT)
6897 		ext_thresholds->boost_threshold_5g =
6898 					roam_req->boost_threshold_5g;
6899 
6900 	ext_thresholds->boost_algorithm_5g =
6901 		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
6902 	ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g;
6903 	ext_thresholds->penalty_algorithm_5g =
6904 		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
6905 	ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g;
6906 	ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g;
6907 	ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g;
6908 	ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold;
6909 
6910 	WMITLV_SET_HDR(&ext_thresholds->tlv_header,
6911 		WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param,
6912 		WMITLV_GET_STRUCT_TLVLEN
6913 		(wmi_roam_scan_extended_threshold_param));
6914 	buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param);
6915 	WMITLV_SET_HDR(buf_ptr,
6916 			WMITLV_TAG_ARRAY_STRUC,
6917 			sizeof(wmi_roam_earlystop_rssi_thres_param));
6918 	buf_ptr += WMI_TLV_HDR_SIZE;
6919 	early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr;
6920 	early_stop_thresholds->roam_earlystop_thres_min =
6921 		roam_req->roam_earlystop_thres_min;
6922 	early_stop_thresholds->roam_earlystop_thres_max =
6923 		roam_req->roam_earlystop_thres_max;
6924 	WMITLV_SET_HDR(&early_stop_thresholds->tlv_header,
6925 		WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param,
6926 		WMITLV_GET_STRUCT_TLVLEN
6927 		(wmi_roam_earlystop_rssi_thres_param));
6928 
6929 	buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param);
6930 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6931 			 sizeof(wmi_roam_dense_thres_param));
6932 	buf_ptr += WMI_TLV_HDR_SIZE;
6933 	dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr;
6934 	dense_thresholds->roam_dense_rssi_thres_offset =
6935 			roam_req->dense_rssi_thresh_offset;
6936 	dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt;
6937 	dense_thresholds->roam_dense_traffic_thres =
6938 			roam_req->traffic_threshold;
6939 	dense_thresholds->roam_dense_status = roam_req->initial_dense_status;
6940 	WMITLV_SET_HDR(&dense_thresholds->tlv_header,
6941 			WMITLV_TAG_STRUC_wmi_roam_dense_thres_param,
6942 			WMITLV_GET_STRUCT_TLVLEN
6943 			(wmi_roam_dense_thres_param));
6944 
6945 	buf_ptr += sizeof(wmi_roam_dense_thres_param);
6946 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6947 			 sizeof(wmi_roam_bg_scan_roaming_param));
6948 	buf_ptr += WMI_TLV_HDR_SIZE;
6949 	bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr;
6950 	bg_scan_params->roam_bg_scan_bad_rssi_thresh =
6951 		roam_req->bg_scan_bad_rssi_thresh;
6952 	bg_scan_params->roam_bg_scan_client_bitmap =
6953 		roam_req->bg_scan_client_bitmap;
6954 	bg_scan_params->bad_rssi_thresh_offset_2g =
6955 		roam_req->roam_bad_rssi_thresh_offset_2g;
6956 	bg_scan_params->flags = roam_req->flags;
6957 	WMITLV_SET_HDR(&bg_scan_params->tlv_header,
6958 			WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param,
6959 			WMITLV_GET_STRUCT_TLVLEN
6960 			(wmi_roam_bg_scan_roaming_param));
6961 
6962 	wmi_mtrace(WMI_ROAM_SCAN_RSSI_THRESHOLD, NO_SESSION, 0);
6963 	status = wmi_unified_cmd_send(wmi_handle, buf,
6964 				      len, WMI_ROAM_SCAN_RSSI_THRESHOLD);
6965 	if (QDF_IS_STATUS_ERROR(status)) {
6966 		WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d",
6967 					status);
6968 		wmi_buf_free(buf);
6969 	}
6970 
6971 	return status;
6972 }
6973 
6974 /**
6975  * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime
6976  * configuration params
6977  * @wma_handle:  wma handler
6978  * @dwelltime_params: pointer to dwelltime_params
6979  *
6980  * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
6981  */
6982 static
6983 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle,
6984 		struct wmi_adaptive_dwelltime_params *dwelltime_params)
6985 {
6986 	wmi_scan_adaptive_dwell_config_fixed_param *dwell_param;
6987 	wmi_scan_adaptive_dwell_parameters_tlv *cmd;
6988 	wmi_buf_t buf;
6989 	uint8_t *buf_ptr;
6990 	int32_t err;
6991 	int len;
6992 
6993 	len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
6994 	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
6995 	len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv);
6996 	buf = wmi_buf_alloc(wmi_handle, len);
6997 	if (!buf) {
6998 		WMI_LOGE("%s :Failed to allocate buffer to send cmd",
6999 				__func__);
7000 		return QDF_STATUS_E_NOMEM;
7001 	}
7002 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7003 	dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr;
7004 	WMITLV_SET_HDR(&dwell_param->tlv_header,
7005 		WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param,
7006 		WMITLV_GET_STRUCT_TLVLEN
7007 		(wmi_scan_adaptive_dwell_config_fixed_param));
7008 
7009 	dwell_param->enable = dwelltime_params->is_enabled;
7010 	buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
7011 	WMITLV_SET_HDR(buf_ptr,
7012 			WMITLV_TAG_ARRAY_STRUC,
7013 			sizeof(wmi_scan_adaptive_dwell_parameters_tlv));
7014 	buf_ptr += WMI_TLV_HDR_SIZE;
7015 
7016 	cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr;
7017 	WMITLV_SET_HDR(&cmd->tlv_header,
7018 			WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv,
7019 			WMITLV_GET_STRUCT_TLVLEN(
7020 				wmi_scan_adaptive_dwell_parameters_tlv));
7021 
7022 	cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode;
7023 	cmd->adapative_lpf_weight = dwelltime_params->lpf_weight;
7024 	cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval;
7025 	cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold;
7026 	wmi_mtrace(WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID, NO_SESSION, 0);
7027 	err = wmi_unified_cmd_send(wmi_handle, buf,
7028 			len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID);
7029 	if (err) {
7030 		WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err);
7031 		wmi_buf_free(buf);
7032 		return QDF_STATUS_E_FAILURE;
7033 	}
7034 
7035 	return QDF_STATUS_SUCCESS;
7036 }
7037 
7038 /**
7039  * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection
7040  * configuration params
7041  * @wmi_handle: wmi handler
7042  * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params
7043  *
7044  * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
7045  */
7046 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle,
7047 			struct wmi_dbs_scan_sel_params *dbs_scan_params)
7048 {
7049 	wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param;
7050 	wmi_scan_dbs_duty_cycle_tlv_param *cmd;
7051 	wmi_buf_t buf;
7052 	uint8_t *buf_ptr;
7053 	QDF_STATUS err;
7054 	uint32_t i;
7055 	int len;
7056 
7057 	len = sizeof(*dbs_scan_param);
7058 	len += WMI_TLV_HDR_SIZE;
7059 	len += dbs_scan_params->num_clients * sizeof(*cmd);
7060 
7061 	buf = wmi_buf_alloc(wmi_handle, len);
7062 	if (!buf) {
7063 		WMI_LOGE("%s:Failed to allocate buffer to send cmd", __func__);
7064 		return QDF_STATUS_E_NOMEM;
7065 	}
7066 
7067 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7068 	dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr;
7069 	WMITLV_SET_HDR(&dbs_scan_param->tlv_header,
7070 		       WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param,
7071 		       WMITLV_GET_STRUCT_TLVLEN
7072 		       (wmi_scan_dbs_duty_cycle_fixed_param));
7073 
7074 	dbs_scan_param->num_clients = dbs_scan_params->num_clients;
7075 	dbs_scan_param->pdev_id = dbs_scan_params->pdev_id;
7076 	buf_ptr += sizeof(*dbs_scan_param);
7077 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7078 		       (sizeof(*cmd) * dbs_scan_params->num_clients));
7079 	buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE;
7080 
7081 	for (i = 0; i < dbs_scan_params->num_clients; i++) {
7082 		cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr;
7083 		WMITLV_SET_HDR(&cmd->tlv_header,
7084 			WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv,
7085 			WMITLV_GET_STRUCT_TLVLEN(
7086 					wmi_scan_dbs_duty_cycle_tlv_param));
7087 		cmd->module_id = dbs_scan_params->module_id[i];
7088 		cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i];
7089 		cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i];
7090 		buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd);
7091 	}
7092 
7093 	wmi_mtrace(WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID, NO_SESSION, 0);
7094 	err = wmi_unified_cmd_send(wmi_handle, buf,
7095 				   len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID);
7096 	if (QDF_IS_STATUS_ERROR(err)) {
7097 		WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err);
7098 		wmi_buf_free(buf);
7099 		return QDF_STATUS_E_FAILURE;
7100 	}
7101 
7102 	return QDF_STATUS_SUCCESS;
7103 }
7104 
7105 /**
7106  * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming
7107  * @wmi_handle:     wmi handle
7108  * @roam_req:       Request which contains the filters
7109  *
7110  * There are filters such as whitelist, blacklist and preferred
7111  * list that need to be applied to the scan results to form the
7112  * probable candidates for roaming.
7113  *
7114  * Return: Return success upon successfully passing the
7115  *         parameters to the firmware, otherwise failure.
7116  */
7117 static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle,
7118 				struct roam_scan_filter_params *roam_req)
7119 {
7120 	wmi_buf_t buf = NULL;
7121 	QDF_STATUS status;
7122 	uint32_t i;
7123 	uint32_t len, blist_len = 0;
7124 	uint8_t *buf_ptr;
7125 	wmi_roam_filter_fixed_param *roam_filter;
7126 	uint8_t *bssid_src_ptr = NULL;
7127 	wmi_mac_addr *bssid_dst_ptr = NULL;
7128 	wmi_ssid *ssid_ptr = NULL;
7129 	uint32_t *bssid_preferred_factor_ptr = NULL;
7130 	wmi_roam_lca_disallow_config_tlv_param *blist_param;
7131 	wmi_roam_rssi_rejection_oce_config_param *rssi_rej;
7132 
7133 	len = sizeof(wmi_roam_filter_fixed_param);
7134 
7135 	len += WMI_TLV_HDR_SIZE;
7136 	if (roam_req->num_bssid_black_list)
7137 		len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr);
7138 	len += WMI_TLV_HDR_SIZE;
7139 	if (roam_req->num_ssid_white_list)
7140 		len += roam_req->num_ssid_white_list * sizeof(wmi_ssid);
7141 	len += 2 * WMI_TLV_HDR_SIZE;
7142 	if (roam_req->num_bssid_preferred_list) {
7143 		len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr);
7144 		len += roam_req->num_bssid_preferred_list * sizeof(uint32_t);
7145 	}
7146 	len += WMI_TLV_HDR_SIZE;
7147 	if (roam_req->lca_disallow_config_present) {
7148 		len += sizeof(*blist_param);
7149 		blist_len = sizeof(*blist_param);
7150 	}
7151 
7152 	len += WMI_TLV_HDR_SIZE;
7153 	if (roam_req->num_rssi_rejection_ap)
7154 		len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej);
7155 
7156 	buf = wmi_buf_alloc(wmi_handle, len);
7157 	if (!buf) {
7158 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
7159 		return QDF_STATUS_E_NOMEM;
7160 	}
7161 
7162 	buf_ptr = (u_int8_t *) wmi_buf_data(buf);
7163 	roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr;
7164 	WMITLV_SET_HDR(&roam_filter->tlv_header,
7165 		WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param,
7166 		WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param));
7167 	/* fill in fixed values */
7168 	roam_filter->vdev_id = roam_req->session_id;
7169 	roam_filter->flags = 0;
7170 	roam_filter->op_bitmap = roam_req->op_bitmap;
7171 	roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list;
7172 	roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list;
7173 	roam_filter->num_bssid_preferred_list =
7174 			roam_req->num_bssid_preferred_list;
7175 	roam_filter->num_rssi_rejection_ap =
7176 			roam_req->num_rssi_rejection_ap;
7177 	buf_ptr += sizeof(wmi_roam_filter_fixed_param);
7178 
7179 	WMITLV_SET_HDR((buf_ptr),
7180 		WMITLV_TAG_ARRAY_FIXED_STRUC,
7181 		(roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)));
7182 	bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list;
7183 	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
7184 	for (i = 0; i < roam_req->num_bssid_black_list; i++) {
7185 		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr);
7186 		bssid_src_ptr += ATH_MAC_LEN;
7187 		bssid_dst_ptr++;
7188 	}
7189 	buf_ptr += WMI_TLV_HDR_SIZE +
7190 		(roam_req->num_bssid_black_list * sizeof(wmi_mac_addr));
7191 	WMITLV_SET_HDR((buf_ptr),
7192 		WMITLV_TAG_ARRAY_FIXED_STRUC,
7193 		(roam_req->num_ssid_white_list * sizeof(wmi_ssid)));
7194 	ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE);
7195 	for (i = 0; i < roam_req->num_ssid_white_list; i++) {
7196 		qdf_mem_copy(&ssid_ptr->ssid,
7197 			&roam_req->ssid_allowed_list[i].mac_ssid,
7198 			roam_req->ssid_allowed_list[i].length);
7199 		ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length;
7200 		ssid_ptr++;
7201 	}
7202 	buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list *
7203 							sizeof(wmi_ssid));
7204 	WMITLV_SET_HDR((buf_ptr),
7205 		WMITLV_TAG_ARRAY_FIXED_STRUC,
7206 		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)));
7207 	bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored;
7208 	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
7209 	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
7210 		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr,
7211 				(wmi_mac_addr *)bssid_dst_ptr);
7212 		bssid_src_ptr += ATH_MAC_LEN;
7213 		bssid_dst_ptr++;
7214 	}
7215 	buf_ptr += WMI_TLV_HDR_SIZE +
7216 		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr));
7217 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
7218 		(roam_req->num_bssid_preferred_list * sizeof(uint32_t)));
7219 	bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
7220 	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
7221 		*bssid_preferred_factor_ptr =
7222 			roam_req->bssid_favored_factor[i];
7223 		bssid_preferred_factor_ptr++;
7224 	}
7225 	buf_ptr += WMI_TLV_HDR_SIZE +
7226 		(roam_req->num_bssid_preferred_list * sizeof(uint32_t));
7227 
7228 	WMITLV_SET_HDR(buf_ptr,
7229 			WMITLV_TAG_ARRAY_STRUC, blist_len);
7230 	buf_ptr += WMI_TLV_HDR_SIZE;
7231 	if (roam_req->lca_disallow_config_present) {
7232 		blist_param =
7233 			(wmi_roam_lca_disallow_config_tlv_param *) buf_ptr;
7234 		WMITLV_SET_HDR(&blist_param->tlv_header,
7235 			WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param,
7236 			WMITLV_GET_STRUCT_TLVLEN(
7237 				wmi_roam_lca_disallow_config_tlv_param));
7238 
7239 		blist_param->disallow_duration = roam_req->disallow_duration;
7240 		blist_param->rssi_channel_penalization =
7241 				roam_req->rssi_channel_penalization;
7242 		blist_param->num_disallowed_aps = roam_req->num_disallowed_aps;
7243 		blist_param->disallow_lca_enable_source_bitmap =
7244 			(WMI_ROAM_LCA_DISALLOW_SOURCE_PER |
7245 			WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND);
7246 		buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param));
7247 	}
7248 
7249 	WMITLV_SET_HDR(buf_ptr,
7250 			WMITLV_TAG_ARRAY_STRUC,
7251 			(roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej)));
7252 	buf_ptr += WMI_TLV_HDR_SIZE;
7253 	for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) {
7254 		rssi_rej =
7255 		(wmi_roam_rssi_rejection_oce_config_param *) buf_ptr;
7256 		WMITLV_SET_HDR(&rssi_rej->tlv_header,
7257 			WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param,
7258 			WMITLV_GET_STRUCT_TLVLEN(
7259 			wmi_roam_rssi_rejection_oce_config_param));
7260 		WMI_CHAR_ARRAY_TO_MAC_ADDR(
7261 			roam_req->rssi_rejection_ap[i].bssid.bytes,
7262 			&rssi_rej->bssid);
7263 		rssi_rej->remaining_disallow_duration =
7264 			roam_req->rssi_rejection_ap[i].remaining_duration;
7265 		rssi_rej->requested_rssi =
7266 			(int32_t)roam_req->rssi_rejection_ap[i].expected_rssi;
7267 		buf_ptr +=
7268 			(sizeof(wmi_roam_rssi_rejection_oce_config_param));
7269 	}
7270 
7271 	wmi_mtrace(WMI_ROAM_FILTER_CMDID, NO_SESSION, 0);
7272 	status = wmi_unified_cmd_send(wmi_handle, buf,
7273 		len, WMI_ROAM_FILTER_CMDID);
7274 	if (QDF_IS_STATUS_ERROR(status)) {
7275 		WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d",
7276 				status);
7277 		wmi_buf_free(buf);
7278 	}
7279 
7280 	return status;
7281 }
7282 
7283 #if defined(WLAN_FEATURE_FILS_SK)
7284 static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle,
7285 						  struct hlp_params *params)
7286 {
7287 	uint32_t len;
7288 	uint8_t *buf_ptr;
7289 	wmi_buf_t buf = NULL;
7290 	wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params;
7291 
7292 	len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param);
7293 	len += WMI_TLV_HDR_SIZE;
7294 	len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t));
7295 
7296 	buf = wmi_buf_alloc(wmi_handle, len);
7297 	if (!buf) {
7298 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
7299 		return QDF_STATUS_E_NOMEM;
7300 	}
7301 
7302 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7303 	hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr;
7304 	WMITLV_SET_HDR(&hlp_params->tlv_header,
7305 		WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param,
7306 		WMITLV_GET_STRUCT_TLVLEN(
7307 			wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param));
7308 
7309 	hlp_params->vdev_id = params->vdev_id;
7310 	hlp_params->size = params->hlp_ie_len;
7311 	hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER;
7312 
7313 	buf_ptr += sizeof(*hlp_params);
7314 
7315 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
7316 				round_up(params->hlp_ie_len,
7317 				sizeof(uint32_t)));
7318 	buf_ptr += WMI_TLV_HDR_SIZE;
7319 	qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len);
7320 
7321 	WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"),
7322 			hlp_params->vdev_id, hlp_params->size);
7323 	wmi_mtrace(WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID, NO_SESSION, 0);
7324 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
7325 				WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) {
7326 		WMI_LOGE(FL("Failed to send FILS HLP pkt cmd"));
7327 		wmi_buf_free(buf);
7328 		return QDF_STATUS_E_FAILURE;
7329 	}
7330 
7331 	return QDF_STATUS_SUCCESS;
7332 }
7333 #endif
7334 
7335 #ifdef IPA_OFFLOAD
7336 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter
7337  * @wmi_handle: wmi handle
7338  * @ipa_offload: ipa offload control parameter
7339  *
7340  * Returns: 0 on success, error number otherwise
7341  */
7342 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle,
7343 		struct ipa_uc_offload_control_params *ipa_offload)
7344 {
7345 	wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd;
7346 	wmi_buf_t wmi_buf;
7347 	uint32_t len;
7348 	u_int8_t *buf_ptr;
7349 
7350 	len  = sizeof(*cmd);
7351 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
7352 	if (!wmi_buf) {
7353 		WMI_LOGE("%s: wmi_buf_alloc failed (len=%d)", __func__, len);
7354 		return QDF_STATUS_E_NOMEM;
7355 	}
7356 
7357 	WMI_LOGD("%s: offload_type=%d, enable=%d", __func__,
7358 		ipa_offload->offload_type, ipa_offload->enable);
7359 
7360 	buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf);
7361 
7362 	cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr;
7363 	WMITLV_SET_HDR(&cmd->tlv_header,
7364 		WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param,
7365 		WMITLV_GET_STRUCT_TLVLEN(
7366 		wmi_ipa_offload_enable_disable_cmd_fixed_param));
7367 
7368 	cmd->offload_type = ipa_offload->offload_type;
7369 	cmd->vdev_id = ipa_offload->vdev_id;
7370 	cmd->enable = ipa_offload->enable;
7371 
7372 	wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0);
7373 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
7374 		WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) {
7375 		WMI_LOGE("%s: failed to command", __func__);
7376 		wmi_buf_free(wmi_buf);
7377 		return QDF_STATUS_E_FAILURE;
7378 	}
7379 
7380 	return QDF_STATUS_SUCCESS;
7381 }
7382 #endif
7383 
7384 /**
7385  * send_plm_stop_cmd_tlv() - plm stop request
7386  * @wmi_handle: wmi handle
7387  * @plm: plm request parameters
7388  *
7389  * This function request FW to stop PLM.
7390  *
7391  * Return: CDF status
7392  */
7393 static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle,
7394 			  const struct plm_req_params *plm)
7395 {
7396 	wmi_vdev_plmreq_stop_cmd_fixed_param *cmd;
7397 	int32_t len;
7398 	wmi_buf_t buf;
7399 	uint8_t *buf_ptr;
7400 	int ret;
7401 
7402 	len = sizeof(*cmd);
7403 	buf = wmi_buf_alloc(wmi_handle, len);
7404 	if (!buf) {
7405 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7406 		return QDF_STATUS_E_NOMEM;
7407 	}
7408 
7409 	cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf);
7410 
7411 	buf_ptr = (uint8_t *) cmd;
7412 
7413 	WMITLV_SET_HDR(&cmd->tlv_header,
7414 		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param,
7415 		       WMITLV_GET_STRUCT_TLVLEN
7416 		       (wmi_vdev_plmreq_stop_cmd_fixed_param));
7417 
7418 	cmd->vdev_id = plm->session_id;
7419 
7420 	cmd->meas_token = plm->meas_token;
7421 	WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token);
7422 
7423 	wmi_mtrace(WMI_VDEV_PLMREQ_STOP_CMDID, cmd->vdev_id, 0);
7424 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7425 				   WMI_VDEV_PLMREQ_STOP_CMDID);
7426 	if (ret) {
7427 		WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__);
7428 		wmi_buf_free(buf);
7429 		return QDF_STATUS_E_FAILURE;
7430 	}
7431 
7432 	return QDF_STATUS_SUCCESS;
7433 }
7434 
7435 /**
7436  * send_plm_start_cmd_tlv() - plm start request
7437  * @wmi_handle: wmi handle
7438  * @plm: plm request parameters
7439  *
7440  * This function request FW to start PLM.
7441  *
7442  * Return: CDF status
7443  */
7444 static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle,
7445 			  const struct plm_req_params *plm,
7446 			  uint32_t *gchannel_list)
7447 {
7448 	wmi_vdev_plmreq_start_cmd_fixed_param *cmd;
7449 	uint32_t *channel_list;
7450 	int32_t len;
7451 	wmi_buf_t buf;
7452 	uint8_t *buf_ptr;
7453 	uint8_t count;
7454 	int ret;
7455 
7456 	/* TLV place holder for channel_list */
7457 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
7458 	len += sizeof(uint32_t) * plm->plm_num_ch;
7459 
7460 	buf = wmi_buf_alloc(wmi_handle, len);
7461 	if (!buf) {
7462 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7463 		return QDF_STATUS_E_NOMEM;
7464 	}
7465 	cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf);
7466 
7467 	buf_ptr = (uint8_t *) cmd;
7468 
7469 	WMITLV_SET_HDR(&cmd->tlv_header,
7470 		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param,
7471 		       WMITLV_GET_STRUCT_TLVLEN
7472 			       (wmi_vdev_plmreq_start_cmd_fixed_param));
7473 
7474 	cmd->vdev_id = plm->session_id;
7475 
7476 	cmd->meas_token = plm->meas_token;
7477 	cmd->dialog_token = plm->diag_token;
7478 	cmd->number_bursts = plm->num_bursts;
7479 	cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int);
7480 	cmd->off_duration = plm->meas_duration;
7481 	cmd->burst_cycle = plm->burst_len;
7482 	cmd->tx_power = plm->desired_tx_pwr;
7483 	WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac);
7484 	cmd->num_chans = plm->plm_num_ch;
7485 
7486 	buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param);
7487 
7488 	WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token);
7489 	WMI_LOGD("dialog_token: %d", cmd->dialog_token);
7490 	WMI_LOGD("number_bursts: %d", cmd->number_bursts);
7491 	WMI_LOGD("burst_interval: %d", cmd->burst_interval);
7492 	WMI_LOGD("off_duration: %d", cmd->off_duration);
7493 	WMI_LOGD("burst_cycle: %d", cmd->burst_cycle);
7494 	WMI_LOGD("tx_power: %d", cmd->tx_power);
7495 	WMI_LOGD("Number of channels : %d", cmd->num_chans);
7496 
7497 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
7498 		       (cmd->num_chans * sizeof(uint32_t)));
7499 
7500 	buf_ptr += WMI_TLV_HDR_SIZE;
7501 	if (cmd->num_chans) {
7502 		channel_list = (uint32_t *) buf_ptr;
7503 		for (count = 0; count < cmd->num_chans; count++) {
7504 			channel_list[count] = plm->plm_ch_list[count];
7505 			if (channel_list[count] < WMI_NLO_FREQ_THRESH)
7506 				channel_list[count] =
7507 					gchannel_list[count];
7508 			WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]);
7509 		}
7510 		buf_ptr += cmd->num_chans * sizeof(uint32_t);
7511 	}
7512 
7513 	wmi_mtrace(WMI_VDEV_PLMREQ_START_CMDID, cmd->vdev_id, 0);
7514 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7515 				   WMI_VDEV_PLMREQ_START_CMDID);
7516 	if (ret) {
7517 		WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__);
7518 		wmi_buf_free(buf);
7519 		return QDF_STATUS_E_FAILURE;
7520 	}
7521 
7522 	return QDF_STATUS_SUCCESS;
7523 }
7524 
7525 /**
7526  * send_pno_stop_cmd_tlv() - PNO stop request
7527  * @wmi_handle: wmi handle
7528  * @vdev_id: vdev id
7529  *
7530  * This function request FW to stop ongoing PNO operation.
7531  *
7532  * Return: CDF status
7533  */
7534 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
7535 {
7536 	wmi_nlo_config_cmd_fixed_param *cmd;
7537 	int32_t len = sizeof(*cmd);
7538 	wmi_buf_t buf;
7539 	uint8_t *buf_ptr;
7540 	int ret;
7541 
7542 	/*
7543 	 * TLV place holder for array of structures nlo_configured_parameters
7544 	 * TLV place holder for array of uint32_t channel_list
7545 	 * TLV place holder for chnl prediction cfg
7546 	 */
7547 	len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE;
7548 	buf = wmi_buf_alloc(wmi_handle, len);
7549 	if (!buf) {
7550 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7551 		return QDF_STATUS_E_NOMEM;
7552 	}
7553 
7554 	cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf);
7555 	buf_ptr = (uint8_t *) cmd;
7556 
7557 	WMITLV_SET_HDR(&cmd->tlv_header,
7558 		       WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param,
7559 		       WMITLV_GET_STRUCT_TLVLEN
7560 			       (wmi_nlo_config_cmd_fixed_param));
7561 
7562 	cmd->vdev_id = vdev_id;
7563 	cmd->flags = WMI_NLO_CONFIG_STOP;
7564 	buf_ptr += sizeof(*cmd);
7565 
7566 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
7567 	buf_ptr += WMI_TLV_HDR_SIZE;
7568 
7569 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
7570 	buf_ptr += WMI_TLV_HDR_SIZE;
7571 
7572 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
7573 	buf_ptr += WMI_TLV_HDR_SIZE;
7574 
7575 
7576 	wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0);
7577 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7578 				   WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
7579 	if (ret) {
7580 		WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__);
7581 		wmi_buf_free(buf);
7582 		return QDF_STATUS_E_FAILURE;
7583 	}
7584 
7585 	return QDF_STATUS_SUCCESS;
7586 }
7587 
7588 /**
7589  * wmi_set_pno_channel_prediction() - Set PNO channel prediction
7590  * @buf_ptr:      Buffer passed by upper layers
7591  * @pno:          Buffer to be sent to the firmware
7592  *
7593  * Copy the PNO Channel prediction configuration parameters
7594  * passed by the upper layers to a WMI format TLV and send it
7595  * down to the firmware.
7596  *
7597  * Return: None
7598  */
7599 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr,
7600 		struct pno_scan_req_params *pno)
7601 {
7602 	nlo_channel_prediction_cfg *channel_prediction_cfg =
7603 		(nlo_channel_prediction_cfg *) buf_ptr;
7604 	WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header,
7605 			WMITLV_TAG_ARRAY_BYTE,
7606 			WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg));
7607 #ifdef FEATURE_WLAN_SCAN_PNO
7608 	channel_prediction_cfg->enable = pno->pno_channel_prediction;
7609 	channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels;
7610 	channel_prediction_cfg->stationary_threshold = pno->stationary_thresh;
7611 	channel_prediction_cfg->full_scan_period_ms =
7612 		pno->channel_prediction_full_scan;
7613 #endif
7614 	buf_ptr += sizeof(nlo_channel_prediction_cfg);
7615 	WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d",
7616 			channel_prediction_cfg->enable,
7617 			channel_prediction_cfg->top_k_num,
7618 			channel_prediction_cfg->stationary_threshold,
7619 			channel_prediction_cfg->full_scan_period_ms);
7620 }
7621 
7622 /**
7623  * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration
7624  * @wmi_handle: wmi handle
7625  * @params: configuration parameters
7626  *
7627  * Return: QDF_STATUS
7628  */
7629 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle,
7630 		struct nlo_mawc_params *params)
7631 {
7632 	wmi_buf_t buf = NULL;
7633 	QDF_STATUS status;
7634 	int len;
7635 	uint8_t *buf_ptr;
7636 	wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params;
7637 
7638 	len = sizeof(*wmi_nlo_mawc_params);
7639 	buf = wmi_buf_alloc(wmi_handle, len);
7640 	if (!buf) {
7641 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
7642 		return QDF_STATUS_E_NOMEM;
7643 	}
7644 
7645 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7646 	wmi_nlo_mawc_params =
7647 		(wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr;
7648 	WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header,
7649 		       WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param,
7650 		       WMITLV_GET_STRUCT_TLVLEN
7651 			       (wmi_nlo_configure_mawc_cmd_fixed_param));
7652 	wmi_nlo_mawc_params->vdev_id = params->vdev_id;
7653 	if (params->enable)
7654 		wmi_nlo_mawc_params->enable = 1;
7655 	else
7656 		wmi_nlo_mawc_params->enable = 0;
7657 	wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio;
7658 	wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval;
7659 	wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval;
7660 	WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"),
7661 		wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id,
7662 		wmi_nlo_mawc_params->exp_backoff_ratio,
7663 		wmi_nlo_mawc_params->init_scan_interval,
7664 		wmi_nlo_mawc_params->max_scan_interval);
7665 
7666 	wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0);
7667 	status = wmi_unified_cmd_send(wmi_handle, buf,
7668 				      len, WMI_NLO_CONFIGURE_MAWC_CMDID);
7669 	if (QDF_IS_STATUS_ERROR(status)) {
7670 		WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d",
7671 			status);
7672 		wmi_buf_free(buf);
7673 		return QDF_STATUS_E_FAILURE;
7674 	}
7675 
7676 	return QDF_STATUS_SUCCESS;
7677 }
7678 
7679 /**
7680  * send_pno_start_cmd_tlv() - PNO start request
7681  * @wmi_handle: wmi handle
7682  * @pno: PNO request
7683  *
7684  * This function request FW to start PNO request.
7685  * Request: CDF status
7686  */
7687 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle,
7688 		   struct pno_scan_req_params *pno)
7689 {
7690 	wmi_nlo_config_cmd_fixed_param *cmd;
7691 	nlo_configured_parameters *nlo_list;
7692 	uint32_t *channel_list;
7693 	int32_t len;
7694 	wmi_buf_t buf;
7695 	uint8_t *buf_ptr;
7696 	uint8_t i;
7697 	int ret;
7698 	struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist;
7699 	connected_nlo_rssi_params *nlo_relative_rssi;
7700 	connected_nlo_bss_band_rssi_pref *nlo_band_rssi;
7701 
7702 	/*
7703 	 * TLV place holder for array nlo_configured_parameters(nlo_list)
7704 	 * TLV place holder for array of uint32_t channel_list
7705 	 * TLV place holder for chnnl prediction cfg
7706 	 * TLV place holder for array of wmi_vendor_oui
7707 	 * TLV place holder for array of connected_nlo_bss_band_rssi_pref
7708 	 */
7709 	len = sizeof(*cmd) +
7710 		WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE +
7711 		WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE;
7712 
7713 	len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt,
7714 					  WMI_NLO_MAX_CHAN);
7715 	len += sizeof(nlo_configured_parameters) *
7716 	       QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS);
7717 	len += sizeof(nlo_channel_prediction_cfg);
7718 	len += sizeof(enlo_candidate_score_params);
7719 	len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui;
7720 	len += sizeof(connected_nlo_rssi_params);
7721 	len += sizeof(connected_nlo_bss_band_rssi_pref);
7722 
7723 	buf = wmi_buf_alloc(wmi_handle, len);
7724 	if (!buf) {
7725 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7726 		return QDF_STATUS_E_NOMEM;
7727 	}
7728 
7729 	cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf);
7730 
7731 	buf_ptr = (uint8_t *) cmd;
7732 	WMITLV_SET_HDR(&cmd->tlv_header,
7733 		       WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param,
7734 		       WMITLV_GET_STRUCT_TLVLEN
7735 			       (wmi_nlo_config_cmd_fixed_param));
7736 	cmd->vdev_id = pno->vdev_id;
7737 	cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN;
7738 
7739 #ifdef FEATURE_WLAN_SCAN_PNO
7740 	WMI_SCAN_SET_DWELL_MODE(cmd->flags,
7741 			pno->adaptive_dwell_mode);
7742 #endif
7743 	/* Current FW does not support min-max range for dwell time */
7744 	cmd->active_dwell_time = pno->active_dwell_time;
7745 	cmd->passive_dwell_time = pno->passive_dwell_time;
7746 
7747 	if (pno->do_passive_scan)
7748 		cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE;
7749 	/* Copy scan interval */
7750 	cmd->fast_scan_period = pno->fast_scan_period;
7751 	cmd->slow_scan_period = pno->slow_scan_period;
7752 	cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time);
7753 	cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles;
7754 	cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier;
7755 	WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec",
7756 			cmd->fast_scan_period, cmd->slow_scan_period);
7757 	WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles);
7758 
7759 	/* mac randomization attributes */
7760 	if (pno->scan_random.randomize) {
7761 		cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ |
7762 				WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ;
7763 		wmi_copy_scan_random_mac(pno->scan_random.mac_addr,
7764 					 pno->scan_random.mac_mask,
7765 					 &cmd->mac_addr,
7766 					 &cmd->mac_mask);
7767 	}
7768 
7769 	buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param);
7770 
7771 	cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS);
7772 	WMI_LOGD("SSID count : %d", cmd->no_of_ssids);
7773 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7774 		       cmd->no_of_ssids * sizeof(nlo_configured_parameters));
7775 	buf_ptr += WMI_TLV_HDR_SIZE;
7776 
7777 	nlo_list = (nlo_configured_parameters *) buf_ptr;
7778 	for (i = 0; i < cmd->no_of_ssids; i++) {
7779 		WMITLV_SET_HDR(&nlo_list[i].tlv_header,
7780 			       WMITLV_TAG_ARRAY_BYTE,
7781 			       WMITLV_GET_STRUCT_TLVLEN
7782 				       (nlo_configured_parameters));
7783 		/* Copy ssid and it's length */
7784 		nlo_list[i].ssid.valid = true;
7785 		nlo_list[i].ssid.ssid.ssid_len =
7786 			pno->networks_list[i].ssid.length;
7787 		qdf_mem_copy(nlo_list[i].ssid.ssid.ssid,
7788 			     pno->networks_list[i].ssid.ssid,
7789 			     nlo_list[i].ssid.ssid.ssid_len);
7790 		WMI_LOGD("index: %d ssid: %.*s len: %d", i,
7791 			 nlo_list[i].ssid.ssid.ssid_len,
7792 			 (char *)nlo_list[i].ssid.ssid.ssid,
7793 			 nlo_list[i].ssid.ssid.ssid_len);
7794 
7795 		/* Copy rssi threshold */
7796 		if (pno->networks_list[i].rssi_thresh &&
7797 		    pno->networks_list[i].rssi_thresh >
7798 		    WMI_RSSI_THOLD_DEFAULT) {
7799 			nlo_list[i].rssi_cond.valid = true;
7800 			nlo_list[i].rssi_cond.rssi =
7801 				pno->networks_list[i].rssi_thresh;
7802 			WMI_LOGD("RSSI threshold : %d dBm",
7803 				 nlo_list[i].rssi_cond.rssi);
7804 		}
7805 		nlo_list[i].bcast_nw_type.valid = true;
7806 		nlo_list[i].bcast_nw_type.bcast_nw_type =
7807 			pno->networks_list[i].bc_new_type;
7808 		WMI_LOGD("Broadcast NW type (%u)",
7809 			 nlo_list[i].bcast_nw_type.bcast_nw_type);
7810 	}
7811 	buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters);
7812 
7813 	/* Copy channel info */
7814 	cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt,
7815 				       WMI_NLO_MAX_CHAN);
7816 	WMI_LOGD("Channel count: %d", cmd->num_of_channels);
7817 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
7818 		       (cmd->num_of_channels * sizeof(uint32_t)));
7819 	buf_ptr += WMI_TLV_HDR_SIZE;
7820 
7821 	channel_list = (uint32_t *) buf_ptr;
7822 	for (i = 0; i < cmd->num_of_channels; i++) {
7823 		channel_list[i] = pno->networks_list[0].channels[i];
7824 
7825 		if (channel_list[i] < WMI_NLO_FREQ_THRESH)
7826 			channel_list[i] =
7827 				wlan_chan_to_freq(pno->
7828 					networks_list[0].channels[i]);
7829 
7830 		WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]);
7831 	}
7832 	buf_ptr += cmd->num_of_channels * sizeof(uint32_t);
7833 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7834 			sizeof(nlo_channel_prediction_cfg));
7835 	buf_ptr += WMI_TLV_HDR_SIZE;
7836 	wmi_set_pno_channel_prediction(buf_ptr, pno);
7837 	buf_ptr += sizeof(nlo_channel_prediction_cfg);
7838 	/** TODO: Discrete firmware doesn't have command/option to configure
7839 	 * App IE which comes from wpa_supplicant as of part PNO start request.
7840 	 */
7841 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param,
7842 		       WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params));
7843 	buf_ptr += sizeof(enlo_candidate_score_params);
7844 
7845 	if (ie_whitelist->white_list) {
7846 		cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ;
7847 		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
7848 					    &cmd->num_vendor_oui,
7849 					    ie_whitelist);
7850 	}
7851 
7852 	/* ie white list */
7853 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7854 		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
7855 	buf_ptr += WMI_TLV_HDR_SIZE;
7856 	if (cmd->num_vendor_oui != 0) {
7857 		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
7858 				    ie_whitelist->voui);
7859 		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
7860 	}
7861 
7862 	if (pno->relative_rssi_set)
7863 		cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG;
7864 
7865 	/*
7866 	 * Firmware calculation using connected PNO params:
7867 	 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref)
7868 	 * deduction of rssi_pref for chosen band_pref and
7869 	 * addition of rssi_pref for remaining bands (other than chosen band).
7870 	 */
7871 	nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr;
7872 	WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header,
7873 		WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params,
7874 		WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params));
7875 	nlo_relative_rssi->relative_rssi = pno->relative_rssi;
7876 	WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi);
7877 	buf_ptr += sizeof(*nlo_relative_rssi);
7878 
7879 	/*
7880 	 * As of now Kernel and Host supports one band and rssi preference.
7881 	 * Firmware supports array of band and rssi preferences
7882 	 */
7883 	cmd->num_cnlo_band_pref = 1;
7884 	WMITLV_SET_HDR(buf_ptr,
7885 		WMITLV_TAG_ARRAY_STRUC,
7886 		cmd->num_cnlo_band_pref *
7887 		sizeof(connected_nlo_bss_band_rssi_pref));
7888 	buf_ptr += WMI_TLV_HDR_SIZE;
7889 
7890 	nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr;
7891 	for (i = 0; i < cmd->num_cnlo_band_pref; i++) {
7892 		WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header,
7893 			WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref,
7894 			WMITLV_GET_STRUCT_TLVLEN(
7895 				connected_nlo_bss_band_rssi_pref));
7896 		nlo_band_rssi[i].band = pno->band_rssi_pref.band;
7897 		nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi;
7898 		WMI_LOGI("band_pref %d, rssi_pref %d",
7899 			nlo_band_rssi[i].band,
7900 			nlo_band_rssi[i].rssi_pref);
7901 	}
7902 	buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi);
7903 
7904 	wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0);
7905 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7906 				   WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
7907 	if (ret) {
7908 		WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__);
7909 		wmi_buf_free(buf);
7910 		return QDF_STATUS_E_FAILURE;
7911 	}
7912 
7913 	return QDF_STATUS_SUCCESS;
7914 }
7915 
7916 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
7917 /* send_set_ric_req_cmd_tlv() - set ric request element
7918  * @wmi_handle: wmi handle
7919  * @msg: message
7920  * @is_add_ts: is addts required
7921  *
7922  * This function sets ric request element for 11r roaming.
7923  *
7924  * Return: CDF status
7925  */
7926 static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle,
7927 			void *msg, uint8_t is_add_ts)
7928 {
7929 	wmi_ric_request_fixed_param *cmd;
7930 	wmi_ric_tspec *tspec_param;
7931 	wmi_buf_t buf;
7932 	uint8_t *buf_ptr;
7933 	struct mac_tspec_ie *ptspecIE = NULL;
7934 	int32_t len = sizeof(wmi_ric_request_fixed_param) +
7935 		      WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec);
7936 
7937 	buf = wmi_buf_alloc(wmi_handle, len);
7938 	if (!buf) {
7939 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
7940 		return QDF_STATUS_E_NOMEM;
7941 	}
7942 
7943 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7944 
7945 	cmd = (wmi_ric_request_fixed_param *) buf_ptr;
7946 	WMITLV_SET_HDR(&cmd->tlv_header,
7947 		   WMITLV_TAG_STRUC_wmi_ric_request_fixed_param,
7948 		   WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param));
7949 	if (is_add_ts)
7950 		cmd->vdev_id = ((struct add_ts_param *) msg)->sme_session_id;
7951 	else
7952 		cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId;
7953 	cmd->num_ric_request = 1;
7954 	cmd->is_add_ric = is_add_ts;
7955 
7956 	buf_ptr += sizeof(wmi_ric_request_fixed_param);
7957 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec));
7958 
7959 	buf_ptr += WMI_TLV_HDR_SIZE;
7960 	tspec_param = (wmi_ric_tspec *) buf_ptr;
7961 	WMITLV_SET_HDR(&tspec_param->tlv_header,
7962 		       WMITLV_TAG_STRUC_wmi_ric_tspec,
7963 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec));
7964 
7965 	if (is_add_ts)
7966 		ptspecIE = &(((struct add_ts_param *) msg)->tspec);
7967 	else
7968 		ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec);
7969 	if (ptspecIE) {
7970 		/* Fill the tsinfo in the format expected by firmware */
7971 #ifndef ANI_LITTLE_BIT_ENDIAN
7972 		qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1,
7973 			     ((uint8_t *) &ptspecIE->tsinfo) + 1, 2);
7974 #else
7975 		qdf_mem_copy(((uint8_t *) &tspec_param->ts_info),
7976 			     ((uint8_t *) &ptspecIE->tsinfo) + 1, 2);
7977 #endif /* ANI_LITTLE_BIT_ENDIAN */
7978 
7979 		tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz;
7980 		tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz;
7981 		tspec_param->min_service_interval = ptspecIE->minSvcInterval;
7982 		tspec_param->max_service_interval = ptspecIE->maxSvcInterval;
7983 		tspec_param->inactivity_interval = ptspecIE->inactInterval;
7984 		tspec_param->suspension_interval = ptspecIE->suspendInterval;
7985 		tspec_param->svc_start_time = ptspecIE->svcStartTime;
7986 		tspec_param->min_data_rate = ptspecIE->minDataRate;
7987 		tspec_param->mean_data_rate = ptspecIE->meanDataRate;
7988 		tspec_param->peak_data_rate = ptspecIE->peakDataRate;
7989 		tspec_param->max_burst_size = ptspecIE->maxBurstSz;
7990 		tspec_param->delay_bound = ptspecIE->delayBound;
7991 		tspec_param->min_phy_rate = ptspecIE->minPhyRate;
7992 		tspec_param->surplus_bw_allowance = ptspecIE->surplusBw;
7993 		tspec_param->medium_time = 0;
7994 	}
7995 	WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts);
7996 
7997 	wmi_mtrace(WMI_ROAM_SET_RIC_REQUEST_CMDID, cmd->vdev_id, 0);
7998 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
7999 				 WMI_ROAM_SET_RIC_REQUEST_CMDID)) {
8000 		WMI_LOGP("%s: Failed to send vdev Set RIC Req command",
8001 			 __func__);
8002 		if (is_add_ts)
8003 			((struct add_ts_param *) msg)->status =
8004 					    QDF_STATUS_E_FAILURE;
8005 		wmi_buf_free(buf);
8006 		return QDF_STATUS_E_FAILURE;
8007 	}
8008 
8009 	return QDF_STATUS_SUCCESS;
8010 }
8011 
8012 /**
8013  * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw.
8014  * @wmi_handle: wmi handle
8015  * @vdev_id: vdev id
8016  *
8017  * This function sends roam synch complete event to fw.
8018  *
8019  * Return: CDF STATUS
8020  */
8021 static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle,
8022 		 uint8_t vdev_id)
8023 {
8024 	wmi_roam_synch_complete_fixed_param *cmd;
8025 	wmi_buf_t wmi_buf;
8026 	uint8_t *buf_ptr;
8027 	uint16_t len;
8028 	len = sizeof(wmi_roam_synch_complete_fixed_param);
8029 
8030 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
8031 	if (!wmi_buf) {
8032 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8033 		return QDF_STATUS_E_NOMEM;
8034 	}
8035 	cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf);
8036 	buf_ptr = (uint8_t *) cmd;
8037 	WMITLV_SET_HDR(&cmd->tlv_header,
8038 		       WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param,
8039 		       WMITLV_GET_STRUCT_TLVLEN
8040 			       (wmi_roam_synch_complete_fixed_param));
8041 	cmd->vdev_id = vdev_id;
8042 	wmi_mtrace(WMI_ROAM_SYNCH_COMPLETE, cmd->vdev_id, 0);
8043 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
8044 				 WMI_ROAM_SYNCH_COMPLETE)) {
8045 		WMI_LOGP("%s: failed to send roam synch confirmation",
8046 			 __func__);
8047 		wmi_buf_free(wmi_buf);
8048 		return QDF_STATUS_E_FAILURE;
8049 	}
8050 
8051 	return QDF_STATUS_SUCCESS;
8052 }
8053 #endif
8054 
8055 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
8056 /**
8057  * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats
8058  * @wmi_handle: wmi handle
8059  * @clear_req: ll stats clear request command params
8060  *
8061  * Return: QDF_STATUS_SUCCESS for success or error code
8062  */
8063 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle,
8064 		const struct ll_stats_clear_params *clear_req,
8065 		uint8_t addr[IEEE80211_ADDR_LEN])
8066 {
8067 	wmi_clear_link_stats_cmd_fixed_param *cmd;
8068 	int32_t len;
8069 	wmi_buf_t buf;
8070 	uint8_t *buf_ptr;
8071 	int ret;
8072 
8073 	len = sizeof(*cmd);
8074 	buf = wmi_buf_alloc(wmi_handle, len);
8075 
8076 	if (!buf) {
8077 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8078 		return QDF_STATUS_E_NOMEM;
8079 	}
8080 
8081 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8082 	qdf_mem_zero(buf_ptr, len);
8083 	cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr;
8084 
8085 	WMITLV_SET_HDR(&cmd->tlv_header,
8086 		       WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param,
8087 		       WMITLV_GET_STRUCT_TLVLEN
8088 			       (wmi_clear_link_stats_cmd_fixed_param));
8089 
8090 	cmd->stop_stats_collection_req = clear_req->stop_req;
8091 	cmd->vdev_id = clear_req->sta_id;
8092 	cmd->stats_clear_req_mask = clear_req->stats_clear_mask;
8093 
8094 	WMI_CHAR_ARRAY_TO_MAC_ADDR(addr,
8095 				   &cmd->peer_macaddr);
8096 
8097 	WMI_LOGD("LINK_LAYER_STATS - Clear Request Params");
8098 	WMI_LOGD("StopReq         : %d", cmd->stop_stats_collection_req);
8099 	WMI_LOGD("Vdev Id         : %d", cmd->vdev_id);
8100 	WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask);
8101 	/* WMI_LOGD("Peer MAC Addr   : %pM",
8102 		 cmd->peer_macaddr); */
8103 
8104 	wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0);
8105 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8106 				   WMI_CLEAR_LINK_STATS_CMDID);
8107 	if (ret) {
8108 		WMI_LOGE("%s: Failed to send clear link stats req", __func__);
8109 		wmi_buf_free(buf);
8110 		return QDF_STATUS_E_FAILURE;
8111 	}
8112 
8113 	WMI_LOGD("Clear Link Layer Stats request sent successfully");
8114 	return QDF_STATUS_SUCCESS;
8115 }
8116 
8117 /**
8118  * send_process_ll_stats_set_cmd_tlv() - link layer stats set request
8119  * @wmi_handle:       wmi handle
8120  * @setReq:  ll stats set request command params
8121  *
8122  * Return: QDF_STATUS_SUCCESS for success or error code
8123  */
8124 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle,
8125 		const struct ll_stats_set_params *set_req)
8126 {
8127 	wmi_start_link_stats_cmd_fixed_param *cmd;
8128 	int32_t len;
8129 	wmi_buf_t buf;
8130 	uint8_t *buf_ptr;
8131 	int ret;
8132 
8133 	len = sizeof(*cmd);
8134 	buf = wmi_buf_alloc(wmi_handle, len);
8135 
8136 	if (!buf) {
8137 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8138 		return QDF_STATUS_E_NOMEM;
8139 	}
8140 
8141 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8142 	qdf_mem_zero(buf_ptr, len);
8143 	cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr;
8144 
8145 	WMITLV_SET_HDR(&cmd->tlv_header,
8146 		       WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param,
8147 		       WMITLV_GET_STRUCT_TLVLEN
8148 			       (wmi_start_link_stats_cmd_fixed_param));
8149 
8150 	cmd->mpdu_size_threshold = set_req->mpdu_size_threshold;
8151 	cmd->aggressive_statistics_gathering =
8152 		set_req->aggressive_statistics_gathering;
8153 
8154 	WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params");
8155 	WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold);
8156 	WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering);
8157 
8158 	wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0);
8159 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8160 				   WMI_START_LINK_STATS_CMDID);
8161 	if (ret) {
8162 		WMI_LOGE("%s: Failed to send set link stats request", __func__);
8163 		wmi_buf_free(buf);
8164 		return QDF_STATUS_E_FAILURE;
8165 	}
8166 
8167 	return QDF_STATUS_SUCCESS;
8168 }
8169 
8170 /**
8171  * send_process_ll_stats_get_cmd_tlv() - link layer stats get request
8172  * @wmi_handle:wmi handle
8173  * @get_req:ll stats get request command params
8174  * @addr: mac address
8175  *
8176  * Return: QDF_STATUS_SUCCESS for success or error code
8177  */
8178 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle,
8179 		 const struct ll_stats_get_params  *get_req,
8180 		 uint8_t addr[IEEE80211_ADDR_LEN])
8181 {
8182 	wmi_request_link_stats_cmd_fixed_param *cmd;
8183 	int32_t len;
8184 	wmi_buf_t buf;
8185 	uint8_t *buf_ptr;
8186 	int ret;
8187 
8188 	len = sizeof(*cmd);
8189 	buf = wmi_buf_alloc(wmi_handle, len);
8190 
8191 	if (!buf) {
8192 		WMI_LOGE("%s: buf allocation failed", __func__);
8193 		return QDF_STATUS_E_NOMEM;
8194 	}
8195 
8196 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8197 	qdf_mem_zero(buf_ptr, len);
8198 	cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr;
8199 
8200 	WMITLV_SET_HDR(&cmd->tlv_header,
8201 		       WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param,
8202 		       WMITLV_GET_STRUCT_TLVLEN
8203 			       (wmi_request_link_stats_cmd_fixed_param));
8204 
8205 	cmd->request_id = get_req->req_id;
8206 	cmd->stats_type = get_req->param_id_mask;
8207 	cmd->vdev_id = get_req->sta_id;
8208 
8209 	WMI_CHAR_ARRAY_TO_MAC_ADDR(addr,
8210 				   &cmd->peer_macaddr);
8211 
8212 	WMI_LOGD("LINK_LAYER_STATS - Get Request Params");
8213 	WMI_LOGD("Request ID      : %u", cmd->request_id);
8214 	WMI_LOGD("Stats Type      : %0x", cmd->stats_type);
8215 	WMI_LOGD("Vdev ID         : %d", cmd->vdev_id);
8216 	WMI_LOGD("Peer MAC Addr   : %pM", addr);
8217 
8218 	wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0);
8219 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8220 				   WMI_REQUEST_LINK_STATS_CMDID);
8221 	if (ret) {
8222 		WMI_LOGE("%s: Failed to send get link stats request", __func__);
8223 		wmi_buf_free(buf);
8224 		return QDF_STATUS_E_FAILURE;
8225 	}
8226 
8227 	return QDF_STATUS_SUCCESS;
8228 }
8229 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */
8230 
8231 /**
8232  * send_congestion_cmd_tlv() - send request to fw to get CCA
8233  * @wmi_handle: wmi handle
8234  * @vdev_id: vdev id
8235  *
8236  * Return: CDF status
8237  */
8238 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle,
8239 			uint8_t vdev_id)
8240 {
8241 	wmi_buf_t buf;
8242 	wmi_request_stats_cmd_fixed_param *cmd;
8243 	uint8_t len;
8244 	uint8_t *buf_ptr;
8245 
8246 	len = sizeof(*cmd);
8247 	buf = wmi_buf_alloc(wmi_handle, len);
8248 	if (!buf) {
8249 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
8250 		return QDF_STATUS_E_FAILURE;
8251 	}
8252 
8253 	buf_ptr = wmi_buf_data(buf);
8254 	cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr;
8255 	WMITLV_SET_HDR(&cmd->tlv_header,
8256 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8257 		       WMITLV_GET_STRUCT_TLVLEN
8258 			       (wmi_request_stats_cmd_fixed_param));
8259 
8260 	cmd->stats_id = WMI_REQUEST_CONGESTION_STAT;
8261 	cmd->vdev_id = vdev_id;
8262 	WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->",
8263 			cmd->vdev_id, cmd->stats_id);
8264 
8265 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
8266 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8267 				 WMI_REQUEST_STATS_CMDID)) {
8268 		WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID",
8269 			 __func__);
8270 		wmi_buf_free(buf);
8271 		return QDF_STATUS_E_FAILURE;
8272 	}
8273 
8274 	return QDF_STATUS_SUCCESS;
8275 }
8276 
8277 /**
8278  * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats
8279  * @wmi_handle: wmi handle
8280  * @rssi_req: get RSSI request
8281  *
8282  * Return: CDF status
8283  */
8284 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle)
8285 {
8286 	wmi_buf_t buf;
8287 	wmi_request_stats_cmd_fixed_param *cmd;
8288 	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
8289 
8290 	buf = wmi_buf_alloc(wmi_handle, len);
8291 	if (!buf) {
8292 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8293 		return QDF_STATUS_E_FAILURE;
8294 	}
8295 
8296 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
8297 	WMITLV_SET_HDR(&cmd->tlv_header,
8298 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8299 		       WMITLV_GET_STRUCT_TLVLEN
8300 			       (wmi_request_stats_cmd_fixed_param));
8301 	cmd->stats_id = WMI_REQUEST_VDEV_STAT;
8302 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
8303 	if (wmi_unified_cmd_send
8304 		    (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) {
8305 		WMI_LOGE("Failed to send host stats request to fw");
8306 		wmi_buf_free(buf);
8307 		return QDF_STATUS_E_FAILURE;
8308 	}
8309 
8310 	return QDF_STATUS_SUCCESS;
8311 }
8312 
8313 /**
8314  * send_snr_cmd_tlv() - get RSSI from fw
8315  * @wmi_handle: wmi handle
8316  * @vdev_id: vdev id
8317  *
8318  * Return: CDF status
8319  */
8320 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
8321 {
8322 	wmi_buf_t buf;
8323 	wmi_request_stats_cmd_fixed_param *cmd;
8324 	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
8325 
8326 	buf = wmi_buf_alloc(wmi_handle, len);
8327 	if (!buf) {
8328 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8329 		return QDF_STATUS_E_FAILURE;
8330 	}
8331 
8332 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
8333 	cmd->vdev_id = vdev_id;
8334 
8335 	WMITLV_SET_HDR(&cmd->tlv_header,
8336 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8337 		       WMITLV_GET_STRUCT_TLVLEN
8338 			       (wmi_request_stats_cmd_fixed_param));
8339 	cmd->stats_id = WMI_REQUEST_VDEV_STAT;
8340 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
8341 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8342 				 WMI_REQUEST_STATS_CMDID)) {
8343 		WMI_LOGE("Failed to send host stats request to fw");
8344 		wmi_buf_free(buf);
8345 		return QDF_STATUS_E_FAILURE;
8346 	}
8347 
8348 	return QDF_STATUS_SUCCESS;
8349 }
8350 
8351 /**
8352  * send_link_status_req_cmd_tlv() - process link status request from UMAC
8353  * @wmi_handle: wmi handle
8354  * @link_status: get link params
8355  *
8356  * Return: CDF status
8357  */
8358 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle,
8359 				 struct link_status_params *link_status)
8360 {
8361 	wmi_buf_t buf;
8362 	wmi_request_stats_cmd_fixed_param *cmd;
8363 	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
8364 
8365 	buf = wmi_buf_alloc(wmi_handle, len);
8366 	if (!buf) {
8367 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8368 		return QDF_STATUS_E_FAILURE;
8369 	}
8370 
8371 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
8372 	WMITLV_SET_HDR(&cmd->tlv_header,
8373 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8374 		       WMITLV_GET_STRUCT_TLVLEN
8375 			       (wmi_request_stats_cmd_fixed_param));
8376 	cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT;
8377 	cmd->vdev_id = link_status->session_id;
8378 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
8379 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8380 				 WMI_REQUEST_STATS_CMDID)) {
8381 		WMI_LOGE("Failed to send WMI link  status request to fw");
8382 		wmi_buf_free(buf);
8383 		return QDF_STATUS_E_FAILURE;
8384 	}
8385 
8386 	return QDF_STATUS_SUCCESS;
8387 }
8388 
8389 /**
8390  * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME
8391  * @wmi_handle: wmi handle
8392  * @ta_dhcp_ind: DHCP indication parameter
8393  *
8394  * Return: CDF Status
8395  */
8396 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle,
8397 				wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind)
8398 {
8399 	QDF_STATUS status;
8400 	wmi_buf_t buf = NULL;
8401 	uint8_t *buf_ptr;
8402 	wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp;
8403 	int len = sizeof(wmi_peer_set_param_cmd_fixed_param);
8404 
8405 
8406 	buf = wmi_buf_alloc(wmi_handle, len);
8407 	if (!buf) {
8408 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
8409 		return QDF_STATUS_E_NOMEM;
8410 	}
8411 
8412 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8413 	peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr;
8414 	WMITLV_SET_HDR(&peer_set_param_fp->tlv_header,
8415 		       WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
8416 		       WMITLV_GET_STRUCT_TLVLEN
8417 			       (wmi_peer_set_param_cmd_fixed_param));
8418 
8419 	/* fill in values */
8420 	peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id;
8421 	peer_set_param_fp->param_id = ta_dhcp_ind->param_id;
8422 	peer_set_param_fp->param_value = ta_dhcp_ind->param_value;
8423 	qdf_mem_copy(&peer_set_param_fp->peer_macaddr,
8424 				   &ta_dhcp_ind->peer_macaddr,
8425 				   sizeof(ta_dhcp_ind->peer_macaddr));
8426 
8427 	wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, NO_SESSION, 0);
8428 	status = wmi_unified_cmd_send(wmi_handle, buf,
8429 				      len, WMI_PEER_SET_PARAM_CMDID);
8430 	if (QDF_IS_STATUS_ERROR(status)) {
8431 		WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
8432 			 " returned Error %d", __func__, status);
8433 		wmi_buf_free(buf);
8434 	}
8435 
8436 	return status;
8437 }
8438 
8439 /**
8440  * send_get_link_speed_cmd_tlv() -send command to get linkspeed
8441  * @wmi_handle: wmi handle
8442  * @pLinkSpeed: link speed info
8443  *
8444  * Return: CDF status
8445  */
8446 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle,
8447 		wmi_mac_addr peer_macaddr)
8448 {
8449 	wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd;
8450 	wmi_buf_t wmi_buf;
8451 	uint32_t len;
8452 	uint8_t *buf_ptr;
8453 
8454 	len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param);
8455 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
8456 	if (!wmi_buf) {
8457 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8458 		return QDF_STATUS_E_NOMEM;
8459 	}
8460 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
8461 
8462 	cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr;
8463 	WMITLV_SET_HDR(&cmd->tlv_header,
8464 	       WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param,
8465 	       WMITLV_GET_STRUCT_TLVLEN
8466 	       (wmi_peer_get_estimated_linkspeed_cmd_fixed_param));
8467 
8468 	/* Copy the peer macaddress to the wma buffer */
8469 	qdf_mem_copy(&cmd->peer_macaddr,
8470 				   &peer_macaddr,
8471 				   sizeof(peer_macaddr));
8472 
8473 
8474 	wmi_mtrace(WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID, cmd->vdev_id, 0);
8475 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
8476 				 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) {
8477 		WMI_LOGE("%s: failed to send link speed command", __func__);
8478 		wmi_buf_free(wmi_buf);
8479 		return QDF_STATUS_E_FAILURE;
8480 	}
8481 	return QDF_STATUS_SUCCESS;
8482 }
8483 
8484 #ifdef WLAN_SUPPORT_GREEN_AP
8485 /**
8486  * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params
8487  * @wmi_handle:	 wmi handler
8488  * @egap_params: pointer to egap_params
8489  *
8490  * Return:	 0 for success, otherwise appropriate error code
8491  */
8492 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle,
8493 		     struct wlan_green_ap_egap_params *egap_params)
8494 {
8495 	wmi_ap_ps_egap_param_cmd_fixed_param *cmd;
8496 	wmi_buf_t buf;
8497 	int32_t err;
8498 
8499 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
8500 	if (!buf) {
8501 		WMI_LOGE("Failed to allocate buffer to send ap_ps_egap cmd");
8502 		return QDF_STATUS_E_NOMEM;
8503 	}
8504 	cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf);
8505 	WMITLV_SET_HDR(&cmd->tlv_header,
8506 		       WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param,
8507 		       WMITLV_GET_STRUCT_TLVLEN(
8508 			       wmi_ap_ps_egap_param_cmd_fixed_param));
8509 
8510 	cmd->enable = egap_params->host_enable_egap;
8511 	cmd->inactivity_time = egap_params->egap_inactivity_time;
8512 	cmd->wait_time = egap_params->egap_wait_time;
8513 	cmd->flags = egap_params->egap_feature_flags;
8514 	wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0);
8515 	err = wmi_unified_cmd_send(wmi_handle, buf,
8516 				   sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID);
8517 	if (err) {
8518 		WMI_LOGE("Failed to send ap_ps_egap cmd");
8519 		wmi_buf_free(buf);
8520 		return QDF_STATUS_E_FAILURE;
8521 	}
8522 
8523 	return QDF_STATUS_SUCCESS;
8524 }
8525 #endif
8526 
8527 /**
8528  * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW
8529  * @wmi_handl: wmi handle
8530  * @cmd: Profiling command index
8531  * @value1: parameter1 value
8532  * @value2: parameter2 value
8533  *
8534  * Return: QDF_STATUS_SUCCESS for success else error code
8535  */
8536 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle,
8537 			uint32_t cmd, uint32_t value1, uint32_t value2)
8538 {
8539 	wmi_buf_t buf;
8540 	int32_t len = 0;
8541 	int ret;
8542 	wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd;
8543 	wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd;
8544 	wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd;
8545 	wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd;
8546 
8547 	switch (cmd) {
8548 	case WMI_WLAN_PROFILE_TRIGGER_CMDID:
8549 		len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param);
8550 		buf = wmi_buf_alloc(wmi_handle, len);
8551 		if (!buf) {
8552 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
8553 			return QDF_STATUS_E_NOMEM;
8554 		}
8555 		prof_trig_cmd =
8556 			(wmi_wlan_profile_trigger_cmd_fixed_param *)
8557 				wmi_buf_data(buf);
8558 		WMITLV_SET_HDR(&prof_trig_cmd->tlv_header,
8559 		     WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param,
8560 		     WMITLV_GET_STRUCT_TLVLEN
8561 		    (wmi_wlan_profile_trigger_cmd_fixed_param));
8562 		prof_trig_cmd->enable = value1;
8563 		wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0);
8564 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8565 				WMI_WLAN_PROFILE_TRIGGER_CMDID);
8566 		if (ret) {
8567 			WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d",
8568 					value1);
8569 			wmi_buf_free(buf);
8570 			return ret;
8571 		}
8572 		break;
8573 
8574 	case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
8575 		len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param);
8576 		buf = wmi_buf_alloc(wmi_handle, len);
8577 		if (!buf) {
8578 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
8579 			return QDF_STATUS_E_NOMEM;
8580 		}
8581 		profile_getdata_cmd =
8582 			(wmi_wlan_profile_get_prof_data_cmd_fixed_param *)
8583 				wmi_buf_data(buf);
8584 		WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header,
8585 		      WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param,
8586 		      WMITLV_GET_STRUCT_TLVLEN
8587 		      (wmi_wlan_profile_get_prof_data_cmd_fixed_param));
8588 		wmi_mtrace(WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
8589 			   NO_SESSION, 0);
8590 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8591 				WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID);
8592 		if (ret) {
8593 			WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d",
8594 					value1, value2);
8595 			wmi_buf_free(buf);
8596 			return ret;
8597 		}
8598 		break;
8599 
8600 	case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
8601 		len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param);
8602 		buf = wmi_buf_alloc(wmi_handle, len);
8603 		if (!buf) {
8604 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
8605 			return QDF_STATUS_E_NOMEM;
8606 		}
8607 		hist_intvl_cmd =
8608 			(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *)
8609 				wmi_buf_data(buf);
8610 		WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header,
8611 		      WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param,
8612 		      WMITLV_GET_STRUCT_TLVLEN
8613 		      (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param));
8614 		hist_intvl_cmd->profile_id = value1;
8615 		hist_intvl_cmd->value = value2;
8616 		wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
8617 			   NO_SESSION, 0);
8618 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8619 				WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID);
8620 		if (ret) {
8621 			WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d",
8622 					value1, value2);
8623 			wmi_buf_free(buf);
8624 			return ret;
8625 		}
8626 		break;
8627 
8628 	case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
8629 		len =
8630 		sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param);
8631 		buf = wmi_buf_alloc(wmi_handle, len);
8632 		if (!buf) {
8633 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
8634 			return QDF_STATUS_E_NOMEM;
8635 		}
8636 		profile_enable_cmd =
8637 			(wmi_wlan_profile_enable_profile_id_cmd_fixed_param *)
8638 				wmi_buf_data(buf);
8639 		WMITLV_SET_HDR(&profile_enable_cmd->tlv_header,
8640 		      WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param,
8641 		      WMITLV_GET_STRUCT_TLVLEN
8642 		      (wmi_wlan_profile_enable_profile_id_cmd_fixed_param));
8643 		profile_enable_cmd->profile_id = value1;
8644 		profile_enable_cmd->enable = value2;
8645 		wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
8646 			   NO_SESSION, 0);
8647 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8648 				WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID);
8649 		if (ret) {
8650 			WMI_LOGE("enable cmd Failed for id %d value %d",
8651 					value1, value2);
8652 			wmi_buf_free(buf);
8653 			return ret;
8654 		}
8655 		break;
8656 
8657 	default:
8658 		WMI_LOGD("%s: invalid profiling command", __func__);
8659 		break;
8660 	}
8661 
8662 	return 0;
8663 }
8664 
8665 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle,
8666 				struct wlm_latency_level_param *params)
8667 {
8668 	wmi_wlm_config_cmd_fixed_param *cmd;
8669 	wmi_buf_t buf;
8670 	uint32_t len = sizeof(*cmd);
8671 	static uint32_t ll[4] = {100, 60, 40, 20};
8672 
8673 	buf = wmi_buf_alloc(wmi_handle, len);
8674 	if (!buf) {
8675 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
8676 		return QDF_STATUS_E_NOMEM;
8677 	}
8678 	cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf);
8679 	WMITLV_SET_HDR(&cmd->tlv_header,
8680 		       WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param,
8681 		       WMITLV_GET_STRUCT_TLVLEN
8682 		       (wmi_wlm_config_cmd_fixed_param));
8683 	cmd->vdev_id = params->vdev_id;
8684 	cmd->latency_level = params->wlm_latency_level;
8685 	cmd->ul_latency = ll[params->wlm_latency_level];
8686 	cmd->dl_latency = ll[params->wlm_latency_level];
8687 	cmd->flags = params->wlm_latency_flags;
8688 	wmi_mtrace(WMI_WLM_CONFIG_CMDID, cmd->vdev_id, 0);
8689 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8690 				 WMI_WLM_CONFIG_CMDID)) {
8691 		WMI_LOGE("%s: Failed to send setting latency config command",
8692 			 __func__);
8693 		wmi_buf_free(buf);
8694 		return QDF_STATUS_E_FAILURE;
8695 	}
8696 
8697 	return 0;
8698 }
8699 /**
8700  * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter
8701  * @wmi_handle: wmi handle
8702  * @vdev_id: vdev id
8703  *
8704  * Return: QDF_STATUS_SUCCESS for success or error code
8705  */
8706 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
8707 {
8708 	WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd;
8709 	wmi_buf_t buf;
8710 	int32_t len = sizeof(*cmd);
8711 
8712 	WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
8713 	buf = wmi_buf_alloc(wmi_handle, len);
8714 	if (!buf) {
8715 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
8716 		return QDF_STATUS_E_NOMEM;
8717 	}
8718 	cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *)
8719 		wmi_buf_data(buf);
8720 	WMITLV_SET_HDR(&cmd->tlv_header,
8721 	WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param,
8722 		  WMITLV_GET_STRUCT_TLVLEN
8723 		  (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param));
8724 	cmd->vdev_id = vdev_id;
8725 	cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE;
8726 	wmi_mtrace(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID, cmd->vdev_id, 0);
8727 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8728 				 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) {
8729 		WMI_LOGP("%s: Failed to send NAT keepalive enable command",
8730 			 __func__);
8731 		wmi_buf_free(buf);
8732 		return QDF_STATUS_E_FAILURE;
8733 	}
8734 
8735 	return 0;
8736 }
8737 
8738 /**
8739  * wmi_unified_csa_offload_enable() - sen CSA offload enable command
8740  * @wmi_handle: wmi handle
8741  * @vdev_id: vdev id
8742  *
8743  * Return: QDF_STATUS_SUCCESS for success or error code
8744  */
8745 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle,
8746 			uint8_t vdev_id)
8747 {
8748 	wmi_csa_offload_enable_cmd_fixed_param *cmd;
8749 	wmi_buf_t buf;
8750 	int32_t len = sizeof(*cmd);
8751 
8752 	WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
8753 	buf = wmi_buf_alloc(wmi_handle, len);
8754 	if (!buf) {
8755 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
8756 		return QDF_STATUS_E_NOMEM;
8757 	}
8758 	cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf);
8759 	WMITLV_SET_HDR(&cmd->tlv_header,
8760 		       WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param,
8761 		       WMITLV_GET_STRUCT_TLVLEN
8762 			       (wmi_csa_offload_enable_cmd_fixed_param));
8763 	cmd->vdev_id = vdev_id;
8764 	cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE;
8765 	wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0);
8766 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8767 				 WMI_CSA_OFFLOAD_ENABLE_CMDID)) {
8768 		WMI_LOGP("%s: Failed to send CSA offload enable command",
8769 			 __func__);
8770 		wmi_buf_free(buf);
8771 		return QDF_STATUS_E_FAILURE;
8772 	}
8773 
8774 	return 0;
8775 }
8776 
8777 #ifdef WLAN_FEATURE_CIF_CFR
8778 /**
8779  * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings
8780  * @wmi_handle: wmi handle
8781  * @data_len: len of dma cfg req
8782  * @data: dma cfg req
8783  *
8784  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
8785  */
8786 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle,
8787 				wmi_oem_dma_ring_cfg_req_fixed_param *cfg)
8788 {
8789 	wmi_buf_t buf;
8790 	uint8_t *cmd;
8791 	QDF_STATUS ret;
8792 
8793 	WMITLV_SET_HDR(cfg,
8794 		WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param,
8795 		(sizeof(*cfg) - WMI_TLV_HDR_SIZE));
8796 
8797 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg));
8798 	if (!buf) {
8799 		WMI_LOGE(FL("wmi_buf_alloc failed"));
8800 		return QDF_STATUS_E_FAILURE;
8801 	}
8802 
8803 	cmd = (uint8_t *) wmi_buf_data(buf);
8804 	qdf_mem_copy(cmd, cfg, sizeof(*cfg));
8805 	WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"),
8806 		sizeof(*cfg));
8807 	wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0);
8808 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg),
8809 				WMI_OEM_DMA_RING_CFG_REQ_CMDID);
8810 	if (QDF_IS_STATUS_ERROR(ret)) {
8811 		WMI_LOGE(FL(":wmi cmd send failed"));
8812 		wmi_buf_free(buf);
8813 	}
8814 
8815 	return ret;
8816 }
8817 #endif
8818 
8819 /**
8820  * send_dbr_cfg_cmd_tlv() - configure DMA rings for Direct Buf RX
8821  * @wmi_handle: wmi handle
8822  * @data_len: len of dma cfg req
8823  * @data: dma cfg req
8824  *
8825  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
8826  */
8827 static QDF_STATUS send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle,
8828 				struct direct_buf_rx_cfg_req *cfg)
8829 {
8830 	wmi_buf_t buf;
8831 	wmi_dma_ring_cfg_req_fixed_param *cmd;
8832 	QDF_STATUS ret;
8833 	int32_t len = sizeof(*cmd);
8834 
8835 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
8836 	if (!buf) {
8837 		WMI_LOGE(FL("wmi_buf_alloc failed"));
8838 		return QDF_STATUS_E_FAILURE;
8839 	}
8840 
8841 	cmd = (wmi_dma_ring_cfg_req_fixed_param *)wmi_buf_data(buf);
8842 
8843 	WMITLV_SET_HDR(&cmd->tlv_header,
8844 		WMITLV_TAG_STRUC_wmi_dma_ring_cfg_req_fixed_param,
8845 		WMITLV_GET_STRUCT_TLVLEN(wmi_dma_ring_cfg_req_fixed_param));
8846 
8847 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
8848 						cfg->pdev_id);
8849 	cmd->mod_id = cfg->mod_id;
8850 	cmd->base_paddr_lo = cfg->base_paddr_lo;
8851 	cmd->base_paddr_hi = cfg->base_paddr_hi;
8852 	cmd->head_idx_paddr_lo = cfg->head_idx_paddr_lo;
8853 	cmd->head_idx_paddr_hi = cfg->head_idx_paddr_hi;
8854 	cmd->tail_idx_paddr_lo = cfg->tail_idx_paddr_lo;
8855 	cmd->tail_idx_paddr_hi = cfg->tail_idx_paddr_hi;
8856 	cmd->num_elems = cfg->num_elems;
8857 	cmd->buf_size = cfg->buf_size;
8858 	cmd->num_resp_per_event = cfg->num_resp_per_event;
8859 	cmd->event_timeout_ms = cfg->event_timeout_ms;
8860 
8861 	WMI_LOGD("%s: wmi_dma_ring_cfg_req_fixed_param pdev id %d mod id %d"
8862 		  "base paddr lo %x base paddr hi %x head idx paddr lo %x"
8863 		  "head idx paddr hi %x tail idx paddr lo %x"
8864 		  "tail idx addr hi %x num elems %d buf size %d num resp %d"
8865 		  "event timeout %d\n", __func__, cmd->pdev_id,
8866 		  cmd->mod_id, cmd->base_paddr_lo, cmd->base_paddr_hi,
8867 		  cmd->head_idx_paddr_lo, cmd->head_idx_paddr_hi,
8868 		  cmd->tail_idx_paddr_lo, cmd->tail_idx_paddr_hi,
8869 		  cmd->num_elems, cmd->buf_size, cmd->num_resp_per_event,
8870 		  cmd->event_timeout_ms);
8871 	wmi_mtrace(WMI_PDEV_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0);
8872 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8873 				WMI_PDEV_DMA_RING_CFG_REQ_CMDID);
8874 	if (QDF_IS_STATUS_ERROR(ret)) {
8875 		WMI_LOGE(FL(":wmi cmd send failed"));
8876 		wmi_buf_free(buf);
8877 	}
8878 
8879 	return ret;
8880 }
8881 
8882 /**
8883  * send_start_11d_scan_cmd_tlv() - start 11d scan request
8884  * @wmi_handle: wmi handle
8885  * @start_11d_scan: 11d scan start request parameters
8886  *
8887  * This function request FW to start 11d scan.
8888  *
8889  * Return: QDF status
8890  */
8891 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle,
8892 			  struct reg_start_11d_scan_req *start_11d_scan)
8893 {
8894 	wmi_11d_scan_start_cmd_fixed_param *cmd;
8895 	int32_t len;
8896 	wmi_buf_t buf;
8897 	int ret;
8898 
8899 	len = sizeof(*cmd);
8900 	buf = wmi_buf_alloc(wmi_handle, len);
8901 	if (!buf) {
8902 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8903 		return QDF_STATUS_E_NOMEM;
8904 	}
8905 
8906 	cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf);
8907 
8908 	WMITLV_SET_HDR(&cmd->tlv_header,
8909 		       WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param,
8910 		       WMITLV_GET_STRUCT_TLVLEN
8911 		       (wmi_11d_scan_start_cmd_fixed_param));
8912 
8913 	cmd->vdev_id = start_11d_scan->vdev_id;
8914 	cmd->scan_period_msec = start_11d_scan->scan_period_msec;
8915 	cmd->start_interval_msec = start_11d_scan->start_interval_msec;
8916 
8917 	WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id);
8918 
8919 	wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0);
8920 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8921 				   WMI_11D_SCAN_START_CMDID);
8922 	if (ret) {
8923 		WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__);
8924 		wmi_buf_free(buf);
8925 		return QDF_STATUS_E_FAILURE;
8926 	}
8927 
8928 	return QDF_STATUS_SUCCESS;
8929 }
8930 
8931 /**
8932  * send_stop_11d_scan_cmd_tlv() - stop 11d scan request
8933  * @wmi_handle: wmi handle
8934  * @start_11d_scan: 11d scan stop request parameters
8935  *
8936  * This function request FW to stop 11d scan.
8937  *
8938  * Return: QDF status
8939  */
8940 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle,
8941 			  struct reg_stop_11d_scan_req *stop_11d_scan)
8942 {
8943 	wmi_11d_scan_stop_cmd_fixed_param *cmd;
8944 	int32_t len;
8945 	wmi_buf_t buf;
8946 	int ret;
8947 
8948 	len = sizeof(*cmd);
8949 	buf = wmi_buf_alloc(wmi_handle, len);
8950 	if (!buf) {
8951 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8952 		return QDF_STATUS_E_NOMEM;
8953 	}
8954 
8955 	cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf);
8956 
8957 	WMITLV_SET_HDR(&cmd->tlv_header,
8958 		       WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param,
8959 		       WMITLV_GET_STRUCT_TLVLEN
8960 		       (wmi_11d_scan_stop_cmd_fixed_param));
8961 
8962 	cmd->vdev_id = stop_11d_scan->vdev_id;
8963 
8964 	WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id);
8965 
8966 	wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0);
8967 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8968 				   WMI_11D_SCAN_STOP_CMDID);
8969 	if (ret) {
8970 		WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__);
8971 		wmi_buf_free(buf);
8972 		return QDF_STATUS_E_FAILURE;
8973 	}
8974 
8975 	return QDF_STATUS_SUCCESS;
8976 }
8977 
8978 /**
8979  * send_start_oem_data_cmd_tlv() - start OEM data request to target
8980  * @wmi_handle: wmi handle
8981  * @startOemDataReq: start request params
8982  *
8983  * Return: CDF status
8984  */
8985 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle,
8986 			  uint32_t data_len,
8987 			  uint8_t *data)
8988 {
8989 	wmi_buf_t buf;
8990 	uint8_t *cmd;
8991 	QDF_STATUS ret;
8992 
8993 	buf = wmi_buf_alloc(wmi_handle,
8994 			    (data_len + WMI_TLV_HDR_SIZE));
8995 	if (!buf) {
8996 		WMI_LOGE(FL("wmi_buf_alloc failed"));
8997 		return QDF_STATUS_E_FAILURE;
8998 	}
8999 
9000 	cmd = (uint8_t *) wmi_buf_data(buf);
9001 
9002 	WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len);
9003 	cmd += WMI_TLV_HDR_SIZE;
9004 	qdf_mem_copy(cmd, data,
9005 		     data_len);
9006 
9007 	WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"),
9008 		 data_len);
9009 
9010 	wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0);
9011 	ret = wmi_unified_cmd_send(wmi_handle, buf,
9012 				   (data_len +
9013 				    WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID);
9014 
9015 	if (QDF_IS_STATUS_ERROR(ret)) {
9016 		WMI_LOGE(FL(":wmi cmd send failed"));
9017 		wmi_buf_free(buf);
9018 	}
9019 
9020 	return ret;
9021 }
9022 
9023 /**
9024  * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter
9025  * @wmi_handle: wmi handle
9026  * @dfs_phyerr_filter_offload: is dfs phyerr filter offload
9027  *
9028  * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or
9029  * WMI_DFS_PHYERR_FILTER_DIS_CMDID command
9030  * to firmware based on phyerr filtering
9031  * offload status.
9032  *
9033  * Return: 1 success, 0 failure
9034  */
9035 static QDF_STATUS
9036 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle,
9037 			bool dfs_phyerr_filter_offload)
9038 {
9039 	wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd;
9040 	wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd;
9041 	wmi_buf_t buf;
9042 	uint16_t len;
9043 	QDF_STATUS ret;
9044 
9045 
9046 	if (false == dfs_phyerr_filter_offload) {
9047 		WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini",
9048 			 __func__);
9049 		len = sizeof(*disable_phyerr_offload_cmd);
9050 		buf = wmi_buf_alloc(wmi_handle, len);
9051 		if (!buf) {
9052 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9053 			return 0;
9054 		}
9055 		disable_phyerr_offload_cmd =
9056 			(wmi_dfs_phyerr_filter_dis_cmd_fixed_param *)
9057 			wmi_buf_data(buf);
9058 
9059 		WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header,
9060 		     WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param,
9061 		     WMITLV_GET_STRUCT_TLVLEN
9062 		     (wmi_dfs_phyerr_filter_dis_cmd_fixed_param));
9063 
9064 		/*
9065 		 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID
9066 		 * to the firmware to disable the phyerror
9067 		 * filtering offload.
9068 		 */
9069 		wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0);
9070 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9071 					   WMI_DFS_PHYERR_FILTER_DIS_CMDID);
9072 		if (QDF_IS_STATUS_ERROR(ret)) {
9073 			WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d",
9074 				__func__, ret);
9075 			wmi_buf_free(buf);
9076 		return QDF_STATUS_E_FAILURE;
9077 		}
9078 		WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success",
9079 			 __func__);
9080 	} else {
9081 		WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini",
9082 			 __func__);
9083 
9084 		len = sizeof(*enable_phyerr_offload_cmd);
9085 		buf = wmi_buf_alloc(wmi_handle, len);
9086 		if (!buf) {
9087 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9088 		return QDF_STATUS_E_FAILURE;
9089 		}
9090 
9091 		enable_phyerr_offload_cmd =
9092 			(wmi_dfs_phyerr_filter_ena_cmd_fixed_param *)
9093 			wmi_buf_data(buf);
9094 
9095 		WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header,
9096 		     WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param,
9097 		     WMITLV_GET_STRUCT_TLVLEN
9098 		     (wmi_dfs_phyerr_filter_ena_cmd_fixed_param));
9099 
9100 		/*
9101 		 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID
9102 		 * to the firmware to enable the phyerror
9103 		 * filtering offload.
9104 		 */
9105 		wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0);
9106 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9107 					   WMI_DFS_PHYERR_FILTER_ENA_CMDID);
9108 
9109 		if (QDF_IS_STATUS_ERROR(ret)) {
9110 			WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d",
9111 				__func__, ret);
9112 			wmi_buf_free(buf);
9113 		return QDF_STATUS_E_FAILURE;
9114 		}
9115 		WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success",
9116 			 __func__);
9117 	}
9118 
9119 	return QDF_STATUS_SUCCESS;
9120 }
9121 
9122 /**
9123  * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware
9124  * will wake up host after specified time is elapsed
9125  * @wmi_handle: wmi handle
9126  * @vdev_id: vdev id
9127  * @cookie: value to identify reason why host set up wake call.
9128  * @time: time in ms
9129  *
9130  * Return: QDF status
9131  */
9132 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle,
9133 				uint8_t vdev_id, uint32_t cookie, uint32_t time)
9134 {
9135 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
9136 	wmi_buf_t buf;
9137 	uint8_t *buf_ptr;
9138 	int32_t len;
9139 	int ret;
9140 
9141 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
9142 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) +
9143 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
9144 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
9145 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
9146 		WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) +
9147 		WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
9148 
9149 	buf = wmi_buf_alloc(wmi_handle, len);
9150 	if (!buf) {
9151 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9152 		return QDF_STATUS_E_NOMEM;
9153 	}
9154 
9155 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
9156 	buf_ptr = (uint8_t *) cmd;
9157 
9158 	WMITLV_SET_HDR(&cmd->tlv_header,
9159 		WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
9160 		WMITLV_GET_STRUCT_TLVLEN
9161 			(WMI_WOW_ADD_PATTERN_CMD_fixed_param));
9162 	cmd->vdev_id = vdev_id;
9163 	cmd->pattern_id = cookie,
9164 	cmd->pattern_type = WOW_TIMER_PATTERN;
9165 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
9166 
9167 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
9168 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9169 	buf_ptr += WMI_TLV_HDR_SIZE;
9170 
9171 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
9172 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9173 	buf_ptr += WMI_TLV_HDR_SIZE;
9174 
9175 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
9176 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9177 	buf_ptr += WMI_TLV_HDR_SIZE;
9178 
9179 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
9180 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9181 	buf_ptr += WMI_TLV_HDR_SIZE;
9182 
9183 	/* Fill TLV for pattern_info_timeout, and time value */
9184 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
9185 	buf_ptr += WMI_TLV_HDR_SIZE;
9186 	*((uint32_t *) buf_ptr) = time;
9187 	buf_ptr += sizeof(uint32_t);
9188 
9189 	/* Fill TLV for ra_ratelimit_interval. with dummy 0 value */
9190 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
9191 	buf_ptr += WMI_TLV_HDR_SIZE;
9192 	*((uint32_t *) buf_ptr) = 0;
9193 
9194 	WMI_LOGD("%s: send wake timer pattern with time[%d] to fw vdev = %d",
9195 		__func__, time, vdev_id);
9196 
9197 	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
9198 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9199 				WMI_WOW_ADD_WAKE_PATTERN_CMDID);
9200 	if (ret) {
9201 		WMI_LOGE("%s: Failed to send wake timer pattern to fw",
9202 			__func__);
9203 		wmi_buf_free(buf);
9204 		return QDF_STATUS_E_FAILURE;
9205 	}
9206 
9207 	return QDF_STATUS_SUCCESS;
9208 }
9209 
9210 #if !defined(REMOVE_PKT_LOG)
9211 /**
9212  * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target
9213  * @wmi_handle: wmi handle
9214  * @pktlog_event: pktlog event
9215  * @cmd_id: pktlog cmd id
9216  *
9217  * Return: CDF status
9218  */
9219 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle,
9220 				   WMI_PKTLOG_EVENT pktlog_event,
9221 				   WMI_CMD_ID cmd_id, uint8_t user_triggered)
9222 {
9223 	WMI_PKTLOG_EVENT PKTLOG_EVENT;
9224 	WMI_CMD_ID CMD_ID;
9225 	wmi_pdev_pktlog_enable_cmd_fixed_param *cmd;
9226 	wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd;
9227 	int len = 0;
9228 	wmi_buf_t buf;
9229 
9230 	PKTLOG_EVENT = pktlog_event;
9231 	CMD_ID = cmd_id;
9232 
9233 	switch (CMD_ID) {
9234 	case WMI_PDEV_PKTLOG_ENABLE_CMDID:
9235 		len = sizeof(*cmd);
9236 		buf = wmi_buf_alloc(wmi_handle, len);
9237 		if (!buf) {
9238 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9239 			return QDF_STATUS_E_NOMEM;
9240 		}
9241 		cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *)
9242 			wmi_buf_data(buf);
9243 		WMITLV_SET_HDR(&cmd->tlv_header,
9244 		       WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param,
9245 		       WMITLV_GET_STRUCT_TLVLEN
9246 		       (wmi_pdev_pktlog_enable_cmd_fixed_param));
9247 		cmd->evlist = PKTLOG_EVENT;
9248 		cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE
9249 					: WMI_PKTLOG_ENABLE_AUTO;
9250 		cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
9251 							WMI_HOST_PDEV_ID_SOC);
9252 		wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0);
9253 		if (wmi_unified_cmd_send(wmi_handle, buf, len,
9254 					 WMI_PDEV_PKTLOG_ENABLE_CMDID)) {
9255 			WMI_LOGE("failed to send pktlog enable cmdid");
9256 			goto wmi_send_failed;
9257 		}
9258 		break;
9259 	case WMI_PDEV_PKTLOG_DISABLE_CMDID:
9260 		len = sizeof(*disable_cmd);
9261 		buf = wmi_buf_alloc(wmi_handle, len);
9262 		if (!buf) {
9263 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9264 			return QDF_STATUS_E_NOMEM;
9265 		}
9266 		disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *)
9267 			      wmi_buf_data(buf);
9268 		WMITLV_SET_HDR(&disable_cmd->tlv_header,
9269 		     WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param,
9270 		     WMITLV_GET_STRUCT_TLVLEN
9271 		     (wmi_pdev_pktlog_disable_cmd_fixed_param));
9272 		disable_cmd->pdev_id =
9273 			wmi_handle->ops->convert_pdev_id_host_to_target(
9274 							WMI_HOST_PDEV_ID_SOC);
9275 		wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0);
9276 		if (wmi_unified_cmd_send(wmi_handle, buf, len,
9277 					 WMI_PDEV_PKTLOG_DISABLE_CMDID)) {
9278 			WMI_LOGE("failed to send pktlog disable cmdid");
9279 			goto wmi_send_failed;
9280 		}
9281 		break;
9282 	default:
9283 		WMI_LOGD("%s: invalid PKTLOG command", __func__);
9284 		break;
9285 	}
9286 
9287 	return QDF_STATUS_SUCCESS;
9288 
9289 wmi_send_failed:
9290 	wmi_buf_free(buf);
9291 	return QDF_STATUS_E_FAILURE;
9292 }
9293 #endif /* REMOVE_PKT_LOG */
9294 
9295 /**
9296  * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target
9297  * @wmi_handle: wmi handle
9298  * @ptrn_id: pattern id
9299  * @vdev_id: vdev id
9300  *
9301  * Return: CDF status
9302  */
9303 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle,
9304 			uint8_t ptrn_id, uint8_t vdev_id)
9305 {
9306 	WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd;
9307 	wmi_buf_t buf;
9308 	int32_t len;
9309 	int ret;
9310 
9311 	len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param);
9312 
9313 
9314 	buf = wmi_buf_alloc(wmi_handle, len);
9315 	if (!buf) {
9316 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9317 		return QDF_STATUS_E_NOMEM;
9318 	}
9319 
9320 	cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
9321 
9322 	WMITLV_SET_HDR(&cmd->tlv_header,
9323 		       WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param,
9324 		       WMITLV_GET_STRUCT_TLVLEN(
9325 				WMI_WOW_DEL_PATTERN_CMD_fixed_param));
9326 	cmd->vdev_id = vdev_id;
9327 	cmd->pattern_id = ptrn_id;
9328 	cmd->pattern_type = WOW_BITMAP_PATTERN;
9329 
9330 	WMI_LOGI("Deleting pattern id: %d vdev id %d in fw",
9331 		cmd->pattern_id, vdev_id);
9332 
9333 	wmi_mtrace(WMI_WOW_DEL_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
9334 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9335 				   WMI_WOW_DEL_WAKE_PATTERN_CMDID);
9336 	if (ret) {
9337 		WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__);
9338 		wmi_buf_free(buf);
9339 		return QDF_STATUS_E_FAILURE;
9340 	}
9341 
9342 	return QDF_STATUS_SUCCESS;
9343 }
9344 
9345 /**
9346  * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw
9347  * @wmi_handle: wmi handle
9348  *
9349  * Sends host wakeup indication to FW. On receiving this indication,
9350  * FW will come out of WOW.
9351  *
9352  * Return: CDF status
9353  */
9354 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle)
9355 {
9356 	wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd;
9357 	wmi_buf_t buf;
9358 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
9359 	int32_t len;
9360 	int ret;
9361 
9362 	len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param);
9363 
9364 	buf = wmi_buf_alloc(wmi_handle, len);
9365 	if (!buf) {
9366 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9367 		return QDF_STATUS_E_NOMEM;
9368 	}
9369 
9370 	cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *)
9371 	      wmi_buf_data(buf);
9372 	WMITLV_SET_HDR(&cmd->tlv_header,
9373 		WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param,
9374 		WMITLV_GET_STRUCT_TLVLEN
9375 	       (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param));
9376 
9377 
9378 	wmi_mtrace(WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, NO_SESSION, 0);
9379 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9380 				   WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID);
9381 	if (ret) {
9382 		WMI_LOGE("Failed to send host wakeup indication to fw");
9383 		wmi_buf_free(buf);
9384 		return QDF_STATUS_E_FAILURE;
9385 	}
9386 
9387 	return qdf_status;
9388 }
9389 
9390 /**
9391  * send_del_ts_cmd_tlv() - send DELTS request to fw
9392  * @wmi_handle: wmi handle
9393  * @msg: delts params
9394  *
9395  * Return: CDF status
9396  */
9397 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
9398 				uint8_t ac)
9399 {
9400 	wmi_vdev_wmm_delts_cmd_fixed_param *cmd;
9401 	wmi_buf_t buf;
9402 	int32_t len = sizeof(*cmd);
9403 
9404 	buf = wmi_buf_alloc(wmi_handle, len);
9405 	if (!buf) {
9406 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9407 		return QDF_STATUS_E_NOMEM;
9408 	}
9409 	cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf);
9410 	WMITLV_SET_HDR(&cmd->tlv_header,
9411 		       WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param,
9412 		       WMITLV_GET_STRUCT_TLVLEN
9413 			       (wmi_vdev_wmm_delts_cmd_fixed_param));
9414 	cmd->vdev_id = vdev_id;
9415 	cmd->ac = ac;
9416 
9417 	WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d",
9418 		 cmd->vdev_id, cmd->ac, __func__, __LINE__);
9419 	wmi_mtrace(WMI_VDEV_WMM_DELTS_CMDID, cmd->vdev_id, 0);
9420 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
9421 				 WMI_VDEV_WMM_DELTS_CMDID)) {
9422 		WMI_LOGP("%s: Failed to send vdev DELTS command", __func__);
9423 		wmi_buf_free(buf);
9424 		return QDF_STATUS_E_FAILURE;
9425 	}
9426 
9427 	return QDF_STATUS_SUCCESS;
9428 }
9429 
9430 /**
9431  * send_aggr_qos_cmd_tlv() - send aggr qos request to fw
9432  * @wmi_handle: handle to wmi
9433  * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests.
9434  *
9435  * A function to handle WMI_AGGR_QOS_REQ. This will send out
9436  * ADD_TS requestes to firmware in loop for all the ACs with
9437  * active flow.
9438  *
9439  * Return: CDF status
9440  */
9441 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle,
9442 		      struct aggr_add_ts_param *aggr_qos_rsp_msg)
9443 {
9444 	int i = 0;
9445 	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
9446 	wmi_buf_t buf;
9447 	int32_t len = sizeof(*cmd);
9448 
9449 	for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) {
9450 		/* if flow in this AC is active */
9451 		if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) {
9452 			/*
9453 			 * as per implementation of wma_add_ts_req() we
9454 			 * are not waiting any response from firmware so
9455 			 * apart from sending ADDTS to firmware just send
9456 			 * success to upper layers
9457 			 */
9458 			aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS;
9459 
9460 			buf = wmi_buf_alloc(wmi_handle, len);
9461 			if (!buf) {
9462 				WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9463 				return QDF_STATUS_E_NOMEM;
9464 			}
9465 			cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *)
9466 				wmi_buf_data(buf);
9467 			WMITLV_SET_HDR(&cmd->tlv_header,
9468 			       WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
9469 			       WMITLV_GET_STRUCT_TLVLEN
9470 				       (wmi_vdev_wmm_addts_cmd_fixed_param));
9471 			cmd->vdev_id = aggr_qos_rsp_msg->vdev_id;
9472 			cmd->ac =
9473 				WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo.
9474 					      traffic.userPrio);
9475 			cmd->medium_time_us =
9476 				aggr_qos_rsp_msg->tspec[i].mediumTime * 32;
9477 			cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO;
9478 			WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d",
9479 				__func__, __LINE__, cmd->vdev_id, cmd->ac,
9480 				cmd->medium_time_us, cmd->downgrade_type);
9481 			wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
9482 			if (wmi_unified_cmd_send
9483 				    (wmi_handle, buf, len,
9484 				    WMI_VDEV_WMM_ADDTS_CMDID)) {
9485 				WMI_LOGP("%s: Failed to send vdev ADDTS command",
9486 					__func__);
9487 				aggr_qos_rsp_msg->status[i] =
9488 					QDF_STATUS_E_FAILURE;
9489 				wmi_buf_free(buf);
9490 				return QDF_STATUS_E_FAILURE;
9491 			}
9492 		}
9493 	}
9494 
9495 	return QDF_STATUS_SUCCESS;
9496 }
9497 
9498 /**
9499  * send_add_ts_cmd_tlv() - send ADDTS request to fw
9500  * @wmi_handle: wmi handle
9501  * @msg: ADDTS params
9502  *
9503  * Return: CDF status
9504  */
9505 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle,
9506 		 struct add_ts_param *msg)
9507 {
9508 	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
9509 	wmi_buf_t buf;
9510 	int32_t len = sizeof(*cmd);
9511 
9512 	msg->status = QDF_STATUS_SUCCESS;
9513 
9514 	buf = wmi_buf_alloc(wmi_handle, len);
9515 	if (!buf) {
9516 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9517 		return QDF_STATUS_E_NOMEM;
9518 	}
9519 	cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf);
9520 	WMITLV_SET_HDR(&cmd->tlv_header,
9521 		       WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
9522 		       WMITLV_GET_STRUCT_TLVLEN
9523 			       (wmi_vdev_wmm_addts_cmd_fixed_param));
9524 	cmd->vdev_id = msg->sme_session_id;
9525 	cmd->ac = msg->tspec.tsinfo.traffic.userPrio;
9526 	cmd->medium_time_us = msg->tspec.mediumTime * 32;
9527 	cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP;
9528 	WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d",
9529 		 cmd->vdev_id, cmd->ac, cmd->medium_time_us,
9530 		 cmd->downgrade_type, __func__, __LINE__);
9531 	wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
9532 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
9533 				 WMI_VDEV_WMM_ADDTS_CMDID)) {
9534 		WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__);
9535 		msg->status = QDF_STATUS_E_FAILURE;
9536 		wmi_buf_free(buf);
9537 		return QDF_STATUS_E_FAILURE;
9538 	}
9539 
9540 	return QDF_STATUS_SUCCESS;
9541 }
9542 
9543 /**
9544  * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn
9545  * @wmi_handle: wmi handle
9546  * @pAddPeriodicTxPtrnParams: tx ptrn params
9547  *
9548  * Retrun: CDF status
9549  */
9550 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
9551 						struct periodic_tx_pattern  *
9552 						pAddPeriodicTxPtrnParams,
9553 						uint8_t vdev_id)
9554 {
9555 	WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
9556 	wmi_buf_t wmi_buf;
9557 	uint32_t len;
9558 	uint8_t *buf_ptr;
9559 	uint32_t ptrn_len, ptrn_len_aligned;
9560 	int j;
9561 
9562 	ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize;
9563 	ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t));
9564 	len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) +
9565 	      WMI_TLV_HDR_SIZE + ptrn_len_aligned;
9566 
9567 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
9568 	if (!wmi_buf) {
9569 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
9570 		return QDF_STATUS_E_NOMEM;
9571 	}
9572 
9573 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
9574 
9575 	cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr;
9576 	WMITLV_SET_HDR(&cmd->tlv_header,
9577 	       WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
9578 	       WMITLV_GET_STRUCT_TLVLEN
9579 	       (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
9580 
9581 	/* Pass the pattern id to delete for the corresponding vdev id */
9582 	cmd->vdev_id = vdev_id;
9583 	cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId;
9584 	cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs;
9585 	cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize;
9586 
9587 	/* Pattern info */
9588 	buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
9589 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned);
9590 	buf_ptr += WMI_TLV_HDR_SIZE;
9591 	qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len);
9592 	for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++)
9593 		WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff);
9594 
9595 	WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d",
9596 		 __func__, cmd->pattern_id, cmd->vdev_id);
9597 
9598 	wmi_mtrace(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
9599 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
9600 				 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
9601 		WMI_LOGE("%s: failed to add pattern set state command",
9602 			 __func__);
9603 		wmi_buf_free(wmi_buf);
9604 		return QDF_STATUS_E_FAILURE;
9605 	}
9606 	return QDF_STATUS_SUCCESS;
9607 }
9608 
9609 /**
9610  * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn
9611  * @wmi_handle: wmi handle
9612  * @vdev_id: vdev id
9613  * @pattern_id: pattern id
9614  *
9615  * Retrun: CDF status
9616  */
9617 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
9618 						uint8_t vdev_id,
9619 						uint8_t pattern_id)
9620 {
9621 	WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
9622 	wmi_buf_t wmi_buf;
9623 	uint32_t len =
9624 		sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
9625 
9626 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
9627 	if (!wmi_buf) {
9628 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
9629 		return QDF_STATUS_E_NOMEM;
9630 	}
9631 
9632 	cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)
9633 		wmi_buf_data(wmi_buf);
9634 	WMITLV_SET_HDR(&cmd->tlv_header,
9635 	       WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
9636 	       WMITLV_GET_STRUCT_TLVLEN
9637 	       (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
9638 
9639 	/* Pass the pattern id to delete for the corresponding vdev id */
9640 	cmd->vdev_id = vdev_id;
9641 	cmd->pattern_id = pattern_id;
9642 	WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d",
9643 		 __func__, cmd->pattern_id, cmd->vdev_id);
9644 
9645 	wmi_mtrace(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
9646 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
9647 				 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
9648 		WMI_LOGE("%s: failed to send del pattern command", __func__);
9649 		wmi_buf_free(wmi_buf);
9650 		return QDF_STATUS_E_FAILURE;
9651 	}
9652 	return QDF_STATUS_SUCCESS;
9653 }
9654 
9655 /**
9656  * send_stats_ext_req_cmd_tlv() - request ext stats from fw
9657  * @wmi_handle: wmi handle
9658  * @preq: stats ext params
9659  *
9660  * Return: CDF status
9661  */
9662 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle,
9663 			struct stats_ext_params *preq)
9664 {
9665 	QDF_STATUS ret;
9666 	wmi_req_stats_ext_cmd_fixed_param *cmd;
9667 	wmi_buf_t buf;
9668 	size_t len;
9669 	uint8_t *buf_ptr;
9670 
9671 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len;
9672 
9673 	buf = wmi_buf_alloc(wmi_handle, len);
9674 	if (!buf) {
9675 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9676 		return QDF_STATUS_E_NOMEM;
9677 	}
9678 
9679 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
9680 	cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr;
9681 
9682 	WMITLV_SET_HDR(&cmd->tlv_header,
9683 		       WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param,
9684 		       WMITLV_GET_STRUCT_TLVLEN
9685 			       (wmi_req_stats_ext_cmd_fixed_param));
9686 	cmd->vdev_id = preq->vdev_id;
9687 	cmd->data_len = preq->request_data_len;
9688 
9689 	WMI_LOGD("%s: The data len value is %u and vdev id set is %u ",
9690 		 __func__, preq->request_data_len, preq->vdev_id);
9691 
9692 	buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param);
9693 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len);
9694 
9695 	buf_ptr += WMI_TLV_HDR_SIZE;
9696 	qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len);
9697 
9698 	wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0);
9699 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9700 				   WMI_REQUEST_STATS_EXT_CMDID);
9701 	if (QDF_IS_STATUS_ERROR(ret)) {
9702 		WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__,
9703 			 ret);
9704 		wmi_buf_free(buf);
9705 	}
9706 
9707 	return ret;
9708 }
9709 
9710 /**
9711  * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw
9712  * @wmi_handle: wmi handle
9713  * @params: ext wow params
9714  *
9715  * Return:0 for success or error code
9716  */
9717 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle,
9718 			struct ext_wow_params *params)
9719 {
9720 	wmi_extwow_enable_cmd_fixed_param *cmd;
9721 	wmi_buf_t buf;
9722 	int32_t len;
9723 	int ret;
9724 
9725 	len = sizeof(wmi_extwow_enable_cmd_fixed_param);
9726 	buf = wmi_buf_alloc(wmi_handle, len);
9727 	if (!buf) {
9728 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9729 		return QDF_STATUS_E_NOMEM;
9730 	}
9731 
9732 	cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf);
9733 
9734 	WMITLV_SET_HDR(&cmd->tlv_header,
9735 		       WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param,
9736 		       WMITLV_GET_STRUCT_TLVLEN
9737 			       (wmi_extwow_enable_cmd_fixed_param));
9738 
9739 	cmd->vdev_id = params->vdev_id;
9740 	cmd->type = params->type;
9741 	cmd->wakeup_pin_num = params->wakeup_pin_num;
9742 
9743 	WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x",
9744 		 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num);
9745 
9746 	wmi_mtrace(WMI_EXTWOW_ENABLE_CMDID, cmd->vdev_id, 0);
9747 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9748 				   WMI_EXTWOW_ENABLE_CMDID);
9749 	if (ret) {
9750 		WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__);
9751 		wmi_buf_free(buf);
9752 		return QDF_STATUS_E_FAILURE;
9753 	}
9754 
9755 	return QDF_STATUS_SUCCESS;
9756 
9757 }
9758 
9759 /**
9760  * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw
9761  * @wmi_handle: wmi handle
9762  * @app_type1_params: app type1 params
9763  *
9764  * Return: CDF status
9765  */
9766 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
9767 				   struct app_type1_params *app_type1_params)
9768 {
9769 	wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd;
9770 	wmi_buf_t buf;
9771 	int32_t len;
9772 	int ret;
9773 
9774 	len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param);
9775 	buf = wmi_buf_alloc(wmi_handle, len);
9776 	if (!buf) {
9777 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9778 		return QDF_STATUS_E_NOMEM;
9779 	}
9780 
9781 	cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *)
9782 	      wmi_buf_data(buf);
9783 
9784 	WMITLV_SET_HDR(&cmd->tlv_header,
9785 	       WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param,
9786 	       WMITLV_GET_STRUCT_TLVLEN
9787 	       (wmi_extwow_set_app_type1_params_cmd_fixed_param));
9788 
9789 	cmd->vdev_id = app_type1_params->vdev_id;
9790 	WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes,
9791 				   &cmd->wakee_mac);
9792 	qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8);
9793 	cmd->ident_len = app_type1_params->id_length;
9794 	qdf_mem_copy(cmd->passwd, app_type1_params->password, 16);
9795 	cmd->passwd_len = app_type1_params->pass_length;
9796 
9797 	WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM "
9798 		 "identification_id %.8s id_length %u "
9799 		 "password %.16s pass_length %u",
9800 		 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes,
9801 		 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len);
9802 
9803 	wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID, cmd->vdev_id, 0);
9804 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9805 				   WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID);
9806 	if (ret) {
9807 		WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__);
9808 		wmi_buf_free(buf);
9809 		return QDF_STATUS_E_FAILURE;
9810 	}
9811 
9812 	return QDF_STATUS_SUCCESS;
9813 }
9814 
9815 /**
9816  * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw
9817  * @wmi_handle: wmi handle
9818  * @appType2Params: app type2 params
9819  *
9820  * Return: CDF status
9821  */
9822 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
9823 			  struct app_type2_params *appType2Params)
9824 {
9825 	wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd;
9826 	wmi_buf_t buf;
9827 	int32_t len;
9828 	int ret;
9829 
9830 	len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param);
9831 	buf = wmi_buf_alloc(wmi_handle, len);
9832 	if (!buf) {
9833 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9834 		return QDF_STATUS_E_NOMEM;
9835 	}
9836 
9837 	cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *)
9838 	      wmi_buf_data(buf);
9839 
9840 	WMITLV_SET_HDR(&cmd->tlv_header,
9841 	       WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param,
9842 	       WMITLV_GET_STRUCT_TLVLEN
9843 	       (wmi_extwow_set_app_type2_params_cmd_fixed_param));
9844 
9845 	cmd->vdev_id = appType2Params->vdev_id;
9846 
9847 	qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16);
9848 	cmd->rc4_key_len = appType2Params->rc4_key_len;
9849 
9850 	cmd->ip_id = appType2Params->ip_id;
9851 	cmd->ip_device_ip = appType2Params->ip_device_ip;
9852 	cmd->ip_server_ip = appType2Params->ip_server_ip;
9853 
9854 	cmd->tcp_src_port = appType2Params->tcp_src_port;
9855 	cmd->tcp_dst_port = appType2Params->tcp_dst_port;
9856 	cmd->tcp_seq = appType2Params->tcp_seq;
9857 	cmd->tcp_ack_seq = appType2Params->tcp_ack_seq;
9858 
9859 	cmd->keepalive_init = appType2Params->keepalive_init;
9860 	cmd->keepalive_min = appType2Params->keepalive_min;
9861 	cmd->keepalive_max = appType2Params->keepalive_max;
9862 	cmd->keepalive_inc = appType2Params->keepalive_inc;
9863 
9864 	WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes,
9865 				   &cmd->gateway_mac);
9866 	cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val;
9867 	cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val;
9868 
9869 	WMI_LOGD("%s: vdev_id %d gateway_mac %pM "
9870 		 "rc4_key %.16s rc4_key_len %u "
9871 		 "ip_id %x ip_device_ip %x ip_server_ip %x "
9872 		 "tcp_src_port %u tcp_dst_port %u tcp_seq %u "
9873 		 "tcp_ack_seq %u keepalive_init %u keepalive_min %u "
9874 		 "keepalive_max %u keepalive_inc %u "
9875 		 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u",
9876 		 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes,
9877 		 cmd->rc4_key, cmd->rc4_key_len,
9878 		 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip,
9879 		 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq,
9880 		 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min,
9881 		 cmd->keepalive_max, cmd->keepalive_inc,
9882 		 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val);
9883 
9884 	wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID, cmd->vdev_id, 0);
9885 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9886 				   WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID);
9887 	if (ret) {
9888 		WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__);
9889 		wmi_buf_free(buf);
9890 		return QDF_STATUS_E_FAILURE;
9891 	}
9892 
9893 	return QDF_STATUS_SUCCESS;
9894 
9895 }
9896 
9897 /**
9898  * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware
9899  * @wmi_handle: wmi handle
9900  * @timer_val: auto shutdown timer value
9901  *
9902  * Return: CDF status
9903  */
9904 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle,
9905 						  uint32_t timer_val)
9906 {
9907 	QDF_STATUS status;
9908 	wmi_buf_t buf = NULL;
9909 	uint8_t *buf_ptr;
9910 	wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd;
9911 	int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param);
9912 
9913 	WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d",
9914 		 __func__, timer_val);
9915 
9916 	buf = wmi_buf_alloc(wmi_handle, len);
9917 	if (!buf) {
9918 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
9919 		return QDF_STATUS_E_NOMEM;
9920 	}
9921 
9922 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
9923 	wmi_auto_sh_cmd =
9924 		(wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr;
9925 	wmi_auto_sh_cmd->timer_value = timer_val;
9926 
9927 	WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header,
9928 	       WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param,
9929 	       WMITLV_GET_STRUCT_TLVLEN
9930 	       (wmi_host_auto_shutdown_cfg_cmd_fixed_param));
9931 
9932 	wmi_mtrace(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID, NO_SESSION, 0);
9933 	status = wmi_unified_cmd_send(wmi_handle, buf,
9934 				      len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID);
9935 	if (QDF_IS_STATUS_ERROR(status)) {
9936 		WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d",
9937 			 __func__, status);
9938 		wmi_buf_free(buf);
9939 	}
9940 
9941 	return status;
9942 }
9943 
9944 /**
9945  * send_nan_req_cmd_tlv() - to send nan request to target
9946  * @wmi_handle: wmi handle
9947  * @nan_req: request data which will be non-null
9948  *
9949  * Return: CDF status
9950  */
9951 static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle,
9952 			struct nan_req_params *nan_req)
9953 {
9954 	QDF_STATUS ret;
9955 	wmi_nan_cmd_param *cmd;
9956 	wmi_buf_t buf;
9957 	uint16_t len = sizeof(*cmd);
9958 	uint16_t nan_data_len, nan_data_len_aligned;
9959 	uint8_t *buf_ptr;
9960 
9961 	/*
9962 	 *    <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ---->
9963 	 *    +------------+----------+-----------------------+--------------+
9964 	 *    | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data |
9965 	 *    +------------+----------+-----------------------+--------------+
9966 	 */
9967 	if (!nan_req) {
9968 		WMI_LOGE("%s:nan req is not valid", __func__);
9969 		return QDF_STATUS_E_FAILURE;
9970 	}
9971 	nan_data_len = nan_req->request_data_len;
9972 	nan_data_len_aligned = roundup(nan_req->request_data_len,
9973 				       sizeof(uint32_t));
9974 	if (nan_data_len_aligned < nan_req->request_data_len) {
9975 		WMI_LOGE("%s: integer overflow while rounding up data_len",
9976 			 __func__);
9977 		return QDF_STATUS_E_FAILURE;
9978 	}
9979 
9980 	if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) {
9981 		WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen",
9982 			 __func__);
9983 		return QDF_STATUS_E_FAILURE;
9984 	}
9985 
9986 	len += WMI_TLV_HDR_SIZE + nan_data_len_aligned;
9987 	buf = wmi_buf_alloc(wmi_handle, len);
9988 	if (!buf) {
9989 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9990 		return QDF_STATUS_E_NOMEM;
9991 	}
9992 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
9993 	cmd = (wmi_nan_cmd_param *) buf_ptr;
9994 	WMITLV_SET_HDR(&cmd->tlv_header,
9995 		       WMITLV_TAG_STRUC_wmi_nan_cmd_param,
9996 		       WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param));
9997 	cmd->data_len = nan_req->request_data_len;
9998 	WMI_LOGD("%s: The data len value is %u",
9999 		 __func__, nan_req->request_data_len);
10000 	buf_ptr += sizeof(wmi_nan_cmd_param);
10001 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned);
10002 	buf_ptr += WMI_TLV_HDR_SIZE;
10003 	qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len);
10004 
10005 	wmi_mtrace(WMI_NAN_CMDID, NO_SESSION, 0);
10006 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
10007 				   WMI_NAN_CMDID);
10008 	if (QDF_IS_STATUS_ERROR(ret)) {
10009 		WMI_LOGE("%s Failed to send set param command ret = %d",
10010 			 __func__, ret);
10011 		wmi_buf_free(buf);
10012 	}
10013 
10014 	return ret;
10015 }
10016 
10017 /**
10018  * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload
10019  * @wmi_handle: wmi handle
10020  * @params: DHCP server offload info
10021  *
10022  * Return: QDF_STATUS_SUCCESS for success or error code
10023  */
10024 static QDF_STATUS
10025 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle,
10026 					struct dhcp_offload_info_params *params)
10027 {
10028 	wmi_set_dhcp_server_offload_cmd_fixed_param *cmd;
10029 	wmi_buf_t buf;
10030 	QDF_STATUS status;
10031 
10032 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
10033 	if (!buf) {
10034 		WMI_LOGE("Failed to allocate buffer to send "
10035 			 "set_dhcp_server_offload cmd");
10036 		return QDF_STATUS_E_NOMEM;
10037 	}
10038 
10039 	cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf);
10040 
10041 	WMITLV_SET_HDR(&cmd->tlv_header,
10042 	       WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param,
10043 	       WMITLV_GET_STRUCT_TLVLEN
10044 	       (wmi_set_dhcp_server_offload_cmd_fixed_param));
10045 	cmd->vdev_id = params->vdev_id;
10046 	cmd->enable = params->dhcp_offload_enabled;
10047 	cmd->num_client = params->dhcp_client_num;
10048 	cmd->srv_ipv4 = params->dhcp_srv_addr;
10049 	cmd->start_lsb = 0;
10050 	wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0);
10051 	status = wmi_unified_cmd_send(wmi_handle, buf,
10052 				   sizeof(*cmd),
10053 				   WMI_SET_DHCP_SERVER_OFFLOAD_CMDID);
10054 	if (QDF_IS_STATUS_ERROR(status)) {
10055 		WMI_LOGE("Failed to send set_dhcp_server_offload cmd");
10056 		wmi_buf_free(buf);
10057 		return QDF_STATUS_E_FAILURE;
10058 	}
10059 	WMI_LOGD("Set dhcp server offload to vdevId %d",
10060 		 params->vdev_id);
10061 
10062 	return status;
10063 }
10064 
10065 /**
10066  * send_set_led_flashing_cmd_tlv() - set led flashing in fw
10067  * @wmi_handle: wmi handle
10068  * @flashing: flashing request
10069  *
10070  * Return: CDF status
10071  */
10072 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle,
10073 				struct flashing_req_params *flashing)
10074 {
10075 	wmi_set_led_flashing_cmd_fixed_param *cmd;
10076 	QDF_STATUS status;
10077 	wmi_buf_t buf;
10078 	uint8_t *buf_ptr;
10079 	int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param);
10080 
10081 	buf = wmi_buf_alloc(wmi_handle, len);
10082 	if (!buf) {
10083 		WMI_LOGP(FL("wmi_buf_alloc failed"));
10084 		return QDF_STATUS_E_NOMEM;
10085 	}
10086 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
10087 	cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr;
10088 	WMITLV_SET_HDR(&cmd->tlv_header,
10089 		       WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param,
10090 		       WMITLV_GET_STRUCT_TLVLEN
10091 			       (wmi_set_led_flashing_cmd_fixed_param));
10092 	cmd->pattern_id = flashing->pattern_id;
10093 	cmd->led_x0 = flashing->led_x0;
10094 	cmd->led_x1 = flashing->led_x1;
10095 
10096 	wmi_mtrace(WMI_PDEV_SET_LED_FLASHING_CMDID, NO_SESSION, 0);
10097 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
10098 				      WMI_PDEV_SET_LED_FLASHING_CMDID);
10099 	if (QDF_IS_STATUS_ERROR(status)) {
10100 		WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
10101 			 " returned Error %d", __func__, status);
10102 		wmi_buf_free(buf);
10103 	}
10104 
10105 	return status;
10106 }
10107 
10108 /**
10109  * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request
10110  * @wmi_handle: wmi handle
10111  * @ch_avoid_update_req: channel avoid update params
10112  *
10113  * Return: CDF status
10114  */
10115 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle)
10116 {
10117 	QDF_STATUS status;
10118 	wmi_buf_t buf = NULL;
10119 	uint8_t *buf_ptr;
10120 	wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp;
10121 	int len = sizeof(wmi_chan_avoid_update_cmd_param);
10122 
10123 
10124 	buf = wmi_buf_alloc(wmi_handle, len);
10125 	if (!buf) {
10126 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
10127 		return QDF_STATUS_E_NOMEM;
10128 	}
10129 
10130 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
10131 	ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr;
10132 	WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header,
10133 		       WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param,
10134 		       WMITLV_GET_STRUCT_TLVLEN
10135 			       (wmi_chan_avoid_update_cmd_param));
10136 
10137 	wmi_mtrace(WMI_CHAN_AVOID_UPDATE_CMDID, NO_SESSION, 0);
10138 	status = wmi_unified_cmd_send(wmi_handle, buf,
10139 				      len, WMI_CHAN_AVOID_UPDATE_CMDID);
10140 	if (QDF_IS_STATUS_ERROR(status)) {
10141 		WMI_LOGE("wmi_unified_cmd_send"
10142 			 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE"
10143 			 " returned Error %d", status);
10144 		wmi_buf_free(buf);
10145 	}
10146 
10147 	return status;
10148 }
10149 
10150 /**
10151  * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw
10152  * @wmi_handle: wmi handle
10153  * @param: pointer to pdev regdomain params
10154  *
10155  * Return: 0 for success or error code
10156  */
10157 static QDF_STATUS
10158 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle,
10159 				struct pdev_set_regdomain_params *param)
10160 {
10161 	wmi_buf_t buf;
10162 	wmi_pdev_set_regdomain_cmd_fixed_param *cmd;
10163 	int32_t len = sizeof(*cmd);
10164 
10165 
10166 	buf = wmi_buf_alloc(wmi_handle, len);
10167 	if (!buf) {
10168 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
10169 		return QDF_STATUS_E_NOMEM;
10170 	}
10171 	cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf);
10172 	WMITLV_SET_HDR(&cmd->tlv_header,
10173 		       WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param,
10174 		       WMITLV_GET_STRUCT_TLVLEN
10175 			       (wmi_pdev_set_regdomain_cmd_fixed_param));
10176 
10177 	cmd->reg_domain = param->currentRDinuse;
10178 	cmd->reg_domain_2G = param->currentRD2G;
10179 	cmd->reg_domain_5G = param->currentRD5G;
10180 	cmd->conformance_test_limit_2G = param->ctl_2G;
10181 	cmd->conformance_test_limit_5G = param->ctl_5G;
10182 	cmd->dfs_domain = param->dfsDomain;
10183 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10184 							param->pdev_id);
10185 
10186 	wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0);
10187 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10188 				 WMI_PDEV_SET_REGDOMAIN_CMDID)) {
10189 		WMI_LOGE("%s: Failed to send pdev set regdomain command",
10190 			 __func__);
10191 		wmi_buf_free(buf);
10192 		return QDF_STATUS_E_FAILURE;
10193 	}
10194 
10195 	return QDF_STATUS_SUCCESS;
10196 }
10197 
10198 /**
10199  * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw
10200  * @wmi_handle: wmi handle
10201  * @reg_dmn: reg domain
10202  * @regdmn2G: 2G reg domain
10203  * @regdmn5G: 5G reg domain
10204  * @ctl2G: 2G test limit
10205  * @ctl5G: 5G test limit
10206  *
10207  * Return: none
10208  */
10209 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle,
10210 				   uint32_t reg_dmn, uint16_t regdmn2G,
10211 				   uint16_t regdmn5G, uint8_t ctl2G,
10212 				   uint8_t ctl5G)
10213 {
10214 	wmi_buf_t buf;
10215 	wmi_pdev_set_regdomain_cmd_fixed_param *cmd;
10216 	int32_t len = sizeof(*cmd);
10217 
10218 
10219 	buf = wmi_buf_alloc(wmi_handle, len);
10220 	if (!buf) {
10221 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
10222 		return QDF_STATUS_E_NOMEM;
10223 	}
10224 	cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf);
10225 	WMITLV_SET_HDR(&cmd->tlv_header,
10226 		       WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param,
10227 		       WMITLV_GET_STRUCT_TLVLEN
10228 			       (wmi_pdev_set_regdomain_cmd_fixed_param));
10229 	cmd->reg_domain = reg_dmn;
10230 	cmd->reg_domain_2G = regdmn2G;
10231 	cmd->reg_domain_5G = regdmn5G;
10232 	cmd->conformance_test_limit_2G = ctl2G;
10233 	cmd->conformance_test_limit_5G = ctl5G;
10234 
10235 	wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0);
10236 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10237 				 WMI_PDEV_SET_REGDOMAIN_CMDID)) {
10238 		WMI_LOGP("%s: Failed to send pdev set regdomain command",
10239 			 __func__);
10240 		wmi_buf_free(buf);
10241 		return QDF_STATUS_E_FAILURE;
10242 	}
10243 
10244 	return QDF_STATUS_SUCCESS;
10245 }
10246 
10247 #ifdef FEATURE_WLAN_TDLS
10248 /**
10249  * tdls_get_wmi_offchannel_mode - Get WMI tdls off channel mode
10250  * @tdls_sw_mode: tdls_sw_mode
10251  *
10252  * This function returns wmi tdls offchannel mode
10253  *
10254  * Return: enum value of wmi tdls offchannel mode
10255  */
10256 static uint8_t tdls_get_wmi_offchannel_mode(uint8_t tdls_sw_mode)
10257 {
10258 	uint8_t off_chan_mode;
10259 
10260 	switch (tdls_sw_mode) {
10261 	case ENABLE_CHANSWITCH:
10262 		off_chan_mode = WMI_TDLS_ENABLE_OFFCHANNEL;
10263 		break;
10264 
10265 	case DISABLE_CHANSWITCH:
10266 		off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL;
10267 		break;
10268 
10269 	default:
10270 		WMI_LOGD(FL("unknown tdls_sw_mode %d"), tdls_sw_mode);
10271 		off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL;
10272 	}
10273 	return off_chan_mode;
10274 }
10275 #else
10276 static uint8_t tdls_get_wmi_offchannel_mode(uint8_t tdls_sw_mode)
10277 {
10278 	return WMI_TDLS_DISABLE_OFFCHANNEL;
10279 }
10280 #endif
10281 
10282 /**
10283  * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode
10284  * @wmi_handle: wmi handle
10285  * @chan_switch_params: Pointer to tdls channel switch parameter structure
10286  *
10287  * This function sets tdls off channel mode
10288  *
10289  * Return: 0 on success; Negative errno otherwise
10290  */
10291 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle,
10292 	      struct tdls_channel_switch_params *chan_switch_params)
10293 {
10294 	wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd;
10295 	wmi_buf_t wmi_buf;
10296 	u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param);
10297 
10298 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10299 	if (!wmi_buf) {
10300 		WMI_LOGE(FL("wmi_buf_alloc failed"));
10301 		return QDF_STATUS_E_FAILURE;
10302 	}
10303 	cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *)
10304 		wmi_buf_data(wmi_buf);
10305 	WMITLV_SET_HDR(&cmd->tlv_header,
10306 		WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param,
10307 		WMITLV_GET_STRUCT_TLVLEN(
10308 			wmi_tdls_set_offchan_mode_cmd_fixed_param));
10309 
10310 	WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr,
10311 				&cmd->peer_macaddr);
10312 	cmd->vdev_id = chan_switch_params->vdev_id;
10313 	cmd->offchan_mode =
10314 		tdls_get_wmi_offchannel_mode(chan_switch_params->tdls_sw_mode);
10315 	cmd->is_peer_responder = chan_switch_params->is_responder;
10316 	cmd->offchan_num = chan_switch_params->tdls_off_ch;
10317 	cmd->offchan_bw_bitmap = chan_switch_params->tdls_off_ch_bw_offset;
10318 	cmd->offchan_oper_class = chan_switch_params->oper_class;
10319 
10320 	WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"),
10321 		 cmd->peer_macaddr.mac_addr31to0,
10322 		 cmd->peer_macaddr.mac_addr47to32);
10323 
10324 	WMI_LOGD(FL(
10325 		 "vdev_id: %d, off channel mode: %d, off channel Num: %d, "
10326 		 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d"
10327 		  ),
10328 		 cmd->vdev_id,
10329 		 cmd->offchan_mode,
10330 		 cmd->offchan_num,
10331 		 cmd->offchan_bw_bitmap,
10332 		 cmd->is_peer_responder,
10333 		 cmd->offchan_oper_class);
10334 
10335 	wmi_mtrace(WMI_TDLS_SET_OFFCHAN_MODE_CMDID, cmd->vdev_id, 0);
10336 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10337 		WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) {
10338 		WMI_LOGP(FL("failed to send tdls off chan command"));
10339 		wmi_buf_free(wmi_buf);
10340 		return QDF_STATUS_E_FAILURE;
10341 	}
10342 
10343 
10344 	return QDF_STATUS_SUCCESS;
10345 }
10346 
10347 /**
10348  * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev
10349  * @wmi_handle: wmi handle
10350  * @pwmaTdlsparams: TDLS params
10351  *
10352  * Return: 0 for success or error code
10353  */
10354 static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle,
10355 					 void *tdls_param, uint8_t tdls_state)
10356 {
10357 	wmi_tdls_set_state_cmd_fixed_param *cmd;
10358 	wmi_buf_t wmi_buf;
10359 
10360 	struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param;
10361 	uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param);
10362 
10363 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10364 	if (!wmi_buf) {
10365 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
10366 		return QDF_STATUS_E_FAILURE;
10367 	}
10368 	cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf);
10369 	WMITLV_SET_HDR(&cmd->tlv_header,
10370 		  WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param,
10371 		  WMITLV_GET_STRUCT_TLVLEN
10372 		  (wmi_tdls_set_state_cmd_fixed_param));
10373 	cmd->vdev_id = wmi_tdls->vdev_id;
10374 	cmd->state = tdls_state;
10375 	cmd->notification_interval_ms = wmi_tdls->notification_interval_ms;
10376 	cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold;
10377 	cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold;
10378 	cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold;
10379 	cmd->rssi_delta = wmi_tdls->rssi_delta;
10380 	cmd->tdls_options = wmi_tdls->tdls_options;
10381 	cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window;
10382 	cmd->tdls_peer_traffic_response_timeout_ms =
10383 		wmi_tdls->peer_traffic_response_timeout;
10384 	cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask;
10385 	cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time;
10386 	cmd->tdls_puapsd_rx_frame_threshold =
10387 		wmi_tdls->puapsd_rx_frame_threshold;
10388 	cmd->teardown_notification_ms =
10389 		wmi_tdls->teardown_notification_ms;
10390 	cmd->tdls_peer_kickout_threshold =
10391 		wmi_tdls->tdls_peer_kickout_threshold;
10392 
10393 	WMI_LOGD("%s: tdls_state: %d, state: %d, "
10394 		 "notification_interval_ms: %d, "
10395 		 "tx_discovery_threshold: %d, "
10396 		 "tx_teardown_threshold: %d, "
10397 		 "rssi_teardown_threshold: %d, "
10398 		 "rssi_delta: %d, "
10399 		 "tdls_options: 0x%x, "
10400 		 "tdls_peer_traffic_ind_window: %d, "
10401 		 "tdls_peer_traffic_response_timeout: %d, "
10402 		 "tdls_puapsd_mask: 0x%x, "
10403 		 "tdls_puapsd_inactivity_time: %d, "
10404 		 "tdls_puapsd_rx_frame_threshold: %d, "
10405 		 "teardown_notification_ms: %d, "
10406 		 "tdls_peer_kickout_threshold: %d",
10407 		 __func__, tdls_state, cmd->state,
10408 		 cmd->notification_interval_ms,
10409 		 cmd->tx_discovery_threshold,
10410 		 cmd->tx_teardown_threshold,
10411 		 cmd->rssi_teardown_threshold,
10412 		 cmd->rssi_delta,
10413 		 cmd->tdls_options,
10414 		 cmd->tdls_peer_traffic_ind_window,
10415 		 cmd->tdls_peer_traffic_response_timeout_ms,
10416 		 cmd->tdls_puapsd_mask,
10417 		 cmd->tdls_puapsd_inactivity_time_ms,
10418 		 cmd->tdls_puapsd_rx_frame_threshold,
10419 		 cmd->teardown_notification_ms,
10420 		 cmd->tdls_peer_kickout_threshold);
10421 
10422 	wmi_mtrace(WMI_TDLS_SET_STATE_CMDID, cmd->vdev_id, 0);
10423 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10424 				 WMI_TDLS_SET_STATE_CMDID)) {
10425 		WMI_LOGP("%s: failed to send tdls set state command", __func__);
10426 		wmi_buf_free(wmi_buf);
10427 		return QDF_STATUS_E_FAILURE;
10428 	}
10429 	WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id);
10430 
10431 	return QDF_STATUS_SUCCESS;
10432 }
10433 
10434 /**
10435  * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state
10436  * @wmi_handle: wmi handle
10437  * @peerStateParams: TDLS peer state params
10438  *
10439  * Return: QDF_STATUS_SUCCESS for success or error code
10440  */
10441 static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle,
10442 			       struct tdls_peer_state_params *peerStateParams,
10443 				   uint32_t *ch_mhz)
10444 {
10445 	wmi_tdls_peer_update_cmd_fixed_param *cmd;
10446 	wmi_tdls_peer_capabilities *peer_cap;
10447 	wmi_channel *chan_info;
10448 	wmi_buf_t wmi_buf;
10449 	uint8_t *buf_ptr;
10450 	uint32_t i;
10451 	int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) +
10452 		      sizeof(wmi_tdls_peer_capabilities);
10453 
10454 
10455 	len += WMI_TLV_HDR_SIZE +
10456 	       sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen;
10457 
10458 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10459 	if (!wmi_buf) {
10460 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
10461 		return QDF_STATUS_E_FAILURE;
10462 	}
10463 
10464 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
10465 	cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr;
10466 	WMITLV_SET_HDR(&cmd->tlv_header,
10467 		       WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param,
10468 		       WMITLV_GET_STRUCT_TLVLEN
10469 			       (wmi_tdls_peer_update_cmd_fixed_param));
10470 
10471 	cmd->vdev_id = peerStateParams->vdevId;
10472 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr,
10473 				   &cmd->peer_macaddr);
10474 
10475 
10476 	cmd->peer_state = peerStateParams->peerState;
10477 
10478 	WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, "
10479 		 "peer_macaddr.mac_addr31to0: 0x%x, "
10480 		 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d",
10481 		 __func__, cmd->vdev_id, peerStateParams->peerMacAddr,
10482 		 cmd->peer_macaddr.mac_addr31to0,
10483 		 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state);
10484 
10485 	buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param);
10486 	peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr;
10487 	WMITLV_SET_HDR(&peer_cap->tlv_header,
10488 		       WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities,
10489 		       WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities));
10490 
10491 	if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3)
10492 		WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap);
10493 	if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2)
10494 		WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap);
10495 	if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1)
10496 		WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap);
10497 	if (peerStateParams->peerCap.peerUapsdQueue & 0x01)
10498 		WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap);
10499 
10500 	/* Ack and More Data Ack are sent as 0, so no need to set
10501 	 * but fill SP
10502 	 */
10503 	WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap,
10504 				   peerStateParams->peerCap.peerMaxSp);
10505 
10506 	peer_cap->buff_sta_support =
10507 		peerStateParams->peerCap.peerBuffStaSupport;
10508 	peer_cap->off_chan_support =
10509 		peerStateParams->peerCap.peerOffChanSupport;
10510 	peer_cap->peer_curr_operclass =
10511 		peerStateParams->peerCap.peerCurrOperClass;
10512 	/* self curr operclass is not being used and so pass op class for
10513 	 * preferred off chan in it.
10514 	 */
10515 	peer_cap->self_curr_operclass =
10516 		peerStateParams->peerCap.opClassForPrefOffChan;
10517 	peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen;
10518 	peer_cap->peer_operclass_len =
10519 		peerStateParams->peerCap.peerOperClassLen;
10520 
10521 	WMI_LOGD("%s: peer_operclass_len: %d",
10522 		 __func__, peer_cap->peer_operclass_len);
10523 	for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) {
10524 		peer_cap->peer_operclass[i] =
10525 			peerStateParams->peerCap.peerOperClass[i];
10526 		WMI_LOGD("%s: peer_operclass[%d]: %d",
10527 			 __func__, i, peer_cap->peer_operclass[i]);
10528 	}
10529 
10530 	peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder;
10531 	peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum;
10532 	peer_cap->pref_offchan_bw =
10533 		peerStateParams->peerCap.prefOffChanBandwidth;
10534 
10535 	WMI_LOGD
10536 		("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, "
10537 		 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: "
10538 		 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:"
10539 		 " %d, pref_offchan_bw: %d",
10540 		__func__, peer_cap->peer_qos, peer_cap->buff_sta_support,
10541 		peer_cap->off_chan_support, peer_cap->peer_curr_operclass,
10542 		peer_cap->self_curr_operclass, peer_cap->peer_chan_len,
10543 		peer_cap->peer_operclass_len, peer_cap->is_peer_responder,
10544 		peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw);
10545 
10546 	/* next fill variable size array of peer chan info */
10547 	buf_ptr += sizeof(wmi_tdls_peer_capabilities);
10548 	WMITLV_SET_HDR(buf_ptr,
10549 		       WMITLV_TAG_ARRAY_STRUC,
10550 		       sizeof(wmi_channel) *
10551 		       peerStateParams->peerCap.peerChanLen);
10552 	chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE);
10553 
10554 	for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) {
10555 		WMITLV_SET_HDR(&chan_info->tlv_header,
10556 			       WMITLV_TAG_STRUC_wmi_channel,
10557 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
10558 		chan_info->mhz = ch_mhz[i];
10559 		chan_info->band_center_freq1 = chan_info->mhz;
10560 		chan_info->band_center_freq2 = 0;
10561 
10562 		WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz);
10563 
10564 		if (peerStateParams->peerCap.peerChan[i].dfsSet) {
10565 			WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE);
10566 			WMI_LOGI("chan[%d] DFS[%d]\n",
10567 				 peerStateParams->peerCap.peerChan[i].chanId,
10568 				 peerStateParams->peerCap.peerChan[i].dfsSet);
10569 		}
10570 
10571 		if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ)
10572 			WMI_SET_CHANNEL_MODE(chan_info, MODE_11G);
10573 		else
10574 			WMI_SET_CHANNEL_MODE(chan_info, MODE_11A);
10575 
10576 		WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
10577 					     peerStateParams->peerCap.
10578 					     peerChan[i].pwr);
10579 
10580 		WMI_SET_CHANNEL_REG_POWER(chan_info,
10581 					  peerStateParams->peerCap.peerChan[i].
10582 					  pwr);
10583 		WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz,
10584 			 peerStateParams->peerCap.peerChan[i].pwr);
10585 
10586 		chan_info++;
10587 	}
10588 
10589 	wmi_mtrace(WMI_TDLS_PEER_UPDATE_CMDID, cmd->vdev_id, 0);
10590 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10591 				 WMI_TDLS_PEER_UPDATE_CMDID)) {
10592 		WMI_LOGE("%s: failed to send tdls peer update state command",
10593 			 __func__);
10594 		wmi_buf_free(wmi_buf);
10595 		return QDF_STATUS_E_FAILURE;
10596 	}
10597 
10598 
10599 	return QDF_STATUS_SUCCESS;
10600 }
10601 
10602 /*
10603  * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware
10604  * @wmi_handle:    Pointer to WMi handle
10605  * @ie_data:       Pointer for ie data
10606  *
10607  * This function sends IE information to firmware
10608  *
10609  * Return: QDF_STATUS_SUCCESS for success otherwise failure
10610  *
10611  */
10612 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle,
10613 				   struct vdev_ie_info_param *ie_info)
10614 {
10615 	wmi_vdev_set_ie_cmd_fixed_param *cmd;
10616 	wmi_buf_t buf;
10617 	uint8_t *buf_ptr;
10618 	uint32_t len, ie_len_aligned;
10619 	QDF_STATUS ret;
10620 
10621 
10622 	ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t));
10623 	/* Allocate memory for the WMI command */
10624 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned;
10625 
10626 	buf = wmi_buf_alloc(wmi_handle, len);
10627 	if (!buf) {
10628 		WMI_LOGE(FL("wmi_buf_alloc failed"));
10629 		return QDF_STATUS_E_NOMEM;
10630 	}
10631 
10632 	buf_ptr = wmi_buf_data(buf);
10633 	qdf_mem_zero(buf_ptr, len);
10634 
10635 	/* Populate the WMI command */
10636 	cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr;
10637 
10638 	WMITLV_SET_HDR(&cmd->tlv_header,
10639 		       WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param,
10640 		       WMITLV_GET_STRUCT_TLVLEN(
10641 			wmi_vdev_set_ie_cmd_fixed_param));
10642 	cmd->vdev_id = ie_info->vdev_id;
10643 	cmd->ie_id = ie_info->ie_id;
10644 	cmd->ie_len = ie_info->length;
10645 	cmd->band = ie_info->band;
10646 
10647 	WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id,
10648 		 ie_info->length, ie_info->vdev_id);
10649 
10650 	buf_ptr += sizeof(*cmd);
10651 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
10652 	buf_ptr += WMI_TLV_HDR_SIZE;
10653 
10654 	qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len);
10655 
10656 	wmi_mtrace(WMI_VDEV_SET_IE_CMDID, cmd->vdev_id, 0);
10657 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
10658 				   WMI_VDEV_SET_IE_CMDID);
10659 	if (QDF_IS_STATUS_ERROR(ret)) {
10660 		WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret);
10661 		wmi_buf_free(buf);
10662 	}
10663 
10664 	return ret;
10665 }
10666 
10667 /**
10668  *  send_smart_ant_enable_cmd_tlv() - WMI smart ant enable function
10669  *
10670  *  @param wmi_handle  : handle to WMI.
10671  *  @param param       : pointer to antenna param
10672  *
10673  *  This function sends smart antenna enable command to FW
10674  *
10675  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10676  */
10677 static QDF_STATUS send_smart_ant_enable_cmd_tlv(wmi_unified_t wmi_handle,
10678 				struct smart_ant_enable_params *param)
10679 {
10680 	/* Send WMI COMMAND to Enable */
10681 	wmi_pdev_smart_ant_enable_cmd_fixed_param *cmd;
10682 	wmi_pdev_smart_ant_gpio_handle *gpio_param;
10683 	wmi_buf_t buf;
10684 	uint8_t *buf_ptr;
10685 	int len = 0;
10686 	QDF_STATUS ret;
10687 	int loop = 0;
10688 
10689 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
10690 	len += WMI_HAL_MAX_SANTENNA * sizeof(wmi_pdev_smart_ant_gpio_handle);
10691 	buf = wmi_buf_alloc(wmi_handle, len);
10692 
10693 	if (!buf) {
10694 			WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
10695 			return QDF_STATUS_E_NOMEM;
10696 		}
10697 
10698 	buf_ptr = wmi_buf_data(buf);
10699 	qdf_mem_zero(buf_ptr, len);
10700 	cmd = (wmi_pdev_smart_ant_enable_cmd_fixed_param *)buf_ptr;
10701 
10702 	WMITLV_SET_HDR(&cmd->tlv_header,
10703 		WMITLV_TAG_STRUC_wmi_pdev_smart_ant_enable_cmd_fixed_param,
10704 		WMITLV_GET_STRUCT_TLVLEN(
10705 				wmi_pdev_smart_ant_enable_cmd_fixed_param));
10706 
10707 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10708 								param->pdev_id);
10709 	cmd->enable = param->enable;
10710 	cmd->mode = param->mode;
10711 	cmd->rx_antenna = param->rx_antenna;
10712 	cmd->tx_default_antenna = param->rx_antenna;
10713 
10714 	/* TLV indicating array of structures to follow */
10715 	buf_ptr += sizeof(wmi_pdev_smart_ant_enable_cmd_fixed_param);
10716 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
10717 		       WMI_HAL_MAX_SANTENNA *
10718 		       sizeof(wmi_pdev_smart_ant_gpio_handle));
10719 
10720 	buf_ptr += WMI_TLV_HDR_SIZE;
10721 	gpio_param = (wmi_pdev_smart_ant_gpio_handle *)buf_ptr;
10722 
10723 	for (loop = 0; loop < WMI_HAL_MAX_SANTENNA; loop++) {
10724 		WMITLV_SET_HDR(&gpio_param->tlv_header,
10725 			       WMITLV_TAG_STRUC_wmi_pdev_smart_ant_gpio_handle,
10726 			       WMITLV_GET_STRUCT_TLVLEN(
10727 			       wmi_pdev_smart_ant_gpio_handle));
10728 		if (param->mode == SMART_ANT_MODE_SERIAL) {
10729 			if (loop < WMI_HOST_MAX_SERIAL_ANTENNA) {
10730 				gpio_param->gpio_pin = param->gpio_pin[loop];
10731 				gpio_param->gpio_func = param->gpio_func[loop];
10732 			} else {
10733 				gpio_param->gpio_pin = 0;
10734 				gpio_param->gpio_func = 0;
10735 			}
10736 		} else if (param->mode == SMART_ANT_MODE_PARALLEL) {
10737 			gpio_param->gpio_pin = param->gpio_pin[loop];
10738 			gpio_param->gpio_func = param->gpio_func[loop];
10739 		}
10740 		/* Setting it to 0 for now */
10741 		gpio_param->pdev_id =
10742 			wmi_handle->ops->convert_pdev_id_host_to_target(
10743 								param->pdev_id);
10744 		gpio_param++;
10745 	}
10746 
10747 	wmi_mtrace(WMI_PDEV_SMART_ANT_ENABLE_CMDID, NO_SESSION, 0);
10748 	ret = wmi_unified_cmd_send(wmi_handle,
10749 				buf,
10750 				len,
10751 				WMI_PDEV_SMART_ANT_ENABLE_CMDID);
10752 
10753 	if (ret != 0) {
10754 		WMI_LOGE(" %s :WMI Failed\n", __func__);
10755 		WMI_LOGE("enable:%d mode:%d  rx_antenna: 0x%08x PINS: [%d %d %d %d] Func[%d %d %d %d] cmdstatus=%d\n",
10756 			 cmd->enable,
10757 			 cmd->mode,
10758 			 cmd->rx_antenna,
10759 			 param->gpio_pin[0], param->gpio_pin[1],
10760 			 param->gpio_pin[2], param->gpio_pin[3],
10761 			 param->gpio_func[0], param->gpio_func[1],
10762 			 param->gpio_func[2], param->gpio_func[3],
10763 			 ret);
10764 		wmi_buf_free(buf);
10765 	}
10766 
10767 	return ret;
10768 }
10769 
10770 /**
10771  *  send_smart_ant_set_rx_ant_cmd_tlv() - WMI set rx antenna function
10772  *
10773  *  @param wmi_handle     : handle to WMI.
10774  *  @param param          : pointer to rx antenna param
10775  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10776  */
10777 static QDF_STATUS send_smart_ant_set_rx_ant_cmd_tlv(wmi_unified_t wmi_handle,
10778 				struct smart_ant_rx_ant_params *param)
10779 {
10780 	wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *cmd;
10781 	wmi_buf_t buf;
10782 	uint8_t *buf_ptr;
10783 	uint32_t len;
10784 	QDF_STATUS ret;
10785 
10786 	len = sizeof(*cmd);
10787 	buf = wmi_buf_alloc(wmi_handle, len);
10788 	WMI_LOGD("%s:\n", __func__);
10789 	if (!buf) {
10790 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
10791 		return QDF_STATUS_E_NOMEM;
10792 	}
10793 
10794 	buf_ptr = wmi_buf_data(buf);
10795 	cmd = (wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *)buf_ptr;
10796 	WMITLV_SET_HDR(&cmd->tlv_header,
10797 	    WMITLV_TAG_STRUC_wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param,
10798 	    WMITLV_GET_STRUCT_TLVLEN(
10799 		wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param));
10800 	cmd->rx_antenna = param->antenna;
10801 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10802 								param->pdev_id);
10803 
10804 	wmi_mtrace(WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID, NO_SESSION, 0);
10805 	ret = wmi_unified_cmd_send(wmi_handle,
10806 				buf,
10807 				len,
10808 				WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID);
10809 
10810 	if (ret != 0) {
10811 		WMI_LOGE(" %s :WMI Failed\n", __func__);
10812 		WMI_LOGE("%s: rx_antenna: 0x%08x cmdstatus=%d\n",
10813 			 __func__,
10814 			 cmd->rx_antenna,
10815 			 ret);
10816 		wmi_buf_free(buf);
10817 	}
10818 
10819 	return ret;
10820 }
10821 
10822 /**
10823  * send_set_ctl_table_cmd_tlv() - send ctl table cmd to fw
10824  * @wmi_handle: wmi handle
10825  * @param: pointer to hold ctl table param
10826  *
10827  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10828  */
10829 static QDF_STATUS
10830 send_set_ctl_table_cmd_tlv(wmi_unified_t wmi_handle,
10831 			   struct ctl_table_params *param)
10832 {
10833 	uint16_t len, ctl_tlv_len;
10834 	uint8_t *buf_ptr;
10835 	wmi_buf_t buf;
10836 	wmi_pdev_set_ctl_table_cmd_fixed_param *cmd;
10837 	uint32_t *ctl_array;
10838 
10839 	if (!param->ctl_array)
10840 		return QDF_STATUS_E_FAILURE;
10841 
10842 	ctl_tlv_len = WMI_TLV_HDR_SIZE +
10843 		roundup(param->ctl_cmd_len, sizeof(uint32_t));
10844 	len = sizeof(*cmd) + ctl_tlv_len;
10845 
10846 	buf = wmi_buf_alloc(wmi_handle, len);
10847 	if (!buf) {
10848 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
10849 		return QDF_STATUS_E_FAILURE;
10850 	}
10851 
10852 	buf_ptr = wmi_buf_data(buf);
10853 	qdf_mem_zero(buf_ptr, len);
10854 
10855 	cmd = (wmi_pdev_set_ctl_table_cmd_fixed_param *)buf_ptr;
10856 
10857 	WMITLV_SET_HDR(&cmd->tlv_header,
10858 		       WMITLV_TAG_STRUC_wmi_pdev_set_ctl_table_cmd_fixed_param,
10859 		       WMITLV_GET_STRUCT_TLVLEN(
10860 				wmi_pdev_set_ctl_table_cmd_fixed_param));
10861 	cmd->ctl_len = param->ctl_cmd_len;
10862 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10863 								param->pdev_id);
10864 
10865 	buf_ptr += sizeof(*cmd);
10866 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
10867 		       (cmd->ctl_len));
10868 	buf_ptr += WMI_TLV_HDR_SIZE;
10869 	ctl_array = (uint32_t *)buf_ptr;
10870 
10871 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[0], &param->ctl_band,
10872 					sizeof(param->ctl_band));
10873 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[1], param->ctl_array,
10874 					param->ctl_cmd_len -
10875 					sizeof(param->ctl_band));
10876 
10877 	wmi_mtrace(WMI_PDEV_SET_CTL_TABLE_CMDID, NO_SESSION, 0);
10878 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10879 				 WMI_PDEV_SET_CTL_TABLE_CMDID)) {
10880 		WMI_LOGE("%s:Failed to send command\n", __func__);
10881 		wmi_buf_free(buf);
10882 		return QDF_STATUS_E_FAILURE;
10883 	}
10884 
10885 	return QDF_STATUS_SUCCESS;
10886 }
10887 
10888 /**
10889  * send_set_mimogain_table_cmd_tlv() - send mimogain table cmd to fw
10890  * @wmi_handle: wmi handle
10891  * @param: pointer to hold mimogain table param
10892  *
10893  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10894  */
10895 static QDF_STATUS
10896 send_set_mimogain_table_cmd_tlv(wmi_unified_t wmi_handle,
10897 				struct mimogain_table_params *param)
10898 {
10899 	uint16_t len, table_tlv_len;
10900 	wmi_buf_t buf;
10901 	uint8_t *buf_ptr;
10902 	wmi_pdev_set_mimogain_table_cmd_fixed_param *cmd;
10903 	uint32_t *gain_table;
10904 
10905 	if (!param->array_gain)
10906 		return QDF_STATUS_E_FAILURE;
10907 
10908 	/* len must be multiple of a single array gain table */
10909 	if (param->tbl_len %
10910 	    ((WMI_HOST_TX_NUM_CHAIN-1) * WMI_HOST_TPC_REGINDEX_MAX *
10911 	     WMI_HOST_ARRAY_GAIN_NUM_STREAMS) != 0) {
10912 		WMI_LOGE("Array gain table len not correct\n");
10913 		return QDF_STATUS_E_FAILURE;
10914 	}
10915 
10916 	table_tlv_len = WMI_TLV_HDR_SIZE +
10917 		roundup(param->tbl_len, sizeof(uint32_t));
10918 	len = sizeof(*cmd) + table_tlv_len;
10919 
10920 	buf = wmi_buf_alloc(wmi_handle, len);
10921 	if (!buf) {
10922 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
10923 		return QDF_STATUS_E_FAILURE;
10924 	}
10925 
10926 	buf_ptr = wmi_buf_data(buf);
10927 	qdf_mem_zero(buf_ptr, len);
10928 
10929 	cmd = (wmi_pdev_set_mimogain_table_cmd_fixed_param *)buf_ptr;
10930 
10931 	WMITLV_SET_HDR(&cmd->tlv_header,
10932 		WMITLV_TAG_STRUC_wmi_pdev_set_mimogain_table_cmd_fixed_param,
10933 		WMITLV_GET_STRUCT_TLVLEN(
10934 		       wmi_pdev_set_mimogain_table_cmd_fixed_param));
10935 
10936 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10937 								param->pdev_id);
10938 	WMI_MIMOGAIN_ARRAY_GAIN_LEN_SET(cmd->mimogain_info, param->tbl_len);
10939 	WMI_MIMOGAIN_MULTI_CHAIN_BYPASS_SET(cmd->mimogain_info,
10940 					    param->multichain_gain_bypass);
10941 
10942 	buf_ptr += sizeof(*cmd);
10943 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
10944 		       (param->tbl_len));
10945 	buf_ptr += WMI_TLV_HDR_SIZE;
10946 	gain_table = (uint32_t *)buf_ptr;
10947 
10948 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(gain_table,
10949 					param->array_gain,
10950 					param->tbl_len);
10951 
10952 	wmi_mtrace(WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID, NO_SESSION, 0);
10953 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10954 				 WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID)) {
10955 		return QDF_STATUS_E_FAILURE;
10956 	}
10957 
10958 	return QDF_STATUS_SUCCESS;
10959 }
10960 
10961 /**
10962  * enum packet_power_tlv_flags: target defined
10963  * packet power rate flags for TLV
10964  * @WMI_TLV_FLAG_ONE_CHAIN: one chain
10965  * @WMI_TLV_FLAG_TWO_CHAIN: two chain
10966  * @WMI_TLV_FLAG_THREE_CHAIN: three chain
10967  * @WMI_TLV_FLAG_FOUR_CHAIN: four chain
10968  * @WMI_TLV_FLAG_FIVE_CHAIN: five chain
10969  * @WMI_TLV_FLAG_SIX_CHAIN: six chain
10970  * @WMI_TLV_FLAG_SEVEN_CHAIN: seven chain
10971  * @WMI_TLV_FLAG_EIGHT_CHAIN:eight chain
10972  * @WMI_TLV_FLAG_STBC: STBC is set
10973  * @WMI_TLV_FLAG_40MHZ: 40MHz chan width
10974  * @WMI_TLV_FLAG_80MHZ: 80MHz chan width
10975  * @WMI_TLV_FLAG_160MHZ: 160MHz chan width
10976  * @WMI_TLV_FLAG_TXBF: Tx Bf enabled
10977  * @WMI_TLV_FLAG_RTSENA: RTS enabled
10978  * @WMI_TLV_FLAG_CTSENA: CTS enabled
10979  * @WMI_TLV_FLAG_LDPC: LDPC is set
10980  * @WMI_TLV_FLAG_SGI: Short gaurd interval
10981  * @WMI_TLV_FLAG_SU: SU Data
10982  * @WMI_TLV_FLAG_DL_MU_MIMO_AC: DL AC MU data
10983  * @WMI_TLV_FLAG_DL_MU_MIMO_AX: DL AX MU data
10984  * @WMI_TLV_FLAG_DL_OFDMA: DL OFDMA data
10985  * @WMI_TLV_FLAG_UL_OFDMA: UL OFDMA data
10986  * @WMI_TLV_FLAG_UL_MU_MIMO: UL MU data
10987  *
10988  * @WMI_TLV_FLAG_BW_MASK: bandwidth mask
10989  * @WMI_TLV_FLAG_BW_SHIFT: bandwidth shift
10990  * @WMI_TLV_FLAG_SU_MU_OFDMA_MASK: su/mu/ofdma mask
10991  * @WMI_TLV_FLAG_SU_MU_OFDMA_shift: su/mu/ofdma shift
10992  */
10993 enum packet_power_tlv_flags {
10994 	WMI_TLV_FLAG_ONE_CHAIN         = 0x00000001,
10995 	WMI_TLV_FLAG_TWO_CHAIN         = 0x00000003,
10996 	WMI_TLV_FLAG_THREE_CHAIN       = 0x00000007,
10997 	WMI_TLV_FLAG_FOUR_CHAIN        = 0x0000000F,
10998 	WMI_TLV_FLAG_FIVE_CHAIN        = 0x0000001F,
10999 	WMI_TLV_FLAG_SIX_CHAIN         = 0x0000003F,
11000 	WMI_TLV_FLAG_SEVEN_CHAIN       = 0x0000007F,
11001 	WMI_TLV_FLAG_EIGHT_CHAIN       = 0x0000008F,
11002 	WMI_TLV_FLAG_STBC              = 0x00000100,
11003 	WMI_TLV_FLAG_40MHZ             = 0x00000200,
11004 	WMI_TLV_FLAG_80MHZ             = 0x00000300,
11005 	WMI_TLV_FLAG_160MHZ            = 0x00000400,
11006 	WMI_TLV_FLAG_TXBF              = 0x00000800,
11007 	WMI_TLV_FLAG_RTSENA            = 0x00001000,
11008 	WMI_TLV_FLAG_CTSENA            = 0x00002000,
11009 	WMI_TLV_FLAG_LDPC              = 0x00004000,
11010 	WMI_TLV_FLAG_SGI               = 0x00008000,
11011 	WMI_TLV_FLAG_SU                = 0x00100000,
11012 	WMI_TLV_FLAG_DL_MU_MIMO_AC     = 0x00200000,
11013 	WMI_TLV_FLAG_DL_MU_MIMO_AX     = 0x00300000,
11014 	WMI_TLV_FLAG_DL_OFDMA          = 0x00400000,
11015 	WMI_TLV_FLAG_UL_OFDMA          = 0x00500000,
11016 	WMI_TLV_FLAG_UL_MU_MIMO        = 0x00600000,
11017 
11018 	WMI_TLV_FLAG_CHAIN_MASK        = 0xff,
11019 	WMI_TLV_FLAG_BW_MASK           = 0x3,
11020 	WMI_TLV_FLAG_BW_SHIFT          = 9,
11021 	WMI_TLV_FLAG_SU_MU_OFDMA_MASK  = 0x7,
11022 	WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT = 20,
11023 };
11024 
11025 /**
11026  * convert_to_power_info_rate_flags() - convert packet_power_info_params
11027  * to FW understandable format
11028  * @param: pointer to hold packet power info param
11029  *
11030  * @return FW understandable 32 bit rate flags
11031  */
11032 static uint32_t
11033 convert_to_power_info_rate_flags(struct packet_power_info_params *param)
11034 {
11035 	uint32_t rateflags = 0;
11036 
11037 	if (param->chainmask)
11038 		rateflags |=
11039 			(param->chainmask & WMI_TLV_FLAG_CHAIN_MASK);
11040 	if (param->chan_width)
11041 		rateflags |=
11042 			((param->chan_width & WMI_TLV_FLAG_BW_MASK)
11043 			 << WMI_TLV_FLAG_BW_SHIFT);
11044 	if (param->su_mu_ofdma)
11045 		rateflags |=
11046 			((param->su_mu_ofdma & WMI_TLV_FLAG_SU_MU_OFDMA_MASK)
11047 			 << WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT);
11048 	if (param->rate_flags & WMI_HOST_FLAG_STBC)
11049 		rateflags |= WMI_TLV_FLAG_STBC;
11050 	if (param->rate_flags & WMI_HOST_FLAG_LDPC)
11051 		rateflags |= WMI_TLV_FLAG_LDPC;
11052 	if (param->rate_flags & WMI_HOST_FLAG_TXBF)
11053 		rateflags |= WMI_TLV_FLAG_TXBF;
11054 	if (param->rate_flags & WMI_HOST_FLAG_RTSENA)
11055 		rateflags |= WMI_TLV_FLAG_RTSENA;
11056 	if (param->rate_flags & WMI_HOST_FLAG_CTSENA)
11057 		rateflags |= WMI_TLV_FLAG_CTSENA;
11058 	if (param->rate_flags & WMI_HOST_FLAG_SGI)
11059 		rateflags |= WMI_TLV_FLAG_SGI;
11060 
11061 	return rateflags;
11062 }
11063 
11064 /**
11065  * send_packet_power_info_get_cmd_tlv() - send request to get packet power
11066  * info to fw
11067  * @wmi_handle: wmi handle
11068  * @param: pointer to hold packet power info param
11069  *
11070  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11071  */
11072 static QDF_STATUS
11073 send_packet_power_info_get_cmd_tlv(wmi_unified_t wmi_handle,
11074 				   struct packet_power_info_params *param)
11075 {
11076 	wmi_pdev_get_tpc_cmd_fixed_param *cmd;
11077 	wmi_buf_t wmibuf;
11078 	uint8_t *buf_ptr;
11079 	u_int32_t len = sizeof(wmi_pdev_get_tpc_cmd_fixed_param);
11080 
11081 	wmibuf = wmi_buf_alloc(wmi_handle, len);
11082 	if (wmibuf == NULL)
11083 		return QDF_STATUS_E_NOMEM;
11084 
11085 	buf_ptr = (uint8_t *)wmi_buf_data(wmibuf);
11086 
11087 	cmd = (wmi_pdev_get_tpc_cmd_fixed_param *)buf_ptr;
11088 	WMITLV_SET_HDR(&cmd->tlv_header,
11089 		       WMITLV_TAG_STRUC_wmi_pdev_get_tpc_cmd_fixed_param,
11090 		       WMITLV_GET_STRUCT_TLVLEN(
11091 				wmi_pdev_get_tpc_cmd_fixed_param));
11092 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
11093 								param->pdev_id);
11094 	cmd->rate_flags = convert_to_power_info_rate_flags(param);
11095 	cmd->nss = param->nss;
11096 	cmd->preamble = param->preamble;
11097 	cmd->hw_rate = param->hw_rate;
11098 
11099 	WMI_LOGI("%s[%d] commandID %d, wmi_pdev_get_tpc_cmd=0x%x,"
11100 		"rate_flags: 0x%x, nss: %d, preamble: %d, hw_rate: %d\n",
11101 		__func__, __LINE__, WMI_PDEV_GET_TPC_CMDID, *((u_int32_t *)cmd),
11102 		cmd->rate_flags, cmd->nss, cmd->preamble, cmd->hw_rate);
11103 
11104 	wmi_mtrace(WMI_PDEV_GET_TPC_CMDID, NO_SESSION, 0);
11105 	if (wmi_unified_cmd_send(wmi_handle, wmibuf, len,
11106 				 WMI_PDEV_GET_TPC_CMDID)) {
11107 			WMI_LOGE(FL("Failed to get tpc command\n"));
11108 			wmi_buf_free(wmibuf);
11109 			return QDF_STATUS_E_FAILURE;
11110 	}
11111 
11112 	return QDF_STATUS_SUCCESS;
11113 }
11114 
11115 /**
11116  * send_vdev_config_ratemask_cmd_tlv() - config ratemask param in fw
11117  * @wmi_handle: wmi handle
11118  * @param: pointer to hold config ratemask params
11119  *
11120  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11121  */
11122 static QDF_STATUS send_vdev_config_ratemask_cmd_tlv(wmi_unified_t wmi_handle,
11123 					struct config_ratemask_params *param)
11124 {
11125 	wmi_vdev_config_ratemask_cmd_fixed_param *cmd;
11126 	wmi_buf_t buf;
11127 	int32_t len = sizeof(*cmd);
11128 
11129 	buf = wmi_buf_alloc(wmi_handle, len);
11130 	if (!buf) {
11131 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11132 		return QDF_STATUS_E_FAILURE;
11133 	}
11134 	cmd = (wmi_vdev_config_ratemask_cmd_fixed_param *)wmi_buf_data(buf);
11135 	WMITLV_SET_HDR(&cmd->tlv_header,
11136 		       WMITLV_TAG_STRUC_wmi_vdev_config_ratemask_fixed_param,
11137 		       WMITLV_GET_STRUCT_TLVLEN(
11138 				wmi_vdev_config_ratemask_cmd_fixed_param));
11139 	cmd->vdev_id = param->vdev_id;
11140 	cmd->type = param->type;
11141 	cmd->mask_lower32 = param->lower32;
11142 	cmd->mask_higher32 = param->higher32;
11143 	cmd->mask_lower32_2 = param->lower32_2;
11144 	WMI_LOGI("Setting vdev ratemask vdev id = 0x%X, type = 0x%X"
11145 		"mask_l32 = 0x%X mask_h32 = 0x%X mask_l32_2 = 0x%X\n",
11146 		param->vdev_id, param->type, param->lower32,
11147 		param->higher32, param->lower32_2);
11148 
11149 	wmi_mtrace(WMI_VDEV_RATEMASK_CMDID, cmd->vdev_id, 0);
11150 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11151 				 WMI_VDEV_RATEMASK_CMDID)) {
11152 			WMI_LOGE("Seting vdev ratemask failed\n");
11153 			wmi_buf_free(buf);
11154 			return QDF_STATUS_E_FAILURE;
11155 	}
11156 
11157 	return QDF_STATUS_SUCCESS;
11158 }
11159 
11160 /**
11161  * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs
11162  * @param: param sent from the host side
11163  * @cmd: param to be sent to the fw side
11164  */
11165 static inline void copy_custom_aggr_bitmap(
11166 		struct set_custom_aggr_size_params *param,
11167 		wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd)
11168 {
11169 	WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap,
11170 				    param->ac);
11171 	WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap,
11172 				      param->aggr_type);
11173 	WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap,
11174 					   param->tx_aggr_size_disable);
11175 	WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap,
11176 					   param->rx_aggr_size_disable);
11177 	WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap,
11178 				     param->tx_ac_enable);
11179 }
11180 
11181 /**
11182  * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw
11183  * @wmi_handle: wmi handle
11184  * @param: pointer to hold custom aggr size params
11185  *
11186  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11187  */
11188 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv(
11189 			wmi_unified_t wmi_handle,
11190 			struct set_custom_aggr_size_params *param)
11191 {
11192 	wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd;
11193 	wmi_buf_t buf;
11194 	int32_t len = sizeof(*cmd);
11195 
11196 	buf = wmi_buf_alloc(wmi_handle, len);
11197 	if (!buf) {
11198 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11199 		return QDF_STATUS_E_FAILURE;
11200 	}
11201 	cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *)
11202 		wmi_buf_data(buf);
11203 	WMITLV_SET_HDR(&cmd->tlv_header,
11204 		WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param,
11205 		WMITLV_GET_STRUCT_TLVLEN(
11206 		wmi_vdev_set_custom_aggr_size_cmd_fixed_param));
11207 	cmd->vdev_id = param->vdev_id;
11208 	cmd->tx_aggr_size = param->tx_aggr_size;
11209 	cmd->rx_aggr_size = param->rx_aggr_size;
11210 	copy_custom_aggr_bitmap(param, cmd);
11211 
11212 	WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X "
11213 		"rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X "
11214 		"tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X "
11215 		"tx_ac_enable=0x%X\n",
11216 		param->vdev_id, param->tx_aggr_size, param->rx_aggr_size,
11217 		param->ac, param->aggr_type, param->tx_aggr_size_disable,
11218 		param->rx_aggr_size_disable, param->tx_ac_enable);
11219 
11220 	wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0);
11221 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11222 				 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) {
11223 		WMI_LOGE("Seting custom aggregation size failed\n");
11224 		wmi_buf_free(buf);
11225 		return QDF_STATUS_E_FAILURE;
11226 	}
11227 
11228 	return QDF_STATUS_SUCCESS;
11229 }
11230 
11231 /**
11232  *  send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold
11233  *  @param wmi_handle  : handle to WMI.
11234  *  @param param       : pointer to tx antenna param
11235  *
11236  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11237  */
11238 
11239 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle,
11240 				struct set_qdepth_thresh_params *param)
11241 {
11242 	wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd;
11243 	wmi_msduq_qdepth_thresh_update *cmd_update;
11244 	wmi_buf_t buf;
11245 	int32_t len = 0;
11246 	int i;
11247 	uint8_t *buf_ptr;
11248 	QDF_STATUS ret;
11249 
11250 	if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) {
11251 		WMI_LOGE("%s: Invalid Update Count!\n", __func__);
11252 		return QDF_STATUS_E_INVAL;
11253 	}
11254 
11255 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11256 	len += (sizeof(wmi_msduq_qdepth_thresh_update) *
11257 			param->num_of_msduq_updates);
11258 	buf = wmi_buf_alloc(wmi_handle, len);
11259 
11260 	if (!buf) {
11261 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11262 		return QDF_STATUS_E_NOMEM;
11263 	}
11264 
11265 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11266 	cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *)
11267 								buf_ptr;
11268 
11269 	WMITLV_SET_HDR(&cmd->tlv_header,
11270 	WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param
11271 	 , WMITLV_GET_STRUCT_TLVLEN(
11272 		wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param));
11273 
11274 	cmd->pdev_id =
11275 		wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id);
11276 	cmd->vdev_id = param->vdev_id;
11277 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address);
11278 	cmd->num_of_msduq_updates = param->num_of_msduq_updates;
11279 
11280 	buf_ptr += sizeof(
11281 		wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param);
11282 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11283 			param->num_of_msduq_updates *
11284 			sizeof(wmi_msduq_qdepth_thresh_update));
11285 	buf_ptr += WMI_TLV_HDR_SIZE;
11286 	cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr;
11287 
11288 	for (i = 0; i < cmd->num_of_msduq_updates; i++) {
11289 		WMITLV_SET_HDR(&cmd_update->tlv_header,
11290 		    WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update,
11291 		    WMITLV_GET_STRUCT_TLVLEN(
11292 				wmi_msduq_qdepth_thresh_update));
11293 		cmd_update->tid_num = param->update_params[i].tid_num;
11294 		cmd_update->msduq_update_mask =
11295 				param->update_params[i].msduq_update_mask;
11296 		cmd_update->qdepth_thresh_value =
11297 				param->update_params[i].qdepth_thresh_value;
11298 		WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X "
11299 			 "mac_addr_upper4=%X, mac_addr_lower2:%X,"
11300 			 " update mask=0x%X thresh val=0x%X\n",
11301 			 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num,
11302 			 cmd->peer_mac_address.mac_addr31to0,
11303 			 cmd->peer_mac_address.mac_addr47to32,
11304 			 cmd_update->msduq_update_mask,
11305 			 cmd_update->qdepth_thresh_value);
11306 		cmd_update++;
11307 	}
11308 
11309 	wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID,
11310 		   cmd->vdev_id, 0);
11311 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
11312 				WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID);
11313 
11314 	if (ret != 0) {
11315 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11316 		wmi_buf_free(buf);
11317 	}
11318 
11319 	return ret;
11320 }
11321 
11322 /**
11323  * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw
11324  * @wmi_handle: wmi handle
11325  * @param: pointer to hold vap dscp tid map param
11326  *
11327  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11328  */
11329 static QDF_STATUS
11330 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle,
11331 				  struct vap_dscp_tid_map_params *param)
11332 {
11333 	wmi_buf_t buf;
11334 	wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd;
11335 	int32_t len = sizeof(*cmd);
11336 
11337 	buf = wmi_buf_alloc(wmi_handle, len);
11338 	if (!buf) {
11339 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11340 		return QDF_STATUS_E_FAILURE;
11341 	}
11342 
11343 	cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf);
11344 	qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map,
11345 		     sizeof(uint32_t) * WMI_DSCP_MAP_MAX);
11346 
11347 	cmd->vdev_id = param->vdev_id;
11348 	cmd->enable_override = 0;
11349 
11350 	WMI_LOGI("Setting dscp for vap id: %d\n", cmd->vdev_id);
11351 	wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0);
11352 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11353 				 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) {
11354 			WMI_LOGE("Failed to set dscp cmd\n");
11355 			wmi_buf_free(buf);
11356 			return QDF_STATUS_E_FAILURE;
11357 	}
11358 
11359 	return QDF_STATUS_SUCCESS;
11360 }
11361 
11362 /**
11363  * send_vdev_set_neighbour_rx_cmd_tlv() - set neighbour rx param in fw
11364  * @wmi_handle: wmi handle
11365  * @macaddr: vdev mac address
11366  * @param: pointer to hold neigbour rx param
11367  *
11368  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11369  */
11370 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle,
11371 					uint8_t macaddr[IEEE80211_ADDR_LEN],
11372 					struct set_neighbour_rx_params *param)
11373 {
11374 	wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd;
11375 	wmi_buf_t buf;
11376 	int32_t len = sizeof(*cmd);
11377 
11378 	buf = wmi_buf_alloc(wmi_handle, len);
11379 	if (!buf) {
11380 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11381 		return QDF_STATUS_E_FAILURE;
11382 	}
11383 	cmd = (wmi_vdev_filter_nrp_config_cmd_fixed_param *)wmi_buf_data(buf);
11384 	WMITLV_SET_HDR(&cmd->tlv_header,
11385 		WMITLV_TAG_STRUC_wmi_vdev_filter_nrp_config_cmd_fixed_param,
11386 		WMITLV_GET_STRUCT_TLVLEN(
11387 			wmi_vdev_filter_nrp_config_cmd_fixed_param));
11388 	cmd->vdev_id = param->vdev_id;
11389 	cmd->bssid_idx = param->idx;
11390 	cmd->action = param->action;
11391 	cmd->type = param->type;
11392 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->addr);
11393 	cmd->flag = 0;
11394 
11395 	wmi_mtrace(WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID, cmd->vdev_id, 0);
11396 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11397 				 WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID)) {
11398 			WMI_LOGE("Failed to set neighbour rx param\n");
11399 			wmi_buf_free(buf);
11400 			return QDF_STATUS_E_FAILURE;
11401 	}
11402 
11403 	return QDF_STATUS_SUCCESS;
11404 }
11405 
11406 /**
11407  *  send_smart_ant_set_tx_ant_cmd_tlv() - WMI set tx antenna function
11408  *  @param wmi_handle  : handle to WMI.
11409  *  @param macaddr     : vdev mac address
11410  *  @param param       : pointer to tx antenna param
11411  *
11412  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11413  */
11414 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle,
11415 				uint8_t macaddr[IEEE80211_ADDR_LEN],
11416 				struct smart_ant_tx_ant_params *param)
11417 {
11418 	wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd;
11419 	wmi_peer_smart_ant_set_tx_antenna_series *ant_tx_series;
11420 	wmi_buf_t buf;
11421 	int32_t len = 0;
11422 	int i;
11423 	uint8_t *buf_ptr;
11424 	QDF_STATUS ret;
11425 
11426 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11427 	len += (WMI_SMART_ANT_MAX_RATE_SERIES) *
11428 		sizeof(wmi_peer_smart_ant_set_tx_antenna_series);
11429 	buf = wmi_buf_alloc(wmi_handle, len);
11430 
11431 	if (!buf) {
11432 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11433 		return QDF_STATUS_E_NOMEM;
11434 	}
11435 
11436 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11437 	qdf_mem_zero(buf_ptr, len);
11438 	cmd = (wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *)buf_ptr;
11439 
11440 	WMITLV_SET_HDR(&cmd->tlv_header,
11441 	    WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param,
11442 	    WMITLV_GET_STRUCT_TLVLEN(
11443 			wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param));
11444 
11445 	cmd->vdev_id = param->vdev_id;
11446 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11447 
11448 	buf_ptr += sizeof(wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param);
11449 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11450 		       sizeof(wmi_peer_smart_ant_set_tx_antenna_series));
11451 	buf_ptr += WMI_TLV_HDR_SIZE;
11452 	ant_tx_series = (wmi_peer_smart_ant_set_tx_antenna_series *)buf_ptr;
11453 
11454 	for (i = 0; i < WMI_SMART_ANT_MAX_RATE_SERIES; i++) {
11455 		WMITLV_SET_HDR(&ant_tx_series->tlv_header,
11456 		    WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_series,
11457 		    WMITLV_GET_STRUCT_TLVLEN(
11458 				wmi_peer_smart_ant_set_tx_antenna_series));
11459 		ant_tx_series->antenna_series = param->antenna_array[i];
11460 		ant_tx_series++;
11461 	}
11462 
11463 	wmi_mtrace(WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID, cmd->vdev_id, 0);
11464 	ret = wmi_unified_cmd_send(wmi_handle,
11465 				   buf,
11466 				   len,
11467 				   WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID);
11468 
11469 	if (ret != 0) {
11470 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11471 		wmi_buf_free(buf);
11472 	}
11473 
11474 	return ret;
11475 }
11476 
11477 /**
11478  * send_set_ant_switch_tbl_cmd_tlv() - send ant switch tbl cmd to fw
11479  * @wmi_handle: wmi handle
11480  * @param: pointer to hold ant switch tbl param
11481  *
11482  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11483  */
11484 static QDF_STATUS
11485 send_set_ant_switch_tbl_cmd_tlv(wmi_unified_t wmi_handle,
11486 				struct ant_switch_tbl_params *param)
11487 {
11488 	uint8_t len;
11489 	wmi_buf_t buf;
11490 	wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *cmd;
11491 	wmi_pdev_set_ant_ctrl_chain *ctrl_chain;
11492 	uint8_t *buf_ptr;
11493 
11494 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11495 	len += sizeof(wmi_pdev_set_ant_ctrl_chain);
11496 	buf = wmi_buf_alloc(wmi_handle, len);
11497 
11498 	if (!buf) {
11499 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11500 		return QDF_STATUS_E_NOMEM;
11501 	}
11502 
11503 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11504 	qdf_mem_zero(buf_ptr, len);
11505 	cmd = (wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *)buf_ptr;
11506 
11507 	WMITLV_SET_HDR(&cmd->tlv_header,
11508 		WMITLV_TAG_STRUC_wmi_pdev_set_ant_switch_tbl_cmd_fixed_param,
11509 		WMITLV_GET_STRUCT_TLVLEN(
11510 			wmi_pdev_set_ant_switch_tbl_cmd_fixed_param));
11511 
11512 	cmd->antCtrlCommon1 = param->ant_ctrl_common1;
11513 	cmd->antCtrlCommon2 = param->ant_ctrl_common2;
11514 	cmd->mac_id =
11515 		wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id);
11516 
11517 	/* TLV indicating array of structures to follow */
11518 	buf_ptr += sizeof(wmi_pdev_set_ant_switch_tbl_cmd_fixed_param);
11519 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11520 		       sizeof(wmi_pdev_set_ant_ctrl_chain));
11521 	buf_ptr += WMI_TLV_HDR_SIZE;
11522 	ctrl_chain = (wmi_pdev_set_ant_ctrl_chain *)buf_ptr;
11523 
11524 	ctrl_chain->pdev_id =
11525 		wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id);
11526 	ctrl_chain->antCtrlChain = param->antCtrlChain;
11527 
11528 	wmi_mtrace(WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID, NO_SESSION, 0);
11529 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11530 				 WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) {
11531 		wmi_buf_free(buf);
11532 		return QDF_STATUS_E_FAILURE;
11533 	}
11534 
11535 	return QDF_STATUS_SUCCESS;
11536 }
11537 
11538 /**
11539  *  send_smart_ant_set_training_info_cmd_tlv() - WMI set smart antenna
11540  *  training information function
11541  *  @param wmi_handle  : handle to WMI.
11542  *  @macaddr           : vdev mac address
11543  *  @param param       : pointer to tx antenna param
11544  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11545  */
11546 static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv(
11547 				wmi_unified_t wmi_handle,
11548 				uint8_t macaddr[IEEE80211_ADDR_LEN],
11549 				struct smart_ant_training_info_params *param)
11550 {
11551 	wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd;
11552 	wmi_peer_smart_ant_set_train_antenna_param *train_param;
11553 	wmi_buf_t buf;
11554 	uint8_t *buf_ptr;
11555 	int32_t len = 0;
11556 	QDF_STATUS ret;
11557 	int loop;
11558 
11559 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11560 	len += (WMI_SMART_ANT_MAX_RATE_SERIES) *
11561 		 sizeof(wmi_peer_smart_ant_set_train_antenna_param);
11562 	buf = wmi_buf_alloc(wmi_handle, len);
11563 
11564 	if (!buf) {
11565 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11566 		return QDF_STATUS_E_NOMEM;
11567 	}
11568 
11569 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11570 	qdf_mem_zero(buf_ptr, len);
11571 	cmd = (wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *)buf_ptr;
11572 
11573 	WMITLV_SET_HDR(&cmd->tlv_header,
11574 	WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param,
11575 		WMITLV_GET_STRUCT_TLVLEN(
11576 			wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param));
11577 
11578 	cmd->vdev_id = param->vdev_id;
11579 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11580 	cmd->num_pkts = param->numpkts;
11581 
11582 	buf_ptr += sizeof(wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param);
11583 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11584 		       sizeof(wmi_peer_smart_ant_set_train_antenna_param) *
11585 		       WMI_SMART_ANT_MAX_RATE_SERIES);
11586 
11587 	buf_ptr += WMI_TLV_HDR_SIZE;
11588 	train_param = (wmi_peer_smart_ant_set_train_antenna_param *)buf_ptr;
11589 
11590 	for (loop = 0; loop < WMI_SMART_ANT_MAX_RATE_SERIES; loop++) {
11591 		WMITLV_SET_HDR(&train_param->tlv_header,
11592 		WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_param,
11593 			    WMITLV_GET_STRUCT_TLVLEN(
11594 				wmi_peer_smart_ant_set_train_antenna_param));
11595 		train_param->train_rate_series = param->rate_array[loop];
11596 		train_param->train_antenna_series = param->antenna_array[loop];
11597 		train_param->rc_flags = 0;
11598 		WMI_LOGI(FL("Series number:%d\n"), loop);
11599 		WMI_LOGI(FL("Rate [0x%02x] Tx_Antenna [0x%08x]\n"),
11600 			 train_param->train_rate_series,
11601 			 train_param->train_antenna_series);
11602 		train_param++;
11603 	}
11604 
11605 	wmi_mtrace(WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID, cmd->vdev_id, 0);
11606 	ret = wmi_unified_cmd_send(wmi_handle,
11607 				buf,
11608 				len,
11609 				WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID);
11610 
11611 	if (ret != 0) {
11612 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11613 		wmi_buf_free(buf);
11614 		return QDF_STATUS_E_FAILURE;
11615 	}
11616 
11617 	return ret;
11618 }
11619 
11620 /**
11621  *  send_smart_ant_set_node_config_cmd_tlv() - WMI set node
11622  *  configuration function
11623  *  @param wmi_handle		   : handle to WMI.
11624  *  @macaddr			   : vdev mad address
11625  *  @param param		   : pointer to tx antenna param
11626  *
11627  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11628  */
11629 static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv(
11630 				wmi_unified_t wmi_handle,
11631 				uint8_t macaddr[IEEE80211_ADDR_LEN],
11632 				struct smart_ant_node_config_params *param)
11633 {
11634 	wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd;
11635 	wmi_buf_t buf;
11636 	uint8_t *buf_ptr;
11637 	int32_t len = 0, args_tlv_len;
11638 	int ret;
11639 	int i = 0;
11640 	uint32_t *node_config_args;
11641 
11642 	args_tlv_len = WMI_TLV_HDR_SIZE + param->args_count * sizeof(uint32_t);
11643 	len = sizeof(*cmd) + args_tlv_len;
11644 
11645 	if (param->args_count == 0) {
11646 		WMI_LOGE("%s: Can't send a command with %d arguments\n",
11647 			  __func__, param->args_count);
11648 		return QDF_STATUS_E_FAILURE;
11649 	}
11650 
11651 	buf = wmi_buf_alloc(wmi_handle, len);
11652 	if (!buf) {
11653 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11654 		return QDF_STATUS_E_NOMEM;
11655 	}
11656 
11657 	cmd = (wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *)
11658 						wmi_buf_data(buf);
11659 	buf_ptr = (uint8_t *)cmd;
11660 	WMITLV_SET_HDR(&cmd->tlv_header,
11661 	WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param,
11662 		WMITLV_GET_STRUCT_TLVLEN(
11663 		wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param));
11664 	cmd->vdev_id = param->vdev_id;
11665 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11666 	cmd->cmd_id = param->cmd_id;
11667 	cmd->args_count = param->args_count;
11668 	buf_ptr += sizeof(
11669 		wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param);
11670 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
11671 			(cmd->args_count * sizeof(uint32_t)));
11672 	buf_ptr += WMI_TLV_HDR_SIZE;
11673 	node_config_args = (uint32_t *)buf_ptr;
11674 
11675 	for (i = 0; i < param->args_count; i++) {
11676 		node_config_args[i] = param->args_arr[i];
11677 		WMI_LOGI("%d", param->args_arr[i]);
11678 	}
11679 
11680 	wmi_mtrace(WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID,
11681 		   cmd->vdev_id, 0);
11682 	ret = wmi_unified_cmd_send(wmi_handle,
11683 			   buf,
11684 			   len,
11685 			   WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID);
11686 
11687 	if (ret != 0) {
11688 		WMI_LOGE("%s: WMI FAILED:Sent cmd_id: 0x%x\n Node: %02x:%02x:%02x:%02x:%02x:%02x cmdstatus=%d\n",
11689 			 __func__, param->cmd_id, macaddr[0],
11690 			 macaddr[1], macaddr[2], macaddr[3],
11691 			 macaddr[4], macaddr[5], ret);
11692 		wmi_buf_free(buf);
11693 	}
11694 
11695 	return ret;
11696 }
11697 
11698 #ifdef WLAN_ATF_ENABLE
11699 /**
11700  * send_set_atf_cmd_tlv() - send set atf command to fw
11701  * @wmi_handle: wmi handle
11702  * @param: pointer to set atf param
11703  *
11704  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11705  */
11706 static QDF_STATUS
11707 send_set_atf_cmd_tlv(wmi_unified_t wmi_handle,
11708 		     struct set_atf_params *param)
11709 {
11710 	wmi_atf_peer_info *peer_info;
11711 	wmi_peer_atf_request_fixed_param *cmd;
11712 	wmi_buf_t buf;
11713 	uint8_t *buf_ptr;
11714 	int i;
11715 	int32_t len = 0;
11716 	QDF_STATUS retval;
11717 
11718 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11719 	len += param->num_peers * sizeof(wmi_atf_peer_info);
11720 	buf = wmi_buf_alloc(wmi_handle, len);
11721 	if (!buf) {
11722 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11723 		return QDF_STATUS_E_FAILURE;
11724 	}
11725 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11726 	cmd = (wmi_peer_atf_request_fixed_param *)buf_ptr;
11727 	WMITLV_SET_HDR(&cmd->tlv_header,
11728 		       WMITLV_TAG_STRUC_wmi_peer_atf_request_fixed_param,
11729 		       WMITLV_GET_STRUCT_TLVLEN(
11730 				wmi_peer_atf_request_fixed_param));
11731 	cmd->num_peers = param->num_peers;
11732 
11733 	buf_ptr += sizeof(*cmd);
11734 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11735 		       sizeof(wmi_atf_peer_info) *
11736 		       cmd->num_peers);
11737 	buf_ptr += WMI_TLV_HDR_SIZE;
11738 	peer_info = (wmi_atf_peer_info *)buf_ptr;
11739 
11740 	for (i = 0; i < cmd->num_peers; i++) {
11741 		WMITLV_SET_HDR(&peer_info->tlv_header,
11742 			    WMITLV_TAG_STRUC_wmi_atf_peer_info,
11743 			    WMITLV_GET_STRUCT_TLVLEN(
11744 				wmi_atf_peer_info));
11745 		qdf_mem_copy(&(peer_info->peer_macaddr),
11746 				&(param->peer_info[i].peer_macaddr),
11747 				sizeof(wmi_mac_addr));
11748 		peer_info->atf_units = param->peer_info[i].percentage_peer;
11749 		peer_info->vdev_id = param->peer_info[i].vdev_id;
11750 		peer_info->pdev_id =
11751 			wmi_handle->ops->convert_pdev_id_host_to_target(
11752 				param->peer_info[i].pdev_id);
11753 		/*
11754 		 * TLV definition for peer atf request fixed param combines
11755 		 * extension stats. Legacy FW for WIN (Non-TLV) has peer atf
11756 		 * stats and atf extension stats as two different
11757 		 * implementations.
11758 		 * Need to discuss with FW on this.
11759 		 *
11760 		 * peer_info->atf_groupid = param->peer_ext_info[i].group_index;
11761 		 * peer_info->atf_units_reserved =
11762 		 *		param->peer_ext_info[i].atf_index_reserved;
11763 		 */
11764 		peer_info++;
11765 	}
11766 
11767 	wmi_mtrace(WMI_PEER_ATF_REQUEST_CMDID, NO_SESSION, 0);
11768 	retval = wmi_unified_cmd_send(wmi_handle, buf, len,
11769 		WMI_PEER_ATF_REQUEST_CMDID);
11770 
11771 	if (retval != QDF_STATUS_SUCCESS) {
11772 		WMI_LOGE("%s : WMI Failed\n", __func__);
11773 		wmi_buf_free(buf);
11774 	}
11775 
11776 	return retval;
11777 }
11778 #endif
11779 
11780 /**
11781  * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw
11782  * @wmi_handle: wmi handle
11783  * @param: pointer to hold fwtest param
11784  *
11785  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11786  */
11787 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle,
11788 				struct set_fwtest_params *param)
11789 {
11790 	wmi_fwtest_set_param_cmd_fixed_param *cmd;
11791 	wmi_buf_t buf;
11792 	int32_t len = sizeof(*cmd);
11793 
11794 	buf = wmi_buf_alloc(wmi_handle, len);
11795 
11796 	if (!buf) {
11797 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11798 		return QDF_STATUS_E_FAILURE;
11799 	}
11800 
11801 	cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf);
11802 	WMITLV_SET_HDR(&cmd->tlv_header,
11803 		       WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param,
11804 		       WMITLV_GET_STRUCT_TLVLEN(
11805 				wmi_fwtest_set_param_cmd_fixed_param));
11806 	cmd->param_id = param->arg;
11807 	cmd->param_value = param->value;
11808 
11809 	wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0);
11810 	if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) {
11811 		WMI_LOGE("Setting FW test param failed\n");
11812 		wmi_buf_free(buf);
11813 		return QDF_STATUS_E_FAILURE;
11814 	}
11815 
11816 	return QDF_STATUS_SUCCESS;
11817 }
11818 
11819 /**
11820  * send_set_qboost_param_cmd_tlv() - send set qboost command to fw
11821  * @wmi_handle: wmi handle
11822  * @param: pointer to qboost params
11823  * @macaddr: vdev mac address
11824  *
11825  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11826  */
11827 static QDF_STATUS
11828 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle,
11829 			      uint8_t macaddr[IEEE80211_ADDR_LEN],
11830 			      struct set_qboost_params *param)
11831 {
11832 	WMI_QBOOST_CFG_CMD_fixed_param *cmd;
11833 	wmi_buf_t buf;
11834 	int32_t len;
11835 	QDF_STATUS ret;
11836 
11837 	len = sizeof(*cmd);
11838 
11839 	buf = wmi_buf_alloc(wmi_handle, len);
11840 	if (!buf) {
11841 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11842 		return QDF_STATUS_E_FAILURE;
11843 	}
11844 
11845 	cmd = (WMI_QBOOST_CFG_CMD_fixed_param *)wmi_buf_data(buf);
11846 	WMITLV_SET_HDR(&cmd->tlv_header,
11847 		       WMITLV_TAG_STRUC_WMI_QBOOST_CFG_CMD_fixed_param,
11848 		       WMITLV_GET_STRUCT_TLVLEN(
11849 				WMI_QBOOST_CFG_CMD_fixed_param));
11850 	cmd->vdev_id = param->vdev_id;
11851 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11852 	cmd->qb_enable = param->value;
11853 
11854 	wmi_mtrace(WMI_QBOOST_CFG_CMDID, cmd->vdev_id, 0);
11855 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11856 			WMI_QBOOST_CFG_CMDID);
11857 
11858 	if (ret != 0) {
11859 		WMI_LOGE("Setting qboost cmd failed\n");
11860 		wmi_buf_free(buf);
11861 	}
11862 
11863 	return ret;
11864 }
11865 
11866 /**
11867  * send_gpio_config_cmd_tlv() - send gpio config to fw
11868  * @wmi_handle: wmi handle
11869  * @param: pointer to hold gpio config param
11870  *
11871  * Return: 0 for success or error code
11872  */
11873 static QDF_STATUS
11874 send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle,
11875 			 struct gpio_config_params *param)
11876 {
11877 	wmi_gpio_config_cmd_fixed_param *cmd;
11878 	wmi_buf_t buf;
11879 	int32_t len;
11880 	QDF_STATUS ret;
11881 
11882 	len = sizeof(*cmd);
11883 
11884 	/* Sanity Checks */
11885 	if (param->pull_type > WMI_GPIO_PULL_DOWN ||
11886 	    param->intr_mode > WMI_GPIO_INTTYPE_LEVEL_HIGH) {
11887 		return QDF_STATUS_E_FAILURE;
11888 	}
11889 
11890 	buf = wmi_buf_alloc(wmi_handle, len);
11891 	if (!buf) {
11892 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11893 		return QDF_STATUS_E_FAILURE;
11894 	}
11895 
11896 	cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf);
11897 	WMITLV_SET_HDR(&cmd->tlv_header,
11898 		       WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param,
11899 		       WMITLV_GET_STRUCT_TLVLEN(
11900 				wmi_gpio_config_cmd_fixed_param));
11901 	cmd->gpio_num = param->gpio_num;
11902 	cmd->input = param->input;
11903 	cmd->pull_type = param->pull_type;
11904 	cmd->intr_mode = param->intr_mode;
11905 
11906 	wmi_mtrace(WMI_GPIO_CONFIG_CMDID, NO_SESSION, 0);
11907 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11908 			WMI_GPIO_CONFIG_CMDID);
11909 
11910 	if (ret != 0) {
11911 		WMI_LOGE("Sending GPIO config cmd failed\n");
11912 		wmi_buf_free(buf);
11913 	}
11914 
11915 	return ret;
11916 }
11917 
11918 /**
11919  * send_gpio_output_cmd_tlv() - send gpio output to fw
11920  * @wmi_handle: wmi handle
11921  * @param: pointer to hold gpio output param
11922  *
11923  * Return: 0 for success or error code
11924  */
11925 static QDF_STATUS
11926 send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle,
11927 			 struct gpio_output_params *param)
11928 {
11929 	wmi_gpio_output_cmd_fixed_param *cmd;
11930 	wmi_buf_t buf;
11931 	int32_t len;
11932 	QDF_STATUS ret;
11933 
11934 	len = sizeof(*cmd);
11935 
11936 	buf = wmi_buf_alloc(wmi_handle, len);
11937 	if (!buf) {
11938 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11939 		return QDF_STATUS_E_FAILURE;
11940 	}
11941 
11942 	cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf);
11943 	WMITLV_SET_HDR(&cmd->tlv_header,
11944 		       WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param,
11945 		       WMITLV_GET_STRUCT_TLVLEN(
11946 				wmi_gpio_output_cmd_fixed_param));
11947 	cmd->gpio_num = param->gpio_num;
11948 	cmd->set = param->set;
11949 
11950 	wmi_mtrace(WMI_GPIO_OUTPUT_CMDID, NO_SESSION, 0);
11951 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11952 			WMI_GPIO_OUTPUT_CMDID);
11953 
11954 	if (ret != 0) {
11955 		WMI_LOGE("Sending GPIO output cmd failed\n");
11956 		wmi_buf_free(buf);
11957 	}
11958 
11959 	return ret;
11960 
11961 }
11962 
11963 /**
11964  *  send_phyerr_disable_cmd_tlv() - WMI phyerr disable function
11965  *
11966  *  @param wmi_handle     : handle to WMI.
11967  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11968  */
11969 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle)
11970 {
11971 	wmi_pdev_dfs_disable_cmd_fixed_param *cmd;
11972 	wmi_buf_t buf;
11973 	QDF_STATUS ret;
11974 	int32_t len;
11975 
11976 	len = sizeof(*cmd);
11977 
11978 	buf = wmi_buf_alloc(wmi_handle, len);
11979 	if (!buf) {
11980 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11981 		return QDF_STATUS_E_FAILURE;
11982 	}
11983 
11984 	cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf);
11985 	WMITLV_SET_HDR(&cmd->tlv_header,
11986 		       WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param,
11987 		       WMITLV_GET_STRUCT_TLVLEN(
11988 				wmi_pdev_dfs_disable_cmd_fixed_param));
11989 	/* Filling it with WMI_PDEV_ID_SOC for now */
11990 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
11991 							WMI_HOST_PDEV_ID_SOC);
11992 
11993 	wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0);
11994 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11995 			WMI_PDEV_DFS_DISABLE_CMDID);
11996 
11997 	if (ret != 0) {
11998 		WMI_LOGE("Sending PDEV DFS disable cmd failed\n");
11999 		wmi_buf_free(buf);
12000 	}
12001 
12002 	return ret;
12003 }
12004 
12005 /**
12006  *  send_phyerr_enable_cmd_tlv() - WMI phyerr disable function
12007  *
12008  *  @param wmi_handle     : handle to WMI.
12009  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
12010  */
12011 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle)
12012 {
12013 	wmi_pdev_dfs_enable_cmd_fixed_param *cmd;
12014 	wmi_buf_t buf;
12015 	QDF_STATUS ret;
12016 	int32_t len;
12017 
12018 	len = sizeof(*cmd);
12019 
12020 	buf = wmi_buf_alloc(wmi_handle, len);
12021 	if (!buf) {
12022 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12023 		return QDF_STATUS_E_FAILURE;
12024 	}
12025 
12026 	cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf);
12027 	WMITLV_SET_HDR(&cmd->tlv_header,
12028 		       WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param,
12029 		       WMITLV_GET_STRUCT_TLVLEN(
12030 				wmi_pdev_dfs_enable_cmd_fixed_param));
12031 	/* Reserved for future use */
12032 	cmd->reserved0 = 0;
12033 
12034 	wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0);
12035 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
12036 			WMI_PDEV_DFS_ENABLE_CMDID);
12037 
12038 	if (ret != 0) {
12039 		WMI_LOGE("Sending PDEV DFS enable cmd failed\n");
12040 		wmi_buf_free(buf);
12041 	}
12042 
12043 	return ret;
12044 }
12045 
12046 /**
12047  * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd
12048  * to fw
12049  * @wmi_handle: wmi handle
12050  * @param: pointer to hold periodic chan stats param
12051  *
12052  * Return: 0 for success or error code
12053  */
12054 static QDF_STATUS
12055 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle,
12056 				struct periodic_chan_stats_params *param)
12057 {
12058 	wmi_set_periodic_channel_stats_config_fixed_param *cmd;
12059 	wmi_buf_t buf;
12060 	QDF_STATUS ret;
12061 	int32_t len;
12062 
12063 	len = sizeof(*cmd);
12064 
12065 	buf = wmi_buf_alloc(wmi_handle, len);
12066 	if (!buf) {
12067 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12068 		return QDF_STATUS_E_FAILURE;
12069 	}
12070 
12071 	cmd = (wmi_set_periodic_channel_stats_config_fixed_param *)
12072 					wmi_buf_data(buf);
12073 	WMITLV_SET_HDR(&cmd->tlv_header,
12074 	WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param,
12075 		WMITLV_GET_STRUCT_TLVLEN(
12076 		wmi_set_periodic_channel_stats_config_fixed_param));
12077 	cmd->enable = param->enable;
12078 	cmd->stats_period = param->stats_period;
12079 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
12080 						param->pdev_id);
12081 
12082 	wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0);
12083 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
12084 			WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID);
12085 
12086 	if (ret != 0) {
12087 		WMI_LOGE("Sending periodic chan stats config failed");
12088 		wmi_buf_free(buf);
12089 	}
12090 
12091 	return ret;
12092 }
12093 
12094 /**
12095  * send_nf_dbr_dbm_info_get_cmd_tlv() - send request to get nf to fw
12096  * @wmi_handle: wmi handle
12097  * @mac_id: radio context
12098  *
12099  * Return: 0 for success or error code
12100  */
12101 static QDF_STATUS
12102 send_nf_dbr_dbm_info_get_cmd_tlv(wmi_unified_t wmi_handle, uint8_t mac_id)
12103 {
12104 	wmi_buf_t buf;
12105 	QDF_STATUS ret;
12106 	wmi_pdev_get_nfcal_power_fixed_param *cmd;
12107 	int32_t len = sizeof(*cmd);
12108 
12109 	buf = wmi_buf_alloc(wmi_handle, len);
12110 	if (buf == NULL)
12111 		return QDF_STATUS_E_NOMEM;
12112 
12113 	cmd = (wmi_pdev_get_nfcal_power_fixed_param *)wmi_buf_data(buf);
12114 	WMITLV_SET_HDR(&cmd->tlv_header,
12115 		       WMITLV_TAG_STRUC_wmi_pdev_get_nfcal_power_fixed_param,
12116 		       WMITLV_GET_STRUCT_TLVLEN
12117 				(wmi_pdev_get_nfcal_power_fixed_param));
12118 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
12119 
12120 	wmi_mtrace(WMI_PDEV_GET_NFCAL_POWER_CMDID, NO_SESSION, 0);
12121 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12122 				   WMI_PDEV_GET_NFCAL_POWER_CMDID);
12123 	if (ret != 0) {
12124 		WMI_LOGE("Sending get nfcal power cmd failed\n");
12125 		wmi_buf_free(buf);
12126 	}
12127 
12128 	return ret;
12129 }
12130 
12131 /**
12132  * send_set_ht_ie_cmd_tlv() - send ht ie command to fw
12133  * @wmi_handle: wmi handle
12134  * @param: pointer to ht ie param
12135  *
12136  * Return: 0 for success or error code
12137  */
12138 static QDF_STATUS
12139 send_set_ht_ie_cmd_tlv(wmi_unified_t wmi_handle,
12140 		       struct ht_ie_params *param)
12141 {
12142 	wmi_pdev_set_ht_ie_cmd_fixed_param *cmd;
12143 	wmi_buf_t buf;
12144 	QDF_STATUS ret;
12145 	int32_t len;
12146 	uint8_t *buf_ptr;
12147 
12148 	len = sizeof(*cmd)  + WMI_TLV_HDR_SIZE +
12149 	      roundup(param->ie_len, sizeof(uint32_t));
12150 
12151 	buf = wmi_buf_alloc(wmi_handle, len);
12152 	if (!buf) {
12153 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12154 		return QDF_STATUS_E_FAILURE;
12155 	}
12156 
12157 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12158 	cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *)buf_ptr;
12159 	WMITLV_SET_HDR(&cmd->tlv_header,
12160 		       WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param,
12161 		       WMITLV_GET_STRUCT_TLVLEN(
12162 				wmi_pdev_set_ht_ie_cmd_fixed_param));
12163 	cmd->reserved0 = 0;
12164 	cmd->ie_len = param->ie_len;
12165 	cmd->tx_streams = param->tx_streams;
12166 	cmd->rx_streams = param->rx_streams;
12167 
12168 	buf_ptr += sizeof(*cmd);
12169 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len);
12170 	buf_ptr += WMI_TLV_HDR_SIZE;
12171 	if (param->ie_len)
12172 		WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data,
12173 						cmd->ie_len);
12174 
12175 	wmi_mtrace(WMI_PDEV_SET_HT_CAP_IE_CMDID, NO_SESSION, 0);
12176 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12177 				   WMI_PDEV_SET_HT_CAP_IE_CMDID);
12178 
12179 	if (ret != 0) {
12180 		WMI_LOGE("Sending set ht ie cmd failed\n");
12181 		wmi_buf_free(buf);
12182 	}
12183 
12184 	return ret;
12185 }
12186 
12187 /**
12188  * send_set_vht_ie_cmd_tlv() - send vht ie command to fw
12189  * @wmi_handle: wmi handle
12190  * @param: pointer to vht ie param
12191  *
12192  * Return: 0 for success or error code
12193  */
12194 static QDF_STATUS
12195 send_set_vht_ie_cmd_tlv(wmi_unified_t wmi_handle,
12196 			struct vht_ie_params *param)
12197 {
12198 	wmi_pdev_set_vht_ie_cmd_fixed_param *cmd;
12199 	wmi_buf_t buf;
12200 	QDF_STATUS ret;
12201 	int32_t len;
12202 	uint8_t *buf_ptr;
12203 
12204 	len = sizeof(*cmd)  + WMI_TLV_HDR_SIZE +
12205 	      roundup(param->ie_len, sizeof(uint32_t));
12206 
12207 	buf = wmi_buf_alloc(wmi_handle, len);
12208 	if (!buf) {
12209 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12210 		return QDF_STATUS_E_FAILURE;
12211 	}
12212 
12213 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12214 	cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *)buf_ptr;
12215 	WMITLV_SET_HDR(&cmd->tlv_header,
12216 		       WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param,
12217 		       WMITLV_GET_STRUCT_TLVLEN(
12218 				wmi_pdev_set_vht_ie_cmd_fixed_param));
12219 	cmd->reserved0 = 0;
12220 	cmd->ie_len = param->ie_len;
12221 	cmd->tx_streams = param->tx_streams;
12222 	cmd->rx_streams = param->rx_streams;
12223 
12224 	buf_ptr += sizeof(*cmd);
12225 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len);
12226 	buf_ptr += WMI_TLV_HDR_SIZE;
12227 	if (param->ie_len)
12228 		WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data,
12229 						cmd->ie_len);
12230 
12231 	wmi_mtrace(WMI_PDEV_SET_VHT_CAP_IE_CMDID, NO_SESSION, 0);
12232 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12233 				   WMI_PDEV_SET_VHT_CAP_IE_CMDID);
12234 
12235 	if (ret != 0) {
12236 		WMI_LOGE("Sending set vht ie cmd failed\n");
12237 		wmi_buf_free(buf);
12238 	}
12239 
12240 	return ret;
12241 }
12242 
12243 /**
12244  * send_set_quiet_mode_cmd_tlv() - send set quiet mode command to fw
12245  * @wmi_handle: wmi handle
12246  * @param: pointer to quiet mode params
12247  *
12248  * Return: 0 for success or error code
12249  */
12250 static QDF_STATUS
12251 send_set_quiet_mode_cmd_tlv(wmi_unified_t wmi_handle,
12252 			    struct set_quiet_mode_params *param)
12253 {
12254 	wmi_pdev_set_quiet_cmd_fixed_param *quiet_cmd;
12255 	wmi_buf_t buf;
12256 	QDF_STATUS ret;
12257 	int32_t len;
12258 
12259 	len = sizeof(*quiet_cmd);
12260 	buf = wmi_buf_alloc(wmi_handle, len);
12261 	if (!buf) {
12262 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12263 		return QDF_STATUS_E_FAILURE;
12264 	}
12265 
12266 	quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf);
12267 	WMITLV_SET_HDR(&quiet_cmd->tlv_header,
12268 		       WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param,
12269 		       WMITLV_GET_STRUCT_TLVLEN(
12270 				wmi_pdev_set_quiet_cmd_fixed_param));
12271 	quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf);
12272 	quiet_cmd->enabled = param->enabled;
12273 	quiet_cmd->period = (param->period)*(param->intval);
12274 	quiet_cmd->duration = param->duration;
12275 	quiet_cmd->next_start = param->offset;
12276 	quiet_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
12277 							WMI_HOST_PDEV_ID_SOC);
12278 
12279 	wmi_mtrace(WMI_PDEV_SET_QUIET_MODE_CMDID, NO_SESSION, 0);
12280 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12281 				   WMI_PDEV_SET_QUIET_MODE_CMDID);
12282 
12283 	if (ret != 0) {
12284 		WMI_LOGE("Sending set quiet cmd failed\n");
12285 		wmi_buf_free(buf);
12286 	}
12287 
12288 	return ret;
12289 }
12290 
12291 /**
12292  * send_set_bwf_cmd_tlv() - send set bwf command to fw
12293  * @wmi_handle: wmi handle
12294  * @param: pointer to set bwf param
12295  *
12296  * Return: 0 for success or error code
12297  */
12298 static QDF_STATUS
12299 send_set_bwf_cmd_tlv(wmi_unified_t wmi_handle,
12300 		     struct set_bwf_params *param)
12301 {
12302 	wmi_bwf_peer_info *peer_info;
12303 	wmi_peer_bwf_request_fixed_param *cmd;
12304 	wmi_buf_t buf;
12305 	QDF_STATUS retval;
12306 	int32_t len;
12307 	uint8_t *buf_ptr;
12308 	int i;
12309 
12310 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
12311 	len += param->num_peers * sizeof(wmi_bwf_peer_info);
12312 	buf = wmi_buf_alloc(wmi_handle, len);
12313 	if (!buf) {
12314 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
12315 		return QDF_STATUS_E_FAILURE;
12316 	}
12317 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12318 	cmd = (wmi_peer_bwf_request_fixed_param *)buf_ptr;
12319 	WMITLV_SET_HDR(&cmd->tlv_header,
12320 		       WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param,
12321 		       WMITLV_GET_STRUCT_TLVLEN(
12322 				wmi_peer_bwf_request_fixed_param));
12323 	cmd->num_peers = param->num_peers;
12324 
12325 	buf_ptr += sizeof(*cmd);
12326 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
12327 		       sizeof(wmi_bwf_peer_info) *
12328 		       cmd->num_peers);
12329 	buf_ptr += WMI_TLV_HDR_SIZE;
12330 	peer_info = (wmi_bwf_peer_info *)buf_ptr;
12331 
12332 	for (i = 0; i < cmd->num_peers; i++) {
12333 		WMITLV_SET_HDR(&peer_info->tlv_header,
12334 			       WMITLV_TAG_STRUC_wmi_bwf_peer_info,
12335 			       WMITLV_GET_STRUCT_TLVLEN(wmi_bwf_peer_info));
12336 		peer_info->bwf_guaranteed_bandwidth =
12337 				param->peer_info[i].throughput;
12338 		peer_info->bwf_max_airtime =
12339 				param->peer_info[i].max_airtime;
12340 		peer_info->bwf_peer_priority =
12341 				param->peer_info[i].priority;
12342 		qdf_mem_copy(&peer_info->peer_macaddr,
12343 			     &param->peer_info[i].peer_macaddr,
12344 			     sizeof(param->peer_info[i].peer_macaddr));
12345 		peer_info->vdev_id =
12346 				param->peer_info[i].vdev_id;
12347 		peer_info->pdev_id =
12348 			wmi_handle->ops->convert_pdev_id_host_to_target(
12349 				param->peer_info[i].pdev_id);
12350 		peer_info++;
12351 	}
12352 
12353 	wmi_mtrace(WMI_PEER_BWF_REQUEST_CMDID, NO_SESSION, 0);
12354 	retval = wmi_unified_cmd_send(wmi_handle, buf, len,
12355 				      WMI_PEER_BWF_REQUEST_CMDID);
12356 
12357 	if (retval != QDF_STATUS_SUCCESS) {
12358 		WMI_LOGE("%s : WMI Failed\n", __func__);
12359 		wmi_buf_free(buf);
12360 	}
12361 
12362 	return retval;
12363 }
12364 
12365 /**
12366  * send_mcast_group_update_cmd_tlv() - send mcast group update cmd to fw
12367  * @wmi_handle: wmi handle
12368  * @param: pointer to hold mcast update param
12369  *
12370  * Return: 0 for success or error code
12371  */
12372 static QDF_STATUS
12373 send_mcast_group_update_cmd_tlv(wmi_unified_t wmi_handle,
12374 				struct mcast_group_update_params *param)
12375 {
12376 	wmi_peer_mcast_group_cmd_fixed_param *cmd;
12377 	wmi_buf_t buf;
12378 	QDF_STATUS ret;
12379 	int32_t len;
12380 	int offset = 0;
12381 	static char dummymask[4] = { 0xFF, 0xFF, 0xFF, 0xFF};
12382 
12383 	len = sizeof(*cmd);
12384 	buf = wmi_buf_alloc(wmi_handle, len);
12385 	if (!buf) {
12386 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12387 		return QDF_STATUS_E_FAILURE;
12388 	}
12389 	cmd = (wmi_peer_mcast_group_cmd_fixed_param *)wmi_buf_data(buf);
12390 	WMITLV_SET_HDR(&cmd->tlv_header,
12391 		       WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param,
12392 		       WMITLV_GET_STRUCT_TLVLEN(
12393 				wmi_peer_mcast_group_cmd_fixed_param));
12394 	/* confirm the buffer is 4-byte aligned */
12395 	QDF_ASSERT((((size_t) cmd) & 0x3) == 0);
12396 	qdf_mem_zero(cmd, sizeof(*cmd));
12397 
12398 	cmd->vdev_id = param->vap_id;
12399 	/* construct the message assuming our endianness matches the target */
12400 	cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_ACTION_M &
12401 		(param->action << WMI_PEER_MCAST_GROUP_FLAG_ACTION_S);
12402 	cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M &
12403 		(param->wildcard << WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S);
12404 	if (param->is_action_delete)
12405 		cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_DELETEALL_M;
12406 
12407 	if (param->is_mcast_addr_len)
12408 		cmd->flags |=  WMI_PEER_MCAST_GROUP_FLAG_IPV6_M;
12409 
12410 	if (param->is_filter_mode_snoop)
12411 		cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_SRC_FILTER_EXCLUDE_M;
12412 
12413 	/* unicast address spec only applies for non-wildcard cases */
12414 	if (!param->wildcard && param->ucast_mac_addr) {
12415 		WMI_CHAR_ARRAY_TO_MAC_ADDR(param->ucast_mac_addr,
12416 					   &cmd->ucast_mac_addr);
12417 	}
12418 
12419 	if (param->mcast_ip_addr) {
12420 		QDF_ASSERT(param->mcast_ip_addr_bytes <=
12421 			   sizeof(cmd->mcast_ip_addr));
12422 		offset = sizeof(cmd->mcast_ip_addr) -
12423 			 param->mcast_ip_addr_bytes;
12424 		qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_addr) + offset,
12425 			     param->mcast_ip_addr,
12426 			     param->mcast_ip_addr_bytes);
12427 	}
12428 	if (!param->mask)
12429 		param->mask = &dummymask[0];
12430 
12431 	qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_mask) + offset,
12432 		     param->mask,
12433 		     param->mcast_ip_addr_bytes);
12434 
12435 	if (param->srcs && param->nsrcs) {
12436 		cmd->num_filter_addr = param->nsrcs;
12437 		QDF_ASSERT((param->nsrcs * param->mcast_ip_addr_bytes) <=
12438 			sizeof(cmd->filter_addr));
12439 
12440 		qdf_mem_copy(((uint8_t *) &cmd->filter_addr), param->srcs,
12441 			     param->nsrcs * param->mcast_ip_addr_bytes);
12442 	}
12443 
12444 	wmi_mtrace(WMI_PEER_MCAST_GROUP_CMDID, cmd->vdev_id, 0);
12445 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12446 				      WMI_PEER_MCAST_GROUP_CMDID);
12447 
12448 	if (ret != QDF_STATUS_SUCCESS) {
12449 		WMI_LOGE("%s : WMI Failed\n", __func__);
12450 		wmi_buf_free(buf);
12451 	}
12452 
12453 	return ret;
12454 }
12455 
12456 /**
12457  * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure
12458  * command to fw
12459  * @wmi_handle: wmi handle
12460  * @param: pointer to hold spectral config parameter
12461  *
12462  * Return: 0 for success or error code
12463  */
12464 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle,
12465 				struct vdev_spectral_configure_params *param)
12466 {
12467 	wmi_vdev_spectral_configure_cmd_fixed_param *cmd;
12468 	wmi_buf_t buf;
12469 	QDF_STATUS ret;
12470 	int32_t len;
12471 
12472 	len = sizeof(*cmd);
12473 	buf = wmi_buf_alloc(wmi_handle, len);
12474 	if (!buf) {
12475 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12476 		return QDF_STATUS_E_FAILURE;
12477 	}
12478 
12479 	cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf);
12480 	WMITLV_SET_HDR(&cmd->tlv_header,
12481 		WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param,
12482 		WMITLV_GET_STRUCT_TLVLEN(
12483 		wmi_vdev_spectral_configure_cmd_fixed_param));
12484 
12485 	cmd->vdev_id = param->vdev_id;
12486 	cmd->spectral_scan_count = param->count;
12487 	cmd->spectral_scan_period = param->period;
12488 	cmd->spectral_scan_priority = param->spectral_pri;
12489 	cmd->spectral_scan_fft_size = param->fft_size;
12490 	cmd->spectral_scan_gc_ena = param->gc_enable;
12491 	cmd->spectral_scan_restart_ena = param->restart_enable;
12492 	cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref;
12493 	cmd->spectral_scan_init_delay = param->init_delay;
12494 	cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr;
12495 	cmd->spectral_scan_str_bin_thr = param->str_bin_thr;
12496 	cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode;
12497 	cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode;
12498 	cmd->spectral_scan_rssi_thr = param->rssi_thr;
12499 	cmd->spectral_scan_pwr_format = param->pwr_format;
12500 	cmd->spectral_scan_rpt_mode = param->rpt_mode;
12501 	cmd->spectral_scan_bin_scale = param->bin_scale;
12502 	cmd->spectral_scan_dBm_adj = param->dbm_adj;
12503 	cmd->spectral_scan_chn_mask = param->chn_mask;
12504 
12505 	wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0);
12506 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12507 				   WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID);
12508 
12509 	if (ret != 0) {
12510 		WMI_LOGE("Sending set quiet cmd failed\n");
12511 		wmi_buf_free(buf);
12512 	}
12513 
12514 	WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID\n",
12515 		 __func__);
12516 
12517 	WMI_LOGI("vdev_id = %u\n"
12518 		 "spectral_scan_count = %u\n"
12519 		 "spectral_scan_period = %u\n"
12520 		 "spectral_scan_priority = %u\n"
12521 		 "spectral_scan_fft_size = %u\n"
12522 		 "spectral_scan_gc_ena = %u\n"
12523 		 "spectral_scan_restart_ena = %u\n"
12524 		 "spectral_scan_noise_floor_ref = %u\n"
12525 		 "spectral_scan_init_delay = %u\n"
12526 		 "spectral_scan_nb_tone_thr = %u\n"
12527 		 "spectral_scan_str_bin_thr = %u\n"
12528 		 "spectral_scan_wb_rpt_mode = %u\n"
12529 		 "spectral_scan_rssi_rpt_mode = %u\n"
12530 		 "spectral_scan_rssi_thr = %u\n"
12531 		 "spectral_scan_pwr_format = %u\n"
12532 		 "spectral_scan_rpt_mode = %u\n"
12533 		 "spectral_scan_bin_scale = %u\n"
12534 		 "spectral_scan_dBm_adj = %u\n"
12535 		 "spectral_scan_chn_mask = %u\n",
12536 		 param->vdev_id,
12537 		 param->count,
12538 		 param->period,
12539 		 param->spectral_pri,
12540 		 param->fft_size,
12541 		 param->gc_enable,
12542 		 param->restart_enable,
12543 		 param->noise_floor_ref,
12544 		 param->init_delay,
12545 		 param->nb_tone_thr,
12546 		 param->str_bin_thr,
12547 		 param->wb_rpt_mode,
12548 		 param->rssi_rpt_mode,
12549 		 param->rssi_thr,
12550 		 param->pwr_format,
12551 		 param->rpt_mode,
12552 		 param->bin_scale,
12553 		 param->dbm_adj,
12554 		 param->chn_mask);
12555 	WMI_LOGI("%s: Status: %d\n\n", __func__, ret);
12556 
12557 	return ret;
12558 }
12559 
12560 /**
12561  * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure
12562  * command to fw
12563  * @wmi_handle: wmi handle
12564  * @param: pointer to hold spectral enable parameter
12565  *
12566  * Return: 0 for success or error code
12567  */
12568 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle,
12569 				struct vdev_spectral_enable_params *param)
12570 {
12571 	wmi_vdev_spectral_enable_cmd_fixed_param *cmd;
12572 	wmi_buf_t buf;
12573 	QDF_STATUS ret;
12574 	int32_t len;
12575 
12576 	len = sizeof(*cmd);
12577 	buf = wmi_buf_alloc(wmi_handle, len);
12578 	if (!buf) {
12579 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12580 		return QDF_STATUS_E_FAILURE;
12581 	}
12582 
12583 	cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf);
12584 	WMITLV_SET_HDR(&cmd->tlv_header,
12585 		WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param,
12586 		WMITLV_GET_STRUCT_TLVLEN(
12587 		wmi_vdev_spectral_enable_cmd_fixed_param));
12588 
12589 	cmd->vdev_id = param->vdev_id;
12590 
12591 	if (param->active_valid) {
12592 		cmd->trigger_cmd = param->active ? 1 : 2;
12593 		/* 1: Trigger, 2: Clear Trigger */
12594 	} else {
12595 		cmd->trigger_cmd = 0; /* 0: Ignore */
12596 	}
12597 
12598 	if (param->enabled_valid) {
12599 		cmd->enable_cmd = param->enabled ? 1 : 2;
12600 		/* 1: Enable 2: Disable */
12601 	} else {
12602 		cmd->enable_cmd = 0; /* 0: Ignore */
12603 	}
12604 
12605 	wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0);
12606 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12607 				   WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID);
12608 
12609 	if (ret != 0) {
12610 		WMI_LOGE("Sending scan enable CMD failed\n");
12611 		wmi_buf_free(buf);
12612 	}
12613 
12614 	WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID\n", __func__);
12615 
12616 	WMI_LOGI("vdev_id = %u\n"
12617 				 "trigger_cmd = %u\n"
12618 				 "enable_cmd = %u\n",
12619 				 cmd->vdev_id,
12620 				 cmd->trigger_cmd,
12621 				 cmd->enable_cmd);
12622 
12623 	WMI_LOGI("%s: Status: %d\n\n", __func__, ret);
12624 
12625 	return ret;
12626 }
12627 
12628 /**
12629  * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params
12630  * @param wmi_handle : handle to WMI.
12631  * @param param : pointer to hold thermal mitigation param
12632  *
12633  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
12634  */
12635 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv(
12636 		wmi_unified_t wmi_handle,
12637 		struct thermal_mitigation_params *param)
12638 {
12639 	wmi_therm_throt_config_request_fixed_param *tt_conf = NULL;
12640 	wmi_therm_throt_level_config_info *lvl_conf = NULL;
12641 	wmi_buf_t buf = NULL;
12642 	uint8_t *buf_ptr = NULL;
12643 	int error;
12644 	int32_t len;
12645 	int i;
12646 
12647 	len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE +
12648 			THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info);
12649 
12650 	buf = wmi_buf_alloc(wmi_handle, len);
12651 	if (!buf) {
12652 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
12653 		return QDF_STATUS_E_NOMEM;
12654 	}
12655 	tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf);
12656 
12657 	/* init fixed params */
12658 	WMITLV_SET_HDR(tt_conf,
12659 		WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param,
12660 		(WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param)));
12661 
12662 	tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
12663 								param->pdev_id);
12664 	tt_conf->enable = param->enable;
12665 	tt_conf->dc = param->dc;
12666 	tt_conf->dc_per_event = param->dc_per_event;
12667 	tt_conf->therm_throt_levels = THERMAL_LEVELS;
12668 
12669 	buf_ptr = (uint8_t *) ++tt_conf;
12670 	/* init TLV params */
12671 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
12672 			(THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info)));
12673 
12674 	lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr +  WMI_TLV_HDR_SIZE);
12675 	for (i = 0; i < THERMAL_LEVELS; i++) {
12676 		WMITLV_SET_HDR(&lvl_conf->tlv_header,
12677 			WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info,
12678 			WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info));
12679 		lvl_conf->temp_lwm = param->levelconf[i].tmplwm;
12680 		lvl_conf->temp_hwm = param->levelconf[i].tmphwm;
12681 		lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent;
12682 		lvl_conf->prio = param->levelconf[i].priority;
12683 		lvl_conf++;
12684 	}
12685 
12686 	wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0);
12687 	error = wmi_unified_cmd_send(wmi_handle, buf, len,
12688 			WMI_THERM_THROT_SET_CONF_CMDID);
12689 	if (QDF_IS_STATUS_ERROR(error)) {
12690 		wmi_buf_free(buf);
12691 		WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command");
12692 	}
12693 
12694 	return error;
12695 }
12696 
12697 /**
12698  * send_pdev_qvit_cmd_tlv() - send qvit command to fw
12699  * @wmi_handle: wmi handle
12700  * @param: pointer to pdev_qvit_params
12701  *
12702  * Return: 0 for success or error code
12703  */
12704 static QDF_STATUS
12705 send_pdev_qvit_cmd_tlv(wmi_unified_t wmi_handle,
12706 		       struct pdev_qvit_params *param)
12707 {
12708 	wmi_buf_t buf;
12709 	QDF_STATUS ret = QDF_STATUS_E_INVAL;
12710 	uint8_t *cmd;
12711 	static uint8_t msgref = 1;
12712 	uint8_t segnumber = 0, seginfo, numsegments;
12713 	uint16_t chunk_len, total_bytes;
12714 	uint8_t *bufpos;
12715 	QVIT_SEG_HDR_INFO_STRUCT seghdrinfo;
12716 
12717 	bufpos = param->utf_payload;
12718 	total_bytes = param->len;
12719 	ASSERT(total_bytes / MAX_WMI_QVIT_LEN ==
12720 	       (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN));
12721 	numsegments = (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN);
12722 
12723 	if (param->len - (numsegments * MAX_WMI_QVIT_LEN))
12724 		numsegments++;
12725 
12726 	while (param->len) {
12727 		if (param->len > MAX_WMI_QVIT_LEN)
12728 			chunk_len = MAX_WMI_QVIT_LEN;    /* MAX message */
12729 		else
12730 			chunk_len = param->len;
12731 
12732 		buf = wmi_buf_alloc(wmi_handle,
12733 				    (chunk_len + sizeof(seghdrinfo) +
12734 				     WMI_TLV_HDR_SIZE));
12735 		if (!buf) {
12736 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
12737 			return QDF_STATUS_E_NOMEM;
12738 		}
12739 
12740 		cmd = (uint8_t *) wmi_buf_data(buf);
12741 
12742 		seghdrinfo.len = total_bytes;
12743 		seghdrinfo.msgref = msgref;
12744 		seginfo = ((numsegments << 4) & 0xF0) | (segnumber & 0xF);
12745 		seghdrinfo.segmentInfo = seginfo;
12746 
12747 		segnumber++;
12748 
12749 		WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE,
12750 			       (chunk_len + sizeof(seghdrinfo)));
12751 		cmd += WMI_TLV_HDR_SIZE;
12752 		qdf_mem_copy(cmd, &seghdrinfo, sizeof(seghdrinfo));
12753 		qdf_mem_copy(&cmd[sizeof(seghdrinfo)], bufpos, chunk_len);
12754 
12755 		wmi_mtrace(WMI_PDEV_QVIT_CMDID, NO_SESSION, 0);
12756 		ret = wmi_unified_cmd_send(wmi_handle, buf,
12757 					   (chunk_len + sizeof(seghdrinfo) +
12758 					    WMI_TLV_HDR_SIZE),
12759 					   WMI_PDEV_QVIT_CMDID);
12760 
12761 		if (ret != 0) {
12762 			WMI_LOGE("Failed to send WMI_PDEV_QVIT_CMDID command");
12763 			wmi_buf_free(buf);
12764 			break;
12765 		}
12766 
12767 		param->len -= chunk_len;
12768 		bufpos += chunk_len;
12769 	}
12770 	msgref++;
12771 
12772 	return ret;
12773 }
12774 
12775 /**
12776  * send_wmm_update_cmd_tlv() - send wmm update command to fw
12777  * @wmi_handle: wmi handle
12778  * @param: pointer to wmm update param
12779  *
12780  * Return: 0 for success or error code
12781  */
12782 static QDF_STATUS
12783 send_wmm_update_cmd_tlv(wmi_unified_t wmi_handle,
12784 			struct wmm_update_params *param)
12785 {
12786 	wmi_pdev_set_wmm_params_cmd_fixed_param *cmd;
12787 	wmi_wmm_params *wmm_param;
12788 	wmi_buf_t buf;
12789 	QDF_STATUS ret;
12790 	int32_t len;
12791 	int ac = 0;
12792 	struct wmi_host_wmeParams *wmep;
12793 	uint8_t *buf_ptr;
12794 
12795 	len = sizeof(*cmd) + (WME_NUM_AC * sizeof(*wmm_param));
12796 	buf = wmi_buf_alloc(wmi_handle, len);
12797 	if (!buf) {
12798 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12799 		return QDF_STATUS_E_FAILURE;
12800 	}
12801 
12802 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
12803 	cmd = (wmi_pdev_set_wmm_params_cmd_fixed_param *) buf_ptr;
12804 	WMITLV_SET_HDR(&cmd->tlv_header,
12805 		       WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param,
12806 		       WMITLV_GET_STRUCT_TLVLEN
12807 			       (wmi_pdev_set_wmm_params_cmd_fixed_param));
12808 
12809 	cmd->reserved0 = WMI_HOST_PDEV_ID_SOC;
12810 
12811 	buf_ptr += sizeof(wmi_pdev_set_wmm_params_cmd_fixed_param);
12812 
12813 	for (ac = 0; ac < WME_NUM_AC; ac++) {
12814 		wmep = &param->wmep_array[ac];
12815 		wmm_param = (wmi_wmm_params *)buf_ptr;
12816 		WMITLV_SET_HDR(&wmm_param->tlv_header,
12817 			WMITLV_TAG_STRUC_wmi_wmm_params,
12818 			WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params));
12819 		wmm_param->aifs = wmep->wmep_aifsn;
12820 		wmm_param->cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
12821 		wmm_param->cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
12822 		wmm_param->txoplimit = ATH_TXOP_TO_US(wmep->wmep_txopLimit);
12823 		wmm_param->acm = wmep->wmep_acm;
12824 		wmm_param->no_ack = wmep->wmep_noackPolicy;
12825 		buf_ptr += sizeof(wmi_wmm_params);
12826 	}
12827 	wmi_mtrace(WMI_PDEV_SET_WMM_PARAMS_CMDID, NO_SESSION, 0);
12828 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12829 				   WMI_PDEV_SET_WMM_PARAMS_CMDID);
12830 
12831 	if (ret != 0) {
12832 		WMI_LOGE("Sending WMM update CMD failed\n");
12833 		wmi_buf_free(buf);
12834 	}
12835 
12836 	return ret;
12837 }
12838 
12839 /**
12840  * send_coex_config_cmd_tlv() - send coex config command to fw
12841  * @wmi_handle: wmi handle
12842  * @param: pointer to coex config param
12843  *
12844  * Return: 0 for success or error code
12845  */
12846 static QDF_STATUS
12847 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle,
12848 			 struct coex_config_params *param)
12849 {
12850 	WMI_COEX_CONFIG_CMD_fixed_param *cmd;
12851 	wmi_buf_t buf;
12852 	QDF_STATUS ret;
12853 	int32_t len;
12854 
12855 	len = sizeof(*cmd);
12856 	buf = wmi_buf_alloc(wmi_handle, len);
12857 	if (!buf) {
12858 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12859 		return QDF_STATUS_E_FAILURE;
12860 	}
12861 
12862 	cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf);
12863 	WMITLV_SET_HDR(&cmd->tlv_header,
12864 		       WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param,
12865 		       WMITLV_GET_STRUCT_TLVLEN(
12866 		       WMI_COEX_CONFIG_CMD_fixed_param));
12867 
12868 	cmd->vdev_id = param->vdev_id;
12869 	cmd->config_type = param->config_type;
12870 	cmd->config_arg1 = param->config_arg1;
12871 	cmd->config_arg2 = param->config_arg2;
12872 	cmd->config_arg3 = param->config_arg3;
12873 	cmd->config_arg4 = param->config_arg4;
12874 	cmd->config_arg5 = param->config_arg5;
12875 	cmd->config_arg6 = param->config_arg6;
12876 
12877 	wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0);
12878 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12879 				   WMI_COEX_CONFIG_CMDID);
12880 
12881 	if (ret != 0) {
12882 		WMI_LOGE("Sending COEX CONFIG CMD failed\n");
12883 		wmi_buf_free(buf);
12884 	}
12885 
12886 	return ret;
12887 }
12888 
12889 
12890 #ifdef WLAN_SUPPORT_TWT
12891 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg,
12892 					target_resource_config *tgt_res_cfg)
12893 {
12894 	resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count;
12895 	resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count;
12896 }
12897 #else
12898 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg,
12899 					target_resource_config *tgt_res_cfg)
12900 {
12901 	resource_cfg->twt_ap_pdev_count = 0;
12902 	resource_cfg->twt_ap_sta_count = 0;
12903 }
12904 #endif
12905 
12906 static
12907 void wmi_copy_resource_config(wmi_resource_config *resource_cfg,
12908 				target_resource_config *tgt_res_cfg)
12909 {
12910 	resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs;
12911 	resource_cfg->num_peers = tgt_res_cfg->num_peers;
12912 	resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers;
12913 	resource_cfg->num_offload_reorder_buffs =
12914 			tgt_res_cfg->num_offload_reorder_buffs;
12915 	resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys;
12916 	resource_cfg->num_tids = tgt_res_cfg->num_tids;
12917 	resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit;
12918 	resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask;
12919 	resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask;
12920 	resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0];
12921 	resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1];
12922 	resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2];
12923 	resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3];
12924 	resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode;
12925 	resource_cfg->scan_max_pending_req =
12926 			tgt_res_cfg->scan_max_pending_req;
12927 	resource_cfg->bmiss_offload_max_vdev =
12928 			tgt_res_cfg->bmiss_offload_max_vdev;
12929 	resource_cfg->roam_offload_max_vdev =
12930 			tgt_res_cfg->roam_offload_max_vdev;
12931 	resource_cfg->roam_offload_max_ap_profiles =
12932 			tgt_res_cfg->roam_offload_max_ap_profiles;
12933 	resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups;
12934 	resource_cfg->num_mcast_table_elems =
12935 			tgt_res_cfg->num_mcast_table_elems;
12936 	resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode;
12937 	resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size;
12938 	resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries;
12939 	resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size;
12940 	resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim;
12941 	resource_cfg->rx_skip_defrag_timeout_dup_detection_check =
12942 		tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check;
12943 	resource_cfg->vow_config = tgt_res_cfg->vow_config;
12944 	resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev;
12945 	resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc;
12946 	resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries;
12947 	resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs;
12948 	resource_cfg->num_tdls_conn_table_entries =
12949 			tgt_res_cfg->num_tdls_conn_table_entries;
12950 	resource_cfg->beacon_tx_offload_max_vdev =
12951 			tgt_res_cfg->beacon_tx_offload_max_vdev;
12952 	resource_cfg->num_multicast_filter_entries =
12953 			tgt_res_cfg->num_multicast_filter_entries;
12954 	resource_cfg->num_wow_filters =
12955 			tgt_res_cfg->num_wow_filters;
12956 	resource_cfg->num_keep_alive_pattern =
12957 			tgt_res_cfg->num_keep_alive_pattern;
12958 	resource_cfg->keep_alive_pattern_size =
12959 			tgt_res_cfg->keep_alive_pattern_size;
12960 	resource_cfg->max_tdls_concurrent_sleep_sta =
12961 			tgt_res_cfg->max_tdls_concurrent_sleep_sta;
12962 	resource_cfg->max_tdls_concurrent_buffer_sta =
12963 			tgt_res_cfg->max_tdls_concurrent_buffer_sta;
12964 	resource_cfg->wmi_send_separate =
12965 			tgt_res_cfg->wmi_send_separate;
12966 	resource_cfg->num_ocb_vdevs =
12967 			tgt_res_cfg->num_ocb_vdevs;
12968 	resource_cfg->num_ocb_channels =
12969 			tgt_res_cfg->num_ocb_channels;
12970 	resource_cfg->num_ocb_schedules =
12971 			tgt_res_cfg->num_ocb_schedules;
12972 	resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size;
12973 	resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters;
12974 	resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id;
12975 	resource_cfg->max_num_dbs_scan_duty_cycle =
12976 		tgt_res_cfg->max_num_dbs_scan_duty_cycle;
12977 	resource_cfg->sched_params = tgt_res_cfg->scheduler_params;
12978 	resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters;
12979 	resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs;
12980 	resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator;
12981 	if (tgt_res_cfg->atf_config)
12982 		WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1);
12983 	if (tgt_res_cfg->mgmt_comp_evt_bundle_support)
12984 		WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET(
12985 			resource_cfg->flag1, 1);
12986 	if (tgt_res_cfg->tx_msdu_new_partition_id_support)
12987 		WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET(
12988 			resource_cfg->flag1, 1);
12989 	if (tgt_res_cfg->cce_disable)
12990 		WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1);
12991 
12992 	wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg);
12993 	resource_cfg->peer_map_unmap_v2_support =
12994 		tgt_res_cfg->peer_map_unmap_v2;
12995 }
12996 
12997 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd
12998  * @wmi_handle: pointer to wmi handle
12999  * @buf_ptr: pointer to current position in init command buffer
13000  * @len: pointer to length. This will be updated with current length of cmd
13001  * @param: point host parameters for init command
13002  *
13003  * Return: Updated pointer of buf_ptr.
13004  */
13005 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle,
13006 		uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param)
13007 {
13008 	uint16_t idx;
13009 
13010 	if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) {
13011 		wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode;
13012 		wmi_pdev_band_to_mac *band_to_mac;
13013 
13014 		hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *)
13015 			(buf_ptr + sizeof(wmi_init_cmd_fixed_param) +
13016 			 sizeof(wmi_resource_config) +
13017 			 WMI_TLV_HDR_SIZE + (param->num_mem_chunks *
13018 				 sizeof(wlan_host_memory_chunk)));
13019 
13020 		WMITLV_SET_HDR(&hw_mode->tlv_header,
13021 			WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param,
13022 			(WMITLV_GET_STRUCT_TLVLEN
13023 			 (wmi_pdev_set_hw_mode_cmd_fixed_param)));
13024 
13025 		hw_mode->hw_mode_index = param->hw_mode_id;
13026 		hw_mode->num_band_to_mac = param->num_band_to_mac;
13027 
13028 		buf_ptr = (uint8_t *) (hw_mode + 1);
13029 		band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr +
13030 				WMI_TLV_HDR_SIZE);
13031 		for (idx = 0; idx < param->num_band_to_mac; idx++) {
13032 			WMITLV_SET_HDR(&band_to_mac[idx].tlv_header,
13033 					WMITLV_TAG_STRUC_wmi_pdev_band_to_mac,
13034 					WMITLV_GET_STRUCT_TLVLEN
13035 					(wmi_pdev_band_to_mac));
13036 			band_to_mac[idx].pdev_id =
13037 				wmi_handle->ops->convert_pdev_id_host_to_target(
13038 					param->band_to_mac[idx].pdev_id);
13039 			band_to_mac[idx].start_freq =
13040 				param->band_to_mac[idx].start_freq;
13041 			band_to_mac[idx].end_freq =
13042 				param->band_to_mac[idx].end_freq;
13043 		}
13044 		*len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) +
13045 			(param->num_band_to_mac *
13046 			 sizeof(wmi_pdev_band_to_mac)) +
13047 			WMI_TLV_HDR_SIZE;
13048 
13049 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
13050 				(param->num_band_to_mac *
13051 				 sizeof(wmi_pdev_band_to_mac)));
13052 	}
13053 
13054 	return buf_ptr;
13055 }
13056 
13057 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle,
13058 		wmi_init_cmd_fixed_param *cmd)
13059 {
13060 	int num_whitelist;
13061 	wmi_abi_version my_vers;
13062 
13063 	num_whitelist = sizeof(version_whitelist) /
13064 		sizeof(wmi_whitelist_version_info);
13065 	my_vers.abi_version_0 = WMI_ABI_VERSION_0;
13066 	my_vers.abi_version_1 = WMI_ABI_VERSION_1;
13067 	my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0;
13068 	my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1;
13069 	my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2;
13070 	my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3;
13071 
13072 	wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist,
13073 			&my_vers,
13074 			(struct _wmi_abi_version *)&wmi_handle->fw_abi_version,
13075 			&cmd->host_abi_vers);
13076 
13077 	qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x",
13078 			__func__,
13079 			WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0),
13080 			WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0),
13081 			cmd->host_abi_vers.abi_version_ns_0,
13082 			cmd->host_abi_vers.abi_version_ns_1,
13083 			cmd->host_abi_vers.abi_version_ns_2,
13084 			cmd->host_abi_vers.abi_version_ns_3);
13085 
13086 	/* Save version sent from host -
13087 	 * Will be used to check ready event
13088 	 */
13089 	qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers,
13090 			sizeof(wmi_abi_version));
13091 }
13092 
13093 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf)
13094 {
13095 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
13096 	wmi_service_ready_event_fixed_param *ev;
13097 
13098 
13099 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
13100 
13101 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
13102 	if (!ev)
13103 		return QDF_STATUS_E_FAILURE;
13104 
13105 	/*Save fw version from service ready message */
13106 	/*This will be used while sending INIT message */
13107 	qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
13108 			sizeof(wmi_handle->fw_abi_version));
13109 
13110 	return QDF_STATUS_SUCCESS;
13111 }
13112 
13113 /**
13114  * wmi_unified_save_fw_version_cmd() - save fw version
13115  * @wmi_handle:      pointer to wmi handle
13116  * @res_cfg:         resource config
13117  * @num_mem_chunks:  no of mem chunck
13118  * @mem_chunk:       pointer to mem chunck structure
13119  *
13120  * This function sends IE information to firmware
13121  *
13122  * Return: QDF_STATUS_SUCCESS for success otherwise failure
13123  *
13124  */
13125 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle,
13126 					  void *evt_buf)
13127 {
13128 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
13129 	wmi_ready_event_fixed_param *ev = NULL;
13130 
13131 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
13132 	ev = param_buf->fixed_param;
13133 	if (!wmi_versions_are_compatible((struct _wmi_abi_version *)
13134 				&wmi_handle->final_abi_vers,
13135 				&ev->fw_abi_vers)) {
13136 		/*
13137 		 * Error: Our host version and the given firmware version
13138 		 * are incompatible.
13139 		 **/
13140 		WMI_LOGD("%s: Error: Incompatible WMI version."
13141 			"Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n",
13142 				__func__,
13143 			WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers.
13144 				abi_version_0),
13145 			WMI_VER_GET_MINOR(wmi_handle->final_abi_vers.
13146 				abi_version_0),
13147 			wmi_handle->final_abi_vers.abi_version_ns_0,
13148 			wmi_handle->final_abi_vers.abi_version_ns_1,
13149 			wmi_handle->final_abi_vers.abi_version_ns_2,
13150 			wmi_handle->final_abi_vers.abi_version_ns_3,
13151 			WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0),
13152 			WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0),
13153 			ev->fw_abi_vers.abi_version_ns_0,
13154 			ev->fw_abi_vers.abi_version_ns_1,
13155 			ev->fw_abi_vers.abi_version_ns_2,
13156 			ev->fw_abi_vers.abi_version_ns_3);
13157 
13158 		return QDF_STATUS_E_FAILURE;
13159 	}
13160 	qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers,
13161 			sizeof(wmi_abi_version));
13162 	qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
13163 			sizeof(wmi_abi_version));
13164 
13165 	return QDF_STATUS_SUCCESS;
13166 }
13167 
13168 /**
13169  * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw
13170  * @wmi_handle: wmi handle
13171  * @custom_addr: base mac address
13172  *
13173  * Return: QDF_STATUS_SUCCESS for success or error code
13174  */
13175 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle,
13176 					 uint8_t *custom_addr)
13177 {
13178 	wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd;
13179 	wmi_buf_t buf;
13180 	int err;
13181 
13182 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
13183 	if (!buf) {
13184 		WMI_LOGE("Failed to allocate buffer to send base macaddr cmd");
13185 		return QDF_STATUS_E_NOMEM;
13186 	}
13187 
13188 	cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf);
13189 	qdf_mem_zero(cmd, sizeof(*cmd));
13190 
13191 	WMITLV_SET_HDR(&cmd->tlv_header,
13192 		   WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param,
13193 		       WMITLV_GET_STRUCT_TLVLEN
13194 			       (wmi_pdev_set_base_macaddr_cmd_fixed_param));
13195 	WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr);
13196 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13197 							WMI_HOST_PDEV_ID_SOC);
13198 	wmi_mtrace(WMI_PDEV_SET_BASE_MACADDR_CMDID, NO_SESSION, 0);
13199 	err = wmi_unified_cmd_send(wmi_handle, buf,
13200 				   sizeof(*cmd),
13201 				   WMI_PDEV_SET_BASE_MACADDR_CMDID);
13202 	if (err) {
13203 		WMI_LOGE("Failed to send set_base_macaddr cmd");
13204 		wmi_buf_free(buf);
13205 		return QDF_STATUS_E_FAILURE;
13206 	}
13207 
13208 	return 0;
13209 }
13210 
13211 /**
13212  * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events
13213  * @handle: wmi handle
13214  * @event:  Event received from FW
13215  * @len:    Length of the event
13216  *
13217  * Enables the low frequency events and disables the high frequency
13218  * events. Bit 17 indicates if the event if low/high frequency.
13219  * 1 - high frequency, 0 - low frequency
13220  *
13221  * Return: 0 on successfully enabling/disabling the events
13222  */
13223 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle,
13224 		uint8_t *event,
13225 		uint32_t len)
13226 {
13227 	uint32_t num_of_diag_events_logs;
13228 	wmi_diag_event_log_config_fixed_param *cmd;
13229 	wmi_buf_t buf;
13230 	uint8_t *buf_ptr;
13231 	uint32_t *cmd_args, *evt_args;
13232 	uint32_t buf_len, i;
13233 
13234 	WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf;
13235 	wmi_diag_event_log_supported_event_fixed_params *wmi_event;
13236 
13237 	WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID");
13238 
13239 	param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event;
13240 	if (!param_buf) {
13241 		WMI_LOGE("Invalid log supported event buffer");
13242 		return QDF_STATUS_E_INVAL;
13243 	}
13244 	wmi_event = param_buf->fixed_param;
13245 	num_of_diag_events_logs = wmi_event->num_of_diag_events_logs;
13246 
13247 	if (num_of_diag_events_logs >
13248 	    param_buf->num_diag_events_logs_list) {
13249 		WMI_LOGE("message number of events %d is more than tlv hdr content %d",
13250 			 num_of_diag_events_logs,
13251 			 param_buf->num_diag_events_logs_list);
13252 		return QDF_STATUS_E_INVAL;
13253 	}
13254 
13255 	evt_args = param_buf->diag_events_logs_list;
13256 	if (!evt_args) {
13257 		WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d",
13258 				__func__, num_of_diag_events_logs);
13259 		return QDF_STATUS_E_INVAL;
13260 	}
13261 
13262 	WMI_LOGD("%s: num_of_diag_events_logs=%d",
13263 			__func__, num_of_diag_events_logs);
13264 
13265 	/* Free any previous allocation */
13266 	if (wmi_handle->events_logs_list)
13267 		qdf_mem_free(wmi_handle->events_logs_list);
13268 
13269 	if (num_of_diag_events_logs >
13270 		(WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) {
13271 		WMI_LOGE("%s: excess num of logs:%d", __func__,
13272 			num_of_diag_events_logs);
13273 		QDF_ASSERT(0);
13274 		return QDF_STATUS_E_INVAL;
13275 	}
13276 	/* Store the event list for run time enable/disable */
13277 	wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs *
13278 			sizeof(uint32_t));
13279 	if (!wmi_handle->events_logs_list) {
13280 		WMI_LOGE("%s: event log list memory allocation failed",
13281 				__func__);
13282 		return QDF_STATUS_E_NOMEM;
13283 	}
13284 	wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs;
13285 
13286 	/* Prepare the send buffer */
13287 	buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
13288 		(num_of_diag_events_logs * sizeof(uint32_t));
13289 
13290 	buf = wmi_buf_alloc(wmi_handle, buf_len);
13291 	if (!buf) {
13292 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13293 		qdf_mem_free(wmi_handle->events_logs_list);
13294 		wmi_handle->events_logs_list = NULL;
13295 		return QDF_STATUS_E_NOMEM;
13296 	}
13297 
13298 	cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf);
13299 	buf_ptr = (uint8_t *) cmd;
13300 
13301 	WMITLV_SET_HDR(&cmd->tlv_header,
13302 			WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param,
13303 			WMITLV_GET_STRUCT_TLVLEN(
13304 				wmi_diag_event_log_config_fixed_param));
13305 
13306 	cmd->num_of_diag_events_logs = num_of_diag_events_logs;
13307 
13308 	buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param);
13309 
13310 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
13311 			(num_of_diag_events_logs * sizeof(uint32_t)));
13312 
13313 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
13314 
13315 	/* Populate the events */
13316 	for (i = 0; i < num_of_diag_events_logs; i++) {
13317 		/* Low freq (0) - Enable (1) the event
13318 		 * High freq (1) - Disable (0) the event
13319 		 */
13320 		WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i],
13321 				!(WMI_DIAG_FREQUENCY_GET(evt_args[i])));
13322 		/* Set the event ID */
13323 		WMI_DIAG_ID_SET(cmd_args[i],
13324 				WMI_DIAG_ID_GET(evt_args[i]));
13325 		/* Set the type */
13326 		WMI_DIAG_TYPE_SET(cmd_args[i],
13327 				WMI_DIAG_TYPE_GET(evt_args[i]));
13328 		/* Storing the event/log list in WMI */
13329 		wmi_handle->events_logs_list[i] = evt_args[i];
13330 	}
13331 
13332 	wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0);
13333 	if (wmi_unified_cmd_send(wmi_handle, buf, buf_len,
13334 				WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) {
13335 		WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed",
13336 				__func__);
13337 		wmi_buf_free(buf);
13338 		/* Not clearing events_logs_list, though wmi cmd failed.
13339 		 * Host can still have this list
13340 		 */
13341 		return QDF_STATUS_E_INVAL;
13342 	}
13343 
13344 	return 0;
13345 }
13346 
13347 /**
13348  * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id
13349  * @wmi_handle: wmi handle
13350  * @start_log: Start logging related parameters
13351  *
13352  * Send the command to the FW based on which specific logging of diag
13353  * event/log id can be started/stopped
13354  *
13355  * Return: None
13356  */
13357 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle,
13358 		struct wmi_wifi_start_log *start_log)
13359 {
13360 	wmi_diag_event_log_config_fixed_param *cmd;
13361 	wmi_buf_t buf;
13362 	uint8_t *buf_ptr;
13363 	uint32_t len, count, log_level, i;
13364 	uint32_t *cmd_args;
13365 	uint32_t total_len;
13366 	count = 0;
13367 
13368 	if (!wmi_handle->events_logs_list) {
13369 		WMI_LOGD("%s: Not received event/log list from FW, yet",
13370 			 __func__);
13371 		return QDF_STATUS_E_NOMEM;
13372 	}
13373 	/* total_len stores the number of events where BITS 17 and 18 are set.
13374 	 * i.e., events of high frequency (17) and for extended debugging (18)
13375 	 */
13376 	total_len = 0;
13377 	for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) {
13378 		if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) &&
13379 		    (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i])))
13380 			total_len++;
13381 	}
13382 
13383 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
13384 		(total_len * sizeof(uint32_t));
13385 
13386 	buf = wmi_buf_alloc(wmi_handle, len);
13387 	if (!buf) {
13388 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13389 		return QDF_STATUS_E_NOMEM;
13390 	}
13391 	cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf);
13392 	buf_ptr = (uint8_t *) cmd;
13393 
13394 	WMITLV_SET_HDR(&cmd->tlv_header,
13395 			WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param,
13396 			WMITLV_GET_STRUCT_TLVLEN(
13397 				wmi_diag_event_log_config_fixed_param));
13398 
13399 	cmd->num_of_diag_events_logs = total_len;
13400 
13401 	buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param);
13402 
13403 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
13404 			(total_len * sizeof(uint32_t)));
13405 
13406 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
13407 
13408 	if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE)
13409 		log_level = 1;
13410 	else
13411 		log_level = 0;
13412 
13413 	WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level);
13414 	for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) {
13415 		uint32_t val = wmi_handle->events_logs_list[i];
13416 		if ((WMI_DIAG_FREQUENCY_GET(val)) &&
13417 				(WMI_DIAG_EXT_FEATURE_GET(val))) {
13418 
13419 			WMI_DIAG_ID_SET(cmd_args[count],
13420 					WMI_DIAG_ID_GET(val));
13421 			WMI_DIAG_TYPE_SET(cmd_args[count],
13422 					WMI_DIAG_TYPE_GET(val));
13423 			WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count],
13424 					log_level);
13425 			WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val);
13426 			count++;
13427 		}
13428 	}
13429 
13430 	wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0);
13431 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13432 				WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) {
13433 		WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed",
13434 				__func__);
13435 		wmi_buf_free(buf);
13436 		return QDF_STATUS_E_INVAL;
13437 	}
13438 
13439 	return QDF_STATUS_SUCCESS;
13440 }
13441 
13442 /**
13443  * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW
13444  * @wmi_handle: WMI handle
13445  *
13446  * This function is used to send the flush command to the FW,
13447  * that will flush the fw logs that are residue in the FW
13448  *
13449  * Return: None
13450  */
13451 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle)
13452 {
13453 	wmi_debug_mesg_flush_fixed_param *cmd;
13454 	wmi_buf_t buf;
13455 	int len = sizeof(*cmd);
13456 	QDF_STATUS ret;
13457 
13458 	buf = wmi_buf_alloc(wmi_handle, len);
13459 	if (!buf) {
13460 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
13461 		return QDF_STATUS_E_NOMEM;
13462 	}
13463 
13464 	cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf);
13465 	WMITLV_SET_HDR(&cmd->tlv_header,
13466 			WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param,
13467 			WMITLV_GET_STRUCT_TLVLEN(
13468 				wmi_debug_mesg_flush_fixed_param));
13469 	cmd->reserved0 = 0;
13470 
13471 	wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0);
13472 	ret = wmi_unified_cmd_send(wmi_handle,
13473 			buf,
13474 			len,
13475 			WMI_DEBUG_MESG_FLUSH_CMDID);
13476 	if (QDF_IS_STATUS_ERROR(ret)) {
13477 		WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID");
13478 		wmi_buf_free(buf);
13479 		return QDF_STATUS_E_INVAL;
13480 	}
13481 	WMI_LOGD("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW");
13482 
13483 	return ret;
13484 }
13485 
13486 /**
13487  * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW
13488  * @wmi_handle: wmi handle
13489  * @msg: PCL structure containing the PCL and the number of channels
13490  *
13491  * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
13492  * firmware. The DBS Manager is the consumer of this information in the WLAN
13493  * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
13494  * to migrate to a new channel without host driver involvement. An example of
13495  * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
13496  * manage the channel selection without firmware involvement.
13497  *
13498  * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual
13499  * channel list. The weights corresponds to the channels sent in
13500  * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
13501  * weightage compared to the non PCL channels.
13502  *
13503  * Return: Success if the cmd is sent successfully to the firmware
13504  */
13505 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle,
13506 				struct wmi_pcl_chan_weights *msg)
13507 {
13508 	wmi_pdev_set_pcl_cmd_fixed_param *cmd;
13509 	wmi_buf_t buf;
13510 	uint8_t *buf_ptr;
13511 	uint32_t *cmd_args, i, len;
13512 	uint32_t chan_len;
13513 
13514 	chan_len = msg->saved_num_chan;
13515 
13516 	len = sizeof(*cmd) +
13517 		WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t));
13518 
13519 	buf = wmi_buf_alloc(wmi_handle, len);
13520 	if (!buf) {
13521 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13522 		return QDF_STATUS_E_NOMEM;
13523 	}
13524 
13525 	cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf);
13526 	buf_ptr = (uint8_t *) cmd;
13527 	WMITLV_SET_HDR(&cmd->tlv_header,
13528 		WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param,
13529 		WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param));
13530 
13531 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13532 							WMI_HOST_PDEV_ID_SOC);
13533 	cmd->num_chan = chan_len;
13534 	WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan);
13535 
13536 	buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param);
13537 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
13538 			(chan_len * sizeof(uint32_t)));
13539 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
13540 	for (i = 0; i < chan_len ; i++) {
13541 		cmd_args[i] = msg->weighed_valid_list[i];
13542 		WMI_LOGD("%s: chan:%d weight:%d", __func__,
13543 			msg->saved_chan_list[i], cmd_args[i]);
13544 	}
13545 	wmi_mtrace(WMI_PDEV_SET_PCL_CMDID, NO_SESSION, 0);
13546 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13547 				WMI_PDEV_SET_PCL_CMDID)) {
13548 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__);
13549 		wmi_buf_free(buf);
13550 		return QDF_STATUS_E_FAILURE;
13551 	}
13552 	return QDF_STATUS_SUCCESS;
13553 }
13554 
13555 /**
13556  * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW
13557  * @wmi_handle: wmi handle
13558  * @msg: Structure containing the following parameters
13559  *
13560  * - hw_mode_index: The HW_Mode field is a enumerated type that is selected
13561  * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID.
13562  *
13563  * Provides notification to the WLAN firmware that host driver is requesting a
13564  * HardWare (HW) Mode change. This command is needed to support iHelium in the
13565  * configurations that include the Dual Band Simultaneous (DBS) feature.
13566  *
13567  * Return: Success if the cmd is sent successfully to the firmware
13568  */
13569 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle,
13570 				uint32_t hw_mode_index)
13571 {
13572 	wmi_pdev_set_hw_mode_cmd_fixed_param *cmd;
13573 	wmi_buf_t buf;
13574 	uint32_t len;
13575 
13576 	len = sizeof(*cmd);
13577 
13578 	buf = wmi_buf_alloc(wmi_handle, len);
13579 	if (!buf) {
13580 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13581 		return QDF_STATUS_E_NOMEM;
13582 	}
13583 
13584 	cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf);
13585 	WMITLV_SET_HDR(&cmd->tlv_header,
13586 		WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param,
13587 		WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param));
13588 
13589 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13590 							WMI_HOST_PDEV_ID_SOC);
13591 	cmd->hw_mode_index = hw_mode_index;
13592 	WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index);
13593 
13594 	wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0);
13595 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13596 				WMI_PDEV_SET_HW_MODE_CMDID)) {
13597 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID",
13598 			__func__);
13599 		wmi_buf_free(buf);
13600 		return QDF_STATUS_E_FAILURE;
13601 	}
13602 
13603 	return QDF_STATUS_SUCCESS;
13604 }
13605 
13606 #ifdef WLAN_POLICY_MGR_ENABLE
13607 /**
13608  * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW
13609  * @wmi_handle: wmi handle
13610  * @msg: Dual MAC config parameters
13611  *
13612  * Configures WLAN firmware with the dual MAC features
13613  *
13614  * Return: QDF_STATUS. 0 on success.
13615  */
13616 static
13617 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle,
13618 		struct policy_mgr_dual_mac_config *msg)
13619 {
13620 	wmi_pdev_set_mac_config_cmd_fixed_param *cmd;
13621 	wmi_buf_t buf;
13622 	uint32_t len;
13623 
13624 	len = sizeof(*cmd);
13625 
13626 	buf = wmi_buf_alloc(wmi_handle, len);
13627 	if (!buf) {
13628 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13629 		return QDF_STATUS_E_FAILURE;
13630 	}
13631 
13632 	cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf);
13633 	WMITLV_SET_HDR(&cmd->tlv_header,
13634 		WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param,
13635 		WMITLV_GET_STRUCT_TLVLEN(
13636 			wmi_pdev_set_mac_config_cmd_fixed_param));
13637 
13638 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13639 							WMI_HOST_PDEV_ID_SOC);
13640 	cmd->concurrent_scan_config_bits = msg->scan_config;
13641 	cmd->fw_mode_config_bits = msg->fw_mode_config;
13642 	WMI_LOGD("%s: scan_config:%x fw_mode_config:%x",
13643 		 __func__, msg->scan_config, msg->fw_mode_config);
13644 
13645 	wmi_mtrace(WMI_PDEV_SET_MAC_CONFIG_CMDID, NO_SESSION, 0);
13646 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13647 				WMI_PDEV_SET_MAC_CONFIG_CMDID)) {
13648 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID",
13649 				__func__);
13650 		wmi_buf_free(buf);
13651 	}
13652 	return QDF_STATUS_SUCCESS;
13653 }
13654 #endif
13655 
13656 #ifdef BIG_ENDIAN_HOST
13657 /**
13658 * fips_conv_data_be() - LE to BE conversion of FIPS ev data
13659 * @param data_len - data length
13660 * @param data - pointer to data
13661 *
13662 * Return: QDF_STATUS - success or error status
13663 */
13664 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle,
13665 			struct fips_params *param)
13666 {
13667 	unsigned char *key_unaligned, *data_unaligned;
13668 	int c;
13669 	u_int8_t *key_aligned = NULL;
13670 	u_int8_t *data_aligned = NULL;
13671 
13672 	/* Assigning unaligned space to copy the key */
13673 	key_unaligned = qdf_mem_malloc(
13674 		sizeof(u_int8_t)*param->key_len + FIPS_ALIGN);
13675 	data_unaligned = qdf_mem_malloc(
13676 		sizeof(u_int8_t)*param->data_len + FIPS_ALIGN);
13677 
13678 	/* Checking if kmalloc is successful to allocate space */
13679 	if (key_unaligned == NULL)
13680 		return QDF_STATUS_SUCCESS;
13681 	/* Checking if space is aligned */
13682 	if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) {
13683 		/* align to 4 */
13684 		key_aligned =
13685 		(u_int8_t *)FIPS_ALIGNTO(key_unaligned,
13686 			FIPS_ALIGN);
13687 	} else {
13688 		key_aligned = (u_int8_t *)key_unaligned;
13689 	}
13690 
13691 	/* memset and copy content from key to key aligned */
13692 	OS_MEMSET(key_aligned, 0, param->key_len);
13693 	OS_MEMCPY(key_aligned, param->key, param->key_len);
13694 
13695 	/* print a hexdump for host debug */
13696 	print_hex_dump(KERN_DEBUG,
13697 		"\t Aligned and Copied Key:@@@@ ",
13698 		DUMP_PREFIX_NONE,
13699 		16, 1, key_aligned, param->key_len, true);
13700 
13701 	/* Checking if kmalloc is successful to allocate space */
13702 	if (data_unaligned == NULL)
13703 		return QDF_STATUS_SUCCESS;
13704 	/* Checking of space is aligned */
13705 	if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) {
13706 		/* align to 4 */
13707 		data_aligned =
13708 		(u_int8_t *)FIPS_ALIGNTO(data_unaligned,
13709 				FIPS_ALIGN);
13710 	} else {
13711 		data_aligned = (u_int8_t *)data_unaligned;
13712 	}
13713 
13714 	/* memset and copy content from data to data aligned */
13715 	OS_MEMSET(data_aligned, 0, param->data_len);
13716 	OS_MEMCPY(data_aligned, param->data, param->data_len);
13717 
13718 	/* print a hexdump for host debug */
13719 	print_hex_dump(KERN_DEBUG,
13720 		"\t Properly Aligned and Copied Data:@@@@ ",
13721 	DUMP_PREFIX_NONE,
13722 	16, 1, data_aligned, param->data_len, true);
13723 
13724 	/* converting to little Endian both key_aligned and
13725 	* data_aligned*/
13726 	for (c = 0; c < param->key_len/4; c++) {
13727 		*((u_int32_t *)key_aligned+c) =
13728 		qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c));
13729 	}
13730 	for (c = 0; c < param->data_len/4; c++) {
13731 		*((u_int32_t *)data_aligned+c) =
13732 		qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c));
13733 	}
13734 
13735 	/* update endian data to key and data vectors */
13736 	OS_MEMCPY(param->key, key_aligned, param->key_len);
13737 	OS_MEMCPY(param->data, data_aligned, param->data_len);
13738 
13739 	/* clean up allocated spaces */
13740 	qdf_mem_free(key_unaligned);
13741 	key_unaligned = NULL;
13742 	key_aligned = NULL;
13743 
13744 	qdf_mem_free(data_unaligned);
13745 	data_unaligned = NULL;
13746 	data_aligned = NULL;
13747 
13748 	return QDF_STATUS_SUCCESS;
13749 }
13750 #else
13751 /**
13752 * fips_align_data_be() - DUMMY for LE platform
13753 *
13754 * Return: QDF_STATUS - success
13755 */
13756 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle,
13757 		struct fips_params *param)
13758 {
13759 	return QDF_STATUS_SUCCESS;
13760 }
13761 #endif
13762 
13763 
13764 /**
13765  * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw
13766  * @wmi_handle: wmi handle
13767  * @param: pointer to hold pdev fips param
13768  *
13769  * Return: 0 for success or error code
13770  */
13771 static QDF_STATUS
13772 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle,
13773 		struct fips_params *param)
13774 {
13775 	wmi_pdev_fips_cmd_fixed_param *cmd;
13776 	wmi_buf_t buf;
13777 	uint8_t *buf_ptr;
13778 	uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param);
13779 	QDF_STATUS retval = QDF_STATUS_SUCCESS;
13780 
13781 	/* Length TLV placeholder for array of bytes */
13782 	len += WMI_TLV_HDR_SIZE;
13783 	if (param->data_len)
13784 		len += (param->data_len*sizeof(uint8_t));
13785 
13786 	/*
13787 	* Data length must be multiples of 16 bytes - checked against 0xF -
13788 	* and must be less than WMI_SVC_MSG_SIZE - static size of
13789 	* wmi_pdev_fips_cmd structure
13790 	*/
13791 
13792 	/* do sanity on the input */
13793 	if (!(((param->data_len & 0xF) == 0) &&
13794 			((param->data_len > 0) &&
13795 			(param->data_len < (WMI_HOST_MAX_BUFFER_SIZE -
13796 		sizeof(wmi_pdev_fips_cmd_fixed_param)))))) {
13797 		return QDF_STATUS_E_INVAL;
13798 	}
13799 
13800 	buf = wmi_buf_alloc(wmi_handle, len);
13801 	if (!buf) {
13802 		qdf_print("%s:wmi_buf_alloc failed", __func__);
13803 		return QDF_STATUS_E_FAILURE;
13804 	}
13805 
13806 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
13807 	cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr;
13808 	WMITLV_SET_HDR(&cmd->tlv_header,
13809 		WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param,
13810 		WMITLV_GET_STRUCT_TLVLEN
13811 		(wmi_pdev_fips_cmd_fixed_param));
13812 
13813 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13814 								param->pdev_id);
13815 	if (param->key != NULL && param->data != NULL) {
13816 		cmd->key_len = param->key_len;
13817 		cmd->data_len = param->data_len;
13818 		cmd->fips_cmd = !!(param->op);
13819 
13820 		if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS)
13821 			return QDF_STATUS_E_FAILURE;
13822 
13823 		qdf_mem_copy(cmd->key, param->key, param->key_len);
13824 
13825 		if (param->mode == FIPS_ENGINE_AES_CTR ||
13826 			param->mode == FIPS_ENGINE_AES_MIC) {
13827 			cmd->mode = param->mode;
13828 		} else {
13829 			cmd->mode = FIPS_ENGINE_AES_CTR;
13830 		}
13831 		qdf_print("Key len = %d, Data len = %d",
13832 			  cmd->key_len, cmd->data_len);
13833 
13834 		print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1,
13835 				cmd->key, cmd->key_len, true);
13836 		buf_ptr += sizeof(*cmd);
13837 
13838 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len);
13839 
13840 		buf_ptr += WMI_TLV_HDR_SIZE;
13841 		if (param->data_len)
13842 			qdf_mem_copy(buf_ptr,
13843 				(uint8_t *) param->data, param->data_len);
13844 
13845 		print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE,
13846 			16, 1, buf_ptr, cmd->data_len, true);
13847 
13848 		buf_ptr += param->data_len;
13849 
13850 		wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0);
13851 		retval = wmi_unified_cmd_send(wmi_handle, buf, len,
13852 			WMI_PDEV_FIPS_CMDID);
13853 		qdf_print("%s return value %d", __func__, retval);
13854 	} else {
13855 		qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__);
13856 		wmi_buf_free(buf);
13857 		retval = -QDF_STATUS_E_BADMSG;
13858 	}
13859 
13860 	return retval;
13861 }
13862 
13863 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
13864 /**
13865  * send_add_wow_wakeup_event_cmd_tlv() -  Configures wow wakeup events.
13866  * @wmi_handle: wmi handle
13867  * @vdev_id: vdev id
13868  * @bitmap: Event bitmap
13869  * @enable: enable/disable
13870  *
13871  * Return: CDF status
13872  */
13873 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle,
13874 					uint32_t vdev_id,
13875 					uint32_t *bitmap,
13876 					bool enable)
13877 {
13878 	WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd;
13879 	uint16_t len;
13880 	wmi_buf_t buf;
13881 	int ret;
13882 
13883 	len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param);
13884 	buf = wmi_buf_alloc(wmi_handle, len);
13885 	if (!buf) {
13886 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
13887 		return QDF_STATUS_E_NOMEM;
13888 	}
13889 	cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf);
13890 	WMITLV_SET_HDR(&cmd->tlv_header,
13891 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param,
13892 		       WMITLV_GET_STRUCT_TLVLEN
13893 			       (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param));
13894 	cmd->vdev_id = vdev_id;
13895 	cmd->is_add = enable;
13896 	qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) *
13897 		     WMI_WOW_MAX_EVENT_BM_LEN);
13898 
13899 	WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0],
13900 		 cmd->event_bitmaps[1], cmd->event_bitmaps[2],
13901 		 cmd->event_bitmaps[3], enable ? "enabled" : "disabled");
13902 
13903 	wmi_mtrace(WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, cmd->vdev_id, 0);
13904 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
13905 				   WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
13906 	if (ret) {
13907 		WMI_LOGE("Failed to config wow wakeup event");
13908 		wmi_buf_free(buf);
13909 		return QDF_STATUS_E_FAILURE;
13910 	}
13911 
13912 	return QDF_STATUS_SUCCESS;
13913 }
13914 
13915 /**
13916  * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW.
13917  * @wmi_handle: wmi handle
13918  * @vdev_id: vdev id
13919  * @ptrn_id: pattern id
13920  * @ptrn: pattern
13921  * @ptrn_len: pattern length
13922  * @ptrn_offset: pattern offset
13923  * @mask: mask
13924  * @mask_len: mask length
13925  * @user: true for user configured pattern and false for default pattern
13926  * @default_patterns: default patterns
13927  *
13928  * Return: CDF status
13929  */
13930 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle,
13931 				uint8_t vdev_id, uint8_t ptrn_id,
13932 				const uint8_t *ptrn, uint8_t ptrn_len,
13933 				uint8_t ptrn_offset, const uint8_t *mask,
13934 				uint8_t mask_len, bool user,
13935 				uint8_t default_patterns)
13936 {
13937 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
13938 	WOW_BITMAP_PATTERN_T *bitmap_pattern;
13939 	wmi_buf_t buf;
13940 	uint8_t *buf_ptr;
13941 	int32_t len;
13942 	int ret;
13943 
13944 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
13945 		WMI_TLV_HDR_SIZE +
13946 		1 * sizeof(WOW_BITMAP_PATTERN_T) +
13947 		WMI_TLV_HDR_SIZE +
13948 		0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
13949 		WMI_TLV_HDR_SIZE +
13950 		0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
13951 		WMI_TLV_HDR_SIZE +
13952 		0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
13953 		WMI_TLV_HDR_SIZE +
13954 		0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
13955 
13956 	buf = wmi_buf_alloc(wmi_handle, len);
13957 	if (!buf) {
13958 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
13959 		return QDF_STATUS_E_NOMEM;
13960 	}
13961 
13962 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
13963 	buf_ptr = (uint8_t *) cmd;
13964 
13965 	WMITLV_SET_HDR(&cmd->tlv_header,
13966 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
13967 		       WMITLV_GET_STRUCT_TLVLEN
13968 			       (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
13969 	cmd->vdev_id = vdev_id;
13970 	cmd->pattern_id = ptrn_id;
13971 
13972 	cmd->pattern_type = WOW_BITMAP_PATTERN;
13973 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
13974 
13975 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
13976 		       sizeof(WOW_BITMAP_PATTERN_T));
13977 	buf_ptr += WMI_TLV_HDR_SIZE;
13978 	bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr;
13979 
13980 	WMITLV_SET_HDR(&bitmap_pattern->tlv_header,
13981 		       WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T,
13982 		       WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T));
13983 
13984 	qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len);
13985 	qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len);
13986 
13987 	bitmap_pattern->pattern_offset = ptrn_offset;
13988 	bitmap_pattern->pattern_len = ptrn_len;
13989 
13990 	if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE)
13991 		bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE;
13992 
13993 	if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE)
13994 		bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE;
13995 
13996 	bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len;
13997 	bitmap_pattern->pattern_id = ptrn_id;
13998 
13999 	WMI_LOGD("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d",
14000 		 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len,
14001 		 bitmap_pattern->pattern_offset, user);
14002 	WMI_LOGD("Pattern : ");
14003 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
14004 			   &bitmap_pattern->patternbuf[0],
14005 			   bitmap_pattern->pattern_len);
14006 
14007 	WMI_LOGD("Mask : ");
14008 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
14009 			   &bitmap_pattern->bitmaskbuf[0],
14010 			   bitmap_pattern->pattern_len);
14011 
14012 	buf_ptr += sizeof(WOW_BITMAP_PATTERN_T);
14013 
14014 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
14015 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14016 	buf_ptr += WMI_TLV_HDR_SIZE;
14017 
14018 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
14019 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14020 	buf_ptr += WMI_TLV_HDR_SIZE;
14021 
14022 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
14023 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14024 	buf_ptr += WMI_TLV_HDR_SIZE;
14025 
14026 	/* Fill TLV for pattern_info_timeout but no data. */
14027 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
14028 	buf_ptr += WMI_TLV_HDR_SIZE;
14029 
14030 	/* Fill TLV for ratelimit_interval with dummy data as this fix elem */
14031 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t));
14032 	buf_ptr += WMI_TLV_HDR_SIZE;
14033 	*(uint32_t *) buf_ptr = 0;
14034 
14035 	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
14036 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
14037 				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
14038 	if (ret) {
14039 		WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__);
14040 		wmi_buf_free(buf);
14041 		return QDF_STATUS_E_FAILURE;
14042 	}
14043 
14044 	return QDF_STATUS_SUCCESS;
14045 }
14046 
14047 /**
14048  * fill_arp_offload_params_tlv() - Fill ARP offload data
14049  * @wmi_handle: wmi handle
14050  * @offload_req: offload request
14051  * @buf_ptr: buffer pointer
14052  *
14053  * To fill ARP offload data to firmware
14054  * when target goes to wow mode.
14055  *
14056  * Return: None
14057  */
14058 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle,
14059 		struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr)
14060 {
14061 
14062 	int i;
14063 	WMI_ARP_OFFLOAD_TUPLE *arp_tuple;
14064 	bool enable_or_disable = offload_req->enable;
14065 
14066 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14067 		(WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE)));
14068 	*buf_ptr += WMI_TLV_HDR_SIZE;
14069 	for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) {
14070 		arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr;
14071 		WMITLV_SET_HDR(&arp_tuple->tlv_header,
14072 			WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE,
14073 			WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE));
14074 
14075 		/* Fill data for ARP and NS in the first tupple for LA */
14076 		if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) {
14077 			/* Copy the target ip addr and flags */
14078 			arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID;
14079 			qdf_mem_copy(&arp_tuple->target_ipaddr,
14080 					offload_req->host_ipv4_addr,
14081 					WMI_IPV4_ADDR_LEN);
14082 			WMI_LOGD("ARPOffload IP4 address: %pI4",
14083 					offload_req->host_ipv4_addr);
14084 		}
14085 		*buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE);
14086 	}
14087 }
14088 
14089 #ifdef WLAN_NS_OFFLOAD
14090 /**
14091  * fill_ns_offload_params_tlv() - Fill NS offload data
14092  * @wmi|_handle: wmi handle
14093  * @offload_req: offload request
14094  * @buf_ptr: buffer pointer
14095  *
14096  * To fill NS offload data to firmware
14097  * when target goes to wow mode.
14098  *
14099  * Return: None
14100  */
14101 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle,
14102 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14103 {
14104 
14105 	int i;
14106 	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
14107 
14108 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14109 		(WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE)));
14110 	*buf_ptr += WMI_TLV_HDR_SIZE;
14111 	for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) {
14112 		ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr;
14113 		WMITLV_SET_HDR(&ns_tuple->tlv_header,
14114 			WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
14115 			(sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE));
14116 
14117 		/*
14118 		 * Fill data only for NS offload in the first ARP tuple for LA
14119 		 */
14120 		if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) {
14121 			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
14122 			/* Copy the target/solicitation/remote ip addr */
14123 			if (ns_req->target_ipv6_addr_valid[i])
14124 				qdf_mem_copy(&ns_tuple->target_ipaddr[0],
14125 					&ns_req->target_ipv6_addr[i],
14126 					sizeof(WMI_IPV6_ADDR));
14127 			qdf_mem_copy(&ns_tuple->solicitation_ipaddr,
14128 				&ns_req->self_ipv6_addr[i],
14129 				sizeof(WMI_IPV6_ADDR));
14130 			if (ns_req->target_ipv6_addr_ac_type[i]) {
14131 				ns_tuple->flags |=
14132 					WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST;
14133 			}
14134 			WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6",
14135 				i, &ns_req->self_ipv6_addr[i],
14136 				&ns_req->target_ipv6_addr[i]);
14137 
14138 			/* target MAC is optional, check if it is valid,
14139 			 * if this is not valid, the target will use the known
14140 			 * local MAC address rather than the tuple
14141 			 */
14142 			WMI_CHAR_ARRAY_TO_MAC_ADDR(
14143 				ns_req->self_macaddr.bytes,
14144 				&ns_tuple->target_mac);
14145 			if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
14146 				(ns_tuple->target_mac.mac_addr47to32 != 0)) {
14147 				ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
14148 			}
14149 		}
14150 		*buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
14151 	}
14152 }
14153 
14154 
14155 /**
14156  * fill_nsoffload_ext_tlv() - Fill NS offload ext data
14157  * @wmi: wmi handle
14158  * @offload_req: offload request
14159  * @buf_ptr: buffer pointer
14160  *
14161  * To fill extended NS offload extended data to firmware
14162  * when target goes to wow mode.
14163  *
14164  * Return: None
14165  */
14166 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle,
14167 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14168 {
14169 	int i;
14170 	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
14171 	uint32_t count, num_ns_ext_tuples;
14172 
14173 	count = ns_req->num_ns_offload_count;
14174 	num_ns_ext_tuples = ns_req->num_ns_offload_count -
14175 		WMI_MAX_NS_OFFLOADS;
14176 
14177 	/* Populate extended NS offload tuples */
14178 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14179 		(num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE)));
14180 	*buf_ptr += WMI_TLV_HDR_SIZE;
14181 	for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) {
14182 		ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr;
14183 		WMITLV_SET_HDR(&ns_tuple->tlv_header,
14184 			WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
14185 			(sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE));
14186 
14187 		/*
14188 		 * Fill data only for NS offload in the first ARP tuple for LA
14189 		 */
14190 		if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) {
14191 			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
14192 			/* Copy the target/solicitation/remote ip addr */
14193 			if (ns_req->target_ipv6_addr_valid[i])
14194 				qdf_mem_copy(&ns_tuple->target_ipaddr[0],
14195 					&ns_req->target_ipv6_addr[i],
14196 					sizeof(WMI_IPV6_ADDR));
14197 			qdf_mem_copy(&ns_tuple->solicitation_ipaddr,
14198 				&ns_req->self_ipv6_addr[i],
14199 				sizeof(WMI_IPV6_ADDR));
14200 			if (ns_req->target_ipv6_addr_ac_type[i]) {
14201 				ns_tuple->flags |=
14202 					WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST;
14203 			}
14204 			WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6",
14205 				i, &ns_req->self_ipv6_addr[i],
14206 				&ns_req->target_ipv6_addr[i]);
14207 
14208 			/* target MAC is optional, check if it is valid,
14209 			 * if this is not valid, the target will use the
14210 			 * known local MAC address rather than the tuple
14211 			 */
14212 			 WMI_CHAR_ARRAY_TO_MAC_ADDR(
14213 				ns_req->self_macaddr.bytes,
14214 				&ns_tuple->target_mac);
14215 			if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
14216 				(ns_tuple->target_mac.mac_addr47to32 != 0)) {
14217 				ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
14218 			}
14219 		}
14220 		*buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
14221 	}
14222 }
14223 #else
14224 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle,
14225 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14226 {
14227 }
14228 
14229 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle,
14230 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14231 {
14232 }
14233 #endif
14234 
14235 /**
14236  * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload
14237  * @wma: wmi handle
14238  * @arp_offload_req: arp offload request
14239  * @ns_offload_req: ns offload request
14240  * @arp_only: flag
14241  *
14242  * To configure ARP NS off load data to firmware
14243  * when target goes to wow mode.
14244  *
14245  * Return: QDF Status
14246  */
14247 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle,
14248 			   struct pmo_arp_offload_params *arp_offload_req,
14249 			   struct pmo_ns_offload_params *ns_offload_req,
14250 			   uint8_t vdev_id)
14251 {
14252 	int32_t res;
14253 	WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd;
14254 	uint8_t *buf_ptr;
14255 	wmi_buf_t buf;
14256 	int32_t len;
14257 	uint32_t count = 0, num_ns_ext_tuples = 0;
14258 
14259 	count = ns_offload_req->num_ns_offload_count;
14260 
14261 	/*
14262 	 * TLV place holder size for array of NS tuples
14263 	 * TLV place holder size for array of ARP tuples
14264 	 */
14265 	len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) +
14266 		WMI_TLV_HDR_SIZE +
14267 		WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) +
14268 		WMI_TLV_HDR_SIZE +
14269 		WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE);
14270 
14271 	/*
14272 	 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate
14273 	 * extra length for extended NS offload tuples which follows ARP offload
14274 	 * tuples. Host needs to fill this structure in following format:
14275 	 * 2 NS ofload tuples
14276 	 * 2 ARP offload tuples
14277 	 * N numbers of extended NS offload tuples if HDD has given more than
14278 	 * 2 NS offload addresses
14279 	 */
14280 	if (count > WMI_MAX_NS_OFFLOADS) {
14281 		num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS;
14282 		len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples
14283 			   * sizeof(WMI_NS_OFFLOAD_TUPLE);
14284 	}
14285 
14286 	buf = wmi_buf_alloc(wmi_handle, len);
14287 	if (!buf) {
14288 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
14289 		return QDF_STATUS_E_NOMEM;
14290 	}
14291 
14292 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14293 	cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr;
14294 	WMITLV_SET_HDR(&cmd->tlv_header,
14295 		       WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param,
14296 		       WMITLV_GET_STRUCT_TLVLEN
14297 			       (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param));
14298 	cmd->flags = 0;
14299 	cmd->vdev_id = vdev_id;
14300 	cmd->num_ns_ext_tuples = num_ns_ext_tuples;
14301 
14302 	WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id);
14303 
14304 	buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param);
14305 	fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr);
14306 	fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr);
14307 	if (num_ns_ext_tuples)
14308 		fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr);
14309 
14310 	wmi_mtrace(WMI_SET_ARP_NS_OFFLOAD_CMDID, cmd->vdev_id, 0);
14311 	res = wmi_unified_cmd_send(wmi_handle, buf, len,
14312 				     WMI_SET_ARP_NS_OFFLOAD_CMDID);
14313 	if (res) {
14314 		WMI_LOGE("Failed to enable ARP NDP/NSffload");
14315 		wmi_buf_free(buf);
14316 		return QDF_STATUS_E_FAILURE;
14317 	}
14318 
14319 	return QDF_STATUS_SUCCESS;
14320 }
14321 
14322 /**
14323  * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload
14324  * @wmi_handle: wmi handle
14325  * @vdev_id: vdev id
14326  * @action: true for enable else false
14327  *
14328  * To enable enhance multicast offload to firmware
14329  * when target goes to wow mode.
14330  *
14331  * Return: QDF Status
14332  */
14333 
14334 static
14335 QDF_STATUS send_enable_enhance_multicast_offload_tlv(
14336 		wmi_unified_t wmi_handle,
14337 		uint8_t vdev_id, bool action)
14338 {
14339 	QDF_STATUS status;
14340 	wmi_buf_t buf;
14341 	wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd;
14342 
14343 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
14344 	if (!buf) {
14345 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
14346 		return QDF_STATUS_E_NOMEM;
14347 	}
14348 
14349 	cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *)
14350 							wmi_buf_data(buf);
14351 
14352 	WMITLV_SET_HDR(&cmd->tlv_header,
14353 		WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param,
14354 		WMITLV_GET_STRUCT_TLVLEN(
14355 			wmi_config_enhanced_mcast_filter_cmd_fixed_param));
14356 
14357 	cmd->vdev_id = vdev_id;
14358 	cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED :
14359 			ENHANCED_MCAST_FILTER_ENABLED);
14360 	WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d",
14361 		__func__, action, vdev_id);
14362 	wmi_mtrace(WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID, cmd->vdev_id, 0);
14363 	status = wmi_unified_cmd_send(wmi_handle, buf,
14364 			sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID);
14365 	if (status != QDF_STATUS_SUCCESS) {
14366 		wmi_buf_free(buf);
14367 		WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID",
14368 			__func__);
14369 	}
14370 
14371 	return status;
14372 }
14373 
14374 /**
14375  * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event
14376  * @wmi_handle: wmi handle
14377  * @param evt_buf: pointer to event buffer
14378  * @param hdr: Pointer to hold header
14379  * @param bufp: Pointer to hold pointer to rx param buffer
14380  *
14381  * Return: QDF_STATUS_SUCCESS for success or error code
14382  */
14383 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle,
14384 	void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len)
14385 {
14386 	WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param;
14387 	WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf;
14388 
14389 	param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf;
14390 	if (!param_buf) {
14391 		WMI_LOGE("gtk param_buf is NULL");
14392 		return QDF_STATUS_E_INVAL;
14393 	}
14394 
14395 	if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) {
14396 		WMI_LOGE("Invalid length for GTK status");
14397 		return QDF_STATUS_E_INVAL;
14398 	}
14399 
14400 	fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *)
14401 		param_buf->fixed_param;
14402 	gtk_rsp_param->vdev_id = fixed_param->vdev_id;
14403 	gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS;
14404 	gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt;
14405 	qdf_mem_copy(&gtk_rsp_param->replay_counter,
14406 		&fixed_param->replay_counter,
14407 		GTK_REPLAY_COUNTER_BYTES);
14408 
14409 	return QDF_STATUS_SUCCESS;
14410 
14411 }
14412 
14413 #ifdef FEATURE_WLAN_RA_FILTERING
14414 /**
14415  * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw
14416  * @wmi_handle: wmi handle
14417  * @vdev_id: vdev id
14418  *
14419  * Return: CDF status
14420  */
14421 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle,
14422 		   uint8_t vdev_id, uint8_t default_pattern,
14423 		   uint16_t rate_limit_interval)
14424 {
14425 
14426 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
14427 	wmi_buf_t buf;
14428 	uint8_t *buf_ptr;
14429 	int32_t len;
14430 	int ret;
14431 
14432 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
14433 	      WMI_TLV_HDR_SIZE +
14434 	      0 * sizeof(WOW_BITMAP_PATTERN_T) +
14435 	      WMI_TLV_HDR_SIZE +
14436 	      0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
14437 	      WMI_TLV_HDR_SIZE +
14438 	      0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
14439 	      WMI_TLV_HDR_SIZE +
14440 	      0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
14441 	      WMI_TLV_HDR_SIZE +
14442 	      0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
14443 
14444 	buf = wmi_buf_alloc(wmi_handle, len);
14445 	if (!buf) {
14446 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
14447 		return QDF_STATUS_E_NOMEM;
14448 	}
14449 
14450 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
14451 	buf_ptr = (uint8_t *) cmd;
14452 
14453 	WMITLV_SET_HDR(&cmd->tlv_header,
14454 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
14455 		       WMITLV_GET_STRUCT_TLVLEN
14456 			       (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
14457 	cmd->vdev_id = vdev_id;
14458 	cmd->pattern_id = default_pattern,
14459 	cmd->pattern_type = WOW_IPV6_RA_PATTERN;
14460 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
14461 
14462 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
14463 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14464 	buf_ptr += WMI_TLV_HDR_SIZE;
14465 
14466 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
14467 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14468 	buf_ptr += WMI_TLV_HDR_SIZE;
14469 
14470 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
14471 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14472 	buf_ptr += WMI_TLV_HDR_SIZE;
14473 
14474 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
14475 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14476 	buf_ptr += WMI_TLV_HDR_SIZE;
14477 
14478 	/* Fill TLV for pattern_info_timeout but no data. */
14479 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
14480 	buf_ptr += WMI_TLV_HDR_SIZE;
14481 
14482 	/* Fill TLV for ra_ratelimit_interval. */
14483 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
14484 	buf_ptr += WMI_TLV_HDR_SIZE;
14485 
14486 	*((uint32_t *) buf_ptr) = rate_limit_interval;
14487 
14488 	WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__,
14489 		 rate_limit_interval, vdev_id);
14490 
14491 	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
14492 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
14493 				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
14494 	if (ret) {
14495 		WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__);
14496 		wmi_buf_free(buf);
14497 		return QDF_STATUS_E_FAILURE;
14498 	}
14499 
14500 	return QDF_STATUS_SUCCESS;
14501 
14502 }
14503 #endif /* FEATURE_WLAN_RA_FILTERING */
14504 
14505 /**
14506  * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw
14507  * @wmi_handle: wmi handle
14508  * @vdev_id: vdev id
14509  * @multicastAddr: mcast address
14510  * @clearList: clear list flag
14511  *
14512  * Return: QDF_STATUS_SUCCESS for success or error code
14513  */
14514 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle,
14515 				     uint8_t vdev_id,
14516 				     struct qdf_mac_addr multicast_addr,
14517 				     bool clearList)
14518 {
14519 	WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd;
14520 	wmi_buf_t buf;
14521 	int err;
14522 
14523 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
14524 	if (!buf) {
14525 		WMI_LOGE("Failed to allocate buffer to send set_param cmd");
14526 		return QDF_STATUS_E_NOMEM;
14527 	}
14528 
14529 	cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf);
14530 	qdf_mem_zero(cmd, sizeof(*cmd));
14531 
14532 	WMITLV_SET_HDR(&cmd->tlv_header,
14533 	       WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param,
14534 	       WMITLV_GET_STRUCT_TLVLEN
14535 	       (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param));
14536 	cmd->action =
14537 		(clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET);
14538 	cmd->vdev_id = vdev_id;
14539 	WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr);
14540 
14541 	WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM",
14542 		 cmd->action, vdev_id, clearList, multicast_addr.bytes);
14543 
14544 	wmi_mtrace(WMI_SET_MCASTBCAST_FILTER_CMDID, cmd->vdev_id, 0);
14545 	err = wmi_unified_cmd_send(wmi_handle, buf,
14546 				   sizeof(*cmd),
14547 				   WMI_SET_MCASTBCAST_FILTER_CMDID);
14548 	if (err) {
14549 		WMI_LOGE("Failed to send set_param cmd");
14550 		wmi_buf_free(buf);
14551 		return QDF_STATUS_E_FAILURE;
14552 	}
14553 
14554 	return QDF_STATUS_SUCCESS;
14555 }
14556 
14557 /**
14558  * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple  mcast filter
14559  *						   command to fw
14560  * @wmi_handle: wmi handle
14561  * @vdev_id: vdev id
14562  * @mcast_filter_params: mcast filter params
14563  *
14564  * Return: QDF_STATUS_SUCCESS for success or error code
14565  */
14566 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv(
14567 				wmi_unified_t wmi_handle,
14568 				uint8_t vdev_id,
14569 				struct pmo_mcast_filter_params *filter_param)
14570 
14571 {
14572 	WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd;
14573 	uint8_t *buf_ptr;
14574 	wmi_buf_t buf;
14575 	int err;
14576 	int i;
14577 	uint8_t *mac_addr_src_ptr = NULL;
14578 	wmi_mac_addr *mac_addr_dst_ptr;
14579 	uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
14580 		sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt;
14581 
14582 	buf = wmi_buf_alloc(wmi_handle, len);
14583 	if (!buf) {
14584 		WMI_LOGE("Failed to allocate memory");
14585 		return QDF_STATUS_E_NOMEM;
14586 	}
14587 
14588 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14589 	cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *)
14590 		wmi_buf_data(buf);
14591 	qdf_mem_zero(cmd, sizeof(*cmd));
14592 
14593 	WMITLV_SET_HDR(&cmd->tlv_header,
14594 	       WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param,
14595 	       WMITLV_GET_STRUCT_TLVLEN
14596 	       (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param));
14597 	cmd->operation =
14598 		((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE
14599 					: WMI_MULTIPLE_MCAST_FILTER_ADD);
14600 	cmd->vdev_id = vdev_id;
14601 	cmd->num_mcastaddrs = filter_param->multicast_addr_cnt;
14602 
14603 	buf_ptr += sizeof(*cmd);
14604 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
14605 		       sizeof(wmi_mac_addr) *
14606 			       filter_param->multicast_addr_cnt);
14607 
14608 	if (filter_param->multicast_addr_cnt == 0)
14609 		goto send_cmd;
14610 
14611 	mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr;
14612 	mac_addr_dst_ptr = (wmi_mac_addr *)
14613 			(buf_ptr + WMI_TLV_HDR_SIZE);
14614 
14615 	for (i = 0; i < filter_param->multicast_addr_cnt; i++) {
14616 		WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr);
14617 		mac_addr_src_ptr += ATH_MAC_LEN;
14618 		mac_addr_dst_ptr++;
14619 	}
14620 
14621 send_cmd:
14622 	wmi_mtrace(WMI_SET_MULTIPLE_MCAST_FILTER_CMDID, cmd->vdev_id, 0);
14623 	err = wmi_unified_cmd_send(wmi_handle, buf,
14624 				   len,
14625 				   WMI_SET_MULTIPLE_MCAST_FILTER_CMDID);
14626 	if (err) {
14627 		WMI_LOGE("Failed to send set_param cmd");
14628 		wmi_buf_free(buf);
14629 		return QDF_STATUS_E_FAILURE;
14630 	}
14631 
14632 	return QDF_STATUS_SUCCESS;
14633 }
14634 
14635 static void
14636 fill_fils_tlv_params(WMI_GTK_OFFLOAD_CMD_fixed_param *cmd,
14637 			  uint8_t vdev_id,
14638 			  struct pmo_gtk_req *params)
14639 {
14640 	uint8_t *buf_ptr;
14641 	wmi_gtk_offload_fils_tlv_param *ext_param;
14642 
14643 	buf_ptr = (uint8_t *) cmd + sizeof(*cmd);
14644 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14645 		       sizeof(*ext_param));
14646 	buf_ptr += WMI_TLV_HDR_SIZE;
14647 
14648 	ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr;
14649 	WMITLV_SET_HDR(&ext_param->tlv_header,
14650 		       WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param,
14651 		       WMITLV_GET_STRUCT_TLVLEN(
14652 				wmi_gtk_offload_fils_tlv_param));
14653 	ext_param->vdev_id = vdev_id;
14654 	ext_param->flags = cmd->flags;
14655 	ext_param->kek_len = params->kek_len;
14656 	qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len);
14657 	qdf_mem_copy(ext_param->KCK, params->kck,
14658 		     WMI_GTK_OFFLOAD_KCK_BYTES);
14659 	qdf_mem_copy(ext_param->replay_counter, &params->replay_counter,
14660 		     GTK_REPLAY_COUNTER_BYTES);
14661 }
14662 
14663 /**
14664  * send_gtk_offload_cmd_tlv() - send GTK offload command to fw
14665  * @wmi_handle: wmi handle
14666  * @vdev_id: vdev id
14667  * @params: GTK offload parameters
14668  *
14669  * Return: CDF status
14670  */
14671 static
14672 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
14673 					   struct pmo_gtk_req *params,
14674 					   bool enable_offload,
14675 					   uint32_t gtk_offload_opcode)
14676 {
14677 	int len;
14678 	wmi_buf_t buf;
14679 	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
14680 	QDF_STATUS status = QDF_STATUS_SUCCESS;
14681 
14682 	WMI_LOGD("%s Enter", __func__);
14683 
14684 	len = sizeof(*cmd);
14685 
14686 	if (params->is_fils_connection)
14687 		len += WMI_TLV_HDR_SIZE +
14688 		       sizeof(wmi_gtk_offload_fils_tlv_param);
14689 
14690 	/* alloc wmi buffer */
14691 	buf = wmi_buf_alloc(wmi_handle, len);
14692 	if (!buf) {
14693 		WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD");
14694 		status = QDF_STATUS_E_NOMEM;
14695 		goto out;
14696 	}
14697 
14698 	cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
14699 	WMITLV_SET_HDR(&cmd->tlv_header,
14700 		       WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
14701 		       WMITLV_GET_STRUCT_TLVLEN
14702 			       (WMI_GTK_OFFLOAD_CMD_fixed_param));
14703 
14704 	cmd->vdev_id = vdev_id;
14705 
14706 	/* Request target to enable GTK offload */
14707 	if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) {
14708 		cmd->flags = gtk_offload_opcode;
14709 
14710 		/* Copy the keys and replay counter */
14711 		qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN);
14712 		qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY);
14713 		qdf_mem_copy(cmd->replay_counter, &params->replay_counter,
14714 			     GTK_REPLAY_COUNTER_BYTES);
14715 	} else {
14716 		cmd->flags = gtk_offload_opcode;
14717 	}
14718 	if (params->is_fils_connection)
14719 		fill_fils_tlv_params(cmd, vdev_id, params);
14720 
14721 	WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len);
14722 	/* send the wmi command */
14723 	wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0);
14724 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
14725 				 WMI_GTK_OFFLOAD_CMDID)) {
14726 		WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID");
14727 		wmi_buf_free(buf);
14728 		status = QDF_STATUS_E_FAILURE;
14729 	}
14730 
14731 out:
14732 	WMI_LOGD("%s Exit", __func__);
14733 	return status;
14734 }
14735 
14736 /**
14737  * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw
14738  * @wmi_handle: wmi handle
14739  * @params: GTK offload params
14740  *
14741  * Return: CDF status
14742  */
14743 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv(
14744 			wmi_unified_t wmi_handle,
14745 			uint8_t vdev_id,
14746 			uint64_t offload_req_opcode)
14747 {
14748 	int len;
14749 	wmi_buf_t buf;
14750 	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
14751 	QDF_STATUS status = QDF_STATUS_SUCCESS;
14752 
14753 	len = sizeof(*cmd);
14754 
14755 	/* alloc wmi buffer */
14756 	buf = wmi_buf_alloc(wmi_handle, len);
14757 	if (!buf) {
14758 		WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD");
14759 		status = QDF_STATUS_E_NOMEM;
14760 		goto out;
14761 	}
14762 
14763 	cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
14764 	WMITLV_SET_HDR(&cmd->tlv_header,
14765 		       WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
14766 		       WMITLV_GET_STRUCT_TLVLEN
14767 			       (WMI_GTK_OFFLOAD_CMD_fixed_param));
14768 
14769 	/* Request for GTK offload status */
14770 	cmd->flags = offload_req_opcode;
14771 	cmd->vdev_id = vdev_id;
14772 
14773 	/* send the wmi command */
14774 	wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0);
14775 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
14776 				 WMI_GTK_OFFLOAD_CMDID)) {
14777 		WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info");
14778 		wmi_buf_free(buf);
14779 		status = QDF_STATUS_E_FAILURE;
14780 	}
14781 
14782 out:
14783 	return status;
14784 }
14785 
14786 /**
14787  * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params
14788  * @wmi_handle: wmi handler
14789  * @action_params: pointer to action_params
14790  *
14791  * Return: 0 for success, otherwise appropriate error code
14792  */
14793 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle,
14794 		struct pmo_action_wakeup_set_params *action_params)
14795 {
14796 	WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd;
14797 	wmi_buf_t buf;
14798 	int i;
14799 	int32_t err;
14800 	uint32_t len = 0, *cmd_args;
14801 	uint8_t *buf_ptr;
14802 
14803 	len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))
14804 				+ WMI_TLV_HDR_SIZE + sizeof(*cmd);
14805 	buf = wmi_buf_alloc(wmi_handle, len);
14806 	if (!buf) {
14807 		WMI_LOGE("Failed to allocate buffer to send action filter cmd");
14808 		return QDF_STATUS_E_NOMEM;
14809 	}
14810 	cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf);
14811 	buf_ptr = (uint8_t *)cmd;
14812 	WMITLV_SET_HDR(&cmd->tlv_header,
14813 		WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param,
14814 		WMITLV_GET_STRUCT_TLVLEN(
14815 				WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param));
14816 
14817 	cmd->vdev_id = action_params->vdev_id;
14818 	cmd->operation = action_params->operation;
14819 
14820 	for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++)
14821 		cmd->action_category_map[i] =
14822 				action_params->action_category_map[i];
14823 
14824 	buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param);
14825 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
14826 			(PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)));
14827 	buf_ptr += WMI_TLV_HDR_SIZE;
14828 	cmd_args = (uint32_t *) buf_ptr;
14829 	for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++)
14830 		cmd_args[i] = action_params->action_per_category[i];
14831 
14832 	wmi_mtrace(WMI_WOW_SET_ACTION_WAKE_UP_CMDID, cmd->vdev_id, 0);
14833 	err = wmi_unified_cmd_send(wmi_handle, buf,
14834 			len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID);
14835 	if (err) {
14836 		WMI_LOGE("Failed to send ap_ps_egap cmd");
14837 		wmi_buf_free(buf);
14838 		return QDF_STATUS_E_FAILURE;
14839 	}
14840 
14841 	return QDF_STATUS_SUCCESS;
14842 }
14843 
14844 #ifdef FEATURE_WLAN_LPHB
14845 
14846 /**
14847  * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration
14848  * @wmi_handle: wmi handle
14849  * @lphb_conf_req: configuration info
14850  *
14851  * Return: CDF status
14852  */
14853 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle,
14854 				wmi_hb_set_enable_cmd_fixed_param *params)
14855 {
14856 	QDF_STATUS status;
14857 	wmi_buf_t buf = NULL;
14858 	uint8_t *buf_ptr;
14859 	wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp;
14860 	int len = sizeof(wmi_hb_set_enable_cmd_fixed_param);
14861 
14862 
14863 	buf = wmi_buf_alloc(wmi_handle, len);
14864 	if (!buf) {
14865 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14866 		return QDF_STATUS_E_NOMEM;
14867 	}
14868 
14869 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14870 	hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr;
14871 	WMITLV_SET_HDR(&hb_enable_fp->tlv_header,
14872 		       WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param,
14873 		       WMITLV_GET_STRUCT_TLVLEN
14874 			       (wmi_hb_set_enable_cmd_fixed_param));
14875 
14876 	/* fill in values */
14877 	hb_enable_fp->vdev_id = params->session;
14878 	hb_enable_fp->enable = params->enable;
14879 	hb_enable_fp->item = params->item;
14880 	hb_enable_fp->session = params->session;
14881 
14882 	wmi_mtrace(WMI_HB_SET_ENABLE_CMDID, NO_SESSION, 0);
14883 	status = wmi_unified_cmd_send(wmi_handle, buf,
14884 				      len, WMI_HB_SET_ENABLE_CMDID);
14885 	if (QDF_IS_STATUS_ERROR(status)) {
14886 		WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d",
14887 			status);
14888 		wmi_buf_free(buf);
14889 	}
14890 
14891 	return status;
14892 }
14893 
14894 /**
14895  * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration
14896  * @wmi_handle: wmi handle
14897  * @lphb_conf_req: lphb config request
14898  *
14899  * Return: CDF status
14900  */
14901 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle,
14902 	    wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req)
14903 {
14904 	QDF_STATUS status;
14905 	wmi_buf_t buf = NULL;
14906 	uint8_t *buf_ptr;
14907 	wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp;
14908 	int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param);
14909 
14910 	buf = wmi_buf_alloc(wmi_handle, len);
14911 	if (!buf) {
14912 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14913 		return QDF_STATUS_E_NOMEM;
14914 	}
14915 
14916 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14917 	hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr;
14918 	WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header,
14919 		       WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param,
14920 		       WMITLV_GET_STRUCT_TLVLEN
14921 			       (wmi_hb_set_tcp_params_cmd_fixed_param));
14922 
14923 	/* fill in values */
14924 	hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id;
14925 	hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip;
14926 	hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip;
14927 	hb_tcp_params_fp->seq = lphb_conf_req->seq;
14928 	hb_tcp_params_fp->src_port = lphb_conf_req->src_port;
14929 	hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port;
14930 	hb_tcp_params_fp->interval = lphb_conf_req->interval;
14931 	hb_tcp_params_fp->timeout = lphb_conf_req->timeout;
14932 	hb_tcp_params_fp->session = lphb_conf_req->session;
14933 	qdf_mem_copy(&hb_tcp_params_fp->gateway_mac,
14934 				   &lphb_conf_req->gateway_mac,
14935 				   sizeof(hb_tcp_params_fp->gateway_mac));
14936 
14937 	wmi_mtrace(WMI_HB_SET_TCP_PARAMS_CMDID, NO_SESSION, 0);
14938 	status = wmi_unified_cmd_send(wmi_handle, buf,
14939 				      len, WMI_HB_SET_TCP_PARAMS_CMDID);
14940 	if (QDF_IS_STATUS_ERROR(status)) {
14941 		WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d",
14942 			status);
14943 		wmi_buf_free(buf);
14944 	}
14945 
14946 	return status;
14947 }
14948 
14949 /**
14950  * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd
14951  * @wmi_handle: wmi handle
14952  * @lphb_conf_req: lphb config request
14953  *
14954  * Return: CDF status
14955  */
14956 static
14957 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
14958 		wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp)
14959 {
14960 	QDF_STATUS status;
14961 	wmi_buf_t buf = NULL;
14962 	uint8_t *buf_ptr;
14963 	wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp;
14964 	int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param);
14965 
14966 	buf = wmi_buf_alloc(wmi_handle, len);
14967 	if (!buf) {
14968 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14969 		return QDF_STATUS_E_NOMEM;
14970 	}
14971 
14972 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14973 	hb_tcp_filter_fp =
14974 		(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr;
14975 	WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header,
14976 		WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param,
14977 		WMITLV_GET_STRUCT_TLVLEN
14978 		       (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param));
14979 
14980 	/* fill in values */
14981 	hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id;
14982 	hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length;
14983 	hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset;
14984 	hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session;
14985 	memcpy((void *)&hb_tcp_filter_fp->filter,
14986 	       (void *)&g_hb_tcp_filter_fp->filter,
14987 	       WMI_WLAN_HB_MAX_FILTER_SIZE);
14988 
14989 	wmi_mtrace(WMI_HB_SET_TCP_PKT_FILTER_CMDID, NO_SESSION, 0);
14990 	status = wmi_unified_cmd_send(wmi_handle, buf,
14991 				      len, WMI_HB_SET_TCP_PKT_FILTER_CMDID);
14992 	if (QDF_IS_STATUS_ERROR(status)) {
14993 		WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d",
14994 			status);
14995 		wmi_buf_free(buf);
14996 	}
14997 
14998 	return status;
14999 }
15000 
15001 /**
15002  * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB
15003  * @wmi_handle: wmi handle
15004  * @lphb_conf_req: lphb config request
15005  *
15006  * Return: CDF status
15007  */
15008 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle,
15009 		   wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req)
15010 {
15011 	QDF_STATUS status;
15012 	wmi_buf_t buf = NULL;
15013 	uint8_t *buf_ptr;
15014 	wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp;
15015 	int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param);
15016 
15017 	buf = wmi_buf_alloc(wmi_handle, len);
15018 	if (!buf) {
15019 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15020 		return QDF_STATUS_E_NOMEM;
15021 	}
15022 
15023 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15024 	hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr;
15025 	WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header,
15026 		       WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param,
15027 		       WMITLV_GET_STRUCT_TLVLEN
15028 			       (wmi_hb_set_udp_params_cmd_fixed_param));
15029 
15030 	/* fill in values */
15031 	hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id;
15032 	hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip;
15033 	hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip;
15034 	hb_udp_params_fp->src_port = lphb_conf_req->src_port;
15035 	hb_udp_params_fp->dst_port = lphb_conf_req->dst_port;
15036 	hb_udp_params_fp->interval = lphb_conf_req->interval;
15037 	hb_udp_params_fp->timeout = lphb_conf_req->timeout;
15038 	hb_udp_params_fp->session = lphb_conf_req->session;
15039 	qdf_mem_copy(&hb_udp_params_fp->gateway_mac,
15040 				   &lphb_conf_req->gateway_mac,
15041 				   sizeof(lphb_conf_req->gateway_mac));
15042 
15043 	wmi_mtrace(WMI_HB_SET_UDP_PARAMS_CMDID, NO_SESSION, 0);
15044 	status = wmi_unified_cmd_send(wmi_handle, buf,
15045 				      len, WMI_HB_SET_UDP_PARAMS_CMDID);
15046 	if (QDF_IS_STATUS_ERROR(status)) {
15047 		WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d",
15048 			status);
15049 		wmi_buf_free(buf);
15050 	}
15051 
15052 	return status;
15053 }
15054 
15055 /**
15056  * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command
15057  * @wmi_handle: wmi handle
15058  * @lphb_conf_req: lphb config request
15059  *
15060  * Return: CDF status
15061  */
15062 static
15063 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
15064 		wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req)
15065 {
15066 	QDF_STATUS status;
15067 	wmi_buf_t buf = NULL;
15068 	uint8_t *buf_ptr;
15069 	wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp;
15070 	int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param);
15071 
15072 	buf = wmi_buf_alloc(wmi_handle, len);
15073 	if (!buf) {
15074 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15075 		return QDF_STATUS_E_NOMEM;
15076 	}
15077 
15078 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15079 	hb_udp_filter_fp =
15080 		(wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr;
15081 	WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header,
15082 		WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param,
15083 		WMITLV_GET_STRUCT_TLVLEN
15084 		       (wmi_hb_set_udp_pkt_filter_cmd_fixed_param));
15085 
15086 	/* fill in values */
15087 	hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id;
15088 	hb_udp_filter_fp->length = lphb_conf_req->length;
15089 	hb_udp_filter_fp->offset = lphb_conf_req->offset;
15090 	hb_udp_filter_fp->session = lphb_conf_req->session;
15091 	memcpy((void *)&hb_udp_filter_fp->filter,
15092 	       (void *)&lphb_conf_req->filter,
15093 	       WMI_WLAN_HB_MAX_FILTER_SIZE);
15094 
15095 	wmi_mtrace(WMI_HB_SET_UDP_PKT_FILTER_CMDID, NO_SESSION, 0);
15096 	status = wmi_unified_cmd_send(wmi_handle, buf,
15097 				      len, WMI_HB_SET_UDP_PKT_FILTER_CMDID);
15098 	if (QDF_IS_STATUS_ERROR(status)) {
15099 		WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d",
15100 			status);
15101 		wmi_buf_free(buf);
15102 	}
15103 
15104 	return status;
15105 }
15106 #endif /* FEATURE_WLAN_LPHB */
15107 
15108 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi,
15109 					      struct pmo_hw_filter_params *req)
15110 {
15111 	QDF_STATUS status;
15112 	wmi_hw_data_filter_cmd_fixed_param *cmd;
15113 	wmi_buf_t wmi_buf;
15114 
15115 	if (!req) {
15116 		WMI_LOGE("req is null");
15117 		return QDF_STATUS_E_INVAL;
15118 	}
15119 
15120 	wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd));
15121 	if (!wmi_buf) {
15122 		WMI_LOGE(FL("Out of memory"));
15123 		return QDF_STATUS_E_NOMEM;
15124 	}
15125 
15126 	cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf);
15127 	WMITLV_SET_HDR(&cmd->tlv_header,
15128 		  WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param,
15129 		  WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param));
15130 	cmd->vdev_id = req->vdev_id;
15131 	cmd->enable = req->enable;
15132 	/* Set all modes in case of disable */
15133 	if (!cmd->enable)
15134 		cmd->hw_filter_bitmap = ((uint32_t)~0U);
15135 	else
15136 		cmd->hw_filter_bitmap = req->mode_bitmap;
15137 
15138 	WMI_LOGD("Send %s hw filter mode: 0x%X for vdev id %d",
15139 		 req->enable ? "enable" : "disable", req->mode_bitmap,
15140 		 req->vdev_id);
15141 
15142 	wmi_mtrace(WMI_HW_DATA_FILTER_CMDID, cmd->vdev_id, 0);
15143 	status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd),
15144 				      WMI_HW_DATA_FILTER_CMDID);
15145 	if (QDF_IS_STATUS_ERROR(status)) {
15146 		WMI_LOGE("Failed to configure hw filter");
15147 		wmi_buf_free(wmi_buf);
15148 	}
15149 
15150 	return status;
15151 }
15152 
15153 #ifdef WLAN_FEATURE_PACKET_FILTERING
15154 /**
15155  * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter
15156  * @wmi_handle: wmi handle
15157  * @vdev_id: vdev id
15158  * @enable: Flag to enable/disable packet filter
15159  *
15160  * Return: QDF_STATUS_SUCCESS for success or error code
15161  */
15162 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv(
15163 		wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable)
15164 {
15165 	int32_t len;
15166 	int ret = 0;
15167 	wmi_buf_t buf;
15168 	WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd;
15169 
15170 	len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param);
15171 
15172 	buf = wmi_buf_alloc(wmi_handle, len);
15173 	if (!buf) {
15174 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
15175 		return QDF_STATUS_E_NOMEM;
15176 	}
15177 
15178 	cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf);
15179 	WMITLV_SET_HDR(&cmd->tlv_header,
15180 		WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param,
15181 		WMITLV_GET_STRUCT_TLVLEN(
15182 		WMI_PACKET_FILTER_ENABLE_CMD_fixed_param));
15183 
15184 	cmd->vdev_id = vdev_id;
15185 	if (enable)
15186 		cmd->enable = PACKET_FILTER_SET_ENABLE;
15187 	else
15188 		cmd->enable = PACKET_FILTER_SET_DISABLE;
15189 
15190 	WMI_LOGE("%s: Packet filter enable %d for vdev_id %d",
15191 		__func__, cmd->enable, vdev_id);
15192 
15193 	wmi_mtrace(WMI_PACKET_FILTER_ENABLE_CMDID, cmd->vdev_id, 0);
15194 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
15195 			 WMI_PACKET_FILTER_ENABLE_CMDID);
15196 	if (ret) {
15197 		WMI_LOGE("Failed to send packet filter wmi cmd to fw");
15198 		wmi_buf_free(buf);
15199 	}
15200 
15201 	return ret;
15202 }
15203 
15204 /**
15205  * send_config_packet_filter_cmd_tlv() - configure packet filter in target
15206  * @wmi_handle: wmi handle
15207  * @vdev_id: vdev id
15208  * @rcv_filter_param: Packet filter parameters
15209  * @filter_id: Filter id
15210  * @enable: Flag to add/delete packet filter configuration
15211  *
15212  * Return: QDF_STATUS_SUCCESS for success or error code
15213  */
15214 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle,
15215 		uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param,
15216 		uint8_t filter_id, bool enable)
15217 {
15218 	int len, i;
15219 	int err = 0;
15220 	wmi_buf_t buf;
15221 	WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd;
15222 
15223 
15224 	/* allocate the memory */
15225 	len = sizeof(*cmd);
15226 	buf = wmi_buf_alloc(wmi_handle, len);
15227 	if (!buf) {
15228 		WMI_LOGE("Failed to allocate buffer to send set_param cmd");
15229 		return QDF_STATUS_E_NOMEM;
15230 	}
15231 
15232 	cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf);
15233 	WMITLV_SET_HDR(&cmd->tlv_header,
15234 		WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param,
15235 		WMITLV_GET_STRUCT_TLVLEN
15236 			       (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param));
15237 
15238 	cmd->vdev_id = vdev_id;
15239 	cmd->filter_id = filter_id;
15240 	if (enable)
15241 		cmd->filter_action = PACKET_FILTER_SET_ACTIVE;
15242 	else
15243 		cmd->filter_action = PACKET_FILTER_SET_INACTIVE;
15244 
15245 	if (enable) {
15246 		cmd->num_params = QDF_MIN(
15247 			WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER,
15248 			rcv_filter_param->num_params);
15249 		cmd->filter_type = rcv_filter_param->filter_type;
15250 		cmd->coalesce_time = rcv_filter_param->coalesce_time;
15251 
15252 		for (i = 0; i < cmd->num_params; i++) {
15253 			cmd->paramsData[i].proto_type =
15254 				rcv_filter_param->params_data[i].protocol_layer;
15255 			cmd->paramsData[i].cmp_type =
15256 				rcv_filter_param->params_data[i].compare_flag;
15257 			cmd->paramsData[i].data_length =
15258 				rcv_filter_param->params_data[i].data_length;
15259 			cmd->paramsData[i].data_offset =
15260 				rcv_filter_param->params_data[i].data_offset;
15261 			memcpy(&cmd->paramsData[i].compareData,
15262 				rcv_filter_param->params_data[i].compare_data,
15263 				sizeof(cmd->paramsData[i].compareData));
15264 			memcpy(&cmd->paramsData[i].dataMask,
15265 				rcv_filter_param->params_data[i].data_mask,
15266 				sizeof(cmd->paramsData[i].dataMask));
15267 		}
15268 	}
15269 
15270 	WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d",
15271 		cmd->filter_action, cmd->filter_id, cmd->num_params);
15272 	/* send the command along with data */
15273 	wmi_mtrace(WMI_PACKET_FILTER_CONFIG_CMDID, cmd->vdev_id, 0);
15274 	err = wmi_unified_cmd_send(wmi_handle, buf, len,
15275 				WMI_PACKET_FILTER_CONFIG_CMDID);
15276 	if (err) {
15277 		WMI_LOGE("Failed to send pkt_filter cmd");
15278 		wmi_buf_free(buf);
15279 		return QDF_STATUS_E_FAILURE;
15280 	}
15281 
15282 	return QDF_STATUS_SUCCESS;
15283 }
15284 #endif /* End of WLAN_FEATURE_PACKET_FILTERING */
15285 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */
15286 
15287 /**
15288  * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request
15289  * @wmi_handle: wmi handle
15290  * @request: SSID hotlist set request
15291  *
15292  * Return: QDF_STATUS enumeration
15293  */
15294 static QDF_STATUS
15295 send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle,
15296 		     struct ssid_hotlist_request_params *request)
15297 {
15298 	wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd;
15299 	wmi_buf_t wmi_buf;
15300 	uint32_t len;
15301 	uint32_t array_size;
15302 	uint8_t *buf_ptr;
15303 
15304 	/* length of fixed portion */
15305 	len = sizeof(*cmd);
15306 
15307 	/* length of variable portion */
15308 	array_size =
15309 		request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry);
15310 	len += WMI_TLV_HDR_SIZE + array_size;
15311 
15312 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15313 	if (!wmi_buf) {
15314 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
15315 		return QDF_STATUS_E_NOMEM;
15316 	}
15317 
15318 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
15319 	cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *)
15320 						buf_ptr;
15321 	WMITLV_SET_HDR
15322 		(&cmd->tlv_header,
15323 		 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param,
15324 		 WMITLV_GET_STRUCT_TLVLEN
15325 			(wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param));
15326 
15327 	cmd->request_id = request->request_id;
15328 	cmd->requestor_id = 0;
15329 	cmd->vdev_id = request->session_id;
15330 	cmd->table_id = 0;
15331 	cmd->lost_ap_scan_count = request->lost_ssid_sample_size;
15332 	cmd->total_entries = request->ssid_count;
15333 	cmd->num_entries_in_page = request->ssid_count;
15334 	cmd->first_entry_index = 0;
15335 
15336 	buf_ptr += sizeof(*cmd);
15337 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size);
15338 
15339 	if (request->ssid_count) {
15340 		wmi_extscan_hotlist_ssid_entry *entry;
15341 		int i;
15342 
15343 		buf_ptr += WMI_TLV_HDR_SIZE;
15344 		entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr;
15345 		for (i = 0; i < request->ssid_count; i++) {
15346 			WMITLV_SET_HDR
15347 				(entry,
15348 				 WMITLV_TAG_ARRAY_STRUC,
15349 				 WMITLV_GET_STRUCT_TLVLEN
15350 					(wmi_extscan_hotlist_ssid_entry));
15351 			entry->ssid.ssid_len = request->ssids[i].ssid.length;
15352 			qdf_mem_copy(entry->ssid.ssid,
15353 				     request->ssids[i].ssid.mac_ssid,
15354 				     request->ssids[i].ssid.length);
15355 			entry->band = request->ssids[i].band;
15356 			entry->min_rssi = request->ssids[i].rssi_low;
15357 			entry->max_rssi = request->ssids[i].rssi_high;
15358 			entry++;
15359 		}
15360 		cmd->mode = WMI_EXTSCAN_MODE_START;
15361 	} else {
15362 		cmd->mode = WMI_EXTSCAN_MODE_STOP;
15363 	}
15364 
15365 	wmi_mtrace(WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID,
15366 		   cmd->vdev_id, 0);
15367 	if (wmi_unified_cmd_send
15368 		(wmi_handle, wmi_buf, len,
15369 		 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) {
15370 		WMI_LOGE("%s: failed to send command", __func__);
15371 		wmi_buf_free(wmi_buf);
15372 		return QDF_STATUS_E_FAILURE;
15373 	}
15374 
15375 	return QDF_STATUS_SUCCESS;
15376 }
15377 
15378 /**
15379  * send_fw_test_cmd_tlv() - send fw test command to fw.
15380  * @wmi_handle: wmi handle
15381  * @wmi_fwtest: fw test command
15382  *
15383  * This function sends fw test command to fw.
15384  *
15385  * Return: CDF STATUS
15386  */
15387 static
15388 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle,
15389 			       struct set_fwtest_params *wmi_fwtest)
15390 {
15391 	wmi_fwtest_set_param_cmd_fixed_param *cmd;
15392 	wmi_buf_t wmi_buf;
15393 	uint16_t len;
15394 
15395 	len = sizeof(*cmd);
15396 
15397 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15398 	if (!wmi_buf) {
15399 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
15400 		return QDF_STATUS_E_NOMEM;
15401 	}
15402 
15403 	cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf);
15404 	WMITLV_SET_HDR(&cmd->tlv_header,
15405 		       WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param,
15406 		       WMITLV_GET_STRUCT_TLVLEN(
15407 		       wmi_fwtest_set_param_cmd_fixed_param));
15408 	cmd->param_id = wmi_fwtest->arg;
15409 	cmd->param_value = wmi_fwtest->value;
15410 
15411 	wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0);
15412 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15413 				 WMI_FWTEST_CMDID)) {
15414 		WMI_LOGP("%s: failed to send fw test command", __func__);
15415 		wmi_buf_free(wmi_buf);
15416 		return QDF_STATUS_E_FAILURE;
15417 	}
15418 
15419 	return QDF_STATUS_SUCCESS;
15420 }
15421 
15422 /**
15423  * send_unit_test_cmd_tlv() - send unit test command to fw.
15424  * @wmi_handle: wmi handle
15425  * @wmi_utest: unit test command
15426  *
15427  * This function send unit test command to fw.
15428  *
15429  * Return: CDF STATUS
15430  */
15431 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle,
15432 			       struct wmi_unit_test_cmd *wmi_utest)
15433 {
15434 	wmi_unit_test_cmd_fixed_param *cmd;
15435 	wmi_buf_t wmi_buf;
15436 	uint8_t *buf_ptr;
15437 	int i;
15438 	uint16_t len, args_tlv_len;
15439 	uint32_t *unit_test_cmd_args;
15440 
15441 	args_tlv_len =
15442 		WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t);
15443 	len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len;
15444 
15445 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15446 	if (!wmi_buf) {
15447 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
15448 		return QDF_STATUS_E_NOMEM;
15449 	}
15450 
15451 	cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf);
15452 	buf_ptr = (uint8_t *) cmd;
15453 	WMITLV_SET_HDR(&cmd->tlv_header,
15454 		       WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param,
15455 		       WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param));
15456 	cmd->vdev_id = wmi_utest->vdev_id;
15457 	cmd->module_id = wmi_utest->module_id;
15458 	cmd->num_args = wmi_utest->num_args;
15459 	cmd->diag_token = wmi_utest->diag_token;
15460 	buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param);
15461 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
15462 		       (wmi_utest->num_args * sizeof(uint32_t)));
15463 	unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
15464 	WMI_LOGI("%s: VDEV ID: %d\n", __func__, cmd->vdev_id);
15465 	WMI_LOGI("%s: MODULE ID: %d\n", __func__, cmd->module_id);
15466 	WMI_LOGI("%s: TOKEN: %d\n", __func__, cmd->diag_token);
15467 	WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args);
15468 	for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) {
15469 		unit_test_cmd_args[i] = wmi_utest->args[i];
15470 		WMI_LOGI("%d,", wmi_utest->args[i]);
15471 	}
15472 	wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0);
15473 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15474 				 WMI_UNIT_TEST_CMDID)) {
15475 		WMI_LOGP("%s: failed to send unit test command", __func__);
15476 		wmi_buf_free(wmi_buf);
15477 		return QDF_STATUS_E_FAILURE;
15478 	}
15479 
15480 	return QDF_STATUS_SUCCESS;
15481 }
15482 
15483 /**
15484  * send_roam_invoke_cmd_tlv() - send roam invoke command to fw.
15485  * @wmi_handle: wma handle
15486  * @roaminvoke: roam invoke command
15487  *
15488  * Send roam invoke command to fw for fastreassoc.
15489  *
15490  * Return: CDF STATUS
15491  */
15492 static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle,
15493 		struct wmi_roam_invoke_cmd *roaminvoke,
15494 		uint32_t ch_hz)
15495 {
15496 	wmi_roam_invoke_cmd_fixed_param *cmd;
15497 	wmi_buf_t wmi_buf;
15498 	u_int8_t *buf_ptr;
15499 	u_int16_t len, args_tlv_len;
15500 	uint32_t *channel_list;
15501 	wmi_mac_addr *bssid_list;
15502 	wmi_tlv_buf_len_param *buf_len_tlv;
15503 
15504 	/* Host sends only one channel and one bssid */
15505 	args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) +
15506 			sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) +
15507 			roundup(roaminvoke->frame_len, sizeof(uint32_t));
15508 	len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len;
15509 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15510 	if (!wmi_buf) {
15511 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
15512 		return QDF_STATUS_E_NOMEM;
15513 	}
15514 
15515 	cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf);
15516 	buf_ptr = (u_int8_t *) cmd;
15517 	WMITLV_SET_HDR(&cmd->tlv_header,
15518 	WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param,
15519 	WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param));
15520 	cmd->vdev_id = roaminvoke->vdev_id;
15521 	cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE);
15522 	if (roaminvoke->is_same_bssid)
15523 		cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP);
15524 	WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid);
15525 
15526 	if (roaminvoke->frame_len) {
15527 		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP;
15528 		/* packing 1 beacon/probe_rsp frame with WMI cmd */
15529 		cmd->num_buf = 1;
15530 	} else {
15531 		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH;
15532 		cmd->num_buf = 0;
15533 	}
15534 
15535 	cmd->roam_ap_sel_mode = 0;
15536 	cmd->roam_delay = 0;
15537 	cmd->num_chan = 1;
15538 	cmd->num_bssid = 1;
15539 
15540 	buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param);
15541 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
15542 				(sizeof(u_int32_t)));
15543 	channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
15544 	*channel_list = ch_hz;
15545 	buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE;
15546 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
15547 				(sizeof(wmi_mac_addr)));
15548 	bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
15549 	WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list);
15550 
15551 	/* move to next tlv i.e. bcn_prb_buf_list */
15552 	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr);
15553 
15554 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
15555 			sizeof(wmi_tlv_buf_len_param));
15556 
15557 	buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE);
15558 	buf_len_tlv->buf_len = roaminvoke->frame_len;
15559 
15560 	/* move to next tlv i.e. bcn_prb_frm */
15561 	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param);
15562 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
15563 		roundup(roaminvoke->frame_len, sizeof(uint32_t)));
15564 
15565 	/* copy frame after the header */
15566 	qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
15567 			roaminvoke->frame_buf,
15568 			roaminvoke->frame_len);
15569 
15570 	WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len);
15571 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
15572 			buf_ptr + WMI_TLV_HDR_SIZE,
15573 			roaminvoke->frame_len);
15574 	WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"),
15575 			cmd->flags, cmd->roam_scan_mode,
15576 			cmd->roam_ap_sel_mode, cmd->roam_delay,
15577 			cmd->num_chan, cmd->num_bssid);
15578 	WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz);
15579 
15580 	wmi_mtrace(WMI_ROAM_INVOKE_CMDID, cmd->vdev_id, 0);
15581 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15582 					WMI_ROAM_INVOKE_CMDID)) {
15583 		WMI_LOGP("%s: failed to send roam invoke command", __func__);
15584 		wmi_buf_free(wmi_buf);
15585 		return QDF_STATUS_E_FAILURE;
15586 	}
15587 
15588 	return QDF_STATUS_SUCCESS;
15589 }
15590 
15591 /**
15592  * send_roam_scan_offload_cmd_tlv() - set roam offload command
15593  * @wmi_handle: wmi handle
15594  * @command: command
15595  * @vdev_id: vdev id
15596  *
15597  * This function set roam offload command to fw.
15598  *
15599  * Return: CDF status
15600  */
15601 static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle,
15602 					 uint32_t command, uint32_t vdev_id)
15603 {
15604 	QDF_STATUS status;
15605 	wmi_roam_scan_cmd_fixed_param *cmd_fp;
15606 	wmi_buf_t buf = NULL;
15607 	int len;
15608 	uint8_t *buf_ptr;
15609 
15610 	len = sizeof(wmi_roam_scan_cmd_fixed_param);
15611 	buf = wmi_buf_alloc(wmi_handle, len);
15612 	if (!buf) {
15613 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15614 		return QDF_STATUS_E_NOMEM;
15615 	}
15616 
15617 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15618 
15619 	cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr;
15620 	WMITLV_SET_HDR(&cmd_fp->tlv_header,
15621 		       WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param,
15622 		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param));
15623 	cmd_fp->vdev_id = vdev_id;
15624 	cmd_fp->command_arg = command;
15625 
15626 	wmi_mtrace(WMI_ROAM_SCAN_CMD, NO_SESSION, 0);
15627 	status = wmi_unified_cmd_send(wmi_handle, buf,
15628 				      len, WMI_ROAM_SCAN_CMD);
15629 	if (QDF_IS_STATUS_ERROR(status)) {
15630 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d",
15631 			status);
15632 		goto error;
15633 	}
15634 
15635 	WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__);
15636 	return QDF_STATUS_SUCCESS;
15637 
15638 error:
15639 	wmi_buf_free(buf);
15640 
15641 	return status;
15642 }
15643 
15644 /**
15645  * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw
15646  * @wmi_handle: wmi handle
15647  * @ap_profile_p: ap profile
15648  * @vdev_id: vdev id
15649  *
15650  * Send WMI_ROAM_AP_PROFILE to firmware
15651  *
15652  * Return: CDF status
15653  */
15654 static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
15655 					    struct ap_profile_params *ap_profile)
15656 {
15657 	wmi_buf_t buf = NULL;
15658 	QDF_STATUS status;
15659 	int len;
15660 	uint8_t *buf_ptr;
15661 	wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp;
15662 	wmi_roam_cnd_scoring_param *score_param;
15663 	wmi_ap_profile *profile;
15664 
15665 	len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile);
15666 	len += sizeof(*score_param);
15667 	buf = wmi_buf_alloc(wmi_handle, len);
15668 	if (!buf) {
15669 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15670 		return QDF_STATUS_E_NOMEM;
15671 	}
15672 
15673 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15674 	roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr;
15675 	WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header,
15676 		       WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param,
15677 		       WMITLV_GET_STRUCT_TLVLEN
15678 			       (wmi_roam_ap_profile_fixed_param));
15679 	/* fill in threshold values */
15680 	roam_ap_profile_fp->vdev_id = ap_profile->vdev_id;
15681 	roam_ap_profile_fp->id = 0;
15682 	buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param);
15683 
15684 	profile = (wmi_ap_profile *)buf_ptr;
15685 	WMITLV_SET_HDR(&profile->tlv_header,
15686 		       WMITLV_TAG_STRUC_wmi_ap_profile,
15687 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile));
15688 	profile->flags = ap_profile->profile.flags;
15689 	profile->rssi_threshold = ap_profile->profile.rssi_threshold;
15690 	profile->ssid.ssid_len = ap_profile->profile.ssid.length;
15691 	qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid,
15692 		     profile->ssid.ssid_len);
15693 	profile->rsn_authmode = ap_profile->profile.rsn_authmode;
15694 	profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset;
15695 	profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset;
15696 	profile->rsn_mcastmgmtcipherset =
15697 				ap_profile->profile.rsn_mcastmgmtcipherset;
15698 	profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh;
15699 
15700 	WMI_LOGD("AP profile: flags %x rssi_threshold %d ssid:%.*s authmode %d uc cipher %d mc cipher %d mc mgmt cipher %d rssi abs thresh %d",
15701 		 profile->flags, profile->rssi_threshold,
15702 		 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid,
15703 		 profile->rsn_authmode, profile->rsn_ucastcipherset,
15704 		 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset,
15705 		 profile->rssi_abs_thresh);
15706 
15707 	buf_ptr += sizeof(wmi_ap_profile);
15708 
15709 	score_param = (wmi_roam_cnd_scoring_param *)buf_ptr;
15710 	WMITLV_SET_HDR(&score_param->tlv_header,
15711 		       WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param,
15712 		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param));
15713 	score_param->disable_bitmap = ap_profile->param.disable_bitmap;
15714 	score_param->rssi_weightage_pcnt =
15715 			ap_profile->param.rssi_weightage;
15716 	score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage;
15717 	score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage;
15718 	score_param->he_weightage_pcnt = ap_profile->param.he_weightage;
15719 	score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage;
15720 	score_param->band_weightage_pcnt = ap_profile->param.band_weightage;
15721 	score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage;
15722 	score_param->esp_qbss_weightage_pcnt =
15723 			ap_profile->param.esp_qbss_weightage;
15724 	score_param->beamforming_weightage_pcnt =
15725 			ap_profile->param.beamforming_weightage;
15726 	score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage;
15727 	score_param->oce_wan_weightage_pcnt =
15728 			ap_profile->param.oce_wan_weightage;
15729 
15730 	WMI_LOGD("Score params weightage: disable_bitmap %x rssi %d ht %d vht %d he %d BW %d band %d NSS %d ESP %d BF %d PCL %d OCE WAN %d",
15731 		 score_param->disable_bitmap, score_param->rssi_weightage_pcnt,
15732 		 score_param->ht_weightage_pcnt,
15733 		 score_param->vht_weightage_pcnt,
15734 		 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt,
15735 		 score_param->band_weightage_pcnt,
15736 		 score_param->nss_weightage_pcnt,
15737 		 score_param->esp_qbss_weightage_pcnt,
15738 		 score_param->beamforming_weightage_pcnt,
15739 		 score_param->pcl_weightage_pcnt,
15740 		 score_param->oce_wan_weightage_pcnt);
15741 
15742 	score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score;
15743 	score_param->band_scoring.score_pcnt =
15744 			ap_profile->param.band_index_score;
15745 	score_param->nss_scoring.score_pcnt =
15746 			ap_profile->param.nss_index_score;
15747 
15748 	WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x",
15749 		 score_param->bw_scoring.score_pcnt,
15750 		 score_param->band_scoring.score_pcnt,
15751 		 score_param->nss_scoring.score_pcnt);
15752 
15753 	score_param->rssi_scoring.best_rssi_threshold =
15754 		(-1) * ap_profile->param.rssi_scoring.best_rssi_threshold;
15755 	score_param->rssi_scoring.good_rssi_threshold =
15756 		(-1) * ap_profile->param.rssi_scoring.good_rssi_threshold;
15757 	score_param->rssi_scoring.bad_rssi_threshold =
15758 		(-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold;
15759 	score_param->rssi_scoring.good_rssi_pcnt =
15760 		ap_profile->param.rssi_scoring.good_rssi_pcnt;
15761 	score_param->rssi_scoring.bad_rssi_pcnt =
15762 		ap_profile->param.rssi_scoring.bad_rssi_pcnt;
15763 	score_param->rssi_scoring.good_bucket_size =
15764 		ap_profile->param.rssi_scoring.good_bucket_size;
15765 	score_param->rssi_scoring.bad_bucket_size =
15766 		ap_profile->param.rssi_scoring.bad_bucket_size;
15767 	score_param->rssi_scoring.rssi_pref_5g_rssi_thresh =
15768 		(-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh;
15769 
15770 	WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d",
15771 		 score_param->rssi_scoring.best_rssi_threshold,
15772 		 score_param->rssi_scoring.good_rssi_threshold,
15773 		 score_param->rssi_scoring.bad_rssi_threshold,
15774 		 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh);
15775 	WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d",
15776 		 score_param->rssi_scoring.good_rssi_pcnt,
15777 		 score_param->rssi_scoring.bad_rssi_pcnt,
15778 		 score_param->rssi_scoring.good_bucket_size,
15779 		 score_param->rssi_scoring.bad_bucket_size);
15780 
15781 	score_param->esp_qbss_scoring.num_slot =
15782 			ap_profile->param.esp_qbss_scoring.num_slot;
15783 	score_param->esp_qbss_scoring.score_pcnt3_to_0 =
15784 			ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0;
15785 	score_param->esp_qbss_scoring.score_pcnt7_to_4 =
15786 			ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4;
15787 	score_param->esp_qbss_scoring.score_pcnt11_to_8 =
15788 			ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8;
15789 	score_param->esp_qbss_scoring.score_pcnt15_to_12 =
15790 			ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12;
15791 
15792 	WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
15793 		 score_param->esp_qbss_scoring.num_slot,
15794 		 score_param->esp_qbss_scoring.score_pcnt3_to_0,
15795 		 score_param->esp_qbss_scoring.score_pcnt7_to_4,
15796 		 score_param->esp_qbss_scoring.score_pcnt11_to_8,
15797 		 score_param->esp_qbss_scoring.score_pcnt15_to_12);
15798 
15799 	score_param->oce_wan_scoring.num_slot =
15800 			ap_profile->param.oce_wan_scoring.num_slot;
15801 	score_param->oce_wan_scoring.score_pcnt3_to_0 =
15802 			ap_profile->param.oce_wan_scoring.score_pcnt3_to_0;
15803 	score_param->oce_wan_scoring.score_pcnt7_to_4 =
15804 			ap_profile->param.oce_wan_scoring.score_pcnt7_to_4;
15805 	score_param->oce_wan_scoring.score_pcnt11_to_8 =
15806 			ap_profile->param.oce_wan_scoring.score_pcnt11_to_8;
15807 	score_param->oce_wan_scoring.score_pcnt15_to_12 =
15808 			ap_profile->param.oce_wan_scoring.score_pcnt15_to_12;
15809 
15810 	WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
15811 		 score_param->oce_wan_scoring.num_slot,
15812 		 score_param->oce_wan_scoring.score_pcnt3_to_0,
15813 		 score_param->oce_wan_scoring.score_pcnt7_to_4,
15814 		 score_param->oce_wan_scoring.score_pcnt11_to_8,
15815 		 score_param->oce_wan_scoring.score_pcnt15_to_12);
15816 
15817 	wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0);
15818 	status = wmi_unified_cmd_send(wmi_handle, buf,
15819 				      len, WMI_ROAM_AP_PROFILE);
15820 	if (QDF_IS_STATUS_ERROR(status)) {
15821 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d",
15822 			status);
15823 		wmi_buf_free(buf);
15824 	}
15825 
15826 	WMI_LOGD("WMI --> WMI_ROAM_AP_PROFILE and other parameters");
15827 
15828 	return status;
15829 }
15830 
15831 /**
15832  * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period
15833  * @wmi_handle: wmi handle
15834  * @scan_period: scan period
15835  * @scan_age: scan age
15836  * @vdev_id: vdev id
15837  *
15838  * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
15839  *
15840  * Return: CDF status
15841  */
15842 static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle,
15843 					     uint32_t scan_period,
15844 					     uint32_t scan_age,
15845 					     uint32_t vdev_id)
15846 {
15847 	QDF_STATUS status;
15848 	wmi_buf_t buf = NULL;
15849 	int len;
15850 	uint8_t *buf_ptr;
15851 	wmi_roam_scan_period_fixed_param *scan_period_fp;
15852 
15853 	/* Send scan period values */
15854 	len = sizeof(wmi_roam_scan_period_fixed_param);
15855 	buf = wmi_buf_alloc(wmi_handle, len);
15856 	if (!buf) {
15857 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15858 		return QDF_STATUS_E_NOMEM;
15859 	}
15860 
15861 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15862 	scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr;
15863 	WMITLV_SET_HDR(&scan_period_fp->tlv_header,
15864 		       WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param,
15865 		       WMITLV_GET_STRUCT_TLVLEN
15866 			       (wmi_roam_scan_period_fixed_param));
15867 	/* fill in scan period values */
15868 	scan_period_fp->vdev_id = vdev_id;
15869 	scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */
15870 	scan_period_fp->roam_scan_age = scan_age;
15871 
15872 	wmi_mtrace(WMI_ROAM_SCAN_PERIOD, NO_SESSION, 0);
15873 	status = wmi_unified_cmd_send(wmi_handle, buf,
15874 				      len, WMI_ROAM_SCAN_PERIOD);
15875 	if (QDF_IS_STATUS_ERROR(status)) {
15876 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d",
15877 			status);
15878 		goto error;
15879 	}
15880 
15881 	WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d",
15882 		__func__, scan_period, scan_age);
15883 	return QDF_STATUS_SUCCESS;
15884 error:
15885 	wmi_buf_free(buf);
15886 
15887 	return status;
15888 }
15889 
15890 /**
15891  * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list
15892  * @wmi_handle: wmi handle
15893  * @chan_count: channel count
15894  * @chan_list: channel list
15895  * @list_type: list type
15896  * @vdev_id: vdev id
15897  *
15898  * Set roam offload channel list.
15899  *
15900  * Return: CDF status
15901  */
15902 static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
15903 				   uint8_t chan_count,
15904 				   uint32_t *chan_list,
15905 				   uint8_t list_type, uint32_t vdev_id)
15906 {
15907 	wmi_buf_t buf = NULL;
15908 	QDF_STATUS status;
15909 	int len, list_tlv_len;
15910 	int i;
15911 	uint8_t *buf_ptr;
15912 	wmi_roam_chan_list_fixed_param *chan_list_fp;
15913 	uint32_t *roam_chan_list_array;
15914 
15915 	if (chan_count == 0) {
15916 		WMI_LOGD("%s : invalid number of channels %d", __func__,
15917 			 chan_count);
15918 		return QDF_STATUS_E_EMPTY;
15919 	}
15920 	/* Channel list is a table of 2 TLV's */
15921 	list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t);
15922 	len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len;
15923 	buf = wmi_buf_alloc(wmi_handle, len);
15924 	if (!buf) {
15925 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15926 		return QDF_STATUS_E_NOMEM;
15927 	}
15928 
15929 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15930 	chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr;
15931 	WMITLV_SET_HDR(&chan_list_fp->tlv_header,
15932 		       WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param,
15933 		       WMITLV_GET_STRUCT_TLVLEN
15934 			       (wmi_roam_chan_list_fixed_param));
15935 	chan_list_fp->vdev_id = vdev_id;
15936 	chan_list_fp->num_chan = chan_count;
15937 	if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) {
15938 		/* external app is controlling channel list */
15939 		chan_list_fp->chan_list_type =
15940 			WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC;
15941 	} else {
15942 		/* umac supplied occupied channel list in LFR */
15943 		chan_list_fp->chan_list_type =
15944 			WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC;
15945 	}
15946 
15947 	buf_ptr += sizeof(wmi_roam_chan_list_fixed_param);
15948 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
15949 		       (chan_list_fp->num_chan * sizeof(uint32_t)));
15950 	roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
15951 	WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan);
15952 	for (i = 0; ((i < chan_list_fp->num_chan) &&
15953 		     (i < WMI_ROAM_MAX_CHANNELS)); i++) {
15954 		roam_chan_list_array[i] = chan_list[i];
15955 		WMI_LOGD("%d,", roam_chan_list_array[i]);
15956 	}
15957 
15958 	wmi_mtrace(WMI_ROAM_CHAN_LIST, NO_SESSION, 0);
15959 	status = wmi_unified_cmd_send(wmi_handle, buf,
15960 				      len, WMI_ROAM_CHAN_LIST);
15961 	if (QDF_IS_STATUS_ERROR(status)) {
15962 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d",
15963 			status);
15964 		goto error;
15965 	}
15966 
15967 	WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__);
15968 	return QDF_STATUS_SUCCESS;
15969 error:
15970 	wmi_buf_free(buf);
15971 
15972 	return status;
15973 }
15974 
15975 /**
15976  * send_per_roam_config_cmd_tlv() - set per roaming config to FW
15977  * @wmi_handle: wmi handle
15978  * @req_buf: per roam config buffer
15979  *
15980  * Return: QDF status
15981  */
15982 static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle,
15983 		struct wmi_per_roam_config_req *req_buf)
15984 {
15985 	wmi_buf_t buf = NULL;
15986 	QDF_STATUS status;
15987 	int len;
15988 	uint8_t *buf_ptr;
15989 	wmi_roam_per_config_fixed_param *wmi_per_config;
15990 
15991 	len = sizeof(wmi_roam_per_config_fixed_param);
15992 	buf = wmi_buf_alloc(wmi_handle, len);
15993 	if (!buf) {
15994 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15995 		return QDF_STATUS_E_NOMEM;
15996 	}
15997 
15998 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15999 	wmi_per_config =
16000 		(wmi_roam_per_config_fixed_param *) buf_ptr;
16001 	WMITLV_SET_HDR(&wmi_per_config->tlv_header,
16002 			WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param,
16003 			WMITLV_GET_STRUCT_TLVLEN
16004 			(wmi_roam_per_config_fixed_param));
16005 
16006 	/* fill in per roam config values */
16007 	wmi_per_config->vdev_id = req_buf->vdev_id;
16008 
16009 	wmi_per_config->enable = req_buf->per_config.enable;
16010 	wmi_per_config->high_rate_thresh =
16011 		(req_buf->per_config.tx_high_rate_thresh << 16) |
16012 		(req_buf->per_config.rx_high_rate_thresh & 0x0000ffff);
16013 	wmi_per_config->low_rate_thresh =
16014 		(req_buf->per_config.tx_low_rate_thresh << 16) |
16015 		(req_buf->per_config.rx_low_rate_thresh & 0x0000ffff);
16016 	wmi_per_config->pkt_err_rate_thresh_pct =
16017 		(req_buf->per_config.tx_rate_thresh_percnt << 16) |
16018 		(req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff);
16019 	wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time;
16020 	wmi_per_config->pkt_err_rate_mon_time =
16021 			(req_buf->per_config.tx_per_mon_time << 16) |
16022 			(req_buf->per_config.rx_per_mon_time & 0x0000ffff);
16023 	wmi_per_config->min_candidate_rssi =
16024 			req_buf->per_config.min_candidate_rssi;
16025 
16026 	/* Send per roam config parameters */
16027 	wmi_mtrace(WMI_ROAM_PER_CONFIG_CMDID, NO_SESSION, 0);
16028 	status = wmi_unified_cmd_send(wmi_handle, buf,
16029 			len, WMI_ROAM_PER_CONFIG_CMDID);
16030 	if (QDF_IS_STATUS_ERROR(status)) {
16031 		WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d",
16032 			 status);
16033 		wmi_buf_free(buf);
16034 		return status;
16035 	}
16036 	WMI_LOGD(FL("per roam enable=%d, vdev=%d"),
16037 		 req_buf->per_config.enable, req_buf->vdev_id);
16038 
16039 	return QDF_STATUS_SUCCESS;
16040 }
16041 
16042 /**
16043  * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th
16044  * @wmi_handle: wmi handle
16045  * @rssi_change_thresh: RSSI Change threshold
16046  * @bcn_rssi_weight: beacon RSSI weight
16047  * @vdev_id: vdev id
16048  *
16049  * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
16050  *
16051  * Return: CDF status
16052  */
16053 static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle,
16054 	uint32_t vdev_id,
16055 	int32_t rssi_change_thresh,
16056 	uint32_t bcn_rssi_weight,
16057 	uint32_t hirssi_delay_btw_scans)
16058 {
16059 	wmi_buf_t buf = NULL;
16060 	QDF_STATUS status;
16061 	int len;
16062 	uint8_t *buf_ptr;
16063 	wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp;
16064 
16065 	/* Send rssi change parameters */
16066 	len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param);
16067 	buf = wmi_buf_alloc(wmi_handle, len);
16068 	if (!buf) {
16069 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16070 		return QDF_STATUS_E_NOMEM;
16071 	}
16072 
16073 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16074 	rssi_change_fp =
16075 		(wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr;
16076 	WMITLV_SET_HDR(&rssi_change_fp->tlv_header,
16077 		       WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param,
16078 		       WMITLV_GET_STRUCT_TLVLEN
16079 			       (wmi_roam_scan_rssi_change_threshold_fixed_param));
16080 	/* fill in rssi change threshold (hysteresis) values */
16081 	rssi_change_fp->vdev_id = vdev_id;
16082 	rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh;
16083 	rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight;
16084 	rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans;
16085 
16086 	wmi_mtrace(WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, NO_SESSION, 0);
16087 	status = wmi_unified_cmd_send(wmi_handle, buf,
16088 				      len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD);
16089 	if (QDF_IS_STATUS_ERROR(status)) {
16090 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d",
16091 			status);
16092 		goto error;
16093 	}
16094 
16095 	WMI_LOGD(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"),
16096 		 rssi_change_thresh, bcn_rssi_weight);
16097 	WMI_LOGD(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans);
16098 	return QDF_STATUS_SUCCESS;
16099 error:
16100 	wmi_buf_free(buf);
16101 
16102 	return status;
16103 }
16104 
16105 /**
16106  * send_power_dbg_cmd_tlv() - send power debug commands
16107  * @wmi_handle: wmi handle
16108  * @param: wmi power debug parameter
16109  *
16110  * Send WMI_POWER_DEBUG_CMDID parameters to fw.
16111  *
16112  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16113  */
16114 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle,
16115 					 struct wmi_power_dbg_params *param)
16116 {
16117 	wmi_buf_t buf = NULL;
16118 	QDF_STATUS status;
16119 	int len, args_tlv_len;
16120 	uint8_t *buf_ptr;
16121 	uint8_t i;
16122 	wmi_pdev_wal_power_debug_cmd_fixed_param *cmd;
16123 	uint32_t *cmd_args;
16124 
16125 	/* Prepare and send power debug cmd parameters */
16126 	args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t);
16127 	len = sizeof(*cmd) + args_tlv_len;
16128 	buf = wmi_buf_alloc(wmi_handle, len);
16129 	if (!buf) {
16130 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16131 		return QDF_STATUS_E_NOMEM;
16132 	}
16133 
16134 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16135 	cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr;
16136 	WMITLV_SET_HDR(&cmd->tlv_header,
16137 		  WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param,
16138 		  WMITLV_GET_STRUCT_TLVLEN
16139 		  (wmi_pdev_wal_power_debug_cmd_fixed_param));
16140 
16141 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
16142 								param->pdev_id);
16143 	cmd->module_id = param->module_id;
16144 	cmd->num_args = param->num_args;
16145 	buf_ptr += sizeof(*cmd);
16146 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
16147 		       (param->num_args * sizeof(uint32_t)));
16148 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
16149 	WMI_LOGI("%s: %d num of args = ", __func__, param->num_args);
16150 	for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) {
16151 		cmd_args[i] = param->args[i];
16152 		WMI_LOGI("%d,", param->args[i]);
16153 	}
16154 
16155 	wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0);
16156 	status = wmi_unified_cmd_send(wmi_handle, buf,
16157 				      len, WMI_PDEV_WAL_POWER_DEBUG_CMDID);
16158 	if (QDF_IS_STATUS_ERROR(status)) {
16159 		WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d",
16160 			status);
16161 		goto error;
16162 	}
16163 
16164 	return QDF_STATUS_SUCCESS;
16165 error:
16166 	wmi_buf_free(buf);
16167 
16168 	return status;
16169 }
16170 
16171 /**
16172  * send_multiple_vdev_restart_req_cmd_tlv() - send multiple vdev restart req
16173  * @wmi_handle: wmi handle
16174  * @param: wmi multiple vdev restart req param
16175  *
16176  * Send WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID parameters to fw.
16177  *
16178  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16179  */
16180 static QDF_STATUS send_multiple_vdev_restart_req_cmd_tlv(
16181 				wmi_unified_t wmi_handle,
16182 				struct multiple_vdev_restart_params *param)
16183 {
16184 	wmi_buf_t buf;
16185 	QDF_STATUS qdf_status;
16186 	wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *cmd;
16187 	int i;
16188 	uint8_t *buf_ptr;
16189 	uint32_t *vdev_ids;
16190 	wmi_channel *chan_info;
16191 	struct channel_param *tchan_info;
16192 	uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
16193 
16194 	len += sizeof(wmi_channel);
16195 	if (param->num_vdevs)
16196 		len += sizeof(uint32_t) * param->num_vdevs;
16197 
16198 	buf = wmi_buf_alloc(wmi_handle, len);
16199 	if (!buf) {
16200 		WMI_LOGE("Failed to allocate memory\n");
16201 		qdf_status = QDF_STATUS_E_NOMEM;
16202 		goto end;
16203 	}
16204 
16205 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
16206 	cmd = (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *)
16207 	       buf_ptr;
16208 
16209 	WMITLV_SET_HDR(&cmd->tlv_header,
16210 	WMITLV_TAG_STRUC_wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param,
16211 	WMITLV_GET_STRUCT_TLVLEN
16212 		(wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param));
16213 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
16214 								param->pdev_id);
16215 	cmd->requestor_id = param->requestor_id;
16216 	cmd->disable_hw_ack = param->disable_hw_ack;
16217 	cmd->cac_duration_ms = param->cac_duration_ms;
16218 	cmd->num_vdevs = param->num_vdevs;
16219 
16220 	WMI_LOGI("%s:cmd->pdev_id: %d ,cmd->requestor_id: %d ,"
16221 		"cmd->disable_hw_ack: %d , cmd->cac_duration_ms:%d ,"
16222 		" cmd->num_vdevs: %d ",
16223 		__func__, cmd->pdev_id, cmd->requestor_id,
16224 		cmd->disable_hw_ack, cmd->cac_duration_ms, cmd->num_vdevs);
16225 	buf_ptr += sizeof(*cmd);
16226 
16227 	WMITLV_SET_HDR(buf_ptr,
16228 		       WMITLV_TAG_ARRAY_UINT32,
16229 		       sizeof(uint32_t) * param->num_vdevs);
16230 	vdev_ids = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
16231 	for (i = 0; i < param->num_vdevs; i++) {
16232 		vdev_ids[i] = param->vdev_ids[i];
16233 	}
16234 
16235 	buf_ptr += (sizeof(uint32_t) * param->num_vdevs) + WMI_TLV_HDR_SIZE;
16236 
16237 	WMITLV_SET_HDR(buf_ptr,
16238 		       WMITLV_TAG_STRUC_wmi_channel,
16239 		       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
16240 	chan_info = (wmi_channel *)buf_ptr;
16241 	tchan_info = &(param->ch_param);
16242 	chan_info->mhz = tchan_info->mhz;
16243 	chan_info->band_center_freq1 = tchan_info->cfreq1;
16244 	chan_info->band_center_freq2 = tchan_info->cfreq2;
16245 	if (tchan_info->is_chan_passive)
16246 		WMI_SET_CHANNEL_FLAG(chan_info,
16247 				     WMI_CHAN_FLAG_PASSIVE);
16248 	if (tchan_info->dfs_set)
16249 		WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS);
16250 
16251 	if (tchan_info->allow_vht)
16252 		WMI_SET_CHANNEL_FLAG(chan_info,
16253 				     WMI_CHAN_FLAG_ALLOW_VHT);
16254 	else  if (tchan_info->allow_ht)
16255 		WMI_SET_CHANNEL_FLAG(chan_info,
16256 				     WMI_CHAN_FLAG_ALLOW_HT);
16257 	WMI_SET_CHANNEL_MODE(chan_info, tchan_info->phy_mode);
16258 	WMI_SET_CHANNEL_MIN_POWER(chan_info, tchan_info->minpower);
16259 	WMI_SET_CHANNEL_MAX_POWER(chan_info, tchan_info->maxpower);
16260 	WMI_SET_CHANNEL_REG_POWER(chan_info, tchan_info->maxregpower);
16261 	WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, tchan_info->antennamax);
16262 	WMI_SET_CHANNEL_REG_CLASSID(chan_info, tchan_info->reg_class_id);
16263 	WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, tchan_info->maxregpower);
16264 
16265 	WMI_LOGI("%s:tchan_info->is_chan_passive: %d ,"
16266 		"tchan_info->dfs_set : %d ,tchan_info->allow_vht:%d ,"
16267 		"tchan_info->allow_ht: %d ,tchan_info->antennamax: %d ,"
16268 		"tchan_info->phy_mode: %d ,tchan_info->minpower: %d,"
16269 		"tchan_info->maxpower: %d ,tchan_info->maxregpower: %d ,"
16270 		"tchan_info->reg_class_id: %d ,"
16271 		"tchan_info->maxregpower : %d ", __func__,
16272 		tchan_info->is_chan_passive, tchan_info->dfs_set,
16273 		tchan_info->allow_vht, tchan_info->allow_ht,
16274 		tchan_info->antennamax, tchan_info->phy_mode,
16275 		tchan_info->minpower, tchan_info->maxpower,
16276 		tchan_info->maxregpower, tchan_info->reg_class_id,
16277 		tchan_info->maxregpower);
16278 
16279 	wmi_mtrace(WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID, NO_SESSION, 0);
16280 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
16281 				WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID);
16282 
16283 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
16284 		WMI_LOGE("%s: Failed to send\n", __func__);
16285 		wmi_buf_free(buf);
16286 	}
16287 
16288 end:
16289 	return qdf_status;
16290 }
16291 
16292 /**
16293  * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd
16294  * @wmi_handle: wmi handle
16295  * @pdev_id: pdev id
16296  *
16297  * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware.
16298  *
16299  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16300  */
16301 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle,
16302 		uint32_t pdev_id)
16303 {
16304 	wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd;
16305 	wmi_buf_t buf;
16306 	uint16_t len;
16307 	QDF_STATUS ret;
16308 
16309 	len = sizeof(*cmd);
16310 	buf = wmi_buf_alloc(wmi_handle, len);
16311 
16312 	WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id);
16313 
16314 	if (!buf) {
16315 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16316 		return QDF_STATUS_E_NOMEM;
16317 	}
16318 
16319 	cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *)
16320 		wmi_buf_data(buf);
16321 
16322 	WMITLV_SET_HDR(&cmd->tlv_header,
16323 	WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param,
16324 	WMITLV_GET_STRUCT_TLVLEN(
16325 		wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param));
16326 
16327 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
16328 	wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0);
16329 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
16330 			WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID);
16331 	if (QDF_IS_STATUS_ERROR(ret)) {
16332 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d",
16333 			__func__, ret, pdev_id);
16334 		wmi_buf_free(buf);
16335 		return QDF_STATUS_E_FAILURE;
16336 	}
16337 
16338 	return QDF_STATUS_SUCCESS;
16339 }
16340 
16341 /**
16342  * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd
16343  * @wmi_handle: wmi handle
16344  * @pdev_id: pdev id
16345  *
16346  * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware.
16347  *
16348  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16349  */
16350 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle,
16351 		uint32_t pdev_id)
16352 {
16353 	wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd;
16354 	wmi_buf_t buf;
16355 	uint16_t len;
16356 	QDF_STATUS ret;
16357 
16358 	len = sizeof(*cmd);
16359 	buf = wmi_buf_alloc(wmi_handle, len);
16360 
16361 	WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id);
16362 
16363 	if (!buf) {
16364 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16365 		return QDF_STATUS_E_NOMEM;
16366 	}
16367 
16368 	cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *)
16369 		wmi_buf_data(buf);
16370 
16371 	WMITLV_SET_HDR(&cmd->tlv_header,
16372 	WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param,
16373 	WMITLV_GET_STRUCT_TLVLEN(
16374 		wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param));
16375 
16376 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
16377 	wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0);
16378 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
16379 			WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID);
16380 	if (QDF_IS_STATUS_ERROR(ret)) {
16381 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d",
16382 			__func__, ret, pdev_id);
16383 		wmi_buf_free(buf);
16384 		return QDF_STATUS_E_FAILURE;
16385 	}
16386 
16387 	return QDF_STATUS_SUCCESS;
16388 }
16389 
16390 /**
16391  * init_cmd_send_tlv() - send initialization cmd to fw
16392  * @wmi_handle: wmi handle
16393  * @param param: pointer to wmi init param
16394  *
16395  * Return: QDF_STATUS_SUCCESS for success or error code
16396  */
16397 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle,
16398 				struct wmi_init_cmd_param *param)
16399 {
16400 	wmi_buf_t buf;
16401 	wmi_init_cmd_fixed_param *cmd;
16402 	uint8_t *buf_ptr;
16403 	wmi_resource_config *resource_cfg;
16404 	wlan_host_memory_chunk *host_mem_chunks;
16405 	uint32_t mem_chunk_len = 0, hw_mode_len = 0;
16406 	uint16_t idx;
16407 	int len;
16408 	QDF_STATUS ret;
16409 
16410 	len = sizeof(*cmd) + sizeof(wmi_resource_config) +
16411 		WMI_TLV_HDR_SIZE;
16412 	mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS);
16413 
16414 	if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX)
16415 		hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) +
16416 			WMI_TLV_HDR_SIZE +
16417 			(param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac));
16418 
16419 	buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len);
16420 	if (!buf) {
16421 		qdf_print("%s: wmi_buf_alloc failed", __func__);
16422 		return QDF_STATUS_E_FAILURE;
16423 	}
16424 
16425 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16426 	cmd = (wmi_init_cmd_fixed_param *) buf_ptr;
16427 	resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd));
16428 
16429 	host_mem_chunks = (wlan_host_memory_chunk *)
16430 		(buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)
16431 		 + WMI_TLV_HDR_SIZE);
16432 
16433 	WMITLV_SET_HDR(&cmd->tlv_header,
16434 			WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param,
16435 			WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param));
16436 
16437 	wmi_copy_resource_config(resource_cfg, param->res_cfg);
16438 	WMITLV_SET_HDR(&resource_cfg->tlv_header,
16439 			WMITLV_TAG_STRUC_wmi_resource_config,
16440 			WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config));
16441 
16442 	for (idx = 0; idx < param->num_mem_chunks; ++idx) {
16443 		WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header),
16444 				WMITLV_TAG_STRUC_wlan_host_memory_chunk,
16445 				WMITLV_GET_STRUCT_TLVLEN
16446 				(wlan_host_memory_chunk));
16447 		host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr;
16448 		host_mem_chunks[idx].size = param->mem_chunks[idx].len;
16449 		host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id;
16450 		QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG,
16451 				"chunk %d len %d requested ,ptr  0x%x ",
16452 				idx, host_mem_chunks[idx].size,
16453 				host_mem_chunks[idx].ptr);
16454 	}
16455 	cmd->num_host_mem_chunks = param->num_mem_chunks;
16456 	len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk));
16457 
16458 	WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)),
16459 			WMITLV_TAG_ARRAY_STRUC,
16460 			(sizeof(wlan_host_memory_chunk) *
16461 			 param->num_mem_chunks));
16462 
16463 	/* Fill hw mode id config */
16464 	buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param);
16465 
16466 	/* Fill fw_abi_vers */
16467 	copy_fw_abi_version_tlv(wmi_handle, cmd);
16468 
16469 	wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0);
16470 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID);
16471 	if (QDF_IS_STATUS_ERROR(ret)) {
16472 		WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d",
16473 			ret);
16474 		wmi_buf_free(buf);
16475 	}
16476 
16477 	return ret;
16478 
16479 }
16480 
16481 /**
16482  * send_addba_send_cmd_tlv() - send addba send command to fw
16483  * @wmi_handle: wmi handle
16484  * @param: pointer to delba send params
16485  * @macaddr: peer mac address
16486  *
16487  * Send WMI_ADDBA_SEND_CMDID command to firmware
16488  * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error
16489  */
16490 static QDF_STATUS
16491 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle,
16492 				uint8_t macaddr[IEEE80211_ADDR_LEN],
16493 				struct addba_send_params *param)
16494 {
16495 	wmi_addba_send_cmd_fixed_param *cmd;
16496 	wmi_buf_t buf;
16497 	uint16_t len;
16498 	QDF_STATUS ret;
16499 
16500 	len = sizeof(*cmd);
16501 
16502 	buf = wmi_buf_alloc(wmi_handle, len);
16503 	if (!buf) {
16504 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16505 		return QDF_STATUS_E_NOMEM;
16506 	}
16507 
16508 	cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf);
16509 
16510 	WMITLV_SET_HDR(&cmd->tlv_header,
16511 			WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param,
16512 			WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param));
16513 
16514 	cmd->vdev_id = param->vdev_id;
16515 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
16516 	cmd->tid = param->tidno;
16517 	cmd->buffersize = param->buffersize;
16518 
16519 	wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0);
16520 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID);
16521 	if (QDF_IS_STATUS_ERROR(ret)) {
16522 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret);
16523 		wmi_buf_free(buf);
16524 		return QDF_STATUS_E_FAILURE;
16525 	}
16526 
16527 	return QDF_STATUS_SUCCESS;
16528 }
16529 
16530 /**
16531  * send_delba_send_cmd_tlv() - send delba send command to fw
16532  * @wmi_handle: wmi handle
16533  * @param: pointer to delba send params
16534  * @macaddr: peer mac address
16535  *
16536  * Send WMI_DELBA_SEND_CMDID command to firmware
16537  * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error
16538  */
16539 static QDF_STATUS
16540 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle,
16541 				uint8_t macaddr[IEEE80211_ADDR_LEN],
16542 				struct delba_send_params *param)
16543 {
16544 	wmi_delba_send_cmd_fixed_param *cmd;
16545 	wmi_buf_t buf;
16546 	uint16_t len;
16547 	QDF_STATUS ret;
16548 
16549 	len = sizeof(*cmd);
16550 
16551 	buf = wmi_buf_alloc(wmi_handle, len);
16552 	if (!buf) {
16553 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16554 		return QDF_STATUS_E_NOMEM;
16555 	}
16556 
16557 	cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf);
16558 
16559 	WMITLV_SET_HDR(&cmd->tlv_header,
16560 			WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param,
16561 			WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param));
16562 
16563 	cmd->vdev_id = param->vdev_id;
16564 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
16565 	cmd->tid = param->tidno;
16566 	cmd->initiator = param->initiator;
16567 	cmd->reasoncode = param->reasoncode;
16568 
16569 	wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0);
16570 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID);
16571 	if (QDF_IS_STATUS_ERROR(ret)) {
16572 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret);
16573 		wmi_buf_free(buf);
16574 		return QDF_STATUS_E_FAILURE;
16575 	}
16576 
16577 	return QDF_STATUS_SUCCESS;
16578 }
16579 
16580 /**
16581  * send_addba_clearresponse_cmd_tlv() - send addba clear response command
16582  * to fw
16583  * @wmi_handle: wmi handle
16584  * @param: pointer to addba clearresp params
16585  * @macaddr: peer mac address
16586  * Return: 0 for success or error code
16587  */
16588 static QDF_STATUS
16589 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle,
16590 			uint8_t macaddr[IEEE80211_ADDR_LEN],
16591 			struct addba_clearresponse_params *param)
16592 {
16593 	wmi_addba_clear_resp_cmd_fixed_param *cmd;
16594 	wmi_buf_t buf;
16595 	uint16_t len;
16596 	QDF_STATUS ret;
16597 
16598 	len = sizeof(*cmd);
16599 
16600 	buf = wmi_buf_alloc(wmi_handle, len);
16601 	if (!buf) {
16602 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
16603 		return QDF_STATUS_E_FAILURE;
16604 	}
16605 	cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf);
16606 
16607 	WMITLV_SET_HDR(&cmd->tlv_header,
16608 		WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param,
16609 		WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param));
16610 
16611 	cmd->vdev_id = param->vdev_id;
16612 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
16613 
16614 	wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0);
16615 	ret = wmi_unified_cmd_send(wmi_handle,
16616 				buf, len, WMI_ADDBA_CLEAR_RESP_CMDID);
16617 	if (QDF_IS_STATUS_ERROR(ret)) {
16618 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret);
16619 		wmi_buf_free(buf);
16620 		return QDF_STATUS_E_FAILURE;
16621 	}
16622 
16623 	return QDF_STATUS_SUCCESS;
16624 }
16625 
16626 /**
16627  * send_bcn_offload_control_cmd_tlv - send beacon ofload control cmd to fw
16628  * @wmi_handle: wmi handle
16629  * @bcn_ctrl_param: pointer to bcn_offload_control param
16630  *
16631  * Return: QDF_STATUS_SUCCESS for success or error code
16632  */
16633 static
16634 QDF_STATUS send_bcn_offload_control_cmd_tlv(wmi_unified_t wmi_handle,
16635 			struct bcn_offload_control *bcn_ctrl_param)
16636 {
16637 	wmi_buf_t buf;
16638 	wmi_bcn_offload_ctrl_cmd_fixed_param *cmd;
16639 	QDF_STATUS ret;
16640 	uint32_t len;
16641 
16642 	len = sizeof(*cmd);
16643 
16644 	buf = wmi_buf_alloc(wmi_handle, len);
16645 	if (!buf) {
16646 		qdf_print("%s: wmi_buf_alloc failed", __func__);
16647 		return QDF_STATUS_E_FAILURE;
16648 	}
16649 
16650 	cmd = (wmi_bcn_offload_ctrl_cmd_fixed_param *) wmi_buf_data(buf);
16651 	WMITLV_SET_HDR(&cmd->tlv_header,
16652 			WMITLV_TAG_STRUC_wmi_bcn_offload_ctrl_cmd_fixed_param,
16653 			WMITLV_GET_STRUCT_TLVLEN
16654 			(wmi_bcn_offload_ctrl_cmd_fixed_param));
16655 	cmd->vdev_id = bcn_ctrl_param->vdev_id;
16656 	switch (bcn_ctrl_param->bcn_ctrl_op) {
16657 	case BCN_OFFLD_CTRL_TX_DISABLE:
16658 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_DISABLE;
16659 		break;
16660 	case BCN_OFFLD_CTRL_TX_ENABLE:
16661 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_ENABLE;
16662 		break;
16663 	case BCN_OFFLD_CTRL_SWBA_DISABLE:
16664 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_DISABLE;
16665 		break;
16666 	case BCN_OFFLD_CTRL_SWBA_ENABLE:
16667 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_ENABLE;
16668 		break;
16669 	default:
16670 		WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID unknown CTRL Operation %d",
16671 			bcn_ctrl_param->bcn_ctrl_op);
16672 		wmi_buf_free(buf);
16673 		return QDF_STATUS_E_FAILURE;
16674 		break;
16675 	}
16676 	wmi_mtrace(WMI_BCN_OFFLOAD_CTRL_CMDID, cmd->vdev_id, 0);
16677 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
16678 			WMI_BCN_OFFLOAD_CTRL_CMDID);
16679 
16680 	if (QDF_IS_STATUS_ERROR(ret)) {
16681 		WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID send returned Error %d",
16682 				ret);
16683 		wmi_buf_free(buf);
16684 	}
16685 
16686 	return ret;
16687 }
16688 
16689 #ifdef OBSS_PD
16690 /**
16691  * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw
16692  * @wmi_handle: wmi handle
16693  * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param
16694  *
16695  * Return: QDF_STATUS_SUCCESS for success or error code
16696  */
16697 static
16698 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle,
16699 			struct wmi_host_obss_spatial_reuse_set_param
16700 			*obss_spatial_reuse_param)
16701 {
16702 	wmi_buf_t buf;
16703 	wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd;
16704 	QDF_STATUS ret;
16705 	uint32_t len;
16706 
16707 	len = sizeof(*cmd);
16708 
16709 	buf = wmi_buf_alloc(wmi_handle, len);
16710 	if (!buf) {
16711 		qdf_print("%s: wmi_buf_alloc failed\n", __func__);
16712 		return QDF_STATUS_E_FAILURE;
16713 	}
16714 
16715 	cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf);
16716 	WMITLV_SET_HDR(&cmd->tlv_header,
16717 		WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param,
16718 		WMITLV_GET_STRUCT_TLVLEN
16719 		(wmi_obss_spatial_reuse_set_cmd_fixed_param));
16720 
16721 	cmd->enable = obss_spatial_reuse_param->enable;
16722 	cmd->obss_min = obss_spatial_reuse_param->obss_min;
16723 	cmd->obss_max = obss_spatial_reuse_param->obss_max;
16724 	cmd->vdev_id = obss_spatial_reuse_param->vdev_id;
16725 
16726 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
16727 			WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID);
16728 
16729 	if (QDF_IS_STATUS_ERROR(ret)) {
16730 		WMI_LOGE(
16731 		 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d",
16732 		 ret);
16733 		wmi_buf_free(buf);
16734 	}
16735 
16736 	return ret;
16737 }
16738 #endif
16739 
16740 #ifdef WLAN_FEATURE_NAN_CONVERGENCE
16741 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle,
16742 				struct nan_datapath_initiator_req *ndp_req)
16743 {
16744 	uint16_t len;
16745 	wmi_buf_t buf;
16746 	uint8_t *tlv_ptr;
16747 	QDF_STATUS status;
16748 	wmi_channel *ch_tlv;
16749 	wmi_ndp_initiator_req_fixed_param *cmd;
16750 	uint32_t passphrase_len, service_name_len;
16751 	uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len;
16752 	wmi_ndp_transport_ip_param *tcp_ip_param;
16753 
16754 	/*
16755 	 * WMI command expects 4 byte alligned len:
16756 	 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes
16757 	 */
16758 	ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4);
16759 	ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4);
16760 	pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4);
16761 	passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4);
16762 	service_name_len =
16763 		   qdf_roundup(ndp_req->service_name.service_name_len, 4);
16764 	/* allocated memory for fixed params as well as variable size data */
16765 	len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE)
16766 		+ ndp_cfg_len + ndp_app_info_len + pmk_len
16767 		+ passphrase_len + service_name_len;
16768 
16769 	if (ndp_req->is_ipv6_addr_present)
16770 		len += sizeof(*tcp_ip_param);
16771 
16772 	buf = wmi_buf_alloc(wmi_handle, len);
16773 	if (!buf) {
16774 		WMI_LOGE("wmi_buf_alloc failed");
16775 		return QDF_STATUS_E_NOMEM;
16776 	}
16777 
16778 	cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf);
16779 	WMITLV_SET_HDR(&cmd->tlv_header,
16780 		       WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param,
16781 		       WMITLV_GET_STRUCT_TLVLEN(
16782 				wmi_ndp_initiator_req_fixed_param));
16783 	cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev);
16784 	cmd->transaction_id = ndp_req->transaction_id;
16785 	cmd->service_instance_id = ndp_req->service_instance_id;
16786 	WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes,
16787 				   &cmd->peer_discovery_mac_addr);
16788 
16789 	cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len;
16790 	cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len;
16791 	cmd->ndp_channel_cfg = ndp_req->channel_cfg;
16792 	cmd->nan_pmk_len = ndp_req->pmk.pmk_len;
16793 	cmd->nan_csid = ndp_req->ncs_sk_type;
16794 	cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len;
16795 	cmd->nan_servicename_len = ndp_req->service_name.service_name_len;
16796 
16797 	ch_tlv = (wmi_channel *)&cmd[1];
16798 	WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel,
16799 			WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
16800 	ch_tlv->mhz = ndp_req->channel;
16801 	tlv_ptr = (uint8_t *)&ch_tlv[1];
16802 
16803 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len);
16804 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16805 		     ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len);
16806 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len;
16807 
16808 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len);
16809 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16810 		     ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len);
16811 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len;
16812 
16813 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len);
16814 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk,
16815 		     cmd->nan_pmk_len);
16816 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len;
16817 
16818 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len);
16819 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase,
16820 		     cmd->nan_passphrase_len);
16821 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len;
16822 
16823 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len);
16824 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16825 		     ndp_req->service_name.service_name,
16826 		     cmd->nan_servicename_len);
16827 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len;
16828 
16829 	if (ndp_req->is_ipv6_addr_present) {
16830 		tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr;
16831 		WMITLV_SET_HDR(tcp_ip_param,
16832 			       WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param,
16833 			       WMITLV_GET_STRUCT_TLVLEN(
16834 						wmi_ndp_transport_ip_param));
16835 		tcp_ip_param->ipv6_addr_present = true;
16836 		qdf_mem_copy(tcp_ip_param->ipv6_intf_addr,
16837 			     ndp_req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN);
16838 	}
16839 	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
16840 		 ndp_req->is_ipv6_addr_present, ndp_req->ipv6_addr);
16841 
16842 	WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d",
16843 		 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id,
16844 		 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid);
16845 	WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x",
16846 		 cmd->peer_discovery_mac_addr.mac_addr31to0,
16847 		 cmd->peer_discovery_mac_addr.mac_addr47to32);
16848 
16849 	WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len);
16850 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16851 			   ndp_req->ndp_config.ndp_cfg,
16852 			   ndp_req->ndp_config.ndp_cfg_len);
16853 
16854 	WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len);
16855 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16856 			   ndp_req->ndp_info.ndp_app_info,
16857 			   ndp_req->ndp_info.ndp_app_info_len);
16858 
16859 	WMI_LOGD("pmk len: %d", cmd->nan_pmk_len);
16860 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16861 			   ndp_req->pmk.pmk, cmd->nan_pmk_len);
16862 
16863 	WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len);
16864 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16865 			   ndp_req->passphrase.passphrase,
16866 			   cmd->nan_passphrase_len);
16867 
16868 	WMI_LOGD("service name len: %d", cmd->nan_servicename_len);
16869 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16870 			   ndp_req->service_name.service_name,
16871 			   cmd->nan_servicename_len);
16872 
16873 	WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)",
16874 		 WMI_NDP_INITIATOR_REQ_CMDID);
16875 
16876 	wmi_mtrace(WMI_NDP_INITIATOR_REQ_CMDID, cmd->vdev_id, 0);
16877 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
16878 				      WMI_NDP_INITIATOR_REQ_CMDID);
16879 	if (QDF_IS_STATUS_ERROR(status)) {
16880 		WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status);
16881 		wmi_buf_free(buf);
16882 	}
16883 
16884 	return status;
16885 }
16886 
16887 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle,
16888 					struct nan_datapath_responder_req *req)
16889 {
16890 	uint16_t len;
16891 	wmi_buf_t buf;
16892 	uint8_t *tlv_ptr;
16893 	QDF_STATUS status;
16894 	wmi_ndp_responder_req_fixed_param *cmd;
16895 	wmi_ndp_transport_ip_param *tcp_ip_param;
16896 	uint32_t passphrase_len, service_name_len;
16897 	uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len;
16898 
16899 	vdev_id = wlan_vdev_get_id(req->vdev);
16900 	WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d",
16901 		 vdev_id, req->transaction_id,
16902 		 req->ndp_rsp,
16903 		 req->ndp_instance_id,
16904 		 req->ndp_info.ndp_app_info_len);
16905 
16906 	/*
16907 	 * WMI command expects 4 byte alligned len:
16908 	 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes
16909 	 */
16910 	ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4);
16911 	ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4);
16912 	pmk_len = qdf_roundup(req->pmk.pmk_len, 4);
16913 	passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4);
16914 	service_name_len =
16915 		qdf_roundup(req->service_name.service_name_len, 4);
16916 
16917 	/* allocated memory for fixed params as well as variable size data */
16918 	len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len
16919 		+ pmk_len + passphrase_len + service_name_len;
16920 
16921 	if (req->is_ipv6_addr_present || req->is_port_present ||
16922 	    req->is_protocol_present)
16923 		len += sizeof(*tcp_ip_param);
16924 
16925 	buf = wmi_buf_alloc(wmi_handle, len);
16926 	if (!buf) {
16927 		WMI_LOGE("wmi_buf_alloc failed");
16928 		return QDF_STATUS_E_NOMEM;
16929 	}
16930 	cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf);
16931 	WMITLV_SET_HDR(&cmd->tlv_header,
16932 		       WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param,
16933 		       WMITLV_GET_STRUCT_TLVLEN(
16934 				wmi_ndp_responder_req_fixed_param));
16935 	cmd->vdev_id = vdev_id;
16936 	cmd->transaction_id = req->transaction_id;
16937 	cmd->ndp_instance_id = req->ndp_instance_id;
16938 	cmd->rsp_code = req->ndp_rsp;
16939 	cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len;
16940 	cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len;
16941 	cmd->nan_pmk_len = req->pmk.pmk_len;
16942 	cmd->nan_csid = req->ncs_sk_type;
16943 	cmd->nan_passphrase_len = req->passphrase.passphrase_len;
16944 	cmd->nan_servicename_len = req->service_name.service_name_len;
16945 
16946 	tlv_ptr = (uint8_t *)&cmd[1];
16947 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len);
16948 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16949 		     req->ndp_config.ndp_cfg, cmd->ndp_cfg_len);
16950 
16951 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len;
16952 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len);
16953 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16954 		     req->ndp_info.ndp_app_info,
16955 		     req->ndp_info.ndp_app_info_len);
16956 
16957 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len;
16958 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len);
16959 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk,
16960 		     cmd->nan_pmk_len);
16961 
16962 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len;
16963 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len);
16964 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16965 		     req->passphrase.passphrase,
16966 		     cmd->nan_passphrase_len);
16967 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len;
16968 
16969 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len);
16970 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16971 		     req->service_name.service_name,
16972 		     cmd->nan_servicename_len);
16973 
16974 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len;
16975 
16976 	if (req->is_ipv6_addr_present || req->is_port_present ||
16977 	    req->is_protocol_present) {
16978 		tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr;
16979 		WMITLV_SET_HDR(tcp_ip_param,
16980 			       WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param,
16981 			       WMITLV_GET_STRUCT_TLVLEN(
16982 						wmi_ndp_transport_ip_param));
16983 		tcp_ip_param->ipv6_addr_present = req->is_ipv6_addr_present;
16984 		qdf_mem_copy(tcp_ip_param->ipv6_intf_addr,
16985 			     req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN);
16986 
16987 		tcp_ip_param->trans_port_present = req->is_port_present;
16988 		tcp_ip_param->transport_port = req->port;
16989 
16990 		tcp_ip_param->trans_proto_present = req->is_protocol_present;
16991 		tcp_ip_param->transport_protocol = req->protocol;
16992 	}
16993 	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
16994 		 req->is_ipv6_addr_present, req->ipv6_addr);
16995 	WMI_LOGD(FL("port: %d present: %d"), req->is_port_present, req->port);
16996 	WMI_LOGD(FL("protocol: %d present: %d"),
16997 		 req->is_protocol_present, req->protocol);
16998 
16999 	WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d",
17000 		 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid);
17001 
17002 	WMI_LOGD("ndp_config len: %d",
17003 		 req->ndp_config.ndp_cfg_len);
17004 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17005 			req->ndp_config.ndp_cfg,
17006 			req->ndp_config.ndp_cfg_len);
17007 
17008 	WMI_LOGD("ndp_app_info len: %d",
17009 		 req->ndp_info.ndp_app_info_len);
17010 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17011 			   req->ndp_info.ndp_app_info,
17012 			   req->ndp_info.ndp_app_info_len);
17013 
17014 	WMI_LOGD("pmk len: %d", cmd->nan_pmk_len);
17015 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17016 			   req->pmk.pmk, cmd->nan_pmk_len);
17017 
17018 	WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len);
17019 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17020 			   req->passphrase.passphrase,
17021 			   cmd->nan_passphrase_len);
17022 
17023 	WMI_LOGD("service name len: %d", cmd->nan_servicename_len);
17024 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17025 			   req->service_name.service_name,
17026 			   cmd->nan_servicename_len);
17027 
17028 	WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)",
17029 		 WMI_NDP_RESPONDER_REQ_CMDID);
17030 	wmi_mtrace(WMI_NDP_RESPONDER_REQ_CMDID, cmd->vdev_id, 0);
17031 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
17032 				      WMI_NDP_RESPONDER_REQ_CMDID);
17033 	if (QDF_IS_STATUS_ERROR(status)) {
17034 		WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status);
17035 		wmi_buf_free(buf);
17036 	}
17037 	return status;
17038 }
17039 
17040 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle,
17041 				      struct nan_datapath_end_req *req)
17042 {
17043 	uint16_t len;
17044 	wmi_buf_t buf;
17045 	QDF_STATUS status;
17046 	uint32_t ndp_end_req_len, i;
17047 	wmi_ndp_end_req *ndp_end_req_lst;
17048 	wmi_ndp_end_req_fixed_param *cmd;
17049 
17050 	/* len of tlv following fixed param  */
17051 	ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances;
17052 	/* above comes out to 4 byte alligned already, no need of padding */
17053 	len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE;
17054 	buf = wmi_buf_alloc(wmi_handle, len);
17055 	if (!buf) {
17056 		WMI_LOGE("Malloc failed");
17057 		return QDF_STATUS_E_NOMEM;
17058 	}
17059 
17060 	cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf);
17061 	WMITLV_SET_HDR(&cmd->tlv_header,
17062 		       WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param,
17063 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param));
17064 
17065 	cmd->transaction_id = req->transaction_id;
17066 
17067 	/* set tlv pointer to end of fixed param */
17068 	WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC,
17069 			ndp_end_req_len);
17070 
17071 	ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] +
17072 						WMI_TLV_HDR_SIZE);
17073 	for (i = 0; i < req->num_ndp_instances; i++) {
17074 		WMITLV_SET_HDR(&ndp_end_req_lst[i],
17075 				WMITLV_TAG_ARRAY_FIXED_STRUC,
17076 				(sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE));
17077 
17078 		ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i];
17079 	}
17080 
17081 	WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW");
17082 	wmi_mtrace(WMI_NDP_END_REQ_CMDID, NO_SESSION, 0);
17083 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
17084 				   WMI_NDP_END_REQ_CMDID);
17085 	if (QDF_IS_STATUS_ERROR(status)) {
17086 		WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status);
17087 		wmi_buf_free(buf);
17088 	}
17089 
17090 	return status;
17091 }
17092 
17093 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle,
17094 			uint8_t *data, struct nan_datapath_initiator_rsp *rsp)
17095 {
17096 	WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event;
17097 	wmi_ndp_initiator_rsp_event_fixed_param  *fixed_params;
17098 
17099 	event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data;
17100 	fixed_params = event->fixed_param;
17101 
17102 	rsp->vdev =
17103 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17104 						     fixed_params->vdev_id,
17105 						     WLAN_NAN_ID);
17106 	if (!rsp->vdev) {
17107 		WMI_LOGE("vdev is null");
17108 		return QDF_STATUS_E_INVAL;
17109 	}
17110 
17111 	rsp->transaction_id = fixed_params->transaction_id;
17112 	rsp->ndp_instance_id = fixed_params->ndp_instance_id;
17113 	rsp->status = fixed_params->rsp_status;
17114 	rsp->reason = fixed_params->reason_code;
17115 
17116 	return QDF_STATUS_SUCCESS;
17117 }
17118 
17119 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle,
17120 		uint8_t *data, struct nan_datapath_indication_event *rsp)
17121 {
17122 	WMI_NDP_INDICATION_EVENTID_param_tlvs *event;
17123 	wmi_ndp_indication_event_fixed_param *fixed_params;
17124 	size_t total_array_len;
17125 
17126 	event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data;
17127 	fixed_params =
17128 		(wmi_ndp_indication_event_fixed_param *)event->fixed_param;
17129 
17130 	if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) {
17131 		WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d",
17132 			 fixed_params->ndp_cfg_len, event->num_ndp_cfg);
17133 		return QDF_STATUS_E_INVAL;
17134 	}
17135 
17136 	if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) {
17137 		WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d",
17138 			 fixed_params->ndp_app_info_len,
17139 			 event->num_ndp_app_info);
17140 		return QDF_STATUS_E_INVAL;
17141 	}
17142 
17143 	if (fixed_params->ndp_cfg_len >
17144 		(WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) {
17145 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17146 			 __func__, fixed_params->ndp_cfg_len);
17147 		return QDF_STATUS_E_INVAL;
17148 	}
17149 
17150 	total_array_len = fixed_params->ndp_cfg_len +
17151 					sizeof(*fixed_params);
17152 
17153 	if (fixed_params->ndp_app_info_len >
17154 		(WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
17155 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17156 			 __func__, fixed_params->ndp_app_info_len);
17157 		return QDF_STATUS_E_INVAL;
17158 	}
17159 	total_array_len += fixed_params->ndp_app_info_len;
17160 
17161 	if (fixed_params->nan_scid_len >
17162 		(WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
17163 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17164 			 __func__, fixed_params->nan_scid_len);
17165 		return QDF_STATUS_E_INVAL;
17166 	}
17167 
17168 	rsp->vdev =
17169 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17170 						     fixed_params->vdev_id,
17171 						     WLAN_NAN_ID);
17172 	if (!rsp->vdev) {
17173 		WMI_LOGE("vdev is null");
17174 		return QDF_STATUS_E_INVAL;
17175 	}
17176 	rsp->service_instance_id = fixed_params->service_instance_id;
17177 	rsp->ndp_instance_id = fixed_params->ndp_instance_id;
17178 	rsp->role = fixed_params->self_ndp_role;
17179 	rsp->policy = fixed_params->accept_policy;
17180 
17181 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
17182 				rsp->peer_mac_addr.bytes);
17183 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr,
17184 				rsp->peer_discovery_mac_addr.bytes);
17185 
17186 	WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n"
17187 		"service_instance %d, ndp_instance %d, role %d, policy %d,\n"
17188 		"csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM",
17189 		 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id,
17190 		 fixed_params->service_instance_id,
17191 		 fixed_params->ndp_instance_id, fixed_params->self_ndp_role,
17192 		 fixed_params->accept_policy,
17193 		 fixed_params->nan_csid, fixed_params->nan_scid_len,
17194 		 rsp->peer_mac_addr.bytes,
17195 		 rsp->peer_discovery_mac_addr.bytes);
17196 
17197 	WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len);
17198 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17199 			   &event->ndp_cfg, fixed_params->ndp_cfg_len);
17200 
17201 	WMI_LOGD("ndp_app_info - %d bytes",
17202 			fixed_params->ndp_app_info_len);
17203 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17204 			&event->ndp_app_info, fixed_params->ndp_app_info_len);
17205 
17206 	rsp->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len;
17207 	rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len;
17208 	rsp->ncs_sk_type = fixed_params->nan_csid;
17209 	rsp->scid.scid_len = fixed_params->nan_scid_len;
17210 
17211 	if (rsp->ndp_config.ndp_cfg_len > NDP_QOS_INFO_LEN)
17212 		rsp->ndp_config.ndp_cfg_len = NDP_QOS_INFO_LEN;
17213 	qdf_mem_copy(rsp->ndp_config.ndp_cfg, event->ndp_cfg,
17214 		     rsp->ndp_config.ndp_cfg_len);
17215 
17216 	if (rsp->ndp_info.ndp_app_info_len > NDP_APP_INFO_LEN)
17217 		rsp->ndp_info.ndp_app_info_len = NDP_APP_INFO_LEN;
17218 	qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info,
17219 		     rsp->ndp_info.ndp_app_info_len);
17220 
17221 	if (rsp->scid.scid_len > NDP_SCID_BUF_LEN)
17222 		rsp->scid.scid_len = NDP_SCID_BUF_LEN;
17223 	qdf_mem_copy(rsp->scid.scid, event->ndp_scid, rsp->scid.scid_len);
17224 
17225 	if (event->ndp_transport_ip_param &&
17226 	    event->num_ndp_transport_ip_param) {
17227 		if (event->ndp_transport_ip_param->ipv6_addr_present) {
17228 			rsp->is_ipv6_addr_present = true;
17229 			qdf_mem_copy(rsp->ipv6_addr,
17230 				event->ndp_transport_ip_param->ipv6_intf_addr,
17231 				WMI_NDP_IPV6_INTF_ADDR_LEN);
17232 		}
17233 	}
17234 	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
17235 		 rsp->is_ipv6_addr_present, rsp->ipv6_addr);
17236 
17237 	WMI_LOGD("scid hex dump:");
17238 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17239 			   rsp->scid.scid, rsp->scid.scid_len);
17240 
17241 	return QDF_STATUS_SUCCESS;
17242 }
17243 
17244 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle,
17245 			uint8_t *data, struct nan_datapath_confirm_event *rsp)
17246 {
17247 	uint8_t i;
17248 	WMI_HOST_WLAN_PHY_MODE ch_mode;
17249 	WMI_NDP_CONFIRM_EVENTID_param_tlvs *event;
17250 	wmi_ndp_confirm_event_fixed_param *fixed_params;
17251 	size_t total_array_len;
17252 
17253 	event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data;
17254 	fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param;
17255 	WMI_LOGD("WMI_NDP_CONFIRM_EVENTID(0x%X) received. vdev %d, ndp_instance %d, rsp_code %d, reason_code: %d, num_active_ndps_on_peer: %d",
17256 		 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id,
17257 		 fixed_params->ndp_instance_id, fixed_params->rsp_code,
17258 		 fixed_params->reason_code,
17259 		 fixed_params->num_active_ndps_on_peer);
17260 	WMI_LOGE("num_ch: %d", fixed_params->num_ndp_channels);
17261 
17262 	if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) {
17263 		WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d",
17264 			 fixed_params->ndp_cfg_len, event->num_ndp_cfg);
17265 		return QDF_STATUS_E_INVAL;
17266 	}
17267 
17268 	WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len);
17269 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17270 		&event->ndp_cfg, fixed_params->ndp_cfg_len);
17271 
17272 	if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) {
17273 		WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d",
17274 			 fixed_params->ndp_app_info_len,
17275 			 event->num_ndp_app_info);
17276 		return QDF_STATUS_E_INVAL;
17277 	}
17278 
17279 	WMI_LOGD("ndp_app_info - %d bytes",
17280 			fixed_params->ndp_app_info_len);
17281 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17282 		&event->ndp_app_info, fixed_params->ndp_app_info_len);
17283 
17284 	if (fixed_params->ndp_cfg_len >
17285 			(WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) {
17286 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17287 			 __func__, fixed_params->ndp_cfg_len);
17288 		return QDF_STATUS_E_INVAL;
17289 	}
17290 
17291 	total_array_len = fixed_params->ndp_cfg_len +
17292 				sizeof(*fixed_params);
17293 
17294 	if (fixed_params->ndp_app_info_len >
17295 		(WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
17296 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17297 			 __func__, fixed_params->ndp_app_info_len);
17298 		return QDF_STATUS_E_INVAL;
17299 	}
17300 
17301 	rsp->vdev =
17302 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17303 						     fixed_params->vdev_id,
17304 						     WLAN_NAN_ID);
17305 	if (!rsp->vdev) {
17306 		WMI_LOGE("vdev is null");
17307 		return QDF_STATUS_E_INVAL;
17308 	}
17309 	rsp->ndp_instance_id = fixed_params->ndp_instance_id;
17310 	rsp->rsp_code = fixed_params->rsp_code;
17311 	rsp->reason_code = fixed_params->reason_code;
17312 	rsp->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer;
17313 	rsp->num_channels = fixed_params->num_ndp_channels;
17314 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
17315 				   rsp->peer_ndi_mac_addr.bytes);
17316 	rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len;
17317 	qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info,
17318 		     rsp->ndp_info.ndp_app_info_len);
17319 
17320 	if (rsp->num_channels > NAN_CH_INFO_MAX_CHANNELS) {
17321 		WMI_LOGE(FL("too many channels"));
17322 		rsp->num_channels = NAN_CH_INFO_MAX_CHANNELS;
17323 	}
17324 
17325 	for (i = 0; i < rsp->num_channels; i++) {
17326 		rsp->ch[i].channel = event->ndp_channel_list[i].mhz;
17327 		rsp->ch[i].nss = event->nss_list[i];
17328 		ch_mode = WMI_GET_CHANNEL_MODE(&event->ndp_channel_list[i]);
17329 		rsp->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle,
17330 								     ch_mode);
17331 		WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"),
17332 			 rsp->ch[i].channel,
17333 			 rsp->ch[i].ch_width,
17334 			 rsp->ch[i].nss);
17335 	}
17336 
17337 	if (event->ndp_transport_ip_param &&
17338 	    event->num_ndp_transport_ip_param) {
17339 		if (event->ndp_transport_ip_param->ipv6_addr_present) {
17340 			rsp->is_ipv6_addr_present = true;
17341 			qdf_mem_copy(rsp->ipv6_addr,
17342 				event->ndp_transport_ip_param->ipv6_intf_addr,
17343 				WMI_NDP_IPV6_INTF_ADDR_LEN);
17344 		}
17345 
17346 		if (event->ndp_transport_ip_param->trans_port_present) {
17347 			rsp->is_port_present = true;
17348 			rsp->port =
17349 			    event->ndp_transport_ip_param->transport_port;
17350 		}
17351 
17352 		if (event->ndp_transport_ip_param->trans_proto_present) {
17353 			rsp->is_protocol_present = true;
17354 			rsp->protocol =
17355 			    event->ndp_transport_ip_param->transport_protocol;
17356 		}
17357 	}
17358 	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
17359 		 rsp->is_ipv6_addr_present, rsp->ipv6_addr);
17360 	WMI_LOGD(FL("port: %d present: %d"), rsp->port, rsp->is_port_present);
17361 	WMI_LOGD(FL("protocol: %d present: %d"),
17362 		 rsp->protocol, rsp->is_protocol_present);
17363 
17364 	return QDF_STATUS_SUCCESS;
17365 }
17366 
17367 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle,
17368 			uint8_t *data, struct nan_datapath_responder_rsp *rsp)
17369 {
17370 	WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event;
17371 	wmi_ndp_responder_rsp_event_fixed_param  *fixed_params;
17372 
17373 	event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data;
17374 	fixed_params = event->fixed_param;
17375 
17376 	WMI_LOGD("WMI_NDP_RESPONDER_RSP_EVENTID(0x%X) received. vdev_id: %d, peer_mac_addr: %pM,transaction_id: %d, status_code %d, reason_code: %d, create_peer: %d",
17377 		 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id,
17378 		 rsp->peer_mac_addr.bytes, rsp->transaction_id,
17379 		 rsp->status, rsp->reason, rsp->create_peer);
17380 
17381 	rsp->vdev =
17382 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17383 						     fixed_params->vdev_id,
17384 						     WLAN_NAN_ID);
17385 	if (!rsp->vdev) {
17386 		WMI_LOGE("vdev is null");
17387 		return QDF_STATUS_E_INVAL;
17388 	}
17389 	rsp->transaction_id = fixed_params->transaction_id;
17390 	rsp->reason = fixed_params->reason_code;
17391 	rsp->status = fixed_params->rsp_status;
17392 	rsp->create_peer = fixed_params->create_peer;
17393 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
17394 				rsp->peer_mac_addr.bytes);
17395 
17396 	return QDF_STATUS_SUCCESS;
17397 }
17398 
17399 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle,
17400 			uint8_t *data, struct nan_datapath_end_rsp_event *rsp)
17401 {
17402 	WMI_NDP_END_RSP_EVENTID_param_tlvs *event;
17403 	wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL;
17404 
17405 	event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data;
17406 	fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param;
17407 	WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) received. transaction_id: %d, rsp_status: %d, reason_code: %d",
17408 		 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id,
17409 		 fixed_params->rsp_status, fixed_params->reason_code);
17410 
17411 	rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
17412 			wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID);
17413 	if (!rsp->vdev) {
17414 		WMI_LOGE("vdev is null");
17415 		return QDF_STATUS_E_INVAL;
17416 	}
17417 	rsp->transaction_id = fixed_params->transaction_id;
17418 	rsp->reason = fixed_params->reason_code;
17419 	rsp->status = fixed_params->rsp_status;
17420 
17421 	return QDF_STATUS_SUCCESS;
17422 }
17423 
17424 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle,
17425 		uint8_t *data, struct nan_datapath_end_indication_event **rsp)
17426 {
17427 	uint32_t i, buf_size;
17428 	wmi_ndp_end_indication *ind;
17429 	struct qdf_mac_addr peer_addr;
17430 	WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event;
17431 
17432 	event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data;
17433 	ind = event->ndp_end_indication_list;
17434 
17435 	if (event->num_ndp_end_indication_list == 0) {
17436 		WMI_LOGE("Error: Event ignored, 0 ndp instances");
17437 		return QDF_STATUS_E_INVAL;
17438 	}
17439 
17440 	WMI_LOGD("number of ndp instances = %d",
17441 		 event->num_ndp_end_indication_list);
17442 
17443 	if (event->num_ndp_end_indication_list > ((UINT_MAX - sizeof(**rsp))/
17444 						sizeof((*rsp)->ndp_map[0]))) {
17445 		WMI_LOGE("num_ndp_end_ind_list %d too large",
17446 			 event->num_ndp_end_indication_list);
17447 		return QDF_STATUS_E_INVAL;
17448 	}
17449 
17450 	buf_size = sizeof(**rsp) + event->num_ndp_end_indication_list *
17451 			sizeof((*rsp)->ndp_map[0]);
17452 	*rsp = qdf_mem_malloc(buf_size);
17453 	if (!(*rsp)) {
17454 		WMI_LOGE("Failed to allocate memory");
17455 		return QDF_STATUS_E_NOMEM;
17456 	}
17457 
17458 	(*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
17459 			wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID);
17460 	if (!(*rsp)->vdev) {
17461 		WMI_LOGE("vdev is null");
17462 		qdf_mem_free(*rsp);
17463 		*rsp = NULL;
17464 		return QDF_STATUS_E_INVAL;
17465 	}
17466 
17467 	(*rsp)->num_ndp_ids = event->num_ndp_end_indication_list;
17468 	for (i = 0; i < (*rsp)->num_ndp_ids; i++) {
17469 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr,
17470 					   peer_addr.bytes);
17471 		WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ",
17472 			 i, ind[i].type, ind[i].reason_code,
17473 			 ind[i].ndp_instance_id,
17474 			 ind[i].num_active_ndps_on_peer);
17475 		/* Add each instance entry to the list */
17476 		(*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id;
17477 		(*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id;
17478 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr,
17479 			(*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes);
17480 		(*rsp)->ndp_map[i].num_active_ndp_sessions =
17481 			ind[i].num_active_ndps_on_peer;
17482 		(*rsp)->ndp_map[i].type = ind[i].type;
17483 		(*rsp)->ndp_map[i].reason_code = ind[i].reason_code;
17484 	}
17485 
17486 	return QDF_STATUS_SUCCESS;
17487 }
17488 
17489 static QDF_STATUS extract_ndp_sch_update_tlv(wmi_unified_t wmi_handle,
17490 		uint8_t *data, struct nan_datapath_sch_update_event *ind)
17491 {
17492 	uint8_t i;
17493 	WMI_HOST_WLAN_PHY_MODE ch_mode;
17494 	WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *event;
17495 	wmi_ndl_schedule_update_fixed_param *fixed_params;
17496 
17497 	event = (WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *)data;
17498 	fixed_params = event->fixed_param;
17499 
17500 	WMI_LOGD(FL("flags: %d, num_ch: %d, num_ndp_instances: %d"),
17501 		 fixed_params->flags, fixed_params->num_channels,
17502 		 fixed_params->num_ndp_instances);
17503 
17504 	ind->vdev =
17505 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17506 						     fixed_params->vdev_id,
17507 						     WLAN_NAN_ID);
17508 	if (!ind->vdev) {
17509 		WMI_LOGE("vdev is null");
17510 		return QDF_STATUS_E_INVAL;
17511 	}
17512 
17513 	ind->flags = fixed_params->flags;
17514 	ind->num_channels = fixed_params->num_channels;
17515 	ind->num_ndp_instances = fixed_params->num_ndp_instances;
17516 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_macaddr,
17517 				   ind->peer_addr.bytes);
17518 
17519 	if (ind->num_ndp_instances > NDP_NUM_INSTANCE_ID) {
17520 		WMI_LOGE(FL("uint32 overflow"));
17521 		wlan_objmgr_vdev_release_ref(ind->vdev, WLAN_NAN_ID);
17522 		return QDF_STATUS_E_INVAL;
17523 	}
17524 
17525 	qdf_mem_copy(ind->ndp_instances, event->ndp_instance_list,
17526 		     sizeof(uint32_t) * ind->num_ndp_instances);
17527 
17528 	if (ind->num_channels > NAN_CH_INFO_MAX_CHANNELS) {
17529 		WMI_LOGE(FL("too many channels"));
17530 		ind->num_channels = NAN_CH_INFO_MAX_CHANNELS;
17531 	}
17532 	for (i = 0; i < ind->num_channels; i++) {
17533 		ind->ch[i].channel = event->ndl_channel_list[i].mhz;
17534 		ind->ch[i].nss = event->nss_list[i];
17535 		ch_mode = WMI_GET_CHANNEL_MODE(&event->ndl_channel_list[i]);
17536 		ind->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle,
17537 								     ch_mode);
17538 		WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"),
17539 			 ind->ch[i].channel,
17540 			 ind->ch[i].ch_width,
17541 			 ind->ch[i].nss);
17542 	}
17543 
17544 	for (i = 0; i < fixed_params->num_ndp_instances; i++)
17545 		WMI_LOGD(FL("instance_id[%d]: %d"),
17546 			 i, event->ndp_instance_list[i]);
17547 
17548 	return QDF_STATUS_SUCCESS;
17549 }
17550 
17551 #endif
17552 
17553 #ifdef QCA_SUPPORT_CP_STATS
17554 /**
17555  * extract_cca_stats_tlv - api to extract congestion stats from event buffer
17556  * @wmi_handle: wma handle
17557  * @evt_buf: event buffer
17558  * @out_buff: buffer to populated after stats extraction
17559  *
17560  * Return: status of operation
17561  */
17562 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle,
17563 		void *evt_buf, struct wmi_host_congestion_stats *out_buff)
17564 {
17565 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
17566 	wmi_congestion_stats *congestion_stats;
17567 
17568 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf;
17569 	congestion_stats = param_buf->congestion_stats;
17570 	if (!congestion_stats) {
17571 		WMI_LOGD("%s: no cca stats in event buffer", __func__);
17572 		return QDF_STATUS_E_INVAL;
17573 	}
17574 
17575 	out_buff->vdev_id = congestion_stats->vdev_id;
17576 	out_buff->congestion = congestion_stats->congestion;
17577 
17578 	WMI_LOGD("%s: cca stats event processed", __func__);
17579 	return QDF_STATUS_SUCCESS;
17580 }
17581 #endif /* QCA_SUPPORT_CP_STATS */
17582 
17583 /**
17584  * save_service_bitmap_tlv() - save service bitmap
17585  * @wmi_handle: wmi handle
17586  * @param evt_buf: pointer to event buffer
17587  * @param bitmap_buf: bitmap buffer, for converged legacy support
17588  *
17589  * Return: QDF_STATUS
17590  */
17591 static
17592 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
17593 			     void *bitmap_buf)
17594 {
17595 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17596 	struct wmi_soc *soc = wmi_handle->soc;
17597 
17598 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17599 
17600 	/* If it is already allocated, use that buffer. This can happen
17601 	 * during target stop/start scenarios where host allocation is skipped.
17602 	 */
17603 	if (!soc->wmi_service_bitmap) {
17604 		soc->wmi_service_bitmap =
17605 			qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t));
17606 		if (!soc->wmi_service_bitmap) {
17607 			WMI_LOGE("Failed memory allocation for service bitmap");
17608 			return QDF_STATUS_E_NOMEM;
17609 		}
17610 	}
17611 
17612 	qdf_mem_copy(soc->wmi_service_bitmap,
17613 			param_buf->wmi_service_bitmap,
17614 			(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
17615 
17616 	if (bitmap_buf)
17617 		qdf_mem_copy(bitmap_buf,
17618 			     param_buf->wmi_service_bitmap,
17619 			     (WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
17620 
17621 	return QDF_STATUS_SUCCESS;
17622 }
17623 
17624 /**
17625  * save_ext_service_bitmap_tlv() - save extendend service bitmap
17626  * @wmi_handle: wmi handle
17627  * @param evt_buf: pointer to event buffer
17628  * @param bitmap_buf: bitmap buffer, for converged legacy support
17629  *
17630  * Return: QDF_STATUS
17631  */
17632 static
17633 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
17634 			     void *bitmap_buf)
17635 {
17636 	WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf;
17637 	wmi_service_available_event_fixed_param *ev;
17638 	struct wmi_soc *soc = wmi_handle->soc;
17639 
17640 	param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf;
17641 
17642 	ev = param_buf->fixed_param;
17643 
17644 	/* If it is already allocated, use that buffer. This can happen
17645 	 * during target stop/start scenarios where host allocation is skipped.
17646 	 */
17647 	if (!soc->wmi_ext_service_bitmap) {
17648 		soc->wmi_ext_service_bitmap = qdf_mem_malloc(
17649 			WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t));
17650 		if (!soc->wmi_ext_service_bitmap) {
17651 			WMI_LOGE("Failed memory allocation for service bitmap");
17652 			return QDF_STATUS_E_NOMEM;
17653 		}
17654 	}
17655 
17656 	qdf_mem_copy(soc->wmi_ext_service_bitmap,
17657 			ev->wmi_service_segment_bitmap,
17658 			(WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)));
17659 
17660 	WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n",
17661 			soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1],
17662 			soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]);
17663 
17664 	if (bitmap_buf)
17665 		qdf_mem_copy(bitmap_buf,
17666 			soc->wmi_ext_service_bitmap,
17667 			(WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)));
17668 
17669 	return QDF_STATUS_SUCCESS;
17670 }
17671 /**
17672  * is_service_enabled_tlv() - Check if service enabled
17673  * @param wmi_handle: wmi handle
17674  * @param service_id: service identifier
17675  *
17676  * Return: 1 enabled, 0 disabled
17677  */
17678 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle,
17679 		uint32_t service_id)
17680 {
17681 	struct wmi_soc *soc = wmi_handle->soc;
17682 
17683 	if (!soc->wmi_service_bitmap) {
17684 		WMI_LOGE("WMI service bit map is not saved yet\n");
17685 		return false;
17686 	}
17687 
17688 	/* if wmi_service_enabled was received with extended bitmap,
17689 	 * use WMI_SERVICE_EXT_IS_ENABLED to check the services.
17690 	 */
17691 	if (soc->wmi_ext_service_bitmap)
17692 		return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap,
17693 				soc->wmi_ext_service_bitmap,
17694 				service_id);
17695 
17696 	if (service_id >= WMI_MAX_SERVICE) {
17697 		WMI_LOGE("Service id %d but WMI ext service bitmap is NULL",
17698 			 service_id);
17699 		return false;
17700 	}
17701 
17702 	return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap,
17703 				service_id);
17704 }
17705 
17706 static inline void copy_ht_cap_info(uint32_t ev_target_cap,
17707 		struct wlan_psoc_target_capability_info *cap)
17708 {
17709        /* except LDPC all flags are common betwen legacy and here
17710 	*  also IBFEER is not defined for TLV
17711 	*/
17712 	cap->ht_cap_info |= ev_target_cap & (
17713 					WMI_HT_CAP_ENABLED
17714 					| WMI_HT_CAP_HT20_SGI
17715 					| WMI_HT_CAP_DYNAMIC_SMPS
17716 					| WMI_HT_CAP_TX_STBC
17717 					| WMI_HT_CAP_TX_STBC_MASK_SHIFT
17718 					| WMI_HT_CAP_RX_STBC
17719 					| WMI_HT_CAP_RX_STBC_MASK_SHIFT
17720 					| WMI_HT_CAP_LDPC
17721 					| WMI_HT_CAP_L_SIG_TXOP_PROT
17722 					| WMI_HT_CAP_MPDU_DENSITY
17723 					| WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT
17724 					| WMI_HT_CAP_HT40_SGI);
17725 	if (ev_target_cap & WMI_HT_CAP_LDPC)
17726 		cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC |
17727 			WMI_HOST_HT_CAP_TX_LDPC;
17728 }
17729 /**
17730  * extract_service_ready_tlv() - extract service ready event
17731  * @wmi_handle: wmi handle
17732  * @param evt_buf: pointer to received event buffer
17733  * @param cap: pointer to hold target capability information extracted from even
17734  *
17735  * Return: QDF_STATUS_SUCCESS for success or error code
17736  */
17737 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle,
17738 		void *evt_buf, struct wlan_psoc_target_capability_info *cap)
17739 {
17740 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17741 	wmi_service_ready_event_fixed_param *ev;
17742 
17743 
17744 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17745 
17746 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
17747 	if (!ev) {
17748 		qdf_print("%s: wmi_buf_alloc failed", __func__);
17749 		return QDF_STATUS_E_FAILURE;
17750 	}
17751 
17752 	cap->phy_capability = ev->phy_capability;
17753 	cap->max_frag_entry = ev->max_frag_entry;
17754 	cap->num_rf_chains = ev->num_rf_chains;
17755 	copy_ht_cap_info(ev->ht_cap_info, cap);
17756 	cap->vht_cap_info = ev->vht_cap_info;
17757 	cap->vht_supp_mcs = ev->vht_supp_mcs;
17758 	cap->hw_min_tx_power = ev->hw_min_tx_power;
17759 	cap->hw_max_tx_power = ev->hw_max_tx_power;
17760 	cap->sys_cap_info = ev->sys_cap_info;
17761 	cap->min_pkt_size_enable = ev->min_pkt_size_enable;
17762 	cap->max_bcn_ie_size = ev->max_bcn_ie_size;
17763 	cap->max_num_scan_channels = ev->max_num_scan_channels;
17764 	cap->max_supported_macs = ev->max_supported_macs;
17765 	cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps;
17766 	cap->txrx_chainmask = ev->txrx_chainmask;
17767 	cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index;
17768 	cap->num_msdu_desc = ev->num_msdu_desc;
17769 	cap->fw_version = ev->fw_build_vers;
17770 	/* fw_version_1 is not available in TLV. */
17771 	cap->fw_version_1 = 0;
17772 
17773 	return QDF_STATUS_SUCCESS;
17774 }
17775 
17776 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target
17777  *         to host internal WMI_HOST_REGDMN_MODE values.
17778  *         REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the
17779  *         host currently. Add this in the future if required.
17780  *         11AX (Phase II) : 11ax related values are not currently
17781  *         advertised separately by FW. As part of phase II regulatory bring-up,
17782  *         finalize the advertisement mechanism.
17783  * @target_wireless_mode: target wireless mode received in message
17784  *
17785  * Return: returns the host internal wireless mode.
17786  */
17787 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode)
17788 {
17789 
17790 	uint32_t wireless_modes = 0;
17791 
17792 	if (target_wireless_mode & REGDMN_MODE_11A)
17793 		wireless_modes |= WMI_HOST_REGDMN_MODE_11A;
17794 
17795 	if (target_wireless_mode & REGDMN_MODE_TURBO)
17796 		wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO;
17797 
17798 	if (target_wireless_mode & REGDMN_MODE_11B)
17799 		wireless_modes |= WMI_HOST_REGDMN_MODE_11B;
17800 
17801 	if (target_wireless_mode & REGDMN_MODE_PUREG)
17802 		wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG;
17803 
17804 	if (target_wireless_mode & REGDMN_MODE_11G)
17805 		wireless_modes |= WMI_HOST_REGDMN_MODE_11G;
17806 
17807 	if (target_wireless_mode & REGDMN_MODE_108G)
17808 		wireless_modes |= WMI_HOST_REGDMN_MODE_108G;
17809 
17810 	if (target_wireless_mode & REGDMN_MODE_108A)
17811 		wireless_modes |= WMI_HOST_REGDMN_MODE_108A;
17812 
17813 	if (target_wireless_mode & REGDMN_MODE_XR)
17814 		wireless_modes |= WMI_HOST_REGDMN_MODE_XR;
17815 
17816 	if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE)
17817 		wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE;
17818 
17819 	if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE)
17820 		wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE;
17821 
17822 	if (target_wireless_mode & REGDMN_MODE_11NG_HT20)
17823 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20;
17824 
17825 	if (target_wireless_mode & REGDMN_MODE_11NA_HT20)
17826 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20;
17827 
17828 	if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS)
17829 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS;
17830 
17831 	if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS)
17832 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS;
17833 
17834 	if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS)
17835 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS;
17836 
17837 	if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS)
17838 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS;
17839 
17840 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT20)
17841 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20;
17842 
17843 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS)
17844 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS;
17845 
17846 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS)
17847 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS;
17848 
17849 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT80)
17850 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80;
17851 
17852 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT160)
17853 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160;
17854 
17855 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80)
17856 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80;
17857 
17858 	return wireless_modes;
17859 }
17860 
17861 /**
17862  * extract_hal_reg_cap_tlv() - extract HAL registered capabilities
17863  * @wmi_handle: wmi handle
17864  * @param evt_buf: Pointer to event buffer
17865  * @param cap: pointer to hold HAL reg capabilities
17866  *
17867  * Return: QDF_STATUS_SUCCESS for success or error code
17868  */
17869 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle,
17870 	void *evt_buf, struct wlan_psoc_hal_reg_capability *cap)
17871 {
17872 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17873 
17874 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17875 
17876 	qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) +
17877 		sizeof(uint32_t)),
17878 		sizeof(struct wlan_psoc_hal_reg_capability));
17879 
17880 	cap->wireless_modes = convert_wireless_modes_tlv(
17881 			param_buf->hal_reg_capabilities->wireless_modes);
17882 
17883 	return QDF_STATUS_SUCCESS;
17884 }
17885 
17886 /**
17887  * extract_host_mem_req_tlv() - Extract host memory request event
17888  * @wmi_handle: wmi handle
17889  * @param evt_buf: pointer to event buffer
17890  * @param num_entries: pointer to hold number of entries requested
17891  *
17892  * Return: Number of entries requested
17893  */
17894 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle,
17895 		void *evt_buf, uint8_t *num_entries)
17896 {
17897 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17898 	wmi_service_ready_event_fixed_param *ev;
17899 
17900 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17901 
17902 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
17903 	if (!ev) {
17904 		qdf_print("%s: wmi_buf_alloc failed", __func__);
17905 		return NULL;
17906 	}
17907 
17908 	*num_entries = ev->num_mem_reqs;
17909 
17910 	return (host_mem_req *)param_buf->mem_reqs;
17911 }
17912 
17913 /**
17914  * save_fw_version_in_service_ready_tlv() - Save fw version in service
17915  * ready function
17916  * @wmi_handle: wmi handle
17917  * @param evt_buf: pointer to event buffer
17918  *
17919  * Return: QDF_STATUS_SUCCESS for success or error code
17920  */
17921 static QDF_STATUS
17922 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf)
17923 {
17924 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17925 	wmi_service_ready_event_fixed_param *ev;
17926 
17927 
17928 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17929 
17930 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
17931 	if (!ev) {
17932 		qdf_print("%s: wmi_buf_alloc failed", __func__);
17933 		return QDF_STATUS_E_FAILURE;
17934 	}
17935 
17936 	/*Save fw version from service ready message */
17937 	/*This will be used while sending INIT message */
17938 	qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
17939 			sizeof(wmi_handle->fw_abi_version));
17940 
17941 	return QDF_STATUS_SUCCESS;
17942 }
17943 
17944 /**
17945  * ready_extract_init_status_tlv() - Extract init status from ready event
17946  * @wmi_handle: wmi handle
17947  * @param evt_buf: Pointer to event buffer
17948  *
17949  * Return: ready status
17950  */
17951 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle,
17952 	void *evt_buf)
17953 {
17954 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
17955 	wmi_ready_event_fixed_param *ev = NULL;
17956 
17957 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
17958 	ev = param_buf->fixed_param;
17959 
17960 	qdf_print("%s:%d", __func__, ev->status);
17961 
17962 	return ev->status;
17963 }
17964 
17965 /**
17966  * ready_extract_mac_addr_tlv() - extract mac address from ready event
17967  * @wmi_handle: wmi handle
17968  * @param evt_buf: pointer to event buffer
17969  * @param macaddr: Pointer to hold MAC address
17970  *
17971  * Return: QDF_STATUS_SUCCESS for success or error code
17972  */
17973 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle,
17974 	void *evt_buf, uint8_t *macaddr)
17975 {
17976 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
17977 	wmi_ready_event_fixed_param *ev = NULL;
17978 
17979 
17980 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
17981 	ev = param_buf->fixed_param;
17982 
17983 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr);
17984 
17985 	return QDF_STATUS_SUCCESS;
17986 }
17987 
17988 /**
17989  * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event
17990  * @wmi_handle: wmi handle
17991  * @param evt_buf: pointer to event buffer
17992  * @param macaddr: Pointer to hold number of MAC addresses
17993  *
17994  * Return: Pointer to addr list
17995  */
17996 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle,
17997 	void *evt_buf, uint8_t *num_mac)
17998 {
17999 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
18000 	wmi_ready_event_fixed_param *ev = NULL;
18001 
18002 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
18003 	ev = param_buf->fixed_param;
18004 
18005 	*num_mac = ev->num_extra_mac_addr;
18006 
18007 	return (wmi_host_mac_addr *) param_buf->mac_addr_list;
18008 }
18009 
18010 /**
18011  * extract_ready_params_tlv() - Extract data from ready event apart from
18012  *                     status, macaddr and version.
18013  * @wmi_handle: Pointer to WMI handle.
18014  * @evt_buf: Pointer to Ready event buffer.
18015  * @ev_param: Pointer to host defined struct to copy the data from event.
18016  *
18017  * Return: QDF_STATUS_SUCCESS on success.
18018  */
18019 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle,
18020 		void *evt_buf, struct wmi_host_ready_ev_param *ev_param)
18021 {
18022 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
18023 	wmi_ready_event_fixed_param *ev = NULL;
18024 
18025 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
18026 	ev = param_buf->fixed_param;
18027 
18028 	ev_param->status = ev->status;
18029 	ev_param->num_dscp_table = ev->num_dscp_table;
18030 	ev_param->num_extra_mac_addr = ev->num_extra_mac_addr;
18031 	ev_param->num_total_peer = ev->num_total_peers;
18032 	ev_param->num_extra_peer = ev->num_extra_peers;
18033 	/* Agile_cap in ready event is not supported in TLV target */
18034 	ev_param->agile_capability = false;
18035 
18036 	return QDF_STATUS_SUCCESS;
18037 }
18038 
18039 /**
18040  * extract_dbglog_data_len_tlv() - extract debuglog data length
18041  * @wmi_handle: wmi handle
18042  * @param evt_buf: pointer to event buffer
18043  *
18044  * Return: length
18045  */
18046 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle,
18047 	void *evt_buf, uint32_t *len)
18048 {
18049 	 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf;
18050 
18051 	 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf;
18052 
18053 	 *len = param_buf->num_bufp;
18054 
18055 	 return param_buf->bufp;
18056 }
18057 
18058 /**
18059  * extract_vdev_start_resp_tlv() - extract vdev start response
18060  * @wmi_handle: wmi handle
18061  * @param evt_buf: pointer to event buffer
18062  * @param vdev_rsp: Pointer to hold vdev response
18063  *
18064  * Return: QDF_STATUS_SUCCESS for success or error code
18065  */
18066 static QDF_STATUS extract_vdev_start_resp_tlv(wmi_unified_t wmi_handle,
18067 	void *evt_buf, wmi_host_vdev_start_resp *vdev_rsp)
18068 {
18069 	WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf;
18070 	wmi_vdev_start_response_event_fixed_param *ev;
18071 
18072 	param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) evt_buf;
18073 	if (!param_buf) {
18074 		qdf_print("Invalid start response event buffer");
18075 		return QDF_STATUS_E_INVAL;
18076 	}
18077 
18078 	ev = param_buf->fixed_param;
18079 	if (!ev) {
18080 		qdf_print("Invalid start response event buffer");
18081 		return QDF_STATUS_E_INVAL;
18082 	}
18083 
18084 	qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp));
18085 
18086 	vdev_rsp->vdev_id = ev->vdev_id;
18087 	vdev_rsp->requestor_id = ev->requestor_id;
18088 	switch (ev->resp_type) {
18089 	case WMI_VDEV_START_RESP_EVENT:
18090 		vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT;
18091 		break;
18092 	case WMI_VDEV_RESTART_RESP_EVENT:
18093 		vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT;
18094 		break;
18095 	default:
18096 		qdf_print("Invalid start response event buffer");
18097 		break;
18098 	};
18099 	vdev_rsp->status = ev->status;
18100 	vdev_rsp->chain_mask = ev->chain_mask;
18101 	vdev_rsp->smps_mode = ev->smps_mode;
18102 	vdev_rsp->mac_id = ev->mac_id;
18103 	vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams;
18104 	vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams;
18105 
18106 	return QDF_STATUS_SUCCESS;
18107 }
18108 
18109 /**
18110  * extract_vdev_delete_resp_tlv() - extract vdev delete response
18111  * @wmi_handle: wmi handle
18112  * @param evt_buf: pointer to event buffer
18113  * @param delete_rsp: Pointer to hold vdev delete response
18114  *
18115  * Return: QDF_STATUS_SUCCESS for success or error code
18116  */
18117 static QDF_STATUS extract_vdev_delete_resp_tlv(wmi_unified_t wmi_handle,
18118 	void *evt_buf, struct wmi_host_vdev_delete_resp *delete_rsp)
18119 {
18120 	WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf;
18121 	wmi_vdev_delete_resp_event_fixed_param *ev;
18122 
18123 	param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *) evt_buf;
18124 	if (!param_buf) {
18125 		WMI_LOGE("Invalid vdev delete response event buffer\n");
18126 		return QDF_STATUS_E_INVAL;
18127 	}
18128 
18129 	ev = param_buf->fixed_param;
18130 	if (!ev) {
18131 		WMI_LOGE("Invalid vdev delete response event\n");
18132 		return QDF_STATUS_E_INVAL;
18133 	}
18134 
18135 	qdf_mem_zero(delete_rsp, sizeof(*delete_rsp));
18136 	delete_rsp->vdev_id = ev->vdev_id;
18137 
18138 	return QDF_STATUS_SUCCESS;
18139 }
18140 
18141 
18142 /**
18143  * extract_tbttoffset_num_vdevs_tlv() - extract tbtt offset num vdev
18144  * @wmi_handle: wmi handle
18145  * @param evt_buf: pointer to event buffer
18146  * @param num_vdevs: Pointer to hold num vdev
18147  *
18148  * Return: QDF_STATUS_SUCCESS for success or error code
18149  */
18150 static QDF_STATUS extract_tbttoffset_num_vdevs_tlv(void *wmi_hdl,
18151 	void *evt_buf, uint32_t *num_vdevs)
18152 {
18153 	WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
18154 	wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
18155 	uint32_t vdev_map;
18156 
18157 	param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf;
18158 	if (!param_buf) {
18159 		qdf_print("Invalid tbtt update ext event buffer");
18160 		return QDF_STATUS_E_INVAL;
18161 	}
18162 	tbtt_offset_event = param_buf->fixed_param;
18163 	vdev_map = tbtt_offset_event->vdev_map;
18164 	*num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map);
18165 
18166 	return QDF_STATUS_SUCCESS;
18167 }
18168 
18169 /**
18170  * extract_ext_tbttoffset_num_vdevs_tlv() - extract ext tbtt offset num vdev
18171  * @wmi_handle: wmi handle
18172  * @param evt_buf: pointer to event buffer
18173  * @param num_vdevs: Pointer to hold num vdev
18174  *
18175  * Return: QDF_STATUS_SUCCESS for success or error code
18176  */
18177 static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(void *wmi_hdl,
18178 	void *evt_buf, uint32_t *num_vdevs)
18179 {
18180 	WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf;
18181 	wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event;
18182 
18183 	param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf;
18184 	if (!param_buf) {
18185 		qdf_print("Invalid tbtt update ext event buffer");
18186 		return QDF_STATUS_E_INVAL;
18187 	}
18188 	tbtt_offset_ext_event = param_buf->fixed_param;
18189 
18190 	*num_vdevs = tbtt_offset_ext_event->num_vdevs;
18191 
18192 	return QDF_STATUS_SUCCESS;
18193 }
18194 
18195 /**
18196  * extract_tbttoffset_update_params_tlv() - extract tbtt offset param
18197  * @wmi_handle: wmi handle
18198  * @param evt_buf: pointer to event buffer
18199  * @param idx: Index referring to a vdev
18200  * @param tbtt_param: Pointer to tbttoffset event param
18201  *
18202  * Return: QDF_STATUS_SUCCESS for success or error code
18203  */
18204 static QDF_STATUS extract_tbttoffset_update_params_tlv(void *wmi_hdl,
18205 	void *evt_buf, uint8_t idx,
18206 	struct tbttoffset_params *tbtt_param)
18207 {
18208 	WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
18209 	wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
18210 	uint32_t vdev_map;
18211 
18212 	param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) evt_buf;
18213 	if (!param_buf) {
18214 		qdf_print("Invalid tbtt update event buffer");
18215 		return QDF_STATUS_E_INVAL;
18216 	}
18217 
18218 	tbtt_offset_event = param_buf->fixed_param;
18219 	vdev_map = tbtt_offset_event->vdev_map;
18220 	tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx);
18221 	if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID)
18222 		return QDF_STATUS_E_INVAL;
18223 	tbtt_param->tbttoffset =
18224 		param_buf->tbttoffset_list[tbtt_param->vdev_id];
18225 
18226 	return QDF_STATUS_SUCCESS;
18227 }
18228 
18229 /**
18230  * extract_ext_tbttoffset_update_params_tlv() - extract ext tbtt offset param
18231  * @wmi_handle: wmi handle
18232  * @param evt_buf: pointer to event buffer
18233  * @param idx: Index referring to a vdev
18234  * @param tbtt_param: Pointer to tbttoffset event param
18235  *
18236  * Return: QDF_STATUS_SUCCESS for success or error code
18237  */
18238 static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(void *wmi_hdl,
18239 	void *evt_buf, uint8_t idx,
18240 	struct tbttoffset_params *tbtt_param)
18241 {
18242 	WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf;
18243 	wmi_tbtt_offset_info *tbtt_offset_info;
18244 
18245 	param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf;
18246 	if (!param_buf) {
18247 		qdf_print("Invalid tbtt update event buffer");
18248 		return QDF_STATUS_E_INVAL;
18249 	}
18250 	tbtt_offset_info = &param_buf->tbtt_offset_info[idx];
18251 
18252 	tbtt_param->vdev_id = tbtt_offset_info->vdev_id;
18253 	tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset;
18254 
18255 	return QDF_STATUS_SUCCESS;
18256 }
18257 
18258 #ifdef CONFIG_MCL
18259 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \
18260 			((_status) & WMI_RXERR_DECRYPT)
18261 #else
18262 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false
18263 #endif
18264 
18265 /**
18266  * extract_mgmt_rx_params_tlv() - extract management rx params from event
18267  * @wmi_handle: wmi handle
18268  * @param evt_buf: pointer to event buffer
18269  * @param hdr: Pointer to hold header
18270  * @param bufp: Pointer to hold pointer to rx param buffer
18271  *
18272  * Return: QDF_STATUS_SUCCESS for success or error code
18273  */
18274 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle,
18275 	void *evt_buf, struct mgmt_rx_event_params *hdr,
18276 	uint8_t **bufp)
18277 {
18278 	WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL;
18279 	wmi_mgmt_rx_hdr *ev_hdr = NULL;
18280 	int i;
18281 
18282 	param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf;
18283 	if (!param_tlvs) {
18284 		WMI_LOGE("Get NULL point message from FW");
18285 		return QDF_STATUS_E_INVAL;
18286 	}
18287 
18288 	ev_hdr = param_tlvs->hdr;
18289 	if (!hdr) {
18290 		WMI_LOGE("Rx event is NULL");
18291 		return QDF_STATUS_E_INVAL;
18292 	}
18293 
18294 	if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) {
18295 		WMI_LOGE("%s: RX mgmt frame decrypt error, discard it",
18296 			 __func__);
18297 		return QDF_STATUS_E_INVAL;
18298 	}
18299 
18300 	hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18301 							ev_hdr->pdev_id);
18302 
18303 	hdr->channel = ev_hdr->channel;
18304 	hdr->snr = ev_hdr->snr;
18305 	hdr->rate = ev_hdr->rate;
18306 	hdr->phy_mode = ev_hdr->phy_mode;
18307 	hdr->buf_len = ev_hdr->buf_len;
18308 	hdr->status = ev_hdr->status;
18309 	hdr->flags = ev_hdr->flags;
18310 	hdr->rssi = ev_hdr->rssi;
18311 	hdr->tsf_delta = ev_hdr->tsf_delta;
18312 	for (i = 0; i < ATH_MAX_ANTENNA; i++)
18313 		hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i];
18314 
18315 	*bufp = param_tlvs->bufp;
18316 
18317 	return QDF_STATUS_SUCCESS;
18318 }
18319 
18320 /**
18321  * extract_vdev_stopped_param_tlv() - extract vdev stop param from event
18322  * @wmi_handle: wmi handle
18323  * @param evt_buf: pointer to event buffer
18324  * @param vdev_id: Pointer to hold vdev identifier
18325  *
18326  * Return: QDF_STATUS_SUCCESS for success or error code
18327  */
18328 static QDF_STATUS extract_vdev_stopped_param_tlv(wmi_unified_t wmi_handle,
18329 	void *evt_buf, uint32_t *vdev_id)
18330 {
18331 	WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf;
18332 	wmi_vdev_stopped_event_fixed_param *resp_event;
18333 
18334 	param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) evt_buf;
18335 	if (!param_buf) {
18336 		WMI_LOGE("Invalid event buffer");
18337 		return QDF_STATUS_E_INVAL;
18338 	}
18339 	resp_event = param_buf->fixed_param;
18340 	*vdev_id = resp_event->vdev_id;
18341 
18342 	return QDF_STATUS_SUCCESS;
18343 }
18344 
18345 /**
18346  * extract_vdev_roam_param_tlv() - extract vdev roam param from event
18347  * @wmi_handle: wmi handle
18348  * @param evt_buf: pointer to event buffer
18349  * @param param: Pointer to hold roam param
18350  *
18351  * Return: QDF_STATUS_SUCCESS for success or error code
18352  */
18353 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle,
18354 	void *evt_buf, wmi_host_roam_event *param)
18355 {
18356 	WMI_ROAM_EVENTID_param_tlvs *param_buf;
18357 	wmi_roam_event_fixed_param *evt;
18358 
18359 	param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf;
18360 	if (!param_buf) {
18361 		WMI_LOGE("Invalid roam event buffer");
18362 		return QDF_STATUS_E_INVAL;
18363 	}
18364 
18365 	evt = param_buf->fixed_param;
18366 	qdf_mem_zero(param, sizeof(*param));
18367 
18368 	param->vdev_id = evt->vdev_id;
18369 	param->reason = evt->reason;
18370 	param->rssi = evt->rssi;
18371 
18372 	return QDF_STATUS_SUCCESS;
18373 }
18374 
18375 /**
18376  * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event
18377  * @wmi_handle: wmi handle
18378  * @param evt_buf: pointer to event buffer
18379  * @param param: Pointer to hold vdev scan param
18380  *
18381  * Return: QDF_STATUS_SUCCESS for success or error code
18382  */
18383 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle,
18384 	void *evt_buf, struct scan_event *param)
18385 {
18386 	WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL;
18387 	wmi_scan_event_fixed_param *evt = NULL;
18388 
18389 	param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf;
18390 	evt = param_buf->fixed_param;
18391 
18392 	qdf_mem_zero(param, sizeof(*param));
18393 
18394 	switch (evt->event) {
18395 	case WMI_SCAN_EVENT_STARTED:
18396 		param->type = SCAN_EVENT_TYPE_STARTED;
18397 		break;
18398 	case WMI_SCAN_EVENT_COMPLETED:
18399 		param->type = SCAN_EVENT_TYPE_COMPLETED;
18400 		break;
18401 	case WMI_SCAN_EVENT_BSS_CHANNEL:
18402 		param->type = SCAN_EVENT_TYPE_BSS_CHANNEL;
18403 		break;
18404 	case WMI_SCAN_EVENT_FOREIGN_CHANNEL:
18405 		param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL;
18406 		break;
18407 	case WMI_SCAN_EVENT_DEQUEUED:
18408 		param->type = SCAN_EVENT_TYPE_DEQUEUED;
18409 		break;
18410 	case WMI_SCAN_EVENT_PREEMPTED:
18411 		param->type = SCAN_EVENT_TYPE_PREEMPTED;
18412 		break;
18413 	case WMI_SCAN_EVENT_START_FAILED:
18414 		param->type = SCAN_EVENT_TYPE_START_FAILED;
18415 		break;
18416 	case WMI_SCAN_EVENT_RESTARTED:
18417 		param->type = SCAN_EVENT_TYPE_RESTARTED;
18418 		break;
18419 	case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT:
18420 		param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT;
18421 		break;
18422 	case WMI_SCAN_EVENT_MAX:
18423 	default:
18424 		param->type = SCAN_EVENT_TYPE_MAX;
18425 		break;
18426 	};
18427 
18428 	switch (evt->reason) {
18429 	case WMI_SCAN_REASON_NONE:
18430 		param->reason = SCAN_REASON_NONE;
18431 		break;
18432 	case WMI_SCAN_REASON_COMPLETED:
18433 		param->reason = SCAN_REASON_COMPLETED;
18434 		break;
18435 	case WMI_SCAN_REASON_CANCELLED:
18436 		param->reason = SCAN_REASON_CANCELLED;
18437 		break;
18438 	case WMI_SCAN_REASON_PREEMPTED:
18439 		param->reason = SCAN_REASON_PREEMPTED;
18440 		break;
18441 	case WMI_SCAN_REASON_TIMEDOUT:
18442 		param->reason = SCAN_REASON_TIMEDOUT;
18443 		break;
18444 	case WMI_SCAN_REASON_INTERNAL_FAILURE:
18445 		param->reason = SCAN_REASON_INTERNAL_FAILURE;
18446 		break;
18447 	case WMI_SCAN_REASON_SUSPENDED:
18448 		param->reason = SCAN_REASON_SUSPENDED;
18449 		break;
18450 	case WMI_SCAN_REASON_MAX:
18451 		param->reason = SCAN_REASON_MAX;
18452 		break;
18453 	default:
18454 		param->reason = SCAN_REASON_MAX;
18455 		break;
18456 	};
18457 
18458 	param->chan_freq = evt->channel_freq;
18459 	param->requester = evt->requestor;
18460 	param->scan_id = evt->scan_id;
18461 	param->vdev_id = evt->vdev_id;
18462 	param->timestamp = evt->tsf_timestamp;
18463 
18464 	return QDF_STATUS_SUCCESS;
18465 }
18466 
18467 #ifdef CONVERGED_TDLS_ENABLE
18468 /**
18469  * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event
18470  * @wmi_handle: wmi handle
18471  * @param evt_buf: pointer to event buffer
18472  * @param param: Pointer to hold vdev tdls param
18473  *
18474  * Return: QDF_STATUS_SUCCESS for success or error code
18475  */
18476 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle,
18477 	void *evt_buf, struct tdls_event_info *param)
18478 {
18479 	WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf;
18480 	wmi_tdls_peer_event_fixed_param *evt;
18481 
18482 	param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf;
18483 	if (!param_buf) {
18484 		WMI_LOGE("%s: NULL param_buf", __func__);
18485 		return QDF_STATUS_E_NULL_VALUE;
18486 	}
18487 
18488 	evt = param_buf->fixed_param;
18489 
18490 	qdf_mem_zero(param, sizeof(*param));
18491 
18492 	param->vdev_id = evt->vdev_id;
18493 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr,
18494 				   param->peermac.bytes);
18495 	switch (evt->peer_status) {
18496 	case WMI_TDLS_SHOULD_DISCOVER:
18497 		param->message_type = TDLS_SHOULD_DISCOVER;
18498 		break;
18499 	case WMI_TDLS_SHOULD_TEARDOWN:
18500 		param->message_type = TDLS_SHOULD_TEARDOWN;
18501 		break;
18502 	case WMI_TDLS_PEER_DISCONNECTED:
18503 		param->message_type = TDLS_PEER_DISCONNECTED;
18504 		break;
18505 	case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION:
18506 		param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY;
18507 		break;
18508 	default:
18509 		WMI_LOGE("%s: Discarding unknown tdls event %d from target",
18510 			 __func__, evt->peer_status);
18511 		return QDF_STATUS_E_INVAL;
18512 	};
18513 
18514 	switch (evt->peer_reason) {
18515 	case WMI_TDLS_TEARDOWN_REASON_TX:
18516 		param->peer_reason = TDLS_TEARDOWN_TX;
18517 		break;
18518 	case WMI_TDLS_TEARDOWN_REASON_RSSI:
18519 		param->peer_reason = TDLS_TEARDOWN_RSSI;
18520 		break;
18521 	case WMI_TDLS_TEARDOWN_REASON_SCAN:
18522 		param->peer_reason = TDLS_TEARDOWN_SCAN;
18523 		break;
18524 	case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE:
18525 		param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE;
18526 		break;
18527 	case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
18528 		param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT;
18529 		break;
18530 	case WMI_TDLS_TEARDOWN_REASON_BAD_PTR:
18531 		param->peer_reason = TDLS_TEARDOWN_BAD_PTR;
18532 		break;
18533 	case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
18534 		param->peer_reason = TDLS_TEARDOWN_NO_RSP;
18535 		break;
18536 	case WMI_TDLS_ENTER_BUF_STA:
18537 		param->peer_reason = TDLS_PEER_ENTER_BUF_STA;
18538 		break;
18539 	case WMI_TDLS_EXIT_BUF_STA:
18540 		param->peer_reason = TDLS_PEER_EXIT_BUF_STA;
18541 		break;
18542 	case WMI_TDLS_ENTER_BT_BUSY_MODE:
18543 		param->peer_reason = TDLS_ENTER_BT_BUSY;
18544 		break;
18545 	case WMI_TDLS_EXIT_BT_BUSY_MODE:
18546 		param->peer_reason = TDLS_EXIT_BT_BUSY;
18547 		break;
18548 	case WMI_TDLS_SCAN_STARTED_EVENT:
18549 		param->peer_reason = TDLS_SCAN_STARTED;
18550 		break;
18551 	case WMI_TDLS_SCAN_COMPLETED_EVENT:
18552 		param->peer_reason = TDLS_SCAN_COMPLETED;
18553 		break;
18554 
18555 	default:
18556 		WMI_LOGE("%s: unknown reason %d in tdls event %d from target",
18557 			 __func__, evt->peer_reason, evt->peer_status);
18558 		return QDF_STATUS_E_INVAL;
18559 	};
18560 
18561 	WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d",
18562 		 __func__, param->peermac.bytes, param->message_type,
18563 		 param->peer_reason, param->vdev_id);
18564 
18565 	return QDF_STATUS_SUCCESS;
18566 }
18567 #endif
18568 
18569 /**
18570  * extract_mgmt_tx_compl_param_tlv() - extract MGMT tx completion event params
18571  * @wmi_handle: wmi handle
18572  * @param evt_buf: pointer to event buffer
18573  * @param param: Pointer to hold MGMT TX completion params
18574  *
18575  * Return: QDF_STATUS_SUCCESS for success or error code
18576  */
18577 static QDF_STATUS extract_mgmt_tx_compl_param_tlv(wmi_unified_t wmi_handle,
18578 	void *evt_buf, wmi_host_mgmt_tx_compl_event *param)
18579 {
18580 	WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf;
18581 	wmi_mgmt_tx_compl_event_fixed_param *cmpl_params;
18582 
18583 	param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *)
18584 		evt_buf;
18585 	if (!param_buf) {
18586 		WMI_LOGE("%s: Invalid mgmt Tx completion event", __func__);
18587 		return QDF_STATUS_E_INVAL;
18588 	}
18589 	cmpl_params = param_buf->fixed_param;
18590 
18591 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18592 							cmpl_params->pdev_id);
18593 	param->desc_id = cmpl_params->desc_id;
18594 	param->status = cmpl_params->status;
18595 	param->ppdu_id = cmpl_params->ppdu_id;
18596 
18597 	return QDF_STATUS_SUCCESS;
18598 }
18599 
18600 /**
18601  * extract_offchan_data_tx_compl_param_tlv() -
18602  *            extract Offchan data tx completion event params
18603  * @wmi_handle: wmi handle
18604  * @param evt_buf: pointer to event buffer
18605  * @param param: Pointer to hold offchan data TX completion params
18606  *
18607  * Return: QDF_STATUS_SUCCESS for success or error code
18608  */
18609 static QDF_STATUS extract_offchan_data_tx_compl_param_tlv(
18610 		wmi_unified_t wmi_handle, void *evt_buf,
18611 		struct wmi_host_offchan_data_tx_compl_event *param)
18612 {
18613 	WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *param_buf;
18614 	wmi_offchan_data_tx_compl_event_fixed_param *cmpl_params;
18615 
18616 	param_buf = (WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *)
18617 		evt_buf;
18618 	if (!param_buf) {
18619 		WMI_LOGE("%s: Invalid offchan data Tx compl event", __func__);
18620 		return QDF_STATUS_E_INVAL;
18621 	}
18622 	cmpl_params = param_buf->fixed_param;
18623 
18624 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18625 							cmpl_params->pdev_id);
18626 	param->desc_id = cmpl_params->desc_id;
18627 	param->status = cmpl_params->status;
18628 
18629 	return QDF_STATUS_SUCCESS;
18630 }
18631 
18632 /**
18633  * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count
18634  *                                              status tlv
18635  * @wmi_handle: wmi handle
18636  * @param evt_buf: pointer to event buffer
18637  * @param param: Pointer to hold csa switch count status event param
18638  *
18639  * Return: QDF_STATUS_SUCCESS for success or error code
18640  */
18641 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv(
18642 				wmi_unified_t wmi_handle,
18643 				void *evt_buf,
18644 				struct pdev_csa_switch_count_status *param)
18645 {
18646 	WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf;
18647 	wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status;
18648 
18649 	param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *)
18650 		     evt_buf;
18651 	if (!param_buf) {
18652 		WMI_LOGE("%s: Invalid CSA status event\n", __func__);
18653 		return QDF_STATUS_E_INVAL;
18654 	}
18655 
18656 	csa_status = param_buf->fixed_param;
18657 
18658 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18659 							csa_status->pdev_id);
18660 	param->current_switch_count = csa_status->current_switch_count;
18661 	param->num_vdevs = csa_status->num_vdevs;
18662 	param->vdev_ids = param_buf->vdev_ids;
18663 
18664 	return QDF_STATUS_SUCCESS;
18665 }
18666 
18667 /**
18668  * extract_pdev_tpc_config_ev_param_tlv() - extract pdev tpc configuration
18669  * param from event
18670  * @wmi_handle: wmi handle
18671  * @param evt_buf: pointer to event buffer
18672  * @param param: Pointer to hold tpc configuration
18673  *
18674  * Return: 0 for success or error code
18675  */
18676 static QDF_STATUS extract_pdev_tpc_config_ev_param_tlv(wmi_unified_t wmi_handle,
18677 		void *evt_buf,
18678 		wmi_host_pdev_tpc_config_event *param)
18679 {
18680 	wmi_pdev_tpc_config_event_fixed_param *event =
18681 		(wmi_pdev_tpc_config_event_fixed_param *)evt_buf;
18682 
18683 	if (!event) {
18684 		WMI_LOGE("Invalid event buffer");
18685 		return QDF_STATUS_E_INVAL;
18686 	}
18687 
18688 	param->pdev_id = event->pdev_id;
18689 	param->regDomain = event->regDomain;
18690 	param->chanFreq = event->chanFreq;
18691 	param->phyMode = event->phyMode;
18692 	param->twiceAntennaReduction = event->twiceAntennaReduction;
18693 	param->twiceAntennaGain = event->twiceAntennaGain;
18694 	param->twiceMaxRDPower = event->twiceMaxRDPower;
18695 	param->powerLimit = event->powerLimit;
18696 	param->rateMax = event->rateMax;
18697 	param->numTxChain = event->numTxChain;
18698 	param->ctl = event->ctl;
18699 	param->flags = event->flags;
18700 
18701 	qdf_mem_copy(param->maxRegAllowedPower, event->maxRegAllowedPower,
18702 		sizeof(param->maxRegAllowedPower));
18703 	qdf_mem_copy(param->maxRegAllowedPowerAGCDD,
18704 		event->maxRegAllowedPowerAGCDD,
18705 		sizeof(param->maxRegAllowedPowerAGCDD));
18706 	qdf_mem_copy(param->maxRegAllowedPowerAGSTBC,
18707 		event->maxRegAllowedPowerAGSTBC,
18708 		sizeof(param->maxRegAllowedPowerAGSTBC));
18709 	qdf_mem_copy(param->maxRegAllowedPowerAGTXBF,
18710 		event->maxRegAllowedPowerAGTXBF,
18711 		sizeof(param->maxRegAllowedPowerAGTXBF));
18712 	WMI_LOGD("%s:extract success", __func__);
18713 
18714 	return QDF_STATUS_SUCCESS;
18715 }
18716 
18717 /**
18718  * extract_swba_num_vdevs_tlv() - extract swba num vdevs from event
18719  * @wmi_handle: wmi handle
18720  * @param evt_buf: pointer to event buffer
18721  * @param num_vdevs: Pointer to hold num vdevs
18722  *
18723  * Return: QDF_STATUS_SUCCESS for success or error code
18724  */
18725 static QDF_STATUS extract_swba_num_vdevs_tlv(wmi_unified_t wmi_handle,
18726 	void *evt_buf, uint32_t *num_vdevs)
18727 {
18728 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
18729 	wmi_host_swba_event_fixed_param *swba_event;
18730 	uint32_t vdev_map;
18731 
18732 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf;
18733 	if (!param_buf) {
18734 		WMI_LOGE("Invalid swba event buffer");
18735 		return QDF_STATUS_E_INVAL;
18736 	}
18737 
18738 	swba_event = param_buf->fixed_param;
18739 	*num_vdevs = swba_event->num_vdevs;
18740 	if (!(*num_vdevs)) {
18741 		vdev_map = swba_event->vdev_map;
18742 		*num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map);
18743 	}
18744 
18745 	return QDF_STATUS_SUCCESS;
18746 }
18747 
18748 /**
18749  * extract_swba_tim_info_tlv() - extract swba tim info from event
18750  * @wmi_handle: wmi handle
18751  * @param evt_buf: pointer to event buffer
18752  * @param idx: Index to bcn info
18753  * @param tim_info: Pointer to hold tim info
18754  *
18755  * Return: QDF_STATUS_SUCCESS for success or error code
18756  */
18757 static QDF_STATUS extract_swba_tim_info_tlv(wmi_unified_t wmi_handle,
18758 	void *evt_buf, uint32_t idx, wmi_host_tim_info *tim_info)
18759 {
18760 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
18761 	wmi_tim_info *tim_info_ev;
18762 
18763 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf;
18764 	if (!param_buf) {
18765 		WMI_LOGE("Invalid swba event buffer");
18766 		return QDF_STATUS_E_INVAL;
18767 	}
18768 
18769 	tim_info_ev = &param_buf->tim_info[idx];
18770 
18771 	tim_info->tim_len = tim_info_ev->tim_len;
18772 	tim_info->tim_mcast = tim_info_ev->tim_mcast;
18773 	qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap,
18774 			(sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE));
18775 	tim_info->tim_changed = tim_info_ev->tim_changed;
18776 	tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending;
18777 	tim_info->vdev_id = tim_info_ev->vdev_id;
18778 
18779 	return QDF_STATUS_SUCCESS;
18780 }
18781 
18782 /**
18783  * extract_swba_noa_info_tlv() - extract swba NoA information from event
18784  * @wmi_handle: wmi handle
18785  * @param evt_buf: pointer to event buffer
18786  * @param idx: Index to bcn info
18787  * @param p2p_desc: Pointer to hold p2p NoA info
18788  *
18789  * Return: QDF_STATUS_SUCCESS for success or error code
18790  */
18791 static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle,
18792 	void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc)
18793 {
18794 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
18795 	wmi_p2p_noa_info *p2p_noa_info;
18796 	uint8_t i = 0;
18797 
18798 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf;
18799 	if (!param_buf) {
18800 		WMI_LOGE("Invalid swba event buffer");
18801 		return QDF_STATUS_E_INVAL;
18802 	}
18803 
18804 	p2p_noa_info = &param_buf->p2p_noa_info[idx];
18805 
18806 	p2p_desc->modified = false;
18807 	p2p_desc->num_descriptors = 0;
18808 	if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) {
18809 		p2p_desc->modified = true;
18810 		p2p_desc->index =
18811 			(uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info);
18812 		p2p_desc->oppPS =
18813 			(uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info);
18814 		p2p_desc->ctwindow =
18815 			(uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info);
18816 		p2p_desc->num_descriptors =
18817 			(uint8_t) WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET
18818 							(p2p_noa_info);
18819 		for (i = 0; i < p2p_desc->num_descriptors; i++) {
18820 			p2p_desc->noa_descriptors[i].type_count =
18821 				(uint8_t) p2p_noa_info->noa_descriptors[i].
18822 				type_count;
18823 			p2p_desc->noa_descriptors[i].duration =
18824 				p2p_noa_info->noa_descriptors[i].duration;
18825 			p2p_desc->noa_descriptors[i].interval =
18826 				p2p_noa_info->noa_descriptors[i].interval;
18827 			p2p_desc->noa_descriptors[i].start_time =
18828 				p2p_noa_info->noa_descriptors[i].start_time;
18829 		}
18830 		p2p_desc->vdev_id = p2p_noa_info->vdev_id;
18831 	}
18832 
18833 	return QDF_STATUS_SUCCESS;
18834 }
18835 
18836 #ifdef CONVERGED_P2P_ENABLE
18837 /**
18838  * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event
18839  * @wmi_handle: wmi handle
18840  * @param evt_buf: pointer to event buffer
18841  * @param param: Pointer to hold p2p noa info
18842  *
18843  * Return: QDF_STATUS_SUCCESS for success or error code
18844  */
18845 static QDF_STATUS extract_p2p_noa_ev_param_tlv(
18846 	wmi_unified_t wmi_handle, void *evt_buf,
18847 	struct p2p_noa_info *param)
18848 {
18849 	WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs;
18850 	wmi_p2p_noa_event_fixed_param *fixed_param;
18851 	uint8_t i;
18852 	wmi_p2p_noa_info *wmi_noa_info;
18853 	uint8_t *buf_ptr;
18854 	uint32_t descriptors;
18855 
18856 	param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf;
18857 	if (!param_tlvs) {
18858 		WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__);
18859 		return QDF_STATUS_E_INVAL;
18860 	}
18861 
18862 	if (!param) {
18863 		WMI_LOGE("noa information param is null");
18864 		return QDF_STATUS_E_INVAL;
18865 	}
18866 
18867 	fixed_param = param_tlvs->fixed_param;
18868 	buf_ptr = (uint8_t *) fixed_param;
18869 	buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param);
18870 	wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr);
18871 
18872 	if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) {
18873 		WMI_LOGE("%s: noa attr is not modified", __func__);
18874 		return QDF_STATUS_E_INVAL;
18875 	}
18876 
18877 	param->vdev_id = fixed_param->vdev_id;
18878 	param->index =
18879 		(uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info);
18880 	param->opps_ps =
18881 		(uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info);
18882 	param->ct_window =
18883 		(uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info);
18884 	descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info);
18885 	param->num_desc = (uint8_t) descriptors;
18886 	if (param->num_desc > WMI_P2P_MAX_NOA_DESCRIPTORS) {
18887 		WMI_LOGE("%s: invalid num desc:%d", __func__,
18888 			 param->num_desc);
18889 		return QDF_STATUS_E_INVAL;
18890 	}
18891 
18892 	WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__,
18893 		param->index, param->opps_ps, param->ct_window,
18894 		param->num_desc);
18895 	for (i = 0; i < param->num_desc; i++) {
18896 		param->noa_desc[i].type_count =
18897 			(uint8_t) wmi_noa_info->noa_descriptors[i].
18898 			type_count;
18899 		param->noa_desc[i].duration =
18900 			wmi_noa_info->noa_descriptors[i].duration;
18901 		param->noa_desc[i].interval =
18902 			wmi_noa_info->noa_descriptors[i].interval;
18903 		param->noa_desc[i].start_time =
18904 			wmi_noa_info->noa_descriptors[i].start_time;
18905 		WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u",
18906 			__func__, i, param->noa_desc[i].type_count,
18907 			param->noa_desc[i].duration,
18908 			param->noa_desc[i].interval,
18909 			param->noa_desc[i].start_time);
18910 	}
18911 
18912 	return QDF_STATUS_SUCCESS;
18913 }
18914 
18915 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
18916 /**
18917  * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop
18918  * information from event
18919  * @wmi_handle: wmi handle
18920  * @param evt_buf: pointer to event buffer
18921  * @param param: Pointer to hold p2p lo stop event information
18922  *
18923  * Return: QDF_STATUS_SUCCESS for success or error code
18924  */
18925 static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv(
18926 	wmi_unified_t wmi_handle, void *evt_buf,
18927 	struct p2p_lo_event *param)
18928 {
18929 	WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs;
18930 	wmi_p2p_lo_stopped_event_fixed_param *lo_param;
18931 
18932 	param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *)
18933 					evt_buf;
18934 	if (!param_tlvs) {
18935 		WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__);
18936 		return QDF_STATUS_E_INVAL;
18937 	}
18938 
18939 	if (!param) {
18940 		WMI_LOGE("lo stop event param is null");
18941 		return QDF_STATUS_E_INVAL;
18942 	}
18943 
18944 	lo_param = param_tlvs->fixed_param;
18945 	param->vdev_id = lo_param->vdev_id;
18946 	param->reason_code = lo_param->reason;
18947 	WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__,
18948 		param->vdev_id, param->reason_code);
18949 
18950 	return QDF_STATUS_SUCCESS;
18951 }
18952 #endif
18953 #endif /* End of CONVERGED_P2P_ENABLE */
18954 
18955 /**
18956  * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event
18957  * @wmi_handle: wmi handle
18958  * @param evt_buf: pointer to event buffer
18959  * @param ev: Pointer to hold peer param
18960  *
18961  * Return: QDF_STATUS_SUCCESS for success or error code
18962  */
18963 static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle,
18964 	void *evt_buf, wmi_host_peer_sta_kickout_event *ev)
18965 {
18966 	WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL;
18967 	wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL;
18968 
18969 	param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) evt_buf;
18970 	kickout_event = param_buf->fixed_param;
18971 
18972 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr,
18973 							ev->peer_macaddr);
18974 
18975 	ev->reason = kickout_event->reason;
18976 	ev->rssi = kickout_event->rssi;
18977 
18978 	return QDF_STATUS_SUCCESS;
18979 }
18980 
18981 /**
18982  * extract_all_stats_counts_tlv() - extract all stats count from event
18983  * @wmi_handle: wmi handle
18984  * @param evt_buf: pointer to event buffer
18985  * @param stats_param: Pointer to hold stats count
18986  *
18987  * Return: QDF_STATUS_SUCCESS for success or error code
18988  */
18989 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle,
18990 	void *evt_buf, wmi_host_stats_event *stats_param)
18991 {
18992 	wmi_stats_event_fixed_param *ev;
18993 	wmi_per_chain_rssi_stats *rssi_event;
18994 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
18995 	uint64_t min_data_len;
18996 
18997 	qdf_mem_zero(stats_param, sizeof(*stats_param));
18998 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
18999 	ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19000 	rssi_event = param_buf->chain_stats;
19001 	if (!ev) {
19002 		WMI_LOGE("%s: event fixed param NULL\n", __func__);
19003 		return QDF_STATUS_E_FAILURE;
19004 	}
19005 
19006 	if (param_buf->num_data > WMI_SVC_MSG_MAX_SIZE - sizeof(*ev)) {
19007 		WMI_LOGE("num_data : %u is invalid", param_buf->num_data);
19008 		return QDF_STATUS_E_FAULT;
19009 	}
19010 
19011 	switch (ev->stats_id) {
19012 	case WMI_REQUEST_PEER_STAT:
19013 		stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT;
19014 		break;
19015 
19016 	case WMI_REQUEST_AP_STAT:
19017 		stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT;
19018 		break;
19019 
19020 	case WMI_REQUEST_PDEV_STAT:
19021 		stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT;
19022 		break;
19023 
19024 	case WMI_REQUEST_VDEV_STAT:
19025 		stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT;
19026 		break;
19027 
19028 	case WMI_REQUEST_BCNFLT_STAT:
19029 		stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT;
19030 		break;
19031 
19032 	case WMI_REQUEST_VDEV_RATE_STAT:
19033 		stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT;
19034 		break;
19035 
19036 	case WMI_REQUEST_BCN_STAT:
19037 		stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT;
19038 		break;
19039 
19040 	default:
19041 		stats_param->stats_id = 0;
19042 		break;
19043 
19044 	}
19045 
19046 	/* ev->num_*_stats may cause uint32_t overflow, so use uint64_t
19047 	 * to save total length calculated
19048 	 */
19049 	min_data_len =
19050 		(((uint64_t)ev->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19051 		(((uint64_t)ev->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19052 		(((uint64_t)ev->num_peer_stats) * sizeof(wmi_peer_stats)) +
19053 		(((uint64_t)ev->num_bcnflt_stats) *
19054 		 sizeof(wmi_bcnfilter_stats_t)) +
19055 		(((uint64_t)ev->num_chan_stats) * sizeof(wmi_chan_stats)) +
19056 		(((uint64_t)ev->num_mib_stats) * sizeof(wmi_mib_stats)) +
19057 		(((uint64_t)ev->num_bcn_stats) * sizeof(wmi_bcn_stats)) +
19058 		(((uint64_t)ev->num_peer_extd_stats) *
19059 		 sizeof(wmi_peer_extd_stats));
19060 	if (param_buf->num_data != min_data_len) {
19061 		WMI_LOGE("data len: %u isn't same as calculated: %llu",
19062 			 param_buf->num_data, min_data_len);
19063 		return QDF_STATUS_E_FAULT;
19064 	}
19065 
19066 	stats_param->num_pdev_stats = ev->num_pdev_stats;
19067 	stats_param->num_pdev_ext_stats = 0;
19068 	stats_param->num_vdev_stats = ev->num_vdev_stats;
19069 	stats_param->num_peer_stats = ev->num_peer_stats;
19070 	stats_param->num_bcnflt_stats = ev->num_bcnflt_stats;
19071 	stats_param->num_chan_stats = ev->num_chan_stats;
19072 	stats_param->num_bcn_stats = ev->num_bcn_stats;
19073 	stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19074 							ev->pdev_id);
19075 
19076 	/* if chain_stats is not populated */
19077 	if (!param_buf->chain_stats || !param_buf->num_chain_stats)
19078 		return QDF_STATUS_SUCCESS;
19079 
19080 	if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats !=
19081 	    WMITLV_GET_TLVTAG(rssi_event->tlv_header))
19082 		return QDF_STATUS_SUCCESS;
19083 
19084 	if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) !=
19085 	    WMITLV_GET_TLVLEN(rssi_event->tlv_header))
19086 		return QDF_STATUS_SUCCESS;
19087 
19088 	if (rssi_event->num_per_chain_rssi_stats >=
19089 	    WMITLV_GET_TLVLEN(rssi_event->tlv_header)) {
19090 		WMI_LOGE("num_per_chain_rssi_stats:%u is out of bounds",
19091 			 rssi_event->num_per_chain_rssi_stats);
19092 		return QDF_STATUS_E_INVAL;
19093 	}
19094 	stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats;
19095 
19096 	return QDF_STATUS_SUCCESS;
19097 }
19098 
19099 /**
19100  * extract_pdev_tx_stats() - extract pdev tx stats from event
19101  */
19102 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, struct wlan_dbg_tx_stats *tx_stats)
19103 {
19104 	/* Tx Stats */
19105 	tx->comp_queued = tx_stats->comp_queued;
19106 	tx->comp_delivered = tx_stats->comp_delivered;
19107 	tx->msdu_enqued = tx_stats->msdu_enqued;
19108 	tx->mpdu_enqued = tx_stats->mpdu_enqued;
19109 	tx->wmm_drop = tx_stats->wmm_drop;
19110 	tx->local_enqued = tx_stats->local_enqued;
19111 	tx->local_freed = tx_stats->local_freed;
19112 	tx->hw_queued = tx_stats->hw_queued;
19113 	tx->hw_reaped = tx_stats->hw_reaped;
19114 	tx->underrun = tx_stats->underrun;
19115 	tx->tx_abort = tx_stats->tx_abort;
19116 	tx->mpdus_requed = tx_stats->mpdus_requed;
19117 	tx->data_rc = tx_stats->data_rc;
19118 	tx->self_triggers = tx_stats->self_triggers;
19119 	tx->sw_retry_failure = tx_stats->sw_retry_failure;
19120 	tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err;
19121 	tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry;
19122 	tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout;
19123 	tx->pdev_resets = tx_stats->pdev_resets;
19124 	tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure;
19125 	tx->phy_underrun = tx_stats->phy_underrun;
19126 	tx->txop_ovf = tx_stats->txop_ovf;
19127 
19128 	return;
19129 }
19130 
19131 
19132 /**
19133  * extract_pdev_rx_stats() - extract pdev rx stats from event
19134  */
19135 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, struct wlan_dbg_rx_stats *rx_stats)
19136 {
19137 	/* Rx Stats */
19138 	rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change;
19139 	rx->status_rcvd = rx_stats->status_rcvd;
19140 	rx->r0_frags = rx_stats->r0_frags;
19141 	rx->r1_frags = rx_stats->r1_frags;
19142 	rx->r2_frags = rx_stats->r2_frags;
19143 	/* Only TLV */
19144 	rx->r3_frags = 0;
19145 	rx->htt_msdus = rx_stats->htt_msdus;
19146 	rx->htt_mpdus = rx_stats->htt_mpdus;
19147 	rx->loc_msdus = rx_stats->loc_msdus;
19148 	rx->loc_mpdus = rx_stats->loc_mpdus;
19149 	rx->oversize_amsdu = rx_stats->oversize_amsdu;
19150 	rx->phy_errs = rx_stats->phy_errs;
19151 	rx->phy_err_drop = rx_stats->phy_err_drop;
19152 	rx->mpdu_errs = rx_stats->mpdu_errs;
19153 
19154 	return;
19155 }
19156 
19157 /**
19158  * extract_pdev_stats_tlv() - extract pdev stats from event
19159  * @wmi_handle: wmi handle
19160  * @param evt_buf: pointer to event buffer
19161  * @param index: Index into pdev stats
19162  * @param pdev_stats: Pointer to hold pdev stats
19163  *
19164  * Return: QDF_STATUS_SUCCESS for success or error code
19165  */
19166 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle,
19167 	void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats)
19168 {
19169 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19170 	wmi_stats_event_fixed_param *ev_param;
19171 	uint8_t *data;
19172 
19173 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19174 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19175 
19176 	data = param_buf->data;
19177 
19178 	if (index < ev_param->num_pdev_stats) {
19179 		wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) +
19180 				(index * sizeof(wmi_pdev_stats)));
19181 
19182 		pdev_stats->chan_nf = ev->chan_nf;
19183 		pdev_stats->tx_frame_count = ev->tx_frame_count;
19184 		pdev_stats->rx_frame_count = ev->rx_frame_count;
19185 		pdev_stats->rx_clear_count = ev->rx_clear_count;
19186 		pdev_stats->cycle_count = ev->cycle_count;
19187 		pdev_stats->phy_err_count = ev->phy_err_count;
19188 		pdev_stats->chan_tx_pwr = ev->chan_tx_pwr;
19189 
19190 		extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx),
19191 			&(ev->pdev_stats.tx));
19192 		extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx),
19193 			&(ev->pdev_stats.rx));
19194 	}
19195 
19196 	return QDF_STATUS_SUCCESS;
19197 }
19198 
19199 /**
19200  * extract_unit_test_tlv() - extract unit test data
19201  * @wmi_handle: wmi handle
19202  * @param evt_buf: pointer to event buffer
19203  * @param unit_test: pointer to hold unit test data
19204  * @param maxspace: Amount of space in evt_buf
19205  *
19206  * Return: QDF_STATUS_SUCCESS for success or error code
19207  */
19208 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle,
19209 	void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace)
19210 {
19211 	WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf;
19212 	wmi_unit_test_event_fixed_param *ev_param;
19213 	uint32_t num_bufp;
19214 	uint32_t copy_size;
19215 	uint8_t *bufp;
19216 
19217 	param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf;
19218 	ev_param = param_buf->fixed_param;
19219 	bufp = param_buf->bufp;
19220 	num_bufp = param_buf->num_bufp;
19221 	unit_test->vdev_id = ev_param->vdev_id;
19222 	unit_test->module_id = ev_param->module_id;
19223 	unit_test->diag_token = ev_param->diag_token;
19224 	unit_test->flag = ev_param->flag;
19225 	unit_test->payload_len = ev_param->payload_len;
19226 	WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d\n", __func__,
19227 			ev_param->vdev_id,
19228 			ev_param->module_id,
19229 			ev_param->diag_token,
19230 			ev_param->flag);
19231 	WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp);
19232 	qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
19233 			bufp, num_bufp);
19234 	copy_size = (num_bufp < maxspace) ? num_bufp : maxspace;
19235 	qdf_mem_copy(unit_test->buffer, bufp, copy_size);
19236 	unit_test->buffer_len = copy_size;
19237 
19238 	return QDF_STATUS_SUCCESS;
19239 }
19240 
19241 /**
19242  * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event
19243  * @wmi_handle: wmi handle
19244  * @param evt_buf: pointer to event buffer
19245  * @param index: Index into extended pdev stats
19246  * @param pdev_ext_stats: Pointer to hold extended pdev stats
19247  *
19248  * Return: QDF_STATUS_SUCCESS for success or error code
19249  */
19250 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle,
19251 	void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats)
19252 {
19253 	return QDF_STATUS_SUCCESS;
19254 }
19255 
19256 /**
19257  * extract_vdev_stats_tlv() - extract vdev stats from event
19258  * @wmi_handle: wmi handle
19259  * @param evt_buf: pointer to event buffer
19260  * @param index: Index into vdev stats
19261  * @param vdev_stats: Pointer to hold vdev stats
19262  *
19263  * Return: QDF_STATUS_SUCCESS for success or error code
19264  */
19265 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle,
19266 	void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats)
19267 {
19268 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19269 	wmi_stats_event_fixed_param *ev_param;
19270 	uint8_t *data;
19271 
19272 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19273 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19274 	data = (uint8_t *) param_buf->data;
19275 
19276 	if (index < ev_param->num_vdev_stats) {
19277 		wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) +
19278 				((ev_param->num_pdev_stats) *
19279 				sizeof(wmi_pdev_stats)) +
19280 				(index * sizeof(wmi_vdev_stats)));
19281 
19282 		vdev_stats->vdev_id = ev->vdev_id;
19283 		vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr;
19284 		vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr;
19285 
19286 		OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt,
19287 			sizeof(ev->tx_frm_cnt));
19288 		vdev_stats->rx_frm_cnt = ev->rx_frm_cnt;
19289 		OS_MEMCPY(vdev_stats->multiple_retry_cnt,
19290 				ev->multiple_retry_cnt,
19291 				sizeof(ev->multiple_retry_cnt));
19292 		OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt,
19293 				sizeof(ev->fail_cnt));
19294 		vdev_stats->rts_fail_cnt = ev->rts_fail_cnt;
19295 		vdev_stats->rts_succ_cnt = ev->rts_succ_cnt;
19296 		vdev_stats->rx_err_cnt = ev->rx_err_cnt;
19297 		vdev_stats->rx_discard_cnt = ev->rx_discard_cnt;
19298 		vdev_stats->ack_fail_cnt = ev->ack_fail_cnt;
19299 		OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history,
19300 			sizeof(ev->tx_rate_history));
19301 		OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history,
19302 			sizeof(ev->bcn_rssi_history));
19303 
19304 	}
19305 
19306 	return QDF_STATUS_SUCCESS;
19307 }
19308 
19309 /**
19310  * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event
19311  * buffer
19312  * @wmi_handle: wmi handle
19313  * @evt_buf: pointer to event buffer
19314  * @index: Index into vdev stats
19315  * @rssi_stats: Pointer to hold rssi stats
19316  *
19317  * Return: QDF_STATUS_SUCCESS for success or error code
19318  */
19319 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle,
19320 			void *evt_buf, uint32_t index,
19321 			struct wmi_host_per_chain_rssi_stats *rssi_stats)
19322 {
19323 	uint8_t *data;
19324 	wmi_rssi_stats *fw_rssi_stats;
19325 	wmi_per_chain_rssi_stats *rssi_event;
19326 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19327 
19328 	if (!evt_buf) {
19329 		WMI_LOGE("evt_buf is null");
19330 		return QDF_STATUS_E_NULL_VALUE;
19331 	}
19332 
19333 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19334 	rssi_event = param_buf->chain_stats;
19335 
19336 	if (index >= rssi_event->num_per_chain_rssi_stats) {
19337 		WMI_LOGE("invalid index");
19338 		return QDF_STATUS_E_INVAL;
19339 	}
19340 
19341 	data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE;
19342 	fw_rssi_stats = &((wmi_rssi_stats *)data)[index];
19343 
19344 	rssi_stats->vdev_id = fw_rssi_stats->vdev_id;
19345 	qdf_mem_copy(rssi_stats->rssi_avg_beacon,
19346 		     fw_rssi_stats->rssi_avg_beacon,
19347 		     sizeof(fw_rssi_stats->rssi_avg_beacon));
19348 	qdf_mem_copy(rssi_stats->rssi_avg_data,
19349 		     fw_rssi_stats->rssi_avg_data,
19350 		     sizeof(fw_rssi_stats->rssi_avg_data));
19351 	qdf_mem_copy(&rssi_stats->peer_macaddr,
19352 		     &fw_rssi_stats->peer_macaddr,
19353 		     sizeof(fw_rssi_stats->peer_macaddr));
19354 
19355 	return QDF_STATUS_SUCCESS;
19356 }
19357 
19358 
19359 
19360 /**
19361  * extract_bcn_stats_tlv() - extract bcn stats from event
19362  * @wmi_handle: wmi handle
19363  * @param evt_buf: pointer to event buffer
19364  * @param index: Index into vdev stats
19365  * @param bcn_stats: Pointer to hold bcn stats
19366  *
19367  * Return: QDF_STATUS_SUCCESS for success or error code
19368  */
19369 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle,
19370 	void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats)
19371 {
19372 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19373 	wmi_stats_event_fixed_param *ev_param;
19374 	uint8_t *data;
19375 
19376 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19377 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19378 	data = (uint8_t *) param_buf->data;
19379 
19380 	if (index < ev_param->num_bcn_stats) {
19381 		wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) +
19382 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19383 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19384 			((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) +
19385 			((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) +
19386 			((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) +
19387 			(index * sizeof(wmi_bcn_stats)));
19388 
19389 		bcn_stats->vdev_id = ev->vdev_id;
19390 		bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt;
19391 		bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt;
19392 	}
19393 
19394 	return QDF_STATUS_SUCCESS;
19395 }
19396 
19397 /**
19398  * extract_peer_stats_tlv() - extract peer stats from event
19399  * @wmi_handle: wmi handle
19400  * @param evt_buf: pointer to event buffer
19401  * @param index: Index into peer stats
19402  * @param peer_stats: Pointer to hold peer stats
19403  *
19404  * Return: QDF_STATUS_SUCCESS for success or error code
19405  */
19406 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle,
19407 	void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats)
19408 {
19409 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19410 	wmi_stats_event_fixed_param *ev_param;
19411 	uint8_t *data;
19412 
19413 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19414 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19415 	data = (uint8_t *) param_buf->data;
19416 
19417 	if (index < ev_param->num_peer_stats) {
19418 		wmi_peer_stats *ev = (wmi_peer_stats *) ((data) +
19419 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19420 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19421 			(index * sizeof(wmi_peer_stats)));
19422 
19423 		OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats));
19424 
19425 		OS_MEMCPY(&(peer_stats->peer_macaddr),
19426 			&(ev->peer_macaddr), sizeof(wmi_mac_addr));
19427 
19428 		peer_stats->peer_rssi = ev->peer_rssi;
19429 		peer_stats->peer_tx_rate = ev->peer_tx_rate;
19430 		peer_stats->peer_rx_rate = ev->peer_rx_rate;
19431 	}
19432 
19433 	return QDF_STATUS_SUCCESS;
19434 }
19435 
19436 /**
19437  * extract_bcnflt_stats_tlv() - extract bcn fault stats from event
19438  * @wmi_handle: wmi handle
19439  * @param evt_buf: pointer to event buffer
19440  * @param index: Index into bcn fault stats
19441  * @param bcnflt_stats: Pointer to hold bcn fault stats
19442  *
19443  * Return: QDF_STATUS_SUCCESS for success or error code
19444  */
19445 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle,
19446 	void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats)
19447 {
19448 	return QDF_STATUS_SUCCESS;
19449 }
19450 
19451 /**
19452  * extract_peer_extd_stats_tlv() - extract extended peer stats from event
19453  * @wmi_handle: wmi handle
19454  * @param evt_buf: pointer to event buffer
19455  * @param index: Index into extended peer stats
19456  * @param peer_extd_stats: Pointer to hold extended peer stats
19457  *
19458  * Return: QDF_STATUS_SUCCESS for success or error code
19459  */
19460 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle,
19461 		void *evt_buf, uint32_t index,
19462 		wmi_host_peer_extd_stats *peer_extd_stats)
19463 {
19464 	return QDF_STATUS_SUCCESS;
19465 }
19466 
19467 /**
19468  * extract_chan_stats_tlv() - extract chan stats from event
19469  * @wmi_handle: wmi handle
19470  * @param evt_buf: pointer to event buffer
19471  * @param index: Index into chan stats
19472  * @param vdev_extd_stats: Pointer to hold chan stats
19473  *
19474  * Return: QDF_STATUS_SUCCESS for success or error code
19475  */
19476 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle,
19477 	void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats)
19478 {
19479 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19480 	wmi_stats_event_fixed_param *ev_param;
19481 	uint8_t *data;
19482 
19483 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19484 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19485 	data = (uint8_t *) param_buf->data;
19486 
19487 	if (index < ev_param->num_chan_stats) {
19488 		wmi_chan_stats *ev = (wmi_chan_stats *) ((data) +
19489 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19490 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19491 			((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) +
19492 			(index * sizeof(wmi_chan_stats)));
19493 
19494 
19495 		/* Non-TLV doesn't have num_chan_stats */
19496 		chan_stats->chan_mhz = ev->chan_mhz;
19497 		chan_stats->sampling_period_us = ev->sampling_period_us;
19498 		chan_stats->rx_clear_count = ev->rx_clear_count;
19499 		chan_stats->tx_duration_us = ev->tx_duration_us;
19500 		chan_stats->rx_duration_us = ev->rx_duration_us;
19501 	}
19502 
19503 	return QDF_STATUS_SUCCESS;
19504 }
19505 
19506 /**
19507  * extract_profile_ctx_tlv() - extract profile context from event
19508  * @wmi_handle: wmi handle
19509  * @param evt_buf: pointer to event buffer
19510  * @idx: profile stats index to extract
19511  * @param profile_ctx: Pointer to hold profile context
19512  *
19513  * Return: QDF_STATUS_SUCCESS for success or error code
19514  */
19515 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle,
19516 	void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx)
19517 {
19518 	return QDF_STATUS_SUCCESS;
19519 }
19520 
19521 /**
19522  * extract_profile_data_tlv() - extract profile data from event
19523  * @wmi_handle: wmi handle
19524  * @param evt_buf: pointer to event buffer
19525  * @param profile_data: Pointer to hold profile data
19526  *
19527  * Return: QDF_STATUS_SUCCESS for success or error code
19528  */
19529 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle,
19530 	void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data)
19531 {
19532 
19533 	return QDF_STATUS_SUCCESS;
19534 }
19535 
19536 /**
19537  * extract_chan_info_event_tlv() - extract chan information from event
19538  * @wmi_handle: wmi handle
19539  * @param evt_buf: pointer to event buffer
19540  * @param chan_info: Pointer to hold chan information
19541  *
19542  * Return: QDF_STATUS_SUCCESS for success or error code
19543  */
19544 static QDF_STATUS extract_chan_info_event_tlv(wmi_unified_t wmi_handle,
19545 	void *evt_buf, wmi_host_chan_info_event *chan_info)
19546 {
19547 	WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf;
19548 	wmi_chan_info_event_fixed_param *ev;
19549 
19550 	param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) evt_buf;
19551 
19552 	ev = (wmi_chan_info_event_fixed_param *) param_buf->fixed_param;
19553 	if (!ev) {
19554 		WMI_LOGE("%s: Failed to allocmemory\n", __func__);
19555 		return QDF_STATUS_E_FAILURE;
19556 	}
19557 
19558 	chan_info->err_code = ev->err_code;
19559 	chan_info->freq = ev->freq;
19560 	chan_info->cmd_flags = ev->cmd_flags;
19561 	chan_info->noise_floor = ev->noise_floor;
19562 	chan_info->rx_clear_count = ev->rx_clear_count;
19563 	chan_info->cycle_count = ev->cycle_count;
19564 	chan_info->tx_frame_cnt = ev->tx_frame_cnt;
19565 	chan_info->mac_clk_mhz = ev->mac_clk_mhz;
19566 	chan_info->pdev_id = wlan_get_pdev_id_from_vdev_id(
19567 			(struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc,
19568 			ev->vdev_id, WLAN_SCAN_ID);
19569 	chan_info->chan_tx_pwr_range = ev->chan_tx_pwr_range;
19570 	chan_info->chan_tx_pwr_tp = ev->chan_tx_pwr_tp;
19571 	chan_info->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count;
19572 	chan_info->rx_11b_mode_data_duration = ev->rx_11b_mode_data_duration;
19573 	chan_info->tx_frame_cnt = ev->tx_frame_cnt;
19574 	chan_info->rx_frame_count = ev->rx_frame_count;
19575 	chan_info->mac_clk_mhz = ev->mac_clk_mhz;
19576 	chan_info->vdev_id = ev->vdev_id;
19577 
19578 	return QDF_STATUS_SUCCESS;
19579 }
19580 
19581 /**
19582  * extract_pdev_utf_event_tlv() - extract UTF data info from event
19583  * @wmi_handle: WMI handle
19584  * @param evt_buf: Pointer to event buffer
19585  * @param param: Pointer to hold data
19586  *
19587  * Return : QDF_STATUS_SUCCESS for success or error code
19588  */
19589 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle,
19590 			     uint8_t *evt_buf,
19591 			     struct wmi_host_pdev_utf_event *event)
19592 {
19593 	WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf;
19594 	struct wmi_host_utf_seg_header_info *seg_hdr;
19595 
19596 	param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf;
19597 	event->data = param_buf->data;
19598 	event->datalen = param_buf->num_data;
19599 
19600 	if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) {
19601 		WMI_LOGE("%s: Invalid datalen: %d ", __func__, event->datalen);
19602 		return QDF_STATUS_E_INVAL;
19603 	}
19604 	seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data;
19605 	/* Set pdev_id=1 until FW adds support to include pdev_id */
19606 	event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19607 							seg_hdr->pdev_id);
19608 
19609 	return QDF_STATUS_SUCCESS;
19610 }
19611 
19612 /**
19613  * extract_chainmask_tables_tlv() - extract chain mask tables from event
19614  * @wmi_handle: wmi handle
19615  * @param evt_buf: pointer to event buffer
19616  * @param param: Pointer to hold evt buf
19617  *
19618  * Return: QDF_STATUS_SUCCESS for success or error code
19619  */
19620 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle,
19621 		uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table)
19622 {
19623 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19624 	WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps;
19625 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19626 	uint8_t i = 0, j = 0;
19627 
19628 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19629 	if (!param_buf)
19630 		return QDF_STATUS_E_INVAL;
19631 
19632 	hw_caps = param_buf->soc_hw_mode_caps;
19633 	if (!hw_caps)
19634 		return QDF_STATUS_E_INVAL;
19635 
19636 	if (!hw_caps->num_chainmask_tables)
19637 		return QDF_STATUS_E_INVAL;
19638 
19639 	chainmask_caps = param_buf->mac_phy_chainmask_caps;
19640 
19641 	if (chainmask_caps == NULL)
19642 		return QDF_STATUS_E_INVAL;
19643 
19644 	for (i = 0; i < hw_caps->num_chainmask_tables; i++) {
19645 
19646 		qdf_print("Dumping chain mask combo data for table : %d", i);
19647 		for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) {
19648 
19649 			chainmask_table[i].cap_list[j].chainmask =
19650 				chainmask_caps->chainmask;
19651 
19652 			chainmask_table[i].cap_list[j].supports_chan_width_20 =
19653 				WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags);
19654 
19655 			chainmask_table[i].cap_list[j].supports_chan_width_40 =
19656 				WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags);
19657 
19658 			chainmask_table[i].cap_list[j].supports_chan_width_80 =
19659 				WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags);
19660 
19661 			chainmask_table[i].cap_list[j].supports_chan_width_160 =
19662 				WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags);
19663 
19664 			chainmask_table[i].cap_list[j].supports_chan_width_80P80 =
19665 				WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags);
19666 
19667 			chainmask_table[i].cap_list[j].chain_mask_2G =
19668 				WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags);
19669 
19670 			chainmask_table[i].cap_list[j].chain_mask_5G =
19671 				WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags);
19672 
19673 			chainmask_table[i].cap_list[j].chain_mask_tx =
19674 				WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags);
19675 
19676 			chainmask_table[i].cap_list[j].chain_mask_rx =
19677 				WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags);
19678 
19679 			chainmask_table[i].cap_list[j].supports_aDFS =
19680 				WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags);
19681 
19682 			qdf_print("supported_flags: 0x%08x  chainmasks: 0x%08x",
19683 				  chainmask_caps->supported_flags,
19684 				  chainmask_caps->chainmask
19685 				 );
19686 			chainmask_caps++;
19687 		}
19688 	}
19689 
19690 	return QDF_STATUS_SUCCESS;
19691 }
19692 
19693 /**
19694  * extract_service_ready_ext_tlv() - extract basic extended service ready params
19695  * from event
19696  * @wmi_handle: wmi handle
19697  * @param evt_buf: pointer to event buffer
19698  * @param param: Pointer to hold evt buf
19699  *
19700  * Return: QDF_STATUS_SUCCESS for success or error code
19701  */
19702 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle,
19703 		uint8_t *event, struct wlan_psoc_host_service_ext_param *param)
19704 {
19705 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19706 	wmi_service_ready_ext_event_fixed_param *ev;
19707 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19708 	WMI_SOC_HAL_REG_CAPABILITIES *reg_caps;
19709 	WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo;
19710 	uint8_t i = 0;
19711 
19712 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19713 	if (!param_buf)
19714 		return QDF_STATUS_E_INVAL;
19715 
19716 	ev = param_buf->fixed_param;
19717 	if (!ev)
19718 		return QDF_STATUS_E_INVAL;
19719 
19720 	/* Move this to host based bitmap */
19721 	param->default_conc_scan_config_bits =
19722 				ev->default_conc_scan_config_bits;
19723 	param->default_fw_config_bits = ev->default_fw_config_bits;
19724 	param->he_cap_info = ev->he_cap_info;
19725 	param->mpdu_density = ev->mpdu_density;
19726 	param->max_bssid_rx_filters = ev->max_bssid_rx_filters;
19727 	param->fw_build_vers_ext = ev->fw_build_vers_ext;
19728 	param->num_dbr_ring_caps = param_buf->num_dma_ring_caps;
19729 	param->max_bssid_indicator = ev->max_bssid_indicator;
19730 	qdf_mem_copy(&param->ppet, &ev->ppet, sizeof(param->ppet));
19731 
19732 	hw_caps = param_buf->soc_hw_mode_caps;
19733 	if (hw_caps)
19734 		param->num_hw_modes = hw_caps->num_hw_modes;
19735 	else
19736 		param->num_hw_modes = 0;
19737 
19738 	reg_caps = param_buf->soc_hal_reg_caps;
19739 	if (reg_caps)
19740 		param->num_phy = reg_caps->num_phy;
19741 	else
19742 		param->num_phy = 0;
19743 
19744 	if (hw_caps) {
19745 		param->num_chainmask_tables = hw_caps->num_chainmask_tables;
19746 		qdf_print("Num chain mask tables: %d", hw_caps->num_chainmask_tables);
19747 	} else
19748 		param->num_chainmask_tables = 0;
19749 
19750 	chain_mask_combo = param_buf->mac_phy_chainmask_combo;
19751 
19752 	if (chain_mask_combo == NULL)
19753 		return QDF_STATUS_SUCCESS;
19754 
19755 	qdf_print("Dumping chain mask combo data");
19756 
19757 	for (i = 0; i < param->num_chainmask_tables; i++) {
19758 
19759 		qdf_print("table_id : %d Num valid chainmasks: %d",
19760 			  chain_mask_combo->chainmask_table_id,
19761 			  chain_mask_combo->num_valid_chainmask
19762 			 );
19763 
19764 		param->chainmask_table[i].table_id =
19765 			chain_mask_combo->chainmask_table_id;
19766 		param->chainmask_table[i].num_valid_chainmasks =
19767 			chain_mask_combo->num_valid_chainmask;
19768 		chain_mask_combo++;
19769 	}
19770 	qdf_print("chain mask combo end");
19771 
19772 	return QDF_STATUS_SUCCESS;
19773 }
19774 
19775 /**
19776  * extract_sar_cap_service_ready_ext_tlv() -
19777  *       extract SAR cap from service ready event
19778  * @wmi_handle: wmi handle
19779  * @event: pointer to event buffer
19780  * @ext_param: extended target info
19781  *
19782  * Return: QDF_STATUS_SUCCESS for success or error code
19783  */
19784 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv(
19785 			wmi_unified_t wmi_handle,
19786 			uint8_t *event,
19787 			struct wlan_psoc_host_service_ext_param *ext_param)
19788 {
19789 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19790 	WMI_SAR_CAPABILITIES *sar_caps;
19791 
19792 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event;
19793 
19794 	if (!param_buf)
19795 		return QDF_STATUS_E_INVAL;
19796 
19797 	sar_caps = param_buf->sar_caps;
19798 	if (sar_caps)
19799 		ext_param->sar_version = sar_caps->active_version;
19800 	else
19801 		ext_param->sar_version = 0;
19802 
19803 	return QDF_STATUS_SUCCESS;
19804 }
19805 
19806 /**
19807  * extract_hw_mode_cap_service_ready_ext_tlv() -
19808  *       extract HW mode cap from service ready event
19809  * @wmi_handle: wmi handle
19810  * @param evt_buf: pointer to event buffer
19811  * @param param: Pointer to hold evt buf
19812  * @param hw_mode_idx: hw mode idx should be less than num_mode
19813  *
19814  * Return: QDF_STATUS_SUCCESS for success or error code
19815  */
19816 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv(
19817 			wmi_unified_t wmi_handle,
19818 			uint8_t *event, uint8_t hw_mode_idx,
19819 			struct wlan_psoc_host_hw_mode_caps *param)
19820 {
19821 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19822 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19823 
19824 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19825 	if (!param_buf)
19826 		return QDF_STATUS_E_INVAL;
19827 
19828 	hw_caps = param_buf->soc_hw_mode_caps;
19829 	if (!hw_caps)
19830 		return QDF_STATUS_E_INVAL;
19831 
19832 	if (hw_mode_idx >= hw_caps->num_hw_modes)
19833 		return QDF_STATUS_E_INVAL;
19834 
19835 	param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id;
19836 	param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map;
19837 
19838 	param->hw_mode_config_type =
19839 		param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type;
19840 
19841 	return QDF_STATUS_SUCCESS;
19842 }
19843 
19844 /**
19845  * extract_mac_phy_cap_service_ready_ext_tlv() -
19846  *       extract MAC phy cap from service ready event
19847  * @wmi_handle: wmi handle
19848  * @param evt_buf: pointer to event buffer
19849  * @param param: Pointer to hold evt buf
19850  * @param hw_mode_idx: hw mode idx should be less than num_mode
19851  * @param phy_id: phy id within hw_mode
19852  *
19853  * Return: QDF_STATUS_SUCCESS for success or error code
19854  */
19855 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv(
19856 			wmi_unified_t wmi_handle,
19857 			uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id,
19858 			struct wlan_psoc_host_mac_phy_caps *param)
19859 {
19860 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19861 	WMI_MAC_PHY_CAPABILITIES *mac_phy_caps;
19862 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19863 	uint32_t phy_map;
19864 	uint8_t hw_idx, phy_idx = 0;
19865 
19866 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19867 	if (!param_buf)
19868 		return QDF_STATUS_E_INVAL;
19869 
19870 	hw_caps = param_buf->soc_hw_mode_caps;
19871 	if (!hw_caps)
19872 		return QDF_STATUS_E_INVAL;
19873 
19874 	for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) {
19875 		if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id)
19876 			break;
19877 
19878 		phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map;
19879 		while (phy_map) {
19880 			phy_map >>= 1;
19881 			phy_idx++;
19882 		}
19883 	}
19884 
19885 	if (hw_idx == hw_caps->num_hw_modes)
19886 		return QDF_STATUS_E_INVAL;
19887 
19888 	phy_idx += phy_id;
19889 	if (phy_idx >= param_buf->num_mac_phy_caps)
19890 		return QDF_STATUS_E_INVAL;
19891 
19892 	mac_phy_caps = &param_buf->mac_phy_caps[phy_idx];
19893 
19894 	param->hw_mode_id = mac_phy_caps->hw_mode_id;
19895 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19896 							mac_phy_caps->pdev_id);
19897 	param->phy_id = mac_phy_caps->phy_id;
19898 	param->supports_11b =
19899 			WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags);
19900 	param->supports_11g =
19901 			WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags);
19902 	param->supports_11a =
19903 			WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags);
19904 	param->supports_11n =
19905 			WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags);
19906 	param->supports_11ac =
19907 			WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags);
19908 	param->supports_11ax =
19909 			WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags);
19910 
19911 	param->supported_bands = mac_phy_caps->supported_bands;
19912 	param->ampdu_density = mac_phy_caps->ampdu_density;
19913 	param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G;
19914 	param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G;
19915 	param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G;
19916 	param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G;
19917 	param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] =
19918 		mac_phy_caps->he_cap_info_2G;
19919 	param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] =
19920 		mac_phy_caps->he_cap_info_2G_ext;
19921 	param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G;
19922 	param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G;
19923 	param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G;
19924 	param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G;
19925 	param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G;
19926 	param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G;
19927 	param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G;
19928 	param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] =
19929 		mac_phy_caps->he_cap_info_5G;
19930 	param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] =
19931 		mac_phy_caps->he_cap_info_5G_ext;
19932 	param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G;
19933 	param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G;
19934 	param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G;
19935 	qdf_mem_copy(&param->he_cap_phy_info_2G,
19936 			&mac_phy_caps->he_cap_phy_info_2G,
19937 			sizeof(param->he_cap_phy_info_2G));
19938 	qdf_mem_copy(&param->he_cap_phy_info_5G,
19939 			&mac_phy_caps->he_cap_phy_info_5G,
19940 			sizeof(param->he_cap_phy_info_5G));
19941 	qdf_mem_copy(&param->he_ppet2G, &mac_phy_caps->he_ppet2G,
19942 				 sizeof(param->he_ppet2G));
19943 	qdf_mem_copy(&param->he_ppet5G, &mac_phy_caps->he_ppet5G,
19944 				sizeof(param->he_ppet5G));
19945 	param->chainmask_table_id = mac_phy_caps->chainmask_table_id;
19946 
19947 	return QDF_STATUS_SUCCESS;
19948 }
19949 
19950 /**
19951  * extract_reg_cap_service_ready_ext_tlv() -
19952  *       extract REG cap from service ready event
19953  * @wmi_handle: wmi handle
19954  * @param evt_buf: pointer to event buffer
19955  * @param param: Pointer to hold evt buf
19956  * @param phy_idx: phy idx should be less than num_mode
19957  *
19958  * Return: QDF_STATUS_SUCCESS for success or error code
19959  */
19960 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv(
19961 			wmi_unified_t wmi_handle,
19962 			uint8_t *event, uint8_t phy_idx,
19963 			struct wlan_psoc_host_hal_reg_capabilities_ext *param)
19964 {
19965 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19966 	WMI_SOC_HAL_REG_CAPABILITIES *reg_caps;
19967 	WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap;
19968 
19969 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19970 	if (!param_buf)
19971 		return QDF_STATUS_E_INVAL;
19972 
19973 	reg_caps = param_buf->soc_hal_reg_caps;
19974 	if (!reg_caps)
19975 		return QDF_STATUS_E_INVAL;
19976 
19977 	if (phy_idx >= reg_caps->num_phy)
19978 		return QDF_STATUS_E_INVAL;
19979 
19980 	ext_reg_cap = &param_buf->hal_reg_caps[phy_idx];
19981 
19982 	param->phy_id = ext_reg_cap->phy_id;
19983 	param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain;
19984 	param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext;
19985 	param->regcap1 = ext_reg_cap->regcap1;
19986 	param->regcap2 = ext_reg_cap->regcap2;
19987 	param->wireless_modes = convert_wireless_modes_tlv(
19988 						ext_reg_cap->wireless_modes);
19989 	param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan;
19990 	param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan;
19991 	param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan;
19992 	param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan;
19993 
19994 	return QDF_STATUS_SUCCESS;
19995 }
19996 
19997 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv(
19998 			wmi_unified_t wmi_handle,
19999 			uint8_t *event, uint8_t idx,
20000 			struct wlan_psoc_host_dbr_ring_caps *param)
20001 {
20002 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
20003 	WMI_DMA_RING_CAPABILITIES *dbr_ring_caps;
20004 
20005 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event;
20006 	if (!param_buf)
20007 		return QDF_STATUS_E_INVAL;
20008 
20009 	dbr_ring_caps = &param_buf->dma_ring_caps[idx];
20010 
20011 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20012 				dbr_ring_caps->pdev_id);
20013 	param->mod_id = dbr_ring_caps->mod_id;
20014 	param->ring_elems_min = dbr_ring_caps->ring_elems_min;
20015 	param->min_buf_size = dbr_ring_caps->min_buf_size;
20016 	param->min_buf_align = dbr_ring_caps->min_buf_align;
20017 
20018 	return QDF_STATUS_SUCCESS;
20019 }
20020 
20021 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle,
20022 		uint8_t *event, struct direct_buf_rx_rsp *param)
20023 {
20024 	WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
20025 	wmi_dma_buf_release_fixed_param *ev;
20026 
20027 	param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
20028 	if (!param_buf)
20029 		return QDF_STATUS_E_INVAL;
20030 
20031 	ev = param_buf->fixed_param;
20032 	if (!ev)
20033 		return QDF_STATUS_E_INVAL;
20034 
20035 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20036 								ev->pdev_id);
20037 	param->mod_id = ev->mod_id;
20038 	param->num_buf_release_entry = ev->num_buf_release_entry;
20039 	param->num_meta_data_entry = ev->num_meta_data_entry;
20040 	WMI_LOGD("%s:pdev id %d mod id %d num buf release entry %d\n", __func__,
20041 		 param->pdev_id, param->mod_id, param->num_buf_release_entry);
20042 
20043 	return QDF_STATUS_SUCCESS;
20044 }
20045 
20046 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle,
20047 		uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param)
20048 {
20049 	WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
20050 	wmi_dma_buf_release_entry *entry;
20051 
20052 	param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
20053 	if (!param_buf)
20054 		return QDF_STATUS_E_INVAL;
20055 
20056 	entry = &param_buf->entries[idx];
20057 
20058 	if (!entry) {
20059 		WMI_LOGE("%s: Entry is NULL\n", __func__);
20060 		return QDF_STATUS_E_FAILURE;
20061 	}
20062 
20063 	WMI_LOGD("%s: paddr_lo[%d] = %x\n", __func__, idx, entry->paddr_lo);
20064 
20065 	param->paddr_lo = entry->paddr_lo;
20066 	param->paddr_hi = entry->paddr_hi;
20067 
20068 	return QDF_STATUS_SUCCESS;
20069 }
20070 
20071 static QDF_STATUS extract_dbr_buf_metadata_tlv(
20072 		wmi_unified_t wmi_handle, uint8_t *event,
20073 		uint8_t idx, struct direct_buf_rx_metadata *param)
20074 {
20075 	WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
20076 	wmi_dma_buf_release_spectral_meta_data *entry;
20077 
20078 	param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
20079 	if (!param_buf)
20080 		return QDF_STATUS_E_INVAL;
20081 
20082 	entry = &param_buf->meta_data[idx];
20083 
20084 	if (!entry) {
20085 		WMI_LOGE("%s: Entry is NULL\n", __func__);
20086 		return QDF_STATUS_E_FAILURE;
20087 	}
20088 
20089 	qdf_mem_copy(param->noisefloor, entry->noise_floor,
20090 		     sizeof(entry->noise_floor));
20091 	return QDF_STATUS_SUCCESS;
20092 }
20093 
20094 /**
20095  * extract_dcs_interference_type_tlv() - extract dcs interference type
20096  * from event
20097  * @wmi_handle: wmi handle
20098  * @param evt_buf: pointer to event buffer
20099  * @param param: Pointer to hold dcs interference param
20100  *
20101  * Return: 0 for success or error code
20102  */
20103 static QDF_STATUS extract_dcs_interference_type_tlv(
20104 		wmi_unified_t wmi_handle,
20105 		void *evt_buf, struct wmi_host_dcs_interference_param *param)
20106 {
20107 	WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf;
20108 
20109 	param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf;
20110 	if (!param_buf)
20111 		return QDF_STATUS_E_INVAL;
20112 
20113 	param->interference_type = param_buf->fixed_param->interference_type;
20114 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20115 					param_buf->fixed_param->pdev_id);
20116 
20117 	return QDF_STATUS_SUCCESS;
20118 }
20119 
20120 /*
20121  * extract_dcs_cw_int_tlv() - extract dcs cw interference from event
20122  * @wmi_handle: wmi handle
20123  * @param evt_buf: pointer to event buffer
20124  * @param cw_int: Pointer to hold cw interference
20125  *
20126  * Return: 0 for success or error code
20127  */
20128 static QDF_STATUS extract_dcs_cw_int_tlv(wmi_unified_t wmi_handle,
20129 		void *evt_buf,
20130 		wmi_host_ath_dcs_cw_int *cw_int)
20131 {
20132 	WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf;
20133 	wlan_dcs_cw_int *ev;
20134 
20135 	param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf;
20136 	if (!param_buf)
20137 		return QDF_STATUS_E_INVAL;
20138 
20139 	ev = param_buf->cw_int;
20140 
20141 	cw_int->channel = ev->channel;
20142 
20143 	return QDF_STATUS_SUCCESS;
20144 }
20145 
20146 /**
20147  * extract_dcs_im_tgt_stats_tlv() - extract dcs im target stats from event
20148  * @wmi_handle: wmi handle
20149  * @param evt_buf: pointer to event buffer
20150  * @param wlan_stat: Pointer to hold wlan stats
20151  *
20152  * Return: 0 for success or error code
20153  */
20154 static QDF_STATUS extract_dcs_im_tgt_stats_tlv(wmi_unified_t wmi_handle,
20155 		void *evt_buf,
20156 		wmi_host_dcs_im_tgt_stats_t *wlan_stat)
20157 {
20158 	WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf;
20159 	wlan_dcs_im_tgt_stats_t *ev;
20160 
20161 	param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf;
20162 	if (!param_buf)
20163 		return QDF_STATUS_E_INVAL;
20164 
20165 	ev = param_buf->wlan_stat;
20166 	wlan_stat->reg_tsf32 = ev->reg_tsf32;
20167 	wlan_stat->last_ack_rssi = ev->last_ack_rssi;
20168 	wlan_stat->tx_waste_time = ev->tx_waste_time;
20169 	wlan_stat->rx_time = ev->rx_time;
20170 	wlan_stat->phyerr_cnt = ev->phyerr_cnt;
20171 	wlan_stat->mib_stats.listen_time = ev->listen_time;
20172 	wlan_stat->mib_stats.reg_tx_frame_cnt = ev->reg_tx_frame_cnt;
20173 	wlan_stat->mib_stats.reg_rx_frame_cnt = ev->reg_rx_frame_cnt;
20174 	wlan_stat->mib_stats.reg_rxclr_cnt = ev->reg_rxclr_cnt;
20175 	wlan_stat->mib_stats.reg_cycle_cnt = ev->reg_cycle_cnt;
20176 	wlan_stat->mib_stats.reg_rxclr_ext_cnt = ev->reg_rxclr_ext_cnt;
20177 	wlan_stat->mib_stats.reg_ofdm_phyerr_cnt = ev->reg_ofdm_phyerr_cnt;
20178 	wlan_stat->mib_stats.reg_cck_phyerr_cnt = ev->reg_cck_phyerr_cnt;
20179 	wlan_stat->chan_nf = ev->chan_nf;
20180 	wlan_stat->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count;
20181 
20182 	return QDF_STATUS_SUCCESS;
20183 }
20184 
20185 /**
20186  * extract_thermal_stats_tlv() - extract thermal stats from event
20187  * @wmi_handle: wmi handle
20188  * @param evt_buf: Pointer to event buffer
20189  * @param temp: Pointer to hold extracted temperature
20190  * @param level: Pointer to hold extracted level
20191  *
20192  * Return: 0 for success or error code
20193  */
20194 static QDF_STATUS
20195 extract_thermal_stats_tlv(wmi_unified_t wmi_handle,
20196 		void *evt_buf, uint32_t *temp,
20197 		uint32_t *level, uint32_t *pdev_id)
20198 {
20199 	WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf;
20200 	wmi_therm_throt_stats_event_fixed_param *tt_stats_event;
20201 
20202 	param_buf =
20203 		(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf;
20204 	if (!param_buf)
20205 		return QDF_STATUS_E_INVAL;
20206 
20207 	tt_stats_event = param_buf->fixed_param;
20208 
20209 	*pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20210 						tt_stats_event->pdev_id);
20211 	*temp = tt_stats_event->temp;
20212 	*level = tt_stats_event->level;
20213 
20214 	return QDF_STATUS_SUCCESS;
20215 }
20216 
20217 /**
20218  * extract_thermal_level_stats_tlv() - extract thermal level stats from event
20219  * @wmi_handle: wmi handle
20220  * @param evt_buf: pointer to event buffer
20221  * @param idx: Index to level stats
20222  * @param levelcount: Pointer to hold levelcount
20223  * @param dccount: Pointer to hold dccount
20224  *
20225  * Return: 0 for success or error code
20226  */
20227 static QDF_STATUS
20228 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle,
20229 		void *evt_buf, uint8_t idx, uint32_t *levelcount,
20230 		uint32_t *dccount)
20231 {
20232 	WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf;
20233 	wmi_therm_throt_level_stats_info *tt_level_info;
20234 
20235 	param_buf =
20236 		(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf;
20237 	if (!param_buf)
20238 		return QDF_STATUS_E_INVAL;
20239 
20240 	tt_level_info = param_buf->therm_throt_level_stats_info;
20241 
20242 	if (idx < THERMAL_LEVELS) {
20243 		*levelcount = tt_level_info[idx].level_count;
20244 		*dccount = tt_level_info[idx].dc_count;
20245 		return QDF_STATUS_SUCCESS;
20246 	}
20247 
20248 	return QDF_STATUS_E_FAILURE;
20249 }
20250 #ifdef BIG_ENDIAN_HOST
20251 /**
20252  * fips_conv_data_be() - LE to BE conversion of FIPS ev data
20253  * @param data_len - data length
20254  * @param data - pointer to data
20255  *
20256  * Return: QDF_STATUS - success or error status
20257  */
20258 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data)
20259 {
20260 	uint8_t *data_aligned = NULL;
20261 	int c;
20262 	unsigned char *data_unaligned;
20263 
20264 	data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) +
20265 					FIPS_ALIGN));
20266 	/* Assigning unaligned space to copy the data */
20267 	/* Checking if kmalloc does successful allocation */
20268 	if (data_unaligned == NULL)
20269 		return QDF_STATUS_E_FAILURE;
20270 
20271 	/* Checking if space is alligned */
20272 	if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) {
20273 		/* align the data space */
20274 		data_aligned =
20275 			(uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN);
20276 	} else {
20277 		data_aligned = (u_int8_t *)data_unaligned;
20278 	}
20279 
20280 	/* memset and copy content from data to data aligned */
20281 	OS_MEMSET(data_aligned, 0, data_len);
20282 	OS_MEMCPY(data_aligned, data, data_len);
20283 	/* Endianness to LE */
20284 	for (c = 0; c < data_len/4; c++) {
20285 		*((u_int32_t *)data_aligned + c) =
20286 			qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c));
20287 	}
20288 
20289 	/* Copy content to event->data */
20290 	OS_MEMCPY(data, data_aligned, data_len);
20291 
20292 	/* clean up allocated space */
20293 	qdf_mem_free(data_unaligned);
20294 	data_aligned = NULL;
20295 	data_unaligned = NULL;
20296 
20297 	/*************************************************************/
20298 
20299 	return QDF_STATUS_SUCCESS;
20300 }
20301 #else
20302 /**
20303  * fips_conv_data_be() - DUMMY for LE platform
20304  *
20305  * Return: QDF_STATUS - success
20306  */
20307 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data)
20308 {
20309 	return QDF_STATUS_SUCCESS;
20310 }
20311 #endif
20312 
20313 /**
20314  * extract_fips_event_data_tlv() - extract fips event data
20315  * @wmi_handle: wmi handle
20316  * @param evt_buf: pointer to event buffer
20317  * @param param: pointer FIPS event params
20318  *
20319  * Return: 0 for success or error code
20320  */
20321 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle,
20322 		void *evt_buf, struct wmi_host_fips_event_param *param)
20323 {
20324 	WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf;
20325 	wmi_pdev_fips_event_fixed_param *event;
20326 
20327 	param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf;
20328 	event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param;
20329 
20330 	if (fips_conv_data_be(event->data_len, param_buf->data) !=
20331 							QDF_STATUS_SUCCESS)
20332 		return QDF_STATUS_E_FAILURE;
20333 
20334 	param->data = (uint32_t *)param_buf->data;
20335 	param->data_len = event->data_len;
20336 	param->error_status = event->error_status;
20337 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20338 								event->pdev_id);
20339 
20340 	return QDF_STATUS_SUCCESS;
20341 }
20342 
20343 /*
20344  * extract_peer_delete_response_event_tlv() - extract peer delete response event
20345  * @wmi_handle: wmi handle
20346  * @param evt_buf: pointer to event buffer
20347  * @param vdev_id: Pointer to hold vdev_id
20348  * @param mac_addr: Pointer to hold peer mac address
20349  *
20350  * Return: QDF_STATUS_SUCCESS for success or error code
20351  */
20352 static QDF_STATUS extract_peer_delete_response_event_tlv(wmi_unified_t wmi_hdl,
20353 	void *evt_buf, struct wmi_host_peer_delete_response_event *param)
20354 {
20355 	WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf;
20356 	wmi_peer_delete_resp_event_fixed_param *ev;
20357 
20358 	param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)evt_buf;
20359 
20360 	ev = (wmi_peer_delete_resp_event_fixed_param *) param_buf->fixed_param;
20361 	if (!ev) {
20362 		WMI_LOGE("%s: Invalid peer_delete response\n", __func__);
20363 		return QDF_STATUS_E_FAILURE;
20364 	}
20365 
20366 	param->vdev_id = ev->vdev_id;
20367 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr,
20368 			&param->mac_address.bytes[0]);
20369 
20370 	return QDF_STATUS_SUCCESS;
20371 }
20372 
20373 static bool is_management_record_tlv(uint32_t cmd_id)
20374 {
20375 	switch (cmd_id) {
20376 	case WMI_MGMT_TX_SEND_CMDID:
20377 	case WMI_MGMT_TX_COMPLETION_EVENTID:
20378 	case WMI_OFFCHAN_DATA_TX_SEND_CMDID:
20379 	case WMI_MGMT_RX_EVENTID:
20380 		return true;
20381 	default:
20382 		return false;
20383 	}
20384 }
20385 
20386 static bool is_diag_event_tlv(uint32_t event_id)
20387 {
20388 	if (WMI_DIAG_EVENTID == event_id)
20389 		return true;
20390 
20391 	return false;
20392 }
20393 
20394 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf)
20395 {
20396 	wmi_vdev_set_param_cmd_fixed_param *set_cmd;
20397 
20398 	set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf);
20399 
20400 	switch (set_cmd->param_id) {
20401 	case WMI_VDEV_PARAM_LISTEN_INTERVAL:
20402 	case WMI_VDEV_PARAM_DTIM_POLICY:
20403 		return HTC_TX_PACKET_TAG_AUTO_PM;
20404 	default:
20405 		break;
20406 	}
20407 
20408 	return 0;
20409 }
20410 
20411 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf)
20412 {
20413 	wmi_sta_powersave_param_cmd_fixed_param *ps_cmd;
20414 
20415 	ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf);
20416 
20417 	switch (ps_cmd->param) {
20418 	case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD:
20419 	case WMI_STA_PS_PARAM_INACTIVITY_TIME:
20420 	case WMI_STA_PS_ENABLE_QPOWER:
20421 		return HTC_TX_PACKET_TAG_AUTO_PM;
20422 	default:
20423 		break;
20424 	}
20425 
20426 	return 0;
20427 }
20428 
20429 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf,
20430 				   uint32_t cmd_id)
20431 {
20432 	if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended))
20433 		return 0;
20434 
20435 	switch (cmd_id) {
20436 	case WMI_VDEV_SET_PARAM_CMDID:
20437 		return wmi_tag_vdev_set_cmd(wmi_hdl, buf);
20438 	case WMI_STA_POWERSAVE_PARAM_CMDID:
20439 		return wmi_tag_sta_powersave_cmd(wmi_hdl, buf);
20440 	default:
20441 		break;
20442 	}
20443 
20444 	return 0;
20445 }
20446 
20447 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle)
20448 {
20449 	uint16_t tag = 0;
20450 
20451 	if (qdf_atomic_read(&wmi_handle->is_target_suspended)) {
20452 		pr_err("%s: Target is already suspended, Ignore FW Hang Command\n",
20453 			__func__);
20454 		return tag;
20455 	}
20456 
20457 	if (wmi_handle->tag_crash_inject)
20458 		tag = HTC_TX_PACKET_TAG_AUTO_PM;
20459 
20460 	wmi_handle->tag_crash_inject = false;
20461 	return tag;
20462 }
20463 
20464 /**
20465  * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands
20466  * @wmi_handle: WMI handle
20467  * @buf:	WMI buffer
20468  * @cmd_id:	WMI command Id
20469  *
20470  * Return htc_tx_tag
20471  */
20472 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle,
20473 				wmi_buf_t buf,
20474 				uint32_t cmd_id)
20475 {
20476 	uint16_t htc_tx_tag = 0;
20477 
20478 	switch (cmd_id) {
20479 	case WMI_WOW_ENABLE_CMDID:
20480 	case WMI_PDEV_SUSPEND_CMDID:
20481 	case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID:
20482 	case WMI_WOW_ADD_WAKE_PATTERN_CMDID:
20483 	case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID:
20484 	case WMI_PDEV_RESUME_CMDID:
20485 	case WMI_WOW_DEL_WAKE_PATTERN_CMDID:
20486 	case WMI_WOW_SET_ACTION_WAKE_UP_CMDID:
20487 #ifdef FEATURE_WLAN_D0WOW
20488 	case WMI_D0_WOW_ENABLE_DISABLE_CMDID:
20489 #endif
20490 		htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM;
20491 		break;
20492 	case WMI_FORCE_FW_HANG_CMDID:
20493 		htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle);
20494 		break;
20495 	case WMI_VDEV_SET_PARAM_CMDID:
20496 	case WMI_STA_POWERSAVE_PARAM_CMDID:
20497 		htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id);
20498 	default:
20499 		break;
20500 	}
20501 
20502 	return htc_tx_tag;
20503 }
20504 
20505 /**
20506  * extract_channel_hopping_event_tlv() - extract channel hopping param
20507  * from event
20508  * @wmi_handle: wmi handle
20509  * @param evt_buf: pointer to event buffer
20510  * @param ch_hopping: Pointer to hold channel hopping param
20511  *
20512  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20513  */
20514 static QDF_STATUS extract_channel_hopping_event_tlv(
20515 	wmi_unified_t wmi_handle, void *evt_buf,
20516 	wmi_host_pdev_channel_hopping_event *ch_hopping)
20517 {
20518 	WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *param_buf;
20519 	wmi_pdev_channel_hopping_event_fixed_param *event;
20520 
20521 	param_buf = (WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *)evt_buf;
20522 	event = (wmi_pdev_channel_hopping_event_fixed_param *)
20523 						param_buf->fixed_param;
20524 
20525 	ch_hopping->noise_floor_report_iter = event->noise_floor_report_iter;
20526 	ch_hopping->noise_floor_total_iter = event->noise_floor_total_iter;
20527 	ch_hopping->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20528 								event->pdev_id);
20529 
20530 	return QDF_STATUS_SUCCESS;
20531 }
20532 
20533 /**
20534  * extract_pdev_tpc_ev_param_tlv() - extract tpc param from event
20535  * @wmi_handle: wmi handle
20536  * @param evt_buf: pointer to event buffer
20537  * @param param: Pointer to hold tpc param
20538  *
20539  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20540  */
20541 static QDF_STATUS extract_pdev_tpc_ev_param_tlv(wmi_unified_t wmi_handle,
20542 		void *evt_buf,
20543 		wmi_host_pdev_tpc_event *param)
20544 {
20545 	WMI_PDEV_TPC_EVENTID_param_tlvs *param_buf;
20546 	wmi_pdev_tpc_event_fixed_param *event;
20547 
20548 	param_buf = (WMI_PDEV_TPC_EVENTID_param_tlvs *)evt_buf;
20549 	event = (wmi_pdev_tpc_event_fixed_param *)param_buf->fixed_param;
20550 
20551 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20552 								event->pdev_id);
20553 	qdf_mem_copy(param->tpc, param_buf->tpc, sizeof(param->tpc));
20554 
20555 	return QDF_STATUS_SUCCESS;
20556 }
20557 
20558 /**
20559  * extract_nfcal_power_ev_param_tlv() - extract noise floor calibration
20560  * power param from event
20561  * @wmi_handle: wmi handle
20562  * @param evt_buf: pointer to event buffer
20563  * @param param: Pointer to hold nf cal power param
20564  *
20565  * Return: 0 for success or error code
20566  */
20567 static QDF_STATUS
20568 extract_nfcal_power_ev_param_tlv(wmi_unified_t wmi_handle,
20569 				 void *evt_buf,
20570 				 wmi_host_pdev_nfcal_power_all_channels_event *param)
20571 {
20572 	WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *param_buf;
20573 	wmi_pdev_nfcal_power_all_channels_event_fixed_param *event;
20574 	wmi_pdev_nfcal_power_all_channels_nfdBr *ch_nfdbr;
20575 	wmi_pdev_nfcal_power_all_channels_nfdBm *ch_nfdbm;
20576 	wmi_pdev_nfcal_power_all_channels_freqNum *ch_freqnum;
20577 	uint32_t i;
20578 
20579 	param_buf =
20580 		(WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *)evt_buf;
20581 	event = param_buf->fixed_param;
20582 	ch_nfdbr = param_buf->nfdbr;
20583 	ch_nfdbm = param_buf->nfdbm;
20584 	ch_freqnum = param_buf->freqnum;
20585 
20586 	WMI_LOGD("pdev_id[%x], num_nfdbr[%d], num_nfdbm[%d] num_freqnum[%d]\n",
20587 		 event->pdev_id, param_buf->num_nfdbr,
20588 		 param_buf->num_nfdbm, param_buf->num_freqnum);
20589 
20590 	if (param_buf->num_nfdbr >
20591 	    WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) {
20592 		WMI_LOGE("invalid number of nfdBr");
20593 		return QDF_STATUS_E_FAILURE;
20594 	}
20595 
20596 	if (param_buf->num_nfdbm >
20597 	    WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) {
20598 		WMI_LOGE("invalid number of nfdBm");
20599 		return QDF_STATUS_E_FAILURE;
20600 	}
20601 
20602 	if (param_buf->num_freqnum > WMI_HOST_RXG_CAL_CHAN_MAX) {
20603 		WMI_LOGE("invalid number of freqNum");
20604 		return QDF_STATUS_E_FAILURE;
20605 	}
20606 
20607 	for (i = 0; i < param_buf->num_nfdbr; i++) {
20608 		param->nfdbr[i] = (int8_t)ch_nfdbr->nfdBr;
20609 		param->nfdbm[i] = (int8_t)ch_nfdbm->nfdBm;
20610 		ch_nfdbr++;
20611 		ch_nfdbm++;
20612 	}
20613 
20614 	for (i = 0; i < param_buf->num_freqnum; i++) {
20615 		param->freqnum[i] = ch_freqnum->freqNum;
20616 		ch_freqnum++;
20617 	}
20618 
20619 	param->pdev_id = wmi_handle->ops->
20620 		convert_pdev_id_target_to_host(event->pdev_id);
20621 
20622 	return QDF_STATUS_SUCCESS;
20623 }
20624 
20625 
20626 #ifdef BIG_ENDIAN_HOST
20627 /**
20628  * wds_addr_ev_conv_data_be() - LE to BE conversion of wds addr event
20629  * @param data_len - data length
20630  * @param data - pointer to data
20631  *
20632  * Return: QDF_STATUS - success or error status
20633  */
20634 static QDF_STATUS wds_addr_ev_conv_data_be(uint16_t data_len, uint8_t *ev)
20635 {
20636 	uint8_t *datap = (uint8_t *)ev;
20637 	int i;
20638 	/* Skip swapping the first word */
20639 	datap += sizeof(uint32_t);
20640 	for (i = 0; i < ((data_len / sizeof(uint32_t))-1);
20641 			i++, datap += sizeof(uint32_t)) {
20642 		*(uint32_t *)datap = qdf_le32_to_cpu(*(uint32_t *)datap);
20643 	}
20644 
20645 	return QDF_STATUS_SUCCESS;
20646 }
20647 #else
20648 /**
20649  * wds_addr_ev_conv_data_be() - Dummy operation for LE platforms
20650  * @param data_len - data length
20651  * @param data - pointer to data
20652  *
20653  * Return: QDF_STATUS - success or error status
20654  */
20655 static QDF_STATUS wds_addr_ev_conv_data_be(uint32_t data_len, uint8_t *ev)
20656 {
20657 	return QDF_STATUS_SUCCESS;
20658 }
20659 #endif
20660 
20661 /**
20662  * extract_wds_addr_event_tlv() - extract wds address from event
20663  * @wmi_handle: wmi handle
20664  * @param evt_buf: pointer to event buffer
20665  * @param wds_ev: Pointer to hold wds address
20666  *
20667  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20668  */
20669 static QDF_STATUS extract_wds_addr_event_tlv(wmi_unified_t wmi_handle,
20670 		void *evt_buf,
20671 		uint16_t len, wds_addr_event_t *wds_ev)
20672 {
20673 	WMI_WDS_PEER_EVENTID_param_tlvs *param_buf;
20674 	wmi_wds_addr_event_fixed_param *ev;
20675 	int i;
20676 
20677 	param_buf = (WMI_WDS_PEER_EVENTID_param_tlvs *)evt_buf;
20678 	ev = (wmi_wds_addr_event_fixed_param *)param_buf->fixed_param;
20679 
20680 	if (wds_addr_ev_conv_data_be(len, (uint8_t *)ev) != QDF_STATUS_SUCCESS)
20681 		return QDF_STATUS_E_FAILURE;
20682 
20683 	qdf_mem_copy(wds_ev->event_type, ev->event_type,
20684 		     sizeof(wds_ev->event_type));
20685 	for (i = 0; i < 4; i++) {
20686 		wds_ev->peer_mac[i] =
20687 			((u_int8_t *)&(ev->peer_mac.mac_addr31to0))[i];
20688 		wds_ev->dest_mac[i] =
20689 			((u_int8_t *)&(ev->dest_mac.mac_addr31to0))[i];
20690 	}
20691 	for (i = 0; i < 2; i++) {
20692 		wds_ev->peer_mac[4+i] =
20693 			((u_int8_t *)&(ev->peer_mac.mac_addr47to32))[i];
20694 		wds_ev->dest_mac[4+i] =
20695 			((u_int8_t *)&(ev->dest_mac.mac_addr47to32))[i];
20696 	}
20697 	wds_ev->vdev_id = ev->vdev_id;
20698 
20699 	return QDF_STATUS_SUCCESS;
20700 }
20701 
20702 /**
20703  * extract_peer_sta_ps_statechange_ev_tlv() - extract peer sta ps state
20704  * from event
20705  * @wmi_handle: wmi handle
20706  * @param evt_buf: pointer to event buffer
20707  * @param ev: Pointer to hold peer param and ps state
20708  *
20709  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20710  */
20711 static QDF_STATUS extract_peer_sta_ps_statechange_ev_tlv(wmi_unified_t wmi_handle,
20712 		void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev)
20713 {
20714 	WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf;
20715 	wmi_peer_sta_ps_statechange_event_fixed_param *event;
20716 
20717 	param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)evt_buf;
20718 	event = (wmi_peer_sta_ps_statechange_event_fixed_param *)
20719 						param_buf->fixed_param;
20720 
20721 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, ev->peer_macaddr);
20722 	ev->peer_ps_state = event->peer_ps_state;
20723 
20724 	return QDF_STATUS_SUCCESS;
20725 }
20726 
20727 /**
20728  * extract_inst_rssi_stats_event_tlv() - extract inst rssi stats from event
20729  * @wmi_handle: wmi handle
20730  * @param evt_buf: pointer to event buffer
20731  * @param inst_rssi_resp: Pointer to hold inst rssi response
20732  *
20733  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20734  */
20735 static QDF_STATUS extract_inst_rssi_stats_event_tlv(
20736 	wmi_unified_t wmi_handle, void *evt_buf,
20737 	wmi_host_inst_stats_resp *inst_rssi_resp)
20738 {
20739 	WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf;
20740 	wmi_inst_rssi_stats_resp_fixed_param *event;
20741 
20742 	param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf;
20743 	event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param;
20744 
20745 	qdf_mem_copy(&(inst_rssi_resp->peer_macaddr),
20746 		     &(event->peer_macaddr), sizeof(wmi_mac_addr));
20747 	inst_rssi_resp->iRSSI = event->iRSSI;
20748 
20749 	return QDF_STATUS_SUCCESS;
20750 }
20751 
20752 static struct cur_reg_rule
20753 *create_reg_rules_from_wmi(uint32_t num_reg_rules,
20754 		wmi_regulatory_rule_struct *wmi_reg_rule)
20755 {
20756 	struct cur_reg_rule *reg_rule_ptr;
20757 	uint32_t count;
20758 
20759 	reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr));
20760 
20761 	if (NULL == reg_rule_ptr) {
20762 		WMI_LOGE("memory allocation failure");
20763 		return NULL;
20764 	}
20765 
20766 	for (count = 0; count < num_reg_rules; count++) {
20767 		reg_rule_ptr[count].start_freq =
20768 			WMI_REG_RULE_START_FREQ_GET(
20769 					wmi_reg_rule[count].freq_info);
20770 		reg_rule_ptr[count].end_freq =
20771 			WMI_REG_RULE_END_FREQ_GET(
20772 					wmi_reg_rule[count].freq_info);
20773 		reg_rule_ptr[count].max_bw =
20774 			WMI_REG_RULE_MAX_BW_GET(
20775 					wmi_reg_rule[count].bw_pwr_info);
20776 		reg_rule_ptr[count].reg_power =
20777 			WMI_REG_RULE_REG_POWER_GET(
20778 					wmi_reg_rule[count].bw_pwr_info);
20779 		reg_rule_ptr[count].ant_gain =
20780 			WMI_REG_RULE_ANTENNA_GAIN_GET(
20781 					wmi_reg_rule[count].bw_pwr_info);
20782 		reg_rule_ptr[count].flags =
20783 			WMI_REG_RULE_FLAGS_GET(
20784 					wmi_reg_rule[count].flag_info);
20785 	}
20786 
20787 	return reg_rule_ptr;
20788 }
20789 
20790 static QDF_STATUS extract_reg_chan_list_update_event_tlv(
20791 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
20792 	struct cur_regulatory_info *reg_info, uint32_t len)
20793 {
20794 	WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf;
20795 	wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr;
20796 	wmi_regulatory_rule_struct *wmi_reg_rule;
20797 	uint32_t num_2g_reg_rules, num_5g_reg_rules;
20798 
20799 	WMI_LOGD("processing regulatory channel list");
20800 
20801 	param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf;
20802 	if (!param_buf) {
20803 		WMI_LOGE("invalid channel list event buf");
20804 		return QDF_STATUS_E_FAILURE;
20805 	}
20806 
20807 	chan_list_event_hdr = param_buf->fixed_param;
20808 
20809 	reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules;
20810 	reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules;
20811 	qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2),
20812 		     REG_ALPHA2_LEN);
20813 	reg_info->dfs_region = chan_list_event_hdr->dfs_region;
20814 	reg_info->phybitmap = chan_list_event_hdr->phybitmap;
20815 	reg_info->offload_enabled = true;
20816 	reg_info->num_phy = chan_list_event_hdr->num_phy;
20817 	reg_info->phy_id = chan_list_event_hdr->phy_id;
20818 	reg_info->ctry_code = chan_list_event_hdr->country_id;
20819 	reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code;
20820 	if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS)
20821 		reg_info->status_code = REG_SET_CC_STATUS_PASS;
20822 	else if (chan_list_event_hdr->status_code ==
20823 		 WMI_REG_CURRENT_ALPHA2_NOT_FOUND)
20824 		reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND;
20825 	else if (chan_list_event_hdr->status_code ==
20826 		 WMI_REG_INIT_ALPHA2_NOT_FOUND)
20827 		reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND;
20828 	else if (chan_list_event_hdr->status_code ==
20829 		 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED)
20830 		reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED;
20831 	else if (chan_list_event_hdr->status_code ==
20832 		 WMI_REG_SET_CC_STATUS_NO_MEMORY)
20833 		reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY;
20834 	else if (chan_list_event_hdr->status_code ==
20835 		 WMI_REG_SET_CC_STATUS_FAIL)
20836 		reg_info->status_code = REG_SET_CC_STATUS_FAIL;
20837 
20838 	reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g;
20839 	reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g;
20840 	reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g;
20841 	reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g;
20842 
20843 	num_2g_reg_rules = reg_info->num_2g_reg_rules;
20844 	num_5g_reg_rules = reg_info->num_5g_reg_rules;
20845 
20846 	WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d",
20847 			__func__, reg_info->alpha2, reg_info->dfs_region,
20848 			reg_info->min_bw_2g, reg_info->max_bw_2g,
20849 			reg_info->min_bw_5g, reg_info->max_bw_5g);
20850 
20851 	WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__,
20852 			num_2g_reg_rules, num_5g_reg_rules);
20853 	wmi_reg_rule =
20854 		(wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr
20855 			+ sizeof(wmi_reg_chan_list_cc_event_fixed_param)
20856 			+ WMI_TLV_HDR_SIZE);
20857 	reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules,
20858 			wmi_reg_rule);
20859 	wmi_reg_rule += num_2g_reg_rules;
20860 
20861 	reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules,
20862 			wmi_reg_rule);
20863 
20864 	WMI_LOGD("processed regulatory channel list");
20865 
20866 	return QDF_STATUS_SUCCESS;
20867 }
20868 
20869 static QDF_STATUS extract_reg_11d_new_country_event_tlv(
20870 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
20871 	struct reg_11d_new_country *reg_11d_country, uint32_t len)
20872 {
20873 	wmi_11d_new_country_event_fixed_param *reg_11d_country_event;
20874 	WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf;
20875 
20876 	param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf;
20877 	if (!param_buf) {
20878 		WMI_LOGE("invalid 11d country event buf");
20879 		return QDF_STATUS_E_FAILURE;
20880 	}
20881 
20882 	reg_11d_country_event = param_buf->fixed_param;
20883 
20884 	qdf_mem_copy(reg_11d_country->alpha2,
20885 			&reg_11d_country_event->new_alpha2, REG_ALPHA2_LEN);
20886 
20887 	WMI_LOGD("processed 11d country event, new cc %s",
20888 			reg_11d_country->alpha2);
20889 
20890 	return QDF_STATUS_SUCCESS;
20891 }
20892 
20893 static QDF_STATUS extract_reg_ch_avoid_event_tlv(
20894 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
20895 	struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len)
20896 {
20897 	wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param;
20898 	wmi_avoid_freq_range_desc *afr_desc;
20899 	uint32_t num_freq_ranges, freq_range_idx;
20900 	WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf =
20901 		(WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf;
20902 
20903 	if (!param_buf) {
20904 		WMI_LOGE("Invalid channel avoid event buffer");
20905 		return QDF_STATUS_E_INVAL;
20906 	}
20907 
20908 	afr_fixed_param = param_buf->fixed_param;
20909 	if (!afr_fixed_param) {
20910 		WMI_LOGE("Invalid channel avoid event fixed param buffer");
20911 		return QDF_STATUS_E_INVAL;
20912 	}
20913 
20914 	if (!ch_avoid_ind) {
20915 		WMI_LOGE("Invalid channel avoid indication buffer");
20916 		return QDF_STATUS_E_INVAL;
20917 	}
20918 	if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) {
20919 		WMI_LOGE(FL("no.of freq ranges exceeded the limit"));
20920 		return QDF_STATUS_E_INVAL;
20921 	}
20922 	num_freq_ranges = (afr_fixed_param->num_freq_ranges >
20923 			CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE :
20924 			afr_fixed_param->num_freq_ranges;
20925 
20926 	WMI_LOGD("Channel avoid event received with %d ranges",
20927 		 num_freq_ranges);
20928 
20929 	ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges;
20930 	afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range);
20931 	for (freq_range_idx = 0; freq_range_idx < num_freq_ranges;
20932 	     freq_range_idx++) {
20933 		ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq =
20934 			afr_desc->start_freq;
20935 		ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq =
20936 			afr_desc->end_freq;
20937 		WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u",
20938 				freq_range_idx, afr_desc->tlv_header,
20939 				afr_desc->start_freq, afr_desc->end_freq);
20940 		afr_desc++;
20941 	}
20942 
20943 	return QDF_STATUS_SUCCESS;
20944 }
20945 #ifdef DFS_COMPONENT_ENABLE
20946 /**
20947  * extract_dfs_cac_complete_event_tlv() - extract cac complete event
20948  * @wmi_handle: wma handle
20949  * @evt_buf: event buffer
20950  * @vdev_id: vdev id
20951  * @len: length of buffer
20952  *
20953  * Return: 0 for success or error code
20954  */
20955 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle,
20956 		uint8_t *evt_buf,
20957 		uint32_t *vdev_id,
20958 		uint32_t len)
20959 {
20960 	WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs;
20961 	wmi_vdev_dfs_cac_complete_event_fixed_param  *cac_event;
20962 
20963 	param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf;
20964 	if (!param_tlvs) {
20965 		WMI_LOGE("invalid cac complete event buf");
20966 		return QDF_STATUS_E_FAILURE;
20967 	}
20968 
20969 	cac_event = param_tlvs->fixed_param;
20970 	*vdev_id = cac_event->vdev_id;
20971 	WMI_LOGD("processed cac complete event vdev %d", *vdev_id);
20972 
20973 	return QDF_STATUS_SUCCESS;
20974 }
20975 
20976 /**
20977  * extract_dfs_radar_detection_event_tlv() - extract radar found event
20978  * @wmi_handle: wma handle
20979  * @evt_buf: event buffer
20980  * @radar_found: radar found event info
20981  * @len: length of buffer
20982  *
20983  * Return: 0 for success or error code
20984  */
20985 static QDF_STATUS extract_dfs_radar_detection_event_tlv(
20986 		wmi_unified_t wmi_handle,
20987 		uint8_t *evt_buf,
20988 		struct radar_found_info *radar_found,
20989 		uint32_t len)
20990 {
20991 	WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv;
20992 	wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event;
20993 
20994 	param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf;
20995 	if (!param_tlv) {
20996 		WMI_LOGE("invalid radar detection event buf");
20997 		return QDF_STATUS_E_FAILURE;
20998 	}
20999 
21000 	radar_event = param_tlv->fixed_param;
21001 	radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id(
21002 			radar_event->pdev_id);
21003 	radar_found->detection_mode = radar_event->detection_mode;
21004 	radar_found->chan_freq = radar_event->chan_freq;
21005 	radar_found->chan_width = radar_event->chan_width;
21006 	radar_found->detector_id = radar_event->detector_id;
21007 	radar_found->segment_id = radar_event->segment_id;
21008 	radar_found->timestamp = radar_event->timestamp;
21009 	radar_found->is_chirp = radar_event->is_chirp;
21010 	radar_found->freq_offset = radar_event->freq_offset;
21011 	radar_found->sidx = radar_event->sidx;
21012 
21013 	WMI_LOGI("processed radar found event pdev %d,"
21014 		"Radar Event Info:pdev_id %d,timestamp %d,chan_freq  (dur) %d,"
21015 		"chan_width (RSSI) %d,detector_id (false_radar) %d,"
21016 		"freq_offset (radar_check) %d,segment_id %d,sidx %d,"
21017 		"is_chirp %d,detection mode %d\n",
21018 		radar_event->pdev_id, radar_found->pdev_id,
21019 		radar_event->timestamp, radar_event->chan_freq,
21020 		radar_event->chan_width, radar_event->detector_id,
21021 		radar_event->freq_offset, radar_event->segment_id,
21022 		radar_event->sidx, radar_event->is_chirp,
21023 		radar_event->detection_mode);
21024 
21025 	return QDF_STATUS_SUCCESS;
21026 }
21027 
21028 #ifdef QCA_MCL_DFS_SUPPORT
21029 /**
21030  * extract_wlan_radar_event_info_tlv() - extract radar pulse event
21031  * @wmi_handle: wma handle
21032  * @evt_buf: event buffer
21033  * @wlan_radar_event: Pointer to struct radar_event_info
21034  * @len: length of buffer
21035  *
21036  * Return: QDF_STATUS
21037  */
21038 static QDF_STATUS extract_wlan_radar_event_info_tlv(
21039 		wmi_unified_t wmi_handle,
21040 		uint8_t *evt_buf,
21041 		struct radar_event_info *wlan_radar_event,
21042 		uint32_t len)
21043 {
21044 	WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv;
21045 	wmi_dfs_radar_event_fixed_param *radar_event;
21046 
21047 	param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf;
21048 	if (!param_tlv) {
21049 		WMI_LOGE("invalid wlan radar event buf");
21050 		return QDF_STATUS_E_FAILURE;
21051 	}
21052 
21053 	radar_event = param_tlv->fixed_param;
21054 	wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp;
21055 	wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq;
21056 	wlan_radar_event->pulse_duration = radar_event->pulse_duration;
21057 	wlan_radar_event->rssi = radar_event->rssi;
21058 	wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts;
21059 	wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high;
21060 	wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low;
21061 	wlan_radar_event->peak_sidx = radar_event->peak_sidx;
21062 	wlan_radar_event->delta_peak = radar_event->pulse_delta_peak;
21063 	wlan_radar_event->delta_diff = radar_event->pulse_delta_diff;
21064 	if (radar_event->pulse_flags &
21065 			WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) {
21066 		wlan_radar_event->is_psidx_diff_valid = true;
21067 		wlan_radar_event->psidx_diff = radar_event->psidx_diff;
21068 	} else {
21069 		wlan_radar_event->is_psidx_diff_valid = false;
21070 	}
21071 
21072 	wlan_radar_event->pdev_id = radar_event->pdev_id;
21073 
21074 	return QDF_STATUS_SUCCESS;
21075 }
21076 #else
21077 static QDF_STATUS extract_wlan_radar_event_info_tlv(
21078 		wmi_unified_t wmi_handle,
21079 		uint8_t *evt_buf,
21080 		struct radar_event_info *wlan_radar_event,
21081 		uint32_t len)
21082 {
21083 	return QDF_STATUS_SUCCESS;
21084 }
21085 #endif
21086 #endif
21087 
21088 /**
21089  * send_get_rcpi_cmd_tlv() - send request for rcpi value
21090  * @wmi_handle: wmi handle
21091  * @get_rcpi_param: rcpi params
21092  *
21093  * Return: QDF status
21094  */
21095 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle,
21096 					struct rcpi_req  *get_rcpi_param)
21097 {
21098 	wmi_buf_t buf;
21099 	wmi_request_rcpi_cmd_fixed_param *cmd;
21100 	uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param);
21101 
21102 	buf = wmi_buf_alloc(wmi_handle, len);
21103 	if (!buf) {
21104 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
21105 		return QDF_STATUS_E_NOMEM;
21106 	}
21107 
21108 	cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf);
21109 	WMITLV_SET_HDR(&cmd->tlv_header,
21110 		       WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param,
21111 		       WMITLV_GET_STRUCT_TLVLEN
21112 		       (wmi_request_rcpi_cmd_fixed_param));
21113 
21114 	cmd->vdev_id = get_rcpi_param->vdev_id;
21115 	WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr,
21116 				   &cmd->peer_macaddr);
21117 
21118 	switch (get_rcpi_param->measurement_type) {
21119 
21120 	case RCPI_MEASUREMENT_TYPE_AVG_MGMT:
21121 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT;
21122 		break;
21123 
21124 	case RCPI_MEASUREMENT_TYPE_AVG_DATA:
21125 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA;
21126 		break;
21127 
21128 	case RCPI_MEASUREMENT_TYPE_LAST_MGMT:
21129 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT;
21130 		break;
21131 
21132 	case RCPI_MEASUREMENT_TYPE_LAST_DATA:
21133 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA;
21134 		break;
21135 
21136 	default:
21137 		/*
21138 		 * invalid rcpi measurement type, fall back to
21139 		 * RCPI_MEASUREMENT_TYPE_AVG_MGMT
21140 		 */
21141 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT;
21142 		break;
21143 	}
21144 	WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id);
21145 	wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0);
21146 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21147 				 WMI_REQUEST_RCPI_CMDID)) {
21148 
21149 		WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID",
21150 			 __func__);
21151 		wmi_buf_free(buf);
21152 		return QDF_STATUS_E_FAILURE;
21153 	}
21154 
21155 	return QDF_STATUS_SUCCESS;
21156 }
21157 
21158 /**
21159  * extract_rcpi_response_event_tlv() - Extract RCPI event params
21160  * @wmi_handle: wmi handle
21161  * @evt_buf: pointer to event buffer
21162  * @res: pointer to hold rcpi response from firmware
21163  *
21164  * Return: QDF_STATUS_SUCCESS for successful event parse
21165  *         else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE
21166  */
21167 static QDF_STATUS
21168 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle,
21169 				void *evt_buf, struct rcpi_res *res)
21170 {
21171 	WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf;
21172 	wmi_update_rcpi_event_fixed_param *event;
21173 
21174 	param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf;
21175 	if (!param_buf) {
21176 		WMI_LOGE(FL("Invalid rcpi event"));
21177 		return QDF_STATUS_E_INVAL;
21178 	}
21179 
21180 	event = param_buf->fixed_param;
21181 	res->vdev_id = event->vdev_id;
21182 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr);
21183 
21184 	switch (event->measurement_type) {
21185 
21186 	case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT:
21187 		res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT;
21188 		break;
21189 
21190 	case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA:
21191 		res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA;
21192 		break;
21193 
21194 	case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT:
21195 		res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT;
21196 		break;
21197 
21198 	case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA:
21199 		res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA;
21200 		break;
21201 
21202 	default:
21203 		WMI_LOGE(FL("Invalid rcpi measurement type from firmware"));
21204 		res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID;
21205 		return QDF_STATUS_E_FAILURE;
21206 	}
21207 
21208 	if (event->status)
21209 		return QDF_STATUS_E_FAILURE;
21210 	else
21211 		return QDF_STATUS_SUCCESS;
21212 }
21213 
21214 /**
21215  * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from
21216  *           host to target defines. For legacy there is not conversion
21217  *           required. Just return pdev_id as it is.
21218  * @param pdev_id: host pdev_id to be converted.
21219  * Return: target pdev_id after conversion.
21220  */
21221 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy(
21222 							uint32_t pdev_id)
21223 {
21224 	if (pdev_id == WMI_HOST_PDEV_ID_SOC)
21225 		return WMI_PDEV_ID_SOC;
21226 
21227 	/*No conversion required*/
21228 	return pdev_id;
21229 }
21230 
21231 /**
21232  * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from
21233  *           target to host defines. For legacy there is not conversion
21234  *           required. Just return pdev_id as it is.
21235  * @param pdev_id: target pdev_id to be converted.
21236  * Return: host pdev_id after conversion.
21237  */
21238 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy(
21239 							uint32_t pdev_id)
21240 {
21241 	/*No conversion required*/
21242 	return pdev_id;
21243 }
21244 
21245 /**
21246  *  send_set_country_cmd_tlv() - WMI scan channel list function
21247  *  @param wmi_handle      : handle to WMI.
21248  *  @param param    : pointer to hold scan channel list parameter
21249  *
21250  *  Return: 0  on success and -ve on failure.
21251  */
21252 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle,
21253 				struct set_country *params)
21254 {
21255 	wmi_buf_t buf;
21256 	QDF_STATUS qdf_status;
21257 	wmi_set_current_country_cmd_fixed_param *cmd;
21258 	uint16_t len = sizeof(*cmd);
21259 
21260 	buf = wmi_buf_alloc(wmi_handle, len);
21261 	if (!buf) {
21262 		WMI_LOGE("Failed to allocate memory");
21263 		qdf_status = QDF_STATUS_E_NOMEM;
21264 		goto end;
21265 	}
21266 
21267 	cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf);
21268 	WMITLV_SET_HDR(&cmd->tlv_header,
21269 		       WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param,
21270 		       WMITLV_GET_STRUCT_TLVLEN
21271 			       (wmi_set_current_country_cmd_fixed_param));
21272 
21273 	WMI_LOGD("setting cuurnet country to  %s", params->country);
21274 
21275 	qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3);
21276 
21277 	cmd->pdev_id = params->pdev_id;
21278 
21279 	wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0);
21280 	qdf_status = wmi_unified_cmd_send(wmi_handle,
21281 			buf, len, WMI_SET_CURRENT_COUNTRY_CMDID);
21282 
21283 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
21284 		WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID");
21285 		wmi_buf_free(buf);
21286 	}
21287 
21288 end:
21289 	return qdf_status;
21290 }
21291 
21292 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2)          do { \
21293 	    WMI_SET_BITS(alpha, 0, 8, val0); \
21294 	    WMI_SET_BITS(alpha, 8, 8, val1); \
21295 	    WMI_SET_BITS(alpha, 16, 8, val2); \
21296 	    } while (0)
21297 
21298 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle,
21299 		uint8_t pdev_id, struct cc_regdmn_s *rd)
21300 {
21301 	wmi_set_init_country_cmd_fixed_param *cmd;
21302 	uint16_t len;
21303 	wmi_buf_t buf;
21304 	int ret;
21305 
21306 	len = sizeof(wmi_set_init_country_cmd_fixed_param);
21307 	buf = wmi_buf_alloc(wmi_handle, len);
21308 	if (!buf) {
21309 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
21310 		return QDF_STATUS_E_NOMEM;
21311 	}
21312 	cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf);
21313 	WMITLV_SET_HDR(&cmd->tlv_header,
21314 			WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param,
21315 			WMITLV_GET_STRUCT_TLVLEN
21316 			(wmi_set_init_country_cmd_fixed_param));
21317 
21318 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
21319 
21320 	if (rd->flags == CC_IS_SET) {
21321 		cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID;
21322 		cmd->country_code.country_id = rd->cc.country_code;
21323 	} else if (rd->flags == ALPHA_IS_SET) {
21324 		cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2;
21325 		WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2,
21326 				rd->cc.alpha[0],
21327 				rd->cc.alpha[1],
21328 				rd->cc.alpha[2]);
21329 	} else if (rd->flags == REGDMN_IS_SET) {
21330 		cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE;
21331 		cmd->country_code.domain_code = rd->cc.regdmn_id;
21332 	}
21333 
21334 	wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0);
21335 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
21336 			WMI_SET_INIT_COUNTRY_CMDID);
21337 	if (ret) {
21338 		WMI_LOGE("Failed to config wow wakeup event");
21339 		wmi_buf_free(buf);
21340 		return QDF_STATUS_E_FAILURE;
21341 	}
21342 
21343 	return QDF_STATUS_SUCCESS;
21344 }
21345 
21346 /**
21347  * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan
21348  * configuration params
21349  * @wmi_handle: wmi handler
21350  * @limit_off_chan_param: pointer to wmi_off_chan_param
21351  *
21352  * Return: 0 for success and non zero for failure
21353  */
21354 static
21355 QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle,
21356 		struct wmi_limit_off_chan_param *limit_off_chan_param)
21357 {
21358 	wmi_vdev_limit_offchan_cmd_fixed_param *cmd;
21359 	wmi_buf_t buf;
21360 	uint32_t len = sizeof(*cmd);
21361 	int err;
21362 
21363 	buf = wmi_buf_alloc(wmi_handle, len);
21364 	if (!buf) {
21365 		WMI_LOGP("%s: failed to allocate memory for limit off chan cmd",
21366 				__func__);
21367 		return QDF_STATUS_E_NOMEM;
21368 	}
21369 
21370 	cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf);
21371 
21372 	WMITLV_SET_HDR(&cmd->tlv_header,
21373 			WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param,
21374 			WMITLV_GET_STRUCT_TLVLEN(
21375 				wmi_vdev_limit_offchan_cmd_fixed_param));
21376 
21377 	cmd->vdev_id = limit_off_chan_param->vdev_id;
21378 
21379 	cmd->flags &= 0;
21380 	if (limit_off_chan_param->status)
21381 		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE;
21382 	if (limit_off_chan_param->skip_dfs_chans)
21383 		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS;
21384 
21385 	cmd->max_offchan_time = limit_off_chan_param->max_offchan_time;
21386 	cmd->rest_time = limit_off_chan_param->rest_time;
21387 
21388 	WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d",
21389 			__func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time,
21390 			cmd->rest_time);
21391 
21392 	wmi_mtrace(WMI_VDEV_LIMIT_OFFCHAN_CMDID, cmd->vdev_id, 0);
21393 	err = wmi_unified_cmd_send(wmi_handle, buf,
21394 			len, WMI_VDEV_LIMIT_OFFCHAN_CMDID);
21395 	if (QDF_IS_STATUS_ERROR(err)) {
21396 		WMI_LOGE("Failed to send limit off chan cmd err=%d", err);
21397 		wmi_buf_free(buf);
21398 		return QDF_STATUS_E_FAILURE;
21399 	}
21400 
21401 	return QDF_STATUS_SUCCESS;
21402 }
21403 
21404 /**
21405  * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request
21406  * @wmi_handle: wmi handler
21407  * @req_buf: set arp stats request buffer
21408  *
21409  * Return: 0 for success and non zero for failure
21410  */
21411 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
21412 					  struct set_arp_stats *req_buf)
21413 {
21414 	wmi_buf_t buf = NULL;
21415 	QDF_STATUS status;
21416 	int len;
21417 	uint8_t *buf_ptr;
21418 	wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp;
21419 
21420 	len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
21421 	if (req_buf->pkt_type_bitmap) {
21422 		len += WMI_TLV_HDR_SIZE;
21423 		len += sizeof(wmi_vdev_set_connectivity_check_stats);
21424 	}
21425 	buf = wmi_buf_alloc(wmi_handle, len);
21426 	if (!buf) {
21427 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
21428 		return QDF_STATUS_E_NOMEM;
21429 	}
21430 
21431 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21432 	wmi_set_arp =
21433 		(wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr;
21434 	WMITLV_SET_HDR(&wmi_set_arp->tlv_header,
21435 		       WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param,
21436 		       WMITLV_GET_STRUCT_TLVLEN
21437 		       (wmi_vdev_set_arp_stats_cmd_fixed_param));
21438 
21439 	/* fill in per roam config values */
21440 	wmi_set_arp->vdev_id = req_buf->vdev_id;
21441 
21442 	wmi_set_arp->set_clr = req_buf->flag;
21443 	wmi_set_arp->pkt_type = req_buf->pkt_type;
21444 	wmi_set_arp->ipv4 = req_buf->ip_addr;
21445 
21446 	WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u",
21447 			 wmi_set_arp->vdev_id, wmi_set_arp->set_clr,
21448 			 wmi_set_arp->pkt_type, wmi_set_arp->ipv4);
21449 
21450 	/*
21451 	 * pkt_type_bitmap should be non-zero to ensure
21452 	 * presence of additional stats.
21453 	 */
21454 	if (req_buf->pkt_type_bitmap) {
21455 		wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats;
21456 
21457 		buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
21458 		WMITLV_SET_HDR(buf_ptr,
21459 			   WMITLV_TAG_ARRAY_STRUC,
21460 			   sizeof(wmi_vdev_set_connectivity_check_stats));
21461 		buf_ptr += WMI_TLV_HDR_SIZE;
21462 		wmi_set_connect_stats =
21463 			(wmi_vdev_set_connectivity_check_stats *)buf_ptr;
21464 		WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header,
21465 			WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats,
21466 			WMITLV_GET_STRUCT_TLVLEN(
21467 					wmi_vdev_set_connectivity_check_stats));
21468 		wmi_set_connect_stats->pkt_type_bitmap =
21469 						req_buf->pkt_type_bitmap;
21470 		wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port;
21471 		wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port;
21472 		wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4;
21473 
21474 		WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u",
21475 			 wmi_set_connect_stats->pkt_type_bitmap,
21476 			 wmi_set_connect_stats->tcp_src_port,
21477 			 wmi_set_connect_stats->tcp_dst_port,
21478 			 wmi_set_connect_stats->icmp_ipv4);
21479 	}
21480 
21481 	/* Send per roam config parameters */
21482 	wmi_mtrace(WMI_VDEV_SET_ARP_STAT_CMDID, NO_SESSION, 0);
21483 	status = wmi_unified_cmd_send(wmi_handle, buf,
21484 				      len, WMI_VDEV_SET_ARP_STAT_CMDID);
21485 	if (QDF_IS_STATUS_ERROR(status)) {
21486 		WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d",
21487 			 status);
21488 		goto error;
21489 	}
21490 
21491 	WMI_LOGD(FL("set arp stats flag=%d, vdev=%d"),
21492 		 req_buf->flag, req_buf->vdev_id);
21493 	return QDF_STATUS_SUCCESS;
21494 error:
21495 	wmi_buf_free(buf);
21496 
21497 	return status;
21498 }
21499 
21500 /**
21501  * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request
21502  * @wmi_handle: wmi handler
21503  * @req_buf: get arp stats request buffer
21504  *
21505  * Return: 0 for success and non zero for failure
21506  */
21507 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
21508 					  struct get_arp_stats *req_buf)
21509 {
21510 	wmi_buf_t buf = NULL;
21511 	QDF_STATUS status;
21512 	int len;
21513 	uint8_t *buf_ptr;
21514 	wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats;
21515 
21516 	len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param);
21517 	buf = wmi_buf_alloc(wmi_handle, len);
21518 	if (!buf) {
21519 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
21520 		return QDF_STATUS_E_NOMEM;
21521 	}
21522 
21523 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21524 	get_arp_stats =
21525 		(wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr;
21526 	WMITLV_SET_HDR(&get_arp_stats->tlv_header,
21527 		       WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param,
21528 		       WMITLV_GET_STRUCT_TLVLEN
21529 		       (wmi_vdev_get_arp_stats_cmd_fixed_param));
21530 
21531 	/* fill in arp stats req cmd values */
21532 	get_arp_stats->vdev_id = req_buf->vdev_id;
21533 
21534 	WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id);
21535 	/* Send per roam config parameters */
21536 	wmi_mtrace(WMI_VDEV_GET_ARP_STAT_CMDID, NO_SESSION, 0);
21537 	status = wmi_unified_cmd_send(wmi_handle, buf,
21538 				      len, WMI_VDEV_GET_ARP_STAT_CMDID);
21539 	if (QDF_IS_STATUS_ERROR(status)) {
21540 		WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d",
21541 			 status);
21542 		goto error;
21543 	}
21544 
21545 	return QDF_STATUS_SUCCESS;
21546 error:
21547 	wmi_buf_free(buf);
21548 
21549 	return status;
21550 }
21551 
21552 /**
21553  * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid
21554  * @wmi_handle: wmi handler
21555  * @pmk_info: pointer to PMK cache entry
21556  * @vdev_id: vdev id
21557  *
21558  * Return: 0 for success and non zero for failure
21559  */
21560 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle,
21561 				struct wmi_unified_pmk_cache *pmk_info)
21562 {
21563 	wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd;
21564 	wmi_buf_t buf;
21565 	QDF_STATUS status;
21566 	uint8_t *buf_ptr;
21567 	wmi_pmk_cache *pmksa;
21568 	uint32_t len = sizeof(*cmd);
21569 
21570 	if (pmk_info->pmk_len)
21571 		len += WMI_TLV_HDR_SIZE + sizeof(*pmksa);
21572 
21573 	buf = wmi_buf_alloc(wmi_handle, len);
21574 	if (!buf) {
21575 		WMI_LOGP("%s: failed to allocate memory for set del pmkid cache",
21576 			 __func__);
21577 		return QDF_STATUS_E_NOMEM;
21578 	}
21579 
21580 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21581 	cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr;
21582 
21583 	WMITLV_SET_HDR(&cmd->tlv_header,
21584 		 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param,
21585 		 WMITLV_GET_STRUCT_TLVLEN(
21586 			wmi_pdev_update_pmk_cache_cmd_fixed_param));
21587 
21588 	cmd->vdev_id = pmk_info->session_id;
21589 
21590 	/* If pmk_info->pmk_len is 0, this is a flush request */
21591 	if (!pmk_info->pmk_len) {
21592 		cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL;
21593 		cmd->num_cache = 0;
21594 		goto send_cmd;
21595 	}
21596 
21597 	cmd->num_cache = 1;
21598 	buf_ptr += sizeof(*cmd);
21599 
21600 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
21601 			sizeof(*pmksa));
21602 	buf_ptr += WMI_TLV_HDR_SIZE;
21603 
21604 	pmksa = (wmi_pmk_cache *)buf_ptr;
21605 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache,
21606 			WMITLV_GET_STRUCT_TLVLEN
21607 				(wmi_pmk_cache));
21608 	pmksa->pmk_len = pmk_info->pmk_len;
21609 	qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len);
21610 	pmksa->pmkid_len = pmk_info->pmkid_len;
21611 	qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len);
21612 	qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr));
21613 	pmksa->ssid.ssid_len = pmk_info->ssid.length;
21614 	qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid),
21615 			pmksa->ssid.ssid_len);
21616 	pmksa->cache_id = pmk_info->cache_id;
21617 	pmksa->cat_flag = pmk_info->cat_flag;
21618 	pmksa->action_flag = pmk_info->action_flag;
21619 
21620 send_cmd:
21621 	wmi_mtrace(WMI_PDEV_UPDATE_PMK_CACHE_CMDID, cmd->vdev_id, 0);
21622 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
21623 			WMI_PDEV_UPDATE_PMK_CACHE_CMDID);
21624 	if (status != QDF_STATUS_SUCCESS) {
21625 		WMI_LOGE("%s: failed to send set del pmkid cache command %d",
21626 			 __func__, status);
21627 		wmi_buf_free(buf);
21628 	}
21629 
21630 	return status;
21631 }
21632 
21633 /**
21634  * send_pdev_caldata_version_check_cmd_tlv() - send caldata check cmd to fw
21635  * @wmi_handle: wmi handle
21636  * @param:	reserved param
21637  *
21638  * Return: 0 for success or error code
21639  */
21640 static QDF_STATUS
21641 send_pdev_caldata_version_check_cmd_tlv(wmi_unified_t wmi_handle,
21642 						uint32_t param)
21643 {
21644 	wmi_pdev_check_cal_version_cmd_fixed_param *cmd;
21645 	wmi_buf_t buf;
21646 	int32_t len = sizeof(wmi_pdev_check_cal_version_cmd_fixed_param);
21647 
21648 	buf = wmi_buf_alloc(wmi_handle, len);
21649 	if (!buf) {
21650 		qdf_print("%s:wmi_buf_alloc failed", __func__);
21651 		return QDF_STATUS_E_FAILURE;
21652 	}
21653 	cmd = (wmi_pdev_check_cal_version_cmd_fixed_param *)wmi_buf_data(buf);
21654 	WMITLV_SET_HDR(&cmd->tlv_header,
21655 			WMITLV_TAG_STRUC_wmi_pdev_check_cal_version_cmd_fixed_param,
21656 			WMITLV_GET_STRUCT_TLVLEN
21657 			(wmi_pdev_check_cal_version_cmd_fixed_param));
21658 	cmd->pdev_id = param; /* set to 0x0 as expected from FW */
21659 	wmi_mtrace(WMI_PDEV_CHECK_CAL_VERSION_CMDID, NO_SESSION, 0);
21660 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21661 			WMI_PDEV_CHECK_CAL_VERSION_CMDID)) {
21662 		wmi_buf_free(buf);
21663 		return QDF_STATUS_E_FAILURE;
21664 	}
21665 
21666 	return QDF_STATUS_SUCCESS;
21667 }
21668 
21669 /**
21670  * extract_pdev_caldata_version_check_ev_param_tlv() - extract caldata from event
21671  * @wmi_handle: wmi handle
21672  * @param evt_buf: pointer to event buffer
21673  * @param param: Pointer to hold peer caldata version data
21674  *
21675  * Return: 0 for success or error code
21676  */
21677 static QDF_STATUS extract_pdev_caldata_version_check_ev_param_tlv(
21678 			wmi_unified_t wmi_handle,
21679 			void *evt_buf,
21680 			wmi_host_pdev_check_cal_version_event *param)
21681 {
21682 	WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *param_tlvs;
21683 	wmi_pdev_check_cal_version_event_fixed_param *event;
21684 
21685 	param_tlvs = (WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *) evt_buf;
21686 	if (!param_tlvs) {
21687 		WMI_LOGE("invalid cal version event buf");
21688 		return QDF_STATUS_E_FAILURE;
21689 	}
21690 	event =  param_tlvs->fixed_param;
21691 	if (event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] != '\0')
21692 		event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] = '\0';
21693 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(param->board_mcn_detail,
21694 			event->board_mcn_detail, WMI_BOARD_MCN_STRING_BUF_SIZE);
21695 
21696 	param->software_cal_version = event->software_cal_version;
21697 	param->board_cal_version = event->board_cal_version;
21698 	param->cal_ok  = event->cal_status;
21699 
21700 	return QDF_STATUS_SUCCESS;
21701 }
21702 
21703 /*
21704  * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config
21705  * @wmi_handle: wmi handle
21706  * @params: pointer to wmi_btm_config
21707  *
21708  * Return: QDF_STATUS
21709  */
21710 static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle,
21711 					  struct wmi_btm_config *params)
21712 {
21713 
21714 	wmi_btm_config_fixed_param *cmd;
21715 	wmi_buf_t buf;
21716 	uint32_t len;
21717 
21718 	len = sizeof(*cmd);
21719 	buf = wmi_buf_alloc(wmi_handle, len);
21720 	if (!buf) {
21721 		qdf_print("%s:wmi_buf_alloc failed", __func__);
21722 		return QDF_STATUS_E_NOMEM;
21723 	}
21724 
21725 	cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf);
21726 	WMITLV_SET_HDR(&cmd->tlv_header,
21727 		       WMITLV_TAG_STRUC_wmi_btm_config_fixed_param,
21728 		       WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param));
21729 	cmd->vdev_id = params->vdev_id;
21730 	cmd->flags = params->btm_offload_config;
21731 	cmd->max_attempt_cnt = params->btm_max_attempt_cnt;
21732 	cmd->solicited_timeout_ms = params->btm_solicited_timeout;
21733 	cmd->stick_time_seconds = params->btm_sticky_time;
21734 
21735 	wmi_mtrace(WMI_ROAM_BTM_CONFIG_CMDID, cmd->vdev_id, 0);
21736 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21737 	    WMI_ROAM_BTM_CONFIG_CMDID)) {
21738 		WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID",
21739 			 __func__);
21740 		wmi_buf_free(buf);
21741 		return QDF_STATUS_E_FAILURE;
21742 	}
21743 
21744 	return QDF_STATUS_SUCCESS;
21745 }
21746 
21747 /**
21748  * send_obss_detection_cfg_cmd_tlv() - send obss detection
21749  *   configurations to firmware.
21750  * @wmi_handle: wmi handle
21751  * @obss_cfg_param: obss detection configurations
21752  *
21753  * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw.
21754  *
21755  * Return: QDF_STATUS
21756  */
21757 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle,
21758 		struct wmi_obss_detection_cfg_param *obss_cfg_param)
21759 {
21760 	wmi_buf_t buf;
21761 	wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd;
21762 	uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param);
21763 
21764 	buf = wmi_buf_alloc(wmi_handle, len);
21765 	if (!buf) {
21766 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
21767 		return QDF_STATUS_E_NOMEM;
21768 	}
21769 
21770 	cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf);
21771 	WMITLV_SET_HDR(&cmd->tlv_header,
21772 		WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param,
21773 		       WMITLV_GET_STRUCT_TLVLEN
21774 		       (wmi_sap_obss_detection_cfg_cmd_fixed_param));
21775 
21776 	cmd->vdev_id = obss_cfg_param->vdev_id;
21777 	cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms;
21778 	cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode;
21779 	cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode;
21780 	cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode;
21781 	cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode;
21782 	cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode;
21783 	cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode;
21784 	cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode;
21785 
21786 	wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0);
21787 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21788 				 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) {
21789 		WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID");
21790 		wmi_buf_free(buf);
21791 		return QDF_STATUS_E_FAILURE;
21792 	}
21793 
21794 	return QDF_STATUS_SUCCESS;
21795 }
21796 
21797 /**
21798  * extract_obss_detection_info_tlv() - Extract obss detection info
21799  *   received from firmware.
21800  * @evt_buf: pointer to event buffer
21801  * @obss_detection: Pointer to hold obss detection info
21802  *
21803  * Return: QDF_STATUS
21804  */
21805 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf,
21806 						  struct wmi_obss_detect_info
21807 						  *obss_detection)
21808 {
21809 	WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf;
21810 	wmi_sap_obss_detection_info_evt_fixed_param *fix_param;
21811 
21812 	if (!obss_detection) {
21813 		WMI_LOGE("%s: Invalid obss_detection event buffer", __func__);
21814 		return QDF_STATUS_E_INVAL;
21815 	}
21816 
21817 	param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf;
21818 	if (!param_buf) {
21819 		WMI_LOGE("%s: Invalid evt_buf", __func__);
21820 		return QDF_STATUS_E_INVAL;
21821 	}
21822 
21823 	fix_param = param_buf->fixed_param;
21824 	obss_detection->vdev_id = fix_param->vdev_id;
21825 	obss_detection->matched_detection_masks =
21826 		fix_param->matched_detection_masks;
21827 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr,
21828 				   &obss_detection->matched_bssid_addr[0]);
21829 	switch (fix_param->reason) {
21830 	case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT:
21831 		obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED;
21832 		break;
21833 	case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY:
21834 		obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT;
21835 		break;
21836 	case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT:
21837 		obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT;
21838 		break;
21839 	default:
21840 		WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason);
21841 		return QDF_STATUS_E_INVAL;
21842 	}
21843 
21844 	return QDF_STATUS_SUCCESS;
21845 }
21846 
21847 /**
21848  * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw
21849  * @wmi_handle: wmi handle
21850  * @params: pointer to request structure
21851  *
21852  * Return: QDF_STATUS
21853  */
21854 static QDF_STATUS
21855 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle,
21856 			     struct wmi_roam_scan_stats_req *params)
21857 {
21858 	wmi_buf_t buf;
21859 	wmi_request_roam_scan_stats_cmd_fixed_param *cmd;
21860 	WMITLV_TAG_ID tag;
21861 	uint32_t size;
21862 	uint32_t len = sizeof(*cmd);
21863 
21864 	buf = wmi_buf_alloc(wmi_handle, len);
21865 	if (!buf) {
21866 		WMI_LOGE(FL("Failed to allocate wmi buffer"));
21867 		return QDF_STATUS_E_FAILURE;
21868 	}
21869 
21870 	cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf);
21871 
21872 	tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param;
21873 	size = WMITLV_GET_STRUCT_TLVLEN(
21874 			wmi_request_roam_scan_stats_cmd_fixed_param);
21875 	WMITLV_SET_HDR(&cmd->tlv_header, tag, size);
21876 
21877 	cmd->vdev_id = params->vdev_id;
21878 
21879 	WMI_LOGD(FL("Roam Scan Stats Req vdev_id: %u"), cmd->vdev_id);
21880 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21881 				 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) {
21882 		WMI_LOGE("%s: Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID",
21883 			 __func__);
21884 		wmi_buf_free(buf);
21885 		return QDF_STATUS_E_FAILURE;
21886 	}
21887 
21888 	return QDF_STATUS_SUCCESS;
21889 }
21890 
21891 /**
21892  * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event
21893  * @wmi_handle: wmi handle
21894  * @evt_buf: pointer to event buffer
21895  * @vdev_id: output pointer to hold vdev id
21896  * @res_param: output pointer to hold the allocated response
21897  *
21898  * Return: QDF_STATUS
21899  */
21900 static QDF_STATUS
21901 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf,
21902 				    uint32_t *vdev_id,
21903 				    struct wmi_roam_scan_stats_res **res_param)
21904 {
21905 	WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf;
21906 	wmi_roam_scan_stats_event_fixed_param *fixed_param;
21907 	uint32_t *client_id = NULL;
21908 	wmi_roaming_timestamp *timestamp = NULL;
21909 	uint32_t *num_channels = NULL;
21910 	uint32_t *chan_info = NULL;
21911 	wmi_mac_addr *old_bssid = NULL;
21912 	uint32_t *is_roaming_success = NULL;
21913 	wmi_mac_addr *new_bssid = NULL;
21914 	uint32_t *num_roam_candidates = NULL;
21915 	wmi_roam_scan_trigger_reason *roam_reason = NULL;
21916 	wmi_mac_addr *bssid = NULL;
21917 	uint32_t *score = NULL;
21918 	uint32_t *channel = NULL;
21919 	uint32_t *rssi = NULL;
21920 	int chan_idx = 0, cand_idx = 0;
21921 	uint32_t total_len;
21922 	struct wmi_roam_scan_stats_res *res;
21923 	uint32_t i, j;
21924 	uint32_t num_scans;
21925 
21926 	*res_param = NULL;
21927 	*vdev_id = 0xFF; /* Initialize to invalid vdev id */
21928 	param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf;
21929 	if (!param_buf) {
21930 		WMI_LOGE(FL("Invalid roam scan stats event"));
21931 		return QDF_STATUS_E_INVAL;
21932 	}
21933 
21934 	fixed_param = param_buf->fixed_param;
21935 	total_len = sizeof(*res) + fixed_param->num_roam_scans *
21936 		    sizeof(struct wmi_roam_scan_stats_params);
21937 
21938 	*vdev_id = fixed_param->vdev_id;
21939 	num_scans = fixed_param->num_roam_scans;
21940 
21941 	res = qdf_mem_malloc(total_len);
21942 	if (!res) {
21943 		WMI_LOGE("Failed to allocate roam scan stats response memory");
21944 		return QDF_STATUS_E_NOMEM;
21945 	}
21946 
21947 	if (!num_scans) {
21948 		*res_param = res;
21949 		return QDF_STATUS_SUCCESS;
21950 	}
21951 
21952 	if (param_buf->client_id &&
21953 	    param_buf->num_client_id == num_scans)
21954 		client_id = param_buf->client_id;
21955 
21956 	if (param_buf->timestamp &&
21957 	    param_buf->num_timestamp == num_scans)
21958 		timestamp = param_buf->timestamp;
21959 
21960 	if (param_buf->old_bssid &&
21961 	    param_buf->num_old_bssid == num_scans)
21962 		old_bssid = param_buf->old_bssid;
21963 
21964 	if (param_buf->new_bssid &&
21965 	    param_buf->num_new_bssid == num_scans)
21966 		new_bssid = param_buf->new_bssid;
21967 
21968 	if (param_buf->is_roaming_success &&
21969 	    param_buf->num_is_roaming_success == num_scans)
21970 		is_roaming_success = param_buf->is_roaming_success;
21971 
21972 	if (param_buf->roam_reason &&
21973 	    param_buf->num_roam_reason == num_scans)
21974 		roam_reason = param_buf->roam_reason;
21975 
21976 	if (param_buf->num_channels &&
21977 	    param_buf->num_num_channels == num_scans) {
21978 		uint32_t count, chan_info_sum = 0;
21979 
21980 		num_channels = param_buf->num_channels;
21981 		for (count = 0; count < param_buf->num_num_channels; count++)
21982 			chan_info_sum += param_buf->num_channels[count];
21983 
21984 		if (param_buf->chan_info &&
21985 		    param_buf->num_chan_info == chan_info_sum)
21986 			chan_info = param_buf->chan_info;
21987 	}
21988 
21989 	if (param_buf->num_roam_candidates &&
21990 	    param_buf->num_num_roam_candidates == num_scans) {
21991 		uint32_t count, roam_cand_sum = 0;
21992 
21993 		num_roam_candidates = param_buf->num_roam_candidates;
21994 		for (count = 0; count < param_buf->num_num_roam_candidates;
21995 		     count++)
21996 			roam_cand_sum += param_buf->num_roam_candidates[count];
21997 
21998 		if (param_buf->bssid &&
21999 		    param_buf->num_bssid == roam_cand_sum)
22000 			bssid = param_buf->bssid;
22001 
22002 		if (param_buf->score &&
22003 		    param_buf->num_score == roam_cand_sum)
22004 			score = param_buf->score;
22005 
22006 		if (param_buf->channel &&
22007 		    param_buf->num_channel == roam_cand_sum)
22008 			channel = param_buf->channel;
22009 
22010 		if (param_buf->rssi &&
22011 		    param_buf->num_rssi == roam_cand_sum)
22012 			rssi = param_buf->rssi;
22013 	}
22014 
22015 	res->num_roam_scans = num_scans;
22016 	for (i = 0; i < num_scans; i++) {
22017 		struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i];
22018 
22019 		if (timestamp)
22020 			roam->time_stamp = timestamp[i].lower32bit |
22021 						(timestamp[i].upper32bit << 31);
22022 
22023 		if (client_id)
22024 			roam->client_id = client_id[i];
22025 
22026 		if (num_channels) {
22027 			roam->num_scan_chans = num_channels[i];
22028 			if (chan_info) {
22029 				for (j = 0; j < num_channels[i]; j++)
22030 					roam->scan_freqs[j] =
22031 							chan_info[chan_idx++];
22032 			}
22033 		}
22034 
22035 		if (is_roaming_success)
22036 			roam->is_roam_successful = is_roaming_success[i];
22037 
22038 		if (roam_reason) {
22039 			roam->trigger_id = roam_reason[i].trigger_id;
22040 			roam->trigger_value = roam_reason[i].trigger_value;
22041 		}
22042 
22043 		if (num_roam_candidates) {
22044 			roam->num_roam_candidates = num_roam_candidates[i];
22045 
22046 			for (j = 0; j < num_roam_candidates[i]; j++) {
22047 				if (score)
22048 					roam->cand[j].score = score[cand_idx];
22049 				if (rssi)
22050 					roam->cand[j].rssi = rssi[cand_idx];
22051 				if (channel)
22052 					roam->cand[j].freq =
22053 						channel[cand_idx];
22054 
22055 				if (bssid)
22056 					WMI_MAC_ADDR_TO_CHAR_ARRAY(
22057 							&bssid[cand_idx],
22058 							roam->cand[j].bssid);
22059 
22060 				cand_idx++;
22061 			}
22062 		}
22063 
22064 		if (old_bssid)
22065 			WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i],
22066 						   roam->old_bssid);
22067 
22068 		if (new_bssid)
22069 			WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i],
22070 						   roam->new_bssid);
22071 	}
22072 
22073 	*res_param = res;
22074 
22075 	return QDF_STATUS_SUCCESS;
22076 }
22077 
22078 /**
22079  * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params
22080  * @wmi_handle: wmi handler
22081  * @params: pointer to 11k offload params
22082  *
22083  * Return: 0 for success and non zero for failure
22084  */
22085 static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle,
22086 				struct wmi_11k_offload_params *params)
22087 {
22088 	wmi_11k_offload_report_fixed_param *cmd;
22089 	wmi_buf_t buf;
22090 	QDF_STATUS status;
22091 	uint8_t *buf_ptr;
22092 	wmi_neighbor_report_11k_offload_tlv_param
22093 					*neighbor_report_offload_params;
22094 	wmi_neighbor_report_offload *neighbor_report_offload;
22095 
22096 	uint32_t len = sizeof(*cmd);
22097 
22098 	if (params->offload_11k_bitmask &
22099 	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ)
22100 		len += WMI_TLV_HDR_SIZE +
22101 			sizeof(wmi_neighbor_report_11k_offload_tlv_param);
22102 
22103 	buf = wmi_buf_alloc(wmi_handle, len);
22104 	if (!buf) {
22105 		WMI_LOGP("%s: failed to allocate memory for 11k offload params",
22106 			 __func__);
22107 		return QDF_STATUS_E_NOMEM;
22108 	}
22109 
22110 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
22111 	cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr;
22112 
22113 	WMITLV_SET_HDR(&cmd->tlv_header,
22114 		 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param,
22115 		 WMITLV_GET_STRUCT_TLVLEN(
22116 			wmi_11k_offload_report_fixed_param));
22117 
22118 	cmd->vdev_id = params->vdev_id;
22119 	cmd->offload_11k = params->offload_11k_bitmask;
22120 
22121 	if (params->offload_11k_bitmask &
22122 	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) {
22123 		buf_ptr += sizeof(wmi_11k_offload_report_fixed_param);
22124 
22125 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
22126 			sizeof(wmi_neighbor_report_11k_offload_tlv_param));
22127 		buf_ptr += WMI_TLV_HDR_SIZE;
22128 
22129 		neighbor_report_offload_params =
22130 			(wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr;
22131 		WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header,
22132 			WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param,
22133 			WMITLV_GET_STRUCT_TLVLEN(
22134 			wmi_neighbor_report_11k_offload_tlv_param));
22135 
22136 		neighbor_report_offload = &neighbor_report_offload_params->
22137 			neighbor_rep_ofld_params;
22138 
22139 		neighbor_report_offload->time_offset =
22140 			params->neighbor_report_params.time_offset;
22141 		neighbor_report_offload->low_rssi_offset =
22142 			params->neighbor_report_params.low_rssi_offset;
22143 		neighbor_report_offload->bmiss_count_trigger =
22144 			params->neighbor_report_params.bmiss_count_trigger;
22145 		neighbor_report_offload->per_threshold_offset =
22146 			params->neighbor_report_params.per_threshold_offset;
22147 		neighbor_report_offload->neighbor_report_cache_timeout =
22148 			params->neighbor_report_params.
22149 			neighbor_report_cache_timeout;
22150 		neighbor_report_offload->max_neighbor_report_req_cap =
22151 			params->neighbor_report_params.
22152 			max_neighbor_report_req_cap;
22153 		neighbor_report_offload->ssid.ssid_len =
22154 			params->neighbor_report_params.ssid.length;
22155 		qdf_mem_copy(neighbor_report_offload->ssid.ssid,
22156 			&params->neighbor_report_params.ssid.mac_ssid,
22157 			neighbor_report_offload->ssid.ssid_len);
22158 	}
22159 
22160 	wmi_mtrace(WMI_11K_OFFLOAD_REPORT_CMDID, cmd->vdev_id, 0);
22161 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
22162 			WMI_11K_OFFLOAD_REPORT_CMDID);
22163 	if (status != QDF_STATUS_SUCCESS) {
22164 		WMI_LOGE("%s: failed to send 11k offload command %d",
22165 			 __func__, status);
22166 		wmi_buf_free(buf);
22167 	}
22168 
22169 	return status;
22170 }
22171 
22172 /**
22173  * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report
22174  * command
22175  * @wmi_handle: wmi handler
22176  * @params: pointer to neighbor report invoke params
22177  *
22178  * Return: 0 for success and non zero for failure
22179  */
22180 static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle,
22181 			struct wmi_invoke_neighbor_report_params *params)
22182 {
22183 	wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd;
22184 	wmi_buf_t buf;
22185 	QDF_STATUS status;
22186 	uint8_t *buf_ptr;
22187 	uint32_t len = sizeof(*cmd);
22188 
22189 	buf = wmi_buf_alloc(wmi_handle, len);
22190 	if (!buf) {
22191 		WMI_LOGP("%s:failed to allocate memory for neighbor invoke cmd",
22192 			 __func__);
22193 		return QDF_STATUS_E_NOMEM;
22194 	}
22195 
22196 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
22197 	cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr;
22198 
22199 	WMITLV_SET_HDR(&cmd->tlv_header,
22200 		 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param,
22201 		 WMITLV_GET_STRUCT_TLVLEN(
22202 			wmi_11k_offload_invoke_neighbor_report_fixed_param));
22203 
22204 	cmd->vdev_id = params->vdev_id;
22205 	cmd->flags = params->send_resp_to_host;
22206 
22207 	cmd->ssid.ssid_len = params->ssid.length;
22208 	qdf_mem_copy(cmd->ssid.ssid,
22209 		     &params->ssid.mac_ssid,
22210 		     cmd->ssid.ssid_len);
22211 
22212 	wmi_mtrace(WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID, cmd->vdev_id, 0);
22213 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
22214 			WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID);
22215 	if (status != QDF_STATUS_SUCCESS) {
22216 		WMI_LOGE("%s: failed to send invoke neighbor report command %d",
22217 			 __func__, status);
22218 		wmi_buf_free(buf);
22219 	}
22220 
22221 	return status;
22222 }
22223 
22224 #ifdef WLAN_SUPPORT_GREEN_AP
22225 static QDF_STATUS extract_green_ap_egap_status_info_tlv(
22226 		uint8_t *evt_buf,
22227 		struct wlan_green_ap_egap_status_info *egap_status_info_params)
22228 {
22229 	WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf;
22230 	wmi_ap_ps_egap_info_event_fixed_param  *egap_info_event;
22231 	wmi_ap_ps_egap_info_chainmask_list *chainmask_event;
22232 
22233 	param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf;
22234 	if (!param_buf) {
22235 		WMI_LOGE("Invalid EGAP Info status event buffer");
22236 		return QDF_STATUS_E_INVAL;
22237 	}
22238 
22239 	egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *)
22240 				param_buf->fixed_param;
22241 	chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *)
22242 				param_buf->chainmask_list;
22243 
22244 	egap_status_info_params->status = egap_info_event->status;
22245 	egap_status_info_params->mac_id = chainmask_event->mac_id;
22246 	egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask;
22247 	egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask;
22248 
22249 	return QDF_STATUS_SUCCESS;
22250 }
22251 #endif
22252 
22253 /*
22254  * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of
22255  * updating bss color change within firmware when AP announces bss color change.
22256  * @wmi_handle: wmi handle
22257  * @vdev_id: vdev ID
22258  * @enable: enable bss color change within firmware
22259  *
22260  * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw.
22261  *
22262  * Return: QDF_STATUS
22263  */
22264 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle,
22265 						       uint32_t vdev_id,
22266 						       bool enable)
22267 {
22268 	wmi_buf_t buf;
22269 	wmi_bss_color_change_enable_fixed_param *cmd;
22270 	uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param);
22271 
22272 	buf = wmi_buf_alloc(wmi_handle, len);
22273 	if (!buf) {
22274 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
22275 		return QDF_STATUS_E_NOMEM;
22276 	}
22277 
22278 	cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf);
22279 	WMITLV_SET_HDR(&cmd->tlv_header,
22280 		WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param,
22281 		       WMITLV_GET_STRUCT_TLVLEN
22282 		       (wmi_bss_color_change_enable_fixed_param));
22283 	cmd->vdev_id = vdev_id;
22284 	cmd->enable = enable;
22285 	wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0);
22286 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
22287 				 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) {
22288 		WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID");
22289 		wmi_buf_free(buf);
22290 		return QDF_STATUS_E_FAILURE;
22291 	}
22292 
22293 	return QDF_STATUS_SUCCESS;
22294 }
22295 
22296 /**
22297  * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection
22298  *   configurations to firmware.
22299  * @wmi_handle: wmi handle
22300  * @cfg_param: obss detection configurations
22301  *
22302  * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw.
22303  *
22304  * Return: QDF_STATUS
22305  */
22306 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv(
22307 		wmi_unified_t wmi_handle,
22308 		struct wmi_obss_color_collision_cfg_param *cfg_param)
22309 {
22310 	wmi_buf_t buf;
22311 	wmi_obss_color_collision_det_config_fixed_param *cmd;
22312 	uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param);
22313 
22314 	buf = wmi_buf_alloc(wmi_handle, len);
22315 	if (!buf) {
22316 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
22317 		return QDF_STATUS_E_NOMEM;
22318 	}
22319 
22320 	cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data(
22321 			buf);
22322 	WMITLV_SET_HDR(&cmd->tlv_header,
22323 	WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param,
22324 		       WMITLV_GET_STRUCT_TLVLEN
22325 		       (wmi_obss_color_collision_det_config_fixed_param));
22326 	cmd->vdev_id = cfg_param->vdev_id;
22327 	cmd->flags = cfg_param->flags;
22328 	cmd->current_bss_color = cfg_param->current_bss_color;
22329 	cmd->detection_period_ms = cfg_param->detection_period_ms;
22330 	cmd->scan_period_ms = cfg_param->scan_period_ms;
22331 	cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms;
22332 
22333 	switch (cfg_param->evt_type) {
22334 	case OBSS_COLOR_COLLISION_DETECTION_DISABLE:
22335 		cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE;
22336 		break;
22337 	case OBSS_COLOR_COLLISION_DETECTION:
22338 		cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION;
22339 		break;
22340 	case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY:
22341 		cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY;
22342 		break;
22343 	case OBSS_COLOR_FREE_SLOT_AVAILABLE:
22344 		cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE;
22345 		break;
22346 	default:
22347 		WMI_LOGE("%s: invalid event type: %d",
22348 			 __func__, cfg_param->evt_type);
22349 		wmi_buf_free(buf);
22350 		return QDF_STATUS_E_FAILURE;
22351 	}
22352 
22353 	wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0);
22354 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
22355 				 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) {
22356 		WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d",
22357 			 __func__, cfg_param->vdev_id);
22358 		wmi_buf_free(buf);
22359 		return QDF_STATUS_E_FAILURE;
22360 	}
22361 
22362 	return QDF_STATUS_SUCCESS;
22363 }
22364 
22365 /**
22366  * extract_obss_color_collision_info_tlv() - Extract bss color collision info
22367  *   received from firmware.
22368  * @evt_buf: pointer to event buffer
22369  * @info: Pointer to hold bss collision  info
22370  *
22371  * Return: QDF_STATUS
22372  */
22373 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf,
22374 		struct wmi_obss_color_collision_info *info)
22375 {
22376 	WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf;
22377 	wmi_obss_color_collision_evt_fixed_param *fix_param;
22378 
22379 	if (!info) {
22380 		WMI_LOGE("%s: Invalid obss color buffer", __func__);
22381 		return QDF_STATUS_E_INVAL;
22382 	}
22383 
22384 	param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *)
22385 		    evt_buf;
22386 	if (!param_buf) {
22387 		WMI_LOGE("%s: Invalid evt_buf", __func__);
22388 		return QDF_STATUS_E_INVAL;
22389 	}
22390 
22391 	fix_param = param_buf->fixed_param;
22392 	info->vdev_id = fix_param->vdev_id;
22393 	info->obss_color_bitmap_bit0to31 = fix_param->bss_color_bitmap_bit0to31;
22394 	info->obss_color_bitmap_bit32to63 =
22395 		fix_param->bss_color_bitmap_bit32to63;
22396 
22397 	switch (fix_param->evt_type) {
22398 	case WMI_BSS_COLOR_COLLISION_DISABLE:
22399 		info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE;
22400 		break;
22401 	case WMI_BSS_COLOR_COLLISION_DETECTION:
22402 		info->evt_type = OBSS_COLOR_COLLISION_DETECTION;
22403 		break;
22404 	case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY:
22405 		info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY;
22406 		break;
22407 	case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE:
22408 		info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE;
22409 		break;
22410 	default:
22411 		WMI_LOGE("%s: invalid event type: %d, vdev_id: %d",
22412 			 __func__, fix_param->evt_type, fix_param->vdev_id);
22413 		return QDF_STATUS_E_FAILURE;
22414 	}
22415 
22416 	return QDF_STATUS_SUCCESS;
22417 }
22418 
22419 /*
22420  * extract_comb_phyerr_tlv() - extract comb phy error from event
22421  * @wmi_handle: wmi handle
22422  * @evt_buf: pointer to event buffer
22423  * @datalen: data length of event buffer
22424  * @buf_offset: Pointer to hold value of current event buffer offset
22425  * post extraction
22426  * @phyerr: Pointer to hold phyerr
22427  *
22428  * Return: QDF_STATUS
22429  */
22430 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle,
22431 					  void *evt_buf,
22432 					  uint16_t datalen,
22433 					  uint16_t *buf_offset,
22434 					  wmi_host_phyerr_t *phyerr)
22435 {
22436 	WMI_PHYERR_EVENTID_param_tlvs *param_tlvs;
22437 	wmi_comb_phyerr_rx_hdr *pe_hdr;
22438 
22439 	param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf;
22440 	if (!param_tlvs) {
22441 		WMI_LOGD("%s: Received null data from FW", __func__);
22442 		return QDF_STATUS_E_FAILURE;
22443 	}
22444 
22445 	pe_hdr = param_tlvs->hdr;
22446 	if (!pe_hdr) {
22447 		WMI_LOGD("%s: Received Data PE Header is NULL", __func__);
22448 		return QDF_STATUS_E_FAILURE;
22449 	}
22450 
22451 	/* Ensure it's at least the size of the header */
22452 	if (datalen < sizeof(*pe_hdr)) {
22453 		WMI_LOGD("%s: Expected minimum size %zu, received %d",
22454 			 __func__, sizeof(*pe_hdr), datalen);
22455 		return QDF_STATUS_E_FAILURE;
22456 	}
22457 
22458 	phyerr->pdev_id = wmi_handle->ops->
22459 		convert_pdev_id_target_to_host(pe_hdr->pdev_id);
22460 	phyerr->tsf64 = pe_hdr->tsf_l32;
22461 	phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32);
22462 	phyerr->bufp = param_tlvs->bufp;
22463 	phyerr->buf_len = pe_hdr->buf_len;
22464 	phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0;
22465 	phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1;
22466 	*buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t);
22467 
22468 	return QDF_STATUS_SUCCESS;
22469 }
22470 
22471 /**
22472  * extract_single_phyerr_tlv() - extract single phy error from event
22473  * @wmi_handle: wmi handle
22474  * @evt_buf: pointer to event buffer
22475  * @datalen: data length of event buffer
22476  * @buf_offset: Pointer to hold value of current event buffer offset
22477  * post extraction
22478  * @phyerr: Pointer to hold phyerr
22479  *
22480  * Return: QDF_STATUS
22481  */
22482 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle,
22483 					    void *evt_buf,
22484 					    uint16_t datalen,
22485 					    uint16_t *buf_offset,
22486 					    wmi_host_phyerr_t *phyerr)
22487 {
22488 	wmi_single_phyerr_rx_event *ev;
22489 	uint16_t n = *buf_offset;
22490 	uint8_t *data = (uint8_t *)evt_buf;
22491 
22492 	if (n < datalen) {
22493 		if ((datalen - n) < sizeof(ev->hdr)) {
22494 			WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu",
22495 				 __func__, datalen, n, sizeof(ev->hdr));
22496 			return QDF_STATUS_E_FAILURE;
22497 		}
22498 
22499 		/*
22500 		 * Obtain a pointer to the beginning of the current event.
22501 		 * data[0] is the beginning of the WMI payload.
22502 		 */
22503 		ev = (wmi_single_phyerr_rx_event *)&data[n];
22504 
22505 		/*
22506 		 * Sanity check the buffer length of the event against
22507 		 * what we currently have.
22508 		 *
22509 		 * Since buf_len is 32 bits, we check if it overflows
22510 		 * a large 32 bit value.  It's not 0x7fffffff because
22511 		 * we increase n by (buf_len + sizeof(hdr)), which would
22512 		 * in itself cause n to overflow.
22513 		 *
22514 		 * If "int" is 64 bits then this becomes a moot point.
22515 		 */
22516 		if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) {
22517 			WMI_LOGD("%s: buf_len is garbage 0x%x",
22518 				 __func__, ev->hdr.buf_len);
22519 			return QDF_STATUS_E_FAILURE;
22520 		}
22521 
22522 		if ((n + ev->hdr.buf_len) > datalen) {
22523 			WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d",
22524 				 __func__, n, ev->hdr.buf_len, datalen);
22525 			return QDF_STATUS_E_FAILURE;
22526 		}
22527 
22528 		phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr);
22529 		phyerr->tsf_timestamp = ev->hdr.tsf_timestamp;
22530 		phyerr->bufp = &ev->bufp[0];
22531 		phyerr->buf_len = ev->hdr.buf_len;
22532 		phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr);
22533 
22534 		/*
22535 		 * Advance the buffer pointer to the next PHY error.
22536 		 * buflen is the length of this payload, so we need to
22537 		 * advance past the current header _AND_ the payload.
22538 		 */
22539 		n += sizeof(*ev) + ev->hdr.buf_len;
22540 	}
22541 	*buf_offset = n;
22542 
22543 	return QDF_STATUS_SUCCESS;
22544 }
22545 
22546 /**
22547  * extract_esp_estimation_ev_param_tlv() - extract air time from event
22548  * @wmi_handle: wmi handle
22549  * @evt_buf: pointer to event buffer
22550  * @param: Pointer to hold esp event
22551  *
22552  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure
22553  */
22554 static QDF_STATUS
22555 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle,
22556 				    void *evt_buf,
22557 				    struct esp_estimation_event *param)
22558 {
22559 	WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf;
22560 	wmi_esp_estimate_event_fixed_param *esp_event;
22561 
22562 	param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf;
22563 	if (!param_buf) {
22564 		WMI_LOGE("Invalid ESP Estimate Event buffer");
22565 		return QDF_STATUS_E_INVAL;
22566 	}
22567 	esp_event = param_buf->fixed_param;
22568 	param->ac_airtime_percentage = esp_event->ac_airtime_percentage;
22569 	param->pdev_id = convert_target_pdev_id_to_host_pdev_id(
22570 				esp_event->pdev_id);
22571 
22572 	return QDF_STATUS_SUCCESS;
22573 }
22574 
22575 struct wmi_ops tlv_ops =  {
22576 	.send_vdev_create_cmd = send_vdev_create_cmd_tlv,
22577 	.send_vdev_delete_cmd = send_vdev_delete_cmd_tlv,
22578 	.send_vdev_down_cmd = send_vdev_down_cmd_tlv,
22579 	.send_vdev_start_cmd = send_vdev_start_cmd_tlv,
22580 	.send_hidden_ssid_vdev_restart_cmd =
22581 		send_hidden_ssid_vdev_restart_cmd_tlv,
22582 	.send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv,
22583 	.send_peer_param_cmd = send_peer_param_cmd_tlv,
22584 	.send_vdev_up_cmd = send_vdev_up_cmd_tlv,
22585 	.send_vdev_stop_cmd = send_vdev_stop_cmd_tlv,
22586 	.send_peer_create_cmd = send_peer_create_cmd_tlv,
22587 	.send_peer_delete_cmd = send_peer_delete_cmd_tlv,
22588 	.send_peer_rx_reorder_queue_setup_cmd =
22589 		send_peer_rx_reorder_queue_setup_cmd_tlv,
22590 	.send_peer_rx_reorder_queue_remove_cmd =
22591 		send_peer_rx_reorder_queue_remove_cmd_tlv,
22592 	.send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv,
22593 	.send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv,
22594 	.send_peer_update_wds_entry_cmd = send_peer_update_wds_entry_cmd_tlv,
22595 	.send_pdev_utf_cmd = send_pdev_utf_cmd_tlv,
22596 	.send_pdev_param_cmd = send_pdev_param_cmd_tlv,
22597 	.send_pdev_get_tpc_config_cmd = send_pdev_get_tpc_config_cmd_tlv,
22598 	.send_suspend_cmd = send_suspend_cmd_tlv,
22599 	.send_resume_cmd = send_resume_cmd_tlv,
22600 #ifdef FEATURE_WLAN_D0WOW
22601 	.send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv,
22602 	.send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv,
22603 #endif
22604 	.send_wow_enable_cmd = send_wow_enable_cmd_tlv,
22605 	.send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv,
22606 	.send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv,
22607 	.send_crash_inject_cmd = send_crash_inject_cmd_tlv,
22608 #ifdef FEATURE_FW_LOG_PARSING
22609 	.send_dbglog_cmd = send_dbglog_cmd_tlv,
22610 #endif
22611 	.send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv,
22612 	.send_stats_request_cmd = send_stats_request_cmd_tlv,
22613 	.send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv,
22614 	.send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv,
22615 	.send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv,
22616 	.send_beacon_send_cmd = send_beacon_send_cmd_tlv,
22617 	.send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv,
22618 	.send_peer_assoc_cmd = send_peer_assoc_cmd_tlv,
22619 	.send_scan_start_cmd = send_scan_start_cmd_tlv,
22620 	.send_scan_stop_cmd = send_scan_stop_cmd_tlv,
22621 	.send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv,
22622 	.send_mgmt_cmd = send_mgmt_cmd_tlv,
22623 	.send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv,
22624 	.send_modem_power_state_cmd = send_modem_power_state_cmd_tlv,
22625 	.send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv,
22626 	.send_set_sta_uapsd_auto_trig_cmd =
22627 		send_set_sta_uapsd_auto_trig_cmd_tlv,
22628 	.send_get_temperature_cmd = send_get_temperature_cmd_tlv,
22629 	.send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv,
22630 	.send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv,
22631 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
22632 	.send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv,
22633 	.send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv,
22634 #endif
22635 	.send_set_smps_params_cmd = send_set_smps_params_cmd_tlv,
22636 	.send_set_mimops_cmd = send_set_mimops_cmd_tlv,
22637 #ifdef WLAN_FEATURE_DSRC
22638 	.send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv,
22639 	.send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv,
22640 	.send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv,
22641 	.send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv,
22642 	.send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv,
22643 	.send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv,
22644 	.send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv,
22645 	.send_ocb_start_timing_advert_cmd =
22646 		send_ocb_start_timing_advert_cmd_tlv,
22647 	.extract_ocb_chan_config_resp = extract_ocb_channel_config_resp_tlv,
22648 	.extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv,
22649 	.extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv,
22650 	.extract_dcc_stats = extract_ocb_dcc_stats_tlv,
22651 #endif
22652 	.send_set_enable_disable_mcc_adaptive_scheduler_cmd =
22653 		 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv,
22654 	.send_set_mcc_channel_time_latency_cmd =
22655 			 send_set_mcc_channel_time_latency_cmd_tlv,
22656 	.send_set_mcc_channel_time_quota_cmd =
22657 			 send_set_mcc_channel_time_quota_cmd_tlv,
22658 	.send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv,
22659 	.send_lro_config_cmd = send_lro_config_cmd_tlv,
22660 	.send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv,
22661 	.send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv,
22662 	.send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv,
22663 	.send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv,
22664 	.send_probe_rsp_tmpl_send_cmd =
22665 				send_probe_rsp_tmpl_send_cmd_tlv,
22666 	.send_p2p_go_set_beacon_ie_cmd =
22667 				send_p2p_go_set_beacon_ie_cmd_tlv,
22668 	.send_setup_install_key_cmd =
22669 				send_setup_install_key_cmd_tlv,
22670 	.send_set_gateway_params_cmd =
22671 				send_set_gateway_params_cmd_tlv,
22672 	.send_set_rssi_monitoring_cmd =
22673 			 send_set_rssi_monitoring_cmd_tlv,
22674 	.send_scan_probe_setoui_cmd =
22675 				send_scan_probe_setoui_cmd_tlv,
22676 	.send_roam_scan_offload_rssi_thresh_cmd =
22677 			send_roam_scan_offload_rssi_thresh_cmd_tlv,
22678 	.send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv,
22679 	.send_roam_scan_filter_cmd =
22680 			send_roam_scan_filter_cmd_tlv,
22681 #ifdef IPA_OFFLOAD
22682 	.send_ipa_offload_control_cmd =
22683 			 send_ipa_offload_control_cmd_tlv,
22684 #endif
22685 	.send_plm_stop_cmd = send_plm_stop_cmd_tlv,
22686 	.send_plm_start_cmd = send_plm_start_cmd_tlv,
22687 	.send_pno_stop_cmd = send_pno_stop_cmd_tlv,
22688 	.send_pno_start_cmd = send_pno_start_cmd_tlv,
22689 	.send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv,
22690 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
22691 	.send_set_ric_req_cmd = send_set_ric_req_cmd_tlv,
22692 	.send_process_roam_synch_complete_cmd =
22693 		 send_process_roam_synch_complete_cmd_tlv,
22694 #endif
22695 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
22696 	.send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv,
22697 	.send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv,
22698 	.send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv,
22699 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/
22700 	.send_congestion_cmd = send_congestion_cmd_tlv,
22701 	.send_snr_request_cmd = send_snr_request_cmd_tlv,
22702 	.send_snr_cmd = send_snr_cmd_tlv,
22703 	.send_link_status_req_cmd = send_link_status_req_cmd_tlv,
22704 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
22705 	.send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv,
22706 	.send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv,
22707 	.send_enable_arp_ns_offload_cmd = send_enable_arp_ns_offload_cmd_tlv,
22708 	.send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv,
22709 	.send_multiple_add_clear_mcbc_filter_cmd =
22710 		send_multiple_add_clear_mcbc_filter_cmd_tlv,
22711 	.send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv,
22712 	.send_gtk_offload_cmd = send_gtk_offload_cmd_tlv,
22713 	.send_process_gtk_offload_getinfo_cmd =
22714 		send_process_gtk_offload_getinfo_cmd_tlv,
22715 	.send_enable_enhance_multicast_offload_cmd =
22716 		send_enable_enhance_multicast_offload_tlv,
22717 	.extract_gtk_rsp_event = extract_gtk_rsp_event_tlv,
22718 #ifdef FEATURE_WLAN_RA_FILTERING
22719 	.send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv,
22720 #endif
22721 	.send_action_frame_patterns_cmd = send_action_frame_patterns_cmd_tlv,
22722 	.send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv,
22723 	.send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv,
22724 	.send_lphb_config_tcp_pkt_filter_cmd =
22725 		send_lphb_config_tcp_pkt_filter_cmd_tlv,
22726 	.send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv,
22727 	.send_lphb_config_udp_pkt_filter_cmd =
22728 		send_lphb_config_udp_pkt_filter_cmd_tlv,
22729 #ifdef WLAN_FEATURE_PACKET_FILTERING
22730 	.send_enable_disable_packet_filter_cmd =
22731 		send_enable_disable_packet_filter_cmd_tlv,
22732 	.send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv,
22733 #endif
22734 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */
22735 #ifdef CONFIG_MCL
22736 	.send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv,
22737 	.send_get_link_speed_cmd = send_get_link_speed_cmd_tlv,
22738 	.send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv,
22739 	.send_roam_scan_offload_mode_cmd =
22740 			send_roam_scan_offload_mode_cmd_tlv,
22741 #ifndef REMOVE_PKT_LOG
22742 	.send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv,
22743 #endif
22744 	.send_roam_scan_offload_ap_profile_cmd =
22745 			send_roam_scan_offload_ap_profile_cmd_tlv,
22746 #endif
22747 #ifdef WLAN_SUPPORT_GREEN_AP
22748 	.send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv,
22749 	.send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv,
22750 	.extract_green_ap_egap_status_info =
22751 			extract_green_ap_egap_status_info_tlv,
22752 #endif
22753 	.send_fw_profiling_cmd = send_fw_profiling_cmd_tlv,
22754 	.send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv,
22755 	.send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv,
22756 	.send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv,
22757 	.send_start_oem_data_cmd = send_start_oem_data_cmd_tlv,
22758 #ifdef WLAN_FEATURE_CIF_CFR
22759 	.send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv,
22760 #endif
22761 	.send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv,
22762 	.send_dfs_phyerr_filter_offload_en_cmd =
22763 		 send_dfs_phyerr_filter_offload_en_cmd_tlv,
22764 	.send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv,
22765 	.send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv,
22766 	.send_del_ts_cmd = send_del_ts_cmd_tlv,
22767 	.send_aggr_qos_cmd = send_aggr_qos_cmd_tlv,
22768 	.send_add_ts_cmd = send_add_ts_cmd_tlv,
22769 	.send_process_add_periodic_tx_ptrn_cmd =
22770 		send_process_add_periodic_tx_ptrn_cmd_tlv,
22771 	.send_process_del_periodic_tx_ptrn_cmd =
22772 		send_process_del_periodic_tx_ptrn_cmd_tlv,
22773 	.send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv,
22774 	.send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv,
22775 	.send_set_app_type2_params_in_fw_cmd =
22776 		send_set_app_type2_params_in_fw_cmd_tlv,
22777 	.send_set_auto_shutdown_timer_cmd =
22778 		send_set_auto_shutdown_timer_cmd_tlv,
22779 	.send_nan_req_cmd = send_nan_req_cmd_tlv,
22780 	.send_process_dhcpserver_offload_cmd =
22781 		send_process_dhcpserver_offload_cmd_tlv,
22782 	.send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv,
22783 	.send_process_ch_avoid_update_cmd =
22784 		send_process_ch_avoid_update_cmd_tlv,
22785 	.send_pdev_set_regdomain_cmd =
22786 				send_pdev_set_regdomain_cmd_tlv,
22787 	.send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv,
22788 	.send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv,
22789 	.send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv,
22790 	.send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv,
22791 	.send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv,
22792 	.save_fw_version_cmd = save_fw_version_cmd_tlv,
22793 	.check_and_update_fw_version =
22794 		 check_and_update_fw_version_cmd_tlv,
22795 	.send_set_base_macaddr_indicate_cmd =
22796 		 send_set_base_macaddr_indicate_cmd_tlv,
22797 	.send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv,
22798 	.send_enable_specific_fw_logs_cmd =
22799 		 send_enable_specific_fw_logs_cmd_tlv,
22800 	.send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv,
22801 	.send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv,
22802 	.send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv,
22803 #ifdef WLAN_POLICY_MGR_ENABLE
22804 	.send_pdev_set_dual_mac_config_cmd =
22805 		 send_pdev_set_dual_mac_config_cmd_tlv,
22806 #endif
22807 	.send_app_type1_params_in_fw_cmd =
22808 		 send_app_type1_params_in_fw_cmd_tlv,
22809 	.send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv,
22810 	.send_unit_test_cmd = send_unit_test_cmd_tlv,
22811 	.send_roam_invoke_cmd = send_roam_invoke_cmd_tlv,
22812 	.send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv,
22813 	.send_roam_scan_offload_scan_period_cmd =
22814 		 send_roam_scan_offload_scan_period_cmd_tlv,
22815 	.send_roam_scan_offload_chan_list_cmd =
22816 		 send_roam_scan_offload_chan_list_cmd_tlv,
22817 	.send_roam_scan_offload_rssi_change_cmd =
22818 		 send_roam_scan_offload_rssi_change_cmd_tlv,
22819 #ifdef FEATURE_WLAN_APF
22820 	.send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv,
22821 	.send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv,
22822 	.send_apf_write_work_memory_cmd =
22823 				wmi_send_apf_write_work_memory_cmd_tlv,
22824 	.send_apf_read_work_memory_cmd =
22825 				wmi_send_apf_read_work_memory_cmd_tlv,
22826 	.extract_apf_read_memory_resp_event =
22827 				wmi_extract_apf_read_memory_resp_event_tlv,
22828 #endif /* FEATURE_WLAN_APF */
22829 	.send_adapt_dwelltime_params_cmd =
22830 		send_adapt_dwelltime_params_cmd_tlv,
22831 	.send_dbs_scan_sel_params_cmd =
22832 		send_dbs_scan_sel_params_cmd_tlv,
22833 	.init_cmd_send = init_cmd_send_tlv,
22834 	.send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv,
22835 	.send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv,
22836 	.send_set_ctl_table_cmd = send_set_ctl_table_cmd_tlv,
22837 	.send_set_mimogain_table_cmd = send_set_mimogain_table_cmd_tlv,
22838 	.send_packet_power_info_get_cmd = send_packet_power_info_get_cmd_tlv,
22839 	.send_vdev_config_ratemask_cmd = send_vdev_config_ratemask_cmd_tlv,
22840 	.send_vdev_set_custom_aggr_size_cmd =
22841 		send_vdev_set_custom_aggr_size_cmd_tlv,
22842 	.send_vdev_set_qdepth_thresh_cmd =
22843 		send_vdev_set_qdepth_thresh_cmd_tlv,
22844 	.send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv,
22845 	.send_vdev_set_neighbour_rx_cmd = send_vdev_set_neighbour_rx_cmd_tlv,
22846 	.send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_tlv,
22847 	.send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_tlv,
22848 	.send_smart_ant_set_training_info_cmd =
22849 		send_smart_ant_set_training_info_cmd_tlv,
22850 	.send_smart_ant_set_node_config_cmd =
22851 		send_smart_ant_set_node_config_cmd_tlv,
22852 #ifdef WLAN_ATF_ENABLE
22853 	.send_set_atf_cmd = send_set_atf_cmd_tlv,
22854 #endif
22855 	.send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv,
22856 	.send_set_qboost_param_cmd = send_set_qboost_param_cmd_tlv,
22857 	.send_gpio_config_cmd = send_gpio_config_cmd_tlv,
22858 	.send_gpio_output_cmd = send_gpio_output_cmd_tlv,
22859 	.send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv,
22860 	.send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv,
22861 	.send_periodic_chan_stats_config_cmd =
22862 		send_periodic_chan_stats_config_cmd_tlv,
22863 	.send_nf_dbr_dbm_info_get_cmd = send_nf_dbr_dbm_info_get_cmd_tlv,
22864 	.send_set_ht_ie_cmd = send_set_ht_ie_cmd_tlv,
22865 	.send_set_vht_ie_cmd = send_set_vht_ie_cmd_tlv,
22866 	.send_set_quiet_mode_cmd = send_set_quiet_mode_cmd_tlv,
22867 	.send_set_bwf_cmd = send_set_bwf_cmd_tlv,
22868 	.send_mcast_group_update_cmd = send_mcast_group_update_cmd_tlv,
22869 	.send_vdev_spectral_configure_cmd =
22870 				send_vdev_spectral_configure_cmd_tlv,
22871 	.send_vdev_spectral_enable_cmd =
22872 				send_vdev_spectral_enable_cmd_tlv,
22873 	.send_thermal_mitigation_param_cmd =
22874 		send_thermal_mitigation_param_cmd_tlv,
22875 	.send_pdev_qvit_cmd = send_pdev_qvit_cmd_tlv,
22876 	.send_wmm_update_cmd = send_wmm_update_cmd_tlv,
22877 	.send_process_update_edca_param_cmd =
22878 				 send_process_update_edca_param_cmd_tlv,
22879 	.send_coex_config_cmd = send_coex_config_cmd_tlv,
22880 	.send_set_country_cmd = send_set_country_cmd_tlv,
22881 	.send_bcn_offload_control_cmd = send_bcn_offload_control_cmd_tlv,
22882 	.send_addba_send_cmd = send_addba_send_cmd_tlv,
22883 	.send_delba_send_cmd = send_delba_send_cmd_tlv,
22884 	.send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv,
22885 	.get_target_cap_from_service_ready = extract_service_ready_tlv,
22886 	.extract_hal_reg_cap = extract_hal_reg_cap_tlv,
22887 	.extract_host_mem_req = extract_host_mem_req_tlv,
22888 	.save_service_bitmap = save_service_bitmap_tlv,
22889 	.save_ext_service_bitmap = save_ext_service_bitmap_tlv,
22890 	.is_service_enabled = is_service_enabled_tlv,
22891 	.save_fw_version = save_fw_version_in_service_ready_tlv,
22892 	.ready_extract_init_status = ready_extract_init_status_tlv,
22893 	.ready_extract_mac_addr = ready_extract_mac_addr_tlv,
22894 	.ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv,
22895 	.extract_ready_event_params = extract_ready_event_params_tlv,
22896 	.extract_dbglog_data_len = extract_dbglog_data_len_tlv,
22897 	.extract_vdev_start_resp = extract_vdev_start_resp_tlv,
22898 	.extract_vdev_delete_resp = extract_vdev_delete_resp_tlv,
22899 	.extract_tbttoffset_update_params =
22900 				extract_tbttoffset_update_params_tlv,
22901 	.extract_ext_tbttoffset_update_params =
22902 				extract_ext_tbttoffset_update_params_tlv,
22903 	.extract_tbttoffset_num_vdevs =
22904 				extract_tbttoffset_num_vdevs_tlv,
22905 	.extract_ext_tbttoffset_num_vdevs =
22906 				extract_ext_tbttoffset_num_vdevs_tlv,
22907 	.extract_mgmt_rx_params = extract_mgmt_rx_params_tlv,
22908 	.extract_vdev_stopped_param = extract_vdev_stopped_param_tlv,
22909 	.extract_vdev_roam_param = extract_vdev_roam_param_tlv,
22910 	.extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv,
22911 #ifdef CONVERGED_TDLS_ENABLE
22912 	.extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv,
22913 #endif
22914 	.extract_mgmt_tx_compl_param = extract_mgmt_tx_compl_param_tlv,
22915 	.extract_swba_num_vdevs = extract_swba_num_vdevs_tlv,
22916 	.extract_swba_tim_info = extract_swba_tim_info_tlv,
22917 	.extract_swba_noa_info = extract_swba_noa_info_tlv,
22918 #ifdef CONVERGED_P2P_ENABLE
22919 	.extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv,
22920 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
22921 	.extract_p2p_lo_stop_ev_param =
22922 				extract_p2p_lo_stop_ev_param_tlv,
22923 #endif
22924 #endif
22925 	.extract_offchan_data_tx_compl_param =
22926 				extract_offchan_data_tx_compl_param_tlv,
22927 	.extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv,
22928 	.extract_all_stats_count = extract_all_stats_counts_tlv,
22929 	.extract_pdev_stats = extract_pdev_stats_tlv,
22930 	.extract_unit_test = extract_unit_test_tlv,
22931 	.extract_pdev_ext_stats = extract_pdev_ext_stats_tlv,
22932 	.extract_vdev_stats = extract_vdev_stats_tlv,
22933 	.extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv,
22934 	.extract_peer_stats = extract_peer_stats_tlv,
22935 	.extract_bcn_stats = extract_bcn_stats_tlv,
22936 	.extract_bcnflt_stats = extract_bcnflt_stats_tlv,
22937 	.extract_peer_extd_stats = extract_peer_extd_stats_tlv,
22938 	.extract_chan_stats = extract_chan_stats_tlv,
22939 	.extract_profile_ctx = extract_profile_ctx_tlv,
22940 	.extract_profile_data = extract_profile_data_tlv,
22941 	.extract_chan_info_event = extract_chan_info_event_tlv,
22942 	.extract_channel_hopping_event = extract_channel_hopping_event_tlv,
22943 	.send_fw_test_cmd = send_fw_test_cmd_tlv,
22944 #ifdef WLAN_FEATURE_DISA
22945 	.send_encrypt_decrypt_send_cmd =
22946 				send_encrypt_decrypt_send_cmd_tlv,
22947 	.extract_encrypt_decrypt_resp_event =
22948 				extract_encrypt_decrypt_resp_event_tlv,
22949 #endif
22950 	.send_sar_limit_cmd = send_sar_limit_cmd_tlv,
22951 	.get_sar_limit_cmd = get_sar_limit_cmd_tlv,
22952 	.extract_sar_limit_event = extract_sar_limit_event_tlv,
22953 	.extract_sar2_result_event = extract_sar2_result_event_tlv,
22954 	.send_power_dbg_cmd = send_power_dbg_cmd_tlv,
22955 	.send_multiple_vdev_restart_req_cmd =
22956 				send_multiple_vdev_restart_req_cmd_tlv,
22957 	.extract_service_ready_ext = extract_service_ready_ext_tlv,
22958 	.extract_hw_mode_cap_service_ready_ext =
22959 				extract_hw_mode_cap_service_ready_ext_tlv,
22960 	.extract_mac_phy_cap_service_ready_ext =
22961 				extract_mac_phy_cap_service_ready_ext_tlv,
22962 	.extract_reg_cap_service_ready_ext =
22963 				extract_reg_cap_service_ready_ext_tlv,
22964 	.extract_dbr_ring_cap_service_ready_ext =
22965 				extract_dbr_ring_cap_service_ready_ext_tlv,
22966 	.extract_sar_cap_service_ready_ext =
22967 				extract_sar_cap_service_ready_ext_tlv,
22968 	.extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv,
22969 	.extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv,
22970 	.extract_dbr_buf_metadata = extract_dbr_buf_metadata_tlv,
22971 	.extract_pdev_utf_event = extract_pdev_utf_event_tlv,
22972 	.wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv,
22973 	.extract_dcs_interference_type = extract_dcs_interference_type_tlv,
22974 	.extract_dcs_cw_int = extract_dcs_cw_int_tlv,
22975 	.extract_dcs_im_tgt_stats = extract_dcs_im_tgt_stats_tlv,
22976 	.extract_fips_event_data = extract_fips_event_data_tlv,
22977 	.send_pdev_fips_cmd = send_pdev_fips_cmd_tlv,
22978 	.extract_peer_delete_response_event =
22979 				extract_peer_delete_response_event_tlv,
22980 	.is_management_record = is_management_record_tlv,
22981 	.is_diag_event = is_diag_event_tlv,
22982 	.extract_pdev_csa_switch_count_status =
22983 				extract_pdev_csa_switch_count_status_tlv,
22984 	.extract_pdev_tpc_ev_param = extract_pdev_tpc_ev_param_tlv,
22985 	.extract_pdev_tpc_config_ev_param =
22986 			extract_pdev_tpc_config_ev_param_tlv,
22987 	.extract_nfcal_power_ev_param = extract_nfcal_power_ev_param_tlv,
22988 	.extract_wds_addr_event = extract_wds_addr_event_tlv,
22989 	.extract_peer_sta_ps_statechange_ev =
22990 		extract_peer_sta_ps_statechange_ev_tlv,
22991 	.extract_inst_rssi_stats_event = extract_inst_rssi_stats_event_tlv,
22992 	.send_per_roam_config_cmd = send_per_roam_config_cmd_tlv,
22993 #ifdef WLAN_FEATURE_ACTION_OUI
22994 	.send_action_oui_cmd = send_action_oui_cmd_tlv,
22995 #endif
22996 	.send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv,
22997 	.send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv,
22998 	.extract_reg_chan_list_update_event =
22999 		extract_reg_chan_list_update_event_tlv,
23000 	.extract_chainmask_tables =
23001 		extract_chainmask_tables_tlv,
23002 	.extract_thermal_stats = extract_thermal_stats_tlv,
23003 	.extract_thermal_level_stats = extract_thermal_level_stats_tlv,
23004 	.send_get_rcpi_cmd = send_get_rcpi_cmd_tlv,
23005 	.extract_rcpi_response_event = extract_rcpi_response_event_tlv,
23006 #ifdef DFS_COMPONENT_ENABLE
23007 	.extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv,
23008 	.extract_dfs_radar_detection_event =
23009 		extract_dfs_radar_detection_event_tlv,
23010 	.extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv,
23011 #endif
23012 	.convert_pdev_id_host_to_target =
23013 		convert_host_pdev_id_to_target_pdev_id_legacy,
23014 	.convert_pdev_id_target_to_host =
23015 		convert_target_pdev_id_to_host_pdev_id_legacy,
23016 
23017 	.send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv,
23018 	.send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv,
23019 	.extract_reg_11d_new_country_event =
23020 		extract_reg_11d_new_country_event_tlv,
23021 	.send_user_country_code_cmd = send_user_country_code_cmd_tlv,
23022 	.send_limit_off_chan_cmd =
23023 		send_limit_off_chan_cmd_tlv,
23024 	.extract_reg_ch_avoid_event =
23025 		extract_reg_ch_avoid_event_tlv,
23026 	.send_pdev_caldata_version_check_cmd =
23027 			send_pdev_caldata_version_check_cmd_tlv,
23028 	.extract_pdev_caldata_version_check_ev_param =
23029 			extract_pdev_caldata_version_check_ev_param_tlv,
23030 	.send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv,
23031 	.send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv,
23032 	.send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv,
23033 #if defined(WLAN_FEATURE_FILS_SK)
23034 	.send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv,
23035 #endif
23036 	.send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv,
23037 #ifdef WLAN_FEATURE_NAN_CONVERGENCE
23038 	.send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv,
23039 	.send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv,
23040 	.send_ndp_end_req_cmd = nan_ndp_end_req_tlv,
23041 	.extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv,
23042 	.extract_ndp_ind = extract_ndp_ind_tlv,
23043 	.extract_ndp_confirm = extract_ndp_confirm_tlv,
23044 	.extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv,
23045 	.extract_ndp_end_rsp = extract_ndp_end_rsp_tlv,
23046 	.extract_ndp_end_ind = extract_ndp_end_ind_tlv,
23047 	.extract_ndp_sch_update = extract_ndp_sch_update_tlv,
23048 #endif
23049 	.send_btm_config = send_btm_config_cmd_tlv,
23050 	.send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv,
23051 	.extract_obss_detection_info = extract_obss_detection_info_tlv,
23052 #ifdef WLAN_SUPPORT_FILS
23053 	.send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_tlv,
23054 	.extract_swfda_vdev_id = extract_swfda_vdev_id_tlv,
23055 	.send_fils_discovery_send_cmd = send_fils_discovery_send_cmd_tlv,
23056 #endif /* WLAN_SUPPORT_FILS */
23057 	.send_offload_11k_cmd = send_offload_11k_cmd_tlv,
23058 	.send_invoke_neighbor_report_cmd = send_invoke_neighbor_report_cmd_tlv,
23059 	.wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable,
23060 	.wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs,
23061 	.wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs,
23062 	.wmi_check_command_params = wmitlv_check_command_tlv_params,
23063 	.send_bss_color_change_enable_cmd =
23064 		send_bss_color_change_enable_cmd_tlv,
23065 	.send_obss_color_collision_cfg_cmd =
23066 		send_obss_color_collision_cfg_cmd_tlv,
23067 	.extract_obss_color_collision_info =
23068 		extract_obss_color_collision_info_tlv,
23069 	.extract_comb_phyerr = extract_comb_phyerr_tlv,
23070 	.extract_single_phyerr = extract_single_phyerr_tlv,
23071 #ifdef QCA_SUPPORT_CP_STATS
23072 	.extract_cca_stats = extract_cca_stats_tlv,
23073 #endif
23074 	.extract_esp_estimation_ev_param =
23075 				extract_esp_estimation_ev_param_tlv,
23076 	.send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv,
23077 	.extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv,
23078 #ifdef OBSS_PD
23079 	.send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv,
23080 #endif
23081 };
23082 
23083 /**
23084  * populate_tlv_event_id() - populates wmi event ids
23085  *
23086  * @param event_ids: Pointer to hold event ids
23087  * Return: None
23088  */
23089 static void populate_tlv_events_id(uint32_t *event_ids)
23090 {
23091 	event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID;
23092 	event_ids[wmi_ready_event_id] = WMI_READY_EVENTID;
23093 	event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID;
23094 	event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID;
23095 	event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID;
23096 	event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID;
23097 	event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID;
23098 	event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID;
23099 	event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID;
23100 	event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID;
23101 	event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID;
23102 	event_ids[wmi_service_ready_ext_event_id] =
23103 						WMI_SERVICE_READY_EXT_EVENTID;
23104 	event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID;
23105 	event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID;
23106 	event_ids[wmi_vdev_install_key_complete_event_id] =
23107 				WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID;
23108 	event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] =
23109 				WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID;
23110 
23111 	event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID;
23112 	event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID;
23113 	event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID;
23114 	event_ids[wmi_peer_tx_fail_cnt_thr_event_id] =
23115 				WMI_PEER_TX_FAIL_CNT_THR_EVENTID;
23116 	event_ids[wmi_peer_estimated_linkspeed_event_id] =
23117 				WMI_PEER_ESTIMATED_LINKSPEED_EVENTID;
23118 	event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID;
23119 	event_ids[wmi_peer_delete_response_event_id] =
23120 					WMI_PEER_DELETE_RESP_EVENTID;
23121 	event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID;
23122 	event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID;
23123 	event_ids[wmi_tbttoffset_update_event_id] =
23124 					WMI_TBTTOFFSET_UPDATE_EVENTID;
23125 	event_ids[wmi_ext_tbttoffset_update_event_id] =
23126 					WMI_TBTTOFFSET_EXT_UPDATE_EVENTID;
23127 	event_ids[wmi_offload_bcn_tx_status_event_id] =
23128 				WMI_OFFLOAD_BCN_TX_STATUS_EVENTID;
23129 	event_ids[wmi_offload_prob_resp_tx_status_event_id] =
23130 				WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID;
23131 	event_ids[wmi_mgmt_tx_completion_event_id] =
23132 				WMI_MGMT_TX_COMPLETION_EVENTID;
23133 	event_ids[wmi_pdev_nfcal_power_all_channels_event_id] =
23134 				WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID;
23135 	event_ids[wmi_tx_delba_complete_event_id] =
23136 					WMI_TX_DELBA_COMPLETE_EVENTID;
23137 	event_ids[wmi_tx_addba_complete_event_id] =
23138 					WMI_TX_ADDBA_COMPLETE_EVENTID;
23139 	event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID;
23140 
23141 	event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID;
23142 
23143 	event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID;
23144 	event_ids[wmi_profile_match] = WMI_PROFILE_MATCH;
23145 
23146 	event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID;
23147 	event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID;
23148 
23149 	event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID;
23150 
23151 	event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID;
23152 	event_ids[wmi_p2p_lo_stop_event_id] =
23153 				WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID;
23154 	event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID;
23155 	event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID;
23156 	event_ids[wmi_d0_wow_disable_ack_event_id] =
23157 				WMI_D0_WOW_DISABLE_ACK_EVENTID;
23158 	event_ids[wmi_wow_initial_wakeup_event_id] =
23159 				WMI_WOW_INITIAL_WAKEUP_EVENTID;
23160 
23161 	event_ids[wmi_rtt_meas_report_event_id] =
23162 				WMI_RTT_MEASUREMENT_REPORT_EVENTID;
23163 	event_ids[wmi_tsf_meas_report_event_id] =
23164 				WMI_TSF_MEASUREMENT_REPORT_EVENTID;
23165 	event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID;
23166 	event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID;
23167 	event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID;
23168 	event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID;
23169 	event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID;
23170 	event_ids[wmi_diag_event_id_log_supported_event_id] =
23171 				WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID;
23172 	event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID;
23173 	event_ids[wmi_nlo_scan_complete_event_id] =
23174 					WMI_NLO_SCAN_COMPLETE_EVENTID;
23175 	event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID;
23176 	event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID;
23177 
23178 	event_ids[wmi_gtk_offload_status_event_id] =
23179 				WMI_GTK_OFFLOAD_STATUS_EVENTID;
23180 	event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID;
23181 	event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID;
23182 	event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID;
23183 
23184 	event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID;
23185 
23186 	event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID;
23187 
23188 	event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID;
23189 	event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID;
23190 	event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID;
23191 	event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID;
23192 	event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID;
23193 	event_ids[wmi_wlan_profile_data_event_id] =
23194 						WMI_WLAN_PROFILE_DATA_EVENTID;
23195 	event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID;
23196 	event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID;
23197 	event_ids[wmi_vdev_get_keepalive_event_id] =
23198 				WMI_VDEV_GET_KEEPALIVE_EVENTID;
23199 	event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID;
23200 
23201 	event_ids[wmi_diag_container_event_id] =
23202 						WMI_DIAG_DATA_CONTAINER_EVENTID;
23203 
23204 	event_ids[wmi_host_auto_shutdown_event_id] =
23205 				WMI_HOST_AUTO_SHUTDOWN_EVENTID;
23206 
23207 	event_ids[wmi_update_whal_mib_stats_event_id] =
23208 				WMI_UPDATE_WHAL_MIB_STATS_EVENTID;
23209 
23210 	/*update ht/vht info based on vdev (rx and tx NSS and preamble) */
23211 	event_ids[wmi_update_vdev_rate_stats_event_id] =
23212 				WMI_UPDATE_VDEV_RATE_STATS_EVENTID;
23213 
23214 	event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID;
23215 	event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID;
23216 
23217 	/** Set OCB Sched Response, deprecated */
23218 	event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID;
23219 
23220 	event_ids[wmi_dbg_mesg_flush_complete_event_id] =
23221 				WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID;
23222 	event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID;
23223 
23224 	/* GPIO Event */
23225 	event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID;
23226 	event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID;
23227 
23228 	event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID;
23229 	event_ids[wmi_rfkill_state_change_event_id] =
23230 				WMI_RFKILL_STATE_CHANGE_EVENTID;
23231 
23232 	/* TDLS Event */
23233 	event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID;
23234 
23235 	event_ids[wmi_batch_scan_enabled_event_id] =
23236 				WMI_BATCH_SCAN_ENABLED_EVENTID;
23237 	event_ids[wmi_batch_scan_result_event_id] =
23238 				WMI_BATCH_SCAN_RESULT_EVENTID;
23239 	/* OEM Event */
23240 	event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID;
23241 	event_ids[wmi_oem_meas_report_event_id] =
23242 				WMI_OEM_MEASUREMENT_REPORT_EVENTID;
23243 	event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID;
23244 
23245 	/* NAN Event */
23246 	event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID;
23247 
23248 	/* LPI Event */
23249 	event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID;
23250 	event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID;
23251 	event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID;
23252 
23253 	/* ExtScan events */
23254 	event_ids[wmi_extscan_start_stop_event_id] =
23255 				WMI_EXTSCAN_START_STOP_EVENTID;
23256 	event_ids[wmi_extscan_operation_event_id] =
23257 				WMI_EXTSCAN_OPERATION_EVENTID;
23258 	event_ids[wmi_extscan_table_usage_event_id] =
23259 				WMI_EXTSCAN_TABLE_USAGE_EVENTID;
23260 	event_ids[wmi_extscan_cached_results_event_id] =
23261 				WMI_EXTSCAN_CACHED_RESULTS_EVENTID;
23262 	event_ids[wmi_extscan_wlan_change_results_event_id] =
23263 				WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID;
23264 	event_ids[wmi_extscan_hotlist_match_event_id] =
23265 				WMI_EXTSCAN_HOTLIST_MATCH_EVENTID;
23266 	event_ids[wmi_extscan_capabilities_event_id] =
23267 				WMI_EXTSCAN_CAPABILITIES_EVENTID;
23268 	event_ids[wmi_extscan_hotlist_ssid_match_event_id] =
23269 				WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID;
23270 
23271 	/* mDNS offload events */
23272 	event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID;
23273 
23274 	/* SAP Authentication offload events */
23275 	event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID;
23276 	event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID;
23277 
23278 	/** Out-of-context-of-bss (OCB) events */
23279 	event_ids[wmi_ocb_set_config_resp_event_id] =
23280 				WMI_OCB_SET_CONFIG_RESP_EVENTID;
23281 	event_ids[wmi_ocb_get_tsf_timer_resp_event_id] =
23282 				WMI_OCB_GET_TSF_TIMER_RESP_EVENTID;
23283 	event_ids[wmi_dcc_get_stats_resp_event_id] =
23284 				WMI_DCC_GET_STATS_RESP_EVENTID;
23285 	event_ids[wmi_dcc_update_ndl_resp_event_id] =
23286 				WMI_DCC_UPDATE_NDL_RESP_EVENTID;
23287 	event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID;
23288 	/* System-On-Chip events */
23289 	event_ids[wmi_soc_set_hw_mode_resp_event_id] =
23290 				WMI_SOC_SET_HW_MODE_RESP_EVENTID;
23291 	event_ids[wmi_soc_hw_mode_transition_event_id] =
23292 				WMI_SOC_HW_MODE_TRANSITION_EVENTID;
23293 	event_ids[wmi_soc_set_dual_mac_config_resp_event_id] =
23294 				WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID;
23295 	event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID;
23296 	event_ids[wmi_pdev_csa_switch_count_status_event_id] =
23297 				WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID;
23298 	event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID;
23299 	event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID;
23300 	event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID;
23301 	event_ids[wmi_peer_sta_ps_statechg_event_id] =
23302 					WMI_PEER_STA_PS_STATECHG_EVENTID;
23303 	event_ids[wmi_pdev_channel_hopping_event_id] =
23304 					WMI_PDEV_CHANNEL_HOPPING_EVENTID;
23305 	event_ids[wmi_offchan_data_tx_completion_event] =
23306 				WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID;
23307 	event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID;
23308 	event_ids[wmi_dfs_radar_detection_event_id] =
23309 		WMI_PDEV_DFS_RADAR_DETECTION_EVENTID;
23310 	event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID;
23311 	event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID;
23312 	event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID;
23313 	event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID;
23314 	event_ids[wmi_service_available_event_id] =
23315 						WMI_SERVICE_AVAILABLE_EVENTID;
23316 	event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID;
23317 	event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID;
23318 	/* NDP events */
23319 	event_ids[wmi_ndp_initiator_rsp_event_id] =
23320 		WMI_NDP_INITIATOR_RSP_EVENTID;
23321 	event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID;
23322 	event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID;
23323 	event_ids[wmi_ndp_responder_rsp_event_id] =
23324 		WMI_NDP_RESPONDER_RSP_EVENTID;
23325 	event_ids[wmi_ndp_end_indication_event_id] =
23326 		WMI_NDP_END_INDICATION_EVENTID;
23327 	event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID;
23328 	event_ids[wmi_ndl_schedule_update_event_id] =
23329 					WMI_NDL_SCHEDULE_UPDATE_EVENTID;
23330 
23331 	event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID;
23332 	event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID;
23333 	event_ids[wmi_pdev_chip_power_stats_event_id] =
23334 		WMI_PDEV_CHIP_POWER_STATS_EVENTID;
23335 	event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID;
23336 	event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID;
23337 	event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID;
23338 	event_ids[wmi_apf_capability_info_event_id] =
23339 		WMI_BPF_CAPABILIY_INFO_EVENTID;
23340 	event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] =
23341 		WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID;
23342 	event_ids[wmi_report_rx_aggr_failure_event_id] =
23343 		WMI_REPORT_RX_AGGR_FAILURE_EVENTID;
23344 	event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] =
23345 		WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID;
23346 	event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID;
23347 	event_ids[wmi_pdev_set_hw_mode_rsp_event_id] =
23348 		WMI_PDEV_SET_HW_MODE_RESP_EVENTID;
23349 	event_ids[wmi_pdev_hw_mode_transition_event_id] =
23350 		WMI_PDEV_HW_MODE_TRANSITION_EVENTID;
23351 	event_ids[wmi_pdev_set_mac_config_resp_event_id] =
23352 		WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID;
23353 	event_ids[wmi_coex_bt_activity_event_id] =
23354 		WMI_WLAN_COEX_BT_ACTIVITY_EVENTID;
23355 	event_ids[wmi_mgmt_tx_bundle_completion_event_id] =
23356 		WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID;
23357 	event_ids[wmi_radio_tx_power_level_stats_event_id] =
23358 		WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID;
23359 	event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID;
23360 	event_ids[wmi_dma_buf_release_event_id] =
23361 					WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID;
23362 	event_ids[wmi_sap_obss_detection_report_event_id] =
23363 		WMI_SAP_OBSS_DETECTION_REPORT_EVENTID;
23364 	event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID;
23365 	event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID;
23366 	event_ids[wmi_obss_color_collision_report_event_id] =
23367 		WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID;
23368 	event_ids[wmi_pdev_div_rssi_antid_event_id] =
23369 		WMI_PDEV_DIV_RSSI_ANTID_EVENTID;
23370 	event_ids[wmi_twt_enable_complete_event_id] =
23371 		WMI_TWT_ENABLE_COMPLETE_EVENTID;
23372 	event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] =
23373 		WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID;
23374 	event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID;
23375 	event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID;
23376 	event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID;
23377 #ifdef AST_HKV1_WORKAROUND
23378 	event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID;
23379 #endif
23380 }
23381 
23382 /**
23383  * populate_tlv_service() - populates wmi services
23384  *
23385  * @param wmi_service: Pointer to hold wmi_service
23386  * Return: None
23387  */
23388 static void populate_tlv_service(uint32_t *wmi_service)
23389 {
23390 	wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD;
23391 	wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT;
23392 	wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD;
23393 	wmi_service[wmi_service_roam_scan_offload] =
23394 					WMI_SERVICE_ROAM_SCAN_OFFLOAD;
23395 	wmi_service[wmi_service_bcn_miss_offload] =
23396 					WMI_SERVICE_BCN_MISS_OFFLOAD;
23397 	wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE;
23398 	wmi_service[wmi_service_sta_advanced_pwrsave] =
23399 				WMI_SERVICE_STA_ADVANCED_PWRSAVE;
23400 	wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD;
23401 	wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS;
23402 	wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC;
23403 	wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK;
23404 	wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR;
23405 	wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER;
23406 	wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT;
23407 	wmi_service[wmi_service_wow] = WMI_SERVICE_WOW;
23408 	wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE;
23409 	wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS;
23410 	wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD;
23411 	wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO;
23412 	wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD;
23413 	wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH;
23414 	wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD;
23415 	wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER;
23416 	wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID;
23417 	wmi_service[wmi_service_packet_power_save] =
23418 					WMI_SERVICE_PACKET_POWER_SAVE;
23419 	wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG;
23420 	wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO;
23421 	wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] =
23422 				WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM;
23423 	wmi_service[wmi_sta_uapsd_basic_auto_trig] =
23424 					WMI_STA_UAPSD_BASIC_AUTO_TRIG;
23425 	wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG;
23426 	wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE;
23427 	wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP;
23428 	wmi_service[wmi_service_ap_ps_detect_out_of_sync] =
23429 				WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC;
23430 	wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX;
23431 	wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS;
23432 	wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST;
23433 	wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC;
23434 	wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS;
23435 	wmi_service[wmi_service_burst] = WMI_SERVICE_BURST;
23436 	wmi_service[wmi_service_mcc_bcn_interval_change] =
23437 				WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE;
23438 	wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS;
23439 	wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT;
23440 	wmi_service[wmi_service_filter_ipsec_natkeepalive] =
23441 				WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE;
23442 	wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB;
23443 	wmi_service[wmi_service_lte_ant_share_support] =
23444 				WMI_SERVICE_LTE_ANT_SHARE_SUPPORT;
23445 	wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN;
23446 	wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER;
23447 	wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ;
23448 	wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT;
23449 	wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC;
23450 	wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD;
23451 	wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR;
23452 	wmi_service[wmi_service_bcn_txrate_override] =
23453 				WMI_SERVICE_BCN_TXRATE_OVERRIDE;
23454 	wmi_service[wmi_service_nan] = WMI_SERVICE_NAN;
23455 	wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT;
23456 	wmi_service[wmi_service_estimate_linkspeed] =
23457 				WMI_SERVICE_ESTIMATE_LINKSPEED;
23458 	wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN;
23459 	wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN;
23460 	wmi_service[wmi_service_tdls_uapsd_buffer_sta] =
23461 				WMI_SERVICE_TDLS_UAPSD_BUFFER_STA;
23462 	wmi_service[wmi_service_tdls_uapsd_sleep_sta] =
23463 				WMI_SERVICE_TDLS_UAPSD_SLEEP_STA;
23464 	wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE;
23465 	wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS;
23466 	wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN;
23467 	wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW;
23468 	wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD;
23469 	wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD;
23470 	wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER;
23471 	wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD;
23472 	wmi_service[wmi_service_sta_rx_ipa_offload_support] =
23473 				WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT;
23474 	wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD;
23475 	wmi_service[wmi_service_sap_auth_offload] =
23476 					WMI_SERVICE_SAP_AUTH_OFFLOAD;
23477 	wmi_service[wmi_service_dual_band_simultaneous_support] =
23478 				WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT;
23479 	wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB;
23480 	wmi_service[wmi_service_ap_arpns_offload] =
23481 					WMI_SERVICE_AP_ARPNS_OFFLOAD;
23482 	wmi_service[wmi_service_per_band_chainmask_support] =
23483 				WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT;
23484 	wmi_service[wmi_service_packet_filter_offload] =
23485 				WMI_SERVICE_PACKET_FILTER_OFFLOAD;
23486 	wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT;
23487 	wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI;
23488 	wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG;
23489 	wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC;
23490 	wmi_service[wmi_service_multiple_vdev_restart] =
23491 			WMI_SERVICE_MULTIPLE_VDEV_RESTART;
23492 
23493 	wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE;
23494 	wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE;
23495 	wmi_service[wmi_service_smart_antenna_sw_support] =
23496 				WMI_SERVICE_UNAVAILABLE;
23497 	wmi_service[wmi_service_smart_antenna_hw_support] =
23498 				WMI_SERVICE_UNAVAILABLE;
23499 	wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE;
23500 	wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT;
23501 	wmi_service[wmi_service_atf] = WMI_SERVICE_ATF;
23502 	wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE;
23503 	wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE;
23504 	wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE;
23505 	wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE;
23506 	wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE;
23507 	wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE;
23508 	wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE;
23509 	wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE;
23510 	wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE;
23511 	wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE;
23512 	wmi_service[wmi_service_periodic_chan_stat_support] =
23513 			WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT;
23514 	wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE;
23515 	wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE;
23516 	wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE;
23517 	wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE;
23518 	wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE;
23519 	wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH;
23520 	wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF;
23521 	wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP;
23522 	wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD;
23523 	wmi_service[wmi_service_unified_wow_capability] =
23524 				WMI_SERVICE_UNIFIED_WOW_CAPABILITY;
23525 	wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH;
23526 	wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD;
23527 	wmi_service[wmi_service_sync_delete_cmds] =
23528 				WMI_SERVICE_SYNC_DELETE_CMDS;
23529 	wmi_service[wmi_service_ratectrl_limit_max_min_rates] =
23530 				WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES;
23531 	wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA;
23532 	wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT;
23533 	wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX;
23534 	wmi_service[wmi_service_deprecated_replace] =
23535 				WMI_SERVICE_DEPRECATED_REPLACE;
23536 	wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] =
23537 				WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE;
23538 	wmi_service[wmi_service_enhanced_mcast_filter] =
23539 				WMI_SERVICE_ENHANCED_MCAST_FILTER;
23540 	wmi_service[wmi_service_half_rate_quarter_rate_support] =
23541 				WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT;
23542 	wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER;
23543 	wmi_service[wmi_service_p2p_listen_offload_support] =
23544 				WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT;
23545 	wmi_service[wmi_service_mark_first_wakeup_packet] =
23546 				WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET;
23547 	wmi_service[wmi_service_multiple_mcast_filter_set] =
23548 				WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET;
23549 	wmi_service[wmi_service_host_managed_rx_reorder] =
23550 				WMI_SERVICE_HOST_MANAGED_RX_REORDER;
23551 	wmi_service[wmi_service_flash_rdwr_support] =
23552 				WMI_SERVICE_FLASH_RDWR_SUPPORT;
23553 	wmi_service[wmi_service_wlan_stats_report] =
23554 				WMI_SERVICE_WLAN_STATS_REPORT;
23555 	wmi_service[wmi_service_tx_msdu_id_new_partition_support] =
23556 				WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT;
23557 	wmi_service[wmi_service_dfs_phyerr_offload] =
23558 				WMI_SERVICE_DFS_PHYERR_OFFLOAD;
23559 	wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT;
23560 	wmi_service[wmi_service_fw_mem_dump_support] =
23561 				WMI_SERVICE_FW_MEM_DUMP_SUPPORT;
23562 	wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO;
23563 	wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB;
23564 	wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD;
23565 	wmi_service[wmi_service_hw_data_filtering] =
23566 				WMI_SERVICE_HW_DATA_FILTERING;
23567 	wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING;
23568 	wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI;
23569 	wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO;
23570 	wmi_service[wmi_service_extended_nss_support] =
23571 				WMI_SERVICE_EXTENDED_NSS_SUPPORT;
23572 	wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT;
23573 	wmi_service[wmi_service_bcn_offload_start_stop_support] =
23574 				WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT;
23575 	wmi_service[wmi_service_offchan_data_tid_support] =
23576 				WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT;
23577 	wmi_service[wmi_service_support_dma] =
23578 				WMI_SERVICE_SUPPORT_DIRECT_DMA;
23579 	wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE;
23580 	wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT;
23581 	wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT;
23582 	wmi_service[wmi_service_wow_wakeup_by_timer_pattern] =
23583 				WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN;
23584 	wmi_service[wmi_service_11k_neighbour_report_support] =
23585 				WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT;
23586 	wmi_service[wmi_service_ap_obss_detection_offload] =
23587 				WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD;
23588 	wmi_service[wmi_service_bss_color_offload] =
23589 				WMI_SERVICE_BSS_COLOR_OFFLOAD;
23590 	wmi_service[wmi_service_gmac_offload_support] =
23591 				WMI_SERVICE_GMAC_OFFLOAD_SUPPORT;
23592 	wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] =
23593 			WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT;
23594 	wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] =
23595 			WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT;
23596 	wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT;
23597 	wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT;
23598 	wmi_service[wmi_service_listen_interval_offload_support] =
23599 			WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT;
23600 	wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT;
23601 	wmi_service[wmi_service_obss_spatial_reuse] =
23602 			WMI_SERVICE_OBSS_SPATIAL_REUSE;
23603 
23604 }
23605 
23606 #ifndef CONFIG_MCL
23607 
23608 /**
23609  * populate_pdev_param_tlv() - populates pdev params
23610  *
23611  * @param pdev_param: Pointer to hold pdev params
23612  * Return: None
23613  */
23614 static void populate_pdev_param_tlv(uint32_t *pdev_param)
23615 {
23616 	pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK;
23617 	pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK;
23618 	pdev_param[wmi_pdev_param_txpower_limit2g] =
23619 				WMI_PDEV_PARAM_TXPOWER_LIMIT2G;
23620 	pdev_param[wmi_pdev_param_txpower_limit5g] =
23621 				WMI_PDEV_PARAM_TXPOWER_LIMIT5G;
23622 	pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE;
23623 	pdev_param[wmi_pdev_param_beacon_gen_mode] =
23624 				WMI_PDEV_PARAM_BEACON_GEN_MODE;
23625 	pdev_param[wmi_pdev_param_beacon_tx_mode] =
23626 				WMI_PDEV_PARAM_BEACON_TX_MODE;
23627 	pdev_param[wmi_pdev_param_resmgr_offchan_mode] =
23628 				WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE;
23629 	pdev_param[wmi_pdev_param_protection_mode] =
23630 				WMI_PDEV_PARAM_PROTECTION_MODE;
23631 	pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW;
23632 	pdev_param[wmi_pdev_param_non_agg_sw_retry_th] =
23633 				WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH;
23634 	pdev_param[wmi_pdev_param_agg_sw_retry_th] =
23635 				WMI_PDEV_PARAM_AGG_SW_RETRY_TH;
23636 	pdev_param[wmi_pdev_param_sta_kickout_th] =
23637 				WMI_PDEV_PARAM_STA_KICKOUT_TH;
23638 	pdev_param[wmi_pdev_param_ac_aggrsize_scaling] =
23639 				WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING;
23640 	pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE;
23641 	pdev_param[wmi_pdev_param_ltr_ac_latency_be] =
23642 				WMI_PDEV_PARAM_LTR_AC_LATENCY_BE;
23643 	pdev_param[wmi_pdev_param_ltr_ac_latency_bk] =
23644 				WMI_PDEV_PARAM_LTR_AC_LATENCY_BK;
23645 	pdev_param[wmi_pdev_param_ltr_ac_latency_vi] =
23646 				WMI_PDEV_PARAM_LTR_AC_LATENCY_VI;
23647 	pdev_param[wmi_pdev_param_ltr_ac_latency_vo] =
23648 				WMI_PDEV_PARAM_LTR_AC_LATENCY_VO;
23649 	pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] =
23650 				WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT;
23651 	pdev_param[wmi_pdev_param_ltr_sleep_override] =
23652 				WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE;
23653 	pdev_param[wmi_pdev_param_ltr_rx_override] =
23654 				WMI_PDEV_PARAM_LTR_RX_OVERRIDE;
23655 	pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] =
23656 				WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT;
23657 	pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE;
23658 	pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE;
23659 	pdev_param[wmi_pdev_param_pcielp_txbuf_flush] =
23660 				WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH;
23661 	pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] =
23662 				WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK;
23663 	pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] =
23664 				WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN;
23665 	pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] =
23666 				WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE;
23667 	pdev_param[wmi_pdev_param_pdev_stats_update_period] =
23668 				WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD;
23669 	pdev_param[wmi_pdev_param_vdev_stats_update_period] =
23670 				WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD;
23671 	pdev_param[wmi_pdev_param_peer_stats_update_period] =
23672 				WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD;
23673 	pdev_param[wmi_pdev_param_bcnflt_stats_update_period] =
23674 				WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD;
23675 	pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS;
23676 	pdev_param[wmi_pdev_param_arp_ac_override] =
23677 				WMI_PDEV_PARAM_ARP_AC_OVERRIDE;
23678 	pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS;
23679 	pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE;
23680 	pdev_param[wmi_pdev_param_ani_poll_period] =
23681 				WMI_PDEV_PARAM_ANI_POLL_PERIOD;
23682 	pdev_param[wmi_pdev_param_ani_listen_period] =
23683 				WMI_PDEV_PARAM_ANI_LISTEN_PERIOD;
23684 	pdev_param[wmi_pdev_param_ani_ofdm_level] =
23685 				WMI_PDEV_PARAM_ANI_OFDM_LEVEL;
23686 	pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL;
23687 	pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN;
23688 	pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA;
23689 	pdev_param[wmi_pdev_param_idle_ps_config] =
23690 				WMI_PDEV_PARAM_IDLE_PS_CONFIG;
23691 	pdev_param[wmi_pdev_param_power_gating_sleep] =
23692 				WMI_PDEV_PARAM_POWER_GATING_SLEEP;
23693 	pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE;
23694 	pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR;
23695 	pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE;
23696 	pdev_param[wmi_pdev_param_hw_rfkill_config] =
23697 				WMI_PDEV_PARAM_HW_RFKILL_CONFIG;
23698 	pdev_param[wmi_pdev_param_low_power_rf_enable] =
23699 				WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE;
23700 	pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK;
23701 	pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN;
23702 	pdev_param[wmi_pdev_param_power_collapse_enable] =
23703 				WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE;
23704 	pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE;
23705 	pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE;
23706 	pdev_param[wmi_pdev_param_audio_over_wlan_latency] =
23707 				WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY;
23708 	pdev_param[wmi_pdev_param_audio_over_wlan_enable] =
23709 				WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE;
23710 	pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] =
23711 				WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE;
23712 	pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] =
23713 				WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD;
23714 	pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW;
23715 	pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG;
23716 	pdev_param[wmi_pdev_param_adaptive_early_rx_enable] =
23717 				WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE;
23718 	pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] =
23719 				WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP;
23720 	pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] =
23721 				WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP;
23722 	pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] =
23723 				WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP;
23724 	pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] =
23725 				WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE;
23726 	pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] =
23727 				WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT;
23728 	pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] =
23729 				WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP;
23730 	pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] =
23731 				WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT;
23732 	pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] =
23733 				WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE;
23734 	pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] =
23735 				WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE;
23736 	pdev_param[wmi_pdev_param_tx_chain_mask_2g] =
23737 				WMI_PDEV_PARAM_TX_CHAIN_MASK_2G;
23738 	pdev_param[wmi_pdev_param_rx_chain_mask_2g] =
23739 				WMI_PDEV_PARAM_RX_CHAIN_MASK_2G;
23740 	pdev_param[wmi_pdev_param_tx_chain_mask_5g] =
23741 				WMI_PDEV_PARAM_TX_CHAIN_MASK_5G;
23742 	pdev_param[wmi_pdev_param_rx_chain_mask_5g] =
23743 				WMI_PDEV_PARAM_RX_CHAIN_MASK_5G;
23744 	pdev_param[wmi_pdev_param_tx_chain_mask_cck] =
23745 				WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK;
23746 	pdev_param[wmi_pdev_param_tx_chain_mask_1ss] =
23747 				WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS;
23748 	pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER;
23749 	pdev_param[wmi_pdev_set_mcast_to_ucast_tid] =
23750 				WMI_PDEV_SET_MCAST_TO_UCAST_TID;
23751 	pdev_param[wmi_pdev_param_mgmt_retry_limit] =
23752 					WMI_PDEV_PARAM_MGMT_RETRY_LIMIT;
23753 	pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST;
23754 	pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] =
23755 					WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE;
23756 	pdev_param[wmi_pdev_param_proxy_sta_mode] =
23757 				WMI_PDEV_PARAM_PROXY_STA_MODE;
23758 	pdev_param[wmi_pdev_param_mu_group_policy] =
23759 				WMI_PDEV_PARAM_MU_GROUP_POLICY;
23760 	pdev_param[wmi_pdev_param_noise_detection] =
23761 				WMI_PDEV_PARAM_NOISE_DETECTION;
23762 	pdev_param[wmi_pdev_param_noise_threshold] =
23763 				WMI_PDEV_PARAM_NOISE_THRESHOLD;
23764 	pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE;
23765 	pdev_param[wmi_pdev_param_set_mcast_bcast_echo] =
23766 				WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO;
23767 	pdev_param[wmi_pdev_param_atf_strict_sch] =
23768 		WMI_PDEV_PARAM_ATF_STRICT_SCH;
23769 	pdev_param[wmi_pdev_param_atf_sched_duration] =
23770 		WMI_PDEV_PARAM_ATF_SCHED_DURATION;
23771 	pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN;
23772 	pdev_param[wmi_pdev_param_sensitivity_level] =
23773 				WMI_PDEV_PARAM_SENSITIVITY_LEVEL;
23774 	pdev_param[wmi_pdev_param_signed_txpower_2g] =
23775 				WMI_PDEV_PARAM_SIGNED_TXPOWER_2G;
23776 	pdev_param[wmi_pdev_param_signed_txpower_5g] =
23777 				WMI_PDEV_PARAM_SIGNED_TXPOWER_5G;
23778 	pdev_param[wmi_pdev_param_enable_per_tid_amsdu] =
23779 		WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU;
23780 	pdev_param[wmi_pdev_param_enable_per_tid_ampdu] =
23781 		WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU;
23782 	pdev_param[wmi_pdev_param_cca_threshold] =
23783 				WMI_PDEV_PARAM_CCA_THRESHOLD;
23784 	pdev_param[wmi_pdev_param_rts_fixed_rate] =
23785 				WMI_PDEV_PARAM_RTS_FIXED_RATE;
23786 	pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM;
23787 	pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET;
23788 	pdev_param[wmi_pdev_param_wapi_mbssid_offset] =
23789 				WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET;
23790 	pdev_param[wmi_pdev_param_arp_srcaddr] =
23791 				WMI_PDEV_PARAM_ARP_DBG_SRCADDR;
23792 	pdev_param[wmi_pdev_param_arp_dstaddr] =
23793 				WMI_PDEV_PARAM_ARP_DBG_DSTADDR;
23794 	pdev_param[wmi_pdev_param_txpower_decr_db] =
23795 				WMI_PDEV_PARAM_TXPOWER_DECR_DB;
23796 	pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM;
23797 	pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM;
23798 	pdev_param[wmi_pdev_param_atf_obss_noise_sch] =
23799 		WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH;
23800 	pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] =
23801 		WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR;
23802 	pdev_param[wmi_pdev_param_cust_txpower_scale] =
23803 				WMI_PDEV_PARAM_CUST_TXPOWER_SCALE;
23804 	pdev_param[wmi_pdev_param_atf_dynamic_enable] =
23805 		WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE;
23806 	pdev_param[wmi_pdev_param_atf_ssid_group_policy] =
23807 						WMI_UNAVAILABLE_PARAM;
23808 	pdev_param[wmi_pdev_param_igmpmld_override] =
23809 					WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE;
23810 	pdev_param[wmi_pdev_param_igmpmld_tid] =
23811 					WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE;
23812 	pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN;
23813 	pdev_param[wmi_pdev_param_block_interbss] =
23814 				WMI_PDEV_PARAM_BLOCK_INTERBSS;
23815 	pdev_param[wmi_pdev_param_set_disable_reset_cmdid] =
23816 				WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID;
23817 	pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] =
23818 				WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID;
23819 	pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] =
23820 				WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID;
23821 	pdev_param[wmi_pdev_param_set_burst_mode_cmdid] =
23822 					WMI_PDEV_PARAM_SET_BURST_MODE_CMDID;
23823 	pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS;
23824 	pdev_param[wmi_pdev_param_mesh_mcast_enable] =
23825 					WMI_PDEV_PARAM_MESH_MCAST_ENABLE;
23826 	pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] =
23827 					WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID;
23828 	pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] =
23829 					WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID;
23830 	pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] =
23831 				WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER;
23832 	pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] =
23833 				WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER;
23834 	pdev_param[wmi_pdev_param_set_mcast2ucast_mode] =
23835 				WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE;
23836 	pdev_param[wmi_pdev_param_smart_antenna_default_antenna] =
23837 				WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA;
23838 	pdev_param[wmi_pdev_param_fast_channel_reset] =
23839 				WMI_PDEV_PARAM_FAST_CHANNEL_RESET;
23840 	pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE;
23841 	pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT;
23842 	pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE;
23843 	pdev_param[wmi_pdev_param_antenna_gain_half_db] =
23844 		WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB;
23845 	pdev_param[wmi_pdev_param_esp_indication_period] =
23846 				WMI_PDEV_PARAM_ESP_INDICATION_PERIOD;
23847 	pdev_param[wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW;
23848 	pdev_param[wmi_pdev_param_esp_airtime_fraction] =
23849 				WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION;
23850 	pdev_param[wmi_pdev_param_esp_ppdu_duration] =
23851 				WMI_PDEV_PARAM_ESP_PPDU_DURATION;
23852 #ifdef WLAN_RU26_SUPPORT
23853 	pdev_param[wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_RU26_ALLOWED;
23854 #endif
23855 }
23856 
23857 /**
23858  * populate_vdev_param_tlv() - populates vdev params
23859  *
23860  * @param vdev_param: Pointer to hold vdev params
23861  * Return: None
23862  */
23863 static void populate_vdev_param_tlv(uint32_t *vdev_param)
23864 {
23865 	vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD;
23866 	vdev_param[wmi_vdev_param_fragmentation_threshold] =
23867 				WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD;
23868 	vdev_param[wmi_vdev_param_beacon_interval] =
23869 				WMI_VDEV_PARAM_BEACON_INTERVAL;
23870 	vdev_param[wmi_vdev_param_listen_interval] =
23871 				WMI_VDEV_PARAM_LISTEN_INTERVAL;
23872 	vdev_param[wmi_vdev_param_multicast_rate] =
23873 				WMI_VDEV_PARAM_MULTICAST_RATE;
23874 	vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE;
23875 	vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME;
23876 	vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE;
23877 	vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME;
23878 	vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD;
23879 	vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME;
23880 	vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL;
23881 	vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD;
23882 	vdev_param[wmi_vdev_oc_scheduler_air_time_limit] =
23883 				WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT;
23884 	vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS;
23885 	vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW;
23886 	vdev_param[wmi_vdev_param_bmiss_count_max] =
23887 				WMI_VDEV_PARAM_BMISS_COUNT_MAX;
23888 	vdev_param[wmi_vdev_param_bmiss_first_bcnt] =
23889 				WMI_VDEV_PARAM_BMISS_FIRST_BCNT;
23890 	vdev_param[wmi_vdev_param_bmiss_final_bcnt] =
23891 				WMI_VDEV_PARAM_BMISS_FINAL_BCNT;
23892 	vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM;
23893 	vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH;
23894 	vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET;
23895 	vdev_param[wmi_vdev_param_disable_htprotection] =
23896 				WMI_VDEV_PARAM_DISABLE_HTPROTECTION;
23897 	vdev_param[wmi_vdev_param_sta_quickkickout] =
23898 				WMI_VDEV_PARAM_STA_QUICKKICKOUT;
23899 	vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE;
23900 	vdev_param[wmi_vdev_param_protection_mode] =
23901 				WMI_VDEV_PARAM_PROTECTION_MODE;
23902 	vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE;
23903 	vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI;
23904 	vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC;
23905 	vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC;
23906 	vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC;
23907 	vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD;
23908 	vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID;
23909 	vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS;
23910 	vdev_param[wmi_vdev_param_bcast_data_rate] =
23911 				WMI_VDEV_PARAM_BCAST_DATA_RATE;
23912 	vdev_param[wmi_vdev_param_mcast_data_rate] =
23913 				WMI_VDEV_PARAM_MCAST_DATA_RATE;
23914 	vdev_param[wmi_vdev_param_mcast_indicate] =
23915 				WMI_VDEV_PARAM_MCAST_INDICATE;
23916 	vdev_param[wmi_vdev_param_dhcp_indicate] =
23917 				WMI_VDEV_PARAM_DHCP_INDICATE;
23918 	vdev_param[wmi_vdev_param_unknown_dest_indicate] =
23919 				WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE;
23920 	vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] =
23921 		WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS;
23922 	vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] =
23923 		WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS;
23924 	vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] =
23925 		WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS;
23926 	vdev_param[wmi_vdev_param_ap_enable_nawds] =
23927 				WMI_VDEV_PARAM_AP_ENABLE_NAWDS;
23928 	vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS;
23929 	vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF;
23930 	vdev_param[wmi_vdev_param_packet_powersave] =
23931 				WMI_VDEV_PARAM_PACKET_POWERSAVE;
23932 	vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY;
23933 	vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
23934 	vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] =
23935 		WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS;
23936 	vdev_param[wmi_vdev_param_early_rx_adjust_enable] =
23937 				WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE;
23938 	vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] =
23939 				WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM;
23940 	vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] =
23941 				WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE;
23942 	vdev_param[wmi_vdev_param_early_rx_slop_step] =
23943 				WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP;
23944 	vdev_param[wmi_vdev_param_early_rx_init_slop] =
23945 				WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP;
23946 	vdev_param[wmi_vdev_param_early_rx_adjust_pause] =
23947 				WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE;
23948 	vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT;
23949 	vdev_param[wmi_vdev_param_snr_num_for_cal] =
23950 				WMI_VDEV_PARAM_SNR_NUM_FOR_CAL;
23951 	vdev_param[wmi_vdev_param_roam_fw_offload] =
23952 				WMI_VDEV_PARAM_ROAM_FW_OFFLOAD;
23953 	vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC;
23954 	vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] =
23955 				WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS;
23956 	vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE;
23957 	vdev_param[wmi_vdev_param_early_rx_drift_sample] =
23958 				WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE;
23959 	vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] =
23960 				WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR;
23961 	vdev_param[wmi_vdev_param_ebt_resync_timeout] =
23962 				WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT;
23963 	vdev_param[wmi_vdev_param_aggr_trig_event_enable] =
23964 				WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE;
23965 	vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] =
23966 				WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED;
23967 	vdev_param[wmi_vdev_param_is_power_collapse_allowed] =
23968 				WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED;
23969 	vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] =
23970 				WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED;
23971 	vdev_param[wmi_vdev_param_inactivity_cnt] =
23972 		WMI_VDEV_PARAM_INACTIVITY_CNT;
23973 	vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] =
23974 				WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS;
23975 	vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY;
23976 	vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] =
23977 				WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS;
23978 	vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] =
23979 			WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE;
23980 	vdev_param[wmi_vdev_param_rx_leak_window] =
23981 			WMI_VDEV_PARAM_RX_LEAK_WINDOW;
23982 	vdev_param[wmi_vdev_param_stats_avg_factor] =
23983 				WMI_VDEV_PARAM_STATS_AVG_FACTOR;
23984 	vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH;
23985 	vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE;
23986 	vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] =
23987 				WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE;
23988 	vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] =
23989 				WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE;
23990 	vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER;
23991 	vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE;
23992 	vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE;
23993 	vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM;
23994 	vdev_param[wmi_vdev_param_he_range_ext_enable] =
23995 				 WMI_VDEV_PARAM_HE_RANGE_EXT;
23996 	vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR;
23997 	vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE;
23998 	vdev_param[wmi_vdev_param_set_he_sounding_mode]
23999 					= WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE;
24000 	vdev_param[wmi_vdev_param_set_heop]      = WMI_VDEV_PARAM_HEOPS_0_31;
24001 	vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP;
24002 	vdev_param[wmi_vdev_param_dtim_enable_cts] =
24003 					WMI_VDEV_PARAM_DTIM_ENABLE_CTS;
24004 	vdev_param[wmi_vdev_param_atf_ssid_sched_policy] =
24005 					WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY;
24006 	vdev_param[wmi_vdev_param_disable_dyn_bw_rts] =
24007 					WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS;
24008 	vdev_param[wmi_vdev_param_mcast2ucast_set] =
24009 					WMI_VDEV_PARAM_MCAST2UCAST_SET;
24010 	vdev_param[wmi_vdev_param_rc_num_retries] =
24011 					WMI_VDEV_PARAM_RC_NUM_RETRIES;
24012 	vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR;
24013 	vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET;
24014 	vdev_param[wmi_vdev_param_rts_fixed_rate] =
24015 					WMI_VDEV_PARAM_RTS_FIXED_RATE;
24016 	vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK;
24017 	vdev_param[wmi_vdev_param_vht80_ratemask] =
24018 					WMI_VDEV_PARAM_VHT80_RATEMASK;
24019 	vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA;
24020 	vdev_param[wmi_vdev_param_bw_nss_ratemask] =
24021 					WMI_VDEV_PARAM_BW_NSS_RATEMASK;
24022 	vdev_param[wmi_vdev_param_set_he_ltf] =
24023 					WMI_VDEV_PARAM_HE_LTF;
24024 	vdev_param[wmi_vdev_param_disable_cabq] =
24025 					WMI_VDEV_PARAM_DISABLE_CABQ;
24026 	vdev_param[wmi_vdev_param_rate_dropdown_bmap] =
24027 					WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP;
24028 	vdev_param[wmi_vdev_param_set_ba_mode] =
24029 					WMI_VDEV_PARAM_BA_MODE;
24030 	vdev_param[wmi_vdev_param_capabilities] =
24031 					WMI_VDEV_PARAM_CAPABILITIES;
24032 	vdev_param[wmi_vdev_param_autorate_misc_cfg] =
24033 					WMI_VDEV_PARAM_AUTORATE_MISC_CFG;
24034 }
24035 #endif
24036 
24037 /**
24038  * populate_target_defines_tlv() - Populate target defines and params
24039  * @wmi_handle: pointer to wmi handle
24040  *
24041  * Return: None
24042  */
24043 #ifndef CONFIG_MCL
24044 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle)
24045 {
24046 	populate_pdev_param_tlv(wmi_handle->pdev_param);
24047 	populate_vdev_param_tlv(wmi_handle->vdev_param);
24048 }
24049 #else
24050 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle)
24051 { }
24052 #endif
24053 
24054 /**
24055  * wmi_ocb_ut_attach() - Attach OCB test framework
24056  * @wmi_handle: wmi handle
24057  *
24058  * Return: None
24059  */
24060 #ifdef WLAN_OCB_UT
24061 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle);
24062 #else
24063 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle)
24064 {
24065 	return;
24066 }
24067 #endif
24068 
24069 /**
24070  * wmi_tlv_attach() - Attach TLV APIs
24071  *
24072  * Return: None
24073  */
24074 void wmi_tlv_attach(wmi_unified_t wmi_handle)
24075 {
24076 	wmi_handle->ops = &tlv_ops;
24077 	wmi_ocb_ut_attach(wmi_handle);
24078 	wmi_handle->soc->svc_ids = &multi_svc_ids[0];
24079 #ifdef WMI_INTERFACE_EVENT_LOGGING
24080 	/* Skip saving WMI_CMD_HDR and TLV HDR */
24081 	wmi_handle->log_info.buf_offset_command = 8;
24082 	/* WMI_CMD_HDR is already stripped, skip saving TLV HDR */
24083 	wmi_handle->log_info.buf_offset_event = 4;
24084 #endif
24085 	populate_tlv_events_id(wmi_handle->wmi_events);
24086 	populate_tlv_service(wmi_handle->services);
24087 	populate_target_defines_tlv(wmi_handle);
24088 	wmi_twt_attach_tlv(wmi_handle);
24089 	wmi_extscan_attach_tlv(wmi_handle);
24090 }
24091 qdf_export_symbol(wmi_tlv_attach);
24092 
24093 /**
24094  * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine
24095  *
24096  * Return: None
24097  */
24098 void wmi_tlv_init(void)
24099 {
24100 	wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach);
24101 }
24102