xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_tlv.c (revision 8b7e2ee3720101d16dde046b0345f866abb7a5d8)
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 /* HTC service ids for WMI for multi-radio */
54 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC,
55 				WMI_CONTROL_SVC_WMAC1,
56 				WMI_CONTROL_SVC_WMAC2};
57 
58 /**
59  * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from
60  *           host to target defines.
61  * @param pdev_id: host pdev_id to be converted.
62  * Return: target pdev_id after conversion.
63  */
64 static uint32_t convert_host_pdev_id_to_target_pdev_id(uint32_t pdev_id)
65 {
66 	switch (pdev_id) {
67 	case WMI_HOST_PDEV_ID_SOC:
68 		return WMI_PDEV_ID_SOC;
69 	case WMI_HOST_PDEV_ID_0:
70 		return WMI_PDEV_ID_1ST;
71 	case WMI_HOST_PDEV_ID_1:
72 		return WMI_PDEV_ID_2ND;
73 	case WMI_HOST_PDEV_ID_2:
74 		return WMI_PDEV_ID_3RD;
75 	}
76 
77 	QDF_ASSERT(0);
78 
79 	return WMI_PDEV_ID_SOC;
80 }
81 
82 /**
83  * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from
84  *           target to host defines.
85  * @param pdev_id: target pdev_id to be converted.
86  * Return: host pdev_id after conversion.
87  */
88 static uint32_t convert_target_pdev_id_to_host_pdev_id(uint32_t pdev_id)
89 {
90 	switch (pdev_id) {
91 	case WMI_PDEV_ID_SOC:
92 		return WMI_HOST_PDEV_ID_SOC;
93 	case WMI_PDEV_ID_1ST:
94 		return WMI_HOST_PDEV_ID_0;
95 	case WMI_PDEV_ID_2ND:
96 		return WMI_HOST_PDEV_ID_1;
97 	case WMI_PDEV_ID_3RD:
98 		return WMI_HOST_PDEV_ID_2;
99 	}
100 
101 	QDF_ASSERT(0);
102 
103 	return WMI_HOST_PDEV_ID_SOC;
104 }
105 
106 /**
107  * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion
108  *
109  * Return None.
110  */
111 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle)
112 {
113 	wmi_handle->ops->convert_pdev_id_host_to_target =
114 		convert_host_pdev_id_to_target_pdev_id;
115 	wmi_handle->ops->convert_pdev_id_target_to_host =
116 		convert_target_pdev_id_to_host_pdev_id;
117 }
118 
119 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command
120  *                              buffer.
121  * @wmi_handle: pointer to wmi_handle
122  * @cmd: pointer target vdev create command buffer
123  * @param: pointer host params for vdev create
124  *
125  * Return: None
126  */
127 #ifdef CONFIG_MCL
128 static inline void copy_vdev_create_pdev_id(
129 		struct wmi_unified *wmi_handle,
130 		wmi_vdev_create_cmd_fixed_param * cmd,
131 		struct vdev_create_params *param)
132 {
133 	cmd->pdev_id = WMI_PDEV_ID_SOC;
134 }
135 #else
136 static inline void copy_vdev_create_pdev_id(
137 		struct wmi_unified *wmi_handle,
138 		wmi_vdev_create_cmd_fixed_param * cmd,
139 		struct vdev_create_params *param)
140 {
141 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
142 							param->pdev_id);
143 }
144 #endif
145 
146 /**
147  * wmi_mtrace() - Wrappper function for qdf_mtrace api
148  * @message_id: 32-Bit Wmi message ID
149  * @vdev_id: Vdev ID
150  * @data: Actual message contents
151  *
152  * This function converts the 32-bit WMI message ID in 15-bit message ID
153  * format for qdf_mtrace as in qdf_mtrace message there are only 15
154  * bits reserved for message ID.
155  * out of these 15-bits, 8-bits (From MSB) specifies the WMI_GRP_ID
156  * and remaining 7-bits specifies the actual WMI command. With this
157  * notation there can be maximum 256 groups and each group can have
158  * max 128 commands can be supported.
159  *
160  * Return: None
161  */
162 static void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data)
163 {
164 	uint16_t mtrace_message_id;
165 
166 	mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) |
167 		(QDF_WMI_MTRACE_GRP_ID(message_id) <<
168 						QDF_WMI_MTRACE_CMD_NUM_BITS);
169 	qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET,
170 		   mtrace_message_id, vdev_id, data);
171 }
172 
173 /**
174  * send_vdev_create_cmd_tlv() - send VDEV create command to fw
175  * @wmi_handle: wmi handle
176  * @param: pointer to hold vdev create parameter
177  * @macaddr: vdev mac address
178  *
179  * Return: QDF_STATUS_SUCCESS for success or error code
180  */
181 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle,
182 				 uint8_t macaddr[IEEE80211_ADDR_LEN],
183 				 struct vdev_create_params *param)
184 {
185 	wmi_vdev_create_cmd_fixed_param *cmd;
186 	wmi_buf_t buf;
187 	int32_t len = sizeof(*cmd);
188 	QDF_STATUS ret;
189 	int num_bands = 2;
190 	uint8_t *buf_ptr;
191 	wmi_vdev_txrx_streams *txrx_streams;
192 
193 	len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE);
194 	buf = wmi_buf_alloc(wmi_handle, len);
195 	if (!buf) {
196 		WMI_LOGP("%s:wmi_buf_alloc failed", __func__);
197 		return QDF_STATUS_E_NOMEM;
198 	}
199 	cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf);
200 	WMITLV_SET_HDR(&cmd->tlv_header,
201 		       WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param,
202 		       WMITLV_GET_STRUCT_TLVLEN
203 			       (wmi_vdev_create_cmd_fixed_param));
204 	cmd->vdev_id = param->if_id;
205 	cmd->vdev_type = param->type;
206 	cmd->vdev_subtype = param->subtype;
207 	cmd->flags = param->mbssid_flags;
208 	cmd->vdevid_trans = param->vdevid_trans;
209 	cmd->num_cfg_txrx_streams = num_bands;
210 	copy_vdev_create_pdev_id(wmi_handle, cmd, param);
211 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr);
212 	WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x",
213 		 __func__, param->if_id, cmd->pdev_id,
214 		 macaddr[0], macaddr[1], macaddr[2],
215 		 macaddr[3], macaddr[4], macaddr[5]);
216 	buf_ptr = (uint8_t *)cmd + sizeof(*cmd);
217 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
218 			(num_bands * sizeof(wmi_vdev_txrx_streams)));
219 	buf_ptr += WMI_TLV_HDR_SIZE;
220 
221 	WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__,
222 			param->type, param->subtype,
223 			param->nss_2g, param->nss_5g);
224 	txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr;
225 	txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G;
226 	txrx_streams->supported_tx_streams = param->nss_2g;
227 	txrx_streams->supported_rx_streams = param->nss_2g;
228 	WMITLV_SET_HDR(&txrx_streams->tlv_header,
229 		       WMITLV_TAG_STRUC_wmi_vdev_txrx_streams,
230 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams));
231 
232 	txrx_streams++;
233 	txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G;
234 	txrx_streams->supported_tx_streams = param->nss_5g;
235 	txrx_streams->supported_rx_streams = param->nss_5g;
236 	WMITLV_SET_HDR(&txrx_streams->tlv_header,
237 		       WMITLV_TAG_STRUC_wmi_vdev_txrx_streams,
238 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams));
239 	wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0);
240 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID);
241 	if (QDF_IS_STATUS_ERROR(ret)) {
242 		WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID");
243 		wmi_buf_free(buf);
244 	}
245 
246 	return ret;
247 }
248 
249 /**
250  * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw
251  * @wmi_handle: wmi handle
252  * @if_id: vdev id
253  *
254  * Return: QDF_STATUS_SUCCESS for success or error code
255  */
256 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle,
257 					  uint8_t if_id)
258 {
259 	wmi_vdev_delete_cmd_fixed_param *cmd;
260 	wmi_buf_t buf;
261 	QDF_STATUS ret;
262 
263 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
264 	if (!buf) {
265 		WMI_LOGP("%s:wmi_buf_alloc failed", __func__);
266 		return QDF_STATUS_E_NOMEM;
267 	}
268 
269 	cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf);
270 	WMITLV_SET_HDR(&cmd->tlv_header,
271 		       WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param,
272 		       WMITLV_GET_STRUCT_TLVLEN
273 			       (wmi_vdev_delete_cmd_fixed_param));
274 	cmd->vdev_id = if_id;
275 	wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0);
276 	ret = wmi_unified_cmd_send(wmi_handle, buf,
277 				   sizeof(wmi_vdev_delete_cmd_fixed_param),
278 				   WMI_VDEV_DELETE_CMDID);
279 	if (QDF_IS_STATUS_ERROR(ret)) {
280 		WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID");
281 		wmi_buf_free(buf);
282 	}
283 	WMI_LOGD("%s:vdev id = %d", __func__, if_id);
284 
285 	return ret;
286 }
287 
288 /**
289  * send_vdev_stop_cmd_tlv() - send vdev stop command to fw
290  * @wmi: wmi handle
291  * @vdev_id: vdev id
292  *
293  * Return: QDF_STATUS_SUCCESS for success or erro code
294  */
295 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi,
296 					uint8_t vdev_id)
297 {
298 	wmi_vdev_stop_cmd_fixed_param *cmd;
299 	wmi_buf_t buf;
300 	int32_t len = sizeof(*cmd);
301 
302 	buf = wmi_buf_alloc(wmi, len);
303 	if (!buf) {
304 		WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
305 		return QDF_STATUS_E_NOMEM;
306 	}
307 	cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf);
308 	WMITLV_SET_HDR(&cmd->tlv_header,
309 		       WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param,
310 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param));
311 	cmd->vdev_id = vdev_id;
312 	wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0);
313 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) {
314 		WMI_LOGP("%s: Failed to send vdev stop command", __func__);
315 		wmi_buf_free(buf);
316 		return QDF_STATUS_E_FAILURE;
317 	}
318 	WMI_LOGD("%s:vdev id = %d", __func__, vdev_id);
319 
320 	return 0;
321 }
322 
323 /**
324  * send_vdev_down_cmd_tlv() - send vdev down command to fw
325  * @wmi: wmi handle
326  * @vdev_id: vdev id
327  *
328  * Return: QDF_STATUS_SUCCESS for success or error code
329  */
330 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id)
331 {
332 	wmi_vdev_down_cmd_fixed_param *cmd;
333 	wmi_buf_t buf;
334 	int32_t len = sizeof(*cmd);
335 
336 	buf = wmi_buf_alloc(wmi, len);
337 	if (!buf) {
338 		WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
339 		return QDF_STATUS_E_NOMEM;
340 	}
341 	cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf);
342 	WMITLV_SET_HDR(&cmd->tlv_header,
343 		       WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param,
344 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param));
345 	cmd->vdev_id = vdev_id;
346 	wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0);
347 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) {
348 		WMI_LOGP("%s: Failed to send vdev down", __func__);
349 		wmi_buf_free(buf);
350 		return QDF_STATUS_E_FAILURE;
351 	}
352 	WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
353 
354 	return 0;
355 }
356 
357 #ifdef CONFIG_MCL
358 static inline void copy_channel_info(
359 		wmi_vdev_start_request_cmd_fixed_param * cmd,
360 		wmi_channel *chan,
361 		struct vdev_start_params *req)
362 {
363 	chan->mhz = req->chan_freq;
364 
365 	WMI_SET_CHANNEL_MODE(chan, req->chan_mode);
366 
367 	chan->band_center_freq1 = req->band_center_freq1;
368 	chan->band_center_freq2 = req->band_center_freq2;
369 
370 	if (req->is_half_rate)
371 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
372 	else if (req->is_quarter_rate)
373 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
374 
375 	if (req->is_dfs && req->flag_dfs) {
376 		WMI_SET_CHANNEL_FLAG(chan, req->flag_dfs);
377 		cmd->disable_hw_ack = req->dis_hw_ack;
378 	}
379 
380 	WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow);
381 	WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->max_txpow);
382 
383 }
384 #else
385 static inline void copy_channel_info(
386 		wmi_vdev_start_request_cmd_fixed_param * cmd,
387 		wmi_channel *chan,
388 		struct vdev_start_params *req)
389 {
390 	chan->mhz = req->channel.mhz;
391 
392 	WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode);
393 
394 	chan->band_center_freq1 = req->channel.cfreq1;
395 	chan->band_center_freq2 = req->channel.cfreq2;
396 	WMI_LOGI("%s: req->channel.phy_mode: %d ", req->channel.phy_mode);
397 
398 	if (req->channel.half_rate)
399 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
400 	else if (req->channel.quarter_rate)
401 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
402 
403 	WMI_LOGI("%s: req->channel.dfs_set: %d ", req->channel.dfs_set);
404 
405 	if (req->channel.dfs_set) {
406 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS);
407 		cmd->disable_hw_ack = req->disable_hw_ack;
408 	}
409 
410 	if (req->channel.dfs_set_cfreq2)
411 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2);
412 
413 	/* According to firmware both reg power and max tx power
414 	 * on set channel power is used and set it to max reg
415 	 * power from regulatory.
416 	 */
417 	WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower);
418 	WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower);
419 	WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower);
420 	WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax);
421 	WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id);
422 	WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower);
423 
424 }
425 #endif
426 /**
427  * send_vdev_start_cmd_tlv() - send vdev start request to fw
428  * @wmi_handle: wmi handle
429  * @req: vdev start params
430  *
431  * Return: QDF status
432  */
433 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle,
434 			  struct vdev_start_params *req)
435 {
436 	wmi_vdev_start_request_cmd_fixed_param *cmd;
437 	wmi_buf_t buf;
438 	wmi_channel *chan;
439 	int32_t len, ret;
440 	uint8_t *buf_ptr;
441 
442 	len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE;
443 	buf = wmi_buf_alloc(wmi_handle, len);
444 	if (!buf) {
445 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
446 		return QDF_STATUS_E_NOMEM;
447 	}
448 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
449 	cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr;
450 	chan = (wmi_channel *) (buf_ptr + sizeof(*cmd));
451 	WMITLV_SET_HDR(&cmd->tlv_header,
452 		       WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param,
453 		       WMITLV_GET_STRUCT_TLVLEN
454 			       (wmi_vdev_start_request_cmd_fixed_param));
455 	WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel,
456 		       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
457 	cmd->vdev_id = req->vdev_id;
458 
459 	/* Fill channel info */
460 	copy_channel_info(cmd, chan, req);
461 
462 	cmd->beacon_interval = req->beacon_intval;
463 	cmd->dtim_period = req->dtim_period;
464 
465 	cmd->bcn_tx_rate = req->bcn_tx_rate_code;
466 	if (req->bcn_tx_rate_code)
467 		cmd->flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT;
468 
469 	if (!req->is_restart) {
470 		cmd->beacon_interval = req->beacon_intval;
471 		cmd->dtim_period = req->dtim_period;
472 
473 		/* Copy the SSID */
474 		if (req->ssid.length) {
475 			if (req->ssid.length < sizeof(cmd->ssid.ssid))
476 				cmd->ssid.ssid_len = req->ssid.length;
477 			else
478 				cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid);
479 			qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid,
480 				     cmd->ssid.ssid_len);
481 		}
482 
483 		if (req->hidden_ssid)
484 			cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
485 
486 		if (req->pmf_enabled)
487 			cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED;
488 	}
489 
490 	cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED;
491 	cmd->num_noa_descriptors = req->num_noa_descriptors;
492 	cmd->preferred_rx_streams = req->preferred_rx_streams;
493 	cmd->preferred_tx_streams = req->preferred_tx_streams;
494 	cmd->cac_duration_ms = req->cac_duration_ms;
495 	cmd->regdomain = req->regdomain;
496 	cmd->he_ops = req->he_ops;
497 
498 	buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) +
499 			       sizeof(wmi_channel));
500 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
501 		       cmd->num_noa_descriptors *
502 		       sizeof(wmi_p2p_noa_descriptor));
503 	WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d "
504 		"beacon interval %d dtim %d center_chan %d center_freq2 %d "
505 		"reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x "
506 		"Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d"
507 		"req->dis_hw_ack: %d ", __func__, req->vdev_id,
508 		chan->mhz, req->chan_mode, chan->info,
509 		req->is_dfs, req->beacon_intval, cmd->dtim_period,
510 		chan->band_center_freq1, chan->band_center_freq2,
511 		chan->reg_info_1, chan->reg_info_2, req->max_txpow,
512 		req->preferred_tx_streams, req->preferred_rx_streams,
513 		req->ldpc_rx_enabled, req->cac_duration_ms,
514 		req->regdomain, req->he_ops,
515 		req->dis_hw_ack);
516 
517 	if (req->is_restart) {
518 		wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0);
519 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
520 					   WMI_VDEV_RESTART_REQUEST_CMDID);
521 	} else {
522 		wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0);
523 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
524 					   WMI_VDEV_START_REQUEST_CMDID);
525 	}
526 	if (ret) {
527 		WMI_LOGP("%s: Failed to send vdev start command", __func__);
528 		wmi_buf_free(buf);
529 		return QDF_STATUS_E_FAILURE;
530 	 }
531 
532 	return QDF_STATUS_SUCCESS;
533 }
534 
535 /**
536  * send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid
537  * @wmi_handle: wmi handle
538  * @restart_params: vdev restart params
539  *
540  * Return: QDF_STATUS_SUCCESS for success or error code
541  */
542 static QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle,
543 			struct hidden_ssid_vdev_restart_params *restart_params)
544 {
545 	wmi_vdev_start_request_cmd_fixed_param *cmd;
546 	wmi_buf_t buf;
547 	wmi_channel *chan;
548 	int32_t len;
549 	uint8_t *buf_ptr;
550 	QDF_STATUS ret = 0;
551 
552 	len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE;
553 	buf = wmi_buf_alloc(wmi_handle, len);
554 	if (!buf) {
555 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
556 		return QDF_STATUS_E_NOMEM;
557 	}
558 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
559 	cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr;
560 	chan = (wmi_channel *) (buf_ptr + sizeof(*cmd));
561 
562 	WMITLV_SET_HDR(&cmd->tlv_header,
563 		       WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param,
564 		       WMITLV_GET_STRUCT_TLVLEN
565 			       (wmi_vdev_start_request_cmd_fixed_param));
566 
567 	WMITLV_SET_HDR(&chan->tlv_header,
568 		       WMITLV_TAG_STRUC_wmi_channel,
569 		       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
570 
571 	cmd->vdev_id = restart_params->session_id;
572 	cmd->ssid.ssid_len = restart_params->ssid_len;
573 	qdf_mem_copy(cmd->ssid.ssid,
574 		     restart_params->ssid,
575 		     cmd->ssid.ssid_len);
576 	cmd->flags = restart_params->flags;
577 	cmd->requestor_id = restart_params->requestor_id;
578 	cmd->disable_hw_ack = restart_params->disable_hw_ack;
579 
580 	chan->mhz = restart_params->mhz;
581 	chan->band_center_freq1 =
582 			restart_params->band_center_freq1;
583 	chan->band_center_freq2 =
584 			restart_params->band_center_freq2;
585 	chan->info = restart_params->info;
586 	chan->reg_info_1 = restart_params->reg_info_1;
587 	chan->reg_info_2 = restart_params->reg_info_2;
588 
589 	cmd->num_noa_descriptors = 0;
590 	buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) +
591 			       sizeof(wmi_channel));
592 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
593 		       cmd->num_noa_descriptors *
594 		       sizeof(wmi_p2p_noa_descriptor));
595 
596 	wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0);
597 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
598 				   WMI_VDEV_RESTART_REQUEST_CMDID);
599 	if (QDF_IS_STATUS_ERROR(ret)) {
600 		wmi_buf_free(buf);
601 		return QDF_STATUS_E_FAILURE;
602 	}
603 	return QDF_STATUS_SUCCESS;
604 }
605 
606 
607 /**
608  * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw
609  * @wmi: wmi handle
610  * @peer_addr: peer mac address
611  * @param: pointer to hold peer flush tid parameter
612  *
613  * Return: 0 for success or error code
614  */
615 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi,
616 					 uint8_t peer_addr[IEEE80211_ADDR_LEN],
617 					 struct peer_flush_params *param)
618 {
619 	wmi_peer_flush_tids_cmd_fixed_param *cmd;
620 	wmi_buf_t buf;
621 	int32_t len = sizeof(*cmd);
622 
623 	buf = wmi_buf_alloc(wmi, len);
624 	if (!buf) {
625 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
626 		return QDF_STATUS_E_NOMEM;
627 	}
628 	cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf);
629 	WMITLV_SET_HDR(&cmd->tlv_header,
630 		       WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param,
631 		       WMITLV_GET_STRUCT_TLVLEN
632 			       (wmi_peer_flush_tids_cmd_fixed_param));
633 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
634 	cmd->peer_tid_bitmap = param->peer_tid_bitmap;
635 	cmd->vdev_id = param->vdev_id;
636 	WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__,
637 				peer_addr, param->vdev_id,
638 				param->peer_tid_bitmap);
639 	wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0);
640 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) {
641 		WMI_LOGP("%s: Failed to send flush tid command", __func__);
642 		wmi_buf_free(buf);
643 		return QDF_STATUS_E_FAILURE;
644 	}
645 
646 	return 0;
647 }
648 
649 /**
650  * send_peer_delete_cmd_tlv() - send PEER delete command to fw
651  * @wmi: wmi handle
652  * @peer_addr: peer mac addr
653  * @vdev_id: vdev id
654  *
655  * Return: QDF_STATUS_SUCCESS for success or error code
656  */
657 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi,
658 				 uint8_t peer_addr[IEEE80211_ADDR_LEN],
659 				 uint8_t vdev_id)
660 {
661 	wmi_peer_delete_cmd_fixed_param *cmd;
662 	wmi_buf_t buf;
663 	int32_t len = sizeof(*cmd);
664 	buf = wmi_buf_alloc(wmi, len);
665 	if (!buf) {
666 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
667 		return QDF_STATUS_E_NOMEM;
668 	}
669 	cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf);
670 	WMITLV_SET_HDR(&cmd->tlv_header,
671 		       WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param,
672 		       WMITLV_GET_STRUCT_TLVLEN
673 			       (wmi_peer_delete_cmd_fixed_param));
674 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
675 	cmd->vdev_id = vdev_id;
676 
677 	WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id);
678 	wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0);
679 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) {
680 		WMI_LOGP("%s: Failed to send peer delete command", __func__);
681 		wmi_buf_free(buf);
682 		return QDF_STATUS_E_FAILURE;
683 	}
684 
685 	return 0;
686 }
687 
688 /**
689  * convert_host_peer_id_to_target_id_tlv - convert host peer param_id
690  * to target id.
691  * @targ_paramid: Target parameter id to hold the result.
692  * @peer_param_id: host param id.
693  *
694  * Return: QDF_STATUS_SUCCESS for success
695  *         QDF_STATUS_E_NOSUPPORT when the param_id in not supported in tareget
696  */
697 #ifdef CONFIG_MCL
698 static QDF_STATUS convert_host_peer_id_to_target_id_tlv(
699 		uint32_t *targ_paramid,
700 		uint32_t peer_param_id)
701 {
702 	*targ_paramid = peer_param_id;
703 	return QDF_STATUS_SUCCESS;
704 }
705 
706 /**
707  * crash_on_send_peer_rx_reorder_queue_remove_cmd() - crash on reorder queue cmd
708  *
709  * On MCL side, we are suspecting this cmd to trigger drop of ARP
710  * response frames from REO by the FW. This function causes a crash if this
711  * command is sent out by the host, so we can track this issue. Ideally no one
712  * should be calling this API from the MCL side
713  *
714  * Return: None
715  */
716 static void crash_on_send_peer_rx_reorder_queue_remove_cmd(void)
717 {
718 	QDF_BUG(0);
719 }
720 #else
721 static QDF_STATUS convert_host_peer_id_to_target_id_tlv(
722 		uint32_t *targ_paramid,
723 		uint32_t peer_param_id)
724 {
725 	switch (peer_param_id) {
726 	case WMI_HOST_PEER_MIMO_PS_STATE:
727 		*targ_paramid = WMI_PEER_MIMO_PS_STATE;
728 		break;
729 	case WMI_HOST_PEER_AMPDU:
730 		*targ_paramid = WMI_PEER_AMPDU;
731 		break;
732 	case WMI_HOST_PEER_AUTHORIZE:
733 		*targ_paramid = WMI_PEER_AUTHORIZE;
734 		break;
735 	case WMI_HOST_PEER_CHWIDTH:
736 		*targ_paramid = WMI_PEER_CHWIDTH;
737 		break;
738 	case WMI_HOST_PEER_NSS:
739 		*targ_paramid = WMI_PEER_NSS;
740 		break;
741 	case WMI_HOST_PEER_USE_4ADDR:
742 		*targ_paramid = WMI_PEER_USE_4ADDR;
743 		break;
744 	case WMI_HOST_PEER_MEMBERSHIP:
745 		*targ_paramid = WMI_PEER_MEMBERSHIP;
746 		break;
747 	case WMI_HOST_PEER_USERPOS:
748 		*targ_paramid = WMI_PEER_USERPOS;
749 		break;
750 	case WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED:
751 		*targ_paramid = WMI_PEER_CRIT_PROTO_HINT_ENABLED;
752 		break;
753 	case WMI_HOST_PEER_TX_FAIL_CNT_THR:
754 		*targ_paramid = WMI_PEER_TX_FAIL_CNT_THR;
755 		break;
756 	case WMI_HOST_PEER_SET_HW_RETRY_CTS2S:
757 		*targ_paramid = WMI_PEER_SET_HW_RETRY_CTS2S;
758 		break;
759 	case WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH:
760 		*targ_paramid = WMI_PEER_IBSS_ATIM_WINDOW_LENGTH;
761 		break;
762 	case WMI_HOST_PEER_PHYMODE:
763 		*targ_paramid = WMI_PEER_PHYMODE;
764 		break;
765 	case WMI_HOST_PEER_USE_FIXED_PWR:
766 		*targ_paramid = WMI_PEER_USE_FIXED_PWR;
767 		break;
768 	case WMI_HOST_PEER_PARAM_FIXED_RATE:
769 		*targ_paramid = WMI_PEER_PARAM_FIXED_RATE;
770 		break;
771 	case WMI_HOST_PEER_SET_MU_WHITELIST:
772 		*targ_paramid = WMI_PEER_SET_MU_WHITELIST;
773 		break;
774 	case WMI_HOST_PEER_SET_MAC_TX_RATE:
775 		*targ_paramid = WMI_PEER_SET_MAX_TX_RATE;
776 		break;
777 	case WMI_HOST_PEER_SET_MIN_TX_RATE:
778 		*targ_paramid = WMI_PEER_SET_MIN_TX_RATE;
779 		break;
780 	case WMI_HOST_PEER_SET_DEFAULT_ROUTING:
781 		*targ_paramid = WMI_PEER_SET_DEFAULT_ROUTING;
782 		break;
783 	case WMI_HOST_PEER_NSS_VHT160:
784 		*targ_paramid = WMI_PEER_NSS_VHT160;
785 		break;
786 	case WMI_HOST_PEER_NSS_VHT80_80:
787 		*targ_paramid = WMI_PEER_NSS_VHT80_80;
788 		break;
789 	case WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL:
790 		*targ_paramid = WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL;
791 		break;
792 	case WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL:
793 		*targ_paramid = WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL;
794 		break;
795 	case WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE:
796 		*targ_paramid = WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE;
797 		break;
798 	case WMI_HOST_PEER_PARAM_MU_ENABLE:
799 		*targ_paramid = WMI_PEER_PARAM_MU_ENABLE;
800 		break;
801 	case WMI_HOST_PEER_PARAM_OFDMA_ENABLE:
802 		*targ_paramid = WMI_PEER_PARAM_OFDMA_ENABLE;
803 		break;
804 	default:
805 		return QDF_STATUS_E_NOSUPPORT;
806 	}
807 
808 	return QDF_STATUS_SUCCESS;
809 }
810 
811 static void crash_on_send_peer_rx_reorder_queue_remove_cmd(void)
812 {
813 	/* No-OP */
814 }
815 
816 #endif
817 /**
818  * send_peer_param_cmd_tlv() - set peer parameter in fw
819  * @wmi: wmi handle
820  * @peer_addr: peer mac address
821  * @param    : pointer to hold peer set parameter
822  *
823  * Return: QDF_STATUS_SUCCESS for success or error code
824  */
825 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi,
826 				uint8_t peer_addr[IEEE80211_ADDR_LEN],
827 				struct peer_set_params *param)
828 {
829 	wmi_peer_set_param_cmd_fixed_param *cmd;
830 	wmi_buf_t buf;
831 	int32_t err;
832 	uint32_t param_id;
833 
834 	if (convert_host_peer_id_to_target_id_tlv(&param_id,
835 				param->param_id) != QDF_STATUS_SUCCESS)
836 		return QDF_STATUS_E_NOSUPPORT;
837 
838 	buf = wmi_buf_alloc(wmi, sizeof(*cmd));
839 	if (!buf) {
840 		WMI_LOGE("Failed to allocate buffer to send set_param cmd");
841 		return QDF_STATUS_E_NOMEM;
842 	}
843 	cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf);
844 	WMITLV_SET_HDR(&cmd->tlv_header,
845 		       WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
846 		       WMITLV_GET_STRUCT_TLVLEN
847 				(wmi_peer_set_param_cmd_fixed_param));
848 	cmd->vdev_id = param->vdev_id;
849 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
850 	cmd->param_id = param_id;
851 	cmd->param_value = param->param_value;
852 	wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0);
853 	err = wmi_unified_cmd_send(wmi, buf,
854 				   sizeof(wmi_peer_set_param_cmd_fixed_param),
855 				   WMI_PEER_SET_PARAM_CMDID);
856 	if (err) {
857 		WMI_LOGE("Failed to send set_param cmd");
858 		wmi_buf_free(buf);
859 		return QDF_STATUS_E_FAILURE;
860 	}
861 
862 	return 0;
863 }
864 
865 /**
866  * send_vdev_up_cmd_tlv() - send vdev up command in fw
867  * @wmi: wmi handle
868  * @bssid: bssid
869  * @vdev_up_params: pointer to hold vdev up parameter
870  *
871  * Return: QDF_STATUS_SUCCESS for success or error code
872  */
873 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi,
874 			     uint8_t bssid[IEEE80211_ADDR_LEN],
875 				 struct vdev_up_params *params)
876 {
877 	wmi_vdev_up_cmd_fixed_param *cmd;
878 	wmi_buf_t buf;
879 	int32_t len = sizeof(*cmd);
880 
881 	WMI_LOGD("%s: VDEV_UP", __func__);
882 	WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__,
883 		 params->vdev_id, params->assoc_id, bssid);
884 	buf = wmi_buf_alloc(wmi, len);
885 	if (!buf) {
886 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
887 		return QDF_STATUS_E_NOMEM;
888 	}
889 	cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf);
890 	WMITLV_SET_HDR(&cmd->tlv_header,
891 		       WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param,
892 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param));
893 	cmd->vdev_id = params->vdev_id;
894 	cmd->vdev_assoc_id = params->assoc_id;
895 	cmd->profile_idx = params->profile_idx;
896 	cmd->profile_num = params->profile_num;
897 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid);
898 	WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid);
899 	wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0);
900 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) {
901 		WMI_LOGP("%s: Failed to send vdev up command", __func__);
902 		wmi_buf_free(buf);
903 		return QDF_STATUS_E_FAILURE;
904 	}
905 
906 	return 0;
907 }
908 
909 /**
910  * send_peer_create_cmd_tlv() - send peer create command to fw
911  * @wmi: wmi handle
912  * @peer_addr: peer mac address
913  * @peer_type: peer type
914  * @vdev_id: vdev id
915  *
916  * Return: QDF_STATUS_SUCCESS for success or error code
917  */
918 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi,
919 					struct peer_create_params *param)
920 {
921 	wmi_peer_create_cmd_fixed_param *cmd;
922 	wmi_buf_t buf;
923 	int32_t len = sizeof(*cmd);
924 
925 	buf = wmi_buf_alloc(wmi, len);
926 	if (!buf) {
927 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
928 		return QDF_STATUS_E_NOMEM;
929 	}
930 	cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf);
931 	WMITLV_SET_HDR(&cmd->tlv_header,
932 		       WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param,
933 		       WMITLV_GET_STRUCT_TLVLEN
934 			       (wmi_peer_create_cmd_fixed_param));
935 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
936 	cmd->peer_type = param->peer_type;
937 	cmd->vdev_id = param->vdev_id;
938 
939 	wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0);
940 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) {
941 		WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__);
942 		wmi_buf_free(buf);
943 		return QDF_STATUS_E_FAILURE;
944 	}
945 	WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr,
946 			param->vdev_id);
947 
948 	return 0;
949 }
950 
951 /**
952  * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup
953  * 	command to fw
954  * @wmi: wmi handle
955  * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters
956  *
957  * Return: 0 for success or error code
958  */
959 static
960 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi,
961 		struct rx_reorder_queue_setup_params *param)
962 {
963 	wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd;
964 	wmi_buf_t buf;
965 	int32_t len = sizeof(*cmd);
966 
967 	buf = wmi_buf_alloc(wmi, len);
968 	if (!buf) {
969 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
970 		return QDF_STATUS_E_NOMEM;
971 	}
972 	cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf);
973 	WMITLV_SET_HDR(&cmd->tlv_header,
974 		WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param,
975 		WMITLV_GET_STRUCT_TLVLEN
976 			(wmi_peer_reorder_queue_setup_cmd_fixed_param));
977 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr);
978 	cmd->vdev_id = param->vdev_id;
979 	cmd->tid = param->tid;
980 	cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo;
981 	cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi;
982 	cmd->queue_no = param->queue_no;
983 	cmd->ba_window_size_valid = param->ba_window_size_valid;
984 	cmd->ba_window_size = param->ba_window_size;
985 
986 
987 	wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0);
988 	if (wmi_unified_cmd_send(wmi, buf, len,
989 			WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) {
990 		WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID",
991 			__func__);
992 		qdf_nbuf_free(buf);
993 		return QDF_STATUS_E_FAILURE;
994 	}
995 	WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d\n", __func__,
996 		param->peer_macaddr, param->vdev_id, param->tid);
997 
998 	return QDF_STATUS_SUCCESS;
999 }
1000 
1001 /**
1002  * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove
1003  * 	command to fw
1004  * @wmi: wmi handle
1005  * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters
1006  *
1007  * Return: 0 for success or error code
1008  */
1009 static
1010 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi,
1011 		struct rx_reorder_queue_remove_params *param)
1012 {
1013 	wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd;
1014 	wmi_buf_t buf;
1015 	int32_t len = sizeof(*cmd);
1016 
1017 	crash_on_send_peer_rx_reorder_queue_remove_cmd();
1018 
1019 	buf = wmi_buf_alloc(wmi, len);
1020 	if (!buf) {
1021 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
1022 		return QDF_STATUS_E_NOMEM;
1023 	}
1024 	cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *)
1025 			wmi_buf_data(buf);
1026 	WMITLV_SET_HDR(&cmd->tlv_header,
1027 		WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param,
1028 		WMITLV_GET_STRUCT_TLVLEN
1029 			(wmi_peer_reorder_queue_remove_cmd_fixed_param));
1030 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr);
1031 	cmd->vdev_id = param->vdev_id;
1032 	cmd->tid_mask = param->peer_tid_bitmap;
1033 
1034 	wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0);
1035 	if (wmi_unified_cmd_send(wmi, buf, len,
1036 			WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) {
1037 		WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID",
1038 			__func__);
1039 		qdf_nbuf_free(buf);
1040 		return QDF_STATUS_E_FAILURE;
1041 	}
1042 	WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__,
1043 		param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap);
1044 
1045 	return QDF_STATUS_SUCCESS;
1046 }
1047 
1048 /**
1049  * send_peer_add_wds_entry_cmd_tlv() - send peer add command to fw
1050  * @wmi_handle: wmi handle
1051  * @param: pointer holding peer details
1052  *
1053  * Return: 0 for success or error code
1054  */
1055 static QDF_STATUS send_peer_add_wds_entry_cmd_tlv(wmi_unified_t wmi_handle,
1056 					struct peer_add_wds_entry_params *param)
1057 {
1058 	wmi_peer_add_wds_entry_cmd_fixed_param *cmd;
1059 	wmi_buf_t buf;
1060 	int len = sizeof(*cmd);
1061 
1062 	buf = wmi_buf_alloc(wmi_handle, len);
1063 	if (!buf) {
1064 		qdf_print("%s: wmi_buf_alloc failed", __func__);
1065 		return QDF_STATUS_E_FAILURE;
1066 	}
1067 	cmd = (wmi_peer_add_wds_entry_cmd_fixed_param *) wmi_buf_data(buf);
1068 	WMITLV_SET_HDR(&cmd->tlv_header,
1069 			WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param,
1070 			WMITLV_GET_STRUCT_TLVLEN
1071 				(wmi_peer_add_wds_entry_cmd_fixed_param));
1072 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr);
1073 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
1074 	cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0;
1075 	cmd->vdev_id = param->vdev_id;
1076 
1077 	wmi_mtrace(WMI_PEER_ADD_WDS_ENTRY_CMDID, cmd->vdev_id, 0);
1078 	return wmi_unified_cmd_send(wmi_handle, buf, len,
1079 			WMI_PEER_ADD_WDS_ENTRY_CMDID);
1080 }
1081 
1082 /**
1083  * send_peer_del_wds_entry_cmd_tlv() - send peer delete command to fw
1084  * @wmi_handle: wmi handle
1085  * @param: pointer holding peer details
1086  *
1087  * Return: 0 for success or error code
1088  */
1089 static QDF_STATUS send_peer_del_wds_entry_cmd_tlv(wmi_unified_t wmi_handle,
1090 					struct peer_del_wds_entry_params *param)
1091 {
1092 	wmi_peer_remove_wds_entry_cmd_fixed_param *cmd;
1093 	wmi_buf_t buf;
1094 	int len = sizeof(*cmd);
1095 
1096 	buf = wmi_buf_alloc(wmi_handle, len);
1097 	if (!buf) {
1098 		qdf_print("%s: wmi_buf_alloc failed", __func__);
1099 		return QDF_STATUS_E_NOMEM;
1100 	}
1101 	cmd = (wmi_peer_remove_wds_entry_cmd_fixed_param *)wmi_buf_data(buf);
1102 	WMITLV_SET_HDR(&cmd->tlv_header,
1103 			WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param,
1104 			WMITLV_GET_STRUCT_TLVLEN
1105 				(wmi_peer_remove_wds_entry_cmd_fixed_param));
1106 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr);
1107 	cmd->vdev_id = param->vdev_id;
1108 	wmi_mtrace(WMI_PEER_REMOVE_WDS_ENTRY_CMDID, cmd->vdev_id, 0);
1109 	return wmi_unified_cmd_send(wmi_handle, buf, len,
1110 			WMI_PEER_REMOVE_WDS_ENTRY_CMDID);
1111 }
1112 
1113 /**
1114  * send_peer_update_wds_entry_cmd_non_tlv() - send peer update command to fw
1115  * @wmi_handle: wmi handle
1116  * @param: pointer holding peer details
1117  *
1118  * Return: 0 for success or error code
1119  */
1120 static QDF_STATUS send_peer_update_wds_entry_cmd_tlv(wmi_unified_t wmi_handle,
1121 				struct peer_update_wds_entry_params *param)
1122 {
1123 	wmi_peer_update_wds_entry_cmd_fixed_param *cmd;
1124 	wmi_buf_t buf;
1125 	int len = sizeof(*cmd);
1126 
1127 	buf = wmi_buf_alloc(wmi_handle, len);
1128 	if (!buf) {
1129 		qdf_print("%s: wmi_buf_alloc failed", __func__);
1130 		return QDF_STATUS_E_NOMEM;
1131 	}
1132 
1133 	/* wmi_buf_alloc returns zeroed command buffer */
1134 	cmd = (wmi_peer_update_wds_entry_cmd_fixed_param *)wmi_buf_data(buf);
1135 	WMITLV_SET_HDR(&cmd->tlv_header,
1136 			WMITLV_TAG_STRUC_wmi_peer_update_wds_entry_cmd_fixed_param,
1137 			WMITLV_GET_STRUCT_TLVLEN
1138 				(wmi_peer_update_wds_entry_cmd_fixed_param));
1139 	cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0;
1140 	cmd->vdev_id = param->vdev_id;
1141 	if (param->wds_macaddr)
1142 		WMI_CHAR_ARRAY_TO_MAC_ADDR(param->wds_macaddr,
1143 				&cmd->wds_macaddr);
1144 	if (param->peer_macaddr)
1145 		WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr,
1146 				&cmd->peer_macaddr);
1147 	wmi_mtrace(WMI_PEER_UPDATE_WDS_ENTRY_CMDID, cmd->vdev_id, 0);
1148 	return wmi_unified_cmd_send(wmi_handle, buf, len,
1149 			WMI_PEER_UPDATE_WDS_ENTRY_CMDID);
1150 }
1151 
1152 /**
1153  * send_pdev_get_tpc_config_cmd_tlv() - send get tpc config command to fw
1154  * @wmi_handle: wmi handle
1155  * @param: pointer to get tpc config params
1156  *
1157  * Return: 0 for success or error code
1158  */
1159 static QDF_STATUS
1160 send_pdev_get_tpc_config_cmd_tlv(wmi_unified_t wmi_handle,
1161 				uint32_t param)
1162 {
1163 	wmi_pdev_get_tpc_config_cmd_fixed_param *cmd;
1164 	wmi_buf_t buf;
1165 	int32_t len = sizeof(wmi_pdev_get_tpc_config_cmd_fixed_param);
1166 
1167 	buf = wmi_buf_alloc(wmi_handle, len);
1168 	if (!buf) {
1169 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
1170 		return QDF_STATUS_E_NOMEM;
1171 	}
1172 	cmd = (wmi_pdev_get_tpc_config_cmd_fixed_param *)wmi_buf_data(buf);
1173 	WMITLV_SET_HDR(&cmd->tlv_header,
1174 		WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param,
1175 		WMITLV_GET_STRUCT_TLVLEN
1176 		(wmi_pdev_get_tpc_config_cmd_fixed_param));
1177 
1178 	cmd->param = param;
1179 	wmi_mtrace(WMI_PDEV_GET_TPC_CONFIG_CMDID, NO_SESSION, 0);
1180 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1181 				 WMI_PDEV_GET_TPC_CONFIG_CMDID)) {
1182 		WMI_LOGE("Send pdev get tpc config cmd failed");
1183 		wmi_buf_free(buf);
1184 		return QDF_STATUS_E_FAILURE;
1185 
1186 	}
1187 	WMI_LOGD("%s:send success", __func__);
1188 
1189 	return QDF_STATUS_SUCCESS;
1190 }
1191 
1192 #ifdef WLAN_SUPPORT_GREEN_AP
1193 /**
1194  * send_green_ap_ps_cmd_tlv() - enable green ap powersave command
1195  * @wmi_handle: wmi handle
1196  * @value: value
1197  * @pdev_id: pdev id to have radio context
1198  *
1199  * Return: QDF_STATUS_SUCCESS for success or error code
1200  */
1201 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle,
1202 						uint32_t value, uint8_t pdev_id)
1203 {
1204 	wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd;
1205 	wmi_buf_t buf;
1206 	int32_t len = sizeof(*cmd);
1207 
1208 	WMI_LOGD("Set Green AP PS val %d", value);
1209 
1210 	buf = wmi_buf_alloc(wmi_handle, len);
1211 	if (!buf) {
1212 		WMI_LOGP("%s: Green AP PS Mem Alloc Failed", __func__);
1213 		return QDF_STATUS_E_NOMEM;
1214 	}
1215 
1216 	cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf);
1217 	WMITLV_SET_HDR(&cmd->tlv_header,
1218 		   WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param,
1219 		   WMITLV_GET_STRUCT_TLVLEN
1220 			       (wmi_pdev_green_ap_ps_enable_cmd_fixed_param));
1221 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
1222 	cmd->enable = value;
1223 
1224 	wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0);
1225 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1226 				 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) {
1227 		WMI_LOGE("Set Green AP PS param Failed val %d", value);
1228 		wmi_buf_free(buf);
1229 		return QDF_STATUS_E_FAILURE;
1230 	}
1231 
1232 	return 0;
1233 }
1234 #endif
1235 
1236 /**
1237  * send_pdev_utf_cmd_tlv() - send utf command to fw
1238  * @wmi_handle: wmi handle
1239  * @param: pointer to pdev_utf_params
1240  * @mac_id: mac id to have radio context
1241  *
1242  * Return: QDF_STATUS_SUCCESS for success or error code
1243  */
1244 static QDF_STATUS
1245 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle,
1246 				struct pdev_utf_params *param,
1247 				uint8_t mac_id)
1248 {
1249 	wmi_buf_t buf;
1250 	uint8_t *cmd;
1251 	/* if param->len is 0 no data is sent, return error */
1252 	QDF_STATUS ret = QDF_STATUS_E_INVAL;
1253 	static uint8_t msgref = 1;
1254 	uint8_t segNumber = 0, segInfo, numSegments;
1255 	uint16_t chunk_len, total_bytes;
1256 	uint8_t *bufpos;
1257 	struct seg_hdr_info segHdrInfo;
1258 
1259 	bufpos = param->utf_payload;
1260 	total_bytes = param->len;
1261 	ASSERT(total_bytes / MAX_WMI_UTF_LEN ==
1262 	       (uint8_t) (total_bytes / MAX_WMI_UTF_LEN));
1263 	numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN);
1264 
1265 	if (param->len - (numSegments * MAX_WMI_UTF_LEN))
1266 		numSegments++;
1267 
1268 	while (param->len) {
1269 		if (param->len > MAX_WMI_UTF_LEN)
1270 			chunk_len = MAX_WMI_UTF_LEN;    /* MAX message */
1271 		else
1272 			chunk_len = param->len;
1273 
1274 		buf = wmi_buf_alloc(wmi_handle,
1275 				    (chunk_len + sizeof(segHdrInfo) +
1276 				     WMI_TLV_HDR_SIZE));
1277 		if (!buf) {
1278 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
1279 			return QDF_STATUS_E_NOMEM;
1280 		}
1281 
1282 		cmd = (uint8_t *) wmi_buf_data(buf);
1283 
1284 		segHdrInfo.len = total_bytes;
1285 		segHdrInfo.msgref = msgref;
1286 		segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF);
1287 		segHdrInfo.segmentInfo = segInfo;
1288 		segHdrInfo.pad = 0;
1289 
1290 		WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d,"
1291 			 " segHdrInfo.segmentInfo = %d",
1292 			 __func__, segHdrInfo.len, segHdrInfo.msgref,
1293 			 segHdrInfo.segmentInfo);
1294 
1295 		WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d"
1296 			 "chunk len %d", __func__, total_bytes, segNumber,
1297 			 numSegments, chunk_len);
1298 
1299 		segNumber++;
1300 
1301 		WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE,
1302 			       (chunk_len + sizeof(segHdrInfo)));
1303 		cmd += WMI_TLV_HDR_SIZE;
1304 		memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo));   /* 4 bytes */
1305 		memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len);
1306 
1307 		wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0);
1308 		ret = wmi_unified_cmd_send(wmi_handle, buf,
1309 					   (chunk_len + sizeof(segHdrInfo) +
1310 					    WMI_TLV_HDR_SIZE),
1311 					   WMI_PDEV_UTF_CMDID);
1312 
1313 		if (QDF_IS_STATUS_ERROR(ret)) {
1314 			WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command");
1315 			wmi_buf_free(buf);
1316 			break;
1317 		}
1318 
1319 		param->len -= chunk_len;
1320 		bufpos += chunk_len;
1321 	}
1322 
1323 	msgref++;
1324 
1325 	return ret;
1326 }
1327 #ifdef CONFIG_MCL
1328 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle,
1329 				uint32_t host_param)
1330 {
1331 	return host_param;
1332 }
1333 #else
1334 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle,
1335 				uint32_t host_param)
1336 {
1337 	if (host_param < wmi_pdev_param_max)
1338 		return wmi_handle->pdev_param[host_param];
1339 
1340 	return WMI_UNAVAILABLE_PARAM;
1341 }
1342 #endif
1343 /**
1344  * send_pdev_param_cmd_tlv() - set pdev parameters
1345  * @wmi_handle: wmi handle
1346  * @param: pointer to pdev parameter
1347  * @mac_id: radio context
1348  *
1349  * Return: 0 on success, errno on failure
1350  */
1351 static QDF_STATUS
1352 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle,
1353 			   struct pdev_params *param,
1354 				uint8_t mac_id)
1355 {
1356 	QDF_STATUS ret;
1357 	wmi_pdev_set_param_cmd_fixed_param *cmd;
1358 	wmi_buf_t buf;
1359 	uint16_t len = sizeof(*cmd);
1360 	uint32_t pdev_param;
1361 
1362 	pdev_param = convert_host_pdev_param_tlv(wmi_handle, param->param_id);
1363 	if (pdev_param == WMI_UNAVAILABLE_PARAM) {
1364 		WMI_LOGW("%s: Unavailable param %d\n",
1365 				__func__, param->param_id);
1366 		return QDF_STATUS_E_INVAL;
1367 	}
1368 
1369 	buf = wmi_buf_alloc(wmi_handle, len);
1370 	if (!buf) {
1371 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
1372 		return QDF_STATUS_E_NOMEM;
1373 	}
1374 	cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
1375 	WMITLV_SET_HDR(&cmd->tlv_header,
1376 		       WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param,
1377 		       WMITLV_GET_STRUCT_TLVLEN
1378 			       (wmi_pdev_set_param_cmd_fixed_param));
1379 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
1380 	cmd->param_id = pdev_param;
1381 	cmd->param_value = param->param_value;
1382 	WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id,
1383 				param->param_value);
1384 	wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0);
1385 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1386 				   WMI_PDEV_SET_PARAM_CMDID);
1387 	if (QDF_IS_STATUS_ERROR(ret)) {
1388 		WMI_LOGE("Failed to send set param command ret = %d", ret);
1389 		wmi_buf_free(buf);
1390 	}
1391 	return ret;
1392 }
1393 
1394 /**
1395  * send_suspend_cmd_tlv() - WMI suspend function
1396  * @param wmi_handle      : handle to WMI.
1397  * @param param    : pointer to hold suspend parameter
1398  * @mac_id: radio context
1399  *
1400  * Return 0  on success and -ve on failure.
1401  */
1402 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle,
1403 				struct suspend_params *param,
1404 				uint8_t mac_id)
1405 {
1406 	wmi_pdev_suspend_cmd_fixed_param *cmd;
1407 	wmi_buf_t wmibuf;
1408 	uint32_t len = sizeof(*cmd);
1409 	int32_t ret;
1410 
1411 	/*
1412 	 * send the command to Target to ignore the
1413 	 * PCIE reset so as to ensure that Host and target
1414 	 * states are in sync
1415 	 */
1416 	wmibuf = wmi_buf_alloc(wmi_handle, len);
1417 	if (wmibuf == NULL)
1418 		return QDF_STATUS_E_NOMEM;
1419 
1420 	cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf);
1421 	WMITLV_SET_HDR(&cmd->tlv_header,
1422 		       WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param,
1423 		       WMITLV_GET_STRUCT_TLVLEN
1424 			       (wmi_pdev_suspend_cmd_fixed_param));
1425 	if (param->disable_target_intr)
1426 		cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR;
1427 	else
1428 		cmd->suspend_opt = WMI_PDEV_SUSPEND;
1429 
1430 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
1431 
1432 	wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0);
1433 	ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len,
1434 				 WMI_PDEV_SUSPEND_CMDID);
1435 	if (ret) {
1436 		wmi_buf_free(wmibuf);
1437 		WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command");
1438 	}
1439 
1440 	return ret;
1441 }
1442 
1443 /**
1444  * send_resume_cmd_tlv() - WMI resume function
1445  * @param wmi_handle      : handle to WMI.
1446  * @mac_id: radio context
1447  *
1448  * Return: 0  on success and -ve on failure.
1449  */
1450 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle,
1451 				uint8_t mac_id)
1452 {
1453 	wmi_buf_t wmibuf;
1454 	wmi_pdev_resume_cmd_fixed_param *cmd;
1455 	QDF_STATUS ret;
1456 
1457 	wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
1458 	if (wmibuf == NULL)
1459 		return QDF_STATUS_E_NOMEM;
1460 	cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf);
1461 	WMITLV_SET_HDR(&cmd->tlv_header,
1462 		       WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param,
1463 		       WMITLV_GET_STRUCT_TLVLEN
1464 			       (wmi_pdev_resume_cmd_fixed_param));
1465 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
1466 	wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0);
1467 	ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd),
1468 				   WMI_PDEV_RESUME_CMDID);
1469 	if (QDF_IS_STATUS_ERROR(ret)) {
1470 		WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command");
1471 		wmi_buf_free(wmibuf);
1472 	}
1473 
1474 	return ret;
1475 }
1476 
1477 #ifdef FEATURE_WLAN_D0WOW
1478 /**
1479  *  send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function
1480  *  @param wmi_handle: handle to WMI.
1481  *  @mac_id: radio context
1482  *
1483  *  Return: 0  on success  and  error code on failure.
1484  */
1485 static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle,
1486 				uint8_t mac_id)
1487 {
1488 	wmi_d0_wow_enable_disable_cmd_fixed_param *cmd;
1489 	wmi_buf_t buf;
1490 	int32_t len;
1491 	QDF_STATUS status;
1492 
1493 	len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param);
1494 
1495 	buf = wmi_buf_alloc(wmi_handle, len);
1496 	if (!buf) {
1497 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
1498 		return QDF_STATUS_E_NOMEM;
1499 	}
1500 	cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf);
1501 	WMITLV_SET_HDR(&cmd->tlv_header,
1502 		WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param,
1503 		WMITLV_GET_STRUCT_TLVLEN
1504 		(wmi_d0_wow_enable_disable_cmd_fixed_param));
1505 
1506 	cmd->enable = true;
1507 
1508 	wmi_mtrace(WMI_D0_WOW_ENABLE_DISABLE_CMDID, NO_SESSION, 0);
1509 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
1510 			WMI_D0_WOW_ENABLE_DISABLE_CMDID);
1511 	if (QDF_IS_STATUS_ERROR(status))
1512 		wmi_buf_free(buf);
1513 
1514 	return status;
1515 }
1516 
1517 /**
1518  *  send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function
1519  *  @param wmi_handle: handle to WMI.
1520  *  @mac_id: radio context
1521  *
1522  *  Return: 0  on success  and  error code on failure.
1523  */
1524 static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle,
1525 				uint8_t mac_id)
1526 {
1527 	wmi_d0_wow_enable_disable_cmd_fixed_param *cmd;
1528 	wmi_buf_t buf;
1529 	int32_t len;
1530 	QDF_STATUS status;
1531 
1532 	len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param);
1533 
1534 	buf = wmi_buf_alloc(wmi_handle, len);
1535 	if (!buf) {
1536 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
1537 		return QDF_STATUS_E_NOMEM;
1538 	}
1539 	cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf);
1540 	WMITLV_SET_HDR(&cmd->tlv_header,
1541 		WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param,
1542 		WMITLV_GET_STRUCT_TLVLEN
1543 		(wmi_d0_wow_enable_disable_cmd_fixed_param));
1544 
1545 	cmd->enable = false;
1546 
1547 	wmi_mtrace(WMI_D0_WOW_ENABLE_DISABLE_CMDID, NO_SESSION, 0);
1548 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
1549 			WMI_D0_WOW_ENABLE_DISABLE_CMDID);
1550 	if (QDF_IS_STATUS_ERROR(status))
1551 		wmi_buf_free(buf);
1552 
1553 	return status;
1554 }
1555 #endif
1556 
1557 /**
1558  *  send_wow_enable_cmd_tlv() - WMI wow enable function
1559  *  @param wmi_handle      : handle to WMI.
1560  *  @param param    : pointer to hold wow enable parameter
1561  *  @mac_id: radio context
1562  *
1563  *  Return: 0  on success and -ve on failure.
1564  */
1565 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle,
1566 				struct wow_cmd_params *param,
1567 				uint8_t mac_id)
1568 {
1569 	wmi_wow_enable_cmd_fixed_param *cmd;
1570 	wmi_buf_t buf;
1571 	int32_t len;
1572 	int32_t ret;
1573 
1574 	len = sizeof(wmi_wow_enable_cmd_fixed_param);
1575 
1576 	buf = wmi_buf_alloc(wmi_handle, len);
1577 	if (!buf) {
1578 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
1579 		return QDF_STATUS_E_NOMEM;
1580 	}
1581 	cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf);
1582 	WMITLV_SET_HDR(&cmd->tlv_header,
1583 		       WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param,
1584 		       WMITLV_GET_STRUCT_TLVLEN
1585 			       (wmi_wow_enable_cmd_fixed_param));
1586 	cmd->enable = param->enable;
1587 	if (param->can_suspend_link)
1588 		cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED;
1589 	else
1590 		cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED;
1591 	cmd->flags = param->flags;
1592 
1593 	WMI_LOGI("suspend type: %s",
1594 		cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ?
1595 		"WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED");
1596 
1597 	wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0);
1598 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1599 				   WMI_WOW_ENABLE_CMDID);
1600 	if (ret)
1601 		wmi_buf_free(buf);
1602 
1603 	return ret;
1604 }
1605 
1606 /**
1607  * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters
1608  * @wmi_handle: wmi handle
1609  * @peer_addr: peer mac address
1610  * @param: pointer to ap_ps parameter structure
1611  *
1612  * Return: QDF_STATUS_SUCCESS for success or error code
1613  */
1614 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle,
1615 					   uint8_t *peer_addr,
1616 					   struct ap_ps_params *param)
1617 {
1618 	wmi_ap_ps_peer_cmd_fixed_param *cmd;
1619 	wmi_buf_t buf;
1620 	int32_t err;
1621 
1622 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
1623 	if (!buf) {
1624 		WMI_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd");
1625 		return QDF_STATUS_E_NOMEM;
1626 	}
1627 	cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf);
1628 	WMITLV_SET_HDR(&cmd->tlv_header,
1629 		       WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param,
1630 		       WMITLV_GET_STRUCT_TLVLEN
1631 			       (wmi_ap_ps_peer_cmd_fixed_param));
1632 	cmd->vdev_id = param->vdev_id;
1633 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
1634 	cmd->param = param->param;
1635 	cmd->value = param->value;
1636 	wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0);
1637 	err = wmi_unified_cmd_send(wmi_handle, buf,
1638 				   sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID);
1639 	if (err) {
1640 		WMI_LOGE("Failed to send set_ap_ps_param cmd");
1641 		wmi_buf_free(buf);
1642 		return QDF_STATUS_E_FAILURE;
1643 	}
1644 
1645 	return 0;
1646 }
1647 
1648 /**
1649  * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters
1650  * @wmi_handle: wmi handle
1651  * @peer_addr: peer mac address
1652  * @param: pointer to sta_ps parameter structure
1653  *
1654  * Return: QDF_STATUS_SUCCESS for success or error code
1655  */
1656 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle,
1657 					   struct sta_ps_params *param)
1658 {
1659 	wmi_sta_powersave_param_cmd_fixed_param *cmd;
1660 	wmi_buf_t buf;
1661 	int32_t len = sizeof(*cmd);
1662 
1663 	buf = wmi_buf_alloc(wmi_handle, len);
1664 	if (!buf) {
1665 		WMI_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__);
1666 		return QDF_STATUS_E_NOMEM;
1667 	}
1668 
1669 	cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf);
1670 	WMITLV_SET_HDR(&cmd->tlv_header,
1671 		       WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param,
1672 		       WMITLV_GET_STRUCT_TLVLEN
1673 			       (wmi_sta_powersave_param_cmd_fixed_param));
1674 	cmd->vdev_id = param->vdev_id;
1675 	cmd->param = param->param;
1676 	cmd->value = param->value;
1677 
1678 	wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0);
1679 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1680 				 WMI_STA_POWERSAVE_PARAM_CMDID)) {
1681 		WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d",
1682 			 param->vdev_id, param->param, param->value);
1683 		wmi_buf_free(buf);
1684 		return QDF_STATUS_E_FAILURE;
1685 	}
1686 
1687 	return 0;
1688 }
1689 
1690 /**
1691  * send_crash_inject_cmd_tlv() - inject fw crash
1692  * @wmi_handle: wmi handle
1693  * @param: ponirt to crash inject parameter structure
1694  *
1695  * Return: QDF_STATUS_SUCCESS for success or return error
1696  */
1697 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle,
1698 			 struct crash_inject *param)
1699 {
1700 	int32_t ret = 0;
1701 	WMI_FORCE_FW_HANG_CMD_fixed_param *cmd;
1702 	uint16_t len = sizeof(*cmd);
1703 	wmi_buf_t buf;
1704 
1705 	buf = wmi_buf_alloc(wmi_handle, len);
1706 	if (!buf) {
1707 		WMI_LOGE("%s: wmi_buf_alloc failed!", __func__);
1708 		return QDF_STATUS_E_NOMEM;
1709 	}
1710 
1711 	cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf);
1712 	WMITLV_SET_HDR(&cmd->tlv_header,
1713 		       WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param,
1714 		       WMITLV_GET_STRUCT_TLVLEN
1715 			       (WMI_FORCE_FW_HANG_CMD_fixed_param));
1716 	cmd->type = param->type;
1717 	cmd->delay_time_ms = param->delay_time_ms;
1718 
1719 	wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0);
1720 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1721 		WMI_FORCE_FW_HANG_CMDID);
1722 	if (ret) {
1723 		WMI_LOGE("%s: Failed to send set param command, ret = %d",
1724 			 __func__, ret);
1725 		wmi_buf_free(buf);
1726 	}
1727 
1728 	return ret;
1729 }
1730 
1731 #ifdef FEATURE_FW_LOG_PARSING
1732 /**
1733  *  send_dbglog_cmd_tlv() - set debug log level
1734  *  @param wmi_handle      : handle to WMI.
1735  *  @param param    : pointer to hold dbglog level parameter
1736  *
1737  *  Return: 0  on success and -ve on failure.
1738  */
1739  static QDF_STATUS
1740 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle,
1741 				struct dbglog_params *dbglog_param)
1742 {
1743 	wmi_buf_t buf;
1744 	wmi_debug_log_config_cmd_fixed_param *configmsg;
1745 	QDF_STATUS status;
1746 	int32_t i;
1747 	int32_t len;
1748 	int8_t *buf_ptr;
1749 	int32_t *module_id_bitmap_array;     /* Used to fomr the second tlv */
1750 
1751 	ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS);
1752 
1753 	/* Allocate size for 2 tlvs - including tlv hdr space for second tlv */
1754 	len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE +
1755 	      (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS);
1756 	buf = wmi_buf_alloc(wmi_handle, len);
1757 	if (buf == NULL)
1758 		return QDF_STATUS_E_NOMEM;
1759 
1760 	configmsg =
1761 		(wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf));
1762 	buf_ptr = (int8_t *) configmsg;
1763 	WMITLV_SET_HDR(&configmsg->tlv_header,
1764 		       WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param,
1765 		       WMITLV_GET_STRUCT_TLVLEN
1766 			       (wmi_debug_log_config_cmd_fixed_param));
1767 	configmsg->dbg_log_param = dbglog_param->param;
1768 	configmsg->value = dbglog_param->val;
1769 	/* Filling in the data part of second tlv -- should
1770 	 * follow first tlv _ WMI_TLV_HDR_SIZE */
1771 	module_id_bitmap_array = (uint32_t *) (buf_ptr +
1772 				       sizeof
1773 				       (wmi_debug_log_config_cmd_fixed_param)
1774 				       + WMI_TLV_HDR_SIZE);
1775 	WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param),
1776 		       WMITLV_TAG_ARRAY_UINT32,
1777 		       sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS);
1778 	if (dbglog_param->module_id_bitmap) {
1779 		for (i = 0; i < dbglog_param->bitmap_len; ++i) {
1780 			module_id_bitmap_array[i] =
1781 					dbglog_param->module_id_bitmap[i];
1782 		}
1783 	}
1784 
1785 	wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0);
1786 	status = wmi_unified_cmd_send(wmi_handle, buf,
1787 				      len, WMI_DBGLOG_CFG_CMDID);
1788 
1789 	if (status != QDF_STATUS_SUCCESS)
1790 		wmi_buf_free(buf);
1791 
1792 	return status;
1793 }
1794 #endif
1795 
1796 #ifdef CONFIG_MCL
1797 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle,
1798 				uint32_t host_param)
1799 {
1800 	return host_param;
1801 }
1802 #else
1803 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle,
1804 				uint32_t host_param)
1805 {
1806 	if (host_param < wmi_vdev_param_max)
1807 		return wmi_handle->vdev_param[host_param];
1808 
1809 	return WMI_UNAVAILABLE_PARAM;
1810 }
1811 #endif
1812 /**
1813  *  send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function
1814  *  @param wmi_handle      : handle to WMI.
1815  *  @param macaddr        : MAC address
1816  *  @param param    : pointer to hold vdev set parameter
1817  *
1818  *  Return: 0  on success and -ve on failure.
1819  */
1820 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle,
1821 				struct vdev_set_params *param)
1822 {
1823 	QDF_STATUS ret;
1824 	wmi_vdev_set_param_cmd_fixed_param *cmd;
1825 	wmi_buf_t buf;
1826 	uint16_t len = sizeof(*cmd);
1827 	uint32_t vdev_param;
1828 
1829 	vdev_param = convert_host_vdev_param_tlv(wmi_handle, param->param_id);
1830 	if (vdev_param == WMI_UNAVAILABLE_PARAM) {
1831 		WMI_LOGW("%s:Vdev param %d not available", __func__,
1832 				param->param_id);
1833 		return QDF_STATUS_E_INVAL;
1834 
1835 	}
1836 
1837 	buf = wmi_buf_alloc(wmi_handle, len);
1838 	if (!buf) {
1839 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
1840 		return QDF_STATUS_E_NOMEM;
1841 	}
1842 	cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
1843 	WMITLV_SET_HDR(&cmd->tlv_header,
1844 		       WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param,
1845 		       WMITLV_GET_STRUCT_TLVLEN
1846 			       (wmi_vdev_set_param_cmd_fixed_param));
1847 	cmd->vdev_id = param->if_id;
1848 	cmd->param_id = vdev_param;
1849 	cmd->param_value = param->param_value;
1850 	WMI_LOGD("Setting vdev %d param = %x, value = %u",
1851 		 cmd->vdev_id, cmd->param_id, cmd->param_value);
1852 	wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0);
1853 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1854 				   WMI_VDEV_SET_PARAM_CMDID);
1855 	if (QDF_IS_STATUS_ERROR(ret)) {
1856 		WMI_LOGE("Failed to send set param command ret = %d", ret);
1857 		wmi_buf_free(buf);
1858 	}
1859 
1860 	return ret;
1861 }
1862 
1863 /**
1864  *  send_stats_request_cmd_tlv() - WMI request stats function
1865  *  @param wmi_handle      : handle to WMI.
1866  *  @param macaddr        : MAC address
1867  *  @param param    : pointer to hold stats request parameter
1868  *
1869  *  Return: 0  on success and -ve on failure.
1870  */
1871 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle,
1872 				uint8_t macaddr[IEEE80211_ADDR_LEN],
1873 				struct stats_request_params *param)
1874 {
1875 	int32_t ret;
1876 	wmi_request_stats_cmd_fixed_param *cmd;
1877 	wmi_buf_t buf;
1878 	uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param);
1879 
1880 	buf = wmi_buf_alloc(wmi_handle, len);
1881 	if (!buf) {
1882 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
1883 		return -QDF_STATUS_E_NOMEM;
1884 	}
1885 
1886 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
1887 	WMITLV_SET_HDR(&cmd->tlv_header,
1888 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
1889 		       WMITLV_GET_STRUCT_TLVLEN
1890 			       (wmi_request_stats_cmd_fixed_param));
1891 	cmd->stats_id = param->stats_id;
1892 	cmd->vdev_id = param->vdev_id;
1893 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
1894 							param->pdev_id);
1895 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
1896 
1897 	WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->",
1898 				cmd->stats_id, cmd->vdev_id, cmd->pdev_id);
1899 
1900 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
1901 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1902 					 WMI_REQUEST_STATS_CMDID);
1903 
1904 	if (ret) {
1905 		WMI_LOGE("Failed to send status request to fw =%d", ret);
1906 		wmi_buf_free(buf);
1907 	}
1908 
1909 	return ret;
1910 }
1911 
1912 #ifdef CONFIG_WIN
1913 /**
1914  *  send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log
1915  *  @param wmi_handle      : handle to WMI.
1916  *  @param PKTLOG_EVENT	: packet log event
1917  *  @mac_id: mac id to have radio context
1918  *
1919  *  Return: 0  on success and -ve on failure.
1920  */
1921 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle,
1922 			WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id)
1923 {
1924 	int32_t ret;
1925 	wmi_pdev_pktlog_enable_cmd_fixed_param *cmd;
1926 	wmi_buf_t buf;
1927 	uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param);
1928 
1929 	buf = wmi_buf_alloc(wmi_handle, len);
1930 	if (!buf) {
1931 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
1932 		return -QDF_STATUS_E_NOMEM;
1933 	}
1934 
1935 	cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf);
1936 	WMITLV_SET_HDR(&cmd->tlv_header,
1937 		       WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param,
1938 		       WMITLV_GET_STRUCT_TLVLEN
1939 			       (wmi_pdev_pktlog_enable_cmd_fixed_param));
1940 	cmd->evlist = PKTLOG_EVENT;
1941 	cmd->pdev_id = mac_id;
1942 	wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0);
1943 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1944 					 WMI_PDEV_PKTLOG_ENABLE_CMDID);
1945 	if (ret) {
1946 		WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret);
1947 		wmi_buf_free(buf);
1948 	}
1949 
1950 	return ret;
1951 }
1952 
1953 /**
1954  *  send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log
1955  *  @param wmi_handle      : handle to WMI.
1956  *  @mac_id: mac id to have radio context
1957  *
1958  *  Return: 0  on success and -ve on failure.
1959  */
1960 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle,
1961 			uint8_t mac_id)
1962 {
1963 	int32_t ret;
1964 	wmi_pdev_pktlog_disable_cmd_fixed_param *cmd;
1965 	wmi_buf_t buf;
1966 	uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param);
1967 
1968 	buf = wmi_buf_alloc(wmi_handle, len);
1969 	if (!buf) {
1970 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
1971 		return -QDF_STATUS_E_NOMEM;
1972 	}
1973 
1974 	cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf);
1975 	WMITLV_SET_HDR(&cmd->tlv_header,
1976 		       WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param,
1977 		       WMITLV_GET_STRUCT_TLVLEN
1978 			       (wmi_pdev_pktlog_disable_cmd_fixed_param));
1979 	cmd->pdev_id = mac_id;
1980 	wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0);
1981 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1982 					 WMI_PDEV_PKTLOG_DISABLE_CMDID);
1983 	if (ret) {
1984 		WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret);
1985 		wmi_buf_free(buf);
1986 	}
1987 
1988 	return ret;
1989 }
1990 #else
1991 /**
1992  *  send_packet_log_enable_cmd_tlv() - Send WMI command to enable
1993  *  packet-log
1994  *  @param wmi_handle      : handle to WMI.
1995  *  @param macaddr        : MAC address
1996  *  @param param    : pointer to hold stats request parameter
1997  *
1998  *  Return: 0  on success and -ve on failure.
1999  */
2000 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle,
2001 				uint8_t macaddr[IEEE80211_ADDR_LEN],
2002 				struct packet_enable_params *param)
2003 {
2004 	return 0;
2005 }
2006 /**
2007  *  send_packet_log_disable_cmd_tlv() - Send WMI command to disable
2008  *  packet-log
2009  *  @param wmi_handle      : handle to WMI.
2010  *  @mac_id: mac id to have radio context
2011  *
2012  *  Return: 0  on success and -ve on failure.
2013  */
2014 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle,
2015 				uint8_t mac_id)
2016 {
2017 	return 0;
2018 }
2019 #endif
2020 
2021 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff
2022 /**
2023  *  send_time_stamp_sync_cmd_tlv() - Send WMI command to
2024  *  sync time between bwtween host and firmware
2025  *  @param wmi_handle      : handle to WMI.
2026  *
2027  *  Return: None
2028  */
2029 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle)
2030 {
2031 	wmi_buf_t buf;
2032 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2033 	WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp;
2034 	int32_t len;
2035 	qdf_time_t time_ms;
2036 
2037 	len = sizeof(*time_stamp);
2038 	buf = wmi_buf_alloc(wmi_handle, len);
2039 
2040 	if (!buf) {
2041 		WMI_LOGP(FL("wmi_buf_alloc failed"));
2042 		return;
2043 	}
2044 	time_stamp =
2045 		(WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *)
2046 			(wmi_buf_data(buf));
2047 	WMITLV_SET_HDR(&time_stamp->tlv_header,
2048 		WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param,
2049 		WMITLV_GET_STRUCT_TLVLEN(
2050 		WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param));
2051 
2052 	time_ms = qdf_get_time_of_the_day_ms();
2053 	time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS;
2054 	time_stamp->time_stamp_low = time_ms &
2055 		WMI_FW_TIME_STAMP_LOW_MASK;
2056 	/*
2057 	 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms
2058 	 * wont exceed 27 bit
2059 	 */
2060 	time_stamp->time_stamp_high = 0;
2061 	WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"),
2062 		time_stamp->mode, time_stamp->time_stamp_low,
2063 		time_stamp->time_stamp_high);
2064 
2065 	wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0);
2066 	status = wmi_unified_cmd_send(wmi_handle, buf,
2067 				      len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID);
2068 	if (status) {
2069 		WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command");
2070 		wmi_buf_free(buf);
2071 	}
2072 
2073 }
2074 
2075 #ifdef WLAN_SUPPORT_FILS
2076 /**
2077  * extract_swfda_vdev_id_tlv() - extract swfda vdev id from event
2078  * @wmi_handle: wmi handle
2079  * @evt_buf: pointer to event buffer
2080  * @vdev_id: pointer to hold vdev id
2081  *
2082  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure
2083  */
2084 static QDF_STATUS
2085 extract_swfda_vdev_id_tlv(wmi_unified_t wmi_handle,
2086 			  void *evt_buf, uint32_t *vdev_id)
2087 {
2088 	WMI_HOST_SWFDA_EVENTID_param_tlvs *param_buf;
2089 	wmi_host_swfda_event_fixed_param *swfda_event;
2090 
2091 	param_buf = (WMI_HOST_SWFDA_EVENTID_param_tlvs *)evt_buf;
2092 	if (!param_buf) {
2093 		WMI_LOGE("Invalid swfda event buffer");
2094 		return QDF_STATUS_E_INVAL;
2095 	}
2096 	swfda_event = param_buf->fixed_param;
2097 	*vdev_id = swfda_event->vdev_id;
2098 
2099 	return QDF_STATUS_SUCCESS;
2100 }
2101 
2102 /**
2103  * send_vdev_fils_enable_cmd_tlv() - enable/Disable FD Frame command to fw
2104  * @wmi_handle: wmi handle
2105  * @param: pointer to hold FILS discovery enable param
2106  *
2107  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE on failure
2108  */
2109 static QDF_STATUS
2110 send_vdev_fils_enable_cmd_tlv(wmi_unified_t wmi_handle,
2111 			      struct config_fils_params *param)
2112 {
2113 	wmi_enable_fils_cmd_fixed_param *cmd;
2114 	wmi_buf_t buf;
2115 	QDF_STATUS status;
2116 	uint32_t len = sizeof(wmi_enable_fils_cmd_fixed_param);
2117 
2118 	buf = wmi_buf_alloc(wmi_handle, len);
2119 	if (!buf) {
2120 		WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__);
2121 		return QDF_STATUS_E_NOMEM;
2122 	}
2123 	cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data(buf);
2124 	WMITLV_SET_HDR(&cmd->tlv_header,
2125 		       WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param,
2126 		       WMITLV_GET_STRUCT_TLVLEN(
2127 		       wmi_enable_fils_cmd_fixed_param));
2128 	cmd->vdev_id = param->vdev_id;
2129 	cmd->fd_period = param->fd_period;
2130 	WMI_LOGI("Setting FD period to %d vdev id : %d\n",
2131 		 param->fd_period, param->vdev_id);
2132 
2133 	wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, 0);
2134 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
2135 				      WMI_ENABLE_FILS_CMDID);
2136 	if (status != QDF_STATUS_SUCCESS) {
2137 		wmi_buf_free(buf);
2138 		return QDF_STATUS_E_FAILURE;
2139 	}
2140 
2141 	return QDF_STATUS_SUCCESS;
2142 }
2143 
2144 /**
2145  * send_fils_discovery_send_cmd_tlv() - WMI FILS Discovery send function
2146  * @wmi_handle: wmi handle
2147  * @param: pointer to hold FD send cmd parameter
2148  *
2149  * Return : QDF_STATUS_SUCCESS on success and QDF_STATUS_E_NOMEM on failure.
2150  */
2151 static QDF_STATUS
2152 send_fils_discovery_send_cmd_tlv(wmi_unified_t wmi_handle,
2153 				 struct fd_params *param)
2154 {
2155 	QDF_STATUS ret;
2156 	wmi_fd_send_from_host_cmd_fixed_param *cmd;
2157 	wmi_buf_t wmi_buf;
2158 	qdf_dma_addr_t dma_addr;
2159 
2160 	wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
2161 	if (!wmi_buf) {
2162 		WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__);
2163 		return QDF_STATUS_E_NOMEM;
2164 	}
2165 	cmd = (wmi_fd_send_from_host_cmd_fixed_param *)wmi_buf_data(wmi_buf);
2166 	WMITLV_SET_HDR(&cmd->tlv_header,
2167 		       WMITLV_TAG_STRUC_wmi_fd_send_from_host_cmd_fixed_param,
2168 		       WMITLV_GET_STRUCT_TLVLEN(
2169 		       wmi_fd_send_from_host_cmd_fixed_param));
2170 	cmd->vdev_id = param->vdev_id;
2171 	cmd->data_len = qdf_nbuf_len(param->wbuf);
2172 	dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0);
2173 	qdf_dmaaddr_to_32s(dma_addr, &cmd->frag_ptr_lo, &cmd->frag_ptr_hi);
2174 	cmd->frame_ctrl = param->frame_ctrl;
2175 
2176 	wmi_mtrace(WMI_PDEV_SEND_FD_CMDID, cmd->vdev_id, 0);
2177 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd),
2178 				   WMI_PDEV_SEND_FD_CMDID);
2179 	if (ret != QDF_STATUS_SUCCESS) {
2180 		WMI_LOGE("%s: Failed to send fils discovery frame: %d",
2181 			 __func__, ret);
2182 		wmi_buf_free(wmi_buf);
2183 	}
2184 
2185 	return ret;
2186 }
2187 #endif /* WLAN_SUPPORT_FILS */
2188 
2189 static QDF_STATUS send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle,
2190 				struct beacon_params *param)
2191 {
2192 	QDF_STATUS ret;
2193 	wmi_bcn_send_from_host_cmd_fixed_param *cmd;
2194 	wmi_buf_t wmi_buf;
2195 	qdf_dma_addr_t dma_addr;
2196 	uint32_t dtim_flag = 0;
2197 
2198 	wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
2199 	if (!wmi_buf) {
2200 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
2201 		return QDF_STATUS_E_NOMEM;
2202 	}
2203 	if (param->is_dtim_count_zero) {
2204 		dtim_flag |= WMI_BCN_SEND_DTIM_ZERO;
2205 		if (param->is_bitctl_reqd) {
2206 			/* deliver CAB traffic in next DTIM beacon */
2207 			dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET;
2208 		}
2209 	}
2210 	cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf);
2211 	WMITLV_SET_HDR(&cmd->tlv_header,
2212 		WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param,
2213 		WMITLV_GET_STRUCT_TLVLEN
2214 				(wmi_bcn_send_from_host_cmd_fixed_param));
2215 	cmd->vdev_id = param->vdev_id;
2216 	cmd->data_len = qdf_nbuf_len(param->wbuf);
2217 	cmd->frame_ctrl = param->frame_ctrl;
2218 	cmd->dtim_flag = dtim_flag;
2219 	dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0);
2220 	cmd->frag_ptr_lo = qdf_get_lower_32_bits(dma_addr);
2221 #if defined(HTT_PADDR64)
2222 	cmd->frag_ptr_hi = qdf_get_upper_32_bits(dma_addr) & 0x1F;
2223 #endif
2224 	cmd->bcn_antenna = param->bcn_txant;
2225 
2226 	wmi_mtrace(WMI_PDEV_SEND_BCN_CMDID, cmd->vdev_id, 0);
2227 	ret = wmi_unified_cmd_send(wmi_handle,
2228 			wmi_buf, sizeof(*cmd), WMI_PDEV_SEND_BCN_CMDID);
2229 	if (ret != QDF_STATUS_SUCCESS) {
2230 		WMI_LOGE("%s: Failed to send bcn: %d", __func__, ret);
2231 		wmi_buf_free(wmi_buf);
2232 	}
2233 
2234 	return ret;
2235 }
2236 
2237 /**
2238  *  send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function
2239  *  @param wmi_handle      : handle to WMI.
2240  *  @param param    : pointer to hold beacon send cmd parameter
2241  *
2242  *  Return: 0  on success and -ve on failure.
2243  */
2244 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle,
2245 				struct beacon_tmpl_params *param)
2246 {
2247 	int32_t ret;
2248 	wmi_bcn_tmpl_cmd_fixed_param *cmd;
2249 	wmi_bcn_prb_info *bcn_prb_info;
2250 	wmi_buf_t wmi_buf;
2251 	uint8_t *buf_ptr;
2252 	uint32_t wmi_buf_len;
2253 
2254 	wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) +
2255 		      sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE +
2256 		      param->tmpl_len_aligned;
2257 	wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
2258 	if (!wmi_buf) {
2259 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
2260 		return QDF_STATUS_E_NOMEM;
2261 	}
2262 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
2263 	cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr;
2264 	WMITLV_SET_HDR(&cmd->tlv_header,
2265 		       WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param,
2266 		       WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param));
2267 	cmd->vdev_id = param->vdev_id;
2268 	cmd->tim_ie_offset = param->tim_ie_offset;
2269 	cmd->mbssid_ie_offset = param->mbssid_ie_offset;
2270 	cmd->csa_switch_count_offset = param->csa_switch_count_offset;
2271 	cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset;
2272 	cmd->esp_ie_offset = param->esp_ie_offset;
2273 	cmd->buf_len = param->tmpl_len;
2274 	buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param);
2275 
2276 	bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr;
2277 	WMITLV_SET_HDR(&bcn_prb_info->tlv_header,
2278 		       WMITLV_TAG_STRUC_wmi_bcn_prb_info,
2279 		       WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info));
2280 	bcn_prb_info->caps = 0;
2281 	bcn_prb_info->erp = 0;
2282 	buf_ptr += sizeof(wmi_bcn_prb_info);
2283 
2284 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned);
2285 	buf_ptr += WMI_TLV_HDR_SIZE;
2286 	qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len);
2287 
2288 	wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0);
2289 	ret = wmi_unified_cmd_send(wmi_handle,
2290 				   wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID);
2291 	if (ret) {
2292 		WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret);
2293 		wmi_buf_free(wmi_buf);
2294 	}
2295 
2296 	return 0;
2297 }
2298 
2299 #ifdef CONFIG_MCL
2300 static inline void copy_peer_flags_tlv(
2301 			wmi_peer_assoc_complete_cmd_fixed_param * cmd,
2302 			struct peer_assoc_params *param)
2303 {
2304 	cmd->peer_flags = param->peer_flags;
2305 }
2306 #else
2307 static inline void copy_peer_flags_tlv(
2308 			wmi_peer_assoc_complete_cmd_fixed_param * cmd,
2309 			struct peer_assoc_params *param)
2310 {
2311 	/*
2312 	 * The target only needs a subset of the flags maintained in the host.
2313 	 * Just populate those flags and send it down
2314 	 */
2315 	cmd->peer_flags = 0;
2316 
2317 	/*
2318 	 * Do not enable HT/VHT if WMM/wme is disabled for vap.
2319 	 */
2320 	if (param->is_wme_set) {
2321 
2322 		if (param->qos_flag)
2323 			cmd->peer_flags |= WMI_PEER_QOS;
2324 		if (param->apsd_flag)
2325 			cmd->peer_flags |= WMI_PEER_APSD;
2326 		if (param->ht_flag)
2327 			cmd->peer_flags |= WMI_PEER_HT;
2328 		if (param->bw_40)
2329 			cmd->peer_flags |= WMI_PEER_40MHZ;
2330 		if (param->bw_80)
2331 			cmd->peer_flags |= WMI_PEER_80MHZ;
2332 		if (param->bw_160)
2333 			cmd->peer_flags |= WMI_PEER_160MHZ;
2334 
2335 		/* Typically if STBC is enabled for VHT it should be enabled
2336 		 * for HT as well
2337 		 **/
2338 		if (param->stbc_flag)
2339 			cmd->peer_flags |= WMI_PEER_STBC;
2340 
2341 		/* Typically if LDPC is enabled for VHT it should be enabled
2342 		 * for HT as well
2343 		 **/
2344 		if (param->ldpc_flag)
2345 			cmd->peer_flags |= WMI_PEER_LDPC;
2346 
2347 		if (param->static_mimops_flag)
2348 			cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS;
2349 		if (param->dynamic_mimops_flag)
2350 			cmd->peer_flags |= WMI_PEER_DYN_MIMOPS;
2351 		if (param->spatial_mux_flag)
2352 			cmd->peer_flags |= WMI_PEER_SPATIAL_MUX;
2353 		if (param->vht_flag)
2354 			cmd->peer_flags |= WMI_PEER_VHT;
2355 		if (param->he_flag)
2356 			cmd->peer_flags |= WMI_PEER_HE;
2357 	}
2358 
2359 	if (param->is_pmf_enabled)
2360 		cmd->peer_flags |= WMI_PEER_PMF;
2361 	/*
2362 	 * Suppress authorization for all AUTH modes that need 4-way handshake
2363 	 * (during re-association).
2364 	 * Authorization will be done for these modes on key installation.
2365 	 */
2366 	if (param->auth_flag)
2367 		cmd->peer_flags |= WMI_PEER_AUTH;
2368 	if (param->need_ptk_4_way)
2369 		cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
2370 	else
2371 		cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY;
2372 	if (param->need_gtk_2_way)
2373 		cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
2374 	/* safe mode bypass the 4-way handshake */
2375 	if (param->safe_mode_enabled)
2376 		cmd->peer_flags &=
2377 		    ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY);
2378 	/* Disable AMSDU for station transmit, if user configures it */
2379 	/* Disable AMSDU for AP transmit to 11n Stations, if user configures
2380 	 * it
2381 	 * if (param->amsdu_disable) Add after FW support
2382 	 **/
2383 
2384 	/* Target asserts if node is marked HT and all MCS is set to 0.
2385 	 * Mark the node as non-HT if all the mcs rates are disabled through
2386 	 * iwpriv
2387 	 **/
2388 	if (param->peer_ht_rates.num_rates == 0)
2389 		cmd->peer_flags &= ~WMI_PEER_HT;
2390 
2391 	if (param->twt_requester)
2392 		cmd->peer_flags |= WMI_PEER_TWT_REQ;
2393 
2394 	if (param->twt_responder)
2395 		cmd->peer_flags |= WMI_PEER_TWT_RESP;
2396 }
2397 #endif
2398 
2399 #ifdef CONFIG_MCL
2400 static inline void copy_peer_mac_addr_tlv(
2401 		wmi_peer_assoc_complete_cmd_fixed_param * cmd,
2402 		struct peer_assoc_params *param)
2403 {
2404 	qdf_mem_copy(&cmd->peer_macaddr, &param->peer_macaddr,
2405 			sizeof(param->peer_macaddr));
2406 }
2407 #else
2408 static inline void copy_peer_mac_addr_tlv(
2409 		wmi_peer_assoc_complete_cmd_fixed_param * cmd,
2410 		struct peer_assoc_params *param)
2411 {
2412 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr);
2413 }
2414 #endif
2415 
2416 /**
2417  *  send_peer_assoc_cmd_tlv() - WMI peer assoc function
2418  *  @param wmi_handle      : handle to WMI.
2419  *  @param param    : pointer to peer assoc parameter
2420  *
2421  *  Return: 0  on success and -ve on failure.
2422  */
2423 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle,
2424 				struct peer_assoc_params *param)
2425 {
2426 	wmi_peer_assoc_complete_cmd_fixed_param *cmd;
2427 	wmi_vht_rate_set *mcs;
2428 	wmi_he_rate_set *he_mcs;
2429 	wmi_buf_t buf;
2430 	int32_t len;
2431 	uint8_t *buf_ptr;
2432 	QDF_STATUS ret;
2433 	uint32_t peer_legacy_rates_align;
2434 	uint32_t peer_ht_rates_align;
2435 	int32_t i;
2436 
2437 
2438 	peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates);
2439 	peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates);
2440 
2441 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
2442 		(peer_legacy_rates_align * sizeof(uint8_t)) +
2443 		WMI_TLV_HDR_SIZE +
2444 		(peer_ht_rates_align * sizeof(uint8_t)) +
2445 		sizeof(wmi_vht_rate_set) +
2446 		(sizeof(wmi_he_rate_set) * param->peer_he_mcs_count
2447 		+ WMI_TLV_HDR_SIZE);
2448 
2449 	buf = wmi_buf_alloc(wmi_handle, len);
2450 	if (!buf) {
2451 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
2452 		return QDF_STATUS_E_NOMEM;
2453 	}
2454 
2455 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
2456 	cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr;
2457 	WMITLV_SET_HDR(&cmd->tlv_header,
2458 		       WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param,
2459 		       WMITLV_GET_STRUCT_TLVLEN
2460 			       (wmi_peer_assoc_complete_cmd_fixed_param));
2461 
2462 	cmd->vdev_id = param->vdev_id;
2463 
2464 	cmd->peer_new_assoc = param->peer_new_assoc;
2465 	cmd->peer_associd = param->peer_associd;
2466 
2467 	copy_peer_flags_tlv(cmd, param);
2468 	copy_peer_mac_addr_tlv(cmd, param);
2469 
2470 	cmd->peer_rate_caps = param->peer_rate_caps;
2471 	cmd->peer_caps = param->peer_caps;
2472 	cmd->peer_listen_intval = param->peer_listen_intval;
2473 	cmd->peer_ht_caps = param->peer_ht_caps;
2474 	cmd->peer_max_mpdu = param->peer_max_mpdu;
2475 	cmd->peer_mpdu_density = param->peer_mpdu_density;
2476 	cmd->peer_vht_caps = param->peer_vht_caps;
2477 	cmd->peer_phymode = param->peer_phymode;
2478 
2479 	/* Update 11ax capabilities */
2480 	cmd->peer_he_cap_info =
2481 		param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1];
2482 	cmd->peer_he_cap_info_ext =
2483 		param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2];
2484 	cmd->peer_he_ops = param->peer_he_ops;
2485 	qdf_mem_copy(&cmd->peer_he_cap_phy, &param->peer_he_cap_phyinfo,
2486 				sizeof(param->peer_he_cap_phyinfo));
2487 	qdf_mem_copy(&cmd->peer_ppet, &param->peer_ppet,
2488 				sizeof(param->peer_ppet));
2489 
2490 	/* Update peer legacy rate information */
2491 	buf_ptr += sizeof(*cmd);
2492 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
2493 				peer_legacy_rates_align);
2494 	buf_ptr += WMI_TLV_HDR_SIZE;
2495 	cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates;
2496 	qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates,
2497 		     param->peer_legacy_rates.num_rates);
2498 
2499 	/* Update peer HT rate information */
2500 	buf_ptr += peer_legacy_rates_align;
2501 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
2502 			  peer_ht_rates_align);
2503 	buf_ptr += WMI_TLV_HDR_SIZE;
2504 	cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates;
2505 	qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates,
2506 				 param->peer_ht_rates.num_rates);
2507 
2508 	/* VHT Rates */
2509 	buf_ptr += peer_ht_rates_align;
2510 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set,
2511 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set));
2512 
2513 	cmd->peer_nss = param->peer_nss;
2514 
2515 	/* Update bandwidth-NSS mapping */
2516 	cmd->peer_bw_rxnss_override = 0;
2517 	cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override;
2518 
2519 	mcs = (wmi_vht_rate_set *) buf_ptr;
2520 	if (param->vht_capable) {
2521 		mcs->rx_max_rate = param->rx_max_rate;
2522 		mcs->rx_mcs_set = param->rx_mcs_set;
2523 		mcs->tx_max_rate = param->tx_max_rate;
2524 		mcs->tx_mcs_set = param->tx_mcs_set;
2525 	}
2526 
2527 	/* HE Rates */
2528 	cmd->peer_he_mcs = param->peer_he_mcs_count;
2529 	buf_ptr += sizeof(wmi_vht_rate_set);
2530 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2531 		(param->peer_he_mcs_count * sizeof(wmi_he_rate_set)));
2532 	buf_ptr += WMI_TLV_HDR_SIZE;
2533 
2534 	/* Loop through the HE rate set */
2535 	for (i = 0; i < param->peer_he_mcs_count; i++) {
2536 		he_mcs = (wmi_he_rate_set *) buf_ptr;
2537 		WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set,
2538 			WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set));
2539 
2540 		he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i];
2541 		he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i];
2542 		WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__,
2543 			i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set);
2544 		buf_ptr += sizeof(wmi_he_rate_set);
2545 	}
2546 
2547 
2548 	WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x "
2549 		 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d "
2550 		 "nss %d phymode %d peer_mpdu_density %d "
2551 		 "cmd->peer_vht_caps %x "
2552 		 "HE cap_info %x ops %x "
2553 		 "HE cap_info_ext %x "
2554 		 "HE phy %x  %x  %x  "
2555 		 "peer_bw_rxnss_override %x", __func__,
2556 		 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags,
2557 		 cmd->peer_rate_caps, cmd->peer_caps,
2558 		 cmd->peer_listen_intval, cmd->peer_ht_caps,
2559 		 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode,
2560 		 cmd->peer_mpdu_density,
2561 		 cmd->peer_vht_caps, cmd->peer_he_cap_info,
2562 		 cmd->peer_he_ops, cmd->peer_he_cap_info_ext,
2563 		 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1],
2564 		 cmd->peer_he_cap_phy[2],
2565 		 cmd->peer_bw_rxnss_override);
2566 
2567 	wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0);
2568 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2569 				   WMI_PEER_ASSOC_CMDID);
2570 	if (QDF_IS_STATUS_ERROR(ret)) {
2571 		WMI_LOGP("%s: Failed to send peer assoc command ret = %d",
2572 			 __func__, ret);
2573 		wmi_buf_free(buf);
2574 	}
2575 
2576 	return ret;
2577 }
2578 
2579 /* copy_scan_notify_events() - Helper routine to copy scan notify events
2580  */
2581 static inline void copy_scan_event_cntrl_flags(
2582 		wmi_start_scan_cmd_fixed_param * cmd,
2583 		struct scan_req_params *param)
2584 {
2585 
2586 	/* Scan events subscription */
2587 	if (param->scan_ev_started)
2588 		cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED;
2589 	if (param->scan_ev_completed)
2590 		cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED;
2591 	if (param->scan_ev_bss_chan)
2592 		cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL;
2593 	if (param->scan_ev_foreign_chan)
2594 		cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL;
2595 	if (param->scan_ev_dequeued)
2596 		cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED;
2597 	if (param->scan_ev_preempted)
2598 		cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED;
2599 	if (param->scan_ev_start_failed)
2600 		cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED;
2601 	if (param->scan_ev_restarted)
2602 		cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED;
2603 	if (param->scan_ev_foreign_chn_exit)
2604 		cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT;
2605 	if (param->scan_ev_suspended)
2606 		cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED;
2607 	if (param->scan_ev_resumed)
2608 		cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED;
2609 
2610 	/** Set scan control flags */
2611 	cmd->scan_ctrl_flags = 0;
2612 	if (param->scan_f_passive)
2613 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
2614 	if (param->scan_f_strict_passive_pch)
2615 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN;
2616 	if (param->scan_f_promisc_mode)
2617 		cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS;
2618 	if (param->scan_f_capture_phy_err)
2619 		cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR;
2620 	if (param->scan_f_half_rate)
2621 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT;
2622 	if (param->scan_f_quarter_rate)
2623 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT;
2624 	if (param->scan_f_cck_rates)
2625 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES;
2626 	if (param->scan_f_ofdm_rates)
2627 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES;
2628 	if (param->scan_f_chan_stat_evnt)
2629 		cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT;
2630 	if (param->scan_f_filter_prb_req)
2631 		cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
2632 	if (param->scan_f_bcast_probe)
2633 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ;
2634 	if (param->scan_f_offchan_mgmt_tx)
2635 		cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX;
2636 	if (param->scan_f_offchan_data_tx)
2637 		cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX;
2638 	if (param->scan_f_force_active_dfs_chn)
2639 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS;
2640 	if (param->scan_f_add_tpc_ie_in_probe)
2641 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ;
2642 	if (param->scan_f_add_ds_ie_in_probe)
2643 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
2644 	if (param->scan_f_add_spoofed_mac_in_probe)
2645 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ;
2646 	if (param->scan_f_add_rand_seq_in_probe)
2647 		cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ;
2648 	if (param->scan_f_en_ie_whitelist_in_probe)
2649 		cmd->scan_ctrl_flags |=
2650 			WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ;
2651 
2652 	/* for adaptive scan mode using 3 bits (21 - 23 bits) */
2653 	WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags,
2654 		param->adaptive_dwell_time_mode);
2655 }
2656 
2657 /* scan_copy_ie_buffer() - Copy scan ie_data */
2658 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr,
2659 				struct scan_req_params *params)
2660 {
2661 	qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len);
2662 }
2663 
2664 /**
2665  * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer
2666  * @mac: random mac addr
2667  * @mask: random mac mask
2668  * @mac_addr: wmi random mac
2669  * @mac_mask: wmi random mac mask
2670  *
2671  * Return None.
2672  */
2673 static inline
2674 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask,
2675 			      wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask)
2676 {
2677 	WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr);
2678 	WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask);
2679 }
2680 
2681 /*
2682  * wmi_fill_vendor_oui() - fill vendor OUIs
2683  * @buf_ptr: pointer to wmi tlv buffer
2684  * @num_vendor_oui: number of vendor OUIs to be filled
2685  * @param_voui: pointer to OUI buffer
2686  *
2687  * This function populates the wmi tlv buffer when vendor specific OUIs are
2688  * present.
2689  *
2690  * Return: None
2691  */
2692 static inline
2693 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui,
2694 			 uint32_t *pvoui)
2695 {
2696 	wmi_vendor_oui *voui = NULL;
2697 	uint32_t i;
2698 
2699 	voui = (wmi_vendor_oui *)buf_ptr;
2700 
2701 	for (i = 0; i < num_vendor_oui; i++) {
2702 		WMITLV_SET_HDR(&voui[i].tlv_header,
2703 			       WMITLV_TAG_STRUC_wmi_vendor_oui,
2704 			       WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui));
2705 		voui[i].oui_type_subtype = pvoui[i];
2706 	}
2707 }
2708 
2709 /*
2710  * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs
2711  * @ie_bitmap: output pointer to ie bit map in cmd
2712  * @num_vendor_oui: output pointer to num vendor OUIs
2713  * @ie_whitelist: input parameter
2714  *
2715  * This function populates the IE whitelist attrs of scan, pno and
2716  * scan oui commands for ie_whitelist parameter.
2717  *
2718  * Return: None
2719  */
2720 static inline
2721 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap,
2722 				 uint32_t *num_vendor_oui,
2723 				 struct probe_req_whitelist_attr *ie_whitelist)
2724 {
2725 	uint32_t i = 0;
2726 
2727 	for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++)
2728 		ie_bitmap[i] = ie_whitelist->ie_bitmap[i];
2729 
2730 	*num_vendor_oui = ie_whitelist->num_vendor_oui;
2731 }
2732 
2733 /**
2734  *  send_scan_start_cmd_tlv() - WMI scan start function
2735  *  @param wmi_handle      : handle to WMI.
2736  *  @param param    : pointer to hold scan start cmd parameter
2737  *
2738  *  Return: 0  on success and -ve on failure.
2739  */
2740 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle,
2741 				struct scan_req_params *params)
2742 {
2743 	int32_t ret = 0;
2744 	int32_t i;
2745 	wmi_buf_t wmi_buf;
2746 	wmi_start_scan_cmd_fixed_param *cmd;
2747 	uint8_t *buf_ptr;
2748 	uint32_t *tmp_ptr;
2749 	wmi_ssid *ssid = NULL;
2750 	wmi_mac_addr *bssid;
2751 	int len = sizeof(*cmd);
2752 	uint8_t extraie_len_with_pad = 0;
2753 	uint8_t phymode_roundup = 0;
2754 	struct probe_req_whitelist_attr *ie_whitelist = &params->ie_whitelist;
2755 
2756 	/* Length TLV placeholder for array of uint32_t */
2757 	len += WMI_TLV_HDR_SIZE;
2758 	/* calculate the length of buffer required */
2759 	if (params->chan_list.num_chan)
2760 		len += params->chan_list.num_chan * sizeof(uint32_t);
2761 
2762 	/* Length TLV placeholder for array of wmi_ssid structures */
2763 	len += WMI_TLV_HDR_SIZE;
2764 	if (params->num_ssids)
2765 		len += params->num_ssids * sizeof(wmi_ssid);
2766 
2767 	/* Length TLV placeholder for array of wmi_mac_addr structures */
2768 	len += WMI_TLV_HDR_SIZE;
2769 	if (params->num_bssid)
2770 		len += sizeof(wmi_mac_addr) * params->num_bssid;
2771 
2772 	/* Length TLV placeholder for array of bytes */
2773 	len += WMI_TLV_HDR_SIZE;
2774 	if (params->extraie.len)
2775 		extraie_len_with_pad =
2776 		roundup(params->extraie.len, sizeof(uint32_t));
2777 	len += extraie_len_with_pad;
2778 
2779 	len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */
2780 	if (ie_whitelist->num_vendor_oui)
2781 		len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui);
2782 
2783 	len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */
2784 	if (params->scan_f_wide_band)
2785 		phymode_roundup =
2786 			qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t),
2787 					sizeof(uint32_t));
2788 	len += phymode_roundup;
2789 
2790 	/* Allocate the memory */
2791 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
2792 	if (!wmi_buf) {
2793 		WMI_LOGP("%s: failed to allocate memory for start scan cmd",
2794 			 __func__);
2795 		return QDF_STATUS_E_FAILURE;
2796 	}
2797 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
2798 	cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr;
2799 	WMITLV_SET_HDR(&cmd->tlv_header,
2800 		       WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
2801 		       WMITLV_GET_STRUCT_TLVLEN
2802 			       (wmi_start_scan_cmd_fixed_param));
2803 
2804 	cmd->scan_id = params->scan_id;
2805 	cmd->scan_req_id = params->scan_req_id;
2806 	cmd->vdev_id = params->vdev_id;
2807 	cmd->scan_priority = params->scan_priority;
2808 
2809 	copy_scan_event_cntrl_flags(cmd, params);
2810 
2811 	cmd->dwell_time_active = params->dwell_time_active;
2812 	cmd->dwell_time_active_2g = params->dwell_time_active_2g;
2813 	cmd->dwell_time_passive = params->dwell_time_passive;
2814 	cmd->min_rest_time = params->min_rest_time;
2815 	cmd->max_rest_time = params->max_rest_time;
2816 	cmd->repeat_probe_time = params->repeat_probe_time;
2817 	cmd->probe_spacing_time = params->probe_spacing_time;
2818 	cmd->idle_time = params->idle_time;
2819 	cmd->max_scan_time = params->max_scan_time;
2820 	cmd->probe_delay = params->probe_delay;
2821 	cmd->burst_duration = params->burst_duration;
2822 	cmd->num_chan = params->chan_list.num_chan;
2823 	cmd->num_bssid = params->num_bssid;
2824 	cmd->num_ssids = params->num_ssids;
2825 	cmd->ie_len = params->extraie.len;
2826 	cmd->n_probes = params->n_probes;
2827 	cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext;
2828 
2829 	WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext);
2830 
2831 	if (params->scan_random.randomize)
2832 		wmi_copy_scan_random_mac(params->scan_random.mac_addr,
2833 					 params->scan_random.mac_mask,
2834 					 &cmd->mac_addr,
2835 					 &cmd->mac_mask);
2836 
2837 	if (ie_whitelist->white_list)
2838 		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
2839 					    &cmd->num_vendor_oui,
2840 					    ie_whitelist);
2841 
2842 	buf_ptr += sizeof(*cmd);
2843 	tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
2844 	for (i = 0; i < params->chan_list.num_chan; ++i)
2845 		tmp_ptr[i] = params->chan_list.chan[i].freq;
2846 
2847 	WMITLV_SET_HDR(buf_ptr,
2848 		       WMITLV_TAG_ARRAY_UINT32,
2849 		       (params->chan_list.num_chan * sizeof(uint32_t)));
2850 	buf_ptr += WMI_TLV_HDR_SIZE +
2851 			(params->chan_list.num_chan * sizeof(uint32_t));
2852 
2853 	if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) {
2854 		WMI_LOGE("Invalid value for numSsid");
2855 		goto error;
2856 	}
2857 
2858 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
2859 	       (params->num_ssids * sizeof(wmi_ssid)));
2860 
2861 	if (params->num_ssids) {
2862 		ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE);
2863 		for (i = 0; i < params->num_ssids; ++i) {
2864 			ssid->ssid_len = params->ssid[i].length;
2865 			qdf_mem_copy(ssid->ssid, params->ssid[i].ssid,
2866 				     params->ssid[i].length);
2867 			ssid++;
2868 		}
2869 	}
2870 	buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid));
2871 
2872 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
2873 		       (params->num_bssid * sizeof(wmi_mac_addr)));
2874 	bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE);
2875 
2876 	if (params->num_bssid) {
2877 		for (i = 0; i < params->num_bssid; ++i) {
2878 			WMI_CHAR_ARRAY_TO_MAC_ADDR(
2879 				&params->bssid_list[i].bytes[0], bssid);
2880 			bssid++;
2881 		}
2882 	}
2883 
2884 	buf_ptr += WMI_TLV_HDR_SIZE +
2885 		(params->num_bssid * sizeof(wmi_mac_addr));
2886 
2887 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad);
2888 	if (params->extraie.len)
2889 		scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE,
2890 			     params);
2891 
2892 	buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad;
2893 
2894 	/* probe req ie whitelisting */
2895 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2896 		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
2897 
2898 	buf_ptr += WMI_TLV_HDR_SIZE;
2899 
2900 	if (cmd->num_vendor_oui) {
2901 		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
2902 				    ie_whitelist->voui);
2903 		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
2904 	}
2905 
2906 	/* Add phy mode TLV if it's a wide band scan */
2907 	if (params->scan_f_wide_band) {
2908 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup);
2909 		buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
2910 		for (i = 0; i < params->chan_list.num_chan; ++i)
2911 			buf_ptr[i] =
2912 				WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode);
2913 		buf_ptr += phymode_roundup;
2914 	} else {
2915 		/* Add ZERO legth phy mode TLV */
2916 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0);
2917 	}
2918 
2919 	wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0);
2920 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf,
2921 				   len, WMI_START_SCAN_CMDID);
2922 	if (ret) {
2923 		WMI_LOGE("%s: Failed to start scan: %d", __func__, ret);
2924 		wmi_buf_free(wmi_buf);
2925 	}
2926 	return ret;
2927 error:
2928 	wmi_buf_free(wmi_buf);
2929 	return QDF_STATUS_E_FAILURE;
2930 }
2931 
2932 /**
2933  *  send_scan_stop_cmd_tlv() - WMI scan start function
2934  *  @param wmi_handle      : handle to WMI.
2935  *  @param param    : pointer to hold scan cancel cmd parameter
2936  *
2937  *  Return: 0  on success and -ve on failure.
2938  */
2939 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle,
2940 				struct scan_cancel_param *param)
2941 {
2942 	wmi_stop_scan_cmd_fixed_param *cmd;
2943 	int ret;
2944 	int len = sizeof(*cmd);
2945 	wmi_buf_t wmi_buf;
2946 
2947 	/* Allocate the memory */
2948 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
2949 	if (!wmi_buf) {
2950 		WMI_LOGP("%s: failed to allocate memory for stop scan cmd",
2951 			 __func__);
2952 		ret = QDF_STATUS_E_NOMEM;
2953 		goto error;
2954 	}
2955 
2956 	cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf);
2957 	WMITLV_SET_HDR(&cmd->tlv_header,
2958 		       WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param,
2959 		       WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param));
2960 	cmd->vdev_id = param->vdev_id;
2961 	cmd->requestor = param->requester;
2962 	cmd->scan_id = param->scan_id;
2963 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
2964 								param->pdev_id);
2965 	/* stop the scan with the corresponding scan_id */
2966 	if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) {
2967 		/* Cancelling all scans */
2968 		cmd->req_type = WMI_SCAN_STOP_ALL;
2969 	} else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) {
2970 		/* Cancelling VAP scans */
2971 		cmd->req_type = WMI_SCN_STOP_VAP_ALL;
2972 	} else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) {
2973 		/* Cancelling specific scan */
2974 		cmd->req_type = WMI_SCAN_STOP_ONE;
2975 	} else {
2976 		WMI_LOGE("%s: Invalid Command : ", __func__);
2977 		wmi_buf_free(wmi_buf);
2978 		return QDF_STATUS_E_INVAL;
2979 	}
2980 
2981 	wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0);
2982 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf,
2983 				   len, WMI_STOP_SCAN_CMDID);
2984 	if (ret) {
2985 		WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret);
2986 		wmi_buf_free(wmi_buf);
2987 	}
2988 
2989 error:
2990 	return ret;
2991 }
2992 
2993 #ifdef CONFIG_MCL
2994 /**
2995  *  send_scan_chan_list_cmd_tlv() - WMI scan channel list function
2996  *  @param wmi_handle      : handle to WMI.
2997  *  @param param    : pointer to hold scan channel list parameter
2998  *
2999  *  Return: 0  on success and -ve on failure.
3000  */
3001 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
3002 				struct scan_chan_list_params *chan_list)
3003 {
3004 	wmi_buf_t buf;
3005 	QDF_STATUS qdf_status;
3006 	wmi_scan_chan_list_cmd_fixed_param *cmd;
3007 	int i;
3008 	uint8_t *buf_ptr;
3009 	wmi_channel_param *chan_info, *tchan_info;
3010 	uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
3011 
3012 	len += sizeof(wmi_channel) * chan_list->num_scan_chans;
3013 	buf = wmi_buf_alloc(wmi_handle, len);
3014 	if (!buf) {
3015 		WMI_LOGE("Failed to allocate memory");
3016 		qdf_status = QDF_STATUS_E_NOMEM;
3017 		goto end;
3018 	}
3019 
3020 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3021 	cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr;
3022 	WMITLV_SET_HDR(&cmd->tlv_header,
3023 		       WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param,
3024 		       WMITLV_GET_STRUCT_TLVLEN
3025 			       (wmi_scan_chan_list_cmd_fixed_param));
3026 
3027 	WMI_LOGD("no of channels = %d, len = %d", chan_list->num_scan_chans, len);
3028 
3029 	cmd->num_scan_chans = chan_list->num_scan_chans;
3030 	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)),
3031 		       WMITLV_TAG_ARRAY_STRUC,
3032 		       sizeof(wmi_channel) * chan_list->num_scan_chans);
3033 	chan_info = (wmi_channel_param *)
3034 			(buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE);
3035 	tchan_info = chan_list->chan_info;
3036 
3037 	for (i = 0; i < chan_list->num_scan_chans; ++i) {
3038 		WMITLV_SET_HDR(&chan_info->tlv_header,
3039 			       WMITLV_TAG_STRUC_wmi_channel,
3040 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
3041 		chan_info->mhz = tchan_info->mhz;
3042 		chan_info->band_center_freq1 =
3043 				 tchan_info->band_center_freq1;
3044 		chan_info->band_center_freq2 =
3045 				tchan_info->band_center_freq2;
3046 		chan_info->info = tchan_info->info;
3047 		chan_info->reg_info_1 = tchan_info->reg_info_1;
3048 		chan_info->reg_info_2 = tchan_info->reg_info_2;
3049 		WMI_LOGD("chan[%d] = %u", i, chan_info->mhz);
3050 
3051 		/*TODO: Set WMI_SET_CHANNEL_MIN_POWER */
3052 		/*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */
3053 		/*TODO: WMI_SET_CHANNEL_REG_CLASSID */
3054 		tchan_info++;
3055 		chan_info++;
3056 	}
3057 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
3058 							chan_list->pdev_id);
3059 
3060 	wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, NO_SESSION, 0);
3061 	qdf_status = wmi_unified_cmd_send(wmi_handle,
3062 			buf, len, WMI_SCAN_CHAN_LIST_CMDID);
3063 
3064 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
3065 		WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
3066 		wmi_buf_free(buf);
3067 	}
3068 
3069 end:
3070 	return qdf_status;
3071 }
3072 #else
3073 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
3074 				struct scan_chan_list_params *chan_list)
3075 {
3076 	wmi_buf_t buf;
3077 	QDF_STATUS qdf_status;
3078 	wmi_scan_chan_list_cmd_fixed_param *cmd;
3079 	int i;
3080 	uint8_t *buf_ptr;
3081 	wmi_channel *chan_info;
3082 	struct channel_param *tchan_info;
3083 	uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
3084 
3085 	len += sizeof(wmi_channel) * chan_list->nallchans;
3086 	buf = wmi_buf_alloc(wmi_handle, len);
3087 	if (!buf) {
3088 		WMI_LOGE("Failed to allocate memory");
3089 		qdf_status = QDF_STATUS_E_NOMEM;
3090 		goto end;
3091 	}
3092 
3093 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3094 	cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr;
3095 	WMITLV_SET_HDR(&cmd->tlv_header,
3096 		       WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param,
3097 		       WMITLV_GET_STRUCT_TLVLEN
3098 			       (wmi_scan_chan_list_cmd_fixed_param));
3099 
3100 	WMI_LOGD("no of channels = %d, len = %d", chan_list->nallchans, len);
3101 
3102 	if (chan_list->append)
3103 		cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST;
3104 
3105 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
3106 							chan_list->pdev_id);
3107 	cmd->num_scan_chans = chan_list->nallchans;
3108 	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)),
3109 		       WMITLV_TAG_ARRAY_STRUC,
3110 		       sizeof(wmi_channel) * chan_list->nallchans);
3111 	chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE);
3112 	tchan_info = &(chan_list->ch_param[0]);
3113 
3114 	for (i = 0; i < chan_list->nallchans; ++i) {
3115 		WMITLV_SET_HDR(&chan_info->tlv_header,
3116 			       WMITLV_TAG_STRUC_wmi_channel,
3117 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
3118 		chan_info->mhz = tchan_info->mhz;
3119 		chan_info->band_center_freq1 =
3120 				 tchan_info->cfreq1;
3121 		chan_info->band_center_freq2 =
3122 				tchan_info->cfreq2;
3123 
3124 		if (tchan_info->is_chan_passive)
3125 			WMI_SET_CHANNEL_FLAG(chan_info,
3126 					WMI_CHAN_FLAG_PASSIVE);
3127 
3128 		if (tchan_info->allow_vht)
3129 			WMI_SET_CHANNEL_FLAG(chan_info,
3130 					WMI_CHAN_FLAG_ALLOW_VHT);
3131 		else  if (tchan_info->allow_ht)
3132 			WMI_SET_CHANNEL_FLAG(chan_info,
3133 					WMI_CHAN_FLAG_ALLOW_HT);
3134 		WMI_SET_CHANNEL_MODE(chan_info,
3135 				tchan_info->phy_mode);
3136 
3137 		if (tchan_info->half_rate)
3138 			WMI_SET_CHANNEL_FLAG(chan_info,
3139 					WMI_CHAN_FLAG_HALF_RATE);
3140 
3141 		if (tchan_info->quarter_rate)
3142 			WMI_SET_CHANNEL_FLAG(chan_info,
3143 					WMI_CHAN_FLAG_QUARTER_RATE);
3144 
3145 		/* also fill in power information */
3146 		WMI_SET_CHANNEL_MIN_POWER(chan_info,
3147 				tchan_info->minpower);
3148 		WMI_SET_CHANNEL_MAX_POWER(chan_info,
3149 				tchan_info->maxpower);
3150 		WMI_SET_CHANNEL_REG_POWER(chan_info,
3151 				tchan_info->maxregpower);
3152 		WMI_SET_CHANNEL_ANTENNA_MAX(chan_info,
3153 				tchan_info->antennamax);
3154 		WMI_SET_CHANNEL_REG_CLASSID(chan_info,
3155 				tchan_info->reg_class_id);
3156 		WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
3157 				tchan_info->maxregpower);
3158 
3159 		WMI_LOGD("chan[%d] = %u", i, chan_info->mhz);
3160 
3161 		tchan_info++;
3162 		chan_info++;
3163 	}
3164 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
3165 							chan_list->pdev_id);
3166 
3167 	wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0);
3168 	qdf_status = wmi_unified_cmd_send(
3169 			wmi_handle,
3170 			buf, len, WMI_SCAN_CHAN_LIST_CMDID);
3171 
3172 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
3173 		WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
3174 		wmi_buf_free(buf);
3175 	}
3176 
3177 end:
3178 	return qdf_status;
3179 }
3180 #endif
3181 
3182 /**
3183  * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx
3184  *
3185  * @bufp: Pointer to buffer
3186  * @param: Pointer to tx param
3187  *
3188  * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure
3189  */
3190 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp,
3191 					 struct tx_send_params param)
3192 {
3193 	wmi_tx_send_params *tx_param;
3194 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3195 
3196 	if (!bufp) {
3197 		status = QDF_STATUS_E_FAILURE;
3198 		return status;
3199 	}
3200 	tx_param = (wmi_tx_send_params *)bufp;
3201 	WMITLV_SET_HDR(&tx_param->tlv_header,
3202 		       WMITLV_TAG_STRUC_wmi_tx_send_params,
3203 		       WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params));
3204 	WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr);
3205 	WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0,
3206 				       param.mcs_mask);
3207 	WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0,
3208 				       param.nss_mask);
3209 	WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0,
3210 					  param.retry_limit);
3211 	WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1,
3212 					 param.chain_mask);
3213 	WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1,
3214 				      param.bw_mask);
3215 	WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1,
3216 				       param.preamble_type);
3217 	WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1,
3218 					 param.frame_type);
3219 
3220 	return status;
3221 }
3222 
3223 #ifdef CONFIG_HL_SUPPORT
3224 /**
3225  *  send_mgmt_cmd_tlv() - WMI scan start function
3226  *  @wmi_handle      : handle to WMI.
3227  *  @param    : pointer to hold mgmt cmd parameter
3228  *
3229  *  Return: 0  on success and -ve on failure.
3230  */
3231 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
3232 				struct wmi_mgmt_params *param)
3233 {
3234 	wmi_buf_t buf;
3235 	uint8_t *bufp;
3236 	int32_t cmd_len;
3237 	wmi_mgmt_tx_send_cmd_fixed_param *cmd;
3238 	int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len :
3239 		mgmt_tx_dl_frm_len;
3240 
3241 	if (param->frm_len > mgmt_tx_dl_frm_len) {
3242 		WMI_LOGE("%s:mgmt frame len %u exceeds %u",
3243 			 __func__, param->frm_len, mgmt_tx_dl_frm_len);
3244 		return QDF_STATUS_E_INVAL;
3245 	}
3246 
3247 	cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) +
3248 		  WMI_TLV_HDR_SIZE +
3249 		  roundup(bufp_len, sizeof(uint32_t));
3250 
3251 	buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len);
3252 	if (!buf) {
3253 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3254 		return QDF_STATUS_E_NOMEM;
3255 	}
3256 
3257 	cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf);
3258 	bufp = (uint8_t *) cmd;
3259 	WMITLV_SET_HDR(&cmd->tlv_header,
3260 		WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param,
3261 		WMITLV_GET_STRUCT_TLVLEN
3262 		(wmi_mgmt_tx_send_cmd_fixed_param));
3263 
3264 	cmd->vdev_id = param->vdev_id;
3265 
3266 	cmd->desc_id = param->desc_id;
3267 	cmd->chanfreq = param->chanfreq;
3268 	bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param);
3269 	WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
3270 							    sizeof(uint32_t)));
3271 	bufp += WMI_TLV_HDR_SIZE;
3272 	qdf_mem_copy(bufp, param->pdata, bufp_len);
3273 
3274 	cmd->frame_len = param->frm_len;
3275 	cmd->buf_len = bufp_len;
3276 	cmd->tx_params_valid = param->tx_params_valid;
3277 
3278 	wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID,
3279 			bufp, cmd->vdev_id, cmd->chanfreq);
3280 
3281 	bufp += roundup(bufp_len, sizeof(uint32_t));
3282 	if (param->tx_params_valid) {
3283 		if (populate_tx_send_params(bufp, param->tx_param) !=
3284 		    QDF_STATUS_SUCCESS) {
3285 			WMI_LOGE("%s: Populate TX send params failed",
3286 				 __func__);
3287 			goto free_buf;
3288 		}
3289 		cmd_len += sizeof(wmi_tx_send_params);
3290 	}
3291 
3292 	wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0);
3293 	if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
3294 				      WMI_MGMT_TX_SEND_CMDID)) {
3295 		WMI_LOGE("%s: Failed to send mgmt Tx", __func__);
3296 		goto free_buf;
3297 	}
3298 	return QDF_STATUS_SUCCESS;
3299 
3300 free_buf:
3301 	wmi_buf_free(buf);
3302 	return QDF_STATUS_E_FAILURE;
3303 }
3304 #else
3305 /**
3306  *  send_mgmt_cmd_tlv() - WMI scan start function
3307  *  @wmi_handle      : handle to WMI.
3308  *  @param    : pointer to hold mgmt cmd parameter
3309  *
3310  *  Return: 0  on success and -ve on failure.
3311  */
3312 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
3313 				struct wmi_mgmt_params *param)
3314 {
3315 	wmi_buf_t buf;
3316 	wmi_mgmt_tx_send_cmd_fixed_param *cmd;
3317 	int32_t cmd_len;
3318 	uint64_t dma_addr;
3319 	void *qdf_ctx = param->qdf_ctx;
3320 	uint8_t *bufp;
3321 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3322 	int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len :
3323 		mgmt_tx_dl_frm_len;
3324 
3325 	cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) +
3326 		  WMI_TLV_HDR_SIZE +
3327 		  roundup(bufp_len, sizeof(uint32_t));
3328 
3329 	buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len);
3330 	if (!buf) {
3331 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3332 		return QDF_STATUS_E_NOMEM;
3333 	}
3334 
3335 	cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf);
3336 	bufp = (uint8_t *) cmd;
3337 	WMITLV_SET_HDR(&cmd->tlv_header,
3338 		WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param,
3339 		WMITLV_GET_STRUCT_TLVLEN
3340 		(wmi_mgmt_tx_send_cmd_fixed_param));
3341 
3342 	cmd->vdev_id = param->vdev_id;
3343 
3344 	cmd->desc_id = param->desc_id;
3345 	cmd->chanfreq = param->chanfreq;
3346 	bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param);
3347 	WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
3348 							    sizeof(uint32_t)));
3349 	bufp += WMI_TLV_HDR_SIZE;
3350 	qdf_mem_copy(bufp, param->pdata, bufp_len);
3351 
3352 	status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame,
3353 				     QDF_DMA_TO_DEVICE);
3354 	if (status != QDF_STATUS_SUCCESS) {
3355 		WMI_LOGE("%s: wmi buf map failed", __func__);
3356 		goto free_buf;
3357 	}
3358 
3359 	dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0);
3360 	cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff);
3361 #if defined(HTT_PADDR64)
3362 	cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F);
3363 #endif
3364 	cmd->frame_len = param->frm_len;
3365 	cmd->buf_len = bufp_len;
3366 	cmd->tx_params_valid = param->tx_params_valid;
3367 
3368 	wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID,
3369 			bufp, cmd->vdev_id, cmd->chanfreq);
3370 
3371 	bufp += roundup(bufp_len, sizeof(uint32_t));
3372 	if (param->tx_params_valid) {
3373 		status = populate_tx_send_params(bufp, param->tx_param);
3374 		if (status != QDF_STATUS_SUCCESS) {
3375 			WMI_LOGE("%s: Populate TX send params failed",
3376 				 __func__);
3377 			goto unmap_tx_frame;
3378 		}
3379 		cmd_len += sizeof(wmi_tx_send_params);
3380 	}
3381 
3382 	wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0);
3383 	if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
3384 				      WMI_MGMT_TX_SEND_CMDID)) {
3385 		WMI_LOGE("%s: Failed to send mgmt Tx", __func__);
3386 		goto unmap_tx_frame;
3387 	}
3388 	return QDF_STATUS_SUCCESS;
3389 
3390 unmap_tx_frame:
3391 	qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame,
3392 				     QDF_DMA_TO_DEVICE);
3393 free_buf:
3394 	wmi_buf_free(buf);
3395 	return QDF_STATUS_E_FAILURE;
3396 }
3397 #endif /* CONFIG_HL_SUPPORT */
3398 
3399 /**
3400  *  send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data
3401  *  @wmi_handle      : handle to WMI.
3402  *  @param    : pointer to offchan data tx cmd parameter
3403  *
3404  *  Return: QDF_STATUS_SUCCESS  on success and error on failure.
3405  */
3406 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle,
3407 				struct wmi_offchan_data_tx_params *param)
3408 {
3409 	wmi_buf_t buf;
3410 	wmi_offchan_data_tx_send_cmd_fixed_param *cmd;
3411 	int32_t cmd_len;
3412 	uint64_t dma_addr;
3413 	void *qdf_ctx = param->qdf_ctx;
3414 	uint8_t *bufp;
3415 	int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ?
3416 					param->frm_len : mgmt_tx_dl_frm_len;
3417 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3418 
3419 	cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) +
3420 		  WMI_TLV_HDR_SIZE +
3421 		  roundup(bufp_len, sizeof(uint32_t));
3422 
3423 	buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len);
3424 	if (!buf) {
3425 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3426 		return QDF_STATUS_E_NOMEM;
3427 	}
3428 
3429 	cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf);
3430 	bufp = (uint8_t *) cmd;
3431 	WMITLV_SET_HDR(&cmd->tlv_header,
3432 		WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param,
3433 		WMITLV_GET_STRUCT_TLVLEN
3434 		(wmi_offchan_data_tx_send_cmd_fixed_param));
3435 
3436 	cmd->vdev_id = param->vdev_id;
3437 
3438 	cmd->desc_id = param->desc_id;
3439 	cmd->chanfreq = param->chanfreq;
3440 	bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param);
3441 	WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
3442 							    sizeof(uint32_t)));
3443 	bufp += WMI_TLV_HDR_SIZE;
3444 	qdf_mem_copy(bufp, param->pdata, bufp_len);
3445 	qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE);
3446 	dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0);
3447 	cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff);
3448 #if defined(HTT_PADDR64)
3449 	cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F);
3450 #endif
3451 	cmd->frame_len = param->frm_len;
3452 	cmd->buf_len = bufp_len;
3453 	cmd->tx_params_valid = param->tx_params_valid;
3454 
3455 	wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID,
3456 			bufp, cmd->vdev_id, cmd->chanfreq);
3457 
3458 	bufp += roundup(bufp_len, sizeof(uint32_t));
3459 	if (param->tx_params_valid) {
3460 		status = populate_tx_send_params(bufp, param->tx_param);
3461 		if (status != QDF_STATUS_SUCCESS) {
3462 			WMI_LOGE("%s: Populate TX send params failed",
3463 				 __func__);
3464 			goto err1;
3465 		}
3466 		cmd_len += sizeof(wmi_tx_send_params);
3467 	}
3468 
3469 	wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0);
3470 	if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
3471 				WMI_OFFCHAN_DATA_TX_SEND_CMDID)) {
3472 		WMI_LOGE("%s: Failed to offchan data Tx", __func__);
3473 		goto err1;
3474 	}
3475 
3476 	return QDF_STATUS_SUCCESS;
3477 
3478 err1:
3479 	wmi_buf_free(buf);
3480 	return QDF_STATUS_E_FAILURE;
3481 }
3482 
3483 /**
3484  * send_modem_power_state_cmd_tlv() - set modem power state to fw
3485  * @wmi_handle: wmi handle
3486  * @param_value: parameter value
3487  *
3488  * Return: QDF_STATUS_SUCCESS for success or error code
3489  */
3490 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle,
3491 		uint32_t param_value)
3492 {
3493 	QDF_STATUS ret;
3494 	wmi_modem_power_state_cmd_param *cmd;
3495 	wmi_buf_t buf;
3496 	uint16_t len = sizeof(*cmd);
3497 
3498 	buf = wmi_buf_alloc(wmi_handle, len);
3499 	if (!buf) {
3500 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3501 		return QDF_STATUS_E_NOMEM;
3502 	}
3503 	cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf);
3504 	WMITLV_SET_HDR(&cmd->tlv_header,
3505 		       WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param,
3506 		       WMITLV_GET_STRUCT_TLVLEN
3507 			       (wmi_modem_power_state_cmd_param));
3508 	cmd->modem_power_state = param_value;
3509 	WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__,
3510 		 param_value);
3511 	wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0);
3512 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3513 				     WMI_MODEM_POWER_STATE_CMDID);
3514 	if (QDF_IS_STATUS_ERROR(ret)) {
3515 		WMI_LOGE("Failed to send notify cmd ret = %d", ret);
3516 		wmi_buf_free(buf);
3517 	}
3518 
3519 	return ret;
3520 }
3521 
3522 /**
3523  * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw
3524  * @wmi_handle: wmi handle
3525  * @vdev_id: vdev id
3526  * @val: value
3527  *
3528  * Return: QDF_STATUS_SUCCESS for success or error code.
3529  */
3530 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle,
3531 			       uint32_t vdev_id, uint8_t val)
3532 {
3533 	wmi_sta_powersave_mode_cmd_fixed_param *cmd;
3534 	wmi_buf_t buf;
3535 	int32_t len = sizeof(*cmd);
3536 
3537 	WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val);
3538 
3539 	buf = wmi_buf_alloc(wmi_handle, len);
3540 	if (!buf) {
3541 		WMI_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__);
3542 		return QDF_STATUS_E_NOMEM;
3543 	}
3544 	cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf);
3545 	WMITLV_SET_HDR(&cmd->tlv_header,
3546 		       WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param,
3547 		       WMITLV_GET_STRUCT_TLVLEN
3548 			       (wmi_sta_powersave_mode_cmd_fixed_param));
3549 	cmd->vdev_id = vdev_id;
3550 	if (val)
3551 		cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED;
3552 	else
3553 		cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED;
3554 
3555 	wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0);
3556 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
3557 				 WMI_STA_POWERSAVE_MODE_CMDID)) {
3558 		WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d",
3559 			 vdev_id, val);
3560 		wmi_buf_free(buf);
3561 		return QDF_STATUS_E_FAILURE;
3562 	}
3563 	return 0;
3564 }
3565 
3566 /**
3567  * send_set_mimops_cmd_tlv() - set MIMO powersave
3568  * @wmi_handle: wmi handle
3569  * @vdev_id: vdev id
3570  * @value: value
3571  *
3572  * Return: QDF_STATUS_SUCCESS for success or error code.
3573  */
3574 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle,
3575 			uint8_t vdev_id, int value)
3576 {
3577 	QDF_STATUS ret;
3578 	wmi_sta_smps_force_mode_cmd_fixed_param *cmd;
3579 	wmi_buf_t buf;
3580 	uint16_t len = sizeof(*cmd);
3581 
3582 	buf = wmi_buf_alloc(wmi_handle, len);
3583 	if (!buf) {
3584 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3585 		return QDF_STATUS_E_NOMEM;
3586 	}
3587 	cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf);
3588 	WMITLV_SET_HDR(&cmd->tlv_header,
3589 		       WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param,
3590 		       WMITLV_GET_STRUCT_TLVLEN
3591 			       (wmi_sta_smps_force_mode_cmd_fixed_param));
3592 
3593 	cmd->vdev_id = vdev_id;
3594 
3595 	/* WMI_SMPS_FORCED_MODE values do not directly map
3596 	 * to SM power save values defined in the specification.
3597 	 * Make sure to send the right mapping.
3598 	 */
3599 	switch (value) {
3600 	case 0:
3601 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE;
3602 		break;
3603 	case 1:
3604 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED;
3605 		break;
3606 	case 2:
3607 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC;
3608 		break;
3609 	case 3:
3610 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC;
3611 		break;
3612 	default:
3613 		WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__);
3614 		wmi_buf_free(buf);
3615 		return QDF_STATUS_E_FAILURE;
3616 	}
3617 
3618 	WMI_LOGD("Setting vdev %d value = %u", vdev_id, value);
3619 
3620 	wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0);
3621 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3622 				   WMI_STA_SMPS_FORCE_MODE_CMDID);
3623 	if (QDF_IS_STATUS_ERROR(ret)) {
3624 		WMI_LOGE("Failed to send set Mimo PS ret = %d", ret);
3625 		wmi_buf_free(buf);
3626 	}
3627 
3628 	return ret;
3629 }
3630 
3631 /**
3632  * send_set_smps_params_cmd_tlv() - set smps params
3633  * @wmi_handle: wmi handle
3634  * @vdev_id: vdev id
3635  * @value: value
3636  *
3637  * Return: QDF_STATUS_SUCCESS for success or error code.
3638  */
3639 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
3640 			       int value)
3641 {
3642 	QDF_STATUS ret;
3643 	wmi_sta_smps_param_cmd_fixed_param *cmd;
3644 	wmi_buf_t buf;
3645 	uint16_t len = sizeof(*cmd);
3646 
3647 	buf = wmi_buf_alloc(wmi_handle, len);
3648 	if (!buf) {
3649 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3650 		return QDF_STATUS_E_NOMEM;
3651 	}
3652 	cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf);
3653 	WMITLV_SET_HDR(&cmd->tlv_header,
3654 		       WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param,
3655 		       WMITLV_GET_STRUCT_TLVLEN
3656 			       (wmi_sta_smps_param_cmd_fixed_param));
3657 
3658 	cmd->vdev_id = vdev_id;
3659 	cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS;
3660 	cmd->param =
3661 		(value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS;
3662 
3663 	WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value,
3664 		 cmd->param);
3665 
3666 	wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0);
3667 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3668 				   WMI_STA_SMPS_PARAM_CMDID);
3669 	if (QDF_IS_STATUS_ERROR(ret)) {
3670 		WMI_LOGE("Failed to send set Mimo PS ret = %d", ret);
3671 		wmi_buf_free(buf);
3672 	}
3673 
3674 	return ret;
3675 }
3676 
3677 /**
3678  * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw
3679  * @wmi_handle: wmi handle
3680  * @noa: p2p power save parameters
3681  *
3682  * Return: CDF status
3683  */
3684 static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle,
3685 			struct p2p_ps_params *noa)
3686 {
3687 	wmi_p2p_set_noa_cmd_fixed_param *cmd;
3688 	wmi_p2p_noa_descriptor *noa_discriptor;
3689 	wmi_buf_t buf;
3690 	uint8_t *buf_ptr;
3691 	uint16_t len;
3692 	QDF_STATUS status;
3693 	uint32_t duration;
3694 
3695 	WMI_LOGD("%s: Enter", __func__);
3696 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor);
3697 	buf = wmi_buf_alloc(wmi_handle, len);
3698 	if (!buf) {
3699 		WMI_LOGE("Failed to allocate memory");
3700 		status = QDF_STATUS_E_FAILURE;
3701 		goto end;
3702 	}
3703 
3704 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3705 	cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr;
3706 	WMITLV_SET_HDR(&cmd->tlv_header,
3707 		       WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param,
3708 		       WMITLV_GET_STRUCT_TLVLEN
3709 			       (wmi_p2p_set_noa_cmd_fixed_param));
3710 	duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration;
3711 	cmd->vdev_id = noa->session_id;
3712 	cmd->enable = (duration) ? true : false;
3713 	cmd->num_noa = 1;
3714 
3715 	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)),
3716 		       WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor));
3717 	noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr +
3718 						     sizeof
3719 						     (wmi_p2p_set_noa_cmd_fixed_param)
3720 						     + WMI_TLV_HDR_SIZE);
3721 	WMITLV_SET_HDR(&noa_discriptor->tlv_header,
3722 		       WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor,
3723 		       WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor));
3724 	noa_discriptor->type_count = noa->count;
3725 	noa_discriptor->duration = duration;
3726 	noa_discriptor->interval = noa->interval;
3727 	noa_discriptor->start_time = 0;
3728 
3729 	WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d",
3730 		 cmd->vdev_id, noa->count, noa_discriptor->duration,
3731 		 noa->interval);
3732 	wmi_mtrace(WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID, cmd->vdev_id, 0);
3733 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
3734 				      WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID);
3735 	if (QDF_IS_STATUS_ERROR(status)) {
3736 		WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID");
3737 		wmi_buf_free(buf);
3738 	}
3739 
3740 end:
3741 	WMI_LOGD("%s: Exit", __func__);
3742 	return status;
3743 }
3744 
3745 
3746 /**
3747  * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw
3748  * @wmi_handle: wmi handle
3749  * @noa: p2p opp power save parameters
3750  *
3751  * Return: CDF status
3752  */
3753 static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle,
3754 		struct p2p_ps_params *oppps)
3755 {
3756 	wmi_p2p_set_oppps_cmd_fixed_param *cmd;
3757 	wmi_buf_t buf;
3758 	QDF_STATUS status;
3759 
3760 	WMI_LOGD("%s: Enter", __func__);
3761 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
3762 	if (!buf) {
3763 		WMI_LOGE("Failed to allocate memory");
3764 		status = QDF_STATUS_E_FAILURE;
3765 		goto end;
3766 	}
3767 
3768 	cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf);
3769 	WMITLV_SET_HDR(&cmd->tlv_header,
3770 		       WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param,
3771 		       WMITLV_GET_STRUCT_TLVLEN
3772 			       (wmi_p2p_set_oppps_cmd_fixed_param));
3773 	cmd->vdev_id = oppps->session_id;
3774 	if (oppps->ctwindow)
3775 		WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd);
3776 
3777 	WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow);
3778 	WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d",
3779 		 cmd->vdev_id, oppps->ctwindow);
3780 	wmi_mtrace(WMI_P2P_SET_OPPPS_PARAM_CMDID, cmd->vdev_id, 0);
3781 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
3782 				      WMI_P2P_SET_OPPPS_PARAM_CMDID);
3783 	if (QDF_IS_STATUS_ERROR(status)) {
3784 		WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID");
3785 		wmi_buf_free(buf);
3786 	}
3787 
3788 end:
3789 	WMI_LOGD("%s: Exit", __func__);
3790 	return status;
3791 }
3792 
3793 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
3794 /**
3795  * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw
3796  * @wmi_handle: wmi handle
3797  * @param: p2p listen offload start parameters
3798  *
3799  * Return: QDF status
3800  */
3801 static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle,
3802 	struct p2p_lo_start *param)
3803 {
3804 	wmi_buf_t buf;
3805 	wmi_p2p_lo_start_cmd_fixed_param *cmd;
3806 	int32_t len = sizeof(*cmd);
3807 	uint8_t *buf_ptr;
3808 	QDF_STATUS status;
3809 	int device_types_len_aligned;
3810 	int probe_resp_len_aligned;
3811 
3812 	if (!param) {
3813 		WMI_LOGE("lo start param is null");
3814 		return QDF_STATUS_E_INVAL;
3815 	}
3816 
3817 	WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id);
3818 
3819 	device_types_len_aligned =
3820 		qdf_roundup(param->dev_types_len,
3821 			sizeof(uint32_t));
3822 	probe_resp_len_aligned =
3823 		qdf_roundup(param->probe_resp_len,
3824 			sizeof(uint32_t));
3825 
3826 	len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned +
3827 			probe_resp_len_aligned;
3828 
3829 	buf = wmi_buf_alloc(wmi_handle, len);
3830 	if (!buf) {
3831 		WMI_LOGE("%s: Failed to allocate memory for p2p lo start",
3832 			__func__);
3833 		return QDF_STATUS_E_NOMEM;
3834 	}
3835 
3836 	cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf);
3837 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3838 
3839 	WMITLV_SET_HDR(&cmd->tlv_header,
3840 		 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param,
3841 		 WMITLV_GET_STRUCT_TLVLEN(
3842 			wmi_p2p_lo_start_cmd_fixed_param));
3843 
3844 	cmd->vdev_id = param->vdev_id;
3845 	cmd->ctl_flags = param->ctl_flags;
3846 	cmd->channel = param->freq;
3847 	cmd->period = param->period;
3848 	cmd->interval = param->interval;
3849 	cmd->count = param->count;
3850 	cmd->device_types_len = param->dev_types_len;
3851 	cmd->prob_resp_len = param->probe_resp_len;
3852 
3853 	buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param);
3854 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
3855 				device_types_len_aligned);
3856 	buf_ptr += WMI_TLV_HDR_SIZE;
3857 	qdf_mem_copy(buf_ptr, param->device_types,
3858 			param->dev_types_len);
3859 
3860 	buf_ptr += device_types_len_aligned;
3861 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
3862 			probe_resp_len_aligned);
3863 	buf_ptr += WMI_TLV_HDR_SIZE;
3864 	qdf_mem_copy(buf_ptr, param->probe_resp_tmplt,
3865 			param->probe_resp_len);
3866 
3867 	WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__,
3868 	cmd->channel, cmd->period, cmd->interval, cmd->count);
3869 
3870 	wmi_mtrace(WMI_P2P_LISTEN_OFFLOAD_START_CMDID, cmd->vdev_id, 0);
3871 	status = wmi_unified_cmd_send(wmi_handle,
3872 				buf, len,
3873 				WMI_P2P_LISTEN_OFFLOAD_START_CMDID);
3874 	if (status != QDF_STATUS_SUCCESS) {
3875 		WMI_LOGE("%s: Failed to send p2p lo start: %d",
3876 			__func__, status);
3877 		wmi_buf_free(buf);
3878 		return status;
3879 	}
3880 
3881 	WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__);
3882 
3883 	return QDF_STATUS_SUCCESS;
3884 }
3885 
3886 /**
3887  * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw
3888  * @wmi_handle: wmi handle
3889  * @param: p2p listen offload stop parameters
3890  *
3891  * Return: QDF status
3892  */
3893 static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle,
3894 	uint8_t vdev_id)
3895 {
3896 	wmi_buf_t buf;
3897 	wmi_p2p_lo_stop_cmd_fixed_param *cmd;
3898 	int32_t len;
3899 	QDF_STATUS status;
3900 
3901 	WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id);
3902 
3903 	len = sizeof(*cmd);
3904 	buf = wmi_buf_alloc(wmi_handle, len);
3905 	if (!buf) {
3906 		qdf_print("%s: Failed to allocate memory for p2p lo stop",
3907 			__func__);
3908 		return QDF_STATUS_E_NOMEM;
3909 	}
3910 	cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf);
3911 
3912 	WMITLV_SET_HDR(&cmd->tlv_header,
3913 		WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param,
3914 		WMITLV_GET_STRUCT_TLVLEN(
3915 			wmi_p2p_lo_stop_cmd_fixed_param));
3916 
3917 	cmd->vdev_id = vdev_id;
3918 
3919 	WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__);
3920 
3921 	wmi_mtrace(WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID, cmd->vdev_id, 0);
3922 	status = wmi_unified_cmd_send(wmi_handle,
3923 				buf, len,
3924 				WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID);
3925 	if (status != QDF_STATUS_SUCCESS) {
3926 		WMI_LOGE("%s: Failed to send p2p lo stop: %d",
3927 			__func__, status);
3928 		wmi_buf_free(buf);
3929 		return status;
3930 	}
3931 
3932 	WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__);
3933 
3934 	return QDF_STATUS_SUCCESS;
3935 }
3936 #endif /* End of FEATURE_P2P_LISTEN_OFFLOAD */
3937 
3938 /**
3939  * send_get_temperature_cmd_tlv() - get pdev temperature req
3940  * @wmi_handle: wmi handle
3941  *
3942  * Return: QDF_STATUS_SUCCESS for success or error code.
3943  */
3944 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle)
3945 {
3946 	wmi_pdev_get_temperature_cmd_fixed_param *cmd;
3947 	wmi_buf_t wmi_buf;
3948 	uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param);
3949 	uint8_t *buf_ptr;
3950 
3951 	if (!wmi_handle) {
3952 		WMI_LOGE(FL("WMI is closed, can not issue cmd"));
3953 		return QDF_STATUS_E_INVAL;
3954 	}
3955 
3956 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
3957 	if (!wmi_buf) {
3958 		WMI_LOGE(FL("wmi_buf_alloc failed"));
3959 		return QDF_STATUS_E_NOMEM;
3960 	}
3961 
3962 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
3963 
3964 	cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr;
3965 	WMITLV_SET_HDR(&cmd->tlv_header,
3966 		       WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param,
3967 		       WMITLV_GET_STRUCT_TLVLEN
3968 			       (wmi_pdev_get_temperature_cmd_fixed_param));
3969 
3970 	wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0);
3971 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
3972 				 WMI_PDEV_GET_TEMPERATURE_CMDID)) {
3973 		WMI_LOGE(FL("failed to send get temperature command"));
3974 		wmi_buf_free(wmi_buf);
3975 		return QDF_STATUS_E_FAILURE;
3976 	}
3977 
3978 	return QDF_STATUS_SUCCESS;
3979 }
3980 
3981 /**
3982  * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command
3983  * @wmi_handle: wmi handle
3984  * @vdevid: vdev id
3985  * @peer_addr: peer mac address
3986  * @auto_triggerparam: auto trigger parameters
3987  * @num_ac: number of access category
3988  *
3989  * This function sets the trigger
3990  * uapsd params such as service interval, delay interval
3991  * and suspend interval which will be used by the firmware
3992  * to send trigger frames periodically when there is no
3993  * traffic on the transmit side.
3994  *
3995  * Return: QDF_STATUS_SUCCESS for success or error code.
3996  */
3997 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle,
3998 				struct sta_uapsd_trig_params *param)
3999 {
4000 	wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd;
4001 	QDF_STATUS ret;
4002 	uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param);
4003 	uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE;
4004 	uint32_t i;
4005 	wmi_buf_t buf;
4006 	uint8_t *buf_ptr;
4007 	struct sta_uapsd_params *uapsd_param;
4008 	wmi_sta_uapsd_auto_trig_param *trig_param;
4009 
4010 	buf = wmi_buf_alloc(wmi_handle, cmd_len);
4011 	if (!buf) {
4012 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
4013 		return QDF_STATUS_E_NOMEM;
4014 	}
4015 
4016 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
4017 	cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr;
4018 	WMITLV_SET_HDR(&cmd->tlv_header,
4019 		       WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param,
4020 		       WMITLV_GET_STRUCT_TLVLEN
4021 			       (wmi_sta_uapsd_auto_trig_cmd_fixed_param));
4022 	cmd->vdev_id = param->vdevid;
4023 	cmd->num_ac = param->num_ac;
4024 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
4025 
4026 	/* TLV indicating array of structures to follow */
4027 	buf_ptr += sizeof(*cmd);
4028 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len);
4029 
4030 	buf_ptr += WMI_TLV_HDR_SIZE;
4031 
4032 	/*
4033 	 * Update tag and length for uapsd auto trigger params (this will take
4034 	 * care of updating tag and length if it is not pre-filled by caller).
4035 	 */
4036 	uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam;
4037 	trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr;
4038 	for (i = 0; i < param->num_ac; i++) {
4039 		WMITLV_SET_HDR((buf_ptr +
4040 				(i * sizeof(wmi_sta_uapsd_auto_trig_param))),
4041 			       WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param,
4042 			       WMITLV_GET_STRUCT_TLVLEN
4043 				       (wmi_sta_uapsd_auto_trig_param));
4044 		trig_param->wmm_ac = uapsd_param->wmm_ac;
4045 		trig_param->user_priority = uapsd_param->user_priority;
4046 		trig_param->service_interval = uapsd_param->service_interval;
4047 		trig_param->suspend_interval = uapsd_param->suspend_interval;
4048 		trig_param->delay_interval = uapsd_param->delay_interval;
4049 		trig_param++;
4050 		uapsd_param++;
4051 	}
4052 
4053 	wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0);
4054 	ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
4055 				   WMI_STA_UAPSD_AUTO_TRIG_CMDID);
4056 	if (QDF_IS_STATUS_ERROR(ret)) {
4057 		WMI_LOGE("Failed to send set uapsd param ret = %d", ret);
4058 		wmi_buf_free(buf);
4059 	}
4060 
4061 	return ret;
4062 }
4063 
4064 #ifdef WLAN_FEATURE_DSRC
4065 /**
4066  * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware
4067  * @wmi_handle: pointer to the wmi handle
4068  * @utc: pointer to the UTC time struct
4069  *
4070  * Return: 0 on succes
4071  */
4072 static QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle,
4073 				struct ocb_utc_param *utc)
4074 {
4075 	QDF_STATUS ret;
4076 	wmi_ocb_set_utc_time_cmd_fixed_param *cmd;
4077 	uint8_t *buf_ptr;
4078 	uint32_t len, i;
4079 	wmi_buf_t buf;
4080 
4081 	len = sizeof(*cmd);
4082 	buf = wmi_buf_alloc(wmi_handle, len);
4083 	if (!buf) {
4084 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4085 		return QDF_STATUS_E_NOMEM;
4086 	}
4087 
4088 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4089 	cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr;
4090 	WMITLV_SET_HDR(&cmd->tlv_header,
4091 		WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param,
4092 		WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param));
4093 	cmd->vdev_id = utc->vdev_id;
4094 
4095 	for (i = 0; i < SIZE_UTC_TIME; i++)
4096 		WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]);
4097 
4098 	for (i = 0; i < SIZE_UTC_TIME_ERROR; i++)
4099 		WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]);
4100 
4101 	wmi_mtrace(WMI_OCB_SET_UTC_TIME_CMDID, cmd->vdev_id, 0);
4102 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4103 				   WMI_OCB_SET_UTC_TIME_CMDID);
4104 	if (QDF_IS_STATUS_ERROR(ret)) {
4105 		WMI_LOGE(FL("Failed to set OCB UTC time"));
4106 		wmi_buf_free(buf);
4107 	}
4108 
4109 	return ret;
4110 }
4111 
4112 /**
4113  * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement
4114  *				   frames on a channel
4115  * @wmi_handle: pointer to the wmi handle
4116  * @timing_advert: pointer to the timing advertisement struct
4117  *
4118  * Return: 0 on succes
4119  */
4120 static QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
4121 	struct ocb_timing_advert_param *timing_advert)
4122 {
4123 	QDF_STATUS ret;
4124 	wmi_ocb_start_timing_advert_cmd_fixed_param *cmd;
4125 	uint8_t *buf_ptr;
4126 	uint32_t len, len_template;
4127 	wmi_buf_t buf;
4128 
4129 	len = sizeof(*cmd) +
4130 		     WMI_TLV_HDR_SIZE;
4131 
4132 	len_template = timing_advert->template_length;
4133 	/* Add padding to the template if needed */
4134 	if (len_template % 4 != 0)
4135 		len_template += 4 - (len_template % 4);
4136 	len += len_template;
4137 
4138 	buf = wmi_buf_alloc(wmi_handle, len);
4139 	if (!buf) {
4140 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4141 		return QDF_STATUS_E_NOMEM;
4142 	}
4143 
4144 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4145 	cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr;
4146 	WMITLV_SET_HDR(&cmd->tlv_header,
4147 		WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param,
4148 		WMITLV_GET_STRUCT_TLVLEN(
4149 			wmi_ocb_start_timing_advert_cmd_fixed_param));
4150 	cmd->vdev_id = timing_advert->vdev_id;
4151 	cmd->repeat_rate = timing_advert->repeat_rate;
4152 	cmd->channel_freq = timing_advert->chan_freq;
4153 	cmd->timestamp_offset = timing_advert->timestamp_offset;
4154 	cmd->time_value_offset = timing_advert->time_value_offset;
4155 	cmd->timing_advert_template_length = timing_advert->template_length;
4156 	buf_ptr += sizeof(*cmd);
4157 
4158 	/* Add the timing advert template */
4159 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
4160 		       len_template);
4161 	qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
4162 		     (uint8_t *)timing_advert->template_value,
4163 		     timing_advert->template_length);
4164 
4165 	wmi_mtrace(WMI_OCB_START_TIMING_ADVERT_CMDID, cmd->vdev_id, 0);
4166 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4167 				   WMI_OCB_START_TIMING_ADVERT_CMDID);
4168 	if (QDF_IS_STATUS_ERROR(ret)) {
4169 		WMI_LOGE(FL("Failed to start OCB timing advert"));
4170 		wmi_buf_free(buf);
4171 	}
4172 
4173 	return ret;
4174 }
4175 
4176 /**
4177  * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames
4178  *				  on a channel
4179  * @wmi_handle: pointer to the wmi handle
4180  * @timing_advert: pointer to the timing advertisement struct
4181  *
4182  * Return: 0 on succes
4183  */
4184 static QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
4185 	struct ocb_timing_advert_param *timing_advert)
4186 {
4187 	QDF_STATUS ret;
4188 	wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd;
4189 	uint8_t *buf_ptr;
4190 	uint32_t len;
4191 	wmi_buf_t buf;
4192 
4193 	len = sizeof(*cmd);
4194 	buf = wmi_buf_alloc(wmi_handle, len);
4195 	if (!buf) {
4196 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4197 		return QDF_STATUS_E_NOMEM;
4198 	}
4199 
4200 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4201 	cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr;
4202 	WMITLV_SET_HDR(&cmd->tlv_header,
4203 		WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param,
4204 		WMITLV_GET_STRUCT_TLVLEN(
4205 			wmi_ocb_stop_timing_advert_cmd_fixed_param));
4206 	cmd->vdev_id = timing_advert->vdev_id;
4207 	cmd->channel_freq = timing_advert->chan_freq;
4208 
4209 	wmi_mtrace(WMI_OCB_STOP_TIMING_ADVERT_CMDID, cmd->vdev_id, 0);
4210 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4211 				   WMI_OCB_STOP_TIMING_ADVERT_CMDID);
4212 	if (QDF_IS_STATUS_ERROR(ret)) {
4213 		WMI_LOGE(FL("Failed to stop OCB timing advert"));
4214 		wmi_buf_free(buf);
4215 	}
4216 
4217 	return ret;
4218 }
4219 
4220 /**
4221  * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val
4222  * @wmi_handle: pointer to the wmi handle
4223  * @request: pointer to the request
4224  *
4225  * Return: 0 on succes
4226  */
4227 static QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle,
4228 			  uint8_t vdev_id)
4229 {
4230 	QDF_STATUS ret;
4231 	wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd;
4232 	uint8_t *buf_ptr;
4233 	wmi_buf_t buf;
4234 	int32_t len;
4235 
4236 	len = sizeof(*cmd);
4237 	buf = wmi_buf_alloc(wmi_handle, len);
4238 	if (!buf) {
4239 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4240 		return QDF_STATUS_E_NOMEM;
4241 	}
4242 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4243 
4244 	cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr;
4245 	qdf_mem_zero(cmd, len);
4246 	WMITLV_SET_HDR(&cmd->tlv_header,
4247 		WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param,
4248 		WMITLV_GET_STRUCT_TLVLEN(
4249 			wmi_ocb_get_tsf_timer_cmd_fixed_param));
4250 	cmd->vdev_id = vdev_id;
4251 
4252 	/* Send the WMI command */
4253 	wmi_mtrace(WMI_OCB_GET_TSF_TIMER_CMDID, cmd->vdev_id, 0);
4254 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4255 				   WMI_OCB_GET_TSF_TIMER_CMDID);
4256 	/* If there is an error, set the completion event */
4257 	if (QDF_IS_STATUS_ERROR(ret)) {
4258 		WMI_LOGE(FL("Failed to send WMI message: %d"), ret);
4259 		wmi_buf_free(buf);
4260 	}
4261 
4262 	return ret;
4263 }
4264 
4265 /**
4266  * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats
4267  * @wmi_handle: pointer to the wmi handle
4268  * @get_stats_param: pointer to the dcc stats
4269  *
4270  * Return: 0 on succes
4271  */
4272 static QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle,
4273 		     struct ocb_dcc_get_stats_param *get_stats_param)
4274 {
4275 	QDF_STATUS ret;
4276 	wmi_dcc_get_stats_cmd_fixed_param *cmd;
4277 	wmi_dcc_channel_stats_request *channel_stats_array;
4278 	wmi_buf_t buf;
4279 	uint8_t *buf_ptr;
4280 	uint32_t len;
4281 	uint32_t i;
4282 
4283 	/* Validate the input */
4284 	if (get_stats_param->request_array_len !=
4285 	    get_stats_param->channel_count * sizeof(*channel_stats_array)) {
4286 		WMI_LOGE(FL("Invalid parameter"));
4287 		return QDF_STATUS_E_INVAL;
4288 	}
4289 
4290 	/* Allocate memory for the WMI command */
4291 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
4292 		get_stats_param->request_array_len;
4293 
4294 	buf = wmi_buf_alloc(wmi_handle, len);
4295 	if (!buf) {
4296 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4297 		return QDF_STATUS_E_NOMEM;
4298 	}
4299 
4300 	buf_ptr = wmi_buf_data(buf);
4301 	qdf_mem_zero(buf_ptr, len);
4302 
4303 	/* Populate the WMI command */
4304 	cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr;
4305 	buf_ptr += sizeof(*cmd);
4306 
4307 	WMITLV_SET_HDR(&cmd->tlv_header,
4308 		       WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param,
4309 		       WMITLV_GET_STRUCT_TLVLEN(
4310 			   wmi_dcc_get_stats_cmd_fixed_param));
4311 	cmd->vdev_id = get_stats_param->vdev_id;
4312 	cmd->num_channels = get_stats_param->channel_count;
4313 
4314 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4315 		       get_stats_param->request_array_len);
4316 	buf_ptr += WMI_TLV_HDR_SIZE;
4317 
4318 	channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr;
4319 	qdf_mem_copy(channel_stats_array, get_stats_param->request_array,
4320 		     get_stats_param->request_array_len);
4321 	for (i = 0; i < cmd->num_channels; i++)
4322 		WMITLV_SET_HDR(&channel_stats_array[i].tlv_header,
4323 			WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request,
4324 			WMITLV_GET_STRUCT_TLVLEN(
4325 			    wmi_dcc_channel_stats_request));
4326 
4327 	/* Send the WMI command */
4328 	wmi_mtrace(WMI_DCC_GET_STATS_CMDID, cmd->vdev_id, 0);
4329 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4330 				   WMI_DCC_GET_STATS_CMDID);
4331 
4332 	if (QDF_IS_STATUS_ERROR(ret)) {
4333 		WMI_LOGE(FL("Failed to send WMI message: %d"), ret);
4334 		wmi_buf_free(buf);
4335 	}
4336 
4337 	return ret;
4338 }
4339 
4340 /**
4341  * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats
4342  * @wmi_handle: pointer to the wmi handle
4343  * @vdev_id: vdev id
4344  * @dcc_stats_bitmap: dcc status bitmap
4345  *
4346  * Return: 0 on succes
4347  */
4348 static QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle,
4349 				uint32_t vdev_id, uint32_t dcc_stats_bitmap)
4350 {
4351 	QDF_STATUS ret;
4352 	wmi_dcc_clear_stats_cmd_fixed_param *cmd;
4353 	wmi_buf_t buf;
4354 	uint8_t *buf_ptr;
4355 	uint32_t len;
4356 
4357 	/* Allocate memory for the WMI command */
4358 	len = sizeof(*cmd);
4359 
4360 	buf = wmi_buf_alloc(wmi_handle, len);
4361 	if (!buf) {
4362 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4363 		return QDF_STATUS_E_NOMEM;
4364 	}
4365 
4366 	buf_ptr = wmi_buf_data(buf);
4367 	qdf_mem_zero(buf_ptr, len);
4368 
4369 	/* Populate the WMI command */
4370 	cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr;
4371 
4372 	WMITLV_SET_HDR(&cmd->tlv_header,
4373 		       WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param,
4374 		       WMITLV_GET_STRUCT_TLVLEN(
4375 			   wmi_dcc_clear_stats_cmd_fixed_param));
4376 	cmd->vdev_id = vdev_id;
4377 	cmd->dcc_stats_bitmap = dcc_stats_bitmap;
4378 
4379 	/* Send the WMI command */
4380 	wmi_mtrace(WMI_DCC_CLEAR_STATS_CMDID, cmd->vdev_id, 0);
4381 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4382 				   WMI_DCC_CLEAR_STATS_CMDID);
4383 	if (QDF_IS_STATUS_ERROR(ret)) {
4384 		WMI_LOGE(FL("Failed to send the WMI command"));
4385 		wmi_buf_free(buf);
4386 	}
4387 
4388 	return ret;
4389 }
4390 
4391 /**
4392  * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data
4393  * @wmi_handle: pointer to the wmi handle
4394  * @update_ndl_param: pointer to the request parameters
4395  *
4396  * Return: 0 on success
4397  */
4398 static QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle,
4399 		       struct ocb_dcc_update_ndl_param *update_ndl_param)
4400 {
4401 	QDF_STATUS qdf_status;
4402 	wmi_dcc_update_ndl_cmd_fixed_param *cmd;
4403 	wmi_dcc_ndl_chan *ndl_chan_array;
4404 	wmi_dcc_ndl_active_state_config *ndl_active_state_array;
4405 	uint32_t active_state_count;
4406 	wmi_buf_t buf;
4407 	uint8_t *buf_ptr;
4408 	uint32_t len;
4409 	uint32_t i;
4410 
4411 	/* validate the input */
4412 	if (update_ndl_param->dcc_ndl_chan_list_len !=
4413 	    update_ndl_param->channel_count * sizeof(*ndl_chan_array)) {
4414 		WMI_LOGE(FL("Invalid parameter"));
4415 		return QDF_STATUS_E_INVAL;
4416 	}
4417 	active_state_count = 0;
4418 	ndl_chan_array = update_ndl_param->dcc_ndl_chan_list;
4419 	for (i = 0; i < update_ndl_param->channel_count; i++)
4420 		active_state_count +=
4421 			WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]);
4422 	if (update_ndl_param->dcc_ndl_active_state_list_len !=
4423 	    active_state_count * sizeof(*ndl_active_state_array)) {
4424 		WMI_LOGE(FL("Invalid parameter"));
4425 		return QDF_STATUS_E_INVAL;
4426 	}
4427 
4428 	/* Allocate memory for the WMI command */
4429 	len = sizeof(*cmd) +
4430 		WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len +
4431 		WMI_TLV_HDR_SIZE +
4432 		update_ndl_param->dcc_ndl_active_state_list_len;
4433 
4434 	buf = wmi_buf_alloc(wmi_handle, len);
4435 	if (!buf) {
4436 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4437 		return QDF_STATUS_E_NOMEM;
4438 	}
4439 
4440 	buf_ptr = wmi_buf_data(buf);
4441 	qdf_mem_zero(buf_ptr, len);
4442 
4443 	/* Populate the WMI command */
4444 	cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr;
4445 	buf_ptr += sizeof(*cmd);
4446 
4447 	WMITLV_SET_HDR(&cmd->tlv_header,
4448 		       WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param,
4449 		       WMITLV_GET_STRUCT_TLVLEN(
4450 			   wmi_dcc_update_ndl_cmd_fixed_param));
4451 	cmd->vdev_id = update_ndl_param->vdev_id;
4452 	cmd->num_channel = update_ndl_param->channel_count;
4453 
4454 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4455 		       update_ndl_param->dcc_ndl_chan_list_len);
4456 	buf_ptr += WMI_TLV_HDR_SIZE;
4457 
4458 	ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr;
4459 	qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list,
4460 		     update_ndl_param->dcc_ndl_chan_list_len);
4461 	for (i = 0; i < cmd->num_channel; i++)
4462 		WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header,
4463 			WMITLV_TAG_STRUC_wmi_dcc_ndl_chan,
4464 			WMITLV_GET_STRUCT_TLVLEN(
4465 			    wmi_dcc_ndl_chan));
4466 	buf_ptr += update_ndl_param->dcc_ndl_chan_list_len;
4467 
4468 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4469 		       update_ndl_param->dcc_ndl_active_state_list_len);
4470 	buf_ptr += WMI_TLV_HDR_SIZE;
4471 
4472 	ndl_active_state_array = (wmi_dcc_ndl_active_state_config *) buf_ptr;
4473 	qdf_mem_copy(ndl_active_state_array,
4474 		     update_ndl_param->dcc_ndl_active_state_list,
4475 		     update_ndl_param->dcc_ndl_active_state_list_len);
4476 	for (i = 0; i < active_state_count; i++) {
4477 		WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header,
4478 			WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config,
4479 			WMITLV_GET_STRUCT_TLVLEN(
4480 			    wmi_dcc_ndl_active_state_config));
4481 	}
4482 	buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len;
4483 
4484 	/* Send the WMI command */
4485 	wmi_mtrace(WMI_DCC_UPDATE_NDL_CMDID, cmd->vdev_id, 0);
4486 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
4487 				   WMI_DCC_UPDATE_NDL_CMDID);
4488 	/* If there is an error, set the completion event */
4489 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4490 		WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status);
4491 		wmi_buf_free(buf);
4492 	}
4493 
4494 	return qdf_status;
4495 }
4496 
4497 /**
4498  * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW
4499  * @wmi_handle: pointer to the wmi handle
4500  * @config: the OCB configuration
4501  *
4502  * Return: 0 on success
4503  */
4504 static QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle,
4505 				struct ocb_config *config)
4506 {
4507 	QDF_STATUS ret;
4508 	wmi_ocb_set_config_cmd_fixed_param *cmd;
4509 	wmi_channel *chan;
4510 	wmi_ocb_channel *ocb_chan;
4511 	wmi_qos_parameter *qos_param;
4512 	wmi_dcc_ndl_chan *ndl_chan;
4513 	wmi_dcc_ndl_active_state_config *ndl_active_config;
4514 	wmi_ocb_schedule_element *sched_elem;
4515 	uint8_t *buf_ptr;
4516 	wmi_buf_t buf;
4517 	int32_t len;
4518 	int32_t i, j, active_state_count;
4519 
4520 	/*
4521 	 * Validate the dcc_ndl_chan_list_len and count the number of active
4522 	 * states. Validate dcc_ndl_active_state_list_len.
4523 	 */
4524 	active_state_count = 0;
4525 	if (config->dcc_ndl_chan_list_len) {
4526 		if (!config->dcc_ndl_chan_list ||
4527 			config->dcc_ndl_chan_list_len !=
4528 			config->channel_count * sizeof(wmi_dcc_ndl_chan)) {
4529 			WMI_LOGE(FL("NDL channel is invalid. List len: %d"),
4530 				 config->dcc_ndl_chan_list_len);
4531 			return QDF_STATUS_E_INVAL;
4532 		}
4533 
4534 		for (i = 0, ndl_chan = config->dcc_ndl_chan_list;
4535 				i < config->channel_count; ++i, ++ndl_chan)
4536 			active_state_count +=
4537 				WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan);
4538 
4539 		if (active_state_count) {
4540 			if (!config->dcc_ndl_active_state_list ||
4541 				config->dcc_ndl_active_state_list_len !=
4542 				active_state_count *
4543 				sizeof(wmi_dcc_ndl_active_state_config)) {
4544 				WMI_LOGE(FL("NDL active state is invalid."));
4545 				return QDF_STATUS_E_INVAL;
4546 			}
4547 		}
4548 	}
4549 
4550 	len = sizeof(*cmd) +
4551 		WMI_TLV_HDR_SIZE + config->channel_count *
4552 			sizeof(wmi_channel) +
4553 		WMI_TLV_HDR_SIZE + config->channel_count *
4554 			sizeof(wmi_ocb_channel) +
4555 		WMI_TLV_HDR_SIZE + config->channel_count *
4556 			sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC +
4557 		WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len +
4558 		WMI_TLV_HDR_SIZE + active_state_count *
4559 			sizeof(wmi_dcc_ndl_active_state_config) +
4560 		WMI_TLV_HDR_SIZE + config->schedule_size *
4561 			sizeof(wmi_ocb_schedule_element);
4562 	buf = wmi_buf_alloc(wmi_handle, len);
4563 	if (!buf) {
4564 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4565 		return QDF_STATUS_E_NOMEM;
4566 	}
4567 
4568 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4569 	cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr;
4570 	WMITLV_SET_HDR(&cmd->tlv_header,
4571 		WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param,
4572 		WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param));
4573 	cmd->vdev_id = config->vdev_id;
4574 	cmd->channel_count = config->channel_count;
4575 	cmd->schedule_size = config->schedule_size;
4576 	cmd->flags = config->flags;
4577 	buf_ptr += sizeof(*cmd);
4578 
4579 	/* Add the wmi_channel info */
4580 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4581 		       config->channel_count*sizeof(wmi_channel));
4582 	buf_ptr += WMI_TLV_HDR_SIZE;
4583 	for (i = 0; i < config->channel_count; i++) {
4584 		chan = (wmi_channel *)buf_ptr;
4585 		WMITLV_SET_HDR(&chan->tlv_header,
4586 				WMITLV_TAG_STRUC_wmi_channel,
4587 				WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
4588 		chan->mhz = config->channels[i].chan_freq;
4589 		chan->band_center_freq1 = config->channels[i].chan_freq;
4590 		chan->band_center_freq2 = 0;
4591 		chan->info = 0;
4592 
4593 		WMI_SET_CHANNEL_MODE(chan, config->channels[i].ch_mode);
4594 		WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr);
4595 		WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr);
4596 		WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr);
4597 		WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr);
4598 		WMI_SET_CHANNEL_ANTENNA_MAX(chan,
4599 					    config->channels[i].antenna_max);
4600 
4601 		if (config->channels[i].bandwidth < 10)
4602 			WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
4603 		else if (config->channels[i].bandwidth < 20)
4604 			WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
4605 		buf_ptr += sizeof(*chan);
4606 	}
4607 
4608 	/* Add the wmi_ocb_channel info */
4609 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4610 		       config->channel_count*sizeof(wmi_ocb_channel));
4611 	buf_ptr += WMI_TLV_HDR_SIZE;
4612 	for (i = 0; i < config->channel_count; i++) {
4613 		ocb_chan = (wmi_ocb_channel *)buf_ptr;
4614 		WMITLV_SET_HDR(&ocb_chan->tlv_header,
4615 			       WMITLV_TAG_STRUC_wmi_ocb_channel,
4616 			       WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel));
4617 		ocb_chan->bandwidth = config->channels[i].bandwidth;
4618 		WMI_CHAR_ARRAY_TO_MAC_ADDR(
4619 					config->channels[i].mac_address.bytes,
4620 					&ocb_chan->mac_address);
4621 		buf_ptr += sizeof(*ocb_chan);
4622 	}
4623 
4624 	/* Add the wmi_qos_parameter info */
4625 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4626 		config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC);
4627 	buf_ptr += WMI_TLV_HDR_SIZE;
4628 	/* WMI_MAX_NUM_AC parameters for each channel */
4629 	for (i = 0; i < config->channel_count; i++) {
4630 		for (j = 0; j < WMI_MAX_NUM_AC; j++) {
4631 			qos_param = (wmi_qos_parameter *)buf_ptr;
4632 			WMITLV_SET_HDR(&qos_param->tlv_header,
4633 				WMITLV_TAG_STRUC_wmi_qos_parameter,
4634 				WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter));
4635 			qos_param->aifsn =
4636 				config->channels[i].qos_params[j].aifsn;
4637 			qos_param->cwmin =
4638 				config->channels[i].qos_params[j].cwmin;
4639 			qos_param->cwmax =
4640 				config->channels[i].qos_params[j].cwmax;
4641 			buf_ptr += sizeof(*qos_param);
4642 		}
4643 	}
4644 
4645 	/* Add the wmi_dcc_ndl_chan (per channel) */
4646 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4647 		       config->dcc_ndl_chan_list_len);
4648 	buf_ptr += WMI_TLV_HDR_SIZE;
4649 	if (config->dcc_ndl_chan_list_len) {
4650 		ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr;
4651 		qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list,
4652 			     config->dcc_ndl_chan_list_len);
4653 		for (i = 0; i < config->channel_count; i++)
4654 			WMITLV_SET_HDR(&(ndl_chan[i].tlv_header),
4655 				WMITLV_TAG_STRUC_wmi_dcc_ndl_chan,
4656 				WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan));
4657 		buf_ptr += config->dcc_ndl_chan_list_len;
4658 	}
4659 
4660 	/* Add the wmi_dcc_ndl_active_state_config */
4661 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count *
4662 		       sizeof(wmi_dcc_ndl_active_state_config));
4663 	buf_ptr += WMI_TLV_HDR_SIZE;
4664 	if (active_state_count) {
4665 		ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr;
4666 		qdf_mem_copy(ndl_active_config,
4667 			config->dcc_ndl_active_state_list,
4668 			active_state_count * sizeof(*ndl_active_config));
4669 		for (i = 0; i < active_state_count; ++i)
4670 			WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header),
4671 			  WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config,
4672 			  WMITLV_GET_STRUCT_TLVLEN(
4673 				wmi_dcc_ndl_active_state_config));
4674 		buf_ptr += active_state_count *
4675 			sizeof(*ndl_active_config);
4676 	}
4677 
4678 	/* Add the wmi_ocb_schedule_element info */
4679 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4680 		config->schedule_size * sizeof(wmi_ocb_schedule_element));
4681 	buf_ptr += WMI_TLV_HDR_SIZE;
4682 	for (i = 0; i < config->schedule_size; i++) {
4683 		sched_elem = (wmi_ocb_schedule_element *)buf_ptr;
4684 		WMITLV_SET_HDR(&sched_elem->tlv_header,
4685 			WMITLV_TAG_STRUC_wmi_ocb_schedule_element,
4686 			WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element));
4687 		sched_elem->channel_freq = config->schedule[i].chan_freq;
4688 		sched_elem->total_duration = config->schedule[i].total_duration;
4689 		sched_elem->guard_interval = config->schedule[i].guard_interval;
4690 		buf_ptr += sizeof(*sched_elem);
4691 	}
4692 
4693 
4694 	wmi_mtrace(WMI_OCB_SET_CONFIG_CMDID, cmd->vdev_id, 0);
4695 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4696 				   WMI_OCB_SET_CONFIG_CMDID);
4697 	if (QDF_IS_STATUS_ERROR(ret)) {
4698 		WMI_LOGE("Failed to set OCB config");
4699 		wmi_buf_free(buf);
4700 	}
4701 
4702 	return ret;
4703 }
4704 
4705 /**
4706  * extract_ocb_channel_config_resp_tlv() - extract ocb channel config resp
4707  * @wmi_handle: wmi handle
4708  * @evt_buf: wmi event buffer
4709  * @status: status buffer
4710  *
4711  * Return: QDF_STATUS_SUCCESS on success
4712  */
4713 static QDF_STATUS extract_ocb_channel_config_resp_tlv(wmi_unified_t wmi_handle,
4714 						      void *evt_buf,
4715 						      uint32_t *status)
4716 {
4717 	WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs;
4718 	wmi_ocb_set_config_resp_event_fixed_param *fix_param;
4719 
4720 	param_tlvs = evt_buf;
4721 	fix_param = param_tlvs->fixed_param;
4722 
4723 	*status = fix_param->status;
4724 	return QDF_STATUS_SUCCESS;
4725 }
4726 
4727 /**
4728  * extract_ocb_tsf_timer_tlv() - extract TSF timer from event buffer
4729  * @wmi_handle: wmi handle
4730  * @evt_buf: wmi event buffer
4731  * @resp: response buffer
4732  *
4733  * Return: QDF_STATUS_SUCCESS on success
4734  */
4735 static QDF_STATUS extract_ocb_tsf_timer_tlv(wmi_unified_t wmi_handle,
4736 			void *evt_buf, struct ocb_get_tsf_timer_response *resp)
4737 {
4738 	WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs;
4739 	wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param;
4740 
4741 	param_tlvs = evt_buf;
4742 	fix_param = param_tlvs->fixed_param;
4743 	resp->vdev_id = fix_param->vdev_id;
4744 	resp->timer_high = fix_param->tsf_timer_high;
4745 	resp->timer_low = fix_param->tsf_timer_low;
4746 
4747 	return QDF_STATUS_SUCCESS;
4748 }
4749 
4750 /**
4751  * extract_ocb_ndl_resp_tlv() - extract TSF timer from event buffer
4752  * @wmi_handle: wmi handle
4753  * @evt_buf: wmi event buffer
4754  * @resp: response buffer
4755  *
4756  * Return: QDF_STATUS_SUCCESS on success
4757  */
4758 static QDF_STATUS extract_ocb_ndl_resp_tlv(wmi_unified_t wmi_handle,
4759 		void *evt_buf, struct ocb_dcc_update_ndl_response *resp)
4760 {
4761 	WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs;
4762 	wmi_dcc_update_ndl_resp_event_fixed_param *fix_param;
4763 
4764 	param_tlvs = evt_buf;
4765 	fix_param = param_tlvs->fixed_param;
4766 	resp->vdev_id = fix_param->vdev_id;
4767 	resp->status = fix_param->status;
4768 	return QDF_STATUS_SUCCESS;
4769 }
4770 
4771 /**
4772  * extract_ocb_dcc_stats_tlv() - extract DCC stats from event buffer
4773  * @wmi_handle: wmi handle
4774  * @evt_buf: wmi event buffer
4775  * @resp: response buffer
4776  *
4777  * Since length of stats is variable, buffer for DCC stats will be allocated
4778  * in this function. The caller must free the buffer.
4779  *
4780  * Return: QDF_STATUS_SUCCESS on success
4781  */
4782 static QDF_STATUS extract_ocb_dcc_stats_tlv(wmi_unified_t wmi_handle,
4783 		void *evt_buf, struct ocb_dcc_get_stats_response **resp)
4784 {
4785 	struct ocb_dcc_get_stats_response *response;
4786 	WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs;
4787 	wmi_dcc_get_stats_resp_event_fixed_param *fix_param;
4788 
4789 	param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)evt_buf;
4790 	fix_param = param_tlvs->fixed_param;
4791 
4792 	/* Allocate and populate the response */
4793 	if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE -
4794 	    sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) {
4795 		WMI_LOGE("%s: too many channels:%d", __func__,
4796 			 fix_param->num_channels);
4797 		QDF_ASSERT(0);
4798 		*resp = NULL;
4799 		return QDF_STATUS_E_INVAL;
4800 	}
4801 	response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels *
4802 		sizeof(wmi_dcc_ndl_stats_per_channel));
4803 	*resp = response;
4804 	if (!response)
4805 		return  QDF_STATUS_E_NOMEM;
4806 
4807 	response->vdev_id = fix_param->vdev_id;
4808 	response->num_channels = fix_param->num_channels;
4809 	response->channel_stats_array_len =
4810 		fix_param->num_channels *
4811 		sizeof(wmi_dcc_ndl_stats_per_channel);
4812 	response->channel_stats_array = ((uint8_t *)response) +
4813 					sizeof(*response);
4814 	qdf_mem_copy(response->channel_stats_array,
4815 		     param_tlvs->stats_per_channel_list,
4816 		     response->channel_stats_array_len);
4817 
4818 	return QDF_STATUS_SUCCESS;
4819 }
4820 #endif
4821 
4822 /**
4823  * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable mcc scheduler
4824  * @wmi_handle: wmi handle
4825  * @mcc_adaptive_scheduler: enable/disable
4826  *
4827  * This function enable/disable mcc adaptive scheduler in fw.
4828  *
4829  * Return: QDF_STATUS_SUCCESS for success or error code
4830  */
4831 static QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv(
4832 		wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler,
4833 		uint32_t pdev_id)
4834 {
4835 	QDF_STATUS ret;
4836 	wmi_buf_t buf = 0;
4837 	wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL;
4838 	uint16_t len =
4839 		sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param);
4840 
4841 	buf = wmi_buf_alloc(wmi_handle, len);
4842 	if (!buf) {
4843 		WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
4844 		return QDF_STATUS_E_NOMEM;
4845 	}
4846 	cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *)
4847 		wmi_buf_data(buf);
4848 
4849 	WMITLV_SET_HDR(&cmd->tlv_header,
4850 		       WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param,
4851 		       WMITLV_GET_STRUCT_TLVLEN
4852 			       (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param));
4853 	cmd->enable = mcc_adaptive_scheduler;
4854 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
4855 
4856 	wmi_mtrace(WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID, NO_SESSION, 0);
4857 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4858 				   WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID);
4859 	if (QDF_IS_STATUS_ERROR(ret)) {
4860 		WMI_LOGP("%s: Failed to send enable/disable MCC"
4861 			 " adaptive scheduler command", __func__);
4862 		wmi_buf_free(buf);
4863 	}
4864 
4865 	return ret;
4866 }
4867 
4868 /**
4869  * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency
4870  * @wmi: wmi handle
4871  * @mcc_channel: mcc channel
4872  * @mcc_channel_time_latency: MCC channel time latency.
4873  *
4874  * Currently used to set time latency for an MCC vdev/adapter using operating
4875  * channel of it and channel number. The info is provided run time using
4876  * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>.
4877  *
4878  * Return: CDF status
4879  */
4880 static QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(wmi_unified_t wmi_handle,
4881 	uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency)
4882 {
4883 	QDF_STATUS ret;
4884 	wmi_buf_t buf = 0;
4885 	wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL;
4886 	uint16_t len = 0;
4887 	uint8_t *buf_ptr = NULL;
4888 	wmi_resmgr_chan_latency chan_latency;
4889 	/* Note: we only support MCC time latency for a single channel */
4890 	uint32_t num_channels = 1;
4891 	uint32_t chan1_freq = mcc_channel_freq;
4892 	uint32_t latency_chan1 = mcc_channel_time_latency;
4893 
4894 
4895 	/* If 0ms latency is provided, then FW will set to a default.
4896 	 * Otherwise, latency must be at least 30ms.
4897 	 */
4898 	if ((latency_chan1 > 0) &&
4899 	    (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) {
4900 		WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms "
4901 			 "Minimum is 30ms (or 0 to use default value by "
4902 			 "firmware)", __func__, latency_chan1);
4903 		return QDF_STATUS_E_INVAL;
4904 	}
4905 
4906 	/*   Set WMI CMD for channel time latency here */
4907 	len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) +
4908 	      WMI_TLV_HDR_SIZE +  /*Place holder for chan_time_latency array */
4909 	      num_channels * sizeof(wmi_resmgr_chan_latency);
4910 	buf = wmi_buf_alloc(wmi_handle, len);
4911 	if (!buf) {
4912 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
4913 		return QDF_STATUS_E_NOMEM;
4914 	}
4915 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
4916 	cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *)
4917 		wmi_buf_data(buf);
4918 	WMITLV_SET_HDR(&cmdTL->tlv_header,
4919 		WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param,
4920 		       WMITLV_GET_STRUCT_TLVLEN
4921 		       (wmi_resmgr_set_chan_latency_cmd_fixed_param));
4922 	cmdTL->num_chans = num_channels;
4923 	/* Update channel time latency information for home channel(s) */
4924 	buf_ptr += sizeof(*cmdTL);
4925 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
4926 		       num_channels * sizeof(wmi_resmgr_chan_latency));
4927 	buf_ptr += WMI_TLV_HDR_SIZE;
4928 	chan_latency.chan_mhz = chan1_freq;
4929 	chan_latency.latency = latency_chan1;
4930 	qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency));
4931 	wmi_mtrace(WMI_RESMGR_SET_CHAN_LATENCY_CMDID, NO_SESSION, 0);
4932 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4933 				   WMI_RESMGR_SET_CHAN_LATENCY_CMDID);
4934 	if (QDF_IS_STATUS_ERROR(ret)) {
4935 		WMI_LOGE("%s: Failed to send MCC Channel Time Latency command",
4936 			 __func__);
4937 		wmi_buf_free(buf);
4938 		QDF_ASSERT(0);
4939 	}
4940 
4941 	return ret;
4942 }
4943 
4944 /**
4945  * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota
4946  * @wmi: wmi handle
4947  * @adapter_1_chan_number: adapter 1 channel number
4948  * @adapter_1_quota: adapter 1 quota
4949  * @adapter_2_chan_number: adapter 2 channel number
4950  *
4951  * Return: CDF status
4952  */
4953 static QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(wmi_unified_t wmi_handle,
4954 	uint32_t adapter_1_chan_freq,
4955 	uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq)
4956 {
4957 	QDF_STATUS ret;
4958 	wmi_buf_t buf = 0;
4959 	uint16_t len = 0;
4960 	uint8_t *buf_ptr = NULL;
4961 	wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL;
4962 	wmi_resmgr_chan_time_quota chan_quota;
4963 	uint32_t quota_chan1 = adapter_1_quota;
4964 	/* Knowing quota of 1st chan., derive quota for 2nd chan. */
4965 	uint32_t quota_chan2 = 100 - quota_chan1;
4966 	/* Note: setting time quota for MCC requires info for 2 channels */
4967 	uint32_t num_channels = 2;
4968 	uint32_t chan1_freq = adapter_1_chan_freq;
4969 	uint32_t chan2_freq = adapter_2_chan_freq;
4970 
4971 	WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, "
4972 		 "freq2:%dMHz, Quota2:%dms", __func__,
4973 		 chan1_freq, quota_chan1, chan2_freq,
4974 		 quota_chan2);
4975 
4976 	/*
4977 	 * Perform sanity check on time quota values provided.
4978 	 */
4979 	if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA ||
4980 	    quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) {
4981 		WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum "
4982 			 "is 20ms & maximum is 80ms", __func__, quota_chan1);
4983 		return QDF_STATUS_E_INVAL;
4984 	}
4985 	/* Set WMI CMD for channel time quota here */
4986 	len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) +
4987 	      WMI_TLV_HDR_SIZE +       /* Place holder for chan_time_quota array */
4988 	      num_channels * sizeof(wmi_resmgr_chan_time_quota);
4989 	buf = wmi_buf_alloc(wmi_handle, len);
4990 	if (!buf) {
4991 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
4992 		QDF_ASSERT(0);
4993 		return QDF_STATUS_E_NOMEM;
4994 	}
4995 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
4996 	cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *)
4997 		wmi_buf_data(buf);
4998 	WMITLV_SET_HDR(&cmdTQ->tlv_header,
4999 		       WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param,
5000 		       WMITLV_GET_STRUCT_TLVLEN
5001 			       (wmi_resmgr_set_chan_time_quota_cmd_fixed_param));
5002 	cmdTQ->num_chans = num_channels;
5003 
5004 	/* Update channel time quota information for home channel(s) */
5005 	buf_ptr += sizeof(*cmdTQ);
5006 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5007 		       num_channels * sizeof(wmi_resmgr_chan_time_quota));
5008 	buf_ptr += WMI_TLV_HDR_SIZE;
5009 	chan_quota.chan_mhz = chan1_freq;
5010 	chan_quota.channel_time_quota = quota_chan1;
5011 	qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
5012 	/* Construct channel and quota record for the 2nd MCC mode. */
5013 	buf_ptr += sizeof(chan_quota);
5014 	chan_quota.chan_mhz = chan2_freq;
5015 	chan_quota.channel_time_quota = quota_chan2;
5016 	qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
5017 
5018 	wmi_mtrace(WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID, NO_SESSION, 0);
5019 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5020 				   WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID);
5021 	if (QDF_IS_STATUS_ERROR(ret)) {
5022 		WMI_LOGE("Failed to send MCC Channel Time Quota command");
5023 		wmi_buf_free(buf);
5024 		QDF_ASSERT(0);
5025 	}
5026 
5027 	return ret;
5028 }
5029 
5030 /**
5031  * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw
5032  * @wmi_handle: Pointer to wmi handle
5033  * @thermal_info: Thermal command information
5034  *
5035  * This function sends the thermal management command
5036  * to the firmware
5037  *
5038  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5039  */
5040 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
5041 				struct thermal_cmd_params *thermal_info)
5042 {
5043 	wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL;
5044 	wmi_buf_t buf = NULL;
5045 	QDF_STATUS status;
5046 	uint32_t len = 0;
5047 
5048 	len = sizeof(*cmd);
5049 
5050 	buf = wmi_buf_alloc(wmi_handle, len);
5051 	if (!buf) {
5052 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
5053 		return QDF_STATUS_E_FAILURE;
5054 	}
5055 
5056 	cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf);
5057 
5058 	WMITLV_SET_HDR(&cmd->tlv_header,
5059 		       WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param,
5060 		       WMITLV_GET_STRUCT_TLVLEN
5061 			       (wmi_thermal_mgmt_cmd_fixed_param));
5062 
5063 	cmd->lower_thresh_degreeC = thermal_info->min_temp;
5064 	cmd->upper_thresh_degreeC = thermal_info->max_temp;
5065 	cmd->enable = thermal_info->thermal_enable;
5066 
5067 	WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d",
5068 		cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable);
5069 
5070 	wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0);
5071 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
5072 				      WMI_THERMAL_MGMT_CMDID);
5073 	if (QDF_IS_STATUS_ERROR(status)) {
5074 		wmi_buf_free(buf);
5075 		WMI_LOGE("%s:Failed to send thermal mgmt command", __func__);
5076 	}
5077 
5078 	return status;
5079 }
5080 
5081 
5082 /**
5083  * send_lro_config_cmd_tlv() - process the LRO config command
5084  * @wmi_handle: Pointer to WMI handle
5085  * @wmi_lro_cmd: Pointer to LRO configuration parameters
5086  *
5087  * This function sends down the LRO configuration parameters to
5088  * the firmware to enable LRO, sets the TCP flags and sets the
5089  * seed values for the toeplitz hash generation
5090  *
5091  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5092  */
5093 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle,
5094 	 struct wmi_lro_config_cmd_t *wmi_lro_cmd)
5095 {
5096 	wmi_lro_info_cmd_fixed_param *cmd;
5097 	wmi_buf_t buf;
5098 	QDF_STATUS status;
5099 
5100 
5101 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
5102 	if (!buf) {
5103 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
5104 		return QDF_STATUS_E_FAILURE;
5105 	}
5106 
5107 	cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf);
5108 
5109 	WMITLV_SET_HDR(&cmd->tlv_header,
5110 		 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param,
5111 		 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param));
5112 
5113 	cmd->lro_enable = wmi_lro_cmd->lro_enable;
5114 	WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32,
5115 		 wmi_lro_cmd->tcp_flag);
5116 	WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32,
5117 		 wmi_lro_cmd->tcp_flag_mask);
5118 	cmd->toeplitz_hash_ipv4_0_3 =
5119 		 wmi_lro_cmd->toeplitz_hash_ipv4[0];
5120 	cmd->toeplitz_hash_ipv4_4_7 =
5121 		 wmi_lro_cmd->toeplitz_hash_ipv4[1];
5122 	cmd->toeplitz_hash_ipv4_8_11 =
5123 		 wmi_lro_cmd->toeplitz_hash_ipv4[2];
5124 	cmd->toeplitz_hash_ipv4_12_15 =
5125 		 wmi_lro_cmd->toeplitz_hash_ipv4[3];
5126 	cmd->toeplitz_hash_ipv4_16 =
5127 		 wmi_lro_cmd->toeplitz_hash_ipv4[4];
5128 
5129 	cmd->toeplitz_hash_ipv6_0_3 =
5130 		 wmi_lro_cmd->toeplitz_hash_ipv6[0];
5131 	cmd->toeplitz_hash_ipv6_4_7 =
5132 		 wmi_lro_cmd->toeplitz_hash_ipv6[1];
5133 	cmd->toeplitz_hash_ipv6_8_11 =
5134 		 wmi_lro_cmd->toeplitz_hash_ipv6[2];
5135 	cmd->toeplitz_hash_ipv6_12_15 =
5136 		 wmi_lro_cmd->toeplitz_hash_ipv6[3];
5137 	cmd->toeplitz_hash_ipv6_16_19 =
5138 		 wmi_lro_cmd->toeplitz_hash_ipv6[4];
5139 	cmd->toeplitz_hash_ipv6_20_23 =
5140 		 wmi_lro_cmd->toeplitz_hash_ipv6[5];
5141 	cmd->toeplitz_hash_ipv6_24_27 =
5142 		 wmi_lro_cmd->toeplitz_hash_ipv6[6];
5143 	cmd->toeplitz_hash_ipv6_28_31 =
5144 		 wmi_lro_cmd->toeplitz_hash_ipv6[7];
5145 	cmd->toeplitz_hash_ipv6_32_35 =
5146 		 wmi_lro_cmd->toeplitz_hash_ipv6[8];
5147 	cmd->toeplitz_hash_ipv6_36_39 =
5148 		 wmi_lro_cmd->toeplitz_hash_ipv6[9];
5149 	cmd->toeplitz_hash_ipv6_40 =
5150 		 wmi_lro_cmd->toeplitz_hash_ipv6[10];
5151 
5152 	WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x",
5153 		cmd->lro_enable, cmd->tcp_flag_u32);
5154 
5155 	wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0);
5156 	status = wmi_unified_cmd_send(wmi_handle, buf,
5157 		 sizeof(*cmd), WMI_LRO_CONFIG_CMDID);
5158 	if (QDF_IS_STATUS_ERROR(status)) {
5159 		wmi_buf_free(buf);
5160 		WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__);
5161 	}
5162 
5163 	return status;
5164 }
5165 
5166 /**
5167  * send_peer_rate_report_cmd_tlv() - process the peer rate report command
5168  * @wmi_handle: Pointer to wmi handle
5169  * @rate_report_params: Pointer to peer rate report parameters
5170  *
5171  *
5172  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5173  */
5174 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle,
5175 	 struct wmi_peer_rate_report_params *rate_report_params)
5176 {
5177 	wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL;
5178 	wmi_buf_t buf = NULL;
5179 	QDF_STATUS status = 0;
5180 	uint32_t len = 0;
5181 	uint32_t i, j;
5182 
5183 	len = sizeof(*cmd);
5184 
5185 	buf = wmi_buf_alloc(wmi_handle, len);
5186 	if (!buf) {
5187 		WMI_LOGE("Failed to alloc buf to peer_set_condition cmd\n");
5188 		return QDF_STATUS_E_FAILURE;
5189 	}
5190 
5191 	cmd = (wmi_peer_set_rate_report_condition_fixed_param *)
5192 		wmi_buf_data(buf);
5193 
5194 	WMITLV_SET_HDR(
5195 	&cmd->tlv_header,
5196 	WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param,
5197 	WMITLV_GET_STRUCT_TLVLEN(
5198 		wmi_peer_set_rate_report_condition_fixed_param));
5199 
5200 	cmd->enable_rate_report  = rate_report_params->rate_report_enable;
5201 	cmd->report_backoff_time = rate_report_params->backoff_time;
5202 	cmd->report_timer_period = rate_report_params->timer_period;
5203 	for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) {
5204 		cmd->cond_per_phy[i].val_cond_flags        =
5205 			rate_report_params->report_per_phy[i].cond_flags;
5206 		cmd->cond_per_phy[i].rate_delta.min_delta  =
5207 			rate_report_params->report_per_phy[i].delta.delta_min;
5208 		cmd->cond_per_phy[i].rate_delta.percentage =
5209 			rate_report_params->report_per_phy[i].delta.percent;
5210 		for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) {
5211 			cmd->cond_per_phy[i].rate_threshold[j] =
5212 			rate_report_params->report_per_phy[i].
5213 						report_rate_threshold[j];
5214 		}
5215 	}
5216 
5217 	WMI_LOGE("%s enable %d backoff_time %d period %d\n", __func__,
5218 		 cmd->enable_rate_report,
5219 		 cmd->report_backoff_time, cmd->report_timer_period);
5220 
5221 	wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0);
5222 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
5223 			WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID);
5224 	if (QDF_IS_STATUS_ERROR(status)) {
5225 		wmi_buf_free(buf);
5226 		WMI_LOGE("%s:Failed to send peer_set_report_cond command",
5227 			 __func__);
5228 	}
5229 	return status;
5230 }
5231 
5232 /**
5233  * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL
5234  * @wmi_handle: wmi handle
5235  * @param: bcn ll cmd parameter
5236  *
5237  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5238  */
5239 static QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle,
5240 			wmi_bcn_send_from_host_cmd_fixed_param *param)
5241 {
5242 	wmi_bcn_send_from_host_cmd_fixed_param *cmd;
5243 	wmi_buf_t wmi_buf;
5244 	QDF_STATUS ret;
5245 
5246 	wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
5247 	if (!wmi_buf) {
5248 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
5249 		return QDF_STATUS_E_FAILURE;
5250 	}
5251 
5252 	cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf);
5253 	WMITLV_SET_HDR(&cmd->tlv_header,
5254 		       WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param,
5255 		       WMITLV_GET_STRUCT_TLVLEN
5256 			       (wmi_bcn_send_from_host_cmd_fixed_param));
5257 	cmd->vdev_id = param->vdev_id;
5258 	cmd->data_len = param->data_len;
5259 	cmd->frame_ctrl = param->frame_ctrl;
5260 	cmd->frag_ptr = param->frag_ptr;
5261 	cmd->dtim_flag = param->dtim_flag;
5262 
5263 	wmi_mtrace(WMI_PDEV_SEND_BCN_CMDID, cmd->vdev_id, 0);
5264 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd),
5265 				      WMI_PDEV_SEND_BCN_CMDID);
5266 
5267 	if (QDF_IS_STATUS_ERROR(ret)) {
5268 		WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command");
5269 		wmi_buf_free(wmi_buf);
5270 	}
5271 
5272 	return ret;
5273 }
5274 
5275 /**
5276  * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters
5277  * @wmi_handle: wmi handle
5278  * @vdev_id: vdev id
5279  * @max_retries: max retries
5280  * @retry_interval: retry interval
5281  * This function sets sta query related parameters in fw.
5282  *
5283  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5284  */
5285 
5286 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle,
5287 				       uint8_t vdev_id, uint32_t max_retries,
5288 					   uint32_t retry_interval)
5289 {
5290 	wmi_buf_t buf;
5291 	WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd;
5292 	int len;
5293 
5294 	len = sizeof(*cmd);
5295 	buf = wmi_buf_alloc(wmi_handle, len);
5296 	if (!buf) {
5297 		WMI_LOGE(FL("wmi_buf_alloc failed"));
5298 		return QDF_STATUS_E_FAILURE;
5299 	}
5300 
5301 	cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf);
5302 	WMITLV_SET_HDR(&cmd->tlv_header,
5303 		WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param,
5304 		WMITLV_GET_STRUCT_TLVLEN
5305 		(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param));
5306 
5307 
5308 	cmd->vdev_id = vdev_id;
5309 	cmd->sa_query_max_retry_count = max_retries;
5310 	cmd->sa_query_retry_interval = retry_interval;
5311 
5312 	WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"),
5313 		 vdev_id, retry_interval, max_retries);
5314 
5315 	wmi_mtrace(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID, cmd->vdev_id, 0);
5316 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
5317 				 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) {
5318 		WMI_LOGE(FL("Failed to offload STA SA Query"));
5319 		wmi_buf_free(buf);
5320 		return QDF_STATUS_E_FAILURE;
5321 	}
5322 
5323 	WMI_LOGD(FL("Exit :"));
5324 	return 0;
5325 }
5326 
5327 /**
5328  * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters
5329  * @wmi_handle: wmi handle
5330  * @params: sta keep alive parameter
5331  *
5332  * This function sets keep alive related parameters in fw.
5333  *
5334  * Return: CDF status
5335  */
5336 static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle,
5337 				struct sta_params *params)
5338 {
5339 	wmi_buf_t buf;
5340 	WMI_STA_KEEPALIVE_CMD_fixed_param *cmd;
5341 	WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp;
5342 	uint8_t *buf_ptr;
5343 	int len;
5344 	QDF_STATUS ret;
5345 
5346 	WMI_LOGD("%s: Enter", __func__);
5347 
5348 	len = sizeof(*cmd) + sizeof(*arp_rsp);
5349 	buf = wmi_buf_alloc(wmi_handle, len);
5350 	if (!buf) {
5351 		WMI_LOGE("wmi_buf_alloc failed");
5352 		return QDF_STATUS_E_FAILURE;
5353 	}
5354 
5355 	cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf);
5356 	buf_ptr = (uint8_t *) cmd;
5357 	WMITLV_SET_HDR(&cmd->tlv_header,
5358 		       WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param,
5359 		       WMITLV_GET_STRUCT_TLVLEN
5360 			       (WMI_STA_KEEPALIVE_CMD_fixed_param));
5361 	cmd->interval = params->timeperiod;
5362 	cmd->enable = (params->timeperiod) ? 1 : 0;
5363 	cmd->vdev_id = params->vdev_id;
5364 	WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id,
5365 		 params->timeperiod, params->method);
5366 	arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd));
5367 	WMITLV_SET_HDR(&arp_rsp->tlv_header,
5368 		       WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE,
5369 		       WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE));
5370 
5371 	if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) ||
5372 	    (params->method ==
5373 	     WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) {
5374 		if ((NULL == params->hostv4addr) ||
5375 			(NULL == params->destv4addr) ||
5376 			(NULL == params->destmac)) {
5377 			WMI_LOGE("%s: received null pointer, hostv4addr:%pK "
5378 			   "destv4addr:%pK destmac:%pK ", __func__,
5379 			   params->hostv4addr, params->destv4addr, params->destmac);
5380 			wmi_buf_free(buf);
5381 			return QDF_STATUS_E_FAILURE;
5382 		}
5383 		cmd->method = params->method;
5384 		qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr,
5385 			     WMI_IPV4_ADDR_LEN);
5386 		qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr,
5387 			     WMI_IPV4_ADDR_LEN);
5388 		WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr);
5389 	} else {
5390 		cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
5391 	}
5392 
5393 	wmi_mtrace(WMI_STA_KEEPALIVE_CMDID, cmd->vdev_id, 0);
5394 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5395 				 WMI_STA_KEEPALIVE_CMDID);
5396 	if (QDF_IS_STATUS_ERROR(ret)) {
5397 		WMI_LOGE("Failed to set KeepAlive");
5398 		wmi_buf_free(buf);
5399 	}
5400 
5401 	WMI_LOGD("%s: Exit", __func__);
5402 	return ret;
5403 }
5404 
5405 /**
5406  * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params
5407  * @wmi_handle: wmi handle
5408  * @if_id: vdev id
5409  * @gtx_info: GTX config params
5410  *
5411  * This function set GTX related params in firmware.
5412  *
5413  * Return: QDF_STATUS_SUCCESS for success or error code
5414  */
5415 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id,
5416 				  struct wmi_gtx_config *gtx_info)
5417 {
5418 	wmi_vdev_set_gtx_params_cmd_fixed_param *cmd;
5419 	wmi_buf_t buf;
5420 	QDF_STATUS ret;
5421 	int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param);
5422 
5423 	buf = wmi_buf_alloc(wmi_handle, len);
5424 	if (!buf) {
5425 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
5426 		return QDF_STATUS_E_NOMEM;
5427 	}
5428 	cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf);
5429 	WMITLV_SET_HDR(&cmd->tlv_header,
5430 		       WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param,
5431 		       WMITLV_GET_STRUCT_TLVLEN
5432 			       (wmi_vdev_set_gtx_params_cmd_fixed_param));
5433 	cmd->vdev_id = if_id;
5434 
5435 	cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0];
5436 	cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1];
5437 	cmd->userGtxMask = gtx_info->gtx_usrcfg;
5438 	cmd->gtxPERThreshold = gtx_info->gtx_threshold;
5439 	cmd->gtxPERMargin = gtx_info->gtx_margin;
5440 	cmd->gtxTPCstep = gtx_info->gtx_tpcstep;
5441 	cmd->gtxTPCMin = gtx_info->gtx_tpcmin;
5442 	cmd->gtxBWMask = gtx_info->gtx_bwmask;
5443 
5444 	WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \
5445 		gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \
5446 		gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1],
5447 		 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin,
5448 		 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask);
5449 
5450 	wmi_mtrace(WMI_VDEV_SET_GTX_PARAMS_CMDID, cmd->vdev_id, 0);
5451 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5452 				    WMI_VDEV_SET_GTX_PARAMS_CMDID);
5453 	if (QDF_IS_STATUS_ERROR(ret)) {
5454 		WMI_LOGE("Failed to set GTX PARAMS");
5455 		wmi_buf_free(buf);
5456 	}
5457 	return ret;
5458 }
5459 
5460 /**
5461  * send_process_update_edca_param_cmd_tlv() - update EDCA params
5462  * @wmi_handle: wmi handle
5463  * @vdev_id: vdev id.
5464  * @wmm_vparams: edca parameters
5465  *
5466  * This function updates EDCA parameters to the target
5467  *
5468  * Return: CDF Status
5469  */
5470 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle,
5471 				    uint8_t vdev_id, bool mu_edca_param,
5472 				    struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC])
5473 {
5474 	uint8_t *buf_ptr;
5475 	wmi_buf_t buf;
5476 	wmi_vdev_set_wmm_params_cmd_fixed_param *cmd;
5477 	wmi_wmm_vparams *wmm_param;
5478 	struct wmi_host_wme_vparams *twmm_param;
5479 	int len = sizeof(*cmd);
5480 	int ac;
5481 
5482 	buf = wmi_buf_alloc(wmi_handle, len);
5483 
5484 	if (!buf) {
5485 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
5486 		return QDF_STATUS_E_NOMEM;
5487 	}
5488 
5489 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
5490 	cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr;
5491 	WMITLV_SET_HDR(&cmd->tlv_header,
5492 		       WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param,
5493 		       WMITLV_GET_STRUCT_TLVLEN
5494 			       (wmi_vdev_set_wmm_params_cmd_fixed_param));
5495 	cmd->vdev_id = vdev_id;
5496 	cmd->wmm_param_type = mu_edca_param;
5497 
5498 	for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) {
5499 		wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]);
5500 		twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]);
5501 		WMITLV_SET_HDR(&wmm_param->tlv_header,
5502 			       WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param,
5503 			       WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams));
5504 		wmm_param->cwmin = twmm_param->cwmin;
5505 		wmm_param->cwmax = twmm_param->cwmax;
5506 		wmm_param->aifs = twmm_param->aifs;
5507 		if (mu_edca_param)
5508 			wmm_param->mu_edca_timer = twmm_param->mu_edca_timer;
5509 		else
5510 			wmm_param->txoplimit = twmm_param->txoplimit;
5511 		wmm_param->acm = twmm_param->acm;
5512 		wmm_param->no_ack = twmm_param->noackpolicy;
5513 	}
5514 
5515 	wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0);
5516 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
5517 				 WMI_VDEV_SET_WMM_PARAMS_CMDID))
5518 		goto fail;
5519 
5520 	return QDF_STATUS_SUCCESS;
5521 
5522 fail:
5523 	wmi_buf_free(buf);
5524 	WMI_LOGE("%s: Failed to set WMM Paremeters", __func__);
5525 	return QDF_STATUS_E_FAILURE;
5526 }
5527 
5528 /**
5529  * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw
5530  * @wmi_handle: wmi handle
5531  * @vdev_id: vdev id
5532  * @probe_rsp_info: probe response info
5533  *
5534  * Return: QDF_STATUS_SUCCESS for success or error code
5535  */
5536 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle,
5537 				   uint8_t vdev_id,
5538 				   struct wmi_probe_resp_params *probe_rsp_info)
5539 {
5540 	wmi_prb_tmpl_cmd_fixed_param *cmd;
5541 	wmi_bcn_prb_info *bcn_prb_info;
5542 	wmi_buf_t wmi_buf;
5543 	uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len;
5544 	uint8_t *buf_ptr;
5545 	QDF_STATUS ret;
5546 
5547 	WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id);
5548 
5549 	tmpl_len = probe_rsp_info->prb_rsp_template_len;
5550 	tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t));
5551 
5552 	wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) +
5553 			sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE +
5554 			tmpl_len_aligned;
5555 
5556 	if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) {
5557 		WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"),
5558 		wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE);
5559 		return QDF_STATUS_E_INVAL;
5560 	}
5561 
5562 	wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
5563 	if (!wmi_buf) {
5564 		WMI_LOGE(FL("wmi_buf_alloc failed"));
5565 		return QDF_STATUS_E_NOMEM;
5566 	}
5567 
5568 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
5569 
5570 	cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr;
5571 	WMITLV_SET_HDR(&cmd->tlv_header,
5572 		       WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param,
5573 		       WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param));
5574 	cmd->vdev_id = vdev_id;
5575 	cmd->buf_len = tmpl_len;
5576 	buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param);
5577 
5578 	bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr;
5579 	WMITLV_SET_HDR(&bcn_prb_info->tlv_header,
5580 		       WMITLV_TAG_STRUC_wmi_bcn_prb_info,
5581 		       WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info));
5582 	bcn_prb_info->caps = 0;
5583 	bcn_prb_info->erp = 0;
5584 	buf_ptr += sizeof(wmi_bcn_prb_info);
5585 
5586 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned);
5587 	buf_ptr += WMI_TLV_HDR_SIZE;
5588 	qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len);
5589 
5590 	wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0);
5591 	ret = wmi_unified_cmd_send(wmi_handle,
5592 				   wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID);
5593 	if (QDF_IS_STATUS_ERROR(ret)) {
5594 		WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret);
5595 		wmi_buf_free(wmi_buf);
5596 	}
5597 
5598 	return ret;
5599 }
5600 
5601 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI)
5602 #define WPI_IV_LEN 16
5603 
5604 /**
5605  * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters
5606  *
5607  * @dest_tx: destination address of tsc key counter
5608  * @src_tx: source address of tsc key counter
5609  * @dest_rx: destination address of rsc key counter
5610  * @src_rx: source address of rsc key counter
5611  *
5612  * This function copies WAPI tsc and rsc key counters in the wmi buffer.
5613  *
5614  * Return: None
5615  *
5616  */
5617 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx,
5618 					uint8_t *dest_rx, uint8_t *src_rx)
5619 {
5620 	qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN);
5621 	qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN);
5622 }
5623 #else
5624 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx,
5625 					uint8_t *dest_rx, uint8_t *src_rx)
5626 {
5627 	return;
5628 }
5629 #endif
5630 
5631 /**
5632  * send_setup_install_key_cmd_tlv() - set key parameters
5633  * @wmi_handle: wmi handle
5634  * @key_params: key parameters
5635  *
5636  * This function fills structure from information
5637  * passed in key_params.
5638  *
5639  * Return: QDF_STATUS_SUCCESS - success
5640  *         QDF_STATUS_E_FAILURE - failure
5641  *         QDF_STATUS_E_NOMEM - not able to allocate buffer
5642  */
5643 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle,
5644 					   struct set_key_params *key_params)
5645 {
5646 	wmi_vdev_install_key_cmd_fixed_param *cmd;
5647 	wmi_buf_t buf;
5648 	uint8_t *buf_ptr;
5649 	uint32_t len;
5650 	uint8_t *key_data;
5651 	QDF_STATUS status;
5652 
5653 	len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) +
5654 	       WMI_TLV_HDR_SIZE;
5655 
5656 	buf = wmi_buf_alloc(wmi_handle, len);
5657 	if (!buf) {
5658 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
5659 		return QDF_STATUS_E_NOMEM;
5660 	}
5661 
5662 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
5663 	cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr;
5664 	WMITLV_SET_HDR(&cmd->tlv_header,
5665 		       WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param,
5666 		       WMITLV_GET_STRUCT_TLVLEN
5667 			       (wmi_vdev_install_key_cmd_fixed_param));
5668 	cmd->vdev_id = key_params->vdev_id;
5669 	cmd->key_ix = key_params->key_idx;
5670 
5671 
5672 	WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr);
5673 	cmd->key_flags |= key_params->key_flags;
5674 	cmd->key_cipher = key_params->key_cipher;
5675 	if ((key_params->key_txmic_len) &&
5676 			(key_params->key_rxmic_len)) {
5677 		cmd->key_txmic_len = key_params->key_txmic_len;
5678 		cmd->key_rxmic_len = key_params->key_rxmic_len;
5679 	}
5680 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI)
5681 	wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter,
5682 				   key_params->tx_iv,
5683 				   cmd->wpi_key_rsc_counter,
5684 				   key_params->rx_iv);
5685 #endif
5686 	buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param);
5687 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5688 		       roundup(key_params->key_len, sizeof(uint32_t)));
5689 	key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
5690 	qdf_mem_copy((void *)key_data,
5691 		     (const void *)key_params->key_data, key_params->key_len);
5692 	if (key_params->key_rsc_counter)
5693 	    qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter,
5694 			 sizeof(wmi_key_seq_counter));
5695 	cmd->key_len = key_params->key_len;
5696 
5697 	wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0);
5698 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
5699 					      WMI_VDEV_INSTALL_KEY_CMDID);
5700 	if (QDF_IS_STATUS_ERROR(status))
5701 		wmi_buf_free(buf);
5702 
5703 	return status;
5704 }
5705 
5706 /**
5707  * send_sar_limit_cmd_tlv() - send sar limit cmd to fw
5708  * @wmi_handle: wmi handle
5709  * @params: sar limit params
5710  *
5711  * Return: QDF_STATUS_SUCCESS for success or error code
5712  */
5713 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle,
5714 		struct sar_limit_cmd_params *sar_limit_params)
5715 {
5716 	wmi_buf_t buf;
5717 	QDF_STATUS qdf_status;
5718 	wmi_sar_limits_cmd_fixed_param *cmd;
5719 	int i;
5720 	uint8_t *buf_ptr;
5721 	wmi_sar_limit_cmd_row *wmi_sar_rows_list;
5722 	struct sar_limit_cmd_row *sar_rows_list;
5723 	uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
5724 
5725 	len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows;
5726 	buf = wmi_buf_alloc(wmi_handle, len);
5727 	if (!buf) {
5728 		WMI_LOGE("Failed to allocate memory");
5729 		qdf_status = QDF_STATUS_E_NOMEM;
5730 		goto end;
5731 	}
5732 
5733 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
5734 	cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr;
5735 	WMITLV_SET_HDR(&cmd->tlv_header,
5736 		       WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param,
5737 		       WMITLV_GET_STRUCT_TLVLEN
5738 		       (wmi_sar_limits_cmd_fixed_param));
5739 	cmd->sar_enable = sar_limit_params->sar_enable;
5740 	cmd->commit_limits = sar_limit_params->commit_limits;
5741 	cmd->num_limit_rows = sar_limit_params->num_limit_rows;
5742 
5743 	WMI_LOGD("no of sar rows = %d, len = %d",
5744 		 sar_limit_params->num_limit_rows, len);
5745 	buf_ptr += sizeof(*cmd);
5746 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5747 		       sizeof(wmi_sar_limit_cmd_row) *
5748 			       sar_limit_params->num_limit_rows);
5749 	if (cmd->num_limit_rows == 0)
5750 		goto send_sar_limits;
5751 
5752 	wmi_sar_rows_list = (wmi_sar_limit_cmd_row *)
5753 			(buf_ptr + WMI_TLV_HDR_SIZE);
5754 	sar_rows_list = sar_limit_params->sar_limit_row_list;
5755 
5756 	for (i = 0; i < sar_limit_params->num_limit_rows; i++) {
5757 		WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header,
5758 			       WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row,
5759 			       WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row));
5760 		wmi_sar_rows_list->band_id = sar_rows_list->band_id;
5761 		wmi_sar_rows_list->chain_id = sar_rows_list->chain_id;
5762 		wmi_sar_rows_list->mod_id = sar_rows_list->mod_id;
5763 		wmi_sar_rows_list->limit_value = sar_rows_list->limit_value;
5764 		wmi_sar_rows_list->validity_bitmap =
5765 						sar_rows_list->validity_bitmap;
5766 		WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d",
5767 			 i, wmi_sar_rows_list->band_id,
5768 			 wmi_sar_rows_list->chain_id,
5769 			 wmi_sar_rows_list->mod_id,
5770 			 wmi_sar_rows_list->limit_value,
5771 			 wmi_sar_rows_list->validity_bitmap);
5772 		sar_rows_list++;
5773 		wmi_sar_rows_list++;
5774 	}
5775 send_sar_limits:
5776 	wmi_mtrace(WMI_SAR_LIMITS_CMDID, NO_SESSION, 0);
5777 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
5778 				      WMI_SAR_LIMITS_CMDID);
5779 
5780 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
5781 		WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID");
5782 		wmi_buf_free(buf);
5783 	}
5784 
5785 end:
5786 	return qdf_status;
5787 }
5788 
5789 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle)
5790 {
5791 	wmi_sar_get_limits_cmd_fixed_param *cmd;
5792 	wmi_buf_t wmi_buf;
5793 	uint32_t len;
5794 	QDF_STATUS status;
5795 
5796 	WMI_LOGD(FL("Enter"));
5797 
5798 	len = sizeof(*cmd);
5799 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
5800 	if (!wmi_buf) {
5801 		WMI_LOGP(FL("failed to allocate memory for msg"));
5802 		return QDF_STATUS_E_NOMEM;
5803 	}
5804 
5805 	cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf);
5806 
5807 	WMITLV_SET_HDR(&cmd->tlv_header,
5808 		       WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param,
5809 		       WMITLV_GET_STRUCT_TLVLEN
5810 				(wmi_sar_get_limits_cmd_fixed_param));
5811 
5812 	cmd->reserved = 0;
5813 
5814 	wmi_mtrace(WMI_SAR_GET_LIMITS_CMDID, NO_SESSION, 0);
5815 	status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
5816 				      WMI_SAR_GET_LIMITS_CMDID);
5817 	if (QDF_IS_STATUS_ERROR(status)) {
5818 		WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status);
5819 		wmi_buf_free(wmi_buf);
5820 	}
5821 
5822 	WMI_LOGD(FL("Exit"));
5823 
5824 	return status;
5825 }
5826 
5827 /**
5828  * wmi_sar2_result_string() - return string conversion of sar2 result
5829  * @result: sar2 result value
5830  *
5831  * This utility function helps log string conversion of sar2 result.
5832  *
5833  * Return: string conversion of sar 2 result, if match found;
5834  *	   "Unknown response" otherwise.
5835  */
5836 static const char *wmi_sar2_result_string(uint32_t result)
5837 {
5838 	switch (result) {
5839 	CASE_RETURN_STRING(WMI_SAR2_SUCCESS);
5840 	CASE_RETURN_STRING(WMI_SAR2_INVALID_ANTENNA_INDEX);
5841 	CASE_RETURN_STRING(WMI_SAR2_INVALID_TABLE_INDEX);
5842 	CASE_RETURN_STRING(WMI_SAR2_STATE_ERROR);
5843 	CASE_RETURN_STRING(WMI_SAR2_BDF_NO_TABLE);
5844 	default:
5845 		return "Unknown response";
5846 	}
5847 }
5848 
5849 /**
5850  * extract_sar2_result_event_tlv() -  process sar response event from FW.
5851  * @handle: wma handle
5852  * @event: event buffer
5853  * @len: buffer length
5854  *
5855  * Return: 0 for success or error code
5856  */
5857 static QDF_STATUS extract_sar2_result_event_tlv(void *handle,
5858 						uint8_t *event,
5859 						uint32_t len)
5860 {
5861 	wmi_sar2_result_event_fixed_param *sar2_fixed_param;
5862 
5863 	WMI_SAR2_RESULT_EVENTID_param_tlvs *param_buf =
5864 		(WMI_SAR2_RESULT_EVENTID_param_tlvs *)event;
5865 
5866 	if (!param_buf) {
5867 		WMI_LOGI("Invalid sar2 result event buffer");
5868 		return QDF_STATUS_E_INVAL;
5869 	}
5870 
5871 	sar2_fixed_param = param_buf->fixed_param;
5872 	if (!sar2_fixed_param) {
5873 		WMI_LOGI("Invalid sar2 result event fixed param buffer");
5874 		return QDF_STATUS_E_INVAL;
5875 	}
5876 
5877 	WMI_LOGI("SAR2 result: %s",
5878 		 wmi_sar2_result_string(sar2_fixed_param->result));
5879 
5880 	return QDF_STATUS_SUCCESS;
5881 }
5882 
5883 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle,
5884 					      uint8_t *evt_buf,
5885 					      struct sar_limit_event *event)
5886 {
5887 	wmi_sar_get_limits_event_fixed_param *fixed_param;
5888 	WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf;
5889 	wmi_sar_get_limit_event_row *row_in;
5890 	struct sar_limit_event_row *row_out;
5891 	uint32_t row;
5892 
5893 	if (!evt_buf) {
5894 		WMI_LOGE(FL("input event is NULL"));
5895 		return QDF_STATUS_E_INVAL;
5896 	}
5897 	if (!event) {
5898 		WMI_LOGE(FL("output event is NULL"));
5899 		return QDF_STATUS_E_INVAL;
5900 	}
5901 
5902 	param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf;
5903 
5904 	fixed_param = param_buf->fixed_param;
5905 	if (!fixed_param) {
5906 		WMI_LOGE(FL("Invalid fixed param"));
5907 		return QDF_STATUS_E_INVAL;
5908 	}
5909 
5910 	event->sar_enable = fixed_param->sar_enable;
5911 	event->num_limit_rows = fixed_param->num_limit_rows;
5912 
5913 	if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) {
5914 		QDF_ASSERT(0);
5915 		WMI_LOGE(FL("Num rows %d exceeds max of %d"),
5916 			 event->num_limit_rows,
5917 			 MAX_SAR_LIMIT_ROWS_SUPPORTED);
5918 		event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED;
5919 	}
5920 
5921 	row_in = param_buf->sar_get_limits;
5922 	row_out = &event->sar_limit_row[0];
5923 	for (row = 0; row < event->num_limit_rows; row++) {
5924 		row_out->band_id = row_in->band_id;
5925 		row_out->chain_id = row_in->chain_id;
5926 		row_out->mod_id = row_in->mod_id;
5927 		row_out->limit_value = row_in->limit_value;
5928 		row_out++;
5929 		row_in++;
5930 	}
5931 
5932 	return QDF_STATUS_SUCCESS;
5933 }
5934 
5935 #ifdef WLAN_FEATURE_DISA
5936 /**
5937  * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw
5938  * @wmi_handle: wmi handle
5939  * @params: encrypt/decrypt params
5940  *
5941  * Return: QDF_STATUS_SUCCESS for success or error code
5942  */
5943 static
5944 QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle,
5945 		struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params)
5946 {
5947 	wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd;
5948 	wmi_buf_t wmi_buf;
5949 	uint8_t *buf_ptr;
5950 	QDF_STATUS ret;
5951 	uint32_t len;
5952 
5953 	WMI_LOGD(FL("Send encrypt decrypt cmd"));
5954 
5955 	len = sizeof(*cmd) +
5956 		roundup(encrypt_decrypt_params->data_len, sizeof(uint32_t)) +
5957 		WMI_TLV_HDR_SIZE;
5958 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
5959 	if (!wmi_buf) {
5960 		WMI_LOGP("%s: failed to allocate memory for encrypt/decrypt msg",
5961 			 __func__);
5962 		return QDF_STATUS_E_NOMEM;
5963 	}
5964 
5965 	buf_ptr = wmi_buf_data(wmi_buf);
5966 	cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr;
5967 
5968 	WMITLV_SET_HDR(&cmd->tlv_header,
5969 		WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param,
5970 		WMITLV_GET_STRUCT_TLVLEN(
5971 			wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param));
5972 
5973 	cmd->vdev_id = encrypt_decrypt_params->vdev_id;
5974 	cmd->key_flag = encrypt_decrypt_params->key_flag;
5975 	cmd->key_idx = encrypt_decrypt_params->key_idx;
5976 	cmd->key_cipher = encrypt_decrypt_params->key_cipher;
5977 	cmd->key_len = encrypt_decrypt_params->key_len;
5978 	cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len;
5979 	cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len;
5980 
5981 	qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data,
5982 				encrypt_decrypt_params->key_len);
5983 
5984 	qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header,
5985 				MAX_MAC_HEADER_LEN);
5986 
5987 	cmd->data_len = encrypt_decrypt_params->data_len;
5988 
5989 	if (cmd->data_len) {
5990 		buf_ptr += sizeof(*cmd);
5991 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5992 				roundup(encrypt_decrypt_params->data_len,
5993 					sizeof(uint32_t)));
5994 		buf_ptr += WMI_TLV_HDR_SIZE;
5995 		qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data,
5996 					encrypt_decrypt_params->data_len);
5997 	}
5998 
5999 	/* This conversion is to facilitate data to FW in little endian */
6000 	cmd->pn[5] = encrypt_decrypt_params->pn[0];
6001 	cmd->pn[4] = encrypt_decrypt_params->pn[1];
6002 	cmd->pn[3] = encrypt_decrypt_params->pn[2];
6003 	cmd->pn[2] = encrypt_decrypt_params->pn[3];
6004 	cmd->pn[1] = encrypt_decrypt_params->pn[4];
6005 	cmd->pn[0] = encrypt_decrypt_params->pn[5];
6006 
6007 	wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0);
6008 	ret = wmi_unified_cmd_send(wmi_handle,
6009 				   wmi_buf, len,
6010 				   WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID);
6011 	if (QDF_IS_STATUS_ERROR(ret)) {
6012 		WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret);
6013 		wmi_buf_free(wmi_buf);
6014 	}
6015 
6016 	return ret;
6017 }
6018 
6019 /**
6020  * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp
6021  *	params from event
6022  * @wmi_handle: wmi handle
6023  * @evt_buf: pointer to event buffer
6024  * @resp: Pointer to hold resp parameters
6025  *
6026  * Return: QDF_STATUS_SUCCESS for success or error code
6027  */
6028 static
6029 QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle,
6030 	void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp)
6031 {
6032 	WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf;
6033 	wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event;
6034 
6035 	param_buf = evt_buf;
6036 	if (!param_buf) {
6037 		WMI_LOGE("encrypt decrypt resp evt_buf is NULL");
6038 		return QDF_STATUS_E_INVAL;
6039 	}
6040 
6041 	data_event = param_buf->fixed_param;
6042 
6043 	resp->vdev_id = data_event->vdev_id;
6044 	resp->status = data_event->status;
6045 
6046 	if ((data_event->data_length > param_buf->num_enc80211_frame) ||
6047 	    (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE -
6048 	     sizeof(*data_event))) {
6049 		WMI_LOGE("FW msg data_len %d more than TLV hdr %d",
6050 			 data_event->data_length,
6051 			 param_buf->num_enc80211_frame);
6052 		return QDF_STATUS_E_INVAL;
6053 	}
6054 
6055 	resp->data_len = data_event->data_length;
6056 
6057 	if (resp->data_len)
6058 		resp->data = (uint8_t *)param_buf->enc80211_frame;
6059 
6060 	return QDF_STATUS_SUCCESS;
6061 }
6062 #endif
6063 
6064 /**
6065  * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go
6066  * @wmi_handle: wmi handle
6067  * @vdev_id: vdev id
6068  * @p2p_ie: p2p IE
6069  *
6070  * Return: QDF_STATUS_SUCCESS for success or error code
6071  */
6072 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle,
6073 				    uint32_t vdev_id, uint8_t *p2p_ie)
6074 {
6075 	QDF_STATUS ret;
6076 	wmi_p2p_go_set_beacon_ie_fixed_param *cmd;
6077 	wmi_buf_t wmi_buf;
6078 	uint32_t ie_len, ie_len_aligned, wmi_buf_len;
6079 	uint8_t *buf_ptr;
6080 
6081 	ie_len = (uint32_t) (p2p_ie[1] + 2);
6082 
6083 	/* More than one P2P IE may be included in a single frame.
6084 	   If multiple P2P IEs are present, the complete P2P attribute
6085 	   data consists of the concatenation of the P2P Attribute
6086 	   fields of the P2P IEs. The P2P Attributes field of each
6087 	   P2P IE may be any length up to the maximum (251 octets).
6088 	   In this case host sends one P2P IE to firmware so the length
6089 	   should not exceed more than 251 bytes
6090 	 */
6091 	if (ie_len > 251) {
6092 		WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len);
6093 		return QDF_STATUS_E_INVAL;
6094 	}
6095 
6096 	ie_len_aligned = roundup(ie_len, sizeof(uint32_t));
6097 
6098 	wmi_buf_len =
6099 		sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned +
6100 		WMI_TLV_HDR_SIZE;
6101 
6102 	wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
6103 	if (!wmi_buf) {
6104 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6105 		return QDF_STATUS_E_NOMEM;
6106 	}
6107 
6108 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
6109 
6110 	cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr;
6111 	WMITLV_SET_HDR(&cmd->tlv_header,
6112 		       WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param,
6113 		       WMITLV_GET_STRUCT_TLVLEN
6114 			       (wmi_p2p_go_set_beacon_ie_fixed_param));
6115 	cmd->vdev_id = vdev_id;
6116 	cmd->ie_buf_len = ie_len;
6117 
6118 	buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param);
6119 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
6120 	buf_ptr += WMI_TLV_HDR_SIZE;
6121 	qdf_mem_copy(buf_ptr, p2p_ie, ie_len);
6122 
6123 	WMI_LOGD("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__);
6124 
6125 	wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0);
6126 	ret = wmi_unified_cmd_send(wmi_handle,
6127 				   wmi_buf, wmi_buf_len,
6128 				   WMI_P2P_GO_SET_BEACON_IE);
6129 	if (QDF_IS_STATUS_ERROR(ret)) {
6130 		WMI_LOGE("Failed to send bcn tmpl: %d", ret);
6131 		wmi_buf_free(wmi_buf);
6132 	}
6133 
6134 	WMI_LOGD("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__);
6135 	return ret;
6136 }
6137 
6138 /**
6139  * send_set_gateway_params_cmd_tlv() - set gateway parameters
6140  * @wmi_handle: wmi handle
6141  * @req: gateway parameter update request structure
6142  *
6143  * This function reads the incoming @req and fill in the destination
6144  * WMI structure and sends down the gateway configs down to the firmware
6145  *
6146  * Return: QDF_STATUS
6147  */
6148 static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle,
6149 				struct gateway_update_req_param *req)
6150 {
6151 	wmi_roam_subnet_change_config_fixed_param *cmd;
6152 	wmi_buf_t buf;
6153 	QDF_STATUS ret;
6154 	int len = sizeof(*cmd);
6155 
6156 	buf = wmi_buf_alloc(wmi_handle, len);
6157 	if (!buf) {
6158 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
6159 		return QDF_STATUS_E_NOMEM;
6160 	}
6161 
6162 	cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf);
6163 	WMITLV_SET_HDR(&cmd->tlv_header,
6164 		WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param,
6165 		WMITLV_GET_STRUCT_TLVLEN(
6166 			wmi_roam_subnet_change_config_fixed_param));
6167 
6168 	cmd->vdev_id = req->session_id;
6169 	qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr,
6170 		QDF_IPV4_ADDR_SIZE);
6171 	qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr,
6172 		QDF_IPV6_ADDR_SIZE);
6173 	WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes,
6174 		&cmd->inet_gw_mac_addr);
6175 	cmd->max_retries = req->max_retries;
6176 	cmd->timeout = req->timeout;
6177 	cmd->num_skip_subnet_change_detection_bssid_list = 0;
6178 	cmd->flag = 0;
6179 	if (req->ipv4_addr_type)
6180 		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag);
6181 
6182 	if (req->ipv6_addr_type)
6183 		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag);
6184 
6185 	wmi_mtrace(WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID, cmd->vdev_id, 0);
6186 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6187 				WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID);
6188 	if (QDF_IS_STATUS_ERROR(ret)) {
6189 		WMI_LOGE("Failed to send gw config parameter to fw, ret: %d",
6190 			ret);
6191 		wmi_buf_free(buf);
6192 	}
6193 
6194 	return ret;
6195 }
6196 
6197 /**
6198  * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring
6199  * @wmi_handle: wmi handle
6200  * @req: rssi monitoring request structure
6201  *
6202  * This function reads the incoming @req and fill in the destination
6203  * WMI structure and send down the rssi monitoring configs down to the firmware
6204  *
6205  * Return: 0 on success; error number otherwise
6206  */
6207 static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle,
6208 					struct rssi_monitor_param *req)
6209 {
6210 	wmi_rssi_breach_monitor_config_fixed_param *cmd;
6211 	wmi_buf_t buf;
6212 	QDF_STATUS ret;
6213 	uint32_t len = sizeof(*cmd);
6214 
6215 	buf = wmi_buf_alloc(wmi_handle, len);
6216 	if (!buf) {
6217 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
6218 		return QDF_STATUS_E_NOMEM;
6219 	}
6220 
6221 	cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf);
6222 	WMITLV_SET_HDR(&cmd->tlv_header,
6223 		WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param,
6224 		WMITLV_GET_STRUCT_TLVLEN(
6225 			wmi_rssi_breach_monitor_config_fixed_param));
6226 
6227 	cmd->vdev_id = req->session_id;
6228 	cmd->request_id = req->request_id;
6229 	cmd->lo_rssi_reenable_hysteresis = 0;
6230 	cmd->hi_rssi_reenable_histeresis = 0;
6231 	cmd->min_report_interval = 0;
6232 	cmd->max_num_report = 1;
6233 	if (req->control) {
6234 		/* enable one threshold for each min/max */
6235 		cmd->enabled_bitmap = 0x09;
6236 		cmd->low_rssi_breach_threshold[0] = req->min_rssi;
6237 		cmd->hi_rssi_breach_threshold[0] = req->max_rssi;
6238 	} else {
6239 		cmd->enabled_bitmap = 0;
6240 		cmd->low_rssi_breach_threshold[0] = 0;
6241 		cmd->hi_rssi_breach_threshold[0] = 0;
6242 	}
6243 
6244 	wmi_mtrace(WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID, cmd->vdev_id, 0);
6245 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6246 				   WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID);
6247 	if (QDF_IS_STATUS_ERROR(ret)) {
6248 		WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID");
6249 		wmi_buf_free(buf);
6250 	}
6251 
6252 	WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW");
6253 
6254 	return ret;
6255 }
6256 
6257 /**
6258  * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI
6259  * @wmi_handle: wmi handle
6260  * @psetoui: OUI parameters
6261  *
6262  * set scan probe OUI parameters in firmware
6263  *
6264  * Return: CDF status
6265  */
6266 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle,
6267 			  struct scan_mac_oui *psetoui)
6268 {
6269 	wmi_scan_prob_req_oui_cmd_fixed_param *cmd;
6270 	wmi_buf_t wmi_buf;
6271 	uint32_t len;
6272 	uint8_t *buf_ptr;
6273 	uint32_t *oui_buf;
6274 	struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist;
6275 
6276 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
6277 		ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui);
6278 
6279 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
6280 	if (!wmi_buf) {
6281 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
6282 		return QDF_STATUS_E_NOMEM;
6283 	}
6284 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
6285 	cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr;
6286 	WMITLV_SET_HDR(&cmd->tlv_header,
6287 		       WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param,
6288 		       WMITLV_GET_STRUCT_TLVLEN
6289 			       (wmi_scan_prob_req_oui_cmd_fixed_param));
6290 
6291 	oui_buf = &cmd->prob_req_oui;
6292 	qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui));
6293 	*oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8
6294 		   | psetoui->oui[2];
6295 	WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__,
6296 		 cmd->prob_req_oui);
6297 
6298 	cmd->vdev_id = psetoui->vdev_id;
6299 	cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ;
6300 	if (psetoui->enb_probe_req_sno_randomization)
6301 		cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ;
6302 
6303 	if (ie_whitelist->white_list) {
6304 		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
6305 					    &cmd->num_vendor_oui,
6306 					    ie_whitelist);
6307 		cmd->flags |=
6308 			WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ;
6309 	}
6310 
6311 	buf_ptr += sizeof(*cmd);
6312 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6313 		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
6314 	buf_ptr += WMI_TLV_HDR_SIZE;
6315 
6316 	if (cmd->num_vendor_oui != 0) {
6317 		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
6318 				    ie_whitelist->voui);
6319 		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
6320 	}
6321 
6322 	wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0);
6323 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
6324 				 WMI_SCAN_PROB_REQ_OUI_CMDID)) {
6325 		WMI_LOGE("%s: failed to send command", __func__);
6326 		wmi_buf_free(wmi_buf);
6327 		return QDF_STATUS_E_FAILURE;
6328 	}
6329 	return QDF_STATUS_SUCCESS;
6330 }
6331 
6332 #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
6333 /**
6334  * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command
6335  * @wmi_handle: wmi handle
6336  * @roam_req: Roam scan offload params
6337  * @buf_ptr: command buffer to send
6338  * @fils_tlv_len: fils tlv length
6339  *
6340  * Return: Updated buffer pointer
6341  */
6342 static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
6343 			     struct roam_offload_scan_params *roam_req,
6344 			     uint8_t *buf_ptr, uint32_t fils_tlv_len)
6345 {
6346 	wmi_roam_fils_offload_tlv_param *fils_tlv;
6347 	wmi_erp_info *erp_info;
6348 	struct roam_fils_params *roam_fils_params;
6349 
6350 	if (!roam_req->add_fils_tlv)
6351 		return buf_ptr;
6352 
6353 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6354 			sizeof(*fils_tlv));
6355 	buf_ptr += WMI_TLV_HDR_SIZE;
6356 
6357 	fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr;
6358 	WMITLV_SET_HDR(&fils_tlv->tlv_header,
6359 			WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param,
6360 			WMITLV_GET_STRUCT_TLVLEN
6361 				(wmi_roam_fils_offload_tlv_param));
6362 
6363 	roam_fils_params = &roam_req->roam_fils_params;
6364 	erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info);
6365 
6366 	erp_info->username_length = roam_fils_params->username_length;
6367 	qdf_mem_copy(erp_info->username, roam_fils_params->username,
6368 				erp_info->username_length);
6369 
6370 	erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num;
6371 
6372 	erp_info->rRk_length = roam_fils_params->rrk_length;
6373 	qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk,
6374 				erp_info->rRk_length);
6375 
6376 	erp_info->rIk_length = roam_fils_params->rik_length;
6377 	qdf_mem_copy(erp_info->rIk, roam_fils_params->rik,
6378 				erp_info->rIk_length);
6379 
6380 	erp_info->realm_len = roam_fils_params->realm_len;
6381 	qdf_mem_copy(erp_info->realm, roam_fils_params->realm,
6382 				erp_info->realm_len);
6383 
6384 	buf_ptr += sizeof(*fils_tlv);
6385 	return buf_ptr;
6386 }
6387 #else
6388 static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
6389 				struct roam_offload_scan_params *roam_req,
6390 				uint8_t *buf_ptr, uint32_t fils_tlv_len)
6391 {
6392 	return buf_ptr;
6393 }
6394 #endif
6395 /**
6396  * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw
6397  * @wmi_handle: wmi handle
6398  * @scan_cmd_fp: start scan command ptr
6399  * @roam_req: roam request param
6400  *
6401  * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
6402  * of WMI_ROAM_SCAN_MODE.
6403  *
6404  * Return: QDF status
6405  */
6406 static QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle,
6407 				      wmi_start_scan_cmd_fixed_param *
6408 				      scan_cmd_fp,
6409 				      struct roam_offload_scan_params *roam_req)
6410 {
6411 	wmi_buf_t buf = NULL;
6412 	QDF_STATUS status;
6413 	int len;
6414 	uint8_t *buf_ptr;
6415 	wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp;
6416 
6417 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6418 	int auth_mode = roam_req->auth_mode;
6419 	wmi_roam_offload_tlv_param *roam_offload_params;
6420 	wmi_roam_11i_offload_tlv_param *roam_offload_11i;
6421 	wmi_roam_11r_offload_tlv_param *roam_offload_11r;
6422 	wmi_roam_ese_offload_tlv_param *roam_offload_ese;
6423 	wmi_tlv_buf_len_param *assoc_ies;
6424 	uint32_t fils_tlv_len = 0;
6425 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6426 	/* Need to create a buf with roam_scan command at
6427 	 * front and piggyback with scan command */
6428 	len = sizeof(wmi_roam_scan_mode_fixed_param) +
6429 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6430 	      (2 * WMI_TLV_HDR_SIZE) +
6431 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6432 	      sizeof(wmi_start_scan_cmd_fixed_param);
6433 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6434 	WMI_LOGD("auth_mode = %d", auth_mode);
6435 		if (roam_req->is_roam_req_valid &&
6436 				roam_req->roam_offload_enabled) {
6437 			len += sizeof(wmi_roam_offload_tlv_param);
6438 			len += WMI_TLV_HDR_SIZE;
6439 			if ((auth_mode != WMI_AUTH_NONE) &&
6440 				((auth_mode != WMI_AUTH_OPEN) ||
6441 				 (auth_mode == WMI_AUTH_OPEN &&
6442 				  roam_req->mdid.mdie_present &&
6443 				  roam_req->is_11r_assoc) ||
6444 				  roam_req->is_ese_assoc)) {
6445 				len += WMI_TLV_HDR_SIZE;
6446 				if (roam_req->is_ese_assoc)
6447 					len +=
6448 					sizeof(wmi_roam_ese_offload_tlv_param);
6449 				else if (auth_mode == WMI_AUTH_FT_RSNA ||
6450 					 auth_mode == WMI_AUTH_FT_RSNA_PSK ||
6451 					 (auth_mode == WMI_AUTH_OPEN &&
6452 					  roam_req->mdid.mdie_present &&
6453 					  roam_req->is_11r_assoc))
6454 					len +=
6455 					sizeof(wmi_roam_11r_offload_tlv_param);
6456 				else
6457 					len +=
6458 					sizeof(wmi_roam_11i_offload_tlv_param);
6459 			} else {
6460 				len += WMI_TLV_HDR_SIZE;
6461 			}
6462 
6463 			len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE)
6464 					+ roundup(roam_req->assoc_ie_length,
6465 					sizeof(uint32_t)));
6466 
6467 			if (roam_req->add_fils_tlv) {
6468 				fils_tlv_len = sizeof(
6469 					wmi_roam_fils_offload_tlv_param);
6470 				len += WMI_TLV_HDR_SIZE + fils_tlv_len;
6471 			}
6472 		} else {
6473 			if (roam_req->is_roam_req_valid)
6474 				WMI_LOGD("%s : roam offload = %d",
6475 				     __func__, roam_req->roam_offload_enabled);
6476 			else
6477 				WMI_LOGD("%s : roam_req is NULL", __func__);
6478 			len += (4 * WMI_TLV_HDR_SIZE);
6479 		}
6480 		if (roam_req->is_roam_req_valid &&
6481 				roam_req->roam_offload_enabled) {
6482 			roam_req->mode = roam_req->mode |
6483 				WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
6484 		}
6485 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6486 
6487 	if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE
6488 				|WMI_ROAM_SCAN_MODE_ROAMOFFLOAD))
6489 		len = sizeof(wmi_roam_scan_mode_fixed_param);
6490 
6491 	buf = wmi_buf_alloc(wmi_handle, len);
6492 	if (!buf) {
6493 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6494 		return QDF_STATUS_E_NOMEM;
6495 	}
6496 
6497 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6498 	roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr;
6499 	WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header,
6500 		       WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param,
6501 		       WMITLV_GET_STRUCT_TLVLEN
6502 			       (wmi_roam_scan_mode_fixed_param));
6503 
6504 	roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask =
6505 			roam_req->roam_trigger_reason_bitmask;
6506 	roam_scan_mode_fp->min_delay_btw_scans =
6507 			WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans);
6508 	roam_scan_mode_fp->roam_scan_mode = roam_req->mode;
6509 	roam_scan_mode_fp->vdev_id = roam_req->vdev_id;
6510 	if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE |
6511 			WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) {
6512 		roam_scan_mode_fp->flags |=
6513 			WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS;
6514 		goto send_roam_scan_mode_cmd;
6515 	}
6516 
6517 	/* Fill in scan parameters suitable for roaming scan */
6518 	buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param);
6519 
6520 	qdf_mem_copy(buf_ptr, scan_cmd_fp,
6521 		     sizeof(wmi_start_scan_cmd_fixed_param));
6522 	/* Ensure there is no additional IEs */
6523 	scan_cmd_fp->ie_len = 0;
6524 	WMITLV_SET_HDR(buf_ptr,
6525 		       WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
6526 		       WMITLV_GET_STRUCT_TLVLEN
6527 			       (wmi_start_scan_cmd_fixed_param));
6528 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6529 	buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param);
6530 	if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) {
6531 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6532 			       sizeof(wmi_roam_offload_tlv_param));
6533 		buf_ptr += WMI_TLV_HDR_SIZE;
6534 		roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr;
6535 		WMITLV_SET_HDR(buf_ptr,
6536 			       WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param,
6537 			       WMITLV_GET_STRUCT_TLVLEN
6538 				       (wmi_roam_offload_tlv_param));
6539 		roam_offload_params->prefer_5g = roam_req->prefer_5ghz;
6540 		roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap;
6541 		roam_offload_params->select_5g_margin =
6542 			roam_req->select_5ghz_margin;
6543 		roam_offload_params->handoff_delay_for_rx =
6544 			roam_req->roam_offload_params.ho_delay_for_rx;
6545 		roam_offload_params->reassoc_failure_timeout =
6546 			roam_req->reassoc_failure_timeout;
6547 
6548 		/* Fill the capabilities */
6549 		roam_offload_params->capability =
6550 				roam_req->roam_offload_params.capability;
6551 		roam_offload_params->ht_caps_info =
6552 				roam_req->roam_offload_params.ht_caps_info;
6553 		roam_offload_params->ampdu_param =
6554 				roam_req->roam_offload_params.ampdu_param;
6555 		roam_offload_params->ht_ext_cap =
6556 				roam_req->roam_offload_params.ht_ext_cap;
6557 		roam_offload_params->ht_txbf =
6558 				roam_req->roam_offload_params.ht_txbf;
6559 		roam_offload_params->asel_cap =
6560 				roam_req->roam_offload_params.asel_cap;
6561 		roam_offload_params->qos_caps =
6562 				roam_req->roam_offload_params.qos_caps;
6563 		roam_offload_params->qos_enabled =
6564 				roam_req->roam_offload_params.qos_enabled;
6565 		roam_offload_params->wmm_caps =
6566 				roam_req->roam_offload_params.wmm_caps;
6567 		qdf_mem_copy((uint8_t *)roam_offload_params->mcsset,
6568 				(uint8_t *)roam_req->roam_offload_params.mcsset,
6569 				ROAM_OFFLOAD_NUM_MCS_SET);
6570 
6571 		buf_ptr += sizeof(wmi_roam_offload_tlv_param);
6572 		/* The TLV's are in the order of 11i, 11R, ESE. Hence,
6573 		 * they are filled in the same order.Depending on the
6574 		 * authentication type, the other mode TLV's are nullified
6575 		 * and only headers are filled.*/
6576 		if ((auth_mode != WMI_AUTH_NONE) &&
6577 		    ((auth_mode != WMI_AUTH_OPEN) ||
6578 		     (auth_mode == WMI_AUTH_OPEN
6579 		      && roam_req->mdid.mdie_present &&
6580 		      roam_req->is_11r_assoc) ||
6581 			roam_req->is_ese_assoc)) {
6582 			if (roam_req->is_ese_assoc) {
6583 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6584 					       WMITLV_GET_STRUCT_TLVLEN(0));
6585 				buf_ptr += WMI_TLV_HDR_SIZE;
6586 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6587 					       WMITLV_GET_STRUCT_TLVLEN(0));
6588 				buf_ptr += WMI_TLV_HDR_SIZE;
6589 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6590 					sizeof(wmi_roam_ese_offload_tlv_param));
6591 				buf_ptr += WMI_TLV_HDR_SIZE;
6592 				roam_offload_ese =
6593 				    (wmi_roam_ese_offload_tlv_param *) buf_ptr;
6594 				qdf_mem_copy(roam_offload_ese->krk,
6595 					     roam_req->krk,
6596 					     sizeof(roam_req->krk));
6597 				qdf_mem_copy(roam_offload_ese->btk,
6598 					     roam_req->btk,
6599 					     sizeof(roam_req->btk));
6600 				WMITLV_SET_HDR(&roam_offload_ese->tlv_header,
6601 				WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param,
6602 				WMITLV_GET_STRUCT_TLVLEN
6603 				(wmi_roam_ese_offload_tlv_param));
6604 				buf_ptr +=
6605 					sizeof(wmi_roam_ese_offload_tlv_param);
6606 			} else if (auth_mode == WMI_AUTH_FT_RSNA
6607 				   || auth_mode == WMI_AUTH_FT_RSNA_PSK
6608 				   || (auth_mode == WMI_AUTH_OPEN
6609 				       && roam_req->mdid.mdie_present &&
6610 				       roam_req->is_11r_assoc)) {
6611 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6612 					       0);
6613 				buf_ptr += WMI_TLV_HDR_SIZE;
6614 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6615 					sizeof(wmi_roam_11r_offload_tlv_param));
6616 				buf_ptr += WMI_TLV_HDR_SIZE;
6617 				roam_offload_11r =
6618 				    (wmi_roam_11r_offload_tlv_param *) buf_ptr;
6619 				roam_offload_11r->r0kh_id_len =
6620 					roam_req->rokh_id_length;
6621 				qdf_mem_copy(roam_offload_11r->r0kh_id,
6622 					     roam_req->rokh_id,
6623 					     roam_offload_11r->r0kh_id_len);
6624 				qdf_mem_copy(roam_offload_11r->psk_msk,
6625 					     roam_req->psk_pmk,
6626 					     sizeof(roam_req->psk_pmk));
6627 				roam_offload_11r->psk_msk_len =
6628 					roam_req->pmk_len;
6629 				roam_offload_11r->mdie_present =
6630 					roam_req->mdid.mdie_present;
6631 				roam_offload_11r->mdid =
6632 					roam_req->mdid.mobility_domain;
6633 				if (auth_mode == WMI_AUTH_OPEN) {
6634 					/* If FT-Open ensure pmk length
6635 					   and r0khid len are zero */
6636 					roam_offload_11r->r0kh_id_len = 0;
6637 					roam_offload_11r->psk_msk_len = 0;
6638 				}
6639 				WMITLV_SET_HDR(&roam_offload_11r->tlv_header,
6640 				WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param,
6641 				WMITLV_GET_STRUCT_TLVLEN
6642 				(wmi_roam_11r_offload_tlv_param));
6643 				buf_ptr +=
6644 					sizeof(wmi_roam_11r_offload_tlv_param);
6645 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6646 					       WMITLV_GET_STRUCT_TLVLEN(0));
6647 				buf_ptr += WMI_TLV_HDR_SIZE;
6648 				WMI_LOGD("psk_msk_len = %d",
6649 					roam_offload_11r->psk_msk_len);
6650 				if (roam_offload_11r->psk_msk_len)
6651 					QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
6652 						QDF_TRACE_LEVEL_DEBUG,
6653 						roam_offload_11r->psk_msk,
6654 						roam_offload_11r->psk_msk_len);
6655 			} else {
6656 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6657 					sizeof(wmi_roam_11i_offload_tlv_param));
6658 				buf_ptr += WMI_TLV_HDR_SIZE;
6659 				roam_offload_11i =
6660 				     (wmi_roam_11i_offload_tlv_param *) buf_ptr;
6661 
6662 				if (roam_req->roam_key_mgmt_offload_enabled &&
6663 				    roam_req->fw_okc) {
6664 					WMI_SET_ROAM_OFFLOAD_OKC_ENABLED
6665 						(roam_offload_11i->flags);
6666 					WMI_LOGI("LFR3:OKC enabled");
6667 				} else {
6668 					WMI_SET_ROAM_OFFLOAD_OKC_DISABLED
6669 						(roam_offload_11i->flags);
6670 					WMI_LOGI("LFR3:OKC disabled");
6671 				}
6672 				if (roam_req->roam_key_mgmt_offload_enabled &&
6673 				    roam_req->fw_pmksa_cache) {
6674 					WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED
6675 						(roam_offload_11i->flags);
6676 					WMI_LOGI("LFR3:PMKSA caching enabled");
6677 				} else {
6678 					WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED
6679 						(roam_offload_11i->flags);
6680 					WMI_LOGI("LFR3:PMKSA caching disabled");
6681 				}
6682 
6683 				qdf_mem_copy(roam_offload_11i->pmk,
6684 					     roam_req->psk_pmk,
6685 					     sizeof(roam_req->psk_pmk));
6686 				roam_offload_11i->pmk_len = roam_req->pmk_len;
6687 				WMITLV_SET_HDR(&roam_offload_11i->tlv_header,
6688 				WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param,
6689 				WMITLV_GET_STRUCT_TLVLEN
6690 				(wmi_roam_11i_offload_tlv_param));
6691 				buf_ptr +=
6692 					sizeof(wmi_roam_11i_offload_tlv_param);
6693 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6694 					       0);
6695 				buf_ptr += WMI_TLV_HDR_SIZE;
6696 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6697 					       0);
6698 				buf_ptr += WMI_TLV_HDR_SIZE;
6699 				WMI_LOGD("pmk_len = %d",
6700 					roam_offload_11i->pmk_len);
6701 				if (roam_offload_11i->pmk_len)
6702 					QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
6703 						QDF_TRACE_LEVEL_DEBUG,
6704 						roam_offload_11i->pmk,
6705 						roam_offload_11i->pmk_len);
6706 			}
6707 		} else {
6708 			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6709 				       WMITLV_GET_STRUCT_TLVLEN(0));
6710 			buf_ptr += WMI_TLV_HDR_SIZE;
6711 			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6712 				       WMITLV_GET_STRUCT_TLVLEN(0));
6713 			buf_ptr += WMI_TLV_HDR_SIZE;
6714 			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6715 				       WMITLV_GET_STRUCT_TLVLEN(0));
6716 			buf_ptr += WMI_TLV_HDR_SIZE;
6717 		}
6718 
6719 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6720 					sizeof(*assoc_ies));
6721 		buf_ptr += WMI_TLV_HDR_SIZE;
6722 
6723 		assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr;
6724 		WMITLV_SET_HDR(&assoc_ies->tlv_header,
6725 			WMITLV_TAG_STRUC_wmi_tlv_buf_len_param,
6726 			WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param));
6727 		assoc_ies->buf_len = roam_req->assoc_ie_length;
6728 
6729 		buf_ptr += sizeof(*assoc_ies);
6730 
6731 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
6732 				roundup(assoc_ies->buf_len, sizeof(uint32_t)));
6733 		buf_ptr += WMI_TLV_HDR_SIZE;
6734 
6735 		if (assoc_ies->buf_len != 0) {
6736 			qdf_mem_copy(buf_ptr, roam_req->assoc_ie,
6737 					assoc_ies->buf_len);
6738 		}
6739 		buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t));
6740 		buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req,
6741 						buf_ptr, fils_tlv_len);
6742 	} else {
6743 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6744 			       WMITLV_GET_STRUCT_TLVLEN(0));
6745 		buf_ptr += WMI_TLV_HDR_SIZE;
6746 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6747 			       WMITLV_GET_STRUCT_TLVLEN(0));
6748 		buf_ptr += WMI_TLV_HDR_SIZE;
6749 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6750 			       WMITLV_GET_STRUCT_TLVLEN(0));
6751 		buf_ptr += WMI_TLV_HDR_SIZE;
6752 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6753 			       WMITLV_GET_STRUCT_TLVLEN(0));
6754 		buf_ptr += WMI_TLV_HDR_SIZE;
6755 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6756 				WMITLV_GET_STRUCT_TLVLEN(0));
6757 		buf_ptr += WMI_TLV_HDR_SIZE;
6758 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
6759 				WMITLV_GET_STRUCT_TLVLEN(0));
6760 	}
6761 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6762 
6763 send_roam_scan_mode_cmd:
6764 	wmi_mtrace(WMI_ROAM_SCAN_MODE, NO_SESSION, 0);
6765 	status = wmi_unified_cmd_send(wmi_handle, buf,
6766 				      len, WMI_ROAM_SCAN_MODE);
6767 	if (QDF_IS_STATUS_ERROR(status)) {
6768 		WMI_LOGE(
6769 		    "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d",
6770 			status);
6771 		wmi_buf_free(buf);
6772 	}
6773 
6774 	return status;
6775 }
6776 
6777 static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle,
6778 		struct wmi_mawc_roam_params *params)
6779 {
6780 	wmi_buf_t buf = NULL;
6781 	QDF_STATUS status;
6782 	int len;
6783 	uint8_t *buf_ptr;
6784 	wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params;
6785 
6786 	len = sizeof(*wmi_roam_mawc_params);
6787 	buf = wmi_buf_alloc(wmi_handle, len);
6788 	if (!buf) {
6789 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6790 		return QDF_STATUS_E_NOMEM;
6791 	}
6792 
6793 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6794 	wmi_roam_mawc_params =
6795 		(wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr;
6796 	WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header,
6797 		       WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param,
6798 		       WMITLV_GET_STRUCT_TLVLEN
6799 			       (wmi_roam_configure_mawc_cmd_fixed_param));
6800 	wmi_roam_mawc_params->vdev_id = params->vdev_id;
6801 	if (params->enable)
6802 		wmi_roam_mawc_params->enable = 1;
6803 	else
6804 		wmi_roam_mawc_params->enable = 0;
6805 	wmi_roam_mawc_params->traffic_load_threshold =
6806 		params->traffic_load_threshold;
6807 	wmi_roam_mawc_params->best_ap_rssi_threshold =
6808 		params->best_ap_rssi_threshold;
6809 	wmi_roam_mawc_params->rssi_stationary_high_adjust =
6810 		params->rssi_stationary_high_adjust;
6811 	wmi_roam_mawc_params->rssi_stationary_low_adjust =
6812 		params->rssi_stationary_low_adjust;
6813 	WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"),
6814 		wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id,
6815 		wmi_roam_mawc_params->traffic_load_threshold,
6816 		wmi_roam_mawc_params->best_ap_rssi_threshold,
6817 		wmi_roam_mawc_params->rssi_stationary_high_adjust,
6818 		wmi_roam_mawc_params->rssi_stationary_low_adjust);
6819 
6820 	wmi_mtrace(WMI_ROAM_CONFIGURE_MAWC_CMDID, NO_SESSION, 0);
6821 	status = wmi_unified_cmd_send(wmi_handle, buf,
6822 				      len, WMI_ROAM_CONFIGURE_MAWC_CMDID);
6823 	if (QDF_IS_STATUS_ERROR(status)) {
6824 		WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d",
6825 			status);
6826 		wmi_buf_free(buf);
6827 		return status;
6828 	}
6829 
6830 	return QDF_STATUS_SUCCESS;
6831 }
6832 
6833 /**
6834  * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload
6835  *                                                rssi threashold
6836  * @wmi_handle: wmi handle
6837  * @roam_req:   Roaming request buffer
6838  *
6839  * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
6840  *
6841  * Return: QDF status
6842  */
6843 static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle,
6844 				struct roam_offload_scan_rssi_params *roam_req)
6845 {
6846 	wmi_buf_t buf = NULL;
6847 	QDF_STATUS status;
6848 	int len;
6849 	uint8_t *buf_ptr;
6850 	wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp;
6851 	wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL;
6852 	wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL;
6853 	wmi_roam_dense_thres_param *dense_thresholds = NULL;
6854 	wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL;
6855 
6856 	len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
6857 	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
6858 	len += sizeof(wmi_roam_scan_extended_threshold_param);
6859 	len += WMI_TLV_HDR_SIZE;
6860 	len += sizeof(wmi_roam_earlystop_rssi_thres_param);
6861 	len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/
6862 	len += sizeof(wmi_roam_dense_thres_param);
6863 	len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/
6864 	len += sizeof(wmi_roam_bg_scan_roaming_param);
6865 	buf = wmi_buf_alloc(wmi_handle, len);
6866 	if (!buf) {
6867 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6868 		return QDF_STATUS_E_NOMEM;
6869 	}
6870 
6871 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6872 	rssi_threshold_fp =
6873 		(wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr;
6874 	WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header,
6875 		      WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param,
6876 		      WMITLV_GET_STRUCT_TLVLEN
6877 			       (wmi_roam_scan_rssi_threshold_fixed_param));
6878 	/* fill in threshold values */
6879 	rssi_threshold_fp->vdev_id = roam_req->session_id;
6880 	rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh;
6881 	rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff;
6882 	rssi_threshold_fp->hirssi_scan_max_count =
6883 			roam_req->hi_rssi_scan_max_count;
6884 	rssi_threshold_fp->hirssi_scan_delta =
6885 			roam_req->hi_rssi_scan_rssi_delta;
6886 	rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub;
6887 	rssi_threshold_fp->rssi_thresh_offset_5g =
6888 		roam_req->rssi_thresh_offset_5g;
6889 
6890 	buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
6891 	WMITLV_SET_HDR(buf_ptr,
6892 			WMITLV_TAG_ARRAY_STRUC,
6893 			sizeof(wmi_roam_scan_extended_threshold_param));
6894 	buf_ptr += WMI_TLV_HDR_SIZE;
6895 	ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr;
6896 
6897 	ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g;
6898 	if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT)
6899 		ext_thresholds->boost_threshold_5g =
6900 					roam_req->boost_threshold_5g;
6901 
6902 	ext_thresholds->boost_algorithm_5g =
6903 		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
6904 	ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g;
6905 	ext_thresholds->penalty_algorithm_5g =
6906 		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
6907 	ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g;
6908 	ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g;
6909 	ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g;
6910 	ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold;
6911 
6912 	WMITLV_SET_HDR(&ext_thresholds->tlv_header,
6913 		WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param,
6914 		WMITLV_GET_STRUCT_TLVLEN
6915 		(wmi_roam_scan_extended_threshold_param));
6916 	buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param);
6917 	WMITLV_SET_HDR(buf_ptr,
6918 			WMITLV_TAG_ARRAY_STRUC,
6919 			sizeof(wmi_roam_earlystop_rssi_thres_param));
6920 	buf_ptr += WMI_TLV_HDR_SIZE;
6921 	early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr;
6922 	early_stop_thresholds->roam_earlystop_thres_min =
6923 		roam_req->roam_earlystop_thres_min;
6924 	early_stop_thresholds->roam_earlystop_thres_max =
6925 		roam_req->roam_earlystop_thres_max;
6926 	WMITLV_SET_HDR(&early_stop_thresholds->tlv_header,
6927 		WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param,
6928 		WMITLV_GET_STRUCT_TLVLEN
6929 		(wmi_roam_earlystop_rssi_thres_param));
6930 
6931 	buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param);
6932 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6933 			 sizeof(wmi_roam_dense_thres_param));
6934 	buf_ptr += WMI_TLV_HDR_SIZE;
6935 	dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr;
6936 	dense_thresholds->roam_dense_rssi_thres_offset =
6937 			roam_req->dense_rssi_thresh_offset;
6938 	dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt;
6939 	dense_thresholds->roam_dense_traffic_thres =
6940 			roam_req->traffic_threshold;
6941 	dense_thresholds->roam_dense_status = roam_req->initial_dense_status;
6942 	WMITLV_SET_HDR(&dense_thresholds->tlv_header,
6943 			WMITLV_TAG_STRUC_wmi_roam_dense_thres_param,
6944 			WMITLV_GET_STRUCT_TLVLEN
6945 			(wmi_roam_dense_thres_param));
6946 
6947 	buf_ptr += sizeof(wmi_roam_dense_thres_param);
6948 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6949 			 sizeof(wmi_roam_bg_scan_roaming_param));
6950 	buf_ptr += WMI_TLV_HDR_SIZE;
6951 	bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr;
6952 	bg_scan_params->roam_bg_scan_bad_rssi_thresh =
6953 		roam_req->bg_scan_bad_rssi_thresh;
6954 	bg_scan_params->roam_bg_scan_client_bitmap =
6955 		roam_req->bg_scan_client_bitmap;
6956 	bg_scan_params->bad_rssi_thresh_offset_2g =
6957 		roam_req->roam_bad_rssi_thresh_offset_2g;
6958 	bg_scan_params->flags = roam_req->flags;
6959 	WMITLV_SET_HDR(&bg_scan_params->tlv_header,
6960 			WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param,
6961 			WMITLV_GET_STRUCT_TLVLEN
6962 			(wmi_roam_bg_scan_roaming_param));
6963 
6964 	wmi_mtrace(WMI_ROAM_SCAN_RSSI_THRESHOLD, NO_SESSION, 0);
6965 	status = wmi_unified_cmd_send(wmi_handle, buf,
6966 				      len, WMI_ROAM_SCAN_RSSI_THRESHOLD);
6967 	if (QDF_IS_STATUS_ERROR(status)) {
6968 		WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d",
6969 					status);
6970 		wmi_buf_free(buf);
6971 	}
6972 
6973 	return status;
6974 }
6975 
6976 /**
6977  * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime
6978  * configuration params
6979  * @wma_handle:  wma handler
6980  * @dwelltime_params: pointer to dwelltime_params
6981  *
6982  * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
6983  */
6984 static
6985 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle,
6986 		struct wmi_adaptive_dwelltime_params *dwelltime_params)
6987 {
6988 	wmi_scan_adaptive_dwell_config_fixed_param *dwell_param;
6989 	wmi_scan_adaptive_dwell_parameters_tlv *cmd;
6990 	wmi_buf_t buf;
6991 	uint8_t *buf_ptr;
6992 	int32_t err;
6993 	int len;
6994 
6995 	len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
6996 	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
6997 	len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv);
6998 	buf = wmi_buf_alloc(wmi_handle, len);
6999 	if (!buf) {
7000 		WMI_LOGE("%s :Failed to allocate buffer to send cmd",
7001 				__func__);
7002 		return QDF_STATUS_E_NOMEM;
7003 	}
7004 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7005 	dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr;
7006 	WMITLV_SET_HDR(&dwell_param->tlv_header,
7007 		WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param,
7008 		WMITLV_GET_STRUCT_TLVLEN
7009 		(wmi_scan_adaptive_dwell_config_fixed_param));
7010 
7011 	dwell_param->enable = dwelltime_params->is_enabled;
7012 	buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
7013 	WMITLV_SET_HDR(buf_ptr,
7014 			WMITLV_TAG_ARRAY_STRUC,
7015 			sizeof(wmi_scan_adaptive_dwell_parameters_tlv));
7016 	buf_ptr += WMI_TLV_HDR_SIZE;
7017 
7018 	cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr;
7019 	WMITLV_SET_HDR(&cmd->tlv_header,
7020 			WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv,
7021 			WMITLV_GET_STRUCT_TLVLEN(
7022 				wmi_scan_adaptive_dwell_parameters_tlv));
7023 
7024 	cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode;
7025 	cmd->adapative_lpf_weight = dwelltime_params->lpf_weight;
7026 	cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval;
7027 	cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold;
7028 	wmi_mtrace(WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID, NO_SESSION, 0);
7029 	err = wmi_unified_cmd_send(wmi_handle, buf,
7030 			len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID);
7031 	if (err) {
7032 		WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err);
7033 		wmi_buf_free(buf);
7034 		return QDF_STATUS_E_FAILURE;
7035 	}
7036 
7037 	return QDF_STATUS_SUCCESS;
7038 }
7039 
7040 /**
7041  * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection
7042  * configuration params
7043  * @wmi_handle: wmi handler
7044  * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params
7045  *
7046  * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
7047  */
7048 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle,
7049 			struct wmi_dbs_scan_sel_params *dbs_scan_params)
7050 {
7051 	wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param;
7052 	wmi_scan_dbs_duty_cycle_tlv_param *cmd;
7053 	wmi_buf_t buf;
7054 	uint8_t *buf_ptr;
7055 	QDF_STATUS err;
7056 	uint32_t i;
7057 	int len;
7058 
7059 	len = sizeof(*dbs_scan_param);
7060 	len += WMI_TLV_HDR_SIZE;
7061 	len += dbs_scan_params->num_clients * sizeof(*cmd);
7062 
7063 	buf = wmi_buf_alloc(wmi_handle, len);
7064 	if (!buf) {
7065 		WMI_LOGE("%s:Failed to allocate buffer to send cmd", __func__);
7066 		return QDF_STATUS_E_NOMEM;
7067 	}
7068 
7069 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7070 	dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr;
7071 	WMITLV_SET_HDR(&dbs_scan_param->tlv_header,
7072 		       WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param,
7073 		       WMITLV_GET_STRUCT_TLVLEN
7074 		       (wmi_scan_dbs_duty_cycle_fixed_param));
7075 
7076 	dbs_scan_param->num_clients = dbs_scan_params->num_clients;
7077 	dbs_scan_param->pdev_id = dbs_scan_params->pdev_id;
7078 	buf_ptr += sizeof(*dbs_scan_param);
7079 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7080 		       (sizeof(*cmd) * dbs_scan_params->num_clients));
7081 	buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE;
7082 
7083 	for (i = 0; i < dbs_scan_params->num_clients; i++) {
7084 		cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr;
7085 		WMITLV_SET_HDR(&cmd->tlv_header,
7086 			WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv,
7087 			WMITLV_GET_STRUCT_TLVLEN(
7088 					wmi_scan_dbs_duty_cycle_tlv_param));
7089 		cmd->module_id = dbs_scan_params->module_id[i];
7090 		cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i];
7091 		cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i];
7092 		buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd);
7093 	}
7094 
7095 	wmi_mtrace(WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID, NO_SESSION, 0);
7096 	err = wmi_unified_cmd_send(wmi_handle, buf,
7097 				   len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID);
7098 	if (QDF_IS_STATUS_ERROR(err)) {
7099 		WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err);
7100 		wmi_buf_free(buf);
7101 		return QDF_STATUS_E_FAILURE;
7102 	}
7103 
7104 	return QDF_STATUS_SUCCESS;
7105 }
7106 
7107 /**
7108  * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming
7109  * @wmi_handle:     wmi handle
7110  * @roam_req:       Request which contains the filters
7111  *
7112  * There are filters such as whitelist, blacklist and preferred
7113  * list that need to be applied to the scan results to form the
7114  * probable candidates for roaming.
7115  *
7116  * Return: Return success upon successfully passing the
7117  *         parameters to the firmware, otherwise failure.
7118  */
7119 static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle,
7120 				struct roam_scan_filter_params *roam_req)
7121 {
7122 	wmi_buf_t buf = NULL;
7123 	QDF_STATUS status;
7124 	uint32_t i;
7125 	uint32_t len, blist_len = 0;
7126 	uint8_t *buf_ptr;
7127 	wmi_roam_filter_fixed_param *roam_filter;
7128 	uint8_t *bssid_src_ptr = NULL;
7129 	wmi_mac_addr *bssid_dst_ptr = NULL;
7130 	wmi_ssid *ssid_ptr = NULL;
7131 	uint32_t *bssid_preferred_factor_ptr = NULL;
7132 	wmi_roam_lca_disallow_config_tlv_param *blist_param;
7133 	wmi_roam_rssi_rejection_oce_config_param *rssi_rej;
7134 
7135 	len = sizeof(wmi_roam_filter_fixed_param);
7136 
7137 	len += WMI_TLV_HDR_SIZE;
7138 	if (roam_req->num_bssid_black_list)
7139 		len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr);
7140 	len += WMI_TLV_HDR_SIZE;
7141 	if (roam_req->num_ssid_white_list)
7142 		len += roam_req->num_ssid_white_list * sizeof(wmi_ssid);
7143 	len += 2 * WMI_TLV_HDR_SIZE;
7144 	if (roam_req->num_bssid_preferred_list) {
7145 		len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr);
7146 		len += roam_req->num_bssid_preferred_list * sizeof(uint32_t);
7147 	}
7148 	len += WMI_TLV_HDR_SIZE;
7149 	if (roam_req->lca_disallow_config_present) {
7150 		len += sizeof(*blist_param);
7151 		blist_len = sizeof(*blist_param);
7152 	}
7153 
7154 	len += WMI_TLV_HDR_SIZE;
7155 	if (roam_req->num_rssi_rejection_ap)
7156 		len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej);
7157 
7158 	buf = wmi_buf_alloc(wmi_handle, len);
7159 	if (!buf) {
7160 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
7161 		return QDF_STATUS_E_NOMEM;
7162 	}
7163 
7164 	buf_ptr = (u_int8_t *) wmi_buf_data(buf);
7165 	roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr;
7166 	WMITLV_SET_HDR(&roam_filter->tlv_header,
7167 		WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param,
7168 		WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param));
7169 	/* fill in fixed values */
7170 	roam_filter->vdev_id = roam_req->session_id;
7171 	roam_filter->flags = 0;
7172 	roam_filter->op_bitmap = roam_req->op_bitmap;
7173 	roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list;
7174 	roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list;
7175 	roam_filter->num_bssid_preferred_list =
7176 			roam_req->num_bssid_preferred_list;
7177 	roam_filter->num_rssi_rejection_ap =
7178 			roam_req->num_rssi_rejection_ap;
7179 	buf_ptr += sizeof(wmi_roam_filter_fixed_param);
7180 
7181 	WMITLV_SET_HDR((buf_ptr),
7182 		WMITLV_TAG_ARRAY_FIXED_STRUC,
7183 		(roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)));
7184 	bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list;
7185 	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
7186 	for (i = 0; i < roam_req->num_bssid_black_list; i++) {
7187 		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr);
7188 		bssid_src_ptr += ATH_MAC_LEN;
7189 		bssid_dst_ptr++;
7190 	}
7191 	buf_ptr += WMI_TLV_HDR_SIZE +
7192 		(roam_req->num_bssid_black_list * sizeof(wmi_mac_addr));
7193 	WMITLV_SET_HDR((buf_ptr),
7194 		WMITLV_TAG_ARRAY_FIXED_STRUC,
7195 		(roam_req->num_ssid_white_list * sizeof(wmi_ssid)));
7196 	ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE);
7197 	for (i = 0; i < roam_req->num_ssid_white_list; i++) {
7198 		qdf_mem_copy(&ssid_ptr->ssid,
7199 			&roam_req->ssid_allowed_list[i].mac_ssid,
7200 			roam_req->ssid_allowed_list[i].length);
7201 		ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length;
7202 		ssid_ptr++;
7203 	}
7204 	buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list *
7205 							sizeof(wmi_ssid));
7206 	WMITLV_SET_HDR((buf_ptr),
7207 		WMITLV_TAG_ARRAY_FIXED_STRUC,
7208 		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)));
7209 	bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored;
7210 	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
7211 	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
7212 		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr,
7213 				(wmi_mac_addr *)bssid_dst_ptr);
7214 		bssid_src_ptr += ATH_MAC_LEN;
7215 		bssid_dst_ptr++;
7216 	}
7217 	buf_ptr += WMI_TLV_HDR_SIZE +
7218 		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr));
7219 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
7220 		(roam_req->num_bssid_preferred_list * sizeof(uint32_t)));
7221 	bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
7222 	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
7223 		*bssid_preferred_factor_ptr =
7224 			roam_req->bssid_favored_factor[i];
7225 		bssid_preferred_factor_ptr++;
7226 	}
7227 	buf_ptr += WMI_TLV_HDR_SIZE +
7228 		(roam_req->num_bssid_preferred_list * sizeof(uint32_t));
7229 
7230 	WMITLV_SET_HDR(buf_ptr,
7231 			WMITLV_TAG_ARRAY_STRUC, blist_len);
7232 	buf_ptr += WMI_TLV_HDR_SIZE;
7233 	if (roam_req->lca_disallow_config_present) {
7234 		blist_param =
7235 			(wmi_roam_lca_disallow_config_tlv_param *) buf_ptr;
7236 		WMITLV_SET_HDR(&blist_param->tlv_header,
7237 			WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param,
7238 			WMITLV_GET_STRUCT_TLVLEN(
7239 				wmi_roam_lca_disallow_config_tlv_param));
7240 
7241 		blist_param->disallow_duration = roam_req->disallow_duration;
7242 		blist_param->rssi_channel_penalization =
7243 				roam_req->rssi_channel_penalization;
7244 		blist_param->num_disallowed_aps = roam_req->num_disallowed_aps;
7245 		blist_param->disallow_lca_enable_source_bitmap =
7246 			(WMI_ROAM_LCA_DISALLOW_SOURCE_PER |
7247 			WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND);
7248 		buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param));
7249 	}
7250 
7251 	WMITLV_SET_HDR(buf_ptr,
7252 			WMITLV_TAG_ARRAY_STRUC,
7253 			(roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej)));
7254 	buf_ptr += WMI_TLV_HDR_SIZE;
7255 	for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) {
7256 		rssi_rej =
7257 		(wmi_roam_rssi_rejection_oce_config_param *) buf_ptr;
7258 		WMITLV_SET_HDR(&rssi_rej->tlv_header,
7259 			WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param,
7260 			WMITLV_GET_STRUCT_TLVLEN(
7261 			wmi_roam_rssi_rejection_oce_config_param));
7262 		WMI_CHAR_ARRAY_TO_MAC_ADDR(
7263 			roam_req->rssi_rejection_ap[i].bssid.bytes,
7264 			&rssi_rej->bssid);
7265 		rssi_rej->remaining_disallow_duration =
7266 			roam_req->rssi_rejection_ap[i].remaining_duration;
7267 		rssi_rej->requested_rssi =
7268 			(int32_t)roam_req->rssi_rejection_ap[i].expected_rssi;
7269 		buf_ptr +=
7270 			(sizeof(wmi_roam_rssi_rejection_oce_config_param));
7271 	}
7272 
7273 	wmi_mtrace(WMI_ROAM_FILTER_CMDID, NO_SESSION, 0);
7274 	status = wmi_unified_cmd_send(wmi_handle, buf,
7275 		len, WMI_ROAM_FILTER_CMDID);
7276 	if (QDF_IS_STATUS_ERROR(status)) {
7277 		WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d",
7278 				status);
7279 		wmi_buf_free(buf);
7280 	}
7281 
7282 	return status;
7283 }
7284 
7285 #if defined(WLAN_FEATURE_FILS_SK)
7286 static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle,
7287 						  struct hlp_params *params)
7288 {
7289 	uint32_t len;
7290 	uint8_t *buf_ptr;
7291 	wmi_buf_t buf = NULL;
7292 	wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params;
7293 
7294 	len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param);
7295 	len += WMI_TLV_HDR_SIZE;
7296 	len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t));
7297 
7298 	buf = wmi_buf_alloc(wmi_handle, len);
7299 	if (!buf) {
7300 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
7301 		return QDF_STATUS_E_NOMEM;
7302 	}
7303 
7304 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7305 	hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr;
7306 	WMITLV_SET_HDR(&hlp_params->tlv_header,
7307 		WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param,
7308 		WMITLV_GET_STRUCT_TLVLEN(
7309 			wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param));
7310 
7311 	hlp_params->vdev_id = params->vdev_id;
7312 	hlp_params->size = params->hlp_ie_len;
7313 	hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER;
7314 
7315 	buf_ptr += sizeof(*hlp_params);
7316 
7317 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
7318 				round_up(params->hlp_ie_len,
7319 				sizeof(uint32_t)));
7320 	buf_ptr += WMI_TLV_HDR_SIZE;
7321 	qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len);
7322 
7323 	WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"),
7324 			hlp_params->vdev_id, hlp_params->size);
7325 	wmi_mtrace(WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID, NO_SESSION, 0);
7326 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
7327 				WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) {
7328 		WMI_LOGE(FL("Failed to send FILS HLP pkt cmd"));
7329 		wmi_buf_free(buf);
7330 		return QDF_STATUS_E_FAILURE;
7331 	}
7332 
7333 	return QDF_STATUS_SUCCESS;
7334 }
7335 #endif
7336 
7337 #ifdef IPA_OFFLOAD
7338 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter
7339  * @wmi_handle: wmi handle
7340  * @ipa_offload: ipa offload control parameter
7341  *
7342  * Returns: 0 on success, error number otherwise
7343  */
7344 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle,
7345 		struct ipa_uc_offload_control_params *ipa_offload)
7346 {
7347 	wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd;
7348 	wmi_buf_t wmi_buf;
7349 	uint32_t len;
7350 	u_int8_t *buf_ptr;
7351 
7352 	len  = sizeof(*cmd);
7353 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
7354 	if (!wmi_buf) {
7355 		WMI_LOGE("%s: wmi_buf_alloc failed (len=%d)", __func__, len);
7356 		return QDF_STATUS_E_NOMEM;
7357 	}
7358 
7359 	WMI_LOGD("%s: offload_type=%d, enable=%d", __func__,
7360 		ipa_offload->offload_type, ipa_offload->enable);
7361 
7362 	buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf);
7363 
7364 	cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr;
7365 	WMITLV_SET_HDR(&cmd->tlv_header,
7366 		WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param,
7367 		WMITLV_GET_STRUCT_TLVLEN(
7368 		wmi_ipa_offload_enable_disable_cmd_fixed_param));
7369 
7370 	cmd->offload_type = ipa_offload->offload_type;
7371 	cmd->vdev_id = ipa_offload->vdev_id;
7372 	cmd->enable = ipa_offload->enable;
7373 
7374 	wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0);
7375 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
7376 		WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) {
7377 		WMI_LOGE("%s: failed to command", __func__);
7378 		wmi_buf_free(wmi_buf);
7379 		return QDF_STATUS_E_FAILURE;
7380 	}
7381 
7382 	return QDF_STATUS_SUCCESS;
7383 }
7384 #endif
7385 
7386 /**
7387  * send_plm_stop_cmd_tlv() - plm stop request
7388  * @wmi_handle: wmi handle
7389  * @plm: plm request parameters
7390  *
7391  * This function request FW to stop PLM.
7392  *
7393  * Return: CDF status
7394  */
7395 static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle,
7396 			  const struct plm_req_params *plm)
7397 {
7398 	wmi_vdev_plmreq_stop_cmd_fixed_param *cmd;
7399 	int32_t len;
7400 	wmi_buf_t buf;
7401 	uint8_t *buf_ptr;
7402 	int ret;
7403 
7404 	len = sizeof(*cmd);
7405 	buf = wmi_buf_alloc(wmi_handle, len);
7406 	if (!buf) {
7407 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7408 		return QDF_STATUS_E_NOMEM;
7409 	}
7410 
7411 	cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf);
7412 
7413 	buf_ptr = (uint8_t *) cmd;
7414 
7415 	WMITLV_SET_HDR(&cmd->tlv_header,
7416 		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param,
7417 		       WMITLV_GET_STRUCT_TLVLEN
7418 		       (wmi_vdev_plmreq_stop_cmd_fixed_param));
7419 
7420 	cmd->vdev_id = plm->session_id;
7421 
7422 	cmd->meas_token = plm->meas_token;
7423 	WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token);
7424 
7425 	wmi_mtrace(WMI_VDEV_PLMREQ_STOP_CMDID, cmd->vdev_id, 0);
7426 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7427 				   WMI_VDEV_PLMREQ_STOP_CMDID);
7428 	if (ret) {
7429 		WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__);
7430 		wmi_buf_free(buf);
7431 		return QDF_STATUS_E_FAILURE;
7432 	}
7433 
7434 	return QDF_STATUS_SUCCESS;
7435 }
7436 
7437 /**
7438  * send_plm_start_cmd_tlv() - plm start request
7439  * @wmi_handle: wmi handle
7440  * @plm: plm request parameters
7441  *
7442  * This function request FW to start PLM.
7443  *
7444  * Return: CDF status
7445  */
7446 static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle,
7447 			  const struct plm_req_params *plm,
7448 			  uint32_t *gchannel_list)
7449 {
7450 	wmi_vdev_plmreq_start_cmd_fixed_param *cmd;
7451 	uint32_t *channel_list;
7452 	int32_t len;
7453 	wmi_buf_t buf;
7454 	uint8_t *buf_ptr;
7455 	uint8_t count;
7456 	int ret;
7457 
7458 	/* TLV place holder for channel_list */
7459 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
7460 	len += sizeof(uint32_t) * plm->plm_num_ch;
7461 
7462 	buf = wmi_buf_alloc(wmi_handle, len);
7463 	if (!buf) {
7464 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7465 		return QDF_STATUS_E_NOMEM;
7466 	}
7467 	cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf);
7468 
7469 	buf_ptr = (uint8_t *) cmd;
7470 
7471 	WMITLV_SET_HDR(&cmd->tlv_header,
7472 		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param,
7473 		       WMITLV_GET_STRUCT_TLVLEN
7474 			       (wmi_vdev_plmreq_start_cmd_fixed_param));
7475 
7476 	cmd->vdev_id = plm->session_id;
7477 
7478 	cmd->meas_token = plm->meas_token;
7479 	cmd->dialog_token = plm->diag_token;
7480 	cmd->number_bursts = plm->num_bursts;
7481 	cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int);
7482 	cmd->off_duration = plm->meas_duration;
7483 	cmd->burst_cycle = plm->burst_len;
7484 	cmd->tx_power = plm->desired_tx_pwr;
7485 	WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac);
7486 	cmd->num_chans = plm->plm_num_ch;
7487 
7488 	buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param);
7489 
7490 	WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token);
7491 	WMI_LOGD("dialog_token: %d", cmd->dialog_token);
7492 	WMI_LOGD("number_bursts: %d", cmd->number_bursts);
7493 	WMI_LOGD("burst_interval: %d", cmd->burst_interval);
7494 	WMI_LOGD("off_duration: %d", cmd->off_duration);
7495 	WMI_LOGD("burst_cycle: %d", cmd->burst_cycle);
7496 	WMI_LOGD("tx_power: %d", cmd->tx_power);
7497 	WMI_LOGD("Number of channels : %d", cmd->num_chans);
7498 
7499 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
7500 		       (cmd->num_chans * sizeof(uint32_t)));
7501 
7502 	buf_ptr += WMI_TLV_HDR_SIZE;
7503 	if (cmd->num_chans) {
7504 		channel_list = (uint32_t *) buf_ptr;
7505 		for (count = 0; count < cmd->num_chans; count++) {
7506 			channel_list[count] = plm->plm_ch_list[count];
7507 			if (channel_list[count] < WMI_NLO_FREQ_THRESH)
7508 				channel_list[count] =
7509 					gchannel_list[count];
7510 			WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]);
7511 		}
7512 		buf_ptr += cmd->num_chans * sizeof(uint32_t);
7513 	}
7514 
7515 	wmi_mtrace(WMI_VDEV_PLMREQ_START_CMDID, cmd->vdev_id, 0);
7516 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7517 				   WMI_VDEV_PLMREQ_START_CMDID);
7518 	if (ret) {
7519 		WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__);
7520 		wmi_buf_free(buf);
7521 		return QDF_STATUS_E_FAILURE;
7522 	}
7523 
7524 	return QDF_STATUS_SUCCESS;
7525 }
7526 
7527 /**
7528  * send_pno_stop_cmd_tlv() - PNO stop request
7529  * @wmi_handle: wmi handle
7530  * @vdev_id: vdev id
7531  *
7532  * This function request FW to stop ongoing PNO operation.
7533  *
7534  * Return: CDF status
7535  */
7536 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
7537 {
7538 	wmi_nlo_config_cmd_fixed_param *cmd;
7539 	int32_t len = sizeof(*cmd);
7540 	wmi_buf_t buf;
7541 	uint8_t *buf_ptr;
7542 	int ret;
7543 
7544 	/*
7545 	 * TLV place holder for array of structures nlo_configured_parameters
7546 	 * TLV place holder for array of uint32_t channel_list
7547 	 * TLV place holder for chnl prediction cfg
7548 	 */
7549 	len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE;
7550 	buf = wmi_buf_alloc(wmi_handle, len);
7551 	if (!buf) {
7552 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7553 		return QDF_STATUS_E_NOMEM;
7554 	}
7555 
7556 	cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf);
7557 	buf_ptr = (uint8_t *) cmd;
7558 
7559 	WMITLV_SET_HDR(&cmd->tlv_header,
7560 		       WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param,
7561 		       WMITLV_GET_STRUCT_TLVLEN
7562 			       (wmi_nlo_config_cmd_fixed_param));
7563 
7564 	cmd->vdev_id = vdev_id;
7565 	cmd->flags = WMI_NLO_CONFIG_STOP;
7566 	buf_ptr += sizeof(*cmd);
7567 
7568 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
7569 	buf_ptr += WMI_TLV_HDR_SIZE;
7570 
7571 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
7572 	buf_ptr += WMI_TLV_HDR_SIZE;
7573 
7574 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
7575 	buf_ptr += WMI_TLV_HDR_SIZE;
7576 
7577 
7578 	wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0);
7579 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7580 				   WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
7581 	if (ret) {
7582 		WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__);
7583 		wmi_buf_free(buf);
7584 		return QDF_STATUS_E_FAILURE;
7585 	}
7586 
7587 	return QDF_STATUS_SUCCESS;
7588 }
7589 
7590 /**
7591  * wmi_set_pno_channel_prediction() - Set PNO channel prediction
7592  * @buf_ptr:      Buffer passed by upper layers
7593  * @pno:          Buffer to be sent to the firmware
7594  *
7595  * Copy the PNO Channel prediction configuration parameters
7596  * passed by the upper layers to a WMI format TLV and send it
7597  * down to the firmware.
7598  *
7599  * Return: None
7600  */
7601 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr,
7602 		struct pno_scan_req_params *pno)
7603 {
7604 	nlo_channel_prediction_cfg *channel_prediction_cfg =
7605 		(nlo_channel_prediction_cfg *) buf_ptr;
7606 	WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header,
7607 			WMITLV_TAG_ARRAY_BYTE,
7608 			WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg));
7609 #ifdef FEATURE_WLAN_SCAN_PNO
7610 	channel_prediction_cfg->enable = pno->pno_channel_prediction;
7611 	channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels;
7612 	channel_prediction_cfg->stationary_threshold = pno->stationary_thresh;
7613 	channel_prediction_cfg->full_scan_period_ms =
7614 		pno->channel_prediction_full_scan;
7615 #endif
7616 	buf_ptr += sizeof(nlo_channel_prediction_cfg);
7617 	WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d",
7618 			channel_prediction_cfg->enable,
7619 			channel_prediction_cfg->top_k_num,
7620 			channel_prediction_cfg->stationary_threshold,
7621 			channel_prediction_cfg->full_scan_period_ms);
7622 }
7623 
7624 /**
7625  * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration
7626  * @wmi_handle: wmi handle
7627  * @params: configuration parameters
7628  *
7629  * Return: QDF_STATUS
7630  */
7631 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle,
7632 		struct nlo_mawc_params *params)
7633 {
7634 	wmi_buf_t buf = NULL;
7635 	QDF_STATUS status;
7636 	int len;
7637 	uint8_t *buf_ptr;
7638 	wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params;
7639 
7640 	len = sizeof(*wmi_nlo_mawc_params);
7641 	buf = wmi_buf_alloc(wmi_handle, len);
7642 	if (!buf) {
7643 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
7644 		return QDF_STATUS_E_NOMEM;
7645 	}
7646 
7647 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7648 	wmi_nlo_mawc_params =
7649 		(wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr;
7650 	WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header,
7651 		       WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param,
7652 		       WMITLV_GET_STRUCT_TLVLEN
7653 			       (wmi_nlo_configure_mawc_cmd_fixed_param));
7654 	wmi_nlo_mawc_params->vdev_id = params->vdev_id;
7655 	if (params->enable)
7656 		wmi_nlo_mawc_params->enable = 1;
7657 	else
7658 		wmi_nlo_mawc_params->enable = 0;
7659 	wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio;
7660 	wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval;
7661 	wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval;
7662 	WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"),
7663 		wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id,
7664 		wmi_nlo_mawc_params->exp_backoff_ratio,
7665 		wmi_nlo_mawc_params->init_scan_interval,
7666 		wmi_nlo_mawc_params->max_scan_interval);
7667 
7668 	wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0);
7669 	status = wmi_unified_cmd_send(wmi_handle, buf,
7670 				      len, WMI_NLO_CONFIGURE_MAWC_CMDID);
7671 	if (QDF_IS_STATUS_ERROR(status)) {
7672 		WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d",
7673 			status);
7674 		wmi_buf_free(buf);
7675 		return QDF_STATUS_E_FAILURE;
7676 	}
7677 
7678 	return QDF_STATUS_SUCCESS;
7679 }
7680 
7681 /**
7682  * send_pno_start_cmd_tlv() - PNO start request
7683  * @wmi_handle: wmi handle
7684  * @pno: PNO request
7685  *
7686  * This function request FW to start PNO request.
7687  * Request: CDF status
7688  */
7689 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle,
7690 		   struct pno_scan_req_params *pno)
7691 {
7692 	wmi_nlo_config_cmd_fixed_param *cmd;
7693 	nlo_configured_parameters *nlo_list;
7694 	uint32_t *channel_list;
7695 	int32_t len;
7696 	wmi_buf_t buf;
7697 	uint8_t *buf_ptr;
7698 	uint8_t i;
7699 	int ret;
7700 	struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist;
7701 	connected_nlo_rssi_params *nlo_relative_rssi;
7702 	connected_nlo_bss_band_rssi_pref *nlo_band_rssi;
7703 
7704 	/*
7705 	 * TLV place holder for array nlo_configured_parameters(nlo_list)
7706 	 * TLV place holder for array of uint32_t channel_list
7707 	 * TLV place holder for chnnl prediction cfg
7708 	 * TLV place holder for array of wmi_vendor_oui
7709 	 * TLV place holder for array of connected_nlo_bss_band_rssi_pref
7710 	 */
7711 	len = sizeof(*cmd) +
7712 		WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE +
7713 		WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE;
7714 
7715 	len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt,
7716 					  WMI_NLO_MAX_CHAN);
7717 	len += sizeof(nlo_configured_parameters) *
7718 	       QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS);
7719 	len += sizeof(nlo_channel_prediction_cfg);
7720 	len += sizeof(enlo_candidate_score_params);
7721 	len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui;
7722 	len += sizeof(connected_nlo_rssi_params);
7723 	len += sizeof(connected_nlo_bss_band_rssi_pref);
7724 
7725 	buf = wmi_buf_alloc(wmi_handle, len);
7726 	if (!buf) {
7727 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7728 		return QDF_STATUS_E_NOMEM;
7729 	}
7730 
7731 	cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf);
7732 
7733 	buf_ptr = (uint8_t *) cmd;
7734 	WMITLV_SET_HDR(&cmd->tlv_header,
7735 		       WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param,
7736 		       WMITLV_GET_STRUCT_TLVLEN
7737 			       (wmi_nlo_config_cmd_fixed_param));
7738 	cmd->vdev_id = pno->vdev_id;
7739 	cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN;
7740 
7741 #ifdef FEATURE_WLAN_SCAN_PNO
7742 	WMI_SCAN_SET_DWELL_MODE(cmd->flags,
7743 			pno->adaptive_dwell_mode);
7744 #endif
7745 	/* Current FW does not support min-max range for dwell time */
7746 	cmd->active_dwell_time = pno->active_dwell_time;
7747 	cmd->passive_dwell_time = pno->passive_dwell_time;
7748 
7749 	if (pno->do_passive_scan)
7750 		cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE;
7751 	/* Copy scan interval */
7752 	cmd->fast_scan_period = pno->fast_scan_period;
7753 	cmd->slow_scan_period = pno->slow_scan_period;
7754 	cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time);
7755 	cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles;
7756 	cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier;
7757 	WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec",
7758 			cmd->fast_scan_period, cmd->slow_scan_period);
7759 	WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles);
7760 
7761 	/* mac randomization attributes */
7762 	if (pno->scan_random.randomize) {
7763 		cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ |
7764 				WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ;
7765 		wmi_copy_scan_random_mac(pno->scan_random.mac_addr,
7766 					 pno->scan_random.mac_mask,
7767 					 &cmd->mac_addr,
7768 					 &cmd->mac_mask);
7769 	}
7770 
7771 	buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param);
7772 
7773 	cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS);
7774 	WMI_LOGD("SSID count : %d", cmd->no_of_ssids);
7775 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7776 		       cmd->no_of_ssids * sizeof(nlo_configured_parameters));
7777 	buf_ptr += WMI_TLV_HDR_SIZE;
7778 
7779 	nlo_list = (nlo_configured_parameters *) buf_ptr;
7780 	for (i = 0; i < cmd->no_of_ssids; i++) {
7781 		WMITLV_SET_HDR(&nlo_list[i].tlv_header,
7782 			       WMITLV_TAG_ARRAY_BYTE,
7783 			       WMITLV_GET_STRUCT_TLVLEN
7784 				       (nlo_configured_parameters));
7785 		/* Copy ssid and it's length */
7786 		nlo_list[i].ssid.valid = true;
7787 		nlo_list[i].ssid.ssid.ssid_len =
7788 			pno->networks_list[i].ssid.length;
7789 		qdf_mem_copy(nlo_list[i].ssid.ssid.ssid,
7790 			     pno->networks_list[i].ssid.ssid,
7791 			     nlo_list[i].ssid.ssid.ssid_len);
7792 		WMI_LOGD("index: %d ssid: %.*s len: %d", i,
7793 			 nlo_list[i].ssid.ssid.ssid_len,
7794 			 (char *)nlo_list[i].ssid.ssid.ssid,
7795 			 nlo_list[i].ssid.ssid.ssid_len);
7796 
7797 		/* Copy rssi threshold */
7798 		if (pno->networks_list[i].rssi_thresh &&
7799 		    pno->networks_list[i].rssi_thresh >
7800 		    WMI_RSSI_THOLD_DEFAULT) {
7801 			nlo_list[i].rssi_cond.valid = true;
7802 			nlo_list[i].rssi_cond.rssi =
7803 				pno->networks_list[i].rssi_thresh;
7804 			WMI_LOGD("RSSI threshold : %d dBm",
7805 				 nlo_list[i].rssi_cond.rssi);
7806 		}
7807 		nlo_list[i].bcast_nw_type.valid = true;
7808 		nlo_list[i].bcast_nw_type.bcast_nw_type =
7809 			pno->networks_list[i].bc_new_type;
7810 		WMI_LOGD("Broadcast NW type (%u)",
7811 			 nlo_list[i].bcast_nw_type.bcast_nw_type);
7812 	}
7813 	buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters);
7814 
7815 	/* Copy channel info */
7816 	cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt,
7817 				       WMI_NLO_MAX_CHAN);
7818 	WMI_LOGD("Channel count: %d", cmd->num_of_channels);
7819 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
7820 		       (cmd->num_of_channels * sizeof(uint32_t)));
7821 	buf_ptr += WMI_TLV_HDR_SIZE;
7822 
7823 	channel_list = (uint32_t *) buf_ptr;
7824 	for (i = 0; i < cmd->num_of_channels; i++) {
7825 		channel_list[i] = pno->networks_list[0].channels[i];
7826 
7827 		if (channel_list[i] < WMI_NLO_FREQ_THRESH)
7828 			channel_list[i] =
7829 				wlan_chan_to_freq(pno->
7830 					networks_list[0].channels[i]);
7831 
7832 		WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]);
7833 	}
7834 	buf_ptr += cmd->num_of_channels * sizeof(uint32_t);
7835 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7836 			sizeof(nlo_channel_prediction_cfg));
7837 	buf_ptr += WMI_TLV_HDR_SIZE;
7838 	wmi_set_pno_channel_prediction(buf_ptr, pno);
7839 	buf_ptr += sizeof(nlo_channel_prediction_cfg);
7840 	/** TODO: Discrete firmware doesn't have command/option to configure
7841 	 * App IE which comes from wpa_supplicant as of part PNO start request.
7842 	 */
7843 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param,
7844 		       WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params));
7845 	buf_ptr += sizeof(enlo_candidate_score_params);
7846 
7847 	if (ie_whitelist->white_list) {
7848 		cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ;
7849 		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
7850 					    &cmd->num_vendor_oui,
7851 					    ie_whitelist);
7852 	}
7853 
7854 	/* ie white list */
7855 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7856 		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
7857 	buf_ptr += WMI_TLV_HDR_SIZE;
7858 	if (cmd->num_vendor_oui != 0) {
7859 		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
7860 				    ie_whitelist->voui);
7861 		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
7862 	}
7863 
7864 	if (pno->relative_rssi_set)
7865 		cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG;
7866 
7867 	/*
7868 	 * Firmware calculation using connected PNO params:
7869 	 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref)
7870 	 * deduction of rssi_pref for chosen band_pref and
7871 	 * addition of rssi_pref for remaining bands (other than chosen band).
7872 	 */
7873 	nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr;
7874 	WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header,
7875 		WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params,
7876 		WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params));
7877 	nlo_relative_rssi->relative_rssi = pno->relative_rssi;
7878 	WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi);
7879 	buf_ptr += sizeof(*nlo_relative_rssi);
7880 
7881 	/*
7882 	 * As of now Kernel and Host supports one band and rssi preference.
7883 	 * Firmware supports array of band and rssi preferences
7884 	 */
7885 	cmd->num_cnlo_band_pref = 1;
7886 	WMITLV_SET_HDR(buf_ptr,
7887 		WMITLV_TAG_ARRAY_STRUC,
7888 		cmd->num_cnlo_band_pref *
7889 		sizeof(connected_nlo_bss_band_rssi_pref));
7890 	buf_ptr += WMI_TLV_HDR_SIZE;
7891 
7892 	nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr;
7893 	for (i = 0; i < cmd->num_cnlo_band_pref; i++) {
7894 		WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header,
7895 			WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref,
7896 			WMITLV_GET_STRUCT_TLVLEN(
7897 				connected_nlo_bss_band_rssi_pref));
7898 		nlo_band_rssi[i].band = pno->band_rssi_pref.band;
7899 		nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi;
7900 		WMI_LOGI("band_pref %d, rssi_pref %d",
7901 			nlo_band_rssi[i].band,
7902 			nlo_band_rssi[i].rssi_pref);
7903 	}
7904 	buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi);
7905 
7906 	wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0);
7907 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7908 				   WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
7909 	if (ret) {
7910 		WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__);
7911 		wmi_buf_free(buf);
7912 		return QDF_STATUS_E_FAILURE;
7913 	}
7914 
7915 	return QDF_STATUS_SUCCESS;
7916 }
7917 
7918 /* send_set_ric_req_cmd_tlv() - set ric request element
7919  * @wmi_handle: wmi handle
7920  * @msg: message
7921  * @is_add_ts: is addts required
7922  *
7923  * This function sets ric request element for 11r roaming.
7924  *
7925  * Return: CDF status
7926  */
7927 static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle,
7928 			void *msg, uint8_t is_add_ts)
7929 {
7930 	wmi_ric_request_fixed_param *cmd;
7931 	wmi_ric_tspec *tspec_param;
7932 	wmi_buf_t buf;
7933 	uint8_t *buf_ptr;
7934 	struct mac_tspec_ie *ptspecIE = NULL;
7935 	int32_t len = sizeof(wmi_ric_request_fixed_param) +
7936 		      WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec);
7937 
7938 	buf = wmi_buf_alloc(wmi_handle, len);
7939 	if (!buf) {
7940 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
7941 		return QDF_STATUS_E_NOMEM;
7942 	}
7943 
7944 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7945 
7946 	cmd = (wmi_ric_request_fixed_param *) buf_ptr;
7947 	WMITLV_SET_HDR(&cmd->tlv_header,
7948 		   WMITLV_TAG_STRUC_wmi_ric_request_fixed_param,
7949 		   WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param));
7950 	if (is_add_ts)
7951 		cmd->vdev_id = ((struct add_ts_param *) msg)->sme_session_id;
7952 	else
7953 		cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId;
7954 	cmd->num_ric_request = 1;
7955 	cmd->is_add_ric = is_add_ts;
7956 
7957 	buf_ptr += sizeof(wmi_ric_request_fixed_param);
7958 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec));
7959 
7960 	buf_ptr += WMI_TLV_HDR_SIZE;
7961 	tspec_param = (wmi_ric_tspec *) buf_ptr;
7962 	WMITLV_SET_HDR(&tspec_param->tlv_header,
7963 		       WMITLV_TAG_STRUC_wmi_ric_tspec,
7964 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec));
7965 
7966 	if (is_add_ts)
7967 		ptspecIE = &(((struct add_ts_param *) msg)->tspec);
7968 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
7969 	else
7970 		ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec);
7971 #endif
7972 	if (ptspecIE) {
7973 		/* Fill the tsinfo in the format expected by firmware */
7974 #ifndef ANI_LITTLE_BIT_ENDIAN
7975 		qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1,
7976 			     ((uint8_t *) &ptspecIE->tsinfo) + 1, 2);
7977 #else
7978 		qdf_mem_copy(((uint8_t *) &tspec_param->ts_info),
7979 			     ((uint8_t *) &ptspecIE->tsinfo) + 1, 2);
7980 #endif /* ANI_LITTLE_BIT_ENDIAN */
7981 
7982 		tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz;
7983 		tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz;
7984 		tspec_param->min_service_interval = ptspecIE->minSvcInterval;
7985 		tspec_param->max_service_interval = ptspecIE->maxSvcInterval;
7986 		tspec_param->inactivity_interval = ptspecIE->inactInterval;
7987 		tspec_param->suspension_interval = ptspecIE->suspendInterval;
7988 		tspec_param->svc_start_time = ptspecIE->svcStartTime;
7989 		tspec_param->min_data_rate = ptspecIE->minDataRate;
7990 		tspec_param->mean_data_rate = ptspecIE->meanDataRate;
7991 		tspec_param->peak_data_rate = ptspecIE->peakDataRate;
7992 		tspec_param->max_burst_size = ptspecIE->maxBurstSz;
7993 		tspec_param->delay_bound = ptspecIE->delayBound;
7994 		tspec_param->min_phy_rate = ptspecIE->minPhyRate;
7995 		tspec_param->surplus_bw_allowance = ptspecIE->surplusBw;
7996 		tspec_param->medium_time = 0;
7997 	}
7998 	WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts);
7999 
8000 	wmi_mtrace(WMI_ROAM_SET_RIC_REQUEST_CMDID, cmd->vdev_id, 0);
8001 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8002 				 WMI_ROAM_SET_RIC_REQUEST_CMDID)) {
8003 		WMI_LOGP("%s: Failed to send vdev Set RIC Req command",
8004 			 __func__);
8005 		if (is_add_ts)
8006 			((struct add_ts_param *) msg)->status =
8007 					    QDF_STATUS_E_FAILURE;
8008 		wmi_buf_free(buf);
8009 		return QDF_STATUS_E_FAILURE;
8010 	}
8011 
8012 	return QDF_STATUS_SUCCESS;
8013 }
8014 
8015 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
8016 /**
8017  * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats
8018  * @wmi_handle: wmi handle
8019  * @clear_req: ll stats clear request command params
8020  *
8021  * Return: QDF_STATUS_SUCCESS for success or error code
8022  */
8023 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle,
8024 		const struct ll_stats_clear_params *clear_req,
8025 		uint8_t addr[IEEE80211_ADDR_LEN])
8026 {
8027 	wmi_clear_link_stats_cmd_fixed_param *cmd;
8028 	int32_t len;
8029 	wmi_buf_t buf;
8030 	uint8_t *buf_ptr;
8031 	int ret;
8032 
8033 	len = sizeof(*cmd);
8034 	buf = wmi_buf_alloc(wmi_handle, len);
8035 
8036 	if (!buf) {
8037 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8038 		return QDF_STATUS_E_NOMEM;
8039 	}
8040 
8041 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8042 	qdf_mem_zero(buf_ptr, len);
8043 	cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr;
8044 
8045 	WMITLV_SET_HDR(&cmd->tlv_header,
8046 		       WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param,
8047 		       WMITLV_GET_STRUCT_TLVLEN
8048 			       (wmi_clear_link_stats_cmd_fixed_param));
8049 
8050 	cmd->stop_stats_collection_req = clear_req->stop_req;
8051 	cmd->vdev_id = clear_req->sta_id;
8052 	cmd->stats_clear_req_mask = clear_req->stats_clear_mask;
8053 
8054 	WMI_CHAR_ARRAY_TO_MAC_ADDR(addr,
8055 				   &cmd->peer_macaddr);
8056 
8057 	WMI_LOGD("LINK_LAYER_STATS - Clear Request Params");
8058 	WMI_LOGD("StopReq         : %d", cmd->stop_stats_collection_req);
8059 	WMI_LOGD("Vdev Id         : %d", cmd->vdev_id);
8060 	WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask);
8061 	/* WMI_LOGD("Peer MAC Addr   : %pM",
8062 		 cmd->peer_macaddr); */
8063 
8064 	wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0);
8065 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8066 				   WMI_CLEAR_LINK_STATS_CMDID);
8067 	if (ret) {
8068 		WMI_LOGE("%s: Failed to send clear link stats req", __func__);
8069 		wmi_buf_free(buf);
8070 		return QDF_STATUS_E_FAILURE;
8071 	}
8072 
8073 	WMI_LOGD("Clear Link Layer Stats request sent successfully");
8074 	return QDF_STATUS_SUCCESS;
8075 }
8076 
8077 /**
8078  * send_process_ll_stats_set_cmd_tlv() - link layer stats set request
8079  * @wmi_handle:       wmi handle
8080  * @setReq:  ll stats set request command params
8081  *
8082  * Return: QDF_STATUS_SUCCESS for success or error code
8083  */
8084 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle,
8085 		const struct ll_stats_set_params *set_req)
8086 {
8087 	wmi_start_link_stats_cmd_fixed_param *cmd;
8088 	int32_t len;
8089 	wmi_buf_t buf;
8090 	uint8_t *buf_ptr;
8091 	int ret;
8092 
8093 	len = sizeof(*cmd);
8094 	buf = wmi_buf_alloc(wmi_handle, len);
8095 
8096 	if (!buf) {
8097 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8098 		return QDF_STATUS_E_NOMEM;
8099 	}
8100 
8101 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8102 	qdf_mem_zero(buf_ptr, len);
8103 	cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr;
8104 
8105 	WMITLV_SET_HDR(&cmd->tlv_header,
8106 		       WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param,
8107 		       WMITLV_GET_STRUCT_TLVLEN
8108 			       (wmi_start_link_stats_cmd_fixed_param));
8109 
8110 	cmd->mpdu_size_threshold = set_req->mpdu_size_threshold;
8111 	cmd->aggressive_statistics_gathering =
8112 		set_req->aggressive_statistics_gathering;
8113 
8114 	WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params");
8115 	WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold);
8116 	WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering);
8117 
8118 	wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0);
8119 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8120 				   WMI_START_LINK_STATS_CMDID);
8121 	if (ret) {
8122 		WMI_LOGE("%s: Failed to send set link stats request", __func__);
8123 		wmi_buf_free(buf);
8124 		return QDF_STATUS_E_FAILURE;
8125 	}
8126 
8127 	return QDF_STATUS_SUCCESS;
8128 }
8129 
8130 /**
8131  * send_process_ll_stats_get_cmd_tlv() - link layer stats get request
8132  * @wmi_handle:wmi handle
8133  * @get_req:ll stats get request command params
8134  * @addr: mac address
8135  *
8136  * Return: QDF_STATUS_SUCCESS for success or error code
8137  */
8138 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle,
8139 		 const struct ll_stats_get_params  *get_req,
8140 		 uint8_t addr[IEEE80211_ADDR_LEN])
8141 {
8142 	wmi_request_link_stats_cmd_fixed_param *cmd;
8143 	int32_t len;
8144 	wmi_buf_t buf;
8145 	uint8_t *buf_ptr;
8146 	int ret;
8147 
8148 	len = sizeof(*cmd);
8149 	buf = wmi_buf_alloc(wmi_handle, len);
8150 
8151 	if (!buf) {
8152 		WMI_LOGE("%s: buf allocation failed", __func__);
8153 		return QDF_STATUS_E_NOMEM;
8154 	}
8155 
8156 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8157 	qdf_mem_zero(buf_ptr, len);
8158 	cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr;
8159 
8160 	WMITLV_SET_HDR(&cmd->tlv_header,
8161 		       WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param,
8162 		       WMITLV_GET_STRUCT_TLVLEN
8163 			       (wmi_request_link_stats_cmd_fixed_param));
8164 
8165 	cmd->request_id = get_req->req_id;
8166 	cmd->stats_type = get_req->param_id_mask;
8167 	cmd->vdev_id = get_req->sta_id;
8168 
8169 	WMI_CHAR_ARRAY_TO_MAC_ADDR(addr,
8170 				   &cmd->peer_macaddr);
8171 
8172 	WMI_LOGD("LINK_LAYER_STATS - Get Request Params");
8173 	WMI_LOGD("Request ID      : %u", cmd->request_id);
8174 	WMI_LOGD("Stats Type      : %0x", cmd->stats_type);
8175 	WMI_LOGD("Vdev ID         : %d", cmd->vdev_id);
8176 	WMI_LOGD("Peer MAC Addr   : %pM", addr);
8177 
8178 	wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0);
8179 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8180 				   WMI_REQUEST_LINK_STATS_CMDID);
8181 	if (ret) {
8182 		WMI_LOGE("%s: Failed to send get link stats request", __func__);
8183 		wmi_buf_free(buf);
8184 		return QDF_STATUS_E_FAILURE;
8185 	}
8186 
8187 	return QDF_STATUS_SUCCESS;
8188 }
8189 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */
8190 
8191 /**
8192  * send_congestion_cmd_tlv() - send request to fw to get CCA
8193  * @wmi_handle: wmi handle
8194  * @vdev_id: vdev id
8195  *
8196  * Return: CDF status
8197  */
8198 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle,
8199 			uint8_t vdev_id)
8200 {
8201 	wmi_buf_t buf;
8202 	wmi_request_stats_cmd_fixed_param *cmd;
8203 	uint8_t len;
8204 	uint8_t *buf_ptr;
8205 
8206 	len = sizeof(*cmd);
8207 	buf = wmi_buf_alloc(wmi_handle, len);
8208 	if (!buf) {
8209 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
8210 		return QDF_STATUS_E_FAILURE;
8211 	}
8212 
8213 	buf_ptr = wmi_buf_data(buf);
8214 	cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr;
8215 	WMITLV_SET_HDR(&cmd->tlv_header,
8216 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8217 		       WMITLV_GET_STRUCT_TLVLEN
8218 			       (wmi_request_stats_cmd_fixed_param));
8219 
8220 	cmd->stats_id = WMI_REQUEST_CONGESTION_STAT;
8221 	cmd->vdev_id = vdev_id;
8222 	WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->",
8223 			cmd->vdev_id, cmd->stats_id);
8224 
8225 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
8226 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8227 				 WMI_REQUEST_STATS_CMDID)) {
8228 		WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID",
8229 			 __func__);
8230 		wmi_buf_free(buf);
8231 		return QDF_STATUS_E_FAILURE;
8232 	}
8233 
8234 	return QDF_STATUS_SUCCESS;
8235 }
8236 
8237 /**
8238  * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats
8239  * @wmi_handle: wmi handle
8240  * @rssi_req: get RSSI request
8241  *
8242  * Return: CDF status
8243  */
8244 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle)
8245 {
8246 	wmi_buf_t buf;
8247 	wmi_request_stats_cmd_fixed_param *cmd;
8248 	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
8249 
8250 	buf = wmi_buf_alloc(wmi_handle, len);
8251 	if (!buf) {
8252 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8253 		return QDF_STATUS_E_FAILURE;
8254 	}
8255 
8256 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
8257 	WMITLV_SET_HDR(&cmd->tlv_header,
8258 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8259 		       WMITLV_GET_STRUCT_TLVLEN
8260 			       (wmi_request_stats_cmd_fixed_param));
8261 	cmd->stats_id = WMI_REQUEST_VDEV_STAT;
8262 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
8263 	if (wmi_unified_cmd_send
8264 		    (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) {
8265 		WMI_LOGE("Failed to send host stats request to fw");
8266 		wmi_buf_free(buf);
8267 		return QDF_STATUS_E_FAILURE;
8268 	}
8269 
8270 	return QDF_STATUS_SUCCESS;
8271 }
8272 
8273 /**
8274  * send_snr_cmd_tlv() - get RSSI from fw
8275  * @wmi_handle: wmi handle
8276  * @vdev_id: vdev id
8277  *
8278  * Return: CDF status
8279  */
8280 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
8281 {
8282 	wmi_buf_t buf;
8283 	wmi_request_stats_cmd_fixed_param *cmd;
8284 	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
8285 
8286 	buf = wmi_buf_alloc(wmi_handle, len);
8287 	if (!buf) {
8288 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8289 		return QDF_STATUS_E_FAILURE;
8290 	}
8291 
8292 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
8293 	cmd->vdev_id = vdev_id;
8294 
8295 	WMITLV_SET_HDR(&cmd->tlv_header,
8296 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8297 		       WMITLV_GET_STRUCT_TLVLEN
8298 			       (wmi_request_stats_cmd_fixed_param));
8299 	cmd->stats_id = WMI_REQUEST_VDEV_STAT;
8300 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
8301 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8302 				 WMI_REQUEST_STATS_CMDID)) {
8303 		WMI_LOGE("Failed to send host stats request to fw");
8304 		wmi_buf_free(buf);
8305 		return QDF_STATUS_E_FAILURE;
8306 	}
8307 
8308 	return QDF_STATUS_SUCCESS;
8309 }
8310 
8311 /**
8312  * send_link_status_req_cmd_tlv() - process link status request from UMAC
8313  * @wmi_handle: wmi handle
8314  * @link_status: get link params
8315  *
8316  * Return: CDF status
8317  */
8318 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle,
8319 				 struct link_status_params *link_status)
8320 {
8321 	wmi_buf_t buf;
8322 	wmi_request_stats_cmd_fixed_param *cmd;
8323 	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
8324 
8325 	buf = wmi_buf_alloc(wmi_handle, len);
8326 	if (!buf) {
8327 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8328 		return QDF_STATUS_E_FAILURE;
8329 	}
8330 
8331 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
8332 	WMITLV_SET_HDR(&cmd->tlv_header,
8333 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8334 		       WMITLV_GET_STRUCT_TLVLEN
8335 			       (wmi_request_stats_cmd_fixed_param));
8336 	cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT;
8337 	cmd->vdev_id = link_status->session_id;
8338 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
8339 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8340 				 WMI_REQUEST_STATS_CMDID)) {
8341 		WMI_LOGE("Failed to send WMI link  status request to fw");
8342 		wmi_buf_free(buf);
8343 		return QDF_STATUS_E_FAILURE;
8344 	}
8345 
8346 	return QDF_STATUS_SUCCESS;
8347 }
8348 
8349 /**
8350  * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME
8351  * @wmi_handle: wmi handle
8352  * @ta_dhcp_ind: DHCP indication parameter
8353  *
8354  * Return: CDF Status
8355  */
8356 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle,
8357 				wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind)
8358 {
8359 	QDF_STATUS status;
8360 	wmi_buf_t buf = NULL;
8361 	uint8_t *buf_ptr;
8362 	wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp;
8363 	int len = sizeof(wmi_peer_set_param_cmd_fixed_param);
8364 
8365 
8366 	buf = wmi_buf_alloc(wmi_handle, len);
8367 	if (!buf) {
8368 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
8369 		return QDF_STATUS_E_NOMEM;
8370 	}
8371 
8372 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8373 	peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr;
8374 	WMITLV_SET_HDR(&peer_set_param_fp->tlv_header,
8375 		       WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
8376 		       WMITLV_GET_STRUCT_TLVLEN
8377 			       (wmi_peer_set_param_cmd_fixed_param));
8378 
8379 	/* fill in values */
8380 	peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id;
8381 	peer_set_param_fp->param_id = ta_dhcp_ind->param_id;
8382 	peer_set_param_fp->param_value = ta_dhcp_ind->param_value;
8383 	qdf_mem_copy(&peer_set_param_fp->peer_macaddr,
8384 				   &ta_dhcp_ind->peer_macaddr,
8385 				   sizeof(ta_dhcp_ind->peer_macaddr));
8386 
8387 	wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, NO_SESSION, 0);
8388 	status = wmi_unified_cmd_send(wmi_handle, buf,
8389 				      len, WMI_PEER_SET_PARAM_CMDID);
8390 	if (QDF_IS_STATUS_ERROR(status)) {
8391 		WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
8392 			 " returned Error %d", __func__, status);
8393 		wmi_buf_free(buf);
8394 	}
8395 
8396 	return status;
8397 }
8398 
8399 /**
8400  * send_get_link_speed_cmd_tlv() -send command to get linkspeed
8401  * @wmi_handle: wmi handle
8402  * @pLinkSpeed: link speed info
8403  *
8404  * Return: CDF status
8405  */
8406 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle,
8407 		wmi_mac_addr peer_macaddr)
8408 {
8409 	wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd;
8410 	wmi_buf_t wmi_buf;
8411 	uint32_t len;
8412 	uint8_t *buf_ptr;
8413 
8414 	len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param);
8415 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
8416 	if (!wmi_buf) {
8417 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8418 		return QDF_STATUS_E_NOMEM;
8419 	}
8420 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
8421 
8422 	cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr;
8423 	WMITLV_SET_HDR(&cmd->tlv_header,
8424 	       WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param,
8425 	       WMITLV_GET_STRUCT_TLVLEN
8426 	       (wmi_peer_get_estimated_linkspeed_cmd_fixed_param));
8427 
8428 	/* Copy the peer macaddress to the wma buffer */
8429 	qdf_mem_copy(&cmd->peer_macaddr,
8430 				   &peer_macaddr,
8431 				   sizeof(peer_macaddr));
8432 
8433 
8434 	wmi_mtrace(WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID, cmd->vdev_id, 0);
8435 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
8436 				 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) {
8437 		WMI_LOGE("%s: failed to send link speed command", __func__);
8438 		wmi_buf_free(wmi_buf);
8439 		return QDF_STATUS_E_FAILURE;
8440 	}
8441 	return QDF_STATUS_SUCCESS;
8442 }
8443 
8444 #ifdef WLAN_SUPPORT_GREEN_AP
8445 /**
8446  * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params
8447  * @wmi_handle:	 wmi handler
8448  * @egap_params: pointer to egap_params
8449  *
8450  * Return:	 0 for success, otherwise appropriate error code
8451  */
8452 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle,
8453 		     struct wlan_green_ap_egap_params *egap_params)
8454 {
8455 	wmi_ap_ps_egap_param_cmd_fixed_param *cmd;
8456 	wmi_buf_t buf;
8457 	int32_t err;
8458 
8459 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
8460 	if (!buf) {
8461 		WMI_LOGE("Failed to allocate buffer to send ap_ps_egap cmd");
8462 		return QDF_STATUS_E_NOMEM;
8463 	}
8464 	cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf);
8465 	WMITLV_SET_HDR(&cmd->tlv_header,
8466 		       WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param,
8467 		       WMITLV_GET_STRUCT_TLVLEN(
8468 			       wmi_ap_ps_egap_param_cmd_fixed_param));
8469 
8470 	cmd->enable = egap_params->host_enable_egap;
8471 	cmd->inactivity_time = egap_params->egap_inactivity_time;
8472 	cmd->wait_time = egap_params->egap_wait_time;
8473 	cmd->flags = egap_params->egap_feature_flags;
8474 	wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0);
8475 	err = wmi_unified_cmd_send(wmi_handle, buf,
8476 				   sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID);
8477 	if (err) {
8478 		WMI_LOGE("Failed to send ap_ps_egap cmd");
8479 		wmi_buf_free(buf);
8480 		return QDF_STATUS_E_FAILURE;
8481 	}
8482 
8483 	return QDF_STATUS_SUCCESS;
8484 }
8485 #endif
8486 
8487 /**
8488  * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW
8489  * @wmi_handl: wmi handle
8490  * @cmd: Profiling command index
8491  * @value1: parameter1 value
8492  * @value2: parameter2 value
8493  *
8494  * Return: QDF_STATUS_SUCCESS for success else error code
8495  */
8496 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle,
8497 			uint32_t cmd, uint32_t value1, uint32_t value2)
8498 {
8499 	wmi_buf_t buf;
8500 	int32_t len = 0;
8501 	int ret;
8502 	wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd;
8503 	wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd;
8504 	wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd;
8505 	wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd;
8506 
8507 	switch (cmd) {
8508 	case WMI_WLAN_PROFILE_TRIGGER_CMDID:
8509 		len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param);
8510 		buf = wmi_buf_alloc(wmi_handle, len);
8511 		if (!buf) {
8512 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
8513 			return QDF_STATUS_E_NOMEM;
8514 		}
8515 		prof_trig_cmd =
8516 			(wmi_wlan_profile_trigger_cmd_fixed_param *)
8517 				wmi_buf_data(buf);
8518 		WMITLV_SET_HDR(&prof_trig_cmd->tlv_header,
8519 		     WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param,
8520 		     WMITLV_GET_STRUCT_TLVLEN
8521 		    (wmi_wlan_profile_trigger_cmd_fixed_param));
8522 		prof_trig_cmd->enable = value1;
8523 		wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0);
8524 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8525 				WMI_WLAN_PROFILE_TRIGGER_CMDID);
8526 		if (ret) {
8527 			WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d",
8528 					value1);
8529 			wmi_buf_free(buf);
8530 			return ret;
8531 		}
8532 		break;
8533 
8534 	case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
8535 		len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param);
8536 		buf = wmi_buf_alloc(wmi_handle, len);
8537 		if (!buf) {
8538 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
8539 			return QDF_STATUS_E_NOMEM;
8540 		}
8541 		profile_getdata_cmd =
8542 			(wmi_wlan_profile_get_prof_data_cmd_fixed_param *)
8543 				wmi_buf_data(buf);
8544 		WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header,
8545 		      WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param,
8546 		      WMITLV_GET_STRUCT_TLVLEN
8547 		      (wmi_wlan_profile_get_prof_data_cmd_fixed_param));
8548 		wmi_mtrace(WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
8549 			   NO_SESSION, 0);
8550 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8551 				WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID);
8552 		if (ret) {
8553 			WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d",
8554 					value1, value2);
8555 			wmi_buf_free(buf);
8556 			return ret;
8557 		}
8558 		break;
8559 
8560 	case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
8561 		len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param);
8562 		buf = wmi_buf_alloc(wmi_handle, len);
8563 		if (!buf) {
8564 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
8565 			return QDF_STATUS_E_NOMEM;
8566 		}
8567 		hist_intvl_cmd =
8568 			(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *)
8569 				wmi_buf_data(buf);
8570 		WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header,
8571 		      WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param,
8572 		      WMITLV_GET_STRUCT_TLVLEN
8573 		      (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param));
8574 		hist_intvl_cmd->profile_id = value1;
8575 		hist_intvl_cmd->value = value2;
8576 		wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
8577 			   NO_SESSION, 0);
8578 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8579 				WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID);
8580 		if (ret) {
8581 			WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d",
8582 					value1, value2);
8583 			wmi_buf_free(buf);
8584 			return ret;
8585 		}
8586 		break;
8587 
8588 	case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
8589 		len =
8590 		sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param);
8591 		buf = wmi_buf_alloc(wmi_handle, len);
8592 		if (!buf) {
8593 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
8594 			return QDF_STATUS_E_NOMEM;
8595 		}
8596 		profile_enable_cmd =
8597 			(wmi_wlan_profile_enable_profile_id_cmd_fixed_param *)
8598 				wmi_buf_data(buf);
8599 		WMITLV_SET_HDR(&profile_enable_cmd->tlv_header,
8600 		      WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param,
8601 		      WMITLV_GET_STRUCT_TLVLEN
8602 		      (wmi_wlan_profile_enable_profile_id_cmd_fixed_param));
8603 		profile_enable_cmd->profile_id = value1;
8604 		profile_enable_cmd->enable = value2;
8605 		wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
8606 			   NO_SESSION, 0);
8607 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8608 				WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID);
8609 		if (ret) {
8610 			WMI_LOGE("enable cmd Failed for id %d value %d",
8611 					value1, value2);
8612 			wmi_buf_free(buf);
8613 			return ret;
8614 		}
8615 		break;
8616 
8617 	default:
8618 		WMI_LOGD("%s: invalid profiling command", __func__);
8619 		break;
8620 	}
8621 
8622 	return 0;
8623 }
8624 
8625 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle,
8626 				struct wlm_latency_level_param *params)
8627 {
8628 	wmi_wlm_config_cmd_fixed_param *cmd;
8629 	wmi_buf_t buf;
8630 	uint32_t len = sizeof(*cmd);
8631 	static uint32_t ll[4] = {100, 60, 40, 20};
8632 
8633 	buf = wmi_buf_alloc(wmi_handle, len);
8634 	if (!buf) {
8635 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
8636 		return QDF_STATUS_E_NOMEM;
8637 	}
8638 	cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf);
8639 	WMITLV_SET_HDR(&cmd->tlv_header,
8640 		       WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param,
8641 		       WMITLV_GET_STRUCT_TLVLEN
8642 		       (wmi_wlm_config_cmd_fixed_param));
8643 	cmd->vdev_id = params->vdev_id;
8644 	cmd->latency_level = params->wlm_latency_level;
8645 	cmd->ul_latency = ll[params->wlm_latency_level];
8646 	cmd->dl_latency = ll[params->wlm_latency_level];
8647 	cmd->flags = params->wlm_latency_flags;
8648 	wmi_mtrace(WMI_WLM_CONFIG_CMDID, cmd->vdev_id, 0);
8649 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8650 				 WMI_WLM_CONFIG_CMDID)) {
8651 		WMI_LOGE("%s: Failed to send setting latency config command",
8652 			 __func__);
8653 		wmi_buf_free(buf);
8654 		return QDF_STATUS_E_FAILURE;
8655 	}
8656 
8657 	return 0;
8658 }
8659 /**
8660  * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter
8661  * @wmi_handle: wmi handle
8662  * @vdev_id: vdev id
8663  *
8664  * Return: QDF_STATUS_SUCCESS for success or error code
8665  */
8666 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
8667 {
8668 	WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd;
8669 	wmi_buf_t buf;
8670 	int32_t len = sizeof(*cmd);
8671 
8672 	WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
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_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *)
8679 		wmi_buf_data(buf);
8680 	WMITLV_SET_HDR(&cmd->tlv_header,
8681 	WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param,
8682 		  WMITLV_GET_STRUCT_TLVLEN
8683 		  (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param));
8684 	cmd->vdev_id = vdev_id;
8685 	cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE;
8686 	wmi_mtrace(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID, cmd->vdev_id, 0);
8687 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8688 				 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) {
8689 		WMI_LOGP("%s: Failed to send NAT keepalive enable command",
8690 			 __func__);
8691 		wmi_buf_free(buf);
8692 		return QDF_STATUS_E_FAILURE;
8693 	}
8694 
8695 	return 0;
8696 }
8697 
8698 /**
8699  * wmi_unified_csa_offload_enable() - sen CSA offload enable command
8700  * @wmi_handle: wmi handle
8701  * @vdev_id: vdev id
8702  *
8703  * Return: QDF_STATUS_SUCCESS for success or error code
8704  */
8705 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle,
8706 			uint8_t vdev_id)
8707 {
8708 	wmi_csa_offload_enable_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_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf);
8719 	WMITLV_SET_HDR(&cmd->tlv_header,
8720 		       WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param,
8721 		       WMITLV_GET_STRUCT_TLVLEN
8722 			       (wmi_csa_offload_enable_cmd_fixed_param));
8723 	cmd->vdev_id = vdev_id;
8724 	cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE;
8725 	wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0);
8726 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8727 				 WMI_CSA_OFFLOAD_ENABLE_CMDID)) {
8728 		WMI_LOGP("%s: Failed to send CSA offload enable command",
8729 			 __func__);
8730 		wmi_buf_free(buf);
8731 		return QDF_STATUS_E_FAILURE;
8732 	}
8733 
8734 	return 0;
8735 }
8736 
8737 #ifdef WLAN_FEATURE_CIF_CFR
8738 /**
8739  * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings
8740  * @wmi_handle: wmi handle
8741  * @data_len: len of dma cfg req
8742  * @data: dma cfg req
8743  *
8744  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
8745  */
8746 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle,
8747 				wmi_oem_dma_ring_cfg_req_fixed_param *cfg)
8748 {
8749 	wmi_buf_t buf;
8750 	uint8_t *cmd;
8751 	QDF_STATUS ret;
8752 
8753 	WMITLV_SET_HDR(cfg,
8754 		WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param,
8755 		(sizeof(*cfg) - WMI_TLV_HDR_SIZE));
8756 
8757 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg));
8758 	if (!buf) {
8759 		WMI_LOGE(FL("wmi_buf_alloc failed"));
8760 		return QDF_STATUS_E_FAILURE;
8761 	}
8762 
8763 	cmd = (uint8_t *) wmi_buf_data(buf);
8764 	qdf_mem_copy(cmd, cfg, sizeof(*cfg));
8765 	WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"),
8766 		sizeof(*cfg));
8767 	wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0);
8768 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg),
8769 				WMI_OEM_DMA_RING_CFG_REQ_CMDID);
8770 	if (QDF_IS_STATUS_ERROR(ret)) {
8771 		WMI_LOGE(FL(":wmi cmd send failed"));
8772 		wmi_buf_free(buf);
8773 	}
8774 
8775 	return ret;
8776 }
8777 #endif
8778 
8779 /**
8780  * send_dbr_cfg_cmd_tlv() - configure DMA rings for Direct Buf RX
8781  * @wmi_handle: wmi handle
8782  * @data_len: len of dma cfg req
8783  * @data: dma cfg req
8784  *
8785  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
8786  */
8787 static QDF_STATUS send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle,
8788 				struct direct_buf_rx_cfg_req *cfg)
8789 {
8790 	wmi_buf_t buf;
8791 	wmi_dma_ring_cfg_req_fixed_param *cmd;
8792 	QDF_STATUS ret;
8793 	int32_t len = sizeof(*cmd);
8794 
8795 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
8796 	if (!buf) {
8797 		WMI_LOGE(FL("wmi_buf_alloc failed"));
8798 		return QDF_STATUS_E_FAILURE;
8799 	}
8800 
8801 	cmd = (wmi_dma_ring_cfg_req_fixed_param *)wmi_buf_data(buf);
8802 
8803 	WMITLV_SET_HDR(&cmd->tlv_header,
8804 		WMITLV_TAG_STRUC_wmi_dma_ring_cfg_req_fixed_param,
8805 		WMITLV_GET_STRUCT_TLVLEN(wmi_dma_ring_cfg_req_fixed_param));
8806 
8807 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
8808 						cfg->pdev_id);
8809 	cmd->mod_id = cfg->mod_id;
8810 	cmd->base_paddr_lo = cfg->base_paddr_lo;
8811 	cmd->base_paddr_hi = cfg->base_paddr_hi;
8812 	cmd->head_idx_paddr_lo = cfg->head_idx_paddr_lo;
8813 	cmd->head_idx_paddr_hi = cfg->head_idx_paddr_hi;
8814 	cmd->tail_idx_paddr_lo = cfg->tail_idx_paddr_lo;
8815 	cmd->tail_idx_paddr_hi = cfg->tail_idx_paddr_hi;
8816 	cmd->num_elems = cfg->num_elems;
8817 	cmd->buf_size = cfg->buf_size;
8818 	cmd->num_resp_per_event = cfg->num_resp_per_event;
8819 	cmd->event_timeout_ms = cfg->event_timeout_ms;
8820 
8821 	WMI_LOGD("%s: wmi_dma_ring_cfg_req_fixed_param pdev id %d mod id %d"
8822 		  "base paddr lo %x base paddr hi %x head idx paddr lo %x"
8823 		  "head idx paddr hi %x tail idx paddr lo %x"
8824 		  "tail idx addr hi %x num elems %d buf size %d num resp %d"
8825 		  "event timeout %d\n", __func__, cmd->pdev_id,
8826 		  cmd->mod_id, cmd->base_paddr_lo, cmd->base_paddr_hi,
8827 		  cmd->head_idx_paddr_lo, cmd->head_idx_paddr_hi,
8828 		  cmd->tail_idx_paddr_lo, cmd->tail_idx_paddr_hi,
8829 		  cmd->num_elems, cmd->buf_size, cmd->num_resp_per_event,
8830 		  cmd->event_timeout_ms);
8831 	wmi_mtrace(WMI_PDEV_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0);
8832 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8833 				WMI_PDEV_DMA_RING_CFG_REQ_CMDID);
8834 	if (QDF_IS_STATUS_ERROR(ret)) {
8835 		WMI_LOGE(FL(":wmi cmd send failed"));
8836 		wmi_buf_free(buf);
8837 	}
8838 
8839 	return ret;
8840 }
8841 
8842 /**
8843  * send_start_11d_scan_cmd_tlv() - start 11d scan request
8844  * @wmi_handle: wmi handle
8845  * @start_11d_scan: 11d scan start request parameters
8846  *
8847  * This function request FW to start 11d scan.
8848  *
8849  * Return: QDF status
8850  */
8851 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle,
8852 			  struct reg_start_11d_scan_req *start_11d_scan)
8853 {
8854 	wmi_11d_scan_start_cmd_fixed_param *cmd;
8855 	int32_t len;
8856 	wmi_buf_t buf;
8857 	int ret;
8858 
8859 	len = sizeof(*cmd);
8860 	buf = wmi_buf_alloc(wmi_handle, len);
8861 	if (!buf) {
8862 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8863 		return QDF_STATUS_E_NOMEM;
8864 	}
8865 
8866 	cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf);
8867 
8868 	WMITLV_SET_HDR(&cmd->tlv_header,
8869 		       WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param,
8870 		       WMITLV_GET_STRUCT_TLVLEN
8871 		       (wmi_11d_scan_start_cmd_fixed_param));
8872 
8873 	cmd->vdev_id = start_11d_scan->vdev_id;
8874 	cmd->scan_period_msec = start_11d_scan->scan_period_msec;
8875 	cmd->start_interval_msec = start_11d_scan->start_interval_msec;
8876 
8877 	WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id);
8878 
8879 	wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0);
8880 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8881 				   WMI_11D_SCAN_START_CMDID);
8882 	if (ret) {
8883 		WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__);
8884 		wmi_buf_free(buf);
8885 		return QDF_STATUS_E_FAILURE;
8886 	}
8887 
8888 	return QDF_STATUS_SUCCESS;
8889 }
8890 
8891 /**
8892  * send_stop_11d_scan_cmd_tlv() - stop 11d scan request
8893  * @wmi_handle: wmi handle
8894  * @start_11d_scan: 11d scan stop request parameters
8895  *
8896  * This function request FW to stop 11d scan.
8897  *
8898  * Return: QDF status
8899  */
8900 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle,
8901 			  struct reg_stop_11d_scan_req *stop_11d_scan)
8902 {
8903 	wmi_11d_scan_stop_cmd_fixed_param *cmd;
8904 	int32_t len;
8905 	wmi_buf_t buf;
8906 	int ret;
8907 
8908 	len = sizeof(*cmd);
8909 	buf = wmi_buf_alloc(wmi_handle, len);
8910 	if (!buf) {
8911 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8912 		return QDF_STATUS_E_NOMEM;
8913 	}
8914 
8915 	cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf);
8916 
8917 	WMITLV_SET_HDR(&cmd->tlv_header,
8918 		       WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param,
8919 		       WMITLV_GET_STRUCT_TLVLEN
8920 		       (wmi_11d_scan_stop_cmd_fixed_param));
8921 
8922 	cmd->vdev_id = stop_11d_scan->vdev_id;
8923 
8924 	WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id);
8925 
8926 	wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0);
8927 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8928 				   WMI_11D_SCAN_STOP_CMDID);
8929 	if (ret) {
8930 		WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__);
8931 		wmi_buf_free(buf);
8932 		return QDF_STATUS_E_FAILURE;
8933 	}
8934 
8935 	return QDF_STATUS_SUCCESS;
8936 }
8937 
8938 /**
8939  * send_start_oem_data_cmd_tlv() - start OEM data request to target
8940  * @wmi_handle: wmi handle
8941  * @startOemDataReq: start request params
8942  *
8943  * Return: CDF status
8944  */
8945 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle,
8946 			  uint32_t data_len,
8947 			  uint8_t *data)
8948 {
8949 	wmi_buf_t buf;
8950 	uint8_t *cmd;
8951 	QDF_STATUS ret;
8952 
8953 	buf = wmi_buf_alloc(wmi_handle,
8954 			    (data_len + WMI_TLV_HDR_SIZE));
8955 	if (!buf) {
8956 		WMI_LOGE(FL("wmi_buf_alloc failed"));
8957 		return QDF_STATUS_E_FAILURE;
8958 	}
8959 
8960 	cmd = (uint8_t *) wmi_buf_data(buf);
8961 
8962 	WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len);
8963 	cmd += WMI_TLV_HDR_SIZE;
8964 	qdf_mem_copy(cmd, data,
8965 		     data_len);
8966 
8967 	WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"),
8968 		 data_len);
8969 
8970 	wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0);
8971 	ret = wmi_unified_cmd_send(wmi_handle, buf,
8972 				   (data_len +
8973 				    WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID);
8974 
8975 	if (QDF_IS_STATUS_ERROR(ret)) {
8976 		WMI_LOGE(FL(":wmi cmd send failed"));
8977 		wmi_buf_free(buf);
8978 	}
8979 
8980 	return ret;
8981 }
8982 
8983 /**
8984  * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter
8985  * @wmi_handle: wmi handle
8986  * @dfs_phyerr_filter_offload: is dfs phyerr filter offload
8987  *
8988  * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or
8989  * WMI_DFS_PHYERR_FILTER_DIS_CMDID command
8990  * to firmware based on phyerr filtering
8991  * offload status.
8992  *
8993  * Return: 1 success, 0 failure
8994  */
8995 static QDF_STATUS
8996 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle,
8997 			bool dfs_phyerr_filter_offload)
8998 {
8999 	wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd;
9000 	wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd;
9001 	wmi_buf_t buf;
9002 	uint16_t len;
9003 	QDF_STATUS ret;
9004 
9005 
9006 	if (false == dfs_phyerr_filter_offload) {
9007 		WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini",
9008 			 __func__);
9009 		len = sizeof(*disable_phyerr_offload_cmd);
9010 		buf = wmi_buf_alloc(wmi_handle, len);
9011 		if (!buf) {
9012 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9013 			return 0;
9014 		}
9015 		disable_phyerr_offload_cmd =
9016 			(wmi_dfs_phyerr_filter_dis_cmd_fixed_param *)
9017 			wmi_buf_data(buf);
9018 
9019 		WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header,
9020 		     WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param,
9021 		     WMITLV_GET_STRUCT_TLVLEN
9022 		     (wmi_dfs_phyerr_filter_dis_cmd_fixed_param));
9023 
9024 		/*
9025 		 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID
9026 		 * to the firmware to disable the phyerror
9027 		 * filtering offload.
9028 		 */
9029 		wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0);
9030 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9031 					   WMI_DFS_PHYERR_FILTER_DIS_CMDID);
9032 		if (QDF_IS_STATUS_ERROR(ret)) {
9033 			WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d",
9034 				__func__, ret);
9035 			wmi_buf_free(buf);
9036 		return QDF_STATUS_E_FAILURE;
9037 		}
9038 		WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success",
9039 			 __func__);
9040 	} else {
9041 		WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini",
9042 			 __func__);
9043 
9044 		len = sizeof(*enable_phyerr_offload_cmd);
9045 		buf = wmi_buf_alloc(wmi_handle, len);
9046 		if (!buf) {
9047 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9048 		return QDF_STATUS_E_FAILURE;
9049 		}
9050 
9051 		enable_phyerr_offload_cmd =
9052 			(wmi_dfs_phyerr_filter_ena_cmd_fixed_param *)
9053 			wmi_buf_data(buf);
9054 
9055 		WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header,
9056 		     WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param,
9057 		     WMITLV_GET_STRUCT_TLVLEN
9058 		     (wmi_dfs_phyerr_filter_ena_cmd_fixed_param));
9059 
9060 		/*
9061 		 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID
9062 		 * to the firmware to enable the phyerror
9063 		 * filtering offload.
9064 		 */
9065 		wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0);
9066 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9067 					   WMI_DFS_PHYERR_FILTER_ENA_CMDID);
9068 
9069 		if (QDF_IS_STATUS_ERROR(ret)) {
9070 			WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d",
9071 				__func__, ret);
9072 			wmi_buf_free(buf);
9073 		return QDF_STATUS_E_FAILURE;
9074 		}
9075 		WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success",
9076 			 __func__);
9077 	}
9078 
9079 	return QDF_STATUS_SUCCESS;
9080 }
9081 
9082 /**
9083  * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware
9084  * will wake up host after specified time is elapsed
9085  * @wmi_handle: wmi handle
9086  * @vdev_id: vdev id
9087  * @cookie: value to identify reason why host set up wake call.
9088  * @time: time in ms
9089  *
9090  * Return: QDF status
9091  */
9092 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle,
9093 				uint8_t vdev_id, uint32_t cookie, uint32_t time)
9094 {
9095 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
9096 	wmi_buf_t buf;
9097 	uint8_t *buf_ptr;
9098 	int32_t len;
9099 	int ret;
9100 
9101 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
9102 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) +
9103 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
9104 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
9105 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
9106 		WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) +
9107 		WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
9108 
9109 	buf = wmi_buf_alloc(wmi_handle, len);
9110 	if (!buf) {
9111 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9112 		return QDF_STATUS_E_NOMEM;
9113 	}
9114 
9115 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
9116 	buf_ptr = (uint8_t *) cmd;
9117 
9118 	WMITLV_SET_HDR(&cmd->tlv_header,
9119 		WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
9120 		WMITLV_GET_STRUCT_TLVLEN
9121 			(WMI_WOW_ADD_PATTERN_CMD_fixed_param));
9122 	cmd->vdev_id = vdev_id;
9123 	cmd->pattern_id = cookie,
9124 	cmd->pattern_type = WOW_TIMER_PATTERN;
9125 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
9126 
9127 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
9128 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9129 	buf_ptr += WMI_TLV_HDR_SIZE;
9130 
9131 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
9132 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9133 	buf_ptr += WMI_TLV_HDR_SIZE;
9134 
9135 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
9136 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9137 	buf_ptr += WMI_TLV_HDR_SIZE;
9138 
9139 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
9140 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9141 	buf_ptr += WMI_TLV_HDR_SIZE;
9142 
9143 	/* Fill TLV for pattern_info_timeout, and time value */
9144 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
9145 	buf_ptr += WMI_TLV_HDR_SIZE;
9146 	*((uint32_t *) buf_ptr) = time;
9147 	buf_ptr += sizeof(uint32_t);
9148 
9149 	/* Fill TLV for ra_ratelimit_interval. with dummy 0 value */
9150 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
9151 	buf_ptr += WMI_TLV_HDR_SIZE;
9152 	*((uint32_t *) buf_ptr) = 0;
9153 
9154 	WMI_LOGD("%s: send wake timer pattern with time[%d] to fw vdev = %d",
9155 		__func__, time, vdev_id);
9156 
9157 	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
9158 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9159 				WMI_WOW_ADD_WAKE_PATTERN_CMDID);
9160 	if (ret) {
9161 		WMI_LOGE("%s: Failed to send wake timer pattern to fw",
9162 			__func__);
9163 		wmi_buf_free(buf);
9164 		return QDF_STATUS_E_FAILURE;
9165 	}
9166 
9167 	return QDF_STATUS_SUCCESS;
9168 }
9169 
9170 #if !defined(REMOVE_PKT_LOG)
9171 /**
9172  * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target
9173  * @wmi_handle: wmi handle
9174  * @pktlog_event: pktlog event
9175  * @cmd_id: pktlog cmd id
9176  *
9177  * Return: CDF status
9178  */
9179 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle,
9180 				   WMI_PKTLOG_EVENT pktlog_event,
9181 				   WMI_CMD_ID cmd_id, uint8_t user_triggered)
9182 {
9183 	WMI_PKTLOG_EVENT PKTLOG_EVENT;
9184 	WMI_CMD_ID CMD_ID;
9185 	wmi_pdev_pktlog_enable_cmd_fixed_param *cmd;
9186 	wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd;
9187 	int len = 0;
9188 	wmi_buf_t buf;
9189 
9190 	PKTLOG_EVENT = pktlog_event;
9191 	CMD_ID = cmd_id;
9192 
9193 	switch (CMD_ID) {
9194 	case WMI_PDEV_PKTLOG_ENABLE_CMDID:
9195 		len = sizeof(*cmd);
9196 		buf = wmi_buf_alloc(wmi_handle, len);
9197 		if (!buf) {
9198 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9199 			return QDF_STATUS_E_NOMEM;
9200 		}
9201 		cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *)
9202 			wmi_buf_data(buf);
9203 		WMITLV_SET_HDR(&cmd->tlv_header,
9204 		       WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param,
9205 		       WMITLV_GET_STRUCT_TLVLEN
9206 		       (wmi_pdev_pktlog_enable_cmd_fixed_param));
9207 		cmd->evlist = PKTLOG_EVENT;
9208 		cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE
9209 					: WMI_PKTLOG_ENABLE_AUTO;
9210 		cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
9211 							WMI_HOST_PDEV_ID_SOC);
9212 		wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0);
9213 		if (wmi_unified_cmd_send(wmi_handle, buf, len,
9214 					 WMI_PDEV_PKTLOG_ENABLE_CMDID)) {
9215 			WMI_LOGE("failed to send pktlog enable cmdid");
9216 			goto wmi_send_failed;
9217 		}
9218 		break;
9219 	case WMI_PDEV_PKTLOG_DISABLE_CMDID:
9220 		len = sizeof(*disable_cmd);
9221 		buf = wmi_buf_alloc(wmi_handle, len);
9222 		if (!buf) {
9223 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9224 			return QDF_STATUS_E_NOMEM;
9225 		}
9226 		disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *)
9227 			      wmi_buf_data(buf);
9228 		WMITLV_SET_HDR(&disable_cmd->tlv_header,
9229 		     WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param,
9230 		     WMITLV_GET_STRUCT_TLVLEN
9231 		     (wmi_pdev_pktlog_disable_cmd_fixed_param));
9232 		disable_cmd->pdev_id =
9233 			wmi_handle->ops->convert_pdev_id_host_to_target(
9234 							WMI_HOST_PDEV_ID_SOC);
9235 		wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0);
9236 		if (wmi_unified_cmd_send(wmi_handle, buf, len,
9237 					 WMI_PDEV_PKTLOG_DISABLE_CMDID)) {
9238 			WMI_LOGE("failed to send pktlog disable cmdid");
9239 			goto wmi_send_failed;
9240 		}
9241 		break;
9242 	default:
9243 		WMI_LOGD("%s: invalid PKTLOG command", __func__);
9244 		break;
9245 	}
9246 
9247 	return QDF_STATUS_SUCCESS;
9248 
9249 wmi_send_failed:
9250 	wmi_buf_free(buf);
9251 	return QDF_STATUS_E_FAILURE;
9252 }
9253 #endif /* REMOVE_PKT_LOG */
9254 
9255 /**
9256  * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target
9257  * @wmi_handle: wmi handle
9258  * @ptrn_id: pattern id
9259  * @vdev_id: vdev id
9260  *
9261  * Return: CDF status
9262  */
9263 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle,
9264 			uint8_t ptrn_id, uint8_t vdev_id)
9265 {
9266 	WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd;
9267 	wmi_buf_t buf;
9268 	int32_t len;
9269 	int ret;
9270 
9271 	len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param);
9272 
9273 
9274 	buf = wmi_buf_alloc(wmi_handle, len);
9275 	if (!buf) {
9276 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9277 		return QDF_STATUS_E_NOMEM;
9278 	}
9279 
9280 	cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
9281 
9282 	WMITLV_SET_HDR(&cmd->tlv_header,
9283 		       WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param,
9284 		       WMITLV_GET_STRUCT_TLVLEN(
9285 				WMI_WOW_DEL_PATTERN_CMD_fixed_param));
9286 	cmd->vdev_id = vdev_id;
9287 	cmd->pattern_id = ptrn_id;
9288 	cmd->pattern_type = WOW_BITMAP_PATTERN;
9289 
9290 	WMI_LOGI("Deleting pattern id: %d vdev id %d in fw",
9291 		cmd->pattern_id, vdev_id);
9292 
9293 	wmi_mtrace(WMI_WOW_DEL_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
9294 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9295 				   WMI_WOW_DEL_WAKE_PATTERN_CMDID);
9296 	if (ret) {
9297 		WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__);
9298 		wmi_buf_free(buf);
9299 		return QDF_STATUS_E_FAILURE;
9300 	}
9301 
9302 	return QDF_STATUS_SUCCESS;
9303 }
9304 
9305 /**
9306  * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw
9307  * @wmi_handle: wmi handle
9308  *
9309  * Sends host wakeup indication to FW. On receiving this indication,
9310  * FW will come out of WOW.
9311  *
9312  * Return: CDF status
9313  */
9314 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle)
9315 {
9316 	wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd;
9317 	wmi_buf_t buf;
9318 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
9319 	int32_t len;
9320 	int ret;
9321 
9322 	len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param);
9323 
9324 	buf = wmi_buf_alloc(wmi_handle, len);
9325 	if (!buf) {
9326 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9327 		return QDF_STATUS_E_NOMEM;
9328 	}
9329 
9330 	cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *)
9331 	      wmi_buf_data(buf);
9332 	WMITLV_SET_HDR(&cmd->tlv_header,
9333 		WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param,
9334 		WMITLV_GET_STRUCT_TLVLEN
9335 	       (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param));
9336 
9337 
9338 	wmi_mtrace(WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, NO_SESSION, 0);
9339 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9340 				   WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID);
9341 	if (ret) {
9342 		WMI_LOGE("Failed to send host wakeup indication to fw");
9343 		wmi_buf_free(buf);
9344 		return QDF_STATUS_E_FAILURE;
9345 	}
9346 
9347 	return qdf_status;
9348 }
9349 
9350 /**
9351  * send_del_ts_cmd_tlv() - send DELTS request to fw
9352  * @wmi_handle: wmi handle
9353  * @msg: delts params
9354  *
9355  * Return: CDF status
9356  */
9357 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
9358 				uint8_t ac)
9359 {
9360 	wmi_vdev_wmm_delts_cmd_fixed_param *cmd;
9361 	wmi_buf_t buf;
9362 	int32_t len = sizeof(*cmd);
9363 
9364 	buf = wmi_buf_alloc(wmi_handle, len);
9365 	if (!buf) {
9366 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9367 		return QDF_STATUS_E_NOMEM;
9368 	}
9369 	cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf);
9370 	WMITLV_SET_HDR(&cmd->tlv_header,
9371 		       WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param,
9372 		       WMITLV_GET_STRUCT_TLVLEN
9373 			       (wmi_vdev_wmm_delts_cmd_fixed_param));
9374 	cmd->vdev_id = vdev_id;
9375 	cmd->ac = ac;
9376 
9377 	WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d",
9378 		 cmd->vdev_id, cmd->ac, __func__, __LINE__);
9379 	wmi_mtrace(WMI_VDEV_WMM_DELTS_CMDID, cmd->vdev_id, 0);
9380 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
9381 				 WMI_VDEV_WMM_DELTS_CMDID)) {
9382 		WMI_LOGP("%s: Failed to send vdev DELTS command", __func__);
9383 		wmi_buf_free(buf);
9384 		return QDF_STATUS_E_FAILURE;
9385 	}
9386 
9387 	return QDF_STATUS_SUCCESS;
9388 }
9389 
9390 /**
9391  * send_aggr_qos_cmd_tlv() - send aggr qos request to fw
9392  * @wmi_handle: handle to wmi
9393  * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests.
9394  *
9395  * A function to handle WMI_AGGR_QOS_REQ. This will send out
9396  * ADD_TS requestes to firmware in loop for all the ACs with
9397  * active flow.
9398  *
9399  * Return: CDF status
9400  */
9401 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle,
9402 		      struct aggr_add_ts_param *aggr_qos_rsp_msg)
9403 {
9404 	int i = 0;
9405 	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
9406 	wmi_buf_t buf;
9407 	int32_t len = sizeof(*cmd);
9408 
9409 	for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) {
9410 		/* if flow in this AC is active */
9411 		if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) {
9412 			/*
9413 			 * as per implementation of wma_add_ts_req() we
9414 			 * are not waiting any response from firmware so
9415 			 * apart from sending ADDTS to firmware just send
9416 			 * success to upper layers
9417 			 */
9418 			aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS;
9419 
9420 			buf = wmi_buf_alloc(wmi_handle, len);
9421 			if (!buf) {
9422 				WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9423 				return QDF_STATUS_E_NOMEM;
9424 			}
9425 			cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *)
9426 				wmi_buf_data(buf);
9427 			WMITLV_SET_HDR(&cmd->tlv_header,
9428 			       WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
9429 			       WMITLV_GET_STRUCT_TLVLEN
9430 				       (wmi_vdev_wmm_addts_cmd_fixed_param));
9431 			cmd->vdev_id = aggr_qos_rsp_msg->vdev_id;
9432 			cmd->ac =
9433 				WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo.
9434 					      traffic.userPrio);
9435 			cmd->medium_time_us =
9436 				aggr_qos_rsp_msg->tspec[i].mediumTime * 32;
9437 			cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO;
9438 			WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d",
9439 				__func__, __LINE__, cmd->vdev_id, cmd->ac,
9440 				cmd->medium_time_us, cmd->downgrade_type);
9441 			wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
9442 			if (wmi_unified_cmd_send
9443 				    (wmi_handle, buf, len,
9444 				    WMI_VDEV_WMM_ADDTS_CMDID)) {
9445 				WMI_LOGP("%s: Failed to send vdev ADDTS command",
9446 					__func__);
9447 				aggr_qos_rsp_msg->status[i] =
9448 					QDF_STATUS_E_FAILURE;
9449 				wmi_buf_free(buf);
9450 				return QDF_STATUS_E_FAILURE;
9451 			}
9452 		}
9453 	}
9454 
9455 	return QDF_STATUS_SUCCESS;
9456 }
9457 
9458 /**
9459  * send_add_ts_cmd_tlv() - send ADDTS request to fw
9460  * @wmi_handle: wmi handle
9461  * @msg: ADDTS params
9462  *
9463  * Return: CDF status
9464  */
9465 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle,
9466 		 struct add_ts_param *msg)
9467 {
9468 	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
9469 	wmi_buf_t buf;
9470 	int32_t len = sizeof(*cmd);
9471 
9472 	msg->status = QDF_STATUS_SUCCESS;
9473 
9474 	buf = wmi_buf_alloc(wmi_handle, len);
9475 	if (!buf) {
9476 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9477 		return QDF_STATUS_E_NOMEM;
9478 	}
9479 	cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf);
9480 	WMITLV_SET_HDR(&cmd->tlv_header,
9481 		       WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
9482 		       WMITLV_GET_STRUCT_TLVLEN
9483 			       (wmi_vdev_wmm_addts_cmd_fixed_param));
9484 	cmd->vdev_id = msg->sme_session_id;
9485 	cmd->ac = msg->tspec.tsinfo.traffic.userPrio;
9486 	cmd->medium_time_us = msg->tspec.mediumTime * 32;
9487 	cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP;
9488 	WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d",
9489 		 cmd->vdev_id, cmd->ac, cmd->medium_time_us,
9490 		 cmd->downgrade_type, __func__, __LINE__);
9491 	wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
9492 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
9493 				 WMI_VDEV_WMM_ADDTS_CMDID)) {
9494 		WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__);
9495 		msg->status = QDF_STATUS_E_FAILURE;
9496 		wmi_buf_free(buf);
9497 		return QDF_STATUS_E_FAILURE;
9498 	}
9499 
9500 	return QDF_STATUS_SUCCESS;
9501 }
9502 
9503 /**
9504  * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn
9505  * @wmi_handle: wmi handle
9506  * @pAddPeriodicTxPtrnParams: tx ptrn params
9507  *
9508  * Retrun: CDF status
9509  */
9510 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
9511 						struct periodic_tx_pattern  *
9512 						pAddPeriodicTxPtrnParams,
9513 						uint8_t vdev_id)
9514 {
9515 	WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
9516 	wmi_buf_t wmi_buf;
9517 	uint32_t len;
9518 	uint8_t *buf_ptr;
9519 	uint32_t ptrn_len, ptrn_len_aligned;
9520 	int j;
9521 
9522 	ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize;
9523 	ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t));
9524 	len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) +
9525 	      WMI_TLV_HDR_SIZE + ptrn_len_aligned;
9526 
9527 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
9528 	if (!wmi_buf) {
9529 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
9530 		return QDF_STATUS_E_NOMEM;
9531 	}
9532 
9533 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
9534 
9535 	cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr;
9536 	WMITLV_SET_HDR(&cmd->tlv_header,
9537 	       WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
9538 	       WMITLV_GET_STRUCT_TLVLEN
9539 	       (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
9540 
9541 	/* Pass the pattern id to delete for the corresponding vdev id */
9542 	cmd->vdev_id = vdev_id;
9543 	cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId;
9544 	cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs;
9545 	cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize;
9546 
9547 	/* Pattern info */
9548 	buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
9549 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned);
9550 	buf_ptr += WMI_TLV_HDR_SIZE;
9551 	qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len);
9552 	for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++)
9553 		WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff);
9554 
9555 	WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d",
9556 		 __func__, cmd->pattern_id, cmd->vdev_id);
9557 
9558 	wmi_mtrace(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
9559 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
9560 				 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
9561 		WMI_LOGE("%s: failed to add pattern set state command",
9562 			 __func__);
9563 		wmi_buf_free(wmi_buf);
9564 		return QDF_STATUS_E_FAILURE;
9565 	}
9566 	return QDF_STATUS_SUCCESS;
9567 }
9568 
9569 /**
9570  * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn
9571  * @wmi_handle: wmi handle
9572  * @vdev_id: vdev id
9573  * @pattern_id: pattern id
9574  *
9575  * Retrun: CDF status
9576  */
9577 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
9578 						uint8_t vdev_id,
9579 						uint8_t pattern_id)
9580 {
9581 	WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
9582 	wmi_buf_t wmi_buf;
9583 	uint32_t len =
9584 		sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
9585 
9586 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
9587 	if (!wmi_buf) {
9588 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
9589 		return QDF_STATUS_E_NOMEM;
9590 	}
9591 
9592 	cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)
9593 		wmi_buf_data(wmi_buf);
9594 	WMITLV_SET_HDR(&cmd->tlv_header,
9595 	       WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
9596 	       WMITLV_GET_STRUCT_TLVLEN
9597 	       (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
9598 
9599 	/* Pass the pattern id to delete for the corresponding vdev id */
9600 	cmd->vdev_id = vdev_id;
9601 	cmd->pattern_id = pattern_id;
9602 	WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d",
9603 		 __func__, cmd->pattern_id, cmd->vdev_id);
9604 
9605 	wmi_mtrace(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
9606 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
9607 				 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
9608 		WMI_LOGE("%s: failed to send del pattern command", __func__);
9609 		wmi_buf_free(wmi_buf);
9610 		return QDF_STATUS_E_FAILURE;
9611 	}
9612 	return QDF_STATUS_SUCCESS;
9613 }
9614 
9615 /**
9616  * send_stats_ext_req_cmd_tlv() - request ext stats from fw
9617  * @wmi_handle: wmi handle
9618  * @preq: stats ext params
9619  *
9620  * Return: CDF status
9621  */
9622 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle,
9623 			struct stats_ext_params *preq)
9624 {
9625 	QDF_STATUS ret;
9626 	wmi_req_stats_ext_cmd_fixed_param *cmd;
9627 	wmi_buf_t buf;
9628 	size_t len;
9629 	uint8_t *buf_ptr;
9630 
9631 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len;
9632 
9633 	buf = wmi_buf_alloc(wmi_handle, len);
9634 	if (!buf) {
9635 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9636 		return QDF_STATUS_E_NOMEM;
9637 	}
9638 
9639 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
9640 	cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr;
9641 
9642 	WMITLV_SET_HDR(&cmd->tlv_header,
9643 		       WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param,
9644 		       WMITLV_GET_STRUCT_TLVLEN
9645 			       (wmi_req_stats_ext_cmd_fixed_param));
9646 	cmd->vdev_id = preq->vdev_id;
9647 	cmd->data_len = preq->request_data_len;
9648 
9649 	WMI_LOGD("%s: The data len value is %u and vdev id set is %u ",
9650 		 __func__, preq->request_data_len, preq->vdev_id);
9651 
9652 	buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param);
9653 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len);
9654 
9655 	buf_ptr += WMI_TLV_HDR_SIZE;
9656 	qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len);
9657 
9658 	wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0);
9659 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9660 				   WMI_REQUEST_STATS_EXT_CMDID);
9661 	if (QDF_IS_STATUS_ERROR(ret)) {
9662 		WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__,
9663 			 ret);
9664 		wmi_buf_free(buf);
9665 	}
9666 
9667 	return ret;
9668 }
9669 
9670 /**
9671  * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw
9672  * @wmi_handle: wmi handle
9673  * @params: ext wow params
9674  *
9675  * Return:0 for success or error code
9676  */
9677 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle,
9678 			struct ext_wow_params *params)
9679 {
9680 	wmi_extwow_enable_cmd_fixed_param *cmd;
9681 	wmi_buf_t buf;
9682 	int32_t len;
9683 	int ret;
9684 
9685 	len = sizeof(wmi_extwow_enable_cmd_fixed_param);
9686 	buf = wmi_buf_alloc(wmi_handle, len);
9687 	if (!buf) {
9688 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9689 		return QDF_STATUS_E_NOMEM;
9690 	}
9691 
9692 	cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf);
9693 
9694 	WMITLV_SET_HDR(&cmd->tlv_header,
9695 		       WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param,
9696 		       WMITLV_GET_STRUCT_TLVLEN
9697 			       (wmi_extwow_enable_cmd_fixed_param));
9698 
9699 	cmd->vdev_id = params->vdev_id;
9700 	cmd->type = params->type;
9701 	cmd->wakeup_pin_num = params->wakeup_pin_num;
9702 
9703 	WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x",
9704 		 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num);
9705 
9706 	wmi_mtrace(WMI_EXTWOW_ENABLE_CMDID, cmd->vdev_id, 0);
9707 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9708 				   WMI_EXTWOW_ENABLE_CMDID);
9709 	if (ret) {
9710 		WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__);
9711 		wmi_buf_free(buf);
9712 		return QDF_STATUS_E_FAILURE;
9713 	}
9714 
9715 	return QDF_STATUS_SUCCESS;
9716 
9717 }
9718 
9719 /**
9720  * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw
9721  * @wmi_handle: wmi handle
9722  * @app_type1_params: app type1 params
9723  *
9724  * Return: CDF status
9725  */
9726 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
9727 				   struct app_type1_params *app_type1_params)
9728 {
9729 	wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd;
9730 	wmi_buf_t buf;
9731 	int32_t len;
9732 	int ret;
9733 
9734 	len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param);
9735 	buf = wmi_buf_alloc(wmi_handle, len);
9736 	if (!buf) {
9737 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9738 		return QDF_STATUS_E_NOMEM;
9739 	}
9740 
9741 	cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *)
9742 	      wmi_buf_data(buf);
9743 
9744 	WMITLV_SET_HDR(&cmd->tlv_header,
9745 	       WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param,
9746 	       WMITLV_GET_STRUCT_TLVLEN
9747 	       (wmi_extwow_set_app_type1_params_cmd_fixed_param));
9748 
9749 	cmd->vdev_id = app_type1_params->vdev_id;
9750 	WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes,
9751 				   &cmd->wakee_mac);
9752 	qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8);
9753 	cmd->ident_len = app_type1_params->id_length;
9754 	qdf_mem_copy(cmd->passwd, app_type1_params->password, 16);
9755 	cmd->passwd_len = app_type1_params->pass_length;
9756 
9757 	WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM "
9758 		 "identification_id %.8s id_length %u "
9759 		 "password %.16s pass_length %u",
9760 		 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes,
9761 		 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len);
9762 
9763 	wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID, cmd->vdev_id, 0);
9764 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9765 				   WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID);
9766 	if (ret) {
9767 		WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__);
9768 		wmi_buf_free(buf);
9769 		return QDF_STATUS_E_FAILURE;
9770 	}
9771 
9772 	return QDF_STATUS_SUCCESS;
9773 }
9774 
9775 /**
9776  * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw
9777  * @wmi_handle: wmi handle
9778  * @appType2Params: app type2 params
9779  *
9780  * Return: CDF status
9781  */
9782 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
9783 			  struct app_type2_params *appType2Params)
9784 {
9785 	wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd;
9786 	wmi_buf_t buf;
9787 	int32_t len;
9788 	int ret;
9789 
9790 	len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param);
9791 	buf = wmi_buf_alloc(wmi_handle, len);
9792 	if (!buf) {
9793 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9794 		return QDF_STATUS_E_NOMEM;
9795 	}
9796 
9797 	cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *)
9798 	      wmi_buf_data(buf);
9799 
9800 	WMITLV_SET_HDR(&cmd->tlv_header,
9801 	       WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param,
9802 	       WMITLV_GET_STRUCT_TLVLEN
9803 	       (wmi_extwow_set_app_type2_params_cmd_fixed_param));
9804 
9805 	cmd->vdev_id = appType2Params->vdev_id;
9806 
9807 	qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16);
9808 	cmd->rc4_key_len = appType2Params->rc4_key_len;
9809 
9810 	cmd->ip_id = appType2Params->ip_id;
9811 	cmd->ip_device_ip = appType2Params->ip_device_ip;
9812 	cmd->ip_server_ip = appType2Params->ip_server_ip;
9813 
9814 	cmd->tcp_src_port = appType2Params->tcp_src_port;
9815 	cmd->tcp_dst_port = appType2Params->tcp_dst_port;
9816 	cmd->tcp_seq = appType2Params->tcp_seq;
9817 	cmd->tcp_ack_seq = appType2Params->tcp_ack_seq;
9818 
9819 	cmd->keepalive_init = appType2Params->keepalive_init;
9820 	cmd->keepalive_min = appType2Params->keepalive_min;
9821 	cmd->keepalive_max = appType2Params->keepalive_max;
9822 	cmd->keepalive_inc = appType2Params->keepalive_inc;
9823 
9824 	WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes,
9825 				   &cmd->gateway_mac);
9826 	cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val;
9827 	cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val;
9828 
9829 	WMI_LOGD("%s: vdev_id %d gateway_mac %pM "
9830 		 "rc4_key %.16s rc4_key_len %u "
9831 		 "ip_id %x ip_device_ip %x ip_server_ip %x "
9832 		 "tcp_src_port %u tcp_dst_port %u tcp_seq %u "
9833 		 "tcp_ack_seq %u keepalive_init %u keepalive_min %u "
9834 		 "keepalive_max %u keepalive_inc %u "
9835 		 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u",
9836 		 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes,
9837 		 cmd->rc4_key, cmd->rc4_key_len,
9838 		 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip,
9839 		 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq,
9840 		 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min,
9841 		 cmd->keepalive_max, cmd->keepalive_inc,
9842 		 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val);
9843 
9844 	wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID, cmd->vdev_id, 0);
9845 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9846 				   WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID);
9847 	if (ret) {
9848 		WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__);
9849 		wmi_buf_free(buf);
9850 		return QDF_STATUS_E_FAILURE;
9851 	}
9852 
9853 	return QDF_STATUS_SUCCESS;
9854 
9855 }
9856 
9857 /**
9858  * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware
9859  * @wmi_handle: wmi handle
9860  * @timer_val: auto shutdown timer value
9861  *
9862  * Return: CDF status
9863  */
9864 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle,
9865 						  uint32_t timer_val)
9866 {
9867 	QDF_STATUS status;
9868 	wmi_buf_t buf = NULL;
9869 	uint8_t *buf_ptr;
9870 	wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd;
9871 	int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param);
9872 
9873 	WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d",
9874 		 __func__, timer_val);
9875 
9876 	buf = wmi_buf_alloc(wmi_handle, len);
9877 	if (!buf) {
9878 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
9879 		return QDF_STATUS_E_NOMEM;
9880 	}
9881 
9882 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
9883 	wmi_auto_sh_cmd =
9884 		(wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr;
9885 	wmi_auto_sh_cmd->timer_value = timer_val;
9886 
9887 	WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header,
9888 	       WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param,
9889 	       WMITLV_GET_STRUCT_TLVLEN
9890 	       (wmi_host_auto_shutdown_cfg_cmd_fixed_param));
9891 
9892 	wmi_mtrace(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID, NO_SESSION, 0);
9893 	status = wmi_unified_cmd_send(wmi_handle, buf,
9894 				      len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID);
9895 	if (QDF_IS_STATUS_ERROR(status)) {
9896 		WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d",
9897 			 __func__, status);
9898 		wmi_buf_free(buf);
9899 	}
9900 
9901 	return status;
9902 }
9903 
9904 /**
9905  * send_nan_req_cmd_tlv() - to send nan request to target
9906  * @wmi_handle: wmi handle
9907  * @nan_req: request data which will be non-null
9908  *
9909  * Return: CDF status
9910  */
9911 static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle,
9912 			struct nan_req_params *nan_req)
9913 {
9914 	QDF_STATUS ret;
9915 	wmi_nan_cmd_param *cmd;
9916 	wmi_buf_t buf;
9917 	uint16_t len = sizeof(*cmd);
9918 	uint16_t nan_data_len, nan_data_len_aligned;
9919 	uint8_t *buf_ptr;
9920 
9921 	/*
9922 	 *    <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ---->
9923 	 *    +------------+----------+-----------------------+--------------+
9924 	 *    | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data |
9925 	 *    +------------+----------+-----------------------+--------------+
9926 	 */
9927 	if (!nan_req) {
9928 		WMI_LOGE("%s:nan req is not valid", __func__);
9929 		return QDF_STATUS_E_FAILURE;
9930 	}
9931 	nan_data_len = nan_req->request_data_len;
9932 	nan_data_len_aligned = roundup(nan_req->request_data_len,
9933 				       sizeof(uint32_t));
9934 	if (nan_data_len_aligned < nan_req->request_data_len) {
9935 		WMI_LOGE("%s: integer overflow while rounding up data_len",
9936 			 __func__);
9937 		return QDF_STATUS_E_FAILURE;
9938 	}
9939 
9940 	if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) {
9941 		WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen",
9942 			 __func__);
9943 		return QDF_STATUS_E_FAILURE;
9944 	}
9945 
9946 	len += WMI_TLV_HDR_SIZE + nan_data_len_aligned;
9947 	buf = wmi_buf_alloc(wmi_handle, len);
9948 	if (!buf) {
9949 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9950 		return QDF_STATUS_E_NOMEM;
9951 	}
9952 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
9953 	cmd = (wmi_nan_cmd_param *) buf_ptr;
9954 	WMITLV_SET_HDR(&cmd->tlv_header,
9955 		       WMITLV_TAG_STRUC_wmi_nan_cmd_param,
9956 		       WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param));
9957 	cmd->data_len = nan_req->request_data_len;
9958 	WMI_LOGD("%s: The data len value is %u",
9959 		 __func__, nan_req->request_data_len);
9960 	buf_ptr += sizeof(wmi_nan_cmd_param);
9961 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned);
9962 	buf_ptr += WMI_TLV_HDR_SIZE;
9963 	qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len);
9964 
9965 	wmi_mtrace(WMI_NAN_CMDID, NO_SESSION, 0);
9966 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9967 				   WMI_NAN_CMDID);
9968 	if (QDF_IS_STATUS_ERROR(ret)) {
9969 		WMI_LOGE("%s Failed to send set param command ret = %d",
9970 			 __func__, ret);
9971 		wmi_buf_free(buf);
9972 	}
9973 
9974 	return ret;
9975 }
9976 
9977 /**
9978  * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload
9979  * @wmi_handle: wmi handle
9980  * @params: DHCP server offload info
9981  *
9982  * Return: QDF_STATUS_SUCCESS for success or error code
9983  */
9984 static QDF_STATUS
9985 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle,
9986 					struct dhcp_offload_info_params *params)
9987 {
9988 	wmi_set_dhcp_server_offload_cmd_fixed_param *cmd;
9989 	wmi_buf_t buf;
9990 	QDF_STATUS status;
9991 
9992 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
9993 	if (!buf) {
9994 		WMI_LOGE("Failed to allocate buffer to send "
9995 			 "set_dhcp_server_offload cmd");
9996 		return QDF_STATUS_E_NOMEM;
9997 	}
9998 
9999 	cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf);
10000 
10001 	WMITLV_SET_HDR(&cmd->tlv_header,
10002 	       WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param,
10003 	       WMITLV_GET_STRUCT_TLVLEN
10004 	       (wmi_set_dhcp_server_offload_cmd_fixed_param));
10005 	cmd->vdev_id = params->vdev_id;
10006 	cmd->enable = params->dhcp_offload_enabled;
10007 	cmd->num_client = params->dhcp_client_num;
10008 	cmd->srv_ipv4 = params->dhcp_srv_addr;
10009 	cmd->start_lsb = 0;
10010 	wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0);
10011 	status = wmi_unified_cmd_send(wmi_handle, buf,
10012 				   sizeof(*cmd),
10013 				   WMI_SET_DHCP_SERVER_OFFLOAD_CMDID);
10014 	if (QDF_IS_STATUS_ERROR(status)) {
10015 		WMI_LOGE("Failed to send set_dhcp_server_offload cmd");
10016 		wmi_buf_free(buf);
10017 		return QDF_STATUS_E_FAILURE;
10018 	}
10019 	WMI_LOGD("Set dhcp server offload to vdevId %d",
10020 		 params->vdev_id);
10021 
10022 	return status;
10023 }
10024 
10025 /**
10026  * send_set_led_flashing_cmd_tlv() - set led flashing in fw
10027  * @wmi_handle: wmi handle
10028  * @flashing: flashing request
10029  *
10030  * Return: CDF status
10031  */
10032 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle,
10033 				struct flashing_req_params *flashing)
10034 {
10035 	wmi_set_led_flashing_cmd_fixed_param *cmd;
10036 	QDF_STATUS status;
10037 	wmi_buf_t buf;
10038 	uint8_t *buf_ptr;
10039 	int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param);
10040 
10041 	buf = wmi_buf_alloc(wmi_handle, len);
10042 	if (!buf) {
10043 		WMI_LOGP(FL("wmi_buf_alloc failed"));
10044 		return QDF_STATUS_E_NOMEM;
10045 	}
10046 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
10047 	cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr;
10048 	WMITLV_SET_HDR(&cmd->tlv_header,
10049 		       WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param,
10050 		       WMITLV_GET_STRUCT_TLVLEN
10051 			       (wmi_set_led_flashing_cmd_fixed_param));
10052 	cmd->pattern_id = flashing->pattern_id;
10053 	cmd->led_x0 = flashing->led_x0;
10054 	cmd->led_x1 = flashing->led_x1;
10055 
10056 	wmi_mtrace(WMI_PDEV_SET_LED_FLASHING_CMDID, NO_SESSION, 0);
10057 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
10058 				      WMI_PDEV_SET_LED_FLASHING_CMDID);
10059 	if (QDF_IS_STATUS_ERROR(status)) {
10060 		WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
10061 			 " returned Error %d", __func__, status);
10062 		wmi_buf_free(buf);
10063 	}
10064 
10065 	return status;
10066 }
10067 
10068 /**
10069  * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request
10070  * @wmi_handle: wmi handle
10071  * @ch_avoid_update_req: channel avoid update params
10072  *
10073  * Return: CDF status
10074  */
10075 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle)
10076 {
10077 	QDF_STATUS status;
10078 	wmi_buf_t buf = NULL;
10079 	uint8_t *buf_ptr;
10080 	wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp;
10081 	int len = sizeof(wmi_chan_avoid_update_cmd_param);
10082 
10083 
10084 	buf = wmi_buf_alloc(wmi_handle, len);
10085 	if (!buf) {
10086 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
10087 		return QDF_STATUS_E_NOMEM;
10088 	}
10089 
10090 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
10091 	ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr;
10092 	WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header,
10093 		       WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param,
10094 		       WMITLV_GET_STRUCT_TLVLEN
10095 			       (wmi_chan_avoid_update_cmd_param));
10096 
10097 	wmi_mtrace(WMI_CHAN_AVOID_UPDATE_CMDID, NO_SESSION, 0);
10098 	status = wmi_unified_cmd_send(wmi_handle, buf,
10099 				      len, WMI_CHAN_AVOID_UPDATE_CMDID);
10100 	if (QDF_IS_STATUS_ERROR(status)) {
10101 		WMI_LOGE("wmi_unified_cmd_send"
10102 			 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE"
10103 			 " returned Error %d", status);
10104 		wmi_buf_free(buf);
10105 	}
10106 
10107 	return status;
10108 }
10109 
10110 /**
10111  * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw
10112  * @wmi_handle: wmi handle
10113  * @param: pointer to pdev regdomain params
10114  *
10115  * Return: 0 for success or error code
10116  */
10117 static QDF_STATUS
10118 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle,
10119 				struct pdev_set_regdomain_params *param)
10120 {
10121 	wmi_buf_t buf;
10122 	wmi_pdev_set_regdomain_cmd_fixed_param *cmd;
10123 	int32_t len = sizeof(*cmd);
10124 
10125 
10126 	buf = wmi_buf_alloc(wmi_handle, len);
10127 	if (!buf) {
10128 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
10129 		return QDF_STATUS_E_NOMEM;
10130 	}
10131 	cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf);
10132 	WMITLV_SET_HDR(&cmd->tlv_header,
10133 		       WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param,
10134 		       WMITLV_GET_STRUCT_TLVLEN
10135 			       (wmi_pdev_set_regdomain_cmd_fixed_param));
10136 
10137 	cmd->reg_domain = param->currentRDinuse;
10138 	cmd->reg_domain_2G = param->currentRD2G;
10139 	cmd->reg_domain_5G = param->currentRD5G;
10140 	cmd->conformance_test_limit_2G = param->ctl_2G;
10141 	cmd->conformance_test_limit_5G = param->ctl_5G;
10142 	cmd->dfs_domain = param->dfsDomain;
10143 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10144 							param->pdev_id);
10145 
10146 	wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0);
10147 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10148 				 WMI_PDEV_SET_REGDOMAIN_CMDID)) {
10149 		WMI_LOGE("%s: Failed to send pdev set regdomain command",
10150 			 __func__);
10151 		wmi_buf_free(buf);
10152 		return QDF_STATUS_E_FAILURE;
10153 	}
10154 
10155 	return QDF_STATUS_SUCCESS;
10156 }
10157 
10158 /**
10159  * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw
10160  * @wmi_handle: wmi handle
10161  * @reg_dmn: reg domain
10162  * @regdmn2G: 2G reg domain
10163  * @regdmn5G: 5G reg domain
10164  * @ctl2G: 2G test limit
10165  * @ctl5G: 5G test limit
10166  *
10167  * Return: none
10168  */
10169 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle,
10170 				   uint32_t reg_dmn, uint16_t regdmn2G,
10171 				   uint16_t regdmn5G, uint8_t ctl2G,
10172 				   uint8_t ctl5G)
10173 {
10174 	wmi_buf_t buf;
10175 	wmi_pdev_set_regdomain_cmd_fixed_param *cmd;
10176 	int32_t len = sizeof(*cmd);
10177 
10178 
10179 	buf = wmi_buf_alloc(wmi_handle, len);
10180 	if (!buf) {
10181 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
10182 		return QDF_STATUS_E_NOMEM;
10183 	}
10184 	cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf);
10185 	WMITLV_SET_HDR(&cmd->tlv_header,
10186 		       WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param,
10187 		       WMITLV_GET_STRUCT_TLVLEN
10188 			       (wmi_pdev_set_regdomain_cmd_fixed_param));
10189 	cmd->reg_domain = reg_dmn;
10190 	cmd->reg_domain_2G = regdmn2G;
10191 	cmd->reg_domain_5G = regdmn5G;
10192 	cmd->conformance_test_limit_2G = ctl2G;
10193 	cmd->conformance_test_limit_5G = ctl5G;
10194 
10195 	wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0);
10196 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10197 				 WMI_PDEV_SET_REGDOMAIN_CMDID)) {
10198 		WMI_LOGP("%s: Failed to send pdev set regdomain command",
10199 			 __func__);
10200 		wmi_buf_free(buf);
10201 		return QDF_STATUS_E_FAILURE;
10202 	}
10203 
10204 	return QDF_STATUS_SUCCESS;
10205 }
10206 
10207 
10208 /**
10209  * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode
10210  * @wmi_handle: wmi handle
10211  * @chan_switch_params: Pointer to tdls channel switch parameter structure
10212  *
10213  * This function sets tdls off channel mode
10214  *
10215  * Return: 0 on success; Negative errno otherwise
10216  */
10217 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle,
10218 	      struct tdls_channel_switch_params *chan_switch_params)
10219 {
10220 	wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd;
10221 	wmi_buf_t wmi_buf;
10222 	u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param);
10223 
10224 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10225 	if (!wmi_buf) {
10226 		WMI_LOGE(FL("wmi_buf_alloc failed"));
10227 		return QDF_STATUS_E_FAILURE;
10228 	}
10229 	cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *)
10230 		wmi_buf_data(wmi_buf);
10231 	WMITLV_SET_HDR(&cmd->tlv_header,
10232 		WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param,
10233 		WMITLV_GET_STRUCT_TLVLEN(
10234 			wmi_tdls_set_offchan_mode_cmd_fixed_param));
10235 
10236 	WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr,
10237 				&cmd->peer_macaddr);
10238 	cmd->vdev_id = chan_switch_params->vdev_id;
10239 	cmd->offchan_mode = chan_switch_params->tdls_sw_mode;
10240 	cmd->is_peer_responder = chan_switch_params->is_responder;
10241 	cmd->offchan_num = chan_switch_params->tdls_off_ch;
10242 	cmd->offchan_bw_bitmap = chan_switch_params->tdls_off_ch_bw_offset;
10243 	cmd->offchan_oper_class = chan_switch_params->oper_class;
10244 
10245 	WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"),
10246 		 cmd->peer_macaddr.mac_addr31to0,
10247 		 cmd->peer_macaddr.mac_addr47to32);
10248 
10249 	WMI_LOGD(FL(
10250 		 "vdev_id: %d, off channel mode: %d, off channel Num: %d, "
10251 		 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d"
10252 		  ),
10253 		 cmd->vdev_id,
10254 		 cmd->offchan_mode,
10255 		 cmd->offchan_num,
10256 		 cmd->offchan_bw_bitmap,
10257 		 cmd->is_peer_responder,
10258 		 cmd->offchan_oper_class);
10259 
10260 	wmi_mtrace(WMI_TDLS_SET_OFFCHAN_MODE_CMDID, cmd->vdev_id, 0);
10261 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10262 		WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) {
10263 		WMI_LOGP(FL("failed to send tdls off chan command"));
10264 		wmi_buf_free(wmi_buf);
10265 		return QDF_STATUS_E_FAILURE;
10266 	}
10267 
10268 
10269 	return QDF_STATUS_SUCCESS;
10270 }
10271 
10272 /**
10273  * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev
10274  * @wmi_handle: wmi handle
10275  * @pwmaTdlsparams: TDLS params
10276  *
10277  * Return: 0 for success or error code
10278  */
10279 static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle,
10280 					 void *tdls_param, uint8_t tdls_state)
10281 {
10282 	wmi_tdls_set_state_cmd_fixed_param *cmd;
10283 	wmi_buf_t wmi_buf;
10284 
10285 	struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param;
10286 	uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param);
10287 
10288 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10289 	if (!wmi_buf) {
10290 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
10291 		return QDF_STATUS_E_FAILURE;
10292 	}
10293 	cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf);
10294 	WMITLV_SET_HDR(&cmd->tlv_header,
10295 		  WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param,
10296 		  WMITLV_GET_STRUCT_TLVLEN
10297 		  (wmi_tdls_set_state_cmd_fixed_param));
10298 	cmd->vdev_id = wmi_tdls->vdev_id;
10299 	cmd->state = tdls_state;
10300 	cmd->notification_interval_ms = wmi_tdls->notification_interval_ms;
10301 	cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold;
10302 	cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold;
10303 	cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold;
10304 	cmd->rssi_delta = wmi_tdls->rssi_delta;
10305 	cmd->tdls_options = wmi_tdls->tdls_options;
10306 	cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window;
10307 	cmd->tdls_peer_traffic_response_timeout_ms =
10308 		wmi_tdls->peer_traffic_response_timeout;
10309 	cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask;
10310 	cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time;
10311 	cmd->tdls_puapsd_rx_frame_threshold =
10312 		wmi_tdls->puapsd_rx_frame_threshold;
10313 	cmd->teardown_notification_ms =
10314 		wmi_tdls->teardown_notification_ms;
10315 	cmd->tdls_peer_kickout_threshold =
10316 		wmi_tdls->tdls_peer_kickout_threshold;
10317 
10318 	WMI_LOGD("%s: tdls_state: %d, state: %d, "
10319 		 "notification_interval_ms: %d, "
10320 		 "tx_discovery_threshold: %d, "
10321 		 "tx_teardown_threshold: %d, "
10322 		 "rssi_teardown_threshold: %d, "
10323 		 "rssi_delta: %d, "
10324 		 "tdls_options: 0x%x, "
10325 		 "tdls_peer_traffic_ind_window: %d, "
10326 		 "tdls_peer_traffic_response_timeout: %d, "
10327 		 "tdls_puapsd_mask: 0x%x, "
10328 		 "tdls_puapsd_inactivity_time: %d, "
10329 		 "tdls_puapsd_rx_frame_threshold: %d, "
10330 		 "teardown_notification_ms: %d, "
10331 		 "tdls_peer_kickout_threshold: %d",
10332 		 __func__, tdls_state, cmd->state,
10333 		 cmd->notification_interval_ms,
10334 		 cmd->tx_discovery_threshold,
10335 		 cmd->tx_teardown_threshold,
10336 		 cmd->rssi_teardown_threshold,
10337 		 cmd->rssi_delta,
10338 		 cmd->tdls_options,
10339 		 cmd->tdls_peer_traffic_ind_window,
10340 		 cmd->tdls_peer_traffic_response_timeout_ms,
10341 		 cmd->tdls_puapsd_mask,
10342 		 cmd->tdls_puapsd_inactivity_time_ms,
10343 		 cmd->tdls_puapsd_rx_frame_threshold,
10344 		 cmd->teardown_notification_ms,
10345 		 cmd->tdls_peer_kickout_threshold);
10346 
10347 	wmi_mtrace(WMI_TDLS_SET_STATE_CMDID, cmd->vdev_id, 0);
10348 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10349 				 WMI_TDLS_SET_STATE_CMDID)) {
10350 		WMI_LOGP("%s: failed to send tdls set state command", __func__);
10351 		wmi_buf_free(wmi_buf);
10352 		return QDF_STATUS_E_FAILURE;
10353 	}
10354 	WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id);
10355 
10356 	return QDF_STATUS_SUCCESS;
10357 }
10358 
10359 /**
10360  * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state
10361  * @wmi_handle: wmi handle
10362  * @peerStateParams: TDLS peer state params
10363  *
10364  * Return: QDF_STATUS_SUCCESS for success or error code
10365  */
10366 static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle,
10367 			       struct tdls_peer_state_params *peerStateParams,
10368 				   uint32_t *ch_mhz)
10369 {
10370 	wmi_tdls_peer_update_cmd_fixed_param *cmd;
10371 	wmi_tdls_peer_capabilities *peer_cap;
10372 	wmi_channel *chan_info;
10373 	wmi_buf_t wmi_buf;
10374 	uint8_t *buf_ptr;
10375 	uint32_t i;
10376 	int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) +
10377 		      sizeof(wmi_tdls_peer_capabilities);
10378 
10379 
10380 	len += WMI_TLV_HDR_SIZE +
10381 	       sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen;
10382 
10383 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10384 	if (!wmi_buf) {
10385 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
10386 		return QDF_STATUS_E_FAILURE;
10387 	}
10388 
10389 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
10390 	cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr;
10391 	WMITLV_SET_HDR(&cmd->tlv_header,
10392 		       WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param,
10393 		       WMITLV_GET_STRUCT_TLVLEN
10394 			       (wmi_tdls_peer_update_cmd_fixed_param));
10395 
10396 	cmd->vdev_id = peerStateParams->vdevId;
10397 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr,
10398 				   &cmd->peer_macaddr);
10399 
10400 
10401 	cmd->peer_state = peerStateParams->peerState;
10402 
10403 	WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, "
10404 		 "peer_macaddr.mac_addr31to0: 0x%x, "
10405 		 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d",
10406 		 __func__, cmd->vdev_id, peerStateParams->peerMacAddr,
10407 		 cmd->peer_macaddr.mac_addr31to0,
10408 		 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state);
10409 
10410 	buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param);
10411 	peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr;
10412 	WMITLV_SET_HDR(&peer_cap->tlv_header,
10413 		       WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities,
10414 		       WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities));
10415 
10416 	if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3)
10417 		WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap);
10418 	if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2)
10419 		WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap);
10420 	if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1)
10421 		WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap);
10422 	if (peerStateParams->peerCap.peerUapsdQueue & 0x01)
10423 		WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap);
10424 
10425 	/* Ack and More Data Ack are sent as 0, so no need to set
10426 	 * but fill SP
10427 	 */
10428 	WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap,
10429 				   peerStateParams->peerCap.peerMaxSp);
10430 
10431 	peer_cap->buff_sta_support =
10432 		peerStateParams->peerCap.peerBuffStaSupport;
10433 	peer_cap->off_chan_support =
10434 		peerStateParams->peerCap.peerOffChanSupport;
10435 	peer_cap->peer_curr_operclass =
10436 		peerStateParams->peerCap.peerCurrOperClass;
10437 	/* self curr operclass is not being used and so pass op class for
10438 	 * preferred off chan in it.
10439 	 */
10440 	peer_cap->self_curr_operclass =
10441 		peerStateParams->peerCap.opClassForPrefOffChan;
10442 	peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen;
10443 	peer_cap->peer_operclass_len =
10444 		peerStateParams->peerCap.peerOperClassLen;
10445 
10446 	WMI_LOGD("%s: peer_operclass_len: %d",
10447 		 __func__, peer_cap->peer_operclass_len);
10448 	for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) {
10449 		peer_cap->peer_operclass[i] =
10450 			peerStateParams->peerCap.peerOperClass[i];
10451 		WMI_LOGD("%s: peer_operclass[%d]: %d",
10452 			 __func__, i, peer_cap->peer_operclass[i]);
10453 	}
10454 
10455 	peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder;
10456 	peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum;
10457 	peer_cap->pref_offchan_bw =
10458 		peerStateParams->peerCap.prefOffChanBandwidth;
10459 
10460 	WMI_LOGD
10461 		("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, "
10462 		 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: "
10463 		 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:"
10464 		 " %d, pref_offchan_bw: %d",
10465 		__func__, peer_cap->peer_qos, peer_cap->buff_sta_support,
10466 		peer_cap->off_chan_support, peer_cap->peer_curr_operclass,
10467 		peer_cap->self_curr_operclass, peer_cap->peer_chan_len,
10468 		peer_cap->peer_operclass_len, peer_cap->is_peer_responder,
10469 		peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw);
10470 
10471 	/* next fill variable size array of peer chan info */
10472 	buf_ptr += sizeof(wmi_tdls_peer_capabilities);
10473 	WMITLV_SET_HDR(buf_ptr,
10474 		       WMITLV_TAG_ARRAY_STRUC,
10475 		       sizeof(wmi_channel) *
10476 		       peerStateParams->peerCap.peerChanLen);
10477 	chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE);
10478 
10479 	for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) {
10480 		WMITLV_SET_HDR(&chan_info->tlv_header,
10481 			       WMITLV_TAG_STRUC_wmi_channel,
10482 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
10483 		chan_info->mhz = ch_mhz[i];
10484 		chan_info->band_center_freq1 = chan_info->mhz;
10485 		chan_info->band_center_freq2 = 0;
10486 
10487 		WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz);
10488 
10489 		if (peerStateParams->peerCap.peerChan[i].dfsSet) {
10490 			WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE);
10491 			WMI_LOGI("chan[%d] DFS[%d]\n",
10492 				 peerStateParams->peerCap.peerChan[i].chanId,
10493 				 peerStateParams->peerCap.peerChan[i].dfsSet);
10494 		}
10495 
10496 		if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ)
10497 			WMI_SET_CHANNEL_MODE(chan_info, MODE_11G);
10498 		else
10499 			WMI_SET_CHANNEL_MODE(chan_info, MODE_11A);
10500 
10501 		WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
10502 					     peerStateParams->peerCap.
10503 					     peerChan[i].pwr);
10504 
10505 		WMI_SET_CHANNEL_REG_POWER(chan_info,
10506 					  peerStateParams->peerCap.peerChan[i].
10507 					  pwr);
10508 		WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz,
10509 			 peerStateParams->peerCap.peerChan[i].pwr);
10510 
10511 		chan_info++;
10512 	}
10513 
10514 	wmi_mtrace(WMI_TDLS_PEER_UPDATE_CMDID, cmd->vdev_id, 0);
10515 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10516 				 WMI_TDLS_PEER_UPDATE_CMDID)) {
10517 		WMI_LOGE("%s: failed to send tdls peer update state command",
10518 			 __func__);
10519 		wmi_buf_free(wmi_buf);
10520 		return QDF_STATUS_E_FAILURE;
10521 	}
10522 
10523 
10524 	return QDF_STATUS_SUCCESS;
10525 }
10526 
10527 /*
10528  * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware
10529  * @wmi_handle:    Pointer to WMi handle
10530  * @ie_data:       Pointer for ie data
10531  *
10532  * This function sends IE information to firmware
10533  *
10534  * Return: QDF_STATUS_SUCCESS for success otherwise failure
10535  *
10536  */
10537 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle,
10538 				   struct vdev_ie_info_param *ie_info)
10539 {
10540 	wmi_vdev_set_ie_cmd_fixed_param *cmd;
10541 	wmi_buf_t buf;
10542 	uint8_t *buf_ptr;
10543 	uint32_t len, ie_len_aligned;
10544 	QDF_STATUS ret;
10545 
10546 
10547 	ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t));
10548 	/* Allocate memory for the WMI command */
10549 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned;
10550 
10551 	buf = wmi_buf_alloc(wmi_handle, len);
10552 	if (!buf) {
10553 		WMI_LOGE(FL("wmi_buf_alloc failed"));
10554 		return QDF_STATUS_E_NOMEM;
10555 	}
10556 
10557 	buf_ptr = wmi_buf_data(buf);
10558 	qdf_mem_zero(buf_ptr, len);
10559 
10560 	/* Populate the WMI command */
10561 	cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr;
10562 
10563 	WMITLV_SET_HDR(&cmd->tlv_header,
10564 		       WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param,
10565 		       WMITLV_GET_STRUCT_TLVLEN(
10566 			wmi_vdev_set_ie_cmd_fixed_param));
10567 	cmd->vdev_id = ie_info->vdev_id;
10568 	cmd->ie_id = ie_info->ie_id;
10569 	cmd->ie_len = ie_info->length;
10570 	cmd->band = ie_info->band;
10571 
10572 	WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id,
10573 		 ie_info->length, ie_info->vdev_id);
10574 
10575 	buf_ptr += sizeof(*cmd);
10576 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
10577 	buf_ptr += WMI_TLV_HDR_SIZE;
10578 
10579 	qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len);
10580 
10581 	wmi_mtrace(WMI_VDEV_SET_IE_CMDID, cmd->vdev_id, 0);
10582 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
10583 				   WMI_VDEV_SET_IE_CMDID);
10584 	if (QDF_IS_STATUS_ERROR(ret)) {
10585 		WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret);
10586 		wmi_buf_free(buf);
10587 	}
10588 
10589 	return ret;
10590 }
10591 
10592 /**
10593  *  send_smart_ant_enable_cmd_tlv() - WMI smart ant enable function
10594  *
10595  *  @param wmi_handle  : handle to WMI.
10596  *  @param param       : pointer to antenna param
10597  *
10598  *  This function sends smart antenna enable command to FW
10599  *
10600  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10601  */
10602 static QDF_STATUS send_smart_ant_enable_cmd_tlv(wmi_unified_t wmi_handle,
10603 				struct smart_ant_enable_params *param)
10604 {
10605 	/* Send WMI COMMAND to Enable */
10606 	wmi_pdev_smart_ant_enable_cmd_fixed_param *cmd;
10607 	wmi_pdev_smart_ant_gpio_handle *gpio_param;
10608 	wmi_buf_t buf;
10609 	uint8_t *buf_ptr;
10610 	int len = 0;
10611 	QDF_STATUS ret;
10612 	int loop = 0;
10613 
10614 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
10615 	len += WMI_HAL_MAX_SANTENNA * sizeof(wmi_pdev_smart_ant_gpio_handle);
10616 	buf = wmi_buf_alloc(wmi_handle, len);
10617 
10618 	if (!buf) {
10619 			WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
10620 			return QDF_STATUS_E_NOMEM;
10621 		}
10622 
10623 	buf_ptr = wmi_buf_data(buf);
10624 	qdf_mem_zero(buf_ptr, len);
10625 	cmd = (wmi_pdev_smart_ant_enable_cmd_fixed_param *)buf_ptr;
10626 
10627 	WMITLV_SET_HDR(&cmd->tlv_header,
10628 		WMITLV_TAG_STRUC_wmi_pdev_smart_ant_enable_cmd_fixed_param,
10629 		WMITLV_GET_STRUCT_TLVLEN(
10630 				wmi_pdev_smart_ant_enable_cmd_fixed_param));
10631 
10632 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10633 								param->pdev_id);
10634 	cmd->enable = param->enable;
10635 	cmd->mode = param->mode;
10636 	cmd->rx_antenna = param->rx_antenna;
10637 	cmd->tx_default_antenna = param->rx_antenna;
10638 
10639 	/* TLV indicating array of structures to follow */
10640 	buf_ptr += sizeof(wmi_pdev_smart_ant_enable_cmd_fixed_param);
10641 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
10642 		       WMI_HAL_MAX_SANTENNA *
10643 		       sizeof(wmi_pdev_smart_ant_gpio_handle));
10644 
10645 	buf_ptr += WMI_TLV_HDR_SIZE;
10646 	gpio_param = (wmi_pdev_smart_ant_gpio_handle *)buf_ptr;
10647 
10648 	for (loop = 0; loop < WMI_HAL_MAX_SANTENNA; loop++) {
10649 		WMITLV_SET_HDR(&gpio_param->tlv_header,
10650 			       WMITLV_TAG_STRUC_wmi_pdev_smart_ant_gpio_handle,
10651 			       WMITLV_GET_STRUCT_TLVLEN(
10652 			       wmi_pdev_smart_ant_gpio_handle));
10653 		if (param->mode == SMART_ANT_MODE_SERIAL) {
10654 			if (loop < WMI_HOST_MAX_SERIAL_ANTENNA) {
10655 				gpio_param->gpio_pin = param->gpio_pin[loop];
10656 				gpio_param->gpio_func = param->gpio_func[loop];
10657 			} else {
10658 				gpio_param->gpio_pin = 0;
10659 				gpio_param->gpio_func = 0;
10660 			}
10661 		} else if (param->mode == SMART_ANT_MODE_PARALLEL) {
10662 			gpio_param->gpio_pin = param->gpio_pin[loop];
10663 			gpio_param->gpio_func = param->gpio_func[loop];
10664 		}
10665 		/* Setting it to 0 for now */
10666 		gpio_param->pdev_id =
10667 			wmi_handle->ops->convert_pdev_id_host_to_target(
10668 								param->pdev_id);
10669 		gpio_param++;
10670 	}
10671 
10672 	wmi_mtrace(WMI_PDEV_SMART_ANT_ENABLE_CMDID, NO_SESSION, 0);
10673 	ret = wmi_unified_cmd_send(wmi_handle,
10674 				buf,
10675 				len,
10676 				WMI_PDEV_SMART_ANT_ENABLE_CMDID);
10677 
10678 	if (ret != 0) {
10679 		WMI_LOGE(" %s :WMI Failed\n", __func__);
10680 		WMI_LOGE("enable:%d mode:%d  rx_antenna: 0x%08x PINS: [%d %d %d %d] Func[%d %d %d %d] cmdstatus=%d\n",
10681 			 cmd->enable,
10682 			 cmd->mode,
10683 			 cmd->rx_antenna,
10684 			 param->gpio_pin[0], param->gpio_pin[1],
10685 			 param->gpio_pin[2], param->gpio_pin[3],
10686 			 param->gpio_func[0], param->gpio_func[1],
10687 			 param->gpio_func[2], param->gpio_func[3],
10688 			 ret);
10689 		wmi_buf_free(buf);
10690 	}
10691 
10692 	return ret;
10693 }
10694 
10695 /**
10696  *  send_smart_ant_set_rx_ant_cmd_tlv() - WMI set rx antenna function
10697  *
10698  *  @param wmi_handle     : handle to WMI.
10699  *  @param param          : pointer to rx antenna param
10700  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10701  */
10702 static QDF_STATUS send_smart_ant_set_rx_ant_cmd_tlv(wmi_unified_t wmi_handle,
10703 				struct smart_ant_rx_ant_params *param)
10704 {
10705 	wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *cmd;
10706 	wmi_buf_t buf;
10707 	uint8_t *buf_ptr;
10708 	uint32_t len;
10709 	QDF_STATUS ret;
10710 
10711 	len = sizeof(*cmd);
10712 	buf = wmi_buf_alloc(wmi_handle, len);
10713 	WMI_LOGD("%s:\n", __func__);
10714 	if (!buf) {
10715 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
10716 		return QDF_STATUS_E_NOMEM;
10717 	}
10718 
10719 	buf_ptr = wmi_buf_data(buf);
10720 	cmd = (wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *)buf_ptr;
10721 	WMITLV_SET_HDR(&cmd->tlv_header,
10722 	    WMITLV_TAG_STRUC_wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param,
10723 	    WMITLV_GET_STRUCT_TLVLEN(
10724 		wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param));
10725 	cmd->rx_antenna = param->antenna;
10726 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10727 								param->pdev_id);
10728 
10729 	wmi_mtrace(WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID, NO_SESSION, 0);
10730 	ret = wmi_unified_cmd_send(wmi_handle,
10731 				buf,
10732 				len,
10733 				WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID);
10734 
10735 	if (ret != 0) {
10736 		WMI_LOGE(" %s :WMI Failed\n", __func__);
10737 		WMI_LOGE("%s: rx_antenna: 0x%08x cmdstatus=%d\n",
10738 			 __func__,
10739 			 cmd->rx_antenna,
10740 			 ret);
10741 		wmi_buf_free(buf);
10742 	}
10743 
10744 	return ret;
10745 }
10746 
10747 /**
10748  * send_set_ctl_table_cmd_tlv() - send ctl table cmd to fw
10749  * @wmi_handle: wmi handle
10750  * @param: pointer to hold ctl table param
10751  *
10752  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10753  */
10754 static QDF_STATUS
10755 send_set_ctl_table_cmd_tlv(wmi_unified_t wmi_handle,
10756 			   struct ctl_table_params *param)
10757 {
10758 	uint16_t len, ctl_tlv_len;
10759 	uint8_t *buf_ptr;
10760 	wmi_buf_t buf;
10761 	wmi_pdev_set_ctl_table_cmd_fixed_param *cmd;
10762 	uint32_t *ctl_array;
10763 
10764 	if (!param->ctl_array)
10765 		return QDF_STATUS_E_FAILURE;
10766 
10767 	ctl_tlv_len = WMI_TLV_HDR_SIZE +
10768 		roundup(param->ctl_cmd_len, sizeof(uint32_t));
10769 	len = sizeof(*cmd) + ctl_tlv_len;
10770 
10771 	buf = wmi_buf_alloc(wmi_handle, len);
10772 	if (!buf) {
10773 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
10774 		return QDF_STATUS_E_FAILURE;
10775 	}
10776 
10777 	buf_ptr = wmi_buf_data(buf);
10778 	qdf_mem_zero(buf_ptr, len);
10779 
10780 	cmd = (wmi_pdev_set_ctl_table_cmd_fixed_param *)buf_ptr;
10781 
10782 	WMITLV_SET_HDR(&cmd->tlv_header,
10783 		       WMITLV_TAG_STRUC_wmi_pdev_set_ctl_table_cmd_fixed_param,
10784 		       WMITLV_GET_STRUCT_TLVLEN(
10785 				wmi_pdev_set_ctl_table_cmd_fixed_param));
10786 	cmd->ctl_len = param->ctl_cmd_len;
10787 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10788 								param->pdev_id);
10789 
10790 	buf_ptr += sizeof(*cmd);
10791 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
10792 		       (cmd->ctl_len));
10793 	buf_ptr += WMI_TLV_HDR_SIZE;
10794 	ctl_array = (uint32_t *)buf_ptr;
10795 
10796 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[0], &param->ctl_band,
10797 					sizeof(param->ctl_band));
10798 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[1], param->ctl_array,
10799 					param->ctl_cmd_len -
10800 					sizeof(param->ctl_band));
10801 
10802 	wmi_mtrace(WMI_PDEV_SET_CTL_TABLE_CMDID, NO_SESSION, 0);
10803 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10804 				 WMI_PDEV_SET_CTL_TABLE_CMDID)) {
10805 		WMI_LOGE("%s:Failed to send command\n", __func__);
10806 		wmi_buf_free(buf);
10807 		return QDF_STATUS_E_FAILURE;
10808 	}
10809 
10810 	return QDF_STATUS_SUCCESS;
10811 }
10812 
10813 /**
10814  * send_set_mimogain_table_cmd_tlv() - send mimogain table cmd to fw
10815  * @wmi_handle: wmi handle
10816  * @param: pointer to hold mimogain table param
10817  *
10818  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10819  */
10820 static QDF_STATUS
10821 send_set_mimogain_table_cmd_tlv(wmi_unified_t wmi_handle,
10822 				struct mimogain_table_params *param)
10823 {
10824 	uint16_t len, table_tlv_len;
10825 	wmi_buf_t buf;
10826 	uint8_t *buf_ptr;
10827 	wmi_pdev_set_mimogain_table_cmd_fixed_param *cmd;
10828 	uint32_t *gain_table;
10829 
10830 	if (!param->array_gain)
10831 		return QDF_STATUS_E_FAILURE;
10832 
10833 	/* len must be multiple of a single array gain table */
10834 	if (param->tbl_len %
10835 	    ((WMI_HOST_TX_NUM_CHAIN-1) * WMI_HOST_TPC_REGINDEX_MAX *
10836 	     WMI_HOST_ARRAY_GAIN_NUM_STREAMS) != 0) {
10837 		WMI_LOGE("Array gain table len not correct\n");
10838 		return QDF_STATUS_E_FAILURE;
10839 	}
10840 
10841 	table_tlv_len = WMI_TLV_HDR_SIZE +
10842 		roundup(param->tbl_len, sizeof(uint32_t));
10843 	len = sizeof(*cmd) + table_tlv_len;
10844 
10845 	buf = wmi_buf_alloc(wmi_handle, len);
10846 	if (!buf) {
10847 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
10848 		return QDF_STATUS_E_FAILURE;
10849 	}
10850 
10851 	buf_ptr = wmi_buf_data(buf);
10852 	qdf_mem_zero(buf_ptr, len);
10853 
10854 	cmd = (wmi_pdev_set_mimogain_table_cmd_fixed_param *)buf_ptr;
10855 
10856 	WMITLV_SET_HDR(&cmd->tlv_header,
10857 		WMITLV_TAG_STRUC_wmi_pdev_set_mimogain_table_cmd_fixed_param,
10858 		WMITLV_GET_STRUCT_TLVLEN(
10859 		       wmi_pdev_set_mimogain_table_cmd_fixed_param));
10860 
10861 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10862 								param->pdev_id);
10863 	WMI_MIMOGAIN_ARRAY_GAIN_LEN_SET(cmd->mimogain_info, param->tbl_len);
10864 	WMI_MIMOGAIN_MULTI_CHAIN_BYPASS_SET(cmd->mimogain_info,
10865 					    param->multichain_gain_bypass);
10866 
10867 	buf_ptr += sizeof(*cmd);
10868 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
10869 		       (param->tbl_len));
10870 	buf_ptr += WMI_TLV_HDR_SIZE;
10871 	gain_table = (uint32_t *)buf_ptr;
10872 
10873 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(gain_table,
10874 					param->array_gain,
10875 					param->tbl_len);
10876 
10877 	wmi_mtrace(WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID, NO_SESSION, 0);
10878 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10879 				 WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID)) {
10880 		return QDF_STATUS_E_FAILURE;
10881 	}
10882 
10883 	return QDF_STATUS_SUCCESS;
10884 }
10885 
10886 /**
10887  * enum packet_power_tlv_flags: target defined
10888  * packet power rate flags for TLV
10889  * @WMI_TLV_FLAG_ONE_CHAIN: one chain
10890  * @WMI_TLV_FLAG_TWO_CHAIN: two chain
10891  * @WMI_TLV_FLAG_THREE_CHAIN: three chain
10892  * @WMI_TLV_FLAG_FOUR_CHAIN: four chain
10893  * @WMI_TLV_FLAG_FIVE_CHAIN: five chain
10894  * @WMI_TLV_FLAG_SIX_CHAIN: six chain
10895  * @WMI_TLV_FLAG_SEVEN_CHAIN: seven chain
10896  * @WMI_TLV_FLAG_EIGHT_CHAIN:eight chain
10897  * @WMI_TLV_FLAG_STBC: STBC is set
10898  * @WMI_TLV_FLAG_40MHZ: 40MHz chan width
10899  * @WMI_TLV_FLAG_80MHZ: 80MHz chan width
10900  * @WMI_TLV_FLAG_160MHZ: 160MHz chan width
10901  * @WMI_TLV_FLAG_TXBF: Tx Bf enabled
10902  * @WMI_TLV_FLAG_RTSENA: RTS enabled
10903  * @WMI_TLV_FLAG_CTSENA: CTS enabled
10904  * @WMI_TLV_FLAG_LDPC: LDPC is set
10905  * @WMI_TLV_FLAG_SGI: Short gaurd interval
10906  * @WMI_TLV_FLAG_SU: SU Data
10907  * @WMI_TLV_FLAG_DL_MU_MIMO_AC: DL AC MU data
10908  * @WMI_TLV_FLAG_DL_MU_MIMO_AX: DL AX MU data
10909  * @WMI_TLV_FLAG_DL_OFDMA: DL OFDMA data
10910  * @WMI_TLV_FLAG_UL_OFDMA: UL OFDMA data
10911  * @WMI_TLV_FLAG_UL_MU_MIMO: UL MU data
10912  *
10913  * @WMI_TLV_FLAG_BW_MASK: bandwidth mask
10914  * @WMI_TLV_FLAG_BW_SHIFT: bandwidth shift
10915  * @WMI_TLV_FLAG_SU_MU_OFDMA_MASK: su/mu/ofdma mask
10916  * @WMI_TLV_FLAG_SU_MU_OFDMA_shift: su/mu/ofdma shift
10917  */
10918 enum packet_power_tlv_flags {
10919 	WMI_TLV_FLAG_ONE_CHAIN         = 0x00000001,
10920 	WMI_TLV_FLAG_TWO_CHAIN         = 0x00000003,
10921 	WMI_TLV_FLAG_THREE_CHAIN       = 0x00000007,
10922 	WMI_TLV_FLAG_FOUR_CHAIN        = 0x0000000F,
10923 	WMI_TLV_FLAG_FIVE_CHAIN        = 0x0000001F,
10924 	WMI_TLV_FLAG_SIX_CHAIN         = 0x0000003F,
10925 	WMI_TLV_FLAG_SEVEN_CHAIN       = 0x0000007F,
10926 	WMI_TLV_FLAG_EIGHT_CHAIN       = 0x0000008F,
10927 	WMI_TLV_FLAG_STBC              = 0x00000100,
10928 	WMI_TLV_FLAG_40MHZ             = 0x00000200,
10929 	WMI_TLV_FLAG_80MHZ             = 0x00000300,
10930 	WMI_TLV_FLAG_160MHZ            = 0x00000400,
10931 	WMI_TLV_FLAG_TXBF              = 0x00000800,
10932 	WMI_TLV_FLAG_RTSENA            = 0x00001000,
10933 	WMI_TLV_FLAG_CTSENA            = 0x00002000,
10934 	WMI_TLV_FLAG_LDPC              = 0x00004000,
10935 	WMI_TLV_FLAG_SGI               = 0x00008000,
10936 	WMI_TLV_FLAG_SU                = 0x00100000,
10937 	WMI_TLV_FLAG_DL_MU_MIMO_AC     = 0x00200000,
10938 	WMI_TLV_FLAG_DL_MU_MIMO_AX     = 0x00300000,
10939 	WMI_TLV_FLAG_DL_OFDMA          = 0x00400000,
10940 	WMI_TLV_FLAG_UL_OFDMA          = 0x00500000,
10941 	WMI_TLV_FLAG_UL_MU_MIMO        = 0x00600000,
10942 
10943 	WMI_TLV_FLAG_CHAIN_MASK        = 0xff,
10944 	WMI_TLV_FLAG_BW_MASK           = 0x3,
10945 	WMI_TLV_FLAG_BW_SHIFT          = 9,
10946 	WMI_TLV_FLAG_SU_MU_OFDMA_MASK  = 0x7,
10947 	WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT = 20,
10948 };
10949 
10950 /**
10951  * convert_to_power_info_rate_flags() - convert packet_power_info_params
10952  * to FW understandable format
10953  * @param: pointer to hold packet power info param
10954  *
10955  * @return FW understandable 32 bit rate flags
10956  */
10957 static uint32_t
10958 convert_to_power_info_rate_flags(struct packet_power_info_params *param)
10959 {
10960 	uint32_t rateflags = 0;
10961 
10962 	if (param->chainmask)
10963 		rateflags |=
10964 			(param->chainmask & WMI_TLV_FLAG_CHAIN_MASK);
10965 	if (param->chan_width)
10966 		rateflags |=
10967 			((param->chan_width & WMI_TLV_FLAG_BW_MASK)
10968 			 << WMI_TLV_FLAG_BW_SHIFT);
10969 	if (param->su_mu_ofdma)
10970 		rateflags |=
10971 			((param->su_mu_ofdma & WMI_TLV_FLAG_SU_MU_OFDMA_MASK)
10972 			 << WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT);
10973 	if (param->rate_flags & WMI_HOST_FLAG_STBC)
10974 		rateflags |= WMI_TLV_FLAG_STBC;
10975 	if (param->rate_flags & WMI_HOST_FLAG_LDPC)
10976 		rateflags |= WMI_TLV_FLAG_LDPC;
10977 	if (param->rate_flags & WMI_HOST_FLAG_TXBF)
10978 		rateflags |= WMI_TLV_FLAG_TXBF;
10979 	if (param->rate_flags & WMI_HOST_FLAG_RTSENA)
10980 		rateflags |= WMI_TLV_FLAG_RTSENA;
10981 	if (param->rate_flags & WMI_HOST_FLAG_CTSENA)
10982 		rateflags |= WMI_TLV_FLAG_CTSENA;
10983 	if (param->rate_flags & WMI_HOST_FLAG_SGI)
10984 		rateflags |= WMI_TLV_FLAG_SGI;
10985 
10986 	return rateflags;
10987 }
10988 
10989 /**
10990  * send_packet_power_info_get_cmd_tlv() - send request to get packet power
10991  * info to fw
10992  * @wmi_handle: wmi handle
10993  * @param: pointer to hold packet power info param
10994  *
10995  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10996  */
10997 static QDF_STATUS
10998 send_packet_power_info_get_cmd_tlv(wmi_unified_t wmi_handle,
10999 				   struct packet_power_info_params *param)
11000 {
11001 	wmi_pdev_get_tpc_cmd_fixed_param *cmd;
11002 	wmi_buf_t wmibuf;
11003 	uint8_t *buf_ptr;
11004 	u_int32_t len = sizeof(wmi_pdev_get_tpc_cmd_fixed_param);
11005 
11006 	wmibuf = wmi_buf_alloc(wmi_handle, len);
11007 	if (wmibuf == NULL)
11008 		return QDF_STATUS_E_NOMEM;
11009 
11010 	buf_ptr = (uint8_t *)wmi_buf_data(wmibuf);
11011 
11012 	cmd = (wmi_pdev_get_tpc_cmd_fixed_param *)buf_ptr;
11013 	WMITLV_SET_HDR(&cmd->tlv_header,
11014 		       WMITLV_TAG_STRUC_wmi_pdev_get_tpc_cmd_fixed_param,
11015 		       WMITLV_GET_STRUCT_TLVLEN(
11016 				wmi_pdev_get_tpc_cmd_fixed_param));
11017 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
11018 								param->pdev_id);
11019 	cmd->rate_flags = convert_to_power_info_rate_flags(param);
11020 	cmd->nss = param->nss;
11021 	cmd->preamble = param->preamble;
11022 	cmd->hw_rate = param->hw_rate;
11023 
11024 	WMI_LOGI("%s[%d] commandID %d, wmi_pdev_get_tpc_cmd=0x%x,"
11025 		"rate_flags: 0x%x, nss: %d, preamble: %d, hw_rate: %d\n",
11026 		__func__, __LINE__, WMI_PDEV_GET_TPC_CMDID, *((u_int32_t *)cmd),
11027 		cmd->rate_flags, cmd->nss, cmd->preamble, cmd->hw_rate);
11028 
11029 	wmi_mtrace(WMI_PDEV_GET_TPC_CMDID, NO_SESSION, 0);
11030 	if (wmi_unified_cmd_send(wmi_handle, wmibuf, len,
11031 				 WMI_PDEV_GET_TPC_CMDID)) {
11032 			WMI_LOGE(FL("Failed to get tpc command\n"));
11033 			wmi_buf_free(wmibuf);
11034 			return QDF_STATUS_E_FAILURE;
11035 	}
11036 
11037 	return QDF_STATUS_SUCCESS;
11038 }
11039 
11040 /**
11041  * send_vdev_config_ratemask_cmd_tlv() - config ratemask param in fw
11042  * @wmi_handle: wmi handle
11043  * @param: pointer to hold config ratemask params
11044  *
11045  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11046  */
11047 static QDF_STATUS send_vdev_config_ratemask_cmd_tlv(wmi_unified_t wmi_handle,
11048 					struct config_ratemask_params *param)
11049 {
11050 	wmi_vdev_config_ratemask_cmd_fixed_param *cmd;
11051 	wmi_buf_t buf;
11052 	int32_t len = sizeof(*cmd);
11053 
11054 	buf = wmi_buf_alloc(wmi_handle, len);
11055 	if (!buf) {
11056 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11057 		return QDF_STATUS_E_FAILURE;
11058 	}
11059 	cmd = (wmi_vdev_config_ratemask_cmd_fixed_param *)wmi_buf_data(buf);
11060 	WMITLV_SET_HDR(&cmd->tlv_header,
11061 		       WMITLV_TAG_STRUC_wmi_vdev_config_ratemask_fixed_param,
11062 		       WMITLV_GET_STRUCT_TLVLEN(
11063 				wmi_vdev_config_ratemask_cmd_fixed_param));
11064 	cmd->vdev_id = param->vdev_id;
11065 	cmd->type = param->type;
11066 	cmd->mask_lower32 = param->lower32;
11067 	cmd->mask_higher32 = param->higher32;
11068 	cmd->mask_lower32_2 = param->lower32_2;
11069 	WMI_LOGI("Setting vdev ratemask vdev id = 0x%X, type = 0x%X"
11070 		"mask_l32 = 0x%X mask_h32 = 0x%X mask_l32_2 = 0x%X\n",
11071 		param->vdev_id, param->type, param->lower32,
11072 		param->higher32, param->lower32_2);
11073 
11074 	wmi_mtrace(WMI_VDEV_RATEMASK_CMDID, cmd->vdev_id, 0);
11075 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11076 				 WMI_VDEV_RATEMASK_CMDID)) {
11077 			WMI_LOGE("Seting vdev ratemask failed\n");
11078 			wmi_buf_free(buf);
11079 			return QDF_STATUS_E_FAILURE;
11080 	}
11081 
11082 	return QDF_STATUS_SUCCESS;
11083 }
11084 
11085 /**
11086  * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs
11087  * @param: param sent from the host side
11088  * @cmd: param to be sent to the fw side
11089  */
11090 static inline void copy_custom_aggr_bitmap(
11091 		struct set_custom_aggr_size_params *param,
11092 		wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd)
11093 {
11094 	WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap,
11095 				    param->ac);
11096 	WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap,
11097 				      param->aggr_type);
11098 	WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap,
11099 					   param->tx_aggr_size_disable);
11100 	WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap,
11101 					   param->rx_aggr_size_disable);
11102 	WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap,
11103 				     param->tx_ac_enable);
11104 }
11105 
11106 /**
11107  * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw
11108  * @wmi_handle: wmi handle
11109  * @param: pointer to hold custom aggr size params
11110  *
11111  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11112  */
11113 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv(
11114 			wmi_unified_t wmi_handle,
11115 			struct set_custom_aggr_size_params *param)
11116 {
11117 	wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd;
11118 	wmi_buf_t buf;
11119 	int32_t len = sizeof(*cmd);
11120 
11121 	buf = wmi_buf_alloc(wmi_handle, len);
11122 	if (!buf) {
11123 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11124 		return QDF_STATUS_E_FAILURE;
11125 	}
11126 	cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *)
11127 		wmi_buf_data(buf);
11128 	WMITLV_SET_HDR(&cmd->tlv_header,
11129 		WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param,
11130 		WMITLV_GET_STRUCT_TLVLEN(
11131 		wmi_vdev_set_custom_aggr_size_cmd_fixed_param));
11132 	cmd->vdev_id = param->vdev_id;
11133 	cmd->tx_aggr_size = param->tx_aggr_size;
11134 	cmd->rx_aggr_size = param->rx_aggr_size;
11135 	copy_custom_aggr_bitmap(param, cmd);
11136 
11137 	WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X "
11138 		"rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X "
11139 		"tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X "
11140 		"tx_ac_enable=0x%X\n",
11141 		param->vdev_id, param->tx_aggr_size, param->rx_aggr_size,
11142 		param->ac, param->aggr_type, param->tx_aggr_size_disable,
11143 		param->rx_aggr_size_disable, param->tx_ac_enable);
11144 
11145 	wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0);
11146 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11147 				 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) {
11148 		WMI_LOGE("Seting custom aggregation size failed\n");
11149 		wmi_buf_free(buf);
11150 		return QDF_STATUS_E_FAILURE;
11151 	}
11152 
11153 	return QDF_STATUS_SUCCESS;
11154 }
11155 
11156 /**
11157  *  send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold
11158  *  @param wmi_handle  : handle to WMI.
11159  *  @param param       : pointer to tx antenna param
11160  *
11161  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11162  */
11163 
11164 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle,
11165 				struct set_qdepth_thresh_params *param)
11166 {
11167 	wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd;
11168 	wmi_msduq_qdepth_thresh_update *cmd_update;
11169 	wmi_buf_t buf;
11170 	int32_t len = 0;
11171 	int i;
11172 	uint8_t *buf_ptr;
11173 	QDF_STATUS ret;
11174 
11175 	if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) {
11176 		WMI_LOGE("%s: Invalid Update Count!\n", __func__);
11177 		return QDF_STATUS_E_INVAL;
11178 	}
11179 
11180 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11181 	len += (sizeof(wmi_msduq_qdepth_thresh_update) *
11182 			param->num_of_msduq_updates);
11183 	buf = wmi_buf_alloc(wmi_handle, len);
11184 
11185 	if (!buf) {
11186 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11187 		return QDF_STATUS_E_NOMEM;
11188 	}
11189 
11190 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11191 	cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *)
11192 								buf_ptr;
11193 
11194 	WMITLV_SET_HDR(&cmd->tlv_header,
11195 	WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param
11196 	 , WMITLV_GET_STRUCT_TLVLEN(
11197 		wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param));
11198 
11199 	cmd->pdev_id =
11200 		wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id);
11201 	cmd->vdev_id = param->vdev_id;
11202 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address);
11203 	cmd->num_of_msduq_updates = param->num_of_msduq_updates;
11204 
11205 	buf_ptr += sizeof(
11206 		wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param);
11207 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11208 			param->num_of_msduq_updates *
11209 			sizeof(wmi_msduq_qdepth_thresh_update));
11210 	buf_ptr += WMI_TLV_HDR_SIZE;
11211 	cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr;
11212 
11213 	for (i = 0; i < cmd->num_of_msduq_updates; i++) {
11214 		WMITLV_SET_HDR(&cmd_update->tlv_header,
11215 		    WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update,
11216 		    WMITLV_GET_STRUCT_TLVLEN(
11217 				wmi_msduq_qdepth_thresh_update));
11218 		cmd_update->tid_num = param->update_params[i].tid_num;
11219 		cmd_update->msduq_update_mask =
11220 				param->update_params[i].msduq_update_mask;
11221 		cmd_update->qdepth_thresh_value =
11222 				param->update_params[i].qdepth_thresh_value;
11223 		WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X "
11224 			 "mac_addr_upper4=%X, mac_addr_lower2:%X,"
11225 			 " update mask=0x%X thresh val=0x%X\n",
11226 			 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num,
11227 			 cmd->peer_mac_address.mac_addr31to0,
11228 			 cmd->peer_mac_address.mac_addr47to32,
11229 			 cmd_update->msduq_update_mask,
11230 			 cmd_update->qdepth_thresh_value);
11231 		cmd_update++;
11232 	}
11233 
11234 	wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID,
11235 		   cmd->vdev_id, 0);
11236 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
11237 				WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID);
11238 
11239 	if (ret != 0) {
11240 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11241 		wmi_buf_free(buf);
11242 	}
11243 
11244 	return ret;
11245 }
11246 
11247 /**
11248  * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw
11249  * @wmi_handle: wmi handle
11250  * @param: pointer to hold vap dscp tid map param
11251  *
11252  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11253  */
11254 static QDF_STATUS
11255 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle,
11256 				  struct vap_dscp_tid_map_params *param)
11257 {
11258 	wmi_buf_t buf;
11259 	wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd;
11260 	int32_t len = sizeof(*cmd);
11261 
11262 	buf = wmi_buf_alloc(wmi_handle, len);
11263 	if (!buf) {
11264 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11265 		return QDF_STATUS_E_FAILURE;
11266 	}
11267 
11268 	cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf);
11269 	qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map,
11270 		     sizeof(uint32_t) * WMI_DSCP_MAP_MAX);
11271 
11272 	cmd->vdev_id = param->vdev_id;
11273 	cmd->enable_override = 0;
11274 
11275 	WMI_LOGI("Setting dscp for vap id: %d\n", cmd->vdev_id);
11276 	wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0);
11277 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11278 				 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) {
11279 			WMI_LOGE("Failed to set dscp cmd\n");
11280 			wmi_buf_free(buf);
11281 			return QDF_STATUS_E_FAILURE;
11282 	}
11283 
11284 	return QDF_STATUS_SUCCESS;
11285 }
11286 
11287 /**
11288  * send_vdev_set_neighbour_rx_cmd_tlv() - set neighbour rx param in fw
11289  * @wmi_handle: wmi handle
11290  * @macaddr: vdev mac address
11291  * @param: pointer to hold neigbour rx param
11292  *
11293  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11294  */
11295 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle,
11296 					uint8_t macaddr[IEEE80211_ADDR_LEN],
11297 					struct set_neighbour_rx_params *param)
11298 {
11299 	wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd;
11300 	wmi_buf_t buf;
11301 	int32_t len = sizeof(*cmd);
11302 
11303 	buf = wmi_buf_alloc(wmi_handle, len);
11304 	if (!buf) {
11305 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11306 		return QDF_STATUS_E_FAILURE;
11307 	}
11308 	cmd = (wmi_vdev_filter_nrp_config_cmd_fixed_param *)wmi_buf_data(buf);
11309 	WMITLV_SET_HDR(&cmd->tlv_header,
11310 		WMITLV_TAG_STRUC_wmi_vdev_filter_nrp_config_cmd_fixed_param,
11311 		WMITLV_GET_STRUCT_TLVLEN(
11312 			wmi_vdev_filter_nrp_config_cmd_fixed_param));
11313 	cmd->vdev_id = param->vdev_id;
11314 	cmd->bssid_idx = param->idx;
11315 	cmd->action = param->action;
11316 	cmd->type = param->type;
11317 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->addr);
11318 	cmd->flag = 0;
11319 
11320 	wmi_mtrace(WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID, cmd->vdev_id, 0);
11321 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11322 				 WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID)) {
11323 			WMI_LOGE("Failed to set neighbour rx param\n");
11324 			wmi_buf_free(buf);
11325 			return QDF_STATUS_E_FAILURE;
11326 	}
11327 
11328 	return QDF_STATUS_SUCCESS;
11329 }
11330 
11331 /**
11332  *  send_smart_ant_set_tx_ant_cmd_tlv() - WMI set tx antenna function
11333  *  @param wmi_handle  : handle to WMI.
11334  *  @param macaddr     : vdev mac address
11335  *  @param param       : pointer to tx antenna param
11336  *
11337  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11338  */
11339 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle,
11340 				uint8_t macaddr[IEEE80211_ADDR_LEN],
11341 				struct smart_ant_tx_ant_params *param)
11342 {
11343 	wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd;
11344 	wmi_peer_smart_ant_set_tx_antenna_series *ant_tx_series;
11345 	wmi_buf_t buf;
11346 	int32_t len = 0;
11347 	int i;
11348 	uint8_t *buf_ptr;
11349 	QDF_STATUS ret;
11350 
11351 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11352 	len += (WMI_SMART_ANT_MAX_RATE_SERIES) *
11353 		sizeof(wmi_peer_smart_ant_set_tx_antenna_series);
11354 	buf = wmi_buf_alloc(wmi_handle, len);
11355 
11356 	if (!buf) {
11357 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11358 		return QDF_STATUS_E_NOMEM;
11359 	}
11360 
11361 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11362 	qdf_mem_zero(buf_ptr, len);
11363 	cmd = (wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *)buf_ptr;
11364 
11365 	WMITLV_SET_HDR(&cmd->tlv_header,
11366 	    WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param,
11367 	    WMITLV_GET_STRUCT_TLVLEN(
11368 			wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param));
11369 
11370 	cmd->vdev_id = param->vdev_id;
11371 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11372 
11373 	buf_ptr += sizeof(wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param);
11374 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11375 		       sizeof(wmi_peer_smart_ant_set_tx_antenna_series));
11376 	buf_ptr += WMI_TLV_HDR_SIZE;
11377 	ant_tx_series = (wmi_peer_smart_ant_set_tx_antenna_series *)buf_ptr;
11378 
11379 	for (i = 0; i < WMI_SMART_ANT_MAX_RATE_SERIES; i++) {
11380 		WMITLV_SET_HDR(&ant_tx_series->tlv_header,
11381 		    WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_series,
11382 		    WMITLV_GET_STRUCT_TLVLEN(
11383 				wmi_peer_smart_ant_set_tx_antenna_series));
11384 		ant_tx_series->antenna_series = param->antenna_array[i];
11385 		ant_tx_series++;
11386 	}
11387 
11388 	wmi_mtrace(WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID, cmd->vdev_id, 0);
11389 	ret = wmi_unified_cmd_send(wmi_handle,
11390 				   buf,
11391 				   len,
11392 				   WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID);
11393 
11394 	if (ret != 0) {
11395 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11396 		wmi_buf_free(buf);
11397 	}
11398 
11399 	return ret;
11400 }
11401 
11402 /**
11403  * send_set_ant_switch_tbl_cmd_tlv() - send ant switch tbl cmd to fw
11404  * @wmi_handle: wmi handle
11405  * @param: pointer to hold ant switch tbl param
11406  *
11407  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11408  */
11409 static QDF_STATUS
11410 send_set_ant_switch_tbl_cmd_tlv(wmi_unified_t wmi_handle,
11411 				struct ant_switch_tbl_params *param)
11412 {
11413 	uint8_t len;
11414 	wmi_buf_t buf;
11415 	wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *cmd;
11416 	wmi_pdev_set_ant_ctrl_chain *ctrl_chain;
11417 	uint8_t *buf_ptr;
11418 
11419 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11420 	len += sizeof(wmi_pdev_set_ant_ctrl_chain);
11421 	buf = wmi_buf_alloc(wmi_handle, len);
11422 
11423 	if (!buf) {
11424 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11425 		return QDF_STATUS_E_NOMEM;
11426 	}
11427 
11428 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11429 	qdf_mem_zero(buf_ptr, len);
11430 	cmd = (wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *)buf_ptr;
11431 
11432 	WMITLV_SET_HDR(&cmd->tlv_header,
11433 		WMITLV_TAG_STRUC_wmi_pdev_set_ant_switch_tbl_cmd_fixed_param,
11434 		WMITLV_GET_STRUCT_TLVLEN(
11435 			wmi_pdev_set_ant_switch_tbl_cmd_fixed_param));
11436 
11437 	cmd->antCtrlCommon1 = param->ant_ctrl_common1;
11438 	cmd->antCtrlCommon2 = param->ant_ctrl_common2;
11439 	cmd->mac_id =
11440 		wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id);
11441 
11442 	/* TLV indicating array of structures to follow */
11443 	buf_ptr += sizeof(wmi_pdev_set_ant_switch_tbl_cmd_fixed_param);
11444 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11445 		       sizeof(wmi_pdev_set_ant_ctrl_chain));
11446 	buf_ptr += WMI_TLV_HDR_SIZE;
11447 	ctrl_chain = (wmi_pdev_set_ant_ctrl_chain *)buf_ptr;
11448 
11449 	ctrl_chain->pdev_id =
11450 		wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id);
11451 	ctrl_chain->antCtrlChain = param->antCtrlChain;
11452 
11453 	wmi_mtrace(WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID, NO_SESSION, 0);
11454 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11455 				 WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) {
11456 		wmi_buf_free(buf);
11457 		return QDF_STATUS_E_FAILURE;
11458 	}
11459 
11460 	return QDF_STATUS_SUCCESS;
11461 }
11462 
11463 /**
11464  *  send_smart_ant_set_training_info_cmd_tlv() - WMI set smart antenna
11465  *  training information function
11466  *  @param wmi_handle  : handle to WMI.
11467  *  @macaddr           : vdev mac address
11468  *  @param param       : pointer to tx antenna param
11469  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11470  */
11471 static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv(
11472 				wmi_unified_t wmi_handle,
11473 				uint8_t macaddr[IEEE80211_ADDR_LEN],
11474 				struct smart_ant_training_info_params *param)
11475 {
11476 	wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd;
11477 	wmi_peer_smart_ant_set_train_antenna_param *train_param;
11478 	wmi_buf_t buf;
11479 	uint8_t *buf_ptr;
11480 	int32_t len = 0;
11481 	QDF_STATUS ret;
11482 	int loop;
11483 
11484 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11485 	len += (WMI_SMART_ANT_MAX_RATE_SERIES) *
11486 		 sizeof(wmi_peer_smart_ant_set_train_antenna_param);
11487 	buf = wmi_buf_alloc(wmi_handle, len);
11488 
11489 	if (!buf) {
11490 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11491 		return QDF_STATUS_E_NOMEM;
11492 	}
11493 
11494 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11495 	qdf_mem_zero(buf_ptr, len);
11496 	cmd = (wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *)buf_ptr;
11497 
11498 	WMITLV_SET_HDR(&cmd->tlv_header,
11499 	WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param,
11500 		WMITLV_GET_STRUCT_TLVLEN(
11501 			wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param));
11502 
11503 	cmd->vdev_id = param->vdev_id;
11504 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11505 	cmd->num_pkts = param->numpkts;
11506 
11507 	buf_ptr += sizeof(wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param);
11508 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11509 		       sizeof(wmi_peer_smart_ant_set_train_antenna_param) *
11510 		       WMI_SMART_ANT_MAX_RATE_SERIES);
11511 
11512 	buf_ptr += WMI_TLV_HDR_SIZE;
11513 	train_param = (wmi_peer_smart_ant_set_train_antenna_param *)buf_ptr;
11514 
11515 	for (loop = 0; loop < WMI_SMART_ANT_MAX_RATE_SERIES; loop++) {
11516 		WMITLV_SET_HDR(&train_param->tlv_header,
11517 		WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_param,
11518 			    WMITLV_GET_STRUCT_TLVLEN(
11519 				wmi_peer_smart_ant_set_train_antenna_param));
11520 		train_param->train_rate_series = param->rate_array[loop];
11521 		train_param->train_antenna_series = param->antenna_array[loop];
11522 		train_param->rc_flags = 0;
11523 		WMI_LOGI(FL("Series number:%d\n"), loop);
11524 		WMI_LOGI(FL("Rate [0x%02x] Tx_Antenna [0x%08x]\n"),
11525 			 train_param->train_rate_series,
11526 			 train_param->train_antenna_series);
11527 		train_param++;
11528 	}
11529 
11530 	wmi_mtrace(WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID, cmd->vdev_id, 0);
11531 	ret = wmi_unified_cmd_send(wmi_handle,
11532 				buf,
11533 				len,
11534 				WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID);
11535 
11536 	if (ret != 0) {
11537 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11538 		wmi_buf_free(buf);
11539 		return QDF_STATUS_E_FAILURE;
11540 	}
11541 
11542 	return ret;
11543 }
11544 
11545 /**
11546  *  send_smart_ant_set_node_config_cmd_tlv() - WMI set node
11547  *  configuration function
11548  *  @param wmi_handle		   : handle to WMI.
11549  *  @macaddr			   : vdev mad address
11550  *  @param param		   : pointer to tx antenna param
11551  *
11552  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11553  */
11554 static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv(
11555 				wmi_unified_t wmi_handle,
11556 				uint8_t macaddr[IEEE80211_ADDR_LEN],
11557 				struct smart_ant_node_config_params *param)
11558 {
11559 	wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd;
11560 	wmi_buf_t buf;
11561 	uint8_t *buf_ptr;
11562 	int32_t len = 0, args_tlv_len;
11563 	int ret;
11564 	int i = 0;
11565 	uint32_t *node_config_args;
11566 
11567 	args_tlv_len = WMI_TLV_HDR_SIZE + param->args_count * sizeof(uint32_t);
11568 	len = sizeof(*cmd) + args_tlv_len;
11569 
11570 	if (param->args_count == 0) {
11571 		WMI_LOGE("%s: Can't send a command with %d arguments\n",
11572 			  __func__, param->args_count);
11573 		return QDF_STATUS_E_FAILURE;
11574 	}
11575 
11576 	buf = wmi_buf_alloc(wmi_handle, len);
11577 	if (!buf) {
11578 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11579 		return QDF_STATUS_E_NOMEM;
11580 	}
11581 
11582 	cmd = (wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *)
11583 						wmi_buf_data(buf);
11584 	buf_ptr = (uint8_t *)cmd;
11585 	WMITLV_SET_HDR(&cmd->tlv_header,
11586 	WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param,
11587 		WMITLV_GET_STRUCT_TLVLEN(
11588 		wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param));
11589 	cmd->vdev_id = param->vdev_id;
11590 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11591 	cmd->cmd_id = param->cmd_id;
11592 	cmd->args_count = param->args_count;
11593 	buf_ptr += sizeof(
11594 		wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param);
11595 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
11596 			(cmd->args_count * sizeof(uint32_t)));
11597 	buf_ptr += WMI_TLV_HDR_SIZE;
11598 	node_config_args = (uint32_t *)buf_ptr;
11599 
11600 	for (i = 0; i < param->args_count; i++) {
11601 		node_config_args[i] = param->args_arr[i];
11602 		WMI_LOGI("%d", param->args_arr[i]);
11603 	}
11604 
11605 	wmi_mtrace(WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID,
11606 		   cmd->vdev_id, 0);
11607 	ret = wmi_unified_cmd_send(wmi_handle,
11608 			   buf,
11609 			   len,
11610 			   WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID);
11611 
11612 	if (ret != 0) {
11613 		WMI_LOGE("%s: WMI FAILED:Sent cmd_id: 0x%x\n Node: %02x:%02x:%02x:%02x:%02x:%02x cmdstatus=%d\n",
11614 			 __func__, param->cmd_id, macaddr[0],
11615 			 macaddr[1], macaddr[2], macaddr[3],
11616 			 macaddr[4], macaddr[5], ret);
11617 		wmi_buf_free(buf);
11618 	}
11619 
11620 	return ret;
11621 }
11622 
11623 #ifdef WLAN_ATF_ENABLE
11624 /**
11625  * send_set_atf_cmd_tlv() - send set atf command to fw
11626  * @wmi_handle: wmi handle
11627  * @param: pointer to set atf param
11628  *
11629  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11630  */
11631 static QDF_STATUS
11632 send_set_atf_cmd_tlv(wmi_unified_t wmi_handle,
11633 		     struct set_atf_params *param)
11634 {
11635 	wmi_atf_peer_info *peer_info;
11636 	wmi_peer_atf_request_fixed_param *cmd;
11637 	wmi_buf_t buf;
11638 	uint8_t *buf_ptr;
11639 	int i;
11640 	int32_t len = 0;
11641 	QDF_STATUS retval;
11642 
11643 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11644 	len += param->num_peers * sizeof(wmi_atf_peer_info);
11645 	buf = wmi_buf_alloc(wmi_handle, len);
11646 	if (!buf) {
11647 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11648 		return QDF_STATUS_E_FAILURE;
11649 	}
11650 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11651 	cmd = (wmi_peer_atf_request_fixed_param *)buf_ptr;
11652 	WMITLV_SET_HDR(&cmd->tlv_header,
11653 		       WMITLV_TAG_STRUC_wmi_peer_atf_request_fixed_param,
11654 		       WMITLV_GET_STRUCT_TLVLEN(
11655 				wmi_peer_atf_request_fixed_param));
11656 	cmd->num_peers = param->num_peers;
11657 
11658 	buf_ptr += sizeof(*cmd);
11659 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11660 		       sizeof(wmi_atf_peer_info) *
11661 		       cmd->num_peers);
11662 	buf_ptr += WMI_TLV_HDR_SIZE;
11663 	peer_info = (wmi_atf_peer_info *)buf_ptr;
11664 
11665 	for (i = 0; i < cmd->num_peers; i++) {
11666 		WMITLV_SET_HDR(&peer_info->tlv_header,
11667 			    WMITLV_TAG_STRUC_wmi_atf_peer_info,
11668 			    WMITLV_GET_STRUCT_TLVLEN(
11669 				wmi_atf_peer_info));
11670 		qdf_mem_copy(&(peer_info->peer_macaddr),
11671 				&(param->peer_info[i].peer_macaddr),
11672 				sizeof(wmi_mac_addr));
11673 		peer_info->atf_units = param->peer_info[i].percentage_peer;
11674 		peer_info->vdev_id = param->peer_info[i].vdev_id;
11675 		peer_info->pdev_id =
11676 			wmi_handle->ops->convert_pdev_id_host_to_target(
11677 				param->peer_info[i].pdev_id);
11678 		/*
11679 		 * TLV definition for peer atf request fixed param combines
11680 		 * extension stats. Legacy FW for WIN (Non-TLV) has peer atf
11681 		 * stats and atf extension stats as two different
11682 		 * implementations.
11683 		 * Need to discuss with FW on this.
11684 		 *
11685 		 * peer_info->atf_groupid = param->peer_ext_info[i].group_index;
11686 		 * peer_info->atf_units_reserved =
11687 		 *		param->peer_ext_info[i].atf_index_reserved;
11688 		 */
11689 		peer_info++;
11690 	}
11691 
11692 	wmi_mtrace(WMI_PEER_ATF_REQUEST_CMDID, NO_SESSION, 0);
11693 	retval = wmi_unified_cmd_send(wmi_handle, buf, len,
11694 		WMI_PEER_ATF_REQUEST_CMDID);
11695 
11696 	if (retval != QDF_STATUS_SUCCESS) {
11697 		WMI_LOGE("%s : WMI Failed\n", __func__);
11698 		wmi_buf_free(buf);
11699 	}
11700 
11701 	return retval;
11702 }
11703 #endif
11704 
11705 /**
11706  * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw
11707  * @wmi_handle: wmi handle
11708  * @param: pointer to hold fwtest param
11709  *
11710  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11711  */
11712 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle,
11713 				struct set_fwtest_params *param)
11714 {
11715 	wmi_fwtest_set_param_cmd_fixed_param *cmd;
11716 	wmi_buf_t buf;
11717 	int32_t len = sizeof(*cmd);
11718 
11719 	buf = wmi_buf_alloc(wmi_handle, len);
11720 
11721 	if (!buf) {
11722 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11723 		return QDF_STATUS_E_FAILURE;
11724 	}
11725 
11726 	cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf);
11727 	WMITLV_SET_HDR(&cmd->tlv_header,
11728 		       WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param,
11729 		       WMITLV_GET_STRUCT_TLVLEN(
11730 				wmi_fwtest_set_param_cmd_fixed_param));
11731 	cmd->param_id = param->arg;
11732 	cmd->param_value = param->value;
11733 
11734 	wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0);
11735 	if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) {
11736 		WMI_LOGE("Setting FW test param failed\n");
11737 		wmi_buf_free(buf);
11738 		return QDF_STATUS_E_FAILURE;
11739 	}
11740 
11741 	return QDF_STATUS_SUCCESS;
11742 }
11743 
11744 /**
11745  * send_set_qboost_param_cmd_tlv() - send set qboost command to fw
11746  * @wmi_handle: wmi handle
11747  * @param: pointer to qboost params
11748  * @macaddr: vdev mac address
11749  *
11750  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11751  */
11752 static QDF_STATUS
11753 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle,
11754 			      uint8_t macaddr[IEEE80211_ADDR_LEN],
11755 			      struct set_qboost_params *param)
11756 {
11757 	WMI_QBOOST_CFG_CMD_fixed_param *cmd;
11758 	wmi_buf_t buf;
11759 	int32_t len;
11760 	QDF_STATUS ret;
11761 
11762 	len = sizeof(*cmd);
11763 
11764 	buf = wmi_buf_alloc(wmi_handle, len);
11765 	if (!buf) {
11766 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11767 		return QDF_STATUS_E_FAILURE;
11768 	}
11769 
11770 	cmd = (WMI_QBOOST_CFG_CMD_fixed_param *)wmi_buf_data(buf);
11771 	WMITLV_SET_HDR(&cmd->tlv_header,
11772 		       WMITLV_TAG_STRUC_WMI_QBOOST_CFG_CMD_fixed_param,
11773 		       WMITLV_GET_STRUCT_TLVLEN(
11774 				WMI_QBOOST_CFG_CMD_fixed_param));
11775 	cmd->vdev_id = param->vdev_id;
11776 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11777 	cmd->qb_enable = param->value;
11778 
11779 	wmi_mtrace(WMI_QBOOST_CFG_CMDID, cmd->vdev_id, 0);
11780 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11781 			WMI_QBOOST_CFG_CMDID);
11782 
11783 	if (ret != 0) {
11784 		WMI_LOGE("Setting qboost cmd failed\n");
11785 		wmi_buf_free(buf);
11786 	}
11787 
11788 	return ret;
11789 }
11790 
11791 /**
11792  * send_gpio_config_cmd_tlv() - send gpio config to fw
11793  * @wmi_handle: wmi handle
11794  * @param: pointer to hold gpio config param
11795  *
11796  * Return: 0 for success or error code
11797  */
11798 static QDF_STATUS
11799 send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle,
11800 			 struct gpio_config_params *param)
11801 {
11802 	wmi_gpio_config_cmd_fixed_param *cmd;
11803 	wmi_buf_t buf;
11804 	int32_t len;
11805 	QDF_STATUS ret;
11806 
11807 	len = sizeof(*cmd);
11808 
11809 	/* Sanity Checks */
11810 	if (param->pull_type > WMI_GPIO_PULL_DOWN ||
11811 	    param->intr_mode > WMI_GPIO_INTTYPE_LEVEL_HIGH) {
11812 		return QDF_STATUS_E_FAILURE;
11813 	}
11814 
11815 	buf = wmi_buf_alloc(wmi_handle, len);
11816 	if (!buf) {
11817 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11818 		return QDF_STATUS_E_FAILURE;
11819 	}
11820 
11821 	cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf);
11822 	WMITLV_SET_HDR(&cmd->tlv_header,
11823 		       WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param,
11824 		       WMITLV_GET_STRUCT_TLVLEN(
11825 				wmi_gpio_config_cmd_fixed_param));
11826 	cmd->gpio_num = param->gpio_num;
11827 	cmd->input = param->input;
11828 	cmd->pull_type = param->pull_type;
11829 	cmd->intr_mode = param->intr_mode;
11830 
11831 	wmi_mtrace(WMI_GPIO_CONFIG_CMDID, NO_SESSION, 0);
11832 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11833 			WMI_GPIO_CONFIG_CMDID);
11834 
11835 	if (ret != 0) {
11836 		WMI_LOGE("Sending GPIO config cmd failed\n");
11837 		wmi_buf_free(buf);
11838 	}
11839 
11840 	return ret;
11841 }
11842 
11843 /**
11844  * send_gpio_output_cmd_tlv() - send gpio output to fw
11845  * @wmi_handle: wmi handle
11846  * @param: pointer to hold gpio output param
11847  *
11848  * Return: 0 for success or error code
11849  */
11850 static QDF_STATUS
11851 send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle,
11852 			 struct gpio_output_params *param)
11853 {
11854 	wmi_gpio_output_cmd_fixed_param *cmd;
11855 	wmi_buf_t buf;
11856 	int32_t len;
11857 	QDF_STATUS ret;
11858 
11859 	len = sizeof(*cmd);
11860 
11861 	buf = wmi_buf_alloc(wmi_handle, len);
11862 	if (!buf) {
11863 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11864 		return QDF_STATUS_E_FAILURE;
11865 	}
11866 
11867 	cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf);
11868 	WMITLV_SET_HDR(&cmd->tlv_header,
11869 		       WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param,
11870 		       WMITLV_GET_STRUCT_TLVLEN(
11871 				wmi_gpio_output_cmd_fixed_param));
11872 	cmd->gpio_num = param->gpio_num;
11873 	cmd->set = param->set;
11874 
11875 	wmi_mtrace(WMI_GPIO_OUTPUT_CMDID, NO_SESSION, 0);
11876 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11877 			WMI_GPIO_OUTPUT_CMDID);
11878 
11879 	if (ret != 0) {
11880 		WMI_LOGE("Sending GPIO output cmd failed\n");
11881 		wmi_buf_free(buf);
11882 	}
11883 
11884 	return ret;
11885 
11886 }
11887 
11888 /**
11889  *  send_phyerr_disable_cmd_tlv() - WMI phyerr disable function
11890  *
11891  *  @param wmi_handle     : handle to WMI.
11892  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11893  */
11894 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle)
11895 {
11896 	wmi_pdev_dfs_disable_cmd_fixed_param *cmd;
11897 	wmi_buf_t buf;
11898 	QDF_STATUS ret;
11899 	int32_t len;
11900 
11901 	len = sizeof(*cmd);
11902 
11903 	buf = wmi_buf_alloc(wmi_handle, len);
11904 	if (!buf) {
11905 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11906 		return QDF_STATUS_E_FAILURE;
11907 	}
11908 
11909 	cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf);
11910 	WMITLV_SET_HDR(&cmd->tlv_header,
11911 		       WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param,
11912 		       WMITLV_GET_STRUCT_TLVLEN(
11913 				wmi_pdev_dfs_disable_cmd_fixed_param));
11914 	/* Filling it with WMI_PDEV_ID_SOC for now */
11915 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
11916 							WMI_HOST_PDEV_ID_SOC);
11917 
11918 	wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0);
11919 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11920 			WMI_PDEV_DFS_DISABLE_CMDID);
11921 
11922 	if (ret != 0) {
11923 		WMI_LOGE("Sending PDEV DFS disable cmd failed\n");
11924 		wmi_buf_free(buf);
11925 	}
11926 
11927 	return ret;
11928 }
11929 
11930 /**
11931  *  send_phyerr_enable_cmd_tlv() - WMI phyerr disable function
11932  *
11933  *  @param wmi_handle     : handle to WMI.
11934  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11935  */
11936 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle)
11937 {
11938 	wmi_pdev_dfs_enable_cmd_fixed_param *cmd;
11939 	wmi_buf_t buf;
11940 	QDF_STATUS ret;
11941 	int32_t len;
11942 
11943 	len = sizeof(*cmd);
11944 
11945 	buf = wmi_buf_alloc(wmi_handle, len);
11946 	if (!buf) {
11947 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11948 		return QDF_STATUS_E_FAILURE;
11949 	}
11950 
11951 	cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf);
11952 	WMITLV_SET_HDR(&cmd->tlv_header,
11953 		       WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param,
11954 		       WMITLV_GET_STRUCT_TLVLEN(
11955 				wmi_pdev_dfs_enable_cmd_fixed_param));
11956 	/* Reserved for future use */
11957 	cmd->reserved0 = 0;
11958 
11959 	wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0);
11960 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11961 			WMI_PDEV_DFS_ENABLE_CMDID);
11962 
11963 	if (ret != 0) {
11964 		WMI_LOGE("Sending PDEV DFS enable cmd failed\n");
11965 		wmi_buf_free(buf);
11966 	}
11967 
11968 	return ret;
11969 }
11970 
11971 /**
11972  * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd
11973  * to fw
11974  * @wmi_handle: wmi handle
11975  * @param: pointer to hold periodic chan stats param
11976  *
11977  * Return: 0 for success or error code
11978  */
11979 static QDF_STATUS
11980 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle,
11981 				struct periodic_chan_stats_params *param)
11982 {
11983 	wmi_set_periodic_channel_stats_config_fixed_param *cmd;
11984 	wmi_buf_t buf;
11985 	QDF_STATUS ret;
11986 	int32_t len;
11987 
11988 	len = sizeof(*cmd);
11989 
11990 	buf = wmi_buf_alloc(wmi_handle, len);
11991 	if (!buf) {
11992 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11993 		return QDF_STATUS_E_FAILURE;
11994 	}
11995 
11996 	cmd = (wmi_set_periodic_channel_stats_config_fixed_param *)
11997 					wmi_buf_data(buf);
11998 	WMITLV_SET_HDR(&cmd->tlv_header,
11999 	WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param,
12000 		WMITLV_GET_STRUCT_TLVLEN(
12001 		wmi_set_periodic_channel_stats_config_fixed_param));
12002 	cmd->enable = param->enable;
12003 	cmd->stats_period = param->stats_period;
12004 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
12005 						param->pdev_id);
12006 
12007 	wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0);
12008 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
12009 			WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID);
12010 
12011 	if (ret != 0) {
12012 		WMI_LOGE("Sending periodic chan stats config failed");
12013 		wmi_buf_free(buf);
12014 	}
12015 
12016 	return ret;
12017 }
12018 
12019 /**
12020  * send_nf_dbr_dbm_info_get_cmd_tlv() - send request to get nf to fw
12021  * @wmi_handle: wmi handle
12022  * @mac_id: radio context
12023  *
12024  * Return: 0 for success or error code
12025  */
12026 static QDF_STATUS
12027 send_nf_dbr_dbm_info_get_cmd_tlv(wmi_unified_t wmi_handle, uint8_t mac_id)
12028 {
12029 	wmi_buf_t buf;
12030 	QDF_STATUS ret;
12031 	wmi_pdev_get_nfcal_power_fixed_param *cmd;
12032 	int32_t len = sizeof(*cmd);
12033 
12034 	buf = wmi_buf_alloc(wmi_handle, len);
12035 	if (buf == NULL)
12036 		return QDF_STATUS_E_NOMEM;
12037 
12038 	cmd = (wmi_pdev_get_nfcal_power_fixed_param *)wmi_buf_data(buf);
12039 	WMITLV_SET_HDR(&cmd->tlv_header,
12040 		       WMITLV_TAG_STRUC_wmi_pdev_get_nfcal_power_fixed_param,
12041 		       WMITLV_GET_STRUCT_TLVLEN
12042 				(wmi_pdev_get_nfcal_power_fixed_param));
12043 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
12044 
12045 	wmi_mtrace(WMI_PDEV_GET_NFCAL_POWER_CMDID, NO_SESSION, 0);
12046 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12047 				   WMI_PDEV_GET_NFCAL_POWER_CMDID);
12048 	if (ret != 0) {
12049 		WMI_LOGE("Sending get nfcal power cmd failed\n");
12050 		wmi_buf_free(buf);
12051 	}
12052 
12053 	return ret;
12054 }
12055 
12056 /**
12057  * send_set_ht_ie_cmd_tlv() - send ht ie command to fw
12058  * @wmi_handle: wmi handle
12059  * @param: pointer to ht ie param
12060  *
12061  * Return: 0 for success or error code
12062  */
12063 static QDF_STATUS
12064 send_set_ht_ie_cmd_tlv(wmi_unified_t wmi_handle,
12065 		       struct ht_ie_params *param)
12066 {
12067 	wmi_pdev_set_ht_ie_cmd_fixed_param *cmd;
12068 	wmi_buf_t buf;
12069 	QDF_STATUS ret;
12070 	int32_t len;
12071 	uint8_t *buf_ptr;
12072 
12073 	len = sizeof(*cmd)  + WMI_TLV_HDR_SIZE +
12074 	      roundup(param->ie_len, sizeof(uint32_t));
12075 
12076 	buf = wmi_buf_alloc(wmi_handle, len);
12077 	if (!buf) {
12078 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12079 		return QDF_STATUS_E_FAILURE;
12080 	}
12081 
12082 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12083 	cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *)buf_ptr;
12084 	WMITLV_SET_HDR(&cmd->tlv_header,
12085 		       WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param,
12086 		       WMITLV_GET_STRUCT_TLVLEN(
12087 				wmi_pdev_set_ht_ie_cmd_fixed_param));
12088 	cmd->reserved0 = 0;
12089 	cmd->ie_len = param->ie_len;
12090 	cmd->tx_streams = param->tx_streams;
12091 	cmd->rx_streams = param->rx_streams;
12092 
12093 	buf_ptr += sizeof(*cmd);
12094 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len);
12095 	buf_ptr += WMI_TLV_HDR_SIZE;
12096 	if (param->ie_len)
12097 		WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data,
12098 						cmd->ie_len);
12099 
12100 	wmi_mtrace(WMI_PDEV_SET_HT_CAP_IE_CMDID, NO_SESSION, 0);
12101 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12102 				   WMI_PDEV_SET_HT_CAP_IE_CMDID);
12103 
12104 	if (ret != 0) {
12105 		WMI_LOGE("Sending set ht ie cmd failed\n");
12106 		wmi_buf_free(buf);
12107 	}
12108 
12109 	return ret;
12110 }
12111 
12112 /**
12113  * send_set_vht_ie_cmd_tlv() - send vht ie command to fw
12114  * @wmi_handle: wmi handle
12115  * @param: pointer to vht ie param
12116  *
12117  * Return: 0 for success or error code
12118  */
12119 static QDF_STATUS
12120 send_set_vht_ie_cmd_tlv(wmi_unified_t wmi_handle,
12121 			struct vht_ie_params *param)
12122 {
12123 	wmi_pdev_set_vht_ie_cmd_fixed_param *cmd;
12124 	wmi_buf_t buf;
12125 	QDF_STATUS ret;
12126 	int32_t len;
12127 	uint8_t *buf_ptr;
12128 
12129 	len = sizeof(*cmd)  + WMI_TLV_HDR_SIZE +
12130 	      roundup(param->ie_len, sizeof(uint32_t));
12131 
12132 	buf = wmi_buf_alloc(wmi_handle, len);
12133 	if (!buf) {
12134 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12135 		return QDF_STATUS_E_FAILURE;
12136 	}
12137 
12138 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12139 	cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *)buf_ptr;
12140 	WMITLV_SET_HDR(&cmd->tlv_header,
12141 		       WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param,
12142 		       WMITLV_GET_STRUCT_TLVLEN(
12143 				wmi_pdev_set_vht_ie_cmd_fixed_param));
12144 	cmd->reserved0 = 0;
12145 	cmd->ie_len = param->ie_len;
12146 	cmd->tx_streams = param->tx_streams;
12147 	cmd->rx_streams = param->rx_streams;
12148 
12149 	buf_ptr += sizeof(*cmd);
12150 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len);
12151 	buf_ptr += WMI_TLV_HDR_SIZE;
12152 	if (param->ie_len)
12153 		WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data,
12154 						cmd->ie_len);
12155 
12156 	wmi_mtrace(WMI_PDEV_SET_VHT_CAP_IE_CMDID, NO_SESSION, 0);
12157 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12158 				   WMI_PDEV_SET_VHT_CAP_IE_CMDID);
12159 
12160 	if (ret != 0) {
12161 		WMI_LOGE("Sending set vht ie cmd failed\n");
12162 		wmi_buf_free(buf);
12163 	}
12164 
12165 	return ret;
12166 }
12167 
12168 /**
12169  * send_set_quiet_mode_cmd_tlv() - send set quiet mode command to fw
12170  * @wmi_handle: wmi handle
12171  * @param: pointer to quiet mode params
12172  *
12173  * Return: 0 for success or error code
12174  */
12175 static QDF_STATUS
12176 send_set_quiet_mode_cmd_tlv(wmi_unified_t wmi_handle,
12177 			    struct set_quiet_mode_params *param)
12178 {
12179 	wmi_pdev_set_quiet_cmd_fixed_param *quiet_cmd;
12180 	wmi_buf_t buf;
12181 	QDF_STATUS ret;
12182 	int32_t len;
12183 
12184 	len = sizeof(*quiet_cmd);
12185 	buf = wmi_buf_alloc(wmi_handle, len);
12186 	if (!buf) {
12187 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12188 		return QDF_STATUS_E_FAILURE;
12189 	}
12190 
12191 	quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf);
12192 	WMITLV_SET_HDR(&quiet_cmd->tlv_header,
12193 		       WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param,
12194 		       WMITLV_GET_STRUCT_TLVLEN(
12195 				wmi_pdev_set_quiet_cmd_fixed_param));
12196 	quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf);
12197 	quiet_cmd->enabled = param->enabled;
12198 	quiet_cmd->period = (param->period)*(param->intval);
12199 	quiet_cmd->duration = param->duration;
12200 	quiet_cmd->next_start = param->offset;
12201 	quiet_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
12202 							WMI_HOST_PDEV_ID_SOC);
12203 
12204 	wmi_mtrace(WMI_PDEV_SET_QUIET_MODE_CMDID, NO_SESSION, 0);
12205 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12206 				   WMI_PDEV_SET_QUIET_MODE_CMDID);
12207 
12208 	if (ret != 0) {
12209 		WMI_LOGE("Sending set quiet cmd failed\n");
12210 		wmi_buf_free(buf);
12211 	}
12212 
12213 	return ret;
12214 }
12215 
12216 /**
12217  * send_set_bwf_cmd_tlv() - send set bwf command to fw
12218  * @wmi_handle: wmi handle
12219  * @param: pointer to set bwf param
12220  *
12221  * Return: 0 for success or error code
12222  */
12223 static QDF_STATUS
12224 send_set_bwf_cmd_tlv(wmi_unified_t wmi_handle,
12225 		     struct set_bwf_params *param)
12226 {
12227 	wmi_bwf_peer_info *peer_info;
12228 	wmi_peer_bwf_request_fixed_param *cmd;
12229 	wmi_buf_t buf;
12230 	QDF_STATUS retval;
12231 	int32_t len;
12232 	uint8_t *buf_ptr;
12233 	int i;
12234 
12235 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
12236 	len += param->num_peers * sizeof(wmi_bwf_peer_info);
12237 	buf = wmi_buf_alloc(wmi_handle, len);
12238 	if (!buf) {
12239 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
12240 		return QDF_STATUS_E_FAILURE;
12241 	}
12242 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12243 	cmd = (wmi_peer_bwf_request_fixed_param *)buf_ptr;
12244 	WMITLV_SET_HDR(&cmd->tlv_header,
12245 		       WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param,
12246 		       WMITLV_GET_STRUCT_TLVLEN(
12247 				wmi_peer_bwf_request_fixed_param));
12248 	cmd->num_peers = param->num_peers;
12249 
12250 	buf_ptr += sizeof(*cmd);
12251 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
12252 		       sizeof(wmi_bwf_peer_info) *
12253 		       cmd->num_peers);
12254 	buf_ptr += WMI_TLV_HDR_SIZE;
12255 	peer_info = (wmi_bwf_peer_info *)buf_ptr;
12256 
12257 	for (i = 0; i < cmd->num_peers; i++) {
12258 		WMITLV_SET_HDR(&peer_info->tlv_header,
12259 			       WMITLV_TAG_STRUC_wmi_bwf_peer_info,
12260 			       WMITLV_GET_STRUCT_TLVLEN(wmi_bwf_peer_info));
12261 		peer_info->bwf_guaranteed_bandwidth =
12262 				param->peer_info[i].throughput;
12263 		peer_info->bwf_max_airtime =
12264 				param->peer_info[i].max_airtime;
12265 		peer_info->bwf_peer_priority =
12266 				param->peer_info[i].priority;
12267 		qdf_mem_copy(&peer_info->peer_macaddr,
12268 			     &param->peer_info[i].peer_macaddr,
12269 			     sizeof(param->peer_info[i].peer_macaddr));
12270 		peer_info->vdev_id =
12271 				param->peer_info[i].vdev_id;
12272 		peer_info->pdev_id =
12273 			wmi_handle->ops->convert_pdev_id_host_to_target(
12274 				param->peer_info[i].pdev_id);
12275 		peer_info++;
12276 	}
12277 
12278 	wmi_mtrace(WMI_PEER_BWF_REQUEST_CMDID, NO_SESSION, 0);
12279 	retval = wmi_unified_cmd_send(wmi_handle, buf, len,
12280 				      WMI_PEER_BWF_REQUEST_CMDID);
12281 
12282 	if (retval != QDF_STATUS_SUCCESS) {
12283 		WMI_LOGE("%s : WMI Failed\n", __func__);
12284 		wmi_buf_free(buf);
12285 	}
12286 
12287 	return retval;
12288 }
12289 
12290 /**
12291  * send_mcast_group_update_cmd_tlv() - send mcast group update cmd to fw
12292  * @wmi_handle: wmi handle
12293  * @param: pointer to hold mcast update param
12294  *
12295  * Return: 0 for success or error code
12296  */
12297 static QDF_STATUS
12298 send_mcast_group_update_cmd_tlv(wmi_unified_t wmi_handle,
12299 				struct mcast_group_update_params *param)
12300 {
12301 	wmi_peer_mcast_group_cmd_fixed_param *cmd;
12302 	wmi_buf_t buf;
12303 	QDF_STATUS ret;
12304 	int32_t len;
12305 	int offset = 0;
12306 	static char dummymask[4] = { 0xFF, 0xFF, 0xFF, 0xFF};
12307 
12308 	len = sizeof(*cmd);
12309 	buf = wmi_buf_alloc(wmi_handle, len);
12310 	if (!buf) {
12311 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12312 		return QDF_STATUS_E_FAILURE;
12313 	}
12314 	cmd = (wmi_peer_mcast_group_cmd_fixed_param *)wmi_buf_data(buf);
12315 	WMITLV_SET_HDR(&cmd->tlv_header,
12316 		       WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param,
12317 		       WMITLV_GET_STRUCT_TLVLEN(
12318 				wmi_peer_mcast_group_cmd_fixed_param));
12319 	/* confirm the buffer is 4-byte aligned */
12320 	QDF_ASSERT((((size_t) cmd) & 0x3) == 0);
12321 	qdf_mem_zero(cmd, sizeof(*cmd));
12322 
12323 	cmd->vdev_id = param->vap_id;
12324 	/* construct the message assuming our endianness matches the target */
12325 	cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_ACTION_M &
12326 		(param->action << WMI_PEER_MCAST_GROUP_FLAG_ACTION_S);
12327 	cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M &
12328 		(param->wildcard << WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S);
12329 	if (param->is_action_delete)
12330 		cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_DELETEALL_M;
12331 
12332 	if (param->is_mcast_addr_len)
12333 		cmd->flags |=  WMI_PEER_MCAST_GROUP_FLAG_IPV6_M;
12334 
12335 	if (param->is_filter_mode_snoop)
12336 		cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_SRC_FILTER_EXCLUDE_M;
12337 
12338 	/* unicast address spec only applies for non-wildcard cases */
12339 	if (!param->wildcard && param->ucast_mac_addr) {
12340 		WMI_CHAR_ARRAY_TO_MAC_ADDR(param->ucast_mac_addr,
12341 					   &cmd->ucast_mac_addr);
12342 	}
12343 
12344 	if (param->mcast_ip_addr) {
12345 		QDF_ASSERT(param->mcast_ip_addr_bytes <=
12346 			   sizeof(cmd->mcast_ip_addr));
12347 		offset = sizeof(cmd->mcast_ip_addr) -
12348 			 param->mcast_ip_addr_bytes;
12349 		qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_addr) + offset,
12350 			     param->mcast_ip_addr,
12351 			     param->mcast_ip_addr_bytes);
12352 	}
12353 	if (!param->mask)
12354 		param->mask = &dummymask[0];
12355 
12356 	qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_mask) + offset,
12357 		     param->mask,
12358 		     param->mcast_ip_addr_bytes);
12359 
12360 	if (param->srcs && param->nsrcs) {
12361 		cmd->num_filter_addr = param->nsrcs;
12362 		QDF_ASSERT((param->nsrcs * param->mcast_ip_addr_bytes) <=
12363 			sizeof(cmd->filter_addr));
12364 
12365 		qdf_mem_copy(((uint8_t *) &cmd->filter_addr), param->srcs,
12366 			     param->nsrcs * param->mcast_ip_addr_bytes);
12367 	}
12368 
12369 	wmi_mtrace(WMI_PEER_MCAST_GROUP_CMDID, cmd->vdev_id, 0);
12370 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12371 				      WMI_PEER_MCAST_GROUP_CMDID);
12372 
12373 	if (ret != QDF_STATUS_SUCCESS) {
12374 		WMI_LOGE("%s : WMI Failed\n", __func__);
12375 		wmi_buf_free(buf);
12376 	}
12377 
12378 	return ret;
12379 }
12380 
12381 /**
12382  * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure
12383  * command to fw
12384  * @wmi_handle: wmi handle
12385  * @param: pointer to hold spectral config parameter
12386  *
12387  * Return: 0 for success or error code
12388  */
12389 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle,
12390 				struct vdev_spectral_configure_params *param)
12391 {
12392 	wmi_vdev_spectral_configure_cmd_fixed_param *cmd;
12393 	wmi_buf_t buf;
12394 	QDF_STATUS ret;
12395 	int32_t len;
12396 
12397 	len = sizeof(*cmd);
12398 	buf = wmi_buf_alloc(wmi_handle, len);
12399 	if (!buf) {
12400 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12401 		return QDF_STATUS_E_FAILURE;
12402 	}
12403 
12404 	cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf);
12405 	WMITLV_SET_HDR(&cmd->tlv_header,
12406 		WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param,
12407 		WMITLV_GET_STRUCT_TLVLEN(
12408 		wmi_vdev_spectral_configure_cmd_fixed_param));
12409 
12410 	cmd->vdev_id = param->vdev_id;
12411 	cmd->spectral_scan_count = param->count;
12412 	cmd->spectral_scan_period = param->period;
12413 	cmd->spectral_scan_priority = param->spectral_pri;
12414 	cmd->spectral_scan_fft_size = param->fft_size;
12415 	cmd->spectral_scan_gc_ena = param->gc_enable;
12416 	cmd->spectral_scan_restart_ena = param->restart_enable;
12417 	cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref;
12418 	cmd->spectral_scan_init_delay = param->init_delay;
12419 	cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr;
12420 	cmd->spectral_scan_str_bin_thr = param->str_bin_thr;
12421 	cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode;
12422 	cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode;
12423 	cmd->spectral_scan_rssi_thr = param->rssi_thr;
12424 	cmd->spectral_scan_pwr_format = param->pwr_format;
12425 	cmd->spectral_scan_rpt_mode = param->rpt_mode;
12426 	cmd->spectral_scan_bin_scale = param->bin_scale;
12427 	cmd->spectral_scan_dBm_adj = param->dbm_adj;
12428 	cmd->spectral_scan_chn_mask = param->chn_mask;
12429 
12430 	wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0);
12431 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12432 				   WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID);
12433 
12434 	if (ret != 0) {
12435 		WMI_LOGE("Sending set quiet cmd failed\n");
12436 		wmi_buf_free(buf);
12437 	}
12438 
12439 	WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID\n",
12440 		 __func__);
12441 
12442 	WMI_LOGI("vdev_id = %u\n"
12443 		 "spectral_scan_count = %u\n"
12444 		 "spectral_scan_period = %u\n"
12445 		 "spectral_scan_priority = %u\n"
12446 		 "spectral_scan_fft_size = %u\n"
12447 		 "spectral_scan_gc_ena = %u\n"
12448 		 "spectral_scan_restart_ena = %u\n"
12449 		 "spectral_scan_noise_floor_ref = %u\n"
12450 		 "spectral_scan_init_delay = %u\n"
12451 		 "spectral_scan_nb_tone_thr = %u\n"
12452 		 "spectral_scan_str_bin_thr = %u\n"
12453 		 "spectral_scan_wb_rpt_mode = %u\n"
12454 		 "spectral_scan_rssi_rpt_mode = %u\n"
12455 		 "spectral_scan_rssi_thr = %u\n"
12456 		 "spectral_scan_pwr_format = %u\n"
12457 		 "spectral_scan_rpt_mode = %u\n"
12458 		 "spectral_scan_bin_scale = %u\n"
12459 		 "spectral_scan_dBm_adj = %u\n"
12460 		 "spectral_scan_chn_mask = %u\n",
12461 		 param->vdev_id,
12462 		 param->count,
12463 		 param->period,
12464 		 param->spectral_pri,
12465 		 param->fft_size,
12466 		 param->gc_enable,
12467 		 param->restart_enable,
12468 		 param->noise_floor_ref,
12469 		 param->init_delay,
12470 		 param->nb_tone_thr,
12471 		 param->str_bin_thr,
12472 		 param->wb_rpt_mode,
12473 		 param->rssi_rpt_mode,
12474 		 param->rssi_thr,
12475 		 param->pwr_format,
12476 		 param->rpt_mode,
12477 		 param->bin_scale,
12478 		 param->dbm_adj,
12479 		 param->chn_mask);
12480 	WMI_LOGI("%s: Status: %d\n\n", __func__, ret);
12481 
12482 	return ret;
12483 }
12484 
12485 /**
12486  * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure
12487  * command to fw
12488  * @wmi_handle: wmi handle
12489  * @param: pointer to hold spectral enable parameter
12490  *
12491  * Return: 0 for success or error code
12492  */
12493 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle,
12494 				struct vdev_spectral_enable_params *param)
12495 {
12496 	wmi_vdev_spectral_enable_cmd_fixed_param *cmd;
12497 	wmi_buf_t buf;
12498 	QDF_STATUS ret;
12499 	int32_t len;
12500 
12501 	len = sizeof(*cmd);
12502 	buf = wmi_buf_alloc(wmi_handle, len);
12503 	if (!buf) {
12504 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12505 		return QDF_STATUS_E_FAILURE;
12506 	}
12507 
12508 	cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf);
12509 	WMITLV_SET_HDR(&cmd->tlv_header,
12510 		WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param,
12511 		WMITLV_GET_STRUCT_TLVLEN(
12512 		wmi_vdev_spectral_enable_cmd_fixed_param));
12513 
12514 	cmd->vdev_id = param->vdev_id;
12515 
12516 	if (param->active_valid) {
12517 		cmd->trigger_cmd = param->active ? 1 : 2;
12518 		/* 1: Trigger, 2: Clear Trigger */
12519 	} else {
12520 		cmd->trigger_cmd = 0; /* 0: Ignore */
12521 	}
12522 
12523 	if (param->enabled_valid) {
12524 		cmd->enable_cmd = param->enabled ? 1 : 2;
12525 		/* 1: Enable 2: Disable */
12526 	} else {
12527 		cmd->enable_cmd = 0; /* 0: Ignore */
12528 	}
12529 
12530 	wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0);
12531 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12532 				   WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID);
12533 
12534 	if (ret != 0) {
12535 		WMI_LOGE("Sending scan enable CMD failed\n");
12536 		wmi_buf_free(buf);
12537 	}
12538 
12539 	WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID\n", __func__);
12540 
12541 	WMI_LOGI("vdev_id = %u\n"
12542 				 "trigger_cmd = %u\n"
12543 				 "enable_cmd = %u\n",
12544 				 cmd->vdev_id,
12545 				 cmd->trigger_cmd,
12546 				 cmd->enable_cmd);
12547 
12548 	WMI_LOGI("%s: Status: %d\n\n", __func__, ret);
12549 
12550 	return ret;
12551 }
12552 
12553 /**
12554  * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params
12555  * @param wmi_handle : handle to WMI.
12556  * @param param : pointer to hold thermal mitigation param
12557  *
12558  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
12559  */
12560 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv(
12561 		wmi_unified_t wmi_handle,
12562 		struct thermal_mitigation_params *param)
12563 {
12564 	wmi_therm_throt_config_request_fixed_param *tt_conf = NULL;
12565 	wmi_therm_throt_level_config_info *lvl_conf = NULL;
12566 	wmi_buf_t buf = NULL;
12567 	uint8_t *buf_ptr = NULL;
12568 	int error;
12569 	int32_t len;
12570 	int i;
12571 
12572 	len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE +
12573 			THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info);
12574 
12575 	buf = wmi_buf_alloc(wmi_handle, len);
12576 	if (!buf) {
12577 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
12578 		return QDF_STATUS_E_NOMEM;
12579 	}
12580 	tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf);
12581 
12582 	/* init fixed params */
12583 	WMITLV_SET_HDR(tt_conf,
12584 		WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param,
12585 		(WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param)));
12586 
12587 	tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
12588 								param->pdev_id);
12589 	tt_conf->enable = param->enable;
12590 	tt_conf->dc = param->dc;
12591 	tt_conf->dc_per_event = param->dc_per_event;
12592 	tt_conf->therm_throt_levels = THERMAL_LEVELS;
12593 
12594 	buf_ptr = (uint8_t *) ++tt_conf;
12595 	/* init TLV params */
12596 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
12597 			(THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info)));
12598 
12599 	lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr +  WMI_TLV_HDR_SIZE);
12600 	for (i = 0; i < THERMAL_LEVELS; i++) {
12601 		WMITLV_SET_HDR(&lvl_conf->tlv_header,
12602 			WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info,
12603 			WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info));
12604 		lvl_conf->temp_lwm = param->levelconf[i].tmplwm;
12605 		lvl_conf->temp_hwm = param->levelconf[i].tmphwm;
12606 		lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent;
12607 		lvl_conf->prio = param->levelconf[i].priority;
12608 		lvl_conf++;
12609 	}
12610 
12611 	wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0);
12612 	error = wmi_unified_cmd_send(wmi_handle, buf, len,
12613 			WMI_THERM_THROT_SET_CONF_CMDID);
12614 	if (QDF_IS_STATUS_ERROR(error)) {
12615 		wmi_buf_free(buf);
12616 		WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command");
12617 	}
12618 
12619 	return error;
12620 }
12621 
12622 /**
12623  * send_pdev_qvit_cmd_tlv() - send qvit command to fw
12624  * @wmi_handle: wmi handle
12625  * @param: pointer to pdev_qvit_params
12626  *
12627  * Return: 0 for success or error code
12628  */
12629 static QDF_STATUS
12630 send_pdev_qvit_cmd_tlv(wmi_unified_t wmi_handle,
12631 		       struct pdev_qvit_params *param)
12632 {
12633 	wmi_buf_t buf;
12634 	QDF_STATUS ret = QDF_STATUS_E_INVAL;
12635 	uint8_t *cmd;
12636 	static uint8_t msgref = 1;
12637 	uint8_t segnumber = 0, seginfo, numsegments;
12638 	uint16_t chunk_len, total_bytes;
12639 	uint8_t *bufpos;
12640 	QVIT_SEG_HDR_INFO_STRUCT seghdrinfo;
12641 
12642 	bufpos = param->utf_payload;
12643 	total_bytes = param->len;
12644 	ASSERT(total_bytes / MAX_WMI_QVIT_LEN ==
12645 	       (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN));
12646 	numsegments = (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN);
12647 
12648 	if (param->len - (numsegments * MAX_WMI_QVIT_LEN))
12649 		numsegments++;
12650 
12651 	while (param->len) {
12652 		if (param->len > MAX_WMI_QVIT_LEN)
12653 			chunk_len = MAX_WMI_QVIT_LEN;    /* MAX message */
12654 		else
12655 			chunk_len = param->len;
12656 
12657 		buf = wmi_buf_alloc(wmi_handle,
12658 				    (chunk_len + sizeof(seghdrinfo) +
12659 				     WMI_TLV_HDR_SIZE));
12660 		if (!buf) {
12661 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
12662 			return QDF_STATUS_E_NOMEM;
12663 		}
12664 
12665 		cmd = (uint8_t *) wmi_buf_data(buf);
12666 
12667 		seghdrinfo.len = total_bytes;
12668 		seghdrinfo.msgref = msgref;
12669 		seginfo = ((numsegments << 4) & 0xF0) | (segnumber & 0xF);
12670 		seghdrinfo.segmentInfo = seginfo;
12671 
12672 		segnumber++;
12673 
12674 		WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE,
12675 			       (chunk_len + sizeof(seghdrinfo)));
12676 		cmd += WMI_TLV_HDR_SIZE;
12677 		qdf_mem_copy(cmd, &seghdrinfo, sizeof(seghdrinfo));
12678 		qdf_mem_copy(&cmd[sizeof(seghdrinfo)], bufpos, chunk_len);
12679 
12680 		wmi_mtrace(WMI_PDEV_QVIT_CMDID, NO_SESSION, 0);
12681 		ret = wmi_unified_cmd_send(wmi_handle, buf,
12682 					   (chunk_len + sizeof(seghdrinfo) +
12683 					    WMI_TLV_HDR_SIZE),
12684 					   WMI_PDEV_QVIT_CMDID);
12685 
12686 		if (ret != 0) {
12687 			WMI_LOGE("Failed to send WMI_PDEV_QVIT_CMDID command");
12688 			wmi_buf_free(buf);
12689 			break;
12690 		}
12691 
12692 		param->len -= chunk_len;
12693 		bufpos += chunk_len;
12694 	}
12695 	msgref++;
12696 
12697 	return ret;
12698 }
12699 
12700 /**
12701  * send_wmm_update_cmd_tlv() - send wmm update command to fw
12702  * @wmi_handle: wmi handle
12703  * @param: pointer to wmm update param
12704  *
12705  * Return: 0 for success or error code
12706  */
12707 static QDF_STATUS
12708 send_wmm_update_cmd_tlv(wmi_unified_t wmi_handle,
12709 			struct wmm_update_params *param)
12710 {
12711 	wmi_pdev_set_wmm_params_cmd_fixed_param *cmd;
12712 	wmi_wmm_params *wmm_param;
12713 	wmi_buf_t buf;
12714 	QDF_STATUS ret;
12715 	int32_t len;
12716 	int ac = 0;
12717 	struct wmi_host_wmeParams *wmep;
12718 	uint8_t *buf_ptr;
12719 
12720 	len = sizeof(*cmd) + (WME_NUM_AC * sizeof(*wmm_param));
12721 	buf = wmi_buf_alloc(wmi_handle, len);
12722 	if (!buf) {
12723 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12724 		return QDF_STATUS_E_FAILURE;
12725 	}
12726 
12727 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
12728 	cmd = (wmi_pdev_set_wmm_params_cmd_fixed_param *) buf_ptr;
12729 	WMITLV_SET_HDR(&cmd->tlv_header,
12730 		       WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param,
12731 		       WMITLV_GET_STRUCT_TLVLEN
12732 			       (wmi_pdev_set_wmm_params_cmd_fixed_param));
12733 
12734 	cmd->reserved0 = WMI_HOST_PDEV_ID_SOC;
12735 
12736 	buf_ptr += sizeof(wmi_pdev_set_wmm_params_cmd_fixed_param);
12737 
12738 	for (ac = 0; ac < WME_NUM_AC; ac++) {
12739 		wmep = &param->wmep_array[ac];
12740 		wmm_param = (wmi_wmm_params *)buf_ptr;
12741 		WMITLV_SET_HDR(&wmm_param->tlv_header,
12742 			WMITLV_TAG_STRUC_wmi_wmm_params,
12743 			WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params));
12744 		wmm_param->aifs = wmep->wmep_aifsn;
12745 		wmm_param->cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
12746 		wmm_param->cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
12747 		wmm_param->txoplimit = ATH_TXOP_TO_US(wmep->wmep_txopLimit);
12748 		wmm_param->acm = wmep->wmep_acm;
12749 		wmm_param->no_ack = wmep->wmep_noackPolicy;
12750 		buf_ptr += sizeof(wmi_wmm_params);
12751 	}
12752 	wmi_mtrace(WMI_PDEV_SET_WMM_PARAMS_CMDID, NO_SESSION, 0);
12753 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12754 				   WMI_PDEV_SET_WMM_PARAMS_CMDID);
12755 
12756 	if (ret != 0) {
12757 		WMI_LOGE("Sending WMM update CMD failed\n");
12758 		wmi_buf_free(buf);
12759 	}
12760 
12761 	return ret;
12762 }
12763 
12764 /**
12765  * send_coex_config_cmd_tlv() - send coex config command to fw
12766  * @wmi_handle: wmi handle
12767  * @param: pointer to coex config param
12768  *
12769  * Return: 0 for success or error code
12770  */
12771 static QDF_STATUS
12772 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle,
12773 			 struct coex_config_params *param)
12774 {
12775 	WMI_COEX_CONFIG_CMD_fixed_param *cmd;
12776 	wmi_buf_t buf;
12777 	QDF_STATUS ret;
12778 	int32_t len;
12779 
12780 	len = sizeof(*cmd);
12781 	buf = wmi_buf_alloc(wmi_handle, len);
12782 	if (!buf) {
12783 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12784 		return QDF_STATUS_E_FAILURE;
12785 	}
12786 
12787 	cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf);
12788 	WMITLV_SET_HDR(&cmd->tlv_header,
12789 		       WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param,
12790 		       WMITLV_GET_STRUCT_TLVLEN(
12791 		       WMI_COEX_CONFIG_CMD_fixed_param));
12792 
12793 	cmd->vdev_id = param->vdev_id;
12794 	cmd->config_type = param->config_type;
12795 	cmd->config_arg1 = param->config_arg1;
12796 	cmd->config_arg2 = param->config_arg2;
12797 	cmd->config_arg3 = param->config_arg3;
12798 	cmd->config_arg4 = param->config_arg4;
12799 	cmd->config_arg5 = param->config_arg5;
12800 	cmd->config_arg6 = param->config_arg6;
12801 
12802 	wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0);
12803 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12804 				   WMI_COEX_CONFIG_CMDID);
12805 
12806 	if (ret != 0) {
12807 		WMI_LOGE("Sending COEX CONFIG CMD failed\n");
12808 		wmi_buf_free(buf);
12809 	}
12810 
12811 	return ret;
12812 }
12813 
12814 
12815 #ifdef WLAN_SUPPORT_TWT
12816 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg,
12817 					target_resource_config *tgt_res_cfg)
12818 {
12819 	resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count;
12820 	resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count;
12821 }
12822 #else
12823 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg,
12824 					target_resource_config *tgt_res_cfg)
12825 {
12826 	resource_cfg->twt_ap_pdev_count = 0;
12827 	resource_cfg->twt_ap_sta_count = 0;
12828 }
12829 #endif
12830 
12831 static
12832 void wmi_copy_resource_config(wmi_resource_config *resource_cfg,
12833 				target_resource_config *tgt_res_cfg)
12834 {
12835 	resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs;
12836 	resource_cfg->num_peers = tgt_res_cfg->num_peers;
12837 	resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers;
12838 	resource_cfg->num_offload_reorder_buffs =
12839 			tgt_res_cfg->num_offload_reorder_buffs;
12840 	resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys;
12841 	resource_cfg->num_tids = tgt_res_cfg->num_tids;
12842 	resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit;
12843 	resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask;
12844 	resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask;
12845 	resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0];
12846 	resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1];
12847 	resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2];
12848 	resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3];
12849 	resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode;
12850 	resource_cfg->scan_max_pending_req =
12851 			tgt_res_cfg->scan_max_pending_req;
12852 	resource_cfg->bmiss_offload_max_vdev =
12853 			tgt_res_cfg->bmiss_offload_max_vdev;
12854 	resource_cfg->roam_offload_max_vdev =
12855 			tgt_res_cfg->roam_offload_max_vdev;
12856 	resource_cfg->roam_offload_max_ap_profiles =
12857 			tgt_res_cfg->roam_offload_max_ap_profiles;
12858 	resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups;
12859 	resource_cfg->num_mcast_table_elems =
12860 			tgt_res_cfg->num_mcast_table_elems;
12861 	resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode;
12862 	resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size;
12863 	resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries;
12864 	resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size;
12865 	resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim;
12866 	resource_cfg->rx_skip_defrag_timeout_dup_detection_check =
12867 		tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check;
12868 	resource_cfg->vow_config = tgt_res_cfg->vow_config;
12869 	resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev;
12870 	resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc;
12871 	resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries;
12872 	resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs;
12873 	resource_cfg->num_tdls_conn_table_entries =
12874 			tgt_res_cfg->num_tdls_conn_table_entries;
12875 	resource_cfg->beacon_tx_offload_max_vdev =
12876 			tgt_res_cfg->beacon_tx_offload_max_vdev;
12877 	resource_cfg->num_multicast_filter_entries =
12878 			tgt_res_cfg->num_multicast_filter_entries;
12879 	resource_cfg->num_wow_filters =
12880 			tgt_res_cfg->num_wow_filters;
12881 	resource_cfg->num_keep_alive_pattern =
12882 			tgt_res_cfg->num_keep_alive_pattern;
12883 	resource_cfg->keep_alive_pattern_size =
12884 			tgt_res_cfg->keep_alive_pattern_size;
12885 	resource_cfg->max_tdls_concurrent_sleep_sta =
12886 			tgt_res_cfg->max_tdls_concurrent_sleep_sta;
12887 	resource_cfg->max_tdls_concurrent_buffer_sta =
12888 			tgt_res_cfg->max_tdls_concurrent_buffer_sta;
12889 	resource_cfg->wmi_send_separate =
12890 			tgt_res_cfg->wmi_send_separate;
12891 	resource_cfg->num_ocb_vdevs =
12892 			tgt_res_cfg->num_ocb_vdevs;
12893 	resource_cfg->num_ocb_channels =
12894 			tgt_res_cfg->num_ocb_channels;
12895 	resource_cfg->num_ocb_schedules =
12896 			tgt_res_cfg->num_ocb_schedules;
12897 	resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size;
12898 	resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters;
12899 	resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id;
12900 	resource_cfg->max_num_dbs_scan_duty_cycle =
12901 		tgt_res_cfg->max_num_dbs_scan_duty_cycle;
12902 	resource_cfg->sched_params = tgt_res_cfg->scheduler_params;
12903 	resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters;
12904 	resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs;
12905 	resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator;
12906 	if (tgt_res_cfg->atf_config)
12907 		WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1);
12908 	if (tgt_res_cfg->mgmt_comp_evt_bundle_support)
12909 		WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET(
12910 			resource_cfg->flag1, 1);
12911 	if (tgt_res_cfg->tx_msdu_new_partition_id_support)
12912 		WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET(
12913 			resource_cfg->flag1, 1);
12914 	if (tgt_res_cfg->cce_disable)
12915 		WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1);
12916 
12917 	wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg);
12918 }
12919 
12920 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd
12921  * @wmi_handle: pointer to wmi handle
12922  * @buf_ptr: pointer to current position in init command buffer
12923  * @len: pointer to length. This will be updated with current length of cmd
12924  * @param: point host parameters for init command
12925  *
12926  * Return: Updated pointer of buf_ptr.
12927  */
12928 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle,
12929 		uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param)
12930 {
12931 	uint16_t idx;
12932 
12933 	if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) {
12934 		wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode;
12935 		wmi_pdev_band_to_mac *band_to_mac;
12936 
12937 		hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *)
12938 			(buf_ptr + sizeof(wmi_init_cmd_fixed_param) +
12939 			 sizeof(wmi_resource_config) +
12940 			 WMI_TLV_HDR_SIZE + (param->num_mem_chunks *
12941 				 sizeof(wlan_host_memory_chunk)));
12942 
12943 		WMITLV_SET_HDR(&hw_mode->tlv_header,
12944 			WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param,
12945 			(WMITLV_GET_STRUCT_TLVLEN
12946 			 (wmi_pdev_set_hw_mode_cmd_fixed_param)));
12947 
12948 		hw_mode->hw_mode_index = param->hw_mode_id;
12949 		hw_mode->num_band_to_mac = param->num_band_to_mac;
12950 
12951 		buf_ptr = (uint8_t *) (hw_mode + 1);
12952 		band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr +
12953 				WMI_TLV_HDR_SIZE);
12954 		for (idx = 0; idx < param->num_band_to_mac; idx++) {
12955 			WMITLV_SET_HDR(&band_to_mac[idx].tlv_header,
12956 					WMITLV_TAG_STRUC_wmi_pdev_band_to_mac,
12957 					WMITLV_GET_STRUCT_TLVLEN
12958 					(wmi_pdev_band_to_mac));
12959 			band_to_mac[idx].pdev_id =
12960 				wmi_handle->ops->convert_pdev_id_host_to_target(
12961 					param->band_to_mac[idx].pdev_id);
12962 			band_to_mac[idx].start_freq =
12963 				param->band_to_mac[idx].start_freq;
12964 			band_to_mac[idx].end_freq =
12965 				param->band_to_mac[idx].end_freq;
12966 		}
12967 		*len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) +
12968 			(param->num_band_to_mac *
12969 			 sizeof(wmi_pdev_band_to_mac)) +
12970 			WMI_TLV_HDR_SIZE;
12971 
12972 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
12973 				(param->num_band_to_mac *
12974 				 sizeof(wmi_pdev_band_to_mac)));
12975 	}
12976 
12977 	return buf_ptr;
12978 }
12979 
12980 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle,
12981 		wmi_init_cmd_fixed_param *cmd)
12982 {
12983 	int num_whitelist;
12984 	wmi_abi_version my_vers;
12985 
12986 	num_whitelist = sizeof(version_whitelist) /
12987 		sizeof(wmi_whitelist_version_info);
12988 	my_vers.abi_version_0 = WMI_ABI_VERSION_0;
12989 	my_vers.abi_version_1 = WMI_ABI_VERSION_1;
12990 	my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0;
12991 	my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1;
12992 	my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2;
12993 	my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3;
12994 
12995 	wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist,
12996 			&my_vers,
12997 			(struct _wmi_abi_version *)&wmi_handle->fw_abi_version,
12998 			&cmd->host_abi_vers);
12999 
13000 	qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x",
13001 			__func__,
13002 			WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0),
13003 			WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0),
13004 			cmd->host_abi_vers.abi_version_ns_0,
13005 			cmd->host_abi_vers.abi_version_ns_1,
13006 			cmd->host_abi_vers.abi_version_ns_2,
13007 			cmd->host_abi_vers.abi_version_ns_3);
13008 
13009 	/* Save version sent from host -
13010 	 * Will be used to check ready event
13011 	 */
13012 	qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers,
13013 			sizeof(wmi_abi_version));
13014 }
13015 
13016 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf)
13017 {
13018 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
13019 	wmi_service_ready_event_fixed_param *ev;
13020 
13021 
13022 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
13023 
13024 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
13025 	if (!ev)
13026 		return QDF_STATUS_E_FAILURE;
13027 
13028 	/*Save fw version from service ready message */
13029 	/*This will be used while sending INIT message */
13030 	qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
13031 			sizeof(wmi_handle->fw_abi_version));
13032 
13033 	return QDF_STATUS_SUCCESS;
13034 }
13035 
13036 /**
13037  * wmi_unified_save_fw_version_cmd() - save fw version
13038  * @wmi_handle:      pointer to wmi handle
13039  * @res_cfg:         resource config
13040  * @num_mem_chunks:  no of mem chunck
13041  * @mem_chunk:       pointer to mem chunck structure
13042  *
13043  * This function sends IE information to firmware
13044  *
13045  * Return: QDF_STATUS_SUCCESS for success otherwise failure
13046  *
13047  */
13048 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle,
13049 					  void *evt_buf)
13050 {
13051 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
13052 	wmi_ready_event_fixed_param *ev = NULL;
13053 
13054 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
13055 	ev = param_buf->fixed_param;
13056 	if (!wmi_versions_are_compatible((struct _wmi_abi_version *)
13057 				&wmi_handle->final_abi_vers,
13058 				&ev->fw_abi_vers)) {
13059 		/*
13060 		 * Error: Our host version and the given firmware version
13061 		 * are incompatible.
13062 		 **/
13063 		WMI_LOGD("%s: Error: Incompatible WMI version."
13064 			"Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n",
13065 				__func__,
13066 			WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers.
13067 				abi_version_0),
13068 			WMI_VER_GET_MINOR(wmi_handle->final_abi_vers.
13069 				abi_version_0),
13070 			wmi_handle->final_abi_vers.abi_version_ns_0,
13071 			wmi_handle->final_abi_vers.abi_version_ns_1,
13072 			wmi_handle->final_abi_vers.abi_version_ns_2,
13073 			wmi_handle->final_abi_vers.abi_version_ns_3,
13074 			WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0),
13075 			WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0),
13076 			ev->fw_abi_vers.abi_version_ns_0,
13077 			ev->fw_abi_vers.abi_version_ns_1,
13078 			ev->fw_abi_vers.abi_version_ns_2,
13079 			ev->fw_abi_vers.abi_version_ns_3);
13080 
13081 		return QDF_STATUS_E_FAILURE;
13082 	}
13083 	qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers,
13084 			sizeof(wmi_abi_version));
13085 	qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
13086 			sizeof(wmi_abi_version));
13087 
13088 	return QDF_STATUS_SUCCESS;
13089 }
13090 
13091 /**
13092  * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw
13093  * @wmi_handle: wmi handle
13094  * @custom_addr: base mac address
13095  *
13096  * Return: QDF_STATUS_SUCCESS for success or error code
13097  */
13098 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle,
13099 					 uint8_t *custom_addr)
13100 {
13101 	wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd;
13102 	wmi_buf_t buf;
13103 	int err;
13104 
13105 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
13106 	if (!buf) {
13107 		WMI_LOGE("Failed to allocate buffer to send base macaddr cmd");
13108 		return QDF_STATUS_E_NOMEM;
13109 	}
13110 
13111 	cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf);
13112 	qdf_mem_zero(cmd, sizeof(*cmd));
13113 
13114 	WMITLV_SET_HDR(&cmd->tlv_header,
13115 		   WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param,
13116 		       WMITLV_GET_STRUCT_TLVLEN
13117 			       (wmi_pdev_set_base_macaddr_cmd_fixed_param));
13118 	WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr);
13119 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13120 							WMI_HOST_PDEV_ID_SOC);
13121 	wmi_mtrace(WMI_PDEV_SET_BASE_MACADDR_CMDID, NO_SESSION, 0);
13122 	err = wmi_unified_cmd_send(wmi_handle, buf,
13123 				   sizeof(*cmd),
13124 				   WMI_PDEV_SET_BASE_MACADDR_CMDID);
13125 	if (err) {
13126 		WMI_LOGE("Failed to send set_base_macaddr cmd");
13127 		wmi_buf_free(buf);
13128 		return QDF_STATUS_E_FAILURE;
13129 	}
13130 
13131 	return 0;
13132 }
13133 
13134 /**
13135  * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events
13136  * @handle: wmi handle
13137  * @event:  Event received from FW
13138  * @len:    Length of the event
13139  *
13140  * Enables the low frequency events and disables the high frequency
13141  * events. Bit 17 indicates if the event if low/high frequency.
13142  * 1 - high frequency, 0 - low frequency
13143  *
13144  * Return: 0 on successfully enabling/disabling the events
13145  */
13146 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle,
13147 		uint8_t *event,
13148 		uint32_t len)
13149 {
13150 	uint32_t num_of_diag_events_logs;
13151 	wmi_diag_event_log_config_fixed_param *cmd;
13152 	wmi_buf_t buf;
13153 	uint8_t *buf_ptr;
13154 	uint32_t *cmd_args, *evt_args;
13155 	uint32_t buf_len, i;
13156 
13157 	WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf;
13158 	wmi_diag_event_log_supported_event_fixed_params *wmi_event;
13159 
13160 	WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID");
13161 
13162 	param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event;
13163 	if (!param_buf) {
13164 		WMI_LOGE("Invalid log supported event buffer");
13165 		return QDF_STATUS_E_INVAL;
13166 	}
13167 	wmi_event = param_buf->fixed_param;
13168 	num_of_diag_events_logs = wmi_event->num_of_diag_events_logs;
13169 
13170 	if (num_of_diag_events_logs >
13171 	    param_buf->num_diag_events_logs_list) {
13172 		WMI_LOGE("message number of events %d is more than tlv hdr content %d",
13173 			 num_of_diag_events_logs,
13174 			 param_buf->num_diag_events_logs_list);
13175 		return QDF_STATUS_E_INVAL;
13176 	}
13177 
13178 	evt_args = param_buf->diag_events_logs_list;
13179 	if (!evt_args) {
13180 		WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d",
13181 				__func__, num_of_diag_events_logs);
13182 		return QDF_STATUS_E_INVAL;
13183 	}
13184 
13185 	WMI_LOGD("%s: num_of_diag_events_logs=%d",
13186 			__func__, num_of_diag_events_logs);
13187 
13188 	/* Free any previous allocation */
13189 	if (wmi_handle->events_logs_list)
13190 		qdf_mem_free(wmi_handle->events_logs_list);
13191 
13192 	if (num_of_diag_events_logs >
13193 		(WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) {
13194 		WMI_LOGE("%s: excess num of logs:%d", __func__,
13195 			num_of_diag_events_logs);
13196 		QDF_ASSERT(0);
13197 		return QDF_STATUS_E_INVAL;
13198 	}
13199 	/* Store the event list for run time enable/disable */
13200 	wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs *
13201 			sizeof(uint32_t));
13202 	if (!wmi_handle->events_logs_list) {
13203 		WMI_LOGE("%s: event log list memory allocation failed",
13204 				__func__);
13205 		return QDF_STATUS_E_NOMEM;
13206 	}
13207 	wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs;
13208 
13209 	/* Prepare the send buffer */
13210 	buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
13211 		(num_of_diag_events_logs * sizeof(uint32_t));
13212 
13213 	buf = wmi_buf_alloc(wmi_handle, buf_len);
13214 	if (!buf) {
13215 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13216 		qdf_mem_free(wmi_handle->events_logs_list);
13217 		wmi_handle->events_logs_list = NULL;
13218 		return QDF_STATUS_E_NOMEM;
13219 	}
13220 
13221 	cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf);
13222 	buf_ptr = (uint8_t *) cmd;
13223 
13224 	WMITLV_SET_HDR(&cmd->tlv_header,
13225 			WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param,
13226 			WMITLV_GET_STRUCT_TLVLEN(
13227 				wmi_diag_event_log_config_fixed_param));
13228 
13229 	cmd->num_of_diag_events_logs = num_of_diag_events_logs;
13230 
13231 	buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param);
13232 
13233 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
13234 			(num_of_diag_events_logs * sizeof(uint32_t)));
13235 
13236 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
13237 
13238 	/* Populate the events */
13239 	for (i = 0; i < num_of_diag_events_logs; i++) {
13240 		/* Low freq (0) - Enable (1) the event
13241 		 * High freq (1) - Disable (0) the event
13242 		 */
13243 		WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i],
13244 				!(WMI_DIAG_FREQUENCY_GET(evt_args[i])));
13245 		/* Set the event ID */
13246 		WMI_DIAG_ID_SET(cmd_args[i],
13247 				WMI_DIAG_ID_GET(evt_args[i]));
13248 		/* Set the type */
13249 		WMI_DIAG_TYPE_SET(cmd_args[i],
13250 				WMI_DIAG_TYPE_GET(evt_args[i]));
13251 		/* Storing the event/log list in WMI */
13252 		wmi_handle->events_logs_list[i] = evt_args[i];
13253 	}
13254 
13255 	wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0);
13256 	if (wmi_unified_cmd_send(wmi_handle, buf, buf_len,
13257 				WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) {
13258 		WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed",
13259 				__func__);
13260 		wmi_buf_free(buf);
13261 		/* Not clearing events_logs_list, though wmi cmd failed.
13262 		 * Host can still have this list
13263 		 */
13264 		return QDF_STATUS_E_INVAL;
13265 	}
13266 
13267 	return 0;
13268 }
13269 
13270 /**
13271  * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id
13272  * @wmi_handle: wmi handle
13273  * @start_log: Start logging related parameters
13274  *
13275  * Send the command to the FW based on which specific logging of diag
13276  * event/log id can be started/stopped
13277  *
13278  * Return: None
13279  */
13280 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle,
13281 		struct wmi_wifi_start_log *start_log)
13282 {
13283 	wmi_diag_event_log_config_fixed_param *cmd;
13284 	wmi_buf_t buf;
13285 	uint8_t *buf_ptr;
13286 	uint32_t len, count, log_level, i;
13287 	uint32_t *cmd_args;
13288 	uint32_t total_len;
13289 	count = 0;
13290 
13291 	if (!wmi_handle->events_logs_list) {
13292 		WMI_LOGD("%s: Not received event/log list from FW, yet",
13293 			 __func__);
13294 		return QDF_STATUS_E_NOMEM;
13295 	}
13296 	/* total_len stores the number of events where BITS 17 and 18 are set.
13297 	 * i.e., events of high frequency (17) and for extended debugging (18)
13298 	 */
13299 	total_len = 0;
13300 	for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) {
13301 		if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) &&
13302 		    (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i])))
13303 			total_len++;
13304 	}
13305 
13306 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
13307 		(total_len * sizeof(uint32_t));
13308 
13309 	buf = wmi_buf_alloc(wmi_handle, len);
13310 	if (!buf) {
13311 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13312 		return QDF_STATUS_E_NOMEM;
13313 	}
13314 	cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf);
13315 	buf_ptr = (uint8_t *) cmd;
13316 
13317 	WMITLV_SET_HDR(&cmd->tlv_header,
13318 			WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param,
13319 			WMITLV_GET_STRUCT_TLVLEN(
13320 				wmi_diag_event_log_config_fixed_param));
13321 
13322 	cmd->num_of_diag_events_logs = total_len;
13323 
13324 	buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param);
13325 
13326 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
13327 			(total_len * sizeof(uint32_t)));
13328 
13329 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
13330 
13331 	if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE)
13332 		log_level = 1;
13333 	else
13334 		log_level = 0;
13335 
13336 	WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level);
13337 	for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) {
13338 		uint32_t val = wmi_handle->events_logs_list[i];
13339 		if ((WMI_DIAG_FREQUENCY_GET(val)) &&
13340 				(WMI_DIAG_EXT_FEATURE_GET(val))) {
13341 
13342 			WMI_DIAG_ID_SET(cmd_args[count],
13343 					WMI_DIAG_ID_GET(val));
13344 			WMI_DIAG_TYPE_SET(cmd_args[count],
13345 					WMI_DIAG_TYPE_GET(val));
13346 			WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count],
13347 					log_level);
13348 			WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val);
13349 			count++;
13350 		}
13351 	}
13352 
13353 	wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0);
13354 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13355 				WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) {
13356 		WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed",
13357 				__func__);
13358 		wmi_buf_free(buf);
13359 		return QDF_STATUS_E_INVAL;
13360 	}
13361 
13362 	return QDF_STATUS_SUCCESS;
13363 }
13364 
13365 /**
13366  * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW
13367  * @wmi_handle: WMI handle
13368  *
13369  * This function is used to send the flush command to the FW,
13370  * that will flush the fw logs that are residue in the FW
13371  *
13372  * Return: None
13373  */
13374 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle)
13375 {
13376 	wmi_debug_mesg_flush_fixed_param *cmd;
13377 	wmi_buf_t buf;
13378 	int len = sizeof(*cmd);
13379 	QDF_STATUS ret;
13380 
13381 	buf = wmi_buf_alloc(wmi_handle, len);
13382 	if (!buf) {
13383 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
13384 		return QDF_STATUS_E_NOMEM;
13385 	}
13386 
13387 	cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf);
13388 	WMITLV_SET_HDR(&cmd->tlv_header,
13389 			WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param,
13390 			WMITLV_GET_STRUCT_TLVLEN(
13391 				wmi_debug_mesg_flush_fixed_param));
13392 	cmd->reserved0 = 0;
13393 
13394 	wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0);
13395 	ret = wmi_unified_cmd_send(wmi_handle,
13396 			buf,
13397 			len,
13398 			WMI_DEBUG_MESG_FLUSH_CMDID);
13399 	if (QDF_IS_STATUS_ERROR(ret)) {
13400 		WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID");
13401 		wmi_buf_free(buf);
13402 		return QDF_STATUS_E_INVAL;
13403 	}
13404 	WMI_LOGD("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW");
13405 
13406 	return ret;
13407 }
13408 
13409 /**
13410  * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW
13411  * @wmi_handle: wmi handle
13412  * @msg: PCL structure containing the PCL and the number of channels
13413  *
13414  * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
13415  * firmware. The DBS Manager is the consumer of this information in the WLAN
13416  * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
13417  * to migrate to a new channel without host driver involvement. An example of
13418  * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
13419  * manage the channel selection without firmware involvement.
13420  *
13421  * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual
13422  * channel list. The weights corresponds to the channels sent in
13423  * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
13424  * weightage compared to the non PCL channels.
13425  *
13426  * Return: Success if the cmd is sent successfully to the firmware
13427  */
13428 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle,
13429 				struct wmi_pcl_chan_weights *msg)
13430 {
13431 	wmi_pdev_set_pcl_cmd_fixed_param *cmd;
13432 	wmi_buf_t buf;
13433 	uint8_t *buf_ptr;
13434 	uint32_t *cmd_args, i, len;
13435 	uint32_t chan_len;
13436 
13437 	chan_len = msg->saved_num_chan;
13438 
13439 	len = sizeof(*cmd) +
13440 		WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t));
13441 
13442 	buf = wmi_buf_alloc(wmi_handle, len);
13443 	if (!buf) {
13444 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13445 		return QDF_STATUS_E_NOMEM;
13446 	}
13447 
13448 	cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf);
13449 	buf_ptr = (uint8_t *) cmd;
13450 	WMITLV_SET_HDR(&cmd->tlv_header,
13451 		WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param,
13452 		WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param));
13453 
13454 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13455 							WMI_HOST_PDEV_ID_SOC);
13456 	cmd->num_chan = chan_len;
13457 	WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan);
13458 
13459 	buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param);
13460 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
13461 			(chan_len * sizeof(uint32_t)));
13462 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
13463 	for (i = 0; i < chan_len ; i++) {
13464 		cmd_args[i] = msg->weighed_valid_list[i];
13465 		WMI_LOGD("%s: chan:%d weight:%d", __func__,
13466 			msg->saved_chan_list[i], cmd_args[i]);
13467 	}
13468 	wmi_mtrace(WMI_PDEV_SET_PCL_CMDID, NO_SESSION, 0);
13469 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13470 				WMI_PDEV_SET_PCL_CMDID)) {
13471 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__);
13472 		wmi_buf_free(buf);
13473 		return QDF_STATUS_E_FAILURE;
13474 	}
13475 	return QDF_STATUS_SUCCESS;
13476 }
13477 
13478 /**
13479  * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW
13480  * @wmi_handle: wmi handle
13481  * @msg: Structure containing the following parameters
13482  *
13483  * - hw_mode_index: The HW_Mode field is a enumerated type that is selected
13484  * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID.
13485  *
13486  * Provides notification to the WLAN firmware that host driver is requesting a
13487  * HardWare (HW) Mode change. This command is needed to support iHelium in the
13488  * configurations that include the Dual Band Simultaneous (DBS) feature.
13489  *
13490  * Return: Success if the cmd is sent successfully to the firmware
13491  */
13492 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle,
13493 				uint32_t hw_mode_index)
13494 {
13495 	wmi_pdev_set_hw_mode_cmd_fixed_param *cmd;
13496 	wmi_buf_t buf;
13497 	uint32_t len;
13498 
13499 	len = sizeof(*cmd);
13500 
13501 	buf = wmi_buf_alloc(wmi_handle, len);
13502 	if (!buf) {
13503 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13504 		return QDF_STATUS_E_NOMEM;
13505 	}
13506 
13507 	cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf);
13508 	WMITLV_SET_HDR(&cmd->tlv_header,
13509 		WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param,
13510 		WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param));
13511 
13512 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13513 							WMI_HOST_PDEV_ID_SOC);
13514 	cmd->hw_mode_index = hw_mode_index;
13515 	WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index);
13516 
13517 	wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0);
13518 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13519 				WMI_PDEV_SET_HW_MODE_CMDID)) {
13520 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID",
13521 			__func__);
13522 		wmi_buf_free(buf);
13523 		return QDF_STATUS_E_FAILURE;
13524 	}
13525 
13526 	return QDF_STATUS_SUCCESS;
13527 }
13528 
13529 #ifdef WLAN_POLICY_MGR_ENABLE
13530 /**
13531  * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW
13532  * @wmi_handle: wmi handle
13533  * @msg: Dual MAC config parameters
13534  *
13535  * Configures WLAN firmware with the dual MAC features
13536  *
13537  * Return: QDF_STATUS. 0 on success.
13538  */
13539 static
13540 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle,
13541 		struct policy_mgr_dual_mac_config *msg)
13542 {
13543 	wmi_pdev_set_mac_config_cmd_fixed_param *cmd;
13544 	wmi_buf_t buf;
13545 	uint32_t len;
13546 
13547 	len = sizeof(*cmd);
13548 
13549 	buf = wmi_buf_alloc(wmi_handle, len);
13550 	if (!buf) {
13551 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13552 		return QDF_STATUS_E_FAILURE;
13553 	}
13554 
13555 	cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf);
13556 	WMITLV_SET_HDR(&cmd->tlv_header,
13557 		WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param,
13558 		WMITLV_GET_STRUCT_TLVLEN(
13559 			wmi_pdev_set_mac_config_cmd_fixed_param));
13560 
13561 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13562 							WMI_HOST_PDEV_ID_SOC);
13563 	cmd->concurrent_scan_config_bits = msg->scan_config;
13564 	cmd->fw_mode_config_bits = msg->fw_mode_config;
13565 	WMI_LOGD("%s: scan_config:%x fw_mode_config:%x",
13566 		 __func__, msg->scan_config, msg->fw_mode_config);
13567 
13568 	wmi_mtrace(WMI_PDEV_SET_MAC_CONFIG_CMDID, NO_SESSION, 0);
13569 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13570 				WMI_PDEV_SET_MAC_CONFIG_CMDID)) {
13571 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID",
13572 				__func__);
13573 		wmi_buf_free(buf);
13574 	}
13575 	return QDF_STATUS_SUCCESS;
13576 }
13577 #endif
13578 
13579 #ifdef BIG_ENDIAN_HOST
13580 /**
13581 * fips_conv_data_be() - LE to BE conversion of FIPS ev data
13582 * @param data_len - data length
13583 * @param data - pointer to data
13584 *
13585 * Return: QDF_STATUS - success or error status
13586 */
13587 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle,
13588 			struct fips_params *param)
13589 {
13590 	unsigned char *key_unaligned, *data_unaligned;
13591 	int c;
13592 	u_int8_t *key_aligned = NULL;
13593 	u_int8_t *data_aligned = NULL;
13594 
13595 	/* Assigning unaligned space to copy the key */
13596 	key_unaligned = qdf_mem_malloc(
13597 		sizeof(u_int8_t)*param->key_len + FIPS_ALIGN);
13598 	data_unaligned = qdf_mem_malloc(
13599 		sizeof(u_int8_t)*param->data_len + FIPS_ALIGN);
13600 
13601 	/* Checking if kmalloc is successful to allocate space */
13602 	if (key_unaligned == NULL)
13603 		return QDF_STATUS_SUCCESS;
13604 	/* Checking if space is aligned */
13605 	if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) {
13606 		/* align to 4 */
13607 		key_aligned =
13608 		(u_int8_t *)FIPS_ALIGNTO(key_unaligned,
13609 			FIPS_ALIGN);
13610 	} else {
13611 		key_aligned = (u_int8_t *)key_unaligned;
13612 	}
13613 
13614 	/* memset and copy content from key to key aligned */
13615 	OS_MEMSET(key_aligned, 0, param->key_len);
13616 	OS_MEMCPY(key_aligned, param->key, param->key_len);
13617 
13618 	/* print a hexdump for host debug */
13619 	print_hex_dump(KERN_DEBUG,
13620 		"\t Aligned and Copied Key:@@@@ ",
13621 		DUMP_PREFIX_NONE,
13622 		16, 1, key_aligned, param->key_len, true);
13623 
13624 	/* Checking if kmalloc is successful to allocate space */
13625 	if (data_unaligned == NULL)
13626 		return QDF_STATUS_SUCCESS;
13627 	/* Checking of space is aligned */
13628 	if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) {
13629 		/* align to 4 */
13630 		data_aligned =
13631 		(u_int8_t *)FIPS_ALIGNTO(data_unaligned,
13632 				FIPS_ALIGN);
13633 	} else {
13634 		data_aligned = (u_int8_t *)data_unaligned;
13635 	}
13636 
13637 	/* memset and copy content from data to data aligned */
13638 	OS_MEMSET(data_aligned, 0, param->data_len);
13639 	OS_MEMCPY(data_aligned, param->data, param->data_len);
13640 
13641 	/* print a hexdump for host debug */
13642 	print_hex_dump(KERN_DEBUG,
13643 		"\t Properly Aligned and Copied Data:@@@@ ",
13644 	DUMP_PREFIX_NONE,
13645 	16, 1, data_aligned, param->data_len, true);
13646 
13647 	/* converting to little Endian both key_aligned and
13648 	* data_aligned*/
13649 	for (c = 0; c < param->key_len/4; c++) {
13650 		*((u_int32_t *)key_aligned+c) =
13651 		qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c));
13652 	}
13653 	for (c = 0; c < param->data_len/4; c++) {
13654 		*((u_int32_t *)data_aligned+c) =
13655 		qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c));
13656 	}
13657 
13658 	/* update endian data to key and data vectors */
13659 	OS_MEMCPY(param->key, key_aligned, param->key_len);
13660 	OS_MEMCPY(param->data, data_aligned, param->data_len);
13661 
13662 	/* clean up allocated spaces */
13663 	qdf_mem_free(key_unaligned);
13664 	key_unaligned = NULL;
13665 	key_aligned = NULL;
13666 
13667 	qdf_mem_free(data_unaligned);
13668 	data_unaligned = NULL;
13669 	data_aligned = NULL;
13670 
13671 	return QDF_STATUS_SUCCESS;
13672 }
13673 #else
13674 /**
13675 * fips_align_data_be() - DUMMY for LE platform
13676 *
13677 * Return: QDF_STATUS - success
13678 */
13679 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle,
13680 		struct fips_params *param)
13681 {
13682 	return QDF_STATUS_SUCCESS;
13683 }
13684 #endif
13685 
13686 
13687 /**
13688  * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw
13689  * @wmi_handle: wmi handle
13690  * @param: pointer to hold pdev fips param
13691  *
13692  * Return: 0 for success or error code
13693  */
13694 static QDF_STATUS
13695 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle,
13696 		struct fips_params *param)
13697 {
13698 	wmi_pdev_fips_cmd_fixed_param *cmd;
13699 	wmi_buf_t buf;
13700 	uint8_t *buf_ptr;
13701 	uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param);
13702 	QDF_STATUS retval = QDF_STATUS_SUCCESS;
13703 
13704 	/* Length TLV placeholder for array of bytes */
13705 	len += WMI_TLV_HDR_SIZE;
13706 	if (param->data_len)
13707 		len += (param->data_len*sizeof(uint8_t));
13708 
13709 	/*
13710 	* Data length must be multiples of 16 bytes - checked against 0xF -
13711 	* and must be less than WMI_SVC_MSG_SIZE - static size of
13712 	* wmi_pdev_fips_cmd structure
13713 	*/
13714 
13715 	/* do sanity on the input */
13716 	if (!(((param->data_len & 0xF) == 0) &&
13717 			((param->data_len > 0) &&
13718 			(param->data_len < (WMI_HOST_MAX_BUFFER_SIZE -
13719 		sizeof(wmi_pdev_fips_cmd_fixed_param)))))) {
13720 		return QDF_STATUS_E_INVAL;
13721 	}
13722 
13723 	buf = wmi_buf_alloc(wmi_handle, len);
13724 	if (!buf) {
13725 		qdf_print("%s:wmi_buf_alloc failed", __func__);
13726 		return QDF_STATUS_E_FAILURE;
13727 	}
13728 
13729 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
13730 	cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr;
13731 	WMITLV_SET_HDR(&cmd->tlv_header,
13732 		WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param,
13733 		WMITLV_GET_STRUCT_TLVLEN
13734 		(wmi_pdev_fips_cmd_fixed_param));
13735 
13736 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13737 								param->pdev_id);
13738 	if (param->key != NULL && param->data != NULL) {
13739 		cmd->key_len = param->key_len;
13740 		cmd->data_len = param->data_len;
13741 		cmd->fips_cmd = !!(param->op);
13742 
13743 		if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS)
13744 			return QDF_STATUS_E_FAILURE;
13745 
13746 		qdf_mem_copy(cmd->key, param->key, param->key_len);
13747 
13748 		if (param->mode == FIPS_ENGINE_AES_CTR ||
13749 			param->mode == FIPS_ENGINE_AES_MIC) {
13750 			cmd->mode = param->mode;
13751 		} else {
13752 			cmd->mode = FIPS_ENGINE_AES_CTR;
13753 		}
13754 		qdf_print("Key len = %d, Data len = %d",
13755 			  cmd->key_len, cmd->data_len);
13756 
13757 		print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1,
13758 				cmd->key, cmd->key_len, true);
13759 		buf_ptr += sizeof(*cmd);
13760 
13761 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len);
13762 
13763 		buf_ptr += WMI_TLV_HDR_SIZE;
13764 		if (param->data_len)
13765 			qdf_mem_copy(buf_ptr,
13766 				(uint8_t *) param->data, param->data_len);
13767 
13768 		print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE,
13769 			16, 1, buf_ptr, cmd->data_len, true);
13770 
13771 		buf_ptr += param->data_len;
13772 
13773 		wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0);
13774 		retval = wmi_unified_cmd_send(wmi_handle, buf, len,
13775 			WMI_PDEV_FIPS_CMDID);
13776 		qdf_print("%s return value %d", __func__, retval);
13777 	} else {
13778 		qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__);
13779 		wmi_buf_free(buf);
13780 		retval = -QDF_STATUS_E_BADMSG;
13781 	}
13782 
13783 	return retval;
13784 }
13785 
13786 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
13787 /**
13788  * send_add_wow_wakeup_event_cmd_tlv() -  Configures wow wakeup events.
13789  * @wmi_handle: wmi handle
13790  * @vdev_id: vdev id
13791  * @bitmap: Event bitmap
13792  * @enable: enable/disable
13793  *
13794  * Return: CDF status
13795  */
13796 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle,
13797 					uint32_t vdev_id,
13798 					uint32_t *bitmap,
13799 					bool enable)
13800 {
13801 	WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd;
13802 	uint16_t len;
13803 	wmi_buf_t buf;
13804 	int ret;
13805 
13806 	len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param);
13807 	buf = wmi_buf_alloc(wmi_handle, len);
13808 	if (!buf) {
13809 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
13810 		return QDF_STATUS_E_NOMEM;
13811 	}
13812 	cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf);
13813 	WMITLV_SET_HDR(&cmd->tlv_header,
13814 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param,
13815 		       WMITLV_GET_STRUCT_TLVLEN
13816 			       (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param));
13817 	cmd->vdev_id = vdev_id;
13818 	cmd->is_add = enable;
13819 	qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) *
13820 		     WMI_WOW_MAX_EVENT_BM_LEN);
13821 
13822 	WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0],
13823 		 cmd->event_bitmaps[1], cmd->event_bitmaps[2],
13824 		 cmd->event_bitmaps[3], enable ? "enabled" : "disabled");
13825 
13826 	wmi_mtrace(WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, cmd->vdev_id, 0);
13827 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
13828 				   WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
13829 	if (ret) {
13830 		WMI_LOGE("Failed to config wow wakeup event");
13831 		wmi_buf_free(buf);
13832 		return QDF_STATUS_E_FAILURE;
13833 	}
13834 
13835 	return QDF_STATUS_SUCCESS;
13836 }
13837 
13838 /**
13839  * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW.
13840  * @wmi_handle: wmi handle
13841  * @vdev_id: vdev id
13842  * @ptrn_id: pattern id
13843  * @ptrn: pattern
13844  * @ptrn_len: pattern length
13845  * @ptrn_offset: pattern offset
13846  * @mask: mask
13847  * @mask_len: mask length
13848  * @user: true for user configured pattern and false for default pattern
13849  * @default_patterns: default patterns
13850  *
13851  * Return: CDF status
13852  */
13853 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle,
13854 				uint8_t vdev_id, uint8_t ptrn_id,
13855 				const uint8_t *ptrn, uint8_t ptrn_len,
13856 				uint8_t ptrn_offset, const uint8_t *mask,
13857 				uint8_t mask_len, bool user,
13858 				uint8_t default_patterns)
13859 {
13860 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
13861 	WOW_BITMAP_PATTERN_T *bitmap_pattern;
13862 	wmi_buf_t buf;
13863 	uint8_t *buf_ptr;
13864 	int32_t len;
13865 	int ret;
13866 
13867 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
13868 		WMI_TLV_HDR_SIZE +
13869 		1 * sizeof(WOW_BITMAP_PATTERN_T) +
13870 		WMI_TLV_HDR_SIZE +
13871 		0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
13872 		WMI_TLV_HDR_SIZE +
13873 		0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
13874 		WMI_TLV_HDR_SIZE +
13875 		0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
13876 		WMI_TLV_HDR_SIZE +
13877 		0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
13878 
13879 	buf = wmi_buf_alloc(wmi_handle, len);
13880 	if (!buf) {
13881 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
13882 		return QDF_STATUS_E_NOMEM;
13883 	}
13884 
13885 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
13886 	buf_ptr = (uint8_t *) cmd;
13887 
13888 	WMITLV_SET_HDR(&cmd->tlv_header,
13889 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
13890 		       WMITLV_GET_STRUCT_TLVLEN
13891 			       (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
13892 	cmd->vdev_id = vdev_id;
13893 	cmd->pattern_id = ptrn_id;
13894 
13895 	cmd->pattern_type = WOW_BITMAP_PATTERN;
13896 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
13897 
13898 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
13899 		       sizeof(WOW_BITMAP_PATTERN_T));
13900 	buf_ptr += WMI_TLV_HDR_SIZE;
13901 	bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr;
13902 
13903 	WMITLV_SET_HDR(&bitmap_pattern->tlv_header,
13904 		       WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T,
13905 		       WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T));
13906 
13907 	qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len);
13908 	qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len);
13909 
13910 	bitmap_pattern->pattern_offset = ptrn_offset;
13911 	bitmap_pattern->pattern_len = ptrn_len;
13912 
13913 	if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE)
13914 		bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE;
13915 
13916 	if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE)
13917 		bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE;
13918 
13919 	bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len;
13920 	bitmap_pattern->pattern_id = ptrn_id;
13921 
13922 	WMI_LOGD("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d",
13923 		 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len,
13924 		 bitmap_pattern->pattern_offset, user);
13925 	WMI_LOGD("Pattern : ");
13926 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
13927 			   &bitmap_pattern->patternbuf[0],
13928 			   bitmap_pattern->pattern_len);
13929 
13930 	WMI_LOGD("Mask : ");
13931 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
13932 			   &bitmap_pattern->bitmaskbuf[0],
13933 			   bitmap_pattern->pattern_len);
13934 
13935 	buf_ptr += sizeof(WOW_BITMAP_PATTERN_T);
13936 
13937 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
13938 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
13939 	buf_ptr += WMI_TLV_HDR_SIZE;
13940 
13941 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
13942 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
13943 	buf_ptr += WMI_TLV_HDR_SIZE;
13944 
13945 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
13946 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
13947 	buf_ptr += WMI_TLV_HDR_SIZE;
13948 
13949 	/* Fill TLV for pattern_info_timeout but no data. */
13950 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
13951 	buf_ptr += WMI_TLV_HDR_SIZE;
13952 
13953 	/* Fill TLV for ratelimit_interval with dummy data as this fix elem */
13954 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t));
13955 	buf_ptr += WMI_TLV_HDR_SIZE;
13956 	*(uint32_t *) buf_ptr = 0;
13957 
13958 	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
13959 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
13960 				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
13961 	if (ret) {
13962 		WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__);
13963 		wmi_buf_free(buf);
13964 		return QDF_STATUS_E_FAILURE;
13965 	}
13966 
13967 	return QDF_STATUS_SUCCESS;
13968 }
13969 
13970 /**
13971  * fill_arp_offload_params_tlv() - Fill ARP offload data
13972  * @wmi_handle: wmi handle
13973  * @offload_req: offload request
13974  * @buf_ptr: buffer pointer
13975  *
13976  * To fill ARP offload data to firmware
13977  * when target goes to wow mode.
13978  *
13979  * Return: None
13980  */
13981 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle,
13982 		struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr)
13983 {
13984 
13985 	int i;
13986 	WMI_ARP_OFFLOAD_TUPLE *arp_tuple;
13987 	bool enable_or_disable = offload_req->enable;
13988 
13989 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
13990 		(WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE)));
13991 	*buf_ptr += WMI_TLV_HDR_SIZE;
13992 	for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) {
13993 		arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr;
13994 		WMITLV_SET_HDR(&arp_tuple->tlv_header,
13995 			WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE,
13996 			WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE));
13997 
13998 		/* Fill data for ARP and NS in the first tupple for LA */
13999 		if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) {
14000 			/* Copy the target ip addr and flags */
14001 			arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID;
14002 			qdf_mem_copy(&arp_tuple->target_ipaddr,
14003 					offload_req->host_ipv4_addr,
14004 					WMI_IPV4_ADDR_LEN);
14005 			WMI_LOGD("ARPOffload IP4 address: %pI4",
14006 					offload_req->host_ipv4_addr);
14007 		}
14008 		*buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE);
14009 	}
14010 }
14011 
14012 #ifdef WLAN_NS_OFFLOAD
14013 /**
14014  * fill_ns_offload_params_tlv() - Fill NS offload data
14015  * @wmi|_handle: wmi handle
14016  * @offload_req: offload request
14017  * @buf_ptr: buffer pointer
14018  *
14019  * To fill NS offload data to firmware
14020  * when target goes to wow mode.
14021  *
14022  * Return: None
14023  */
14024 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle,
14025 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14026 {
14027 
14028 	int i;
14029 	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
14030 
14031 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14032 		(WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE)));
14033 	*buf_ptr += WMI_TLV_HDR_SIZE;
14034 	for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) {
14035 		ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr;
14036 		WMITLV_SET_HDR(&ns_tuple->tlv_header,
14037 			WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
14038 			(sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE));
14039 
14040 		/*
14041 		 * Fill data only for NS offload in the first ARP tuple for LA
14042 		 */
14043 		if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) {
14044 			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
14045 			/* Copy the target/solicitation/remote ip addr */
14046 			if (ns_req->target_ipv6_addr_valid[i])
14047 				qdf_mem_copy(&ns_tuple->target_ipaddr[0],
14048 					&ns_req->target_ipv6_addr[i],
14049 					sizeof(WMI_IPV6_ADDR));
14050 			qdf_mem_copy(&ns_tuple->solicitation_ipaddr,
14051 				&ns_req->self_ipv6_addr[i],
14052 				sizeof(WMI_IPV6_ADDR));
14053 			if (ns_req->target_ipv6_addr_ac_type[i]) {
14054 				ns_tuple->flags |=
14055 					WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST;
14056 			}
14057 			WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6",
14058 				i, &ns_req->self_ipv6_addr[i],
14059 				&ns_req->target_ipv6_addr[i]);
14060 
14061 			/* target MAC is optional, check if it is valid,
14062 			 * if this is not valid, the target will use the known
14063 			 * local MAC address rather than the tuple
14064 			 */
14065 			WMI_CHAR_ARRAY_TO_MAC_ADDR(
14066 				ns_req->self_macaddr.bytes,
14067 				&ns_tuple->target_mac);
14068 			if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
14069 				(ns_tuple->target_mac.mac_addr47to32 != 0)) {
14070 				ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
14071 			}
14072 		}
14073 		*buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
14074 	}
14075 }
14076 
14077 
14078 /**
14079  * fill_nsoffload_ext_tlv() - Fill NS offload ext data
14080  * @wmi: wmi handle
14081  * @offload_req: offload request
14082  * @buf_ptr: buffer pointer
14083  *
14084  * To fill extended NS offload extended data to firmware
14085  * when target goes to wow mode.
14086  *
14087  * Return: None
14088  */
14089 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle,
14090 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14091 {
14092 	int i;
14093 	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
14094 	uint32_t count, num_ns_ext_tuples;
14095 
14096 	count = ns_req->num_ns_offload_count;
14097 	num_ns_ext_tuples = ns_req->num_ns_offload_count -
14098 		WMI_MAX_NS_OFFLOADS;
14099 
14100 	/* Populate extended NS offload tuples */
14101 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14102 		(num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE)));
14103 	*buf_ptr += WMI_TLV_HDR_SIZE;
14104 	for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) {
14105 		ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr;
14106 		WMITLV_SET_HDR(&ns_tuple->tlv_header,
14107 			WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
14108 			(sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE));
14109 
14110 		/*
14111 		 * Fill data only for NS offload in the first ARP tuple for LA
14112 		 */
14113 		if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) {
14114 			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
14115 			/* Copy the target/solicitation/remote ip addr */
14116 			if (ns_req->target_ipv6_addr_valid[i])
14117 				qdf_mem_copy(&ns_tuple->target_ipaddr[0],
14118 					&ns_req->target_ipv6_addr[i],
14119 					sizeof(WMI_IPV6_ADDR));
14120 			qdf_mem_copy(&ns_tuple->solicitation_ipaddr,
14121 				&ns_req->self_ipv6_addr[i],
14122 				sizeof(WMI_IPV6_ADDR));
14123 			if (ns_req->target_ipv6_addr_ac_type[i]) {
14124 				ns_tuple->flags |=
14125 					WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST;
14126 			}
14127 			WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6",
14128 				i, &ns_req->self_ipv6_addr[i],
14129 				&ns_req->target_ipv6_addr[i]);
14130 
14131 			/* target MAC is optional, check if it is valid,
14132 			 * if this is not valid, the target will use the
14133 			 * known local MAC address rather than the tuple
14134 			 */
14135 			 WMI_CHAR_ARRAY_TO_MAC_ADDR(
14136 				ns_req->self_macaddr.bytes,
14137 				&ns_tuple->target_mac);
14138 			if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
14139 				(ns_tuple->target_mac.mac_addr47to32 != 0)) {
14140 				ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
14141 			}
14142 		}
14143 		*buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
14144 	}
14145 }
14146 #else
14147 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle,
14148 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14149 {
14150 }
14151 
14152 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle,
14153 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14154 {
14155 }
14156 #endif
14157 
14158 /**
14159  * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload
14160  * @wma: wmi handle
14161  * @arp_offload_req: arp offload request
14162  * @ns_offload_req: ns offload request
14163  * @arp_only: flag
14164  *
14165  * To configure ARP NS off load data to firmware
14166  * when target goes to wow mode.
14167  *
14168  * Return: QDF Status
14169  */
14170 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle,
14171 			   struct pmo_arp_offload_params *arp_offload_req,
14172 			   struct pmo_ns_offload_params *ns_offload_req,
14173 			   uint8_t vdev_id)
14174 {
14175 	int32_t res;
14176 	WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd;
14177 	uint8_t *buf_ptr;
14178 	wmi_buf_t buf;
14179 	int32_t len;
14180 	uint32_t count = 0, num_ns_ext_tuples = 0;
14181 
14182 	count = ns_offload_req->num_ns_offload_count;
14183 
14184 	/*
14185 	 * TLV place holder size for array of NS tuples
14186 	 * TLV place holder size for array of ARP tuples
14187 	 */
14188 	len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) +
14189 		WMI_TLV_HDR_SIZE +
14190 		WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) +
14191 		WMI_TLV_HDR_SIZE +
14192 		WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE);
14193 
14194 	/*
14195 	 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate
14196 	 * extra length for extended NS offload tuples which follows ARP offload
14197 	 * tuples. Host needs to fill this structure in following format:
14198 	 * 2 NS ofload tuples
14199 	 * 2 ARP offload tuples
14200 	 * N numbers of extended NS offload tuples if HDD has given more than
14201 	 * 2 NS offload addresses
14202 	 */
14203 	if (count > WMI_MAX_NS_OFFLOADS) {
14204 		num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS;
14205 		len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples
14206 			   * sizeof(WMI_NS_OFFLOAD_TUPLE);
14207 	}
14208 
14209 	buf = wmi_buf_alloc(wmi_handle, len);
14210 	if (!buf) {
14211 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
14212 		return QDF_STATUS_E_NOMEM;
14213 	}
14214 
14215 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14216 	cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr;
14217 	WMITLV_SET_HDR(&cmd->tlv_header,
14218 		       WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param,
14219 		       WMITLV_GET_STRUCT_TLVLEN
14220 			       (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param));
14221 	cmd->flags = 0;
14222 	cmd->vdev_id = vdev_id;
14223 	cmd->num_ns_ext_tuples = num_ns_ext_tuples;
14224 
14225 	WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id);
14226 
14227 	buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param);
14228 	fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr);
14229 	fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr);
14230 	if (num_ns_ext_tuples)
14231 		fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr);
14232 
14233 	wmi_mtrace(WMI_SET_ARP_NS_OFFLOAD_CMDID, cmd->vdev_id, 0);
14234 	res = wmi_unified_cmd_send(wmi_handle, buf, len,
14235 				     WMI_SET_ARP_NS_OFFLOAD_CMDID);
14236 	if (res) {
14237 		WMI_LOGE("Failed to enable ARP NDP/NSffload");
14238 		wmi_buf_free(buf);
14239 		return QDF_STATUS_E_FAILURE;
14240 	}
14241 
14242 	return QDF_STATUS_SUCCESS;
14243 }
14244 
14245 /**
14246  * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload
14247  * @wmi_handle: wmi handle
14248  * @vdev_id: vdev id
14249  * @action: true for enable else false
14250  *
14251  * To enable enhance multicast offload to firmware
14252  * when target goes to wow mode.
14253  *
14254  * Return: QDF Status
14255  */
14256 
14257 static
14258 QDF_STATUS send_enable_enhance_multicast_offload_tlv(
14259 		wmi_unified_t wmi_handle,
14260 		uint8_t vdev_id, bool action)
14261 {
14262 	QDF_STATUS status;
14263 	wmi_buf_t buf;
14264 	wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd;
14265 
14266 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
14267 	if (!buf) {
14268 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
14269 		return QDF_STATUS_E_NOMEM;
14270 	}
14271 
14272 	cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *)
14273 							wmi_buf_data(buf);
14274 
14275 	WMITLV_SET_HDR(&cmd->tlv_header,
14276 		WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param,
14277 		WMITLV_GET_STRUCT_TLVLEN(
14278 			wmi_config_enhanced_mcast_filter_cmd_fixed_param));
14279 
14280 	cmd->vdev_id = vdev_id;
14281 	cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED :
14282 			ENHANCED_MCAST_FILTER_ENABLED);
14283 	WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d",
14284 		__func__, action, vdev_id);
14285 	wmi_mtrace(WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID, cmd->vdev_id, 0);
14286 	status = wmi_unified_cmd_send(wmi_handle, buf,
14287 			sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID);
14288 	if (status != QDF_STATUS_SUCCESS) {
14289 		qdf_nbuf_free(buf);
14290 		WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID",
14291 			__func__);
14292 	}
14293 
14294 	return status;
14295 }
14296 
14297 /**
14298  * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event
14299  * @wmi_handle: wmi handle
14300  * @param evt_buf: pointer to event buffer
14301  * @param hdr: Pointer to hold header
14302  * @param bufp: Pointer to hold pointer to rx param buffer
14303  *
14304  * Return: QDF_STATUS_SUCCESS for success or error code
14305  */
14306 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle,
14307 	void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len)
14308 {
14309 	WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param;
14310 	WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf;
14311 
14312 	param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf;
14313 	if (!param_buf) {
14314 		WMI_LOGE("gtk param_buf is NULL");
14315 		return QDF_STATUS_E_INVAL;
14316 	}
14317 
14318 	if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) {
14319 		WMI_LOGE("Invalid length for GTK status");
14320 		return QDF_STATUS_E_INVAL;
14321 	}
14322 
14323 	fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *)
14324 		param_buf->fixed_param;
14325 	gtk_rsp_param->vdev_id = fixed_param->vdev_id;
14326 	gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS;
14327 	gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt;
14328 	qdf_mem_copy(&gtk_rsp_param->replay_counter,
14329 		&fixed_param->replay_counter,
14330 		GTK_REPLAY_COUNTER_BYTES);
14331 
14332 	return QDF_STATUS_SUCCESS;
14333 
14334 }
14335 
14336 #ifdef FEATURE_WLAN_RA_FILTERING
14337 /**
14338  * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw
14339  * @wmi_handle: wmi handle
14340  * @vdev_id: vdev id
14341  *
14342  * Return: CDF status
14343  */
14344 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle,
14345 		   uint8_t vdev_id, uint8_t default_pattern,
14346 		   uint16_t rate_limit_interval)
14347 {
14348 
14349 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
14350 	wmi_buf_t buf;
14351 	uint8_t *buf_ptr;
14352 	int32_t len;
14353 	int ret;
14354 
14355 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
14356 	      WMI_TLV_HDR_SIZE +
14357 	      0 * sizeof(WOW_BITMAP_PATTERN_T) +
14358 	      WMI_TLV_HDR_SIZE +
14359 	      0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
14360 	      WMI_TLV_HDR_SIZE +
14361 	      0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
14362 	      WMI_TLV_HDR_SIZE +
14363 	      0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
14364 	      WMI_TLV_HDR_SIZE +
14365 	      0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
14366 
14367 	buf = wmi_buf_alloc(wmi_handle, len);
14368 	if (!buf) {
14369 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
14370 		return QDF_STATUS_E_NOMEM;
14371 	}
14372 
14373 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
14374 	buf_ptr = (uint8_t *) cmd;
14375 
14376 	WMITLV_SET_HDR(&cmd->tlv_header,
14377 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
14378 		       WMITLV_GET_STRUCT_TLVLEN
14379 			       (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
14380 	cmd->vdev_id = vdev_id;
14381 	cmd->pattern_id = default_pattern,
14382 	cmd->pattern_type = WOW_IPV6_RA_PATTERN;
14383 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
14384 
14385 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
14386 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14387 	buf_ptr += WMI_TLV_HDR_SIZE;
14388 
14389 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
14390 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14391 	buf_ptr += WMI_TLV_HDR_SIZE;
14392 
14393 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
14394 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14395 	buf_ptr += WMI_TLV_HDR_SIZE;
14396 
14397 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
14398 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14399 	buf_ptr += WMI_TLV_HDR_SIZE;
14400 
14401 	/* Fill TLV for pattern_info_timeout but no data. */
14402 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
14403 	buf_ptr += WMI_TLV_HDR_SIZE;
14404 
14405 	/* Fill TLV for ra_ratelimit_interval. */
14406 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
14407 	buf_ptr += WMI_TLV_HDR_SIZE;
14408 
14409 	*((uint32_t *) buf_ptr) = rate_limit_interval;
14410 
14411 	WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__,
14412 		 rate_limit_interval, vdev_id);
14413 
14414 	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
14415 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
14416 				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
14417 	if (ret) {
14418 		WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__);
14419 		wmi_buf_free(buf);
14420 		return QDF_STATUS_E_FAILURE;
14421 	}
14422 
14423 	return QDF_STATUS_SUCCESS;
14424 
14425 }
14426 #endif /* FEATURE_WLAN_RA_FILTERING */
14427 
14428 /**
14429  * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw
14430  * @wmi_handle: wmi handle
14431  * @vdev_id: vdev id
14432  * @multicastAddr: mcast address
14433  * @clearList: clear list flag
14434  *
14435  * Return: QDF_STATUS_SUCCESS for success or error code
14436  */
14437 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle,
14438 				     uint8_t vdev_id,
14439 				     struct qdf_mac_addr multicast_addr,
14440 				     bool clearList)
14441 {
14442 	WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd;
14443 	wmi_buf_t buf;
14444 	int err;
14445 
14446 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
14447 	if (!buf) {
14448 		WMI_LOGE("Failed to allocate buffer to send set_param cmd");
14449 		return QDF_STATUS_E_NOMEM;
14450 	}
14451 
14452 	cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf);
14453 	qdf_mem_zero(cmd, sizeof(*cmd));
14454 
14455 	WMITLV_SET_HDR(&cmd->tlv_header,
14456 	       WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param,
14457 	       WMITLV_GET_STRUCT_TLVLEN
14458 	       (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param));
14459 	cmd->action =
14460 		(clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET);
14461 	cmd->vdev_id = vdev_id;
14462 	WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr);
14463 
14464 	WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM",
14465 		 cmd->action, vdev_id, clearList, multicast_addr.bytes);
14466 
14467 	wmi_mtrace(WMI_SET_MCASTBCAST_FILTER_CMDID, cmd->vdev_id, 0);
14468 	err = wmi_unified_cmd_send(wmi_handle, buf,
14469 				   sizeof(*cmd),
14470 				   WMI_SET_MCASTBCAST_FILTER_CMDID);
14471 	if (err) {
14472 		WMI_LOGE("Failed to send set_param cmd");
14473 		wmi_buf_free(buf);
14474 		return QDF_STATUS_E_FAILURE;
14475 	}
14476 
14477 	return QDF_STATUS_SUCCESS;
14478 }
14479 
14480 /**
14481  * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple  mcast filter
14482  *						   command to fw
14483  * @wmi_handle: wmi handle
14484  * @vdev_id: vdev id
14485  * @mcast_filter_params: mcast filter params
14486  *
14487  * Return: QDF_STATUS_SUCCESS for success or error code
14488  */
14489 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv(
14490 				wmi_unified_t wmi_handle,
14491 				uint8_t vdev_id,
14492 				struct pmo_mcast_filter_params *filter_param)
14493 
14494 {
14495 	WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd;
14496 	uint8_t *buf_ptr;
14497 	wmi_buf_t buf;
14498 	int err;
14499 	int i;
14500 	uint8_t *mac_addr_src_ptr = NULL;
14501 	wmi_mac_addr *mac_addr_dst_ptr;
14502 	uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
14503 		sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt;
14504 
14505 	buf = wmi_buf_alloc(wmi_handle, len);
14506 	if (!buf) {
14507 		WMI_LOGE("Failed to allocate memory");
14508 		return QDF_STATUS_E_NOMEM;
14509 	}
14510 
14511 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14512 	cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *)
14513 		wmi_buf_data(buf);
14514 	qdf_mem_zero(cmd, sizeof(*cmd));
14515 
14516 	WMITLV_SET_HDR(&cmd->tlv_header,
14517 	       WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param,
14518 	       WMITLV_GET_STRUCT_TLVLEN
14519 	       (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param));
14520 	cmd->operation =
14521 		((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE
14522 					: WMI_MULTIPLE_MCAST_FILTER_ADD);
14523 	cmd->vdev_id = vdev_id;
14524 	cmd->num_mcastaddrs = filter_param->multicast_addr_cnt;
14525 
14526 	buf_ptr += sizeof(*cmd);
14527 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
14528 		       sizeof(wmi_mac_addr) *
14529 			       filter_param->multicast_addr_cnt);
14530 
14531 	if (filter_param->multicast_addr_cnt == 0)
14532 		goto send_cmd;
14533 
14534 	mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr;
14535 	mac_addr_dst_ptr = (wmi_mac_addr *)
14536 			(buf_ptr + WMI_TLV_HDR_SIZE);
14537 
14538 	for (i = 0; i < filter_param->multicast_addr_cnt; i++) {
14539 		WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr);
14540 		mac_addr_src_ptr += ATH_MAC_LEN;
14541 		mac_addr_dst_ptr++;
14542 	}
14543 
14544 send_cmd:
14545 	wmi_mtrace(WMI_SET_MULTIPLE_MCAST_FILTER_CMDID, cmd->vdev_id, 0);
14546 	err = wmi_unified_cmd_send(wmi_handle, buf,
14547 				   len,
14548 				   WMI_SET_MULTIPLE_MCAST_FILTER_CMDID);
14549 	if (err) {
14550 		WMI_LOGE("Failed to send set_param cmd");
14551 		wmi_buf_free(buf);
14552 		return QDF_STATUS_E_FAILURE;
14553 	}
14554 
14555 	return QDF_STATUS_SUCCESS;
14556 }
14557 
14558 static void
14559 fill_fils_tlv_params(WMI_GTK_OFFLOAD_CMD_fixed_param *cmd,
14560 			  uint8_t vdev_id,
14561 			  struct pmo_gtk_req *params)
14562 {
14563 	uint8_t *buf_ptr;
14564 	wmi_gtk_offload_fils_tlv_param *ext_param;
14565 
14566 	buf_ptr = (uint8_t *) cmd + sizeof(*cmd);
14567 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14568 		       sizeof(*ext_param));
14569 	buf_ptr += WMI_TLV_HDR_SIZE;
14570 
14571 	ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr;
14572 	WMITLV_SET_HDR(&ext_param->tlv_header,
14573 		       WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param,
14574 		       WMITLV_GET_STRUCT_TLVLEN(
14575 				wmi_gtk_offload_fils_tlv_param));
14576 	ext_param->vdev_id = vdev_id;
14577 	ext_param->flags = cmd->flags;
14578 	ext_param->kek_len = params->kek_len;
14579 	qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len);
14580 	qdf_mem_copy(ext_param->KCK, params->kck,
14581 		     WMI_GTK_OFFLOAD_KCK_BYTES);
14582 	qdf_mem_copy(ext_param->replay_counter, &params->replay_counter,
14583 		     GTK_REPLAY_COUNTER_BYTES);
14584 }
14585 
14586 /**
14587  * send_gtk_offload_cmd_tlv() - send GTK offload command to fw
14588  * @wmi_handle: wmi handle
14589  * @vdev_id: vdev id
14590  * @params: GTK offload parameters
14591  *
14592  * Return: CDF status
14593  */
14594 static
14595 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
14596 					   struct pmo_gtk_req *params,
14597 					   bool enable_offload,
14598 					   uint32_t gtk_offload_opcode)
14599 {
14600 	int len;
14601 	wmi_buf_t buf;
14602 	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
14603 	QDF_STATUS status = QDF_STATUS_SUCCESS;
14604 
14605 	WMI_LOGD("%s Enter", __func__);
14606 
14607 	len = sizeof(*cmd);
14608 
14609 	if (params->is_fils_connection)
14610 		len += WMI_TLV_HDR_SIZE +
14611 		       sizeof(wmi_gtk_offload_fils_tlv_param);
14612 
14613 	/* alloc wmi buffer */
14614 	buf = wmi_buf_alloc(wmi_handle, len);
14615 	if (!buf) {
14616 		WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD");
14617 		status = QDF_STATUS_E_NOMEM;
14618 		goto out;
14619 	}
14620 
14621 	cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
14622 	WMITLV_SET_HDR(&cmd->tlv_header,
14623 		       WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
14624 		       WMITLV_GET_STRUCT_TLVLEN
14625 			       (WMI_GTK_OFFLOAD_CMD_fixed_param));
14626 
14627 	cmd->vdev_id = vdev_id;
14628 
14629 	/* Request target to enable GTK offload */
14630 	if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) {
14631 		cmd->flags = gtk_offload_opcode;
14632 
14633 		/* Copy the keys and replay counter */
14634 		qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN);
14635 		qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY);
14636 		qdf_mem_copy(cmd->replay_counter, &params->replay_counter,
14637 			     GTK_REPLAY_COUNTER_BYTES);
14638 	} else {
14639 		cmd->flags = gtk_offload_opcode;
14640 	}
14641 	if (params->is_fils_connection)
14642 		fill_fils_tlv_params(cmd, vdev_id, params);
14643 
14644 	WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len);
14645 	/* send the wmi command */
14646 	wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0);
14647 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
14648 				 WMI_GTK_OFFLOAD_CMDID)) {
14649 		WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID");
14650 		wmi_buf_free(buf);
14651 		status = QDF_STATUS_E_FAILURE;
14652 	}
14653 
14654 out:
14655 	WMI_LOGD("%s Exit", __func__);
14656 	return status;
14657 }
14658 
14659 /**
14660  * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw
14661  * @wmi_handle: wmi handle
14662  * @params: GTK offload params
14663  *
14664  * Return: CDF status
14665  */
14666 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv(
14667 			wmi_unified_t wmi_handle,
14668 			uint8_t vdev_id,
14669 			uint64_t offload_req_opcode)
14670 {
14671 	int len;
14672 	wmi_buf_t buf;
14673 	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
14674 	QDF_STATUS status = QDF_STATUS_SUCCESS;
14675 
14676 	len = sizeof(*cmd);
14677 
14678 	/* alloc wmi buffer */
14679 	buf = wmi_buf_alloc(wmi_handle, len);
14680 	if (!buf) {
14681 		WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD");
14682 		status = QDF_STATUS_E_NOMEM;
14683 		goto out;
14684 	}
14685 
14686 	cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
14687 	WMITLV_SET_HDR(&cmd->tlv_header,
14688 		       WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
14689 		       WMITLV_GET_STRUCT_TLVLEN
14690 			       (WMI_GTK_OFFLOAD_CMD_fixed_param));
14691 
14692 	/* Request for GTK offload status */
14693 	cmd->flags = offload_req_opcode;
14694 	cmd->vdev_id = vdev_id;
14695 
14696 	/* send the wmi command */
14697 	wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0);
14698 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
14699 				 WMI_GTK_OFFLOAD_CMDID)) {
14700 		WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info");
14701 		wmi_buf_free(buf);
14702 		status = QDF_STATUS_E_FAILURE;
14703 	}
14704 
14705 out:
14706 	return status;
14707 }
14708 
14709 /**
14710  * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params
14711  * @wmi_handle: wmi handler
14712  * @action_params: pointer to action_params
14713  *
14714  * Return: 0 for success, otherwise appropriate error code
14715  */
14716 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle,
14717 		struct pmo_action_wakeup_set_params *action_params)
14718 {
14719 	WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd;
14720 	wmi_buf_t buf;
14721 	int i;
14722 	int32_t err;
14723 	uint32_t len = 0, *cmd_args;
14724 	uint8_t *buf_ptr;
14725 
14726 	len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))
14727 				+ WMI_TLV_HDR_SIZE + sizeof(*cmd);
14728 	buf = wmi_buf_alloc(wmi_handle, len);
14729 	if (!buf) {
14730 		WMI_LOGE("Failed to allocate buffer to send action filter cmd");
14731 		return QDF_STATUS_E_NOMEM;
14732 	}
14733 	cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf);
14734 	buf_ptr = (uint8_t *)cmd;
14735 	WMITLV_SET_HDR(&cmd->tlv_header,
14736 		WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param,
14737 		WMITLV_GET_STRUCT_TLVLEN(
14738 				WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param));
14739 
14740 	cmd->vdev_id = action_params->vdev_id;
14741 	cmd->operation = action_params->operation;
14742 
14743 	for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++)
14744 		cmd->action_category_map[i] =
14745 				action_params->action_category_map[i];
14746 
14747 	buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param);
14748 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
14749 			(PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)));
14750 	buf_ptr += WMI_TLV_HDR_SIZE;
14751 	cmd_args = (uint32_t *) buf_ptr;
14752 	for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++)
14753 		cmd_args[i] = action_params->action_per_category[i];
14754 
14755 	wmi_mtrace(WMI_WOW_SET_ACTION_WAKE_UP_CMDID, cmd->vdev_id, 0);
14756 	err = wmi_unified_cmd_send(wmi_handle, buf,
14757 			len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID);
14758 	if (err) {
14759 		WMI_LOGE("Failed to send ap_ps_egap cmd");
14760 		wmi_buf_free(buf);
14761 		return QDF_STATUS_E_FAILURE;
14762 	}
14763 
14764 	return QDF_STATUS_SUCCESS;
14765 }
14766 
14767 #ifdef FEATURE_WLAN_LPHB
14768 
14769 /**
14770  * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration
14771  * @wmi_handle: wmi handle
14772  * @lphb_conf_req: configuration info
14773  *
14774  * Return: CDF status
14775  */
14776 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle,
14777 				wmi_hb_set_enable_cmd_fixed_param *params)
14778 {
14779 	QDF_STATUS status;
14780 	wmi_buf_t buf = NULL;
14781 	uint8_t *buf_ptr;
14782 	wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp;
14783 	int len = sizeof(wmi_hb_set_enable_cmd_fixed_param);
14784 
14785 
14786 	buf = wmi_buf_alloc(wmi_handle, len);
14787 	if (!buf) {
14788 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14789 		return QDF_STATUS_E_NOMEM;
14790 	}
14791 
14792 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14793 	hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr;
14794 	WMITLV_SET_HDR(&hb_enable_fp->tlv_header,
14795 		       WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param,
14796 		       WMITLV_GET_STRUCT_TLVLEN
14797 			       (wmi_hb_set_enable_cmd_fixed_param));
14798 
14799 	/* fill in values */
14800 	hb_enable_fp->vdev_id = params->session;
14801 	hb_enable_fp->enable = params->enable;
14802 	hb_enable_fp->item = params->item;
14803 	hb_enable_fp->session = params->session;
14804 
14805 	wmi_mtrace(WMI_HB_SET_ENABLE_CMDID, NO_SESSION, 0);
14806 	status = wmi_unified_cmd_send(wmi_handle, buf,
14807 				      len, WMI_HB_SET_ENABLE_CMDID);
14808 	if (QDF_IS_STATUS_ERROR(status)) {
14809 		WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d",
14810 			status);
14811 		wmi_buf_free(buf);
14812 	}
14813 
14814 	return status;
14815 }
14816 
14817 /**
14818  * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration
14819  * @wmi_handle: wmi handle
14820  * @lphb_conf_req: lphb config request
14821  *
14822  * Return: CDF status
14823  */
14824 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle,
14825 	    wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req)
14826 {
14827 	QDF_STATUS status;
14828 	wmi_buf_t buf = NULL;
14829 	uint8_t *buf_ptr;
14830 	wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp;
14831 	int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param);
14832 
14833 	buf = wmi_buf_alloc(wmi_handle, len);
14834 	if (!buf) {
14835 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14836 		return QDF_STATUS_E_NOMEM;
14837 	}
14838 
14839 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14840 	hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr;
14841 	WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header,
14842 		       WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param,
14843 		       WMITLV_GET_STRUCT_TLVLEN
14844 			       (wmi_hb_set_tcp_params_cmd_fixed_param));
14845 
14846 	/* fill in values */
14847 	hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id;
14848 	hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip;
14849 	hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip;
14850 	hb_tcp_params_fp->seq = lphb_conf_req->seq;
14851 	hb_tcp_params_fp->src_port = lphb_conf_req->src_port;
14852 	hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port;
14853 	hb_tcp_params_fp->interval = lphb_conf_req->interval;
14854 	hb_tcp_params_fp->timeout = lphb_conf_req->timeout;
14855 	hb_tcp_params_fp->session = lphb_conf_req->session;
14856 	qdf_mem_copy(&hb_tcp_params_fp->gateway_mac,
14857 				   &lphb_conf_req->gateway_mac,
14858 				   sizeof(hb_tcp_params_fp->gateway_mac));
14859 
14860 	wmi_mtrace(WMI_HB_SET_TCP_PARAMS_CMDID, NO_SESSION, 0);
14861 	status = wmi_unified_cmd_send(wmi_handle, buf,
14862 				      len, WMI_HB_SET_TCP_PARAMS_CMDID);
14863 	if (QDF_IS_STATUS_ERROR(status)) {
14864 		WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d",
14865 			status);
14866 		wmi_buf_free(buf);
14867 	}
14868 
14869 	return status;
14870 }
14871 
14872 /**
14873  * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd
14874  * @wmi_handle: wmi handle
14875  * @lphb_conf_req: lphb config request
14876  *
14877  * Return: CDF status
14878  */
14879 static
14880 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
14881 		wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp)
14882 {
14883 	QDF_STATUS status;
14884 	wmi_buf_t buf = NULL;
14885 	uint8_t *buf_ptr;
14886 	wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp;
14887 	int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param);
14888 
14889 	buf = wmi_buf_alloc(wmi_handle, len);
14890 	if (!buf) {
14891 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14892 		return QDF_STATUS_E_NOMEM;
14893 	}
14894 
14895 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14896 	hb_tcp_filter_fp =
14897 		(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr;
14898 	WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header,
14899 		WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param,
14900 		WMITLV_GET_STRUCT_TLVLEN
14901 		       (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param));
14902 
14903 	/* fill in values */
14904 	hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id;
14905 	hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length;
14906 	hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset;
14907 	hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session;
14908 	memcpy((void *)&hb_tcp_filter_fp->filter,
14909 	       (void *)&g_hb_tcp_filter_fp->filter,
14910 	       WMI_WLAN_HB_MAX_FILTER_SIZE);
14911 
14912 	wmi_mtrace(WMI_HB_SET_TCP_PKT_FILTER_CMDID, NO_SESSION, 0);
14913 	status = wmi_unified_cmd_send(wmi_handle, buf,
14914 				      len, WMI_HB_SET_TCP_PKT_FILTER_CMDID);
14915 	if (QDF_IS_STATUS_ERROR(status)) {
14916 		WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d",
14917 			status);
14918 		wmi_buf_free(buf);
14919 	}
14920 
14921 	return status;
14922 }
14923 
14924 /**
14925  * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB
14926  * @wmi_handle: wmi handle
14927  * @lphb_conf_req: lphb config request
14928  *
14929  * Return: CDF status
14930  */
14931 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle,
14932 		   wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req)
14933 {
14934 	QDF_STATUS status;
14935 	wmi_buf_t buf = NULL;
14936 	uint8_t *buf_ptr;
14937 	wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp;
14938 	int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param);
14939 
14940 	buf = wmi_buf_alloc(wmi_handle, len);
14941 	if (!buf) {
14942 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14943 		return QDF_STATUS_E_NOMEM;
14944 	}
14945 
14946 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14947 	hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr;
14948 	WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header,
14949 		       WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param,
14950 		       WMITLV_GET_STRUCT_TLVLEN
14951 			       (wmi_hb_set_udp_params_cmd_fixed_param));
14952 
14953 	/* fill in values */
14954 	hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id;
14955 	hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip;
14956 	hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip;
14957 	hb_udp_params_fp->src_port = lphb_conf_req->src_port;
14958 	hb_udp_params_fp->dst_port = lphb_conf_req->dst_port;
14959 	hb_udp_params_fp->interval = lphb_conf_req->interval;
14960 	hb_udp_params_fp->timeout = lphb_conf_req->timeout;
14961 	hb_udp_params_fp->session = lphb_conf_req->session;
14962 	qdf_mem_copy(&hb_udp_params_fp->gateway_mac,
14963 				   &lphb_conf_req->gateway_mac,
14964 				   sizeof(lphb_conf_req->gateway_mac));
14965 
14966 	wmi_mtrace(WMI_HB_SET_UDP_PARAMS_CMDID, NO_SESSION, 0);
14967 	status = wmi_unified_cmd_send(wmi_handle, buf,
14968 				      len, WMI_HB_SET_UDP_PARAMS_CMDID);
14969 	if (QDF_IS_STATUS_ERROR(status)) {
14970 		WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d",
14971 			status);
14972 		wmi_buf_free(buf);
14973 	}
14974 
14975 	return status;
14976 }
14977 
14978 /**
14979  * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command
14980  * @wmi_handle: wmi handle
14981  * @lphb_conf_req: lphb config request
14982  *
14983  * Return: CDF status
14984  */
14985 static
14986 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
14987 		wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req)
14988 {
14989 	QDF_STATUS status;
14990 	wmi_buf_t buf = NULL;
14991 	uint8_t *buf_ptr;
14992 	wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp;
14993 	int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param);
14994 
14995 	buf = wmi_buf_alloc(wmi_handle, len);
14996 	if (!buf) {
14997 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14998 		return QDF_STATUS_E_NOMEM;
14999 	}
15000 
15001 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15002 	hb_udp_filter_fp =
15003 		(wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr;
15004 	WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header,
15005 		WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param,
15006 		WMITLV_GET_STRUCT_TLVLEN
15007 		       (wmi_hb_set_udp_pkt_filter_cmd_fixed_param));
15008 
15009 	/* fill in values */
15010 	hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id;
15011 	hb_udp_filter_fp->length = lphb_conf_req->length;
15012 	hb_udp_filter_fp->offset = lphb_conf_req->offset;
15013 	hb_udp_filter_fp->session = lphb_conf_req->session;
15014 	memcpy((void *)&hb_udp_filter_fp->filter,
15015 	       (void *)&lphb_conf_req->filter,
15016 	       WMI_WLAN_HB_MAX_FILTER_SIZE);
15017 
15018 	wmi_mtrace(WMI_HB_SET_UDP_PKT_FILTER_CMDID, NO_SESSION, 0);
15019 	status = wmi_unified_cmd_send(wmi_handle, buf,
15020 				      len, WMI_HB_SET_UDP_PKT_FILTER_CMDID);
15021 	if (QDF_IS_STATUS_ERROR(status)) {
15022 		WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d",
15023 			status);
15024 		wmi_buf_free(buf);
15025 	}
15026 
15027 	return status;
15028 }
15029 #endif /* FEATURE_WLAN_LPHB */
15030 
15031 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi,
15032 					      struct pmo_hw_filter_params *req)
15033 {
15034 	QDF_STATUS status;
15035 	wmi_hw_data_filter_cmd_fixed_param *cmd;
15036 	wmi_buf_t wmi_buf;
15037 
15038 	if (!req) {
15039 		WMI_LOGE("req is null");
15040 		return QDF_STATUS_E_INVAL;
15041 	}
15042 
15043 	wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd));
15044 	if (!wmi_buf) {
15045 		WMI_LOGE(FL("Out of memory"));
15046 		return QDF_STATUS_E_NOMEM;
15047 	}
15048 
15049 	cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf);
15050 	WMITLV_SET_HDR(&cmd->tlv_header,
15051 		  WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param,
15052 		  WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param));
15053 	cmd->vdev_id = req->vdev_id;
15054 	cmd->enable = req->enable;
15055 	/* Set all modes in case of disable */
15056 	if (!cmd->enable)
15057 		cmd->hw_filter_bitmap = ((uint32_t)~0U);
15058 	else
15059 		cmd->hw_filter_bitmap = req->mode_bitmap;
15060 
15061 	WMI_LOGD("Send %s hw filter mode: 0x%X for vdev id %d",
15062 		 req->enable ? "enable" : "disable", req->mode_bitmap,
15063 		 req->vdev_id);
15064 
15065 	wmi_mtrace(WMI_HW_DATA_FILTER_CMDID, cmd->vdev_id, 0);
15066 	status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd),
15067 				      WMI_HW_DATA_FILTER_CMDID);
15068 	if (QDF_IS_STATUS_ERROR(status)) {
15069 		WMI_LOGE("Failed to configure hw filter");
15070 		wmi_buf_free(wmi_buf);
15071 	}
15072 
15073 	return status;
15074 }
15075 
15076 #ifdef WLAN_FEATURE_PACKET_FILTERING
15077 /**
15078  * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter
15079  * @wmi_handle: wmi handle
15080  * @vdev_id: vdev id
15081  * @enable: Flag to enable/disable packet filter
15082  *
15083  * Return: QDF_STATUS_SUCCESS for success or error code
15084  */
15085 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv(
15086 		wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable)
15087 {
15088 	int32_t len;
15089 	int ret = 0;
15090 	wmi_buf_t buf;
15091 	WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd;
15092 
15093 	len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param);
15094 
15095 	buf = wmi_buf_alloc(wmi_handle, len);
15096 	if (!buf) {
15097 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
15098 		return QDF_STATUS_E_NOMEM;
15099 	}
15100 
15101 	cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf);
15102 	WMITLV_SET_HDR(&cmd->tlv_header,
15103 		WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param,
15104 		WMITLV_GET_STRUCT_TLVLEN(
15105 		WMI_PACKET_FILTER_ENABLE_CMD_fixed_param));
15106 
15107 	cmd->vdev_id = vdev_id;
15108 	if (enable)
15109 		cmd->enable = PACKET_FILTER_SET_ENABLE;
15110 	else
15111 		cmd->enable = PACKET_FILTER_SET_DISABLE;
15112 
15113 	WMI_LOGE("%s: Packet filter enable %d for vdev_id %d",
15114 		__func__, cmd->enable, vdev_id);
15115 
15116 	wmi_mtrace(WMI_PACKET_FILTER_ENABLE_CMDID, cmd->vdev_id, 0);
15117 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
15118 			 WMI_PACKET_FILTER_ENABLE_CMDID);
15119 	if (ret) {
15120 		WMI_LOGE("Failed to send packet filter wmi cmd to fw");
15121 		wmi_buf_free(buf);
15122 	}
15123 
15124 	return ret;
15125 }
15126 
15127 /**
15128  * send_config_packet_filter_cmd_tlv() - configure packet filter in target
15129  * @wmi_handle: wmi handle
15130  * @vdev_id: vdev id
15131  * @rcv_filter_param: Packet filter parameters
15132  * @filter_id: Filter id
15133  * @enable: Flag to add/delete packet filter configuration
15134  *
15135  * Return: QDF_STATUS_SUCCESS for success or error code
15136  */
15137 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle,
15138 		uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param,
15139 		uint8_t filter_id, bool enable)
15140 {
15141 	int len, i;
15142 	int err = 0;
15143 	wmi_buf_t buf;
15144 	WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd;
15145 
15146 
15147 	/* allocate the memory */
15148 	len = sizeof(*cmd);
15149 	buf = wmi_buf_alloc(wmi_handle, len);
15150 	if (!buf) {
15151 		WMI_LOGE("Failed to allocate buffer to send set_param cmd");
15152 		return QDF_STATUS_E_NOMEM;
15153 	}
15154 
15155 	cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf);
15156 	WMITLV_SET_HDR(&cmd->tlv_header,
15157 		WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param,
15158 		WMITLV_GET_STRUCT_TLVLEN
15159 			       (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param));
15160 
15161 	cmd->vdev_id = vdev_id;
15162 	cmd->filter_id = filter_id;
15163 	if (enable)
15164 		cmd->filter_action = PACKET_FILTER_SET_ACTIVE;
15165 	else
15166 		cmd->filter_action = PACKET_FILTER_SET_INACTIVE;
15167 
15168 	if (enable) {
15169 		cmd->num_params = QDF_MIN(
15170 			WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER,
15171 			rcv_filter_param->num_params);
15172 		cmd->filter_type = rcv_filter_param->filter_type;
15173 		cmd->coalesce_time = rcv_filter_param->coalesce_time;
15174 
15175 		for (i = 0; i < cmd->num_params; i++) {
15176 			cmd->paramsData[i].proto_type =
15177 				rcv_filter_param->params_data[i].protocol_layer;
15178 			cmd->paramsData[i].cmp_type =
15179 				rcv_filter_param->params_data[i].compare_flag;
15180 			cmd->paramsData[i].data_length =
15181 				rcv_filter_param->params_data[i].data_length;
15182 			cmd->paramsData[i].data_offset =
15183 				rcv_filter_param->params_data[i].data_offset;
15184 			memcpy(&cmd->paramsData[i].compareData,
15185 				rcv_filter_param->params_data[i].compare_data,
15186 				sizeof(cmd->paramsData[i].compareData));
15187 			memcpy(&cmd->paramsData[i].dataMask,
15188 				rcv_filter_param->params_data[i].data_mask,
15189 				sizeof(cmd->paramsData[i].dataMask));
15190 		}
15191 	}
15192 
15193 	WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d",
15194 		cmd->filter_action, cmd->filter_id, cmd->num_params);
15195 	/* send the command along with data */
15196 	wmi_mtrace(WMI_PACKET_FILTER_CONFIG_CMDID, cmd->vdev_id, 0);
15197 	err = wmi_unified_cmd_send(wmi_handle, buf, len,
15198 				WMI_PACKET_FILTER_CONFIG_CMDID);
15199 	if (err) {
15200 		WMI_LOGE("Failed to send pkt_filter cmd");
15201 		wmi_buf_free(buf);
15202 		return QDF_STATUS_E_FAILURE;
15203 	}
15204 
15205 	return QDF_STATUS_SUCCESS;
15206 }
15207 #endif /* End of WLAN_FEATURE_PACKET_FILTERING */
15208 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */
15209 
15210 /**
15211  * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request
15212  * @wmi_handle: wmi handle
15213  * @request: SSID hotlist set request
15214  *
15215  * Return: QDF_STATUS enumeration
15216  */
15217 static QDF_STATUS
15218 send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle,
15219 		     struct ssid_hotlist_request_params *request)
15220 {
15221 	wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd;
15222 	wmi_buf_t wmi_buf;
15223 	uint32_t len;
15224 	uint32_t array_size;
15225 	uint8_t *buf_ptr;
15226 
15227 	/* length of fixed portion */
15228 	len = sizeof(*cmd);
15229 
15230 	/* length of variable portion */
15231 	array_size =
15232 		request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry);
15233 	len += WMI_TLV_HDR_SIZE + array_size;
15234 
15235 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15236 	if (!wmi_buf) {
15237 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
15238 		return QDF_STATUS_E_NOMEM;
15239 	}
15240 
15241 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
15242 	cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *)
15243 						buf_ptr;
15244 	WMITLV_SET_HDR
15245 		(&cmd->tlv_header,
15246 		 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param,
15247 		 WMITLV_GET_STRUCT_TLVLEN
15248 			(wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param));
15249 
15250 	cmd->request_id = request->request_id;
15251 	cmd->requestor_id = 0;
15252 	cmd->vdev_id = request->session_id;
15253 	cmd->table_id = 0;
15254 	cmd->lost_ap_scan_count = request->lost_ssid_sample_size;
15255 	cmd->total_entries = request->ssid_count;
15256 	cmd->num_entries_in_page = request->ssid_count;
15257 	cmd->first_entry_index = 0;
15258 
15259 	buf_ptr += sizeof(*cmd);
15260 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size);
15261 
15262 	if (request->ssid_count) {
15263 		wmi_extscan_hotlist_ssid_entry *entry;
15264 		int i;
15265 
15266 		buf_ptr += WMI_TLV_HDR_SIZE;
15267 		entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr;
15268 		for (i = 0; i < request->ssid_count; i++) {
15269 			WMITLV_SET_HDR
15270 				(entry,
15271 				 WMITLV_TAG_ARRAY_STRUC,
15272 				 WMITLV_GET_STRUCT_TLVLEN
15273 					(wmi_extscan_hotlist_ssid_entry));
15274 			entry->ssid.ssid_len = request->ssids[i].ssid.length;
15275 			qdf_mem_copy(entry->ssid.ssid,
15276 				     request->ssids[i].ssid.mac_ssid,
15277 				     request->ssids[i].ssid.length);
15278 			entry->band = request->ssids[i].band;
15279 			entry->min_rssi = request->ssids[i].rssi_low;
15280 			entry->max_rssi = request->ssids[i].rssi_high;
15281 			entry++;
15282 		}
15283 		cmd->mode = WMI_EXTSCAN_MODE_START;
15284 	} else {
15285 		cmd->mode = WMI_EXTSCAN_MODE_STOP;
15286 	}
15287 
15288 	wmi_mtrace(WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID,
15289 		   cmd->vdev_id, 0);
15290 	if (wmi_unified_cmd_send
15291 		(wmi_handle, wmi_buf, len,
15292 		 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) {
15293 		WMI_LOGE("%s: failed to send command", __func__);
15294 		wmi_buf_free(wmi_buf);
15295 		return QDF_STATUS_E_FAILURE;
15296 	}
15297 
15298 	return QDF_STATUS_SUCCESS;
15299 }
15300 
15301 /**
15302  * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw.
15303  * @wmi_handle: wmi handle
15304  * @vdev_id: vdev id
15305  *
15306  * This function sends roam synch complete event to fw.
15307  *
15308  * Return: CDF STATUS
15309  */
15310 static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle,
15311 		 uint8_t vdev_id)
15312 {
15313 	wmi_roam_synch_complete_fixed_param *cmd;
15314 	wmi_buf_t wmi_buf;
15315 	uint8_t *buf_ptr;
15316 	uint16_t len;
15317 	len = sizeof(wmi_roam_synch_complete_fixed_param);
15318 
15319 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15320 	if (!wmi_buf) {
15321 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
15322 		return QDF_STATUS_E_NOMEM;
15323 	}
15324 	cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf);
15325 	buf_ptr = (uint8_t *) cmd;
15326 	WMITLV_SET_HDR(&cmd->tlv_header,
15327 		       WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param,
15328 		       WMITLV_GET_STRUCT_TLVLEN
15329 			       (wmi_roam_synch_complete_fixed_param));
15330 	cmd->vdev_id = vdev_id;
15331 	wmi_mtrace(WMI_ROAM_SYNCH_COMPLETE, cmd->vdev_id, 0);
15332 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15333 				 WMI_ROAM_SYNCH_COMPLETE)) {
15334 		WMI_LOGP("%s: failed to send roam synch confirmation",
15335 			 __func__);
15336 		wmi_buf_free(wmi_buf);
15337 		return QDF_STATUS_E_FAILURE;
15338 	}
15339 
15340 	return QDF_STATUS_SUCCESS;
15341 }
15342 
15343 /**
15344  * send_fw_test_cmd_tlv() - send fw test command to fw.
15345  * @wmi_handle: wmi handle
15346  * @wmi_fwtest: fw test command
15347  *
15348  * This function sends fw test command to fw.
15349  *
15350  * Return: CDF STATUS
15351  */
15352 static
15353 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle,
15354 			       struct set_fwtest_params *wmi_fwtest)
15355 {
15356 	wmi_fwtest_set_param_cmd_fixed_param *cmd;
15357 	wmi_buf_t wmi_buf;
15358 	uint16_t len;
15359 
15360 	len = sizeof(*cmd);
15361 
15362 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15363 	if (!wmi_buf) {
15364 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
15365 		return QDF_STATUS_E_NOMEM;
15366 	}
15367 
15368 	cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf);
15369 	WMITLV_SET_HDR(&cmd->tlv_header,
15370 		       WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param,
15371 		       WMITLV_GET_STRUCT_TLVLEN(
15372 		       wmi_fwtest_set_param_cmd_fixed_param));
15373 	cmd->param_id = wmi_fwtest->arg;
15374 	cmd->param_value = wmi_fwtest->value;
15375 
15376 	wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0);
15377 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15378 				 WMI_FWTEST_CMDID)) {
15379 		WMI_LOGP("%s: failed to send fw test command", __func__);
15380 		qdf_nbuf_free(wmi_buf);
15381 		return QDF_STATUS_E_FAILURE;
15382 	}
15383 
15384 	return QDF_STATUS_SUCCESS;
15385 }
15386 
15387 /**
15388  * send_unit_test_cmd_tlv() - send unit test command to fw.
15389  * @wmi_handle: wmi handle
15390  * @wmi_utest: unit test command
15391  *
15392  * This function send unit test command to fw.
15393  *
15394  * Return: CDF STATUS
15395  */
15396 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle,
15397 			       struct wmi_unit_test_cmd *wmi_utest)
15398 {
15399 	wmi_unit_test_cmd_fixed_param *cmd;
15400 	wmi_buf_t wmi_buf;
15401 	uint8_t *buf_ptr;
15402 	int i;
15403 	uint16_t len, args_tlv_len;
15404 	uint32_t *unit_test_cmd_args;
15405 
15406 	args_tlv_len =
15407 		WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t);
15408 	len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len;
15409 
15410 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15411 	if (!wmi_buf) {
15412 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
15413 		return QDF_STATUS_E_NOMEM;
15414 	}
15415 
15416 	cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf);
15417 	buf_ptr = (uint8_t *) cmd;
15418 	WMITLV_SET_HDR(&cmd->tlv_header,
15419 		       WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param,
15420 		       WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param));
15421 	cmd->vdev_id = wmi_utest->vdev_id;
15422 	cmd->module_id = wmi_utest->module_id;
15423 	cmd->num_args = wmi_utest->num_args;
15424 	cmd->diag_token = wmi_utest->diag_token;
15425 	buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param);
15426 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
15427 		       (wmi_utest->num_args * sizeof(uint32_t)));
15428 	unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
15429 	WMI_LOGI("%s: VDEV ID: %d\n", __func__, cmd->vdev_id);
15430 	WMI_LOGI("%s: MODULE ID: %d\n", __func__, cmd->module_id);
15431 	WMI_LOGI("%s: TOKEN: %d\n", __func__, cmd->diag_token);
15432 	WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args);
15433 	for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) {
15434 		unit_test_cmd_args[i] = wmi_utest->args[i];
15435 		WMI_LOGI("%d,", wmi_utest->args[i]);
15436 	}
15437 	wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0);
15438 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15439 				 WMI_UNIT_TEST_CMDID)) {
15440 		WMI_LOGP("%s: failed to send unit test command", __func__);
15441 		wmi_buf_free(wmi_buf);
15442 		return QDF_STATUS_E_FAILURE;
15443 	}
15444 
15445 	return QDF_STATUS_SUCCESS;
15446 }
15447 
15448 /**
15449  * send_roam_invoke_cmd_tlv() - send roam invoke command to fw.
15450  * @wmi_handle: wma handle
15451  * @roaminvoke: roam invoke command
15452  *
15453  * Send roam invoke command to fw for fastreassoc.
15454  *
15455  * Return: CDF STATUS
15456  */
15457 static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle,
15458 		struct wmi_roam_invoke_cmd *roaminvoke,
15459 		uint32_t ch_hz)
15460 {
15461 	wmi_roam_invoke_cmd_fixed_param *cmd;
15462 	wmi_buf_t wmi_buf;
15463 	u_int8_t *buf_ptr;
15464 	u_int16_t len, args_tlv_len;
15465 	uint32_t *channel_list;
15466 	wmi_mac_addr *bssid_list;
15467 	wmi_tlv_buf_len_param *buf_len_tlv;
15468 
15469 	/* Host sends only one channel and one bssid */
15470 	args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) +
15471 			sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) +
15472 			roundup(roaminvoke->frame_len, sizeof(uint32_t));
15473 	len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len;
15474 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15475 	if (!wmi_buf) {
15476 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
15477 		return QDF_STATUS_E_NOMEM;
15478 	}
15479 
15480 	cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf);
15481 	buf_ptr = (u_int8_t *) cmd;
15482 	WMITLV_SET_HDR(&cmd->tlv_header,
15483 	WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param,
15484 	WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param));
15485 	cmd->vdev_id = roaminvoke->vdev_id;
15486 	cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE);
15487 	if (roaminvoke->is_same_bssid)
15488 		cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP);
15489 	WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid);
15490 
15491 	if (roaminvoke->frame_len) {
15492 		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP;
15493 		/* packing 1 beacon/probe_rsp frame with WMI cmd */
15494 		cmd->num_buf = 1;
15495 	} else {
15496 		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH;
15497 		cmd->num_buf = 0;
15498 	}
15499 
15500 	cmd->roam_ap_sel_mode = 0;
15501 	cmd->roam_delay = 0;
15502 	cmd->num_chan = 1;
15503 	cmd->num_bssid = 1;
15504 
15505 	buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param);
15506 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
15507 				(sizeof(u_int32_t)));
15508 	channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
15509 	*channel_list = ch_hz;
15510 	buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE;
15511 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
15512 				(sizeof(wmi_mac_addr)));
15513 	bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
15514 	WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list);
15515 
15516 	/* move to next tlv i.e. bcn_prb_buf_list */
15517 	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr);
15518 
15519 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
15520 			sizeof(wmi_tlv_buf_len_param));
15521 
15522 	buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE);
15523 	buf_len_tlv->buf_len = roaminvoke->frame_len;
15524 
15525 	/* move to next tlv i.e. bcn_prb_frm */
15526 	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param);
15527 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
15528 		roundup(roaminvoke->frame_len, sizeof(uint32_t)));
15529 
15530 	/* copy frame after the header */
15531 	qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
15532 			roaminvoke->frame_buf,
15533 			roaminvoke->frame_len);
15534 
15535 	WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len);
15536 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
15537 			buf_ptr + WMI_TLV_HDR_SIZE,
15538 			roaminvoke->frame_len);
15539 	WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"),
15540 			cmd->flags, cmd->roam_scan_mode,
15541 			cmd->roam_ap_sel_mode, cmd->roam_delay,
15542 			cmd->num_chan, cmd->num_bssid);
15543 	WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz);
15544 
15545 	wmi_mtrace(WMI_ROAM_INVOKE_CMDID, cmd->vdev_id, 0);
15546 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15547 					WMI_ROAM_INVOKE_CMDID)) {
15548 		WMI_LOGP("%s: failed to send roam invoke command", __func__);
15549 		wmi_buf_free(wmi_buf);
15550 		return QDF_STATUS_E_FAILURE;
15551 	}
15552 
15553 	return QDF_STATUS_SUCCESS;
15554 }
15555 
15556 /**
15557  * send_roam_scan_offload_cmd_tlv() - set roam offload command
15558  * @wmi_handle: wmi handle
15559  * @command: command
15560  * @vdev_id: vdev id
15561  *
15562  * This function set roam offload command to fw.
15563  *
15564  * Return: CDF status
15565  */
15566 static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle,
15567 					 uint32_t command, uint32_t vdev_id)
15568 {
15569 	QDF_STATUS status;
15570 	wmi_roam_scan_cmd_fixed_param *cmd_fp;
15571 	wmi_buf_t buf = NULL;
15572 	int len;
15573 	uint8_t *buf_ptr;
15574 
15575 	len = sizeof(wmi_roam_scan_cmd_fixed_param);
15576 	buf = wmi_buf_alloc(wmi_handle, len);
15577 	if (!buf) {
15578 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15579 		return QDF_STATUS_E_NOMEM;
15580 	}
15581 
15582 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15583 
15584 	cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr;
15585 	WMITLV_SET_HDR(&cmd_fp->tlv_header,
15586 		       WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param,
15587 		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param));
15588 	cmd_fp->vdev_id = vdev_id;
15589 	cmd_fp->command_arg = command;
15590 
15591 	wmi_mtrace(WMI_ROAM_SCAN_CMD, NO_SESSION, 0);
15592 	status = wmi_unified_cmd_send(wmi_handle, buf,
15593 				      len, WMI_ROAM_SCAN_CMD);
15594 	if (QDF_IS_STATUS_ERROR(status)) {
15595 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d",
15596 			status);
15597 		goto error;
15598 	}
15599 
15600 	WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__);
15601 	return QDF_STATUS_SUCCESS;
15602 
15603 error:
15604 	wmi_buf_free(buf);
15605 
15606 	return status;
15607 }
15608 
15609 /**
15610  * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw
15611  * @wmi_handle: wmi handle
15612  * @ap_profile_p: ap profile
15613  * @vdev_id: vdev id
15614  *
15615  * Send WMI_ROAM_AP_PROFILE to firmware
15616  *
15617  * Return: CDF status
15618  */
15619 static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
15620 					    struct ap_profile_params *ap_profile)
15621 {
15622 	wmi_buf_t buf = NULL;
15623 	QDF_STATUS status;
15624 	int len;
15625 	uint8_t *buf_ptr;
15626 	wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp;
15627 	wmi_roam_cnd_scoring_param *score_param;
15628 	wmi_ap_profile *profile;
15629 
15630 	len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile);
15631 	len += sizeof(*score_param);
15632 	buf = wmi_buf_alloc(wmi_handle, len);
15633 	if (!buf) {
15634 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15635 		return QDF_STATUS_E_NOMEM;
15636 	}
15637 
15638 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15639 	roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr;
15640 	WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header,
15641 		       WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param,
15642 		       WMITLV_GET_STRUCT_TLVLEN
15643 			       (wmi_roam_ap_profile_fixed_param));
15644 	/* fill in threshold values */
15645 	roam_ap_profile_fp->vdev_id = ap_profile->vdev_id;
15646 	roam_ap_profile_fp->id = 0;
15647 	buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param);
15648 
15649 	profile = (wmi_ap_profile *)buf_ptr;
15650 	WMITLV_SET_HDR(&profile->tlv_header,
15651 		       WMITLV_TAG_STRUC_wmi_ap_profile,
15652 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile));
15653 	profile->flags = ap_profile->profile.flags;
15654 	profile->rssi_threshold = ap_profile->profile.rssi_threshold;
15655 	profile->ssid.ssid_len = ap_profile->profile.ssid.length;
15656 	qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid,
15657 		     profile->ssid.ssid_len);
15658 	profile->rsn_authmode = ap_profile->profile.rsn_authmode;
15659 	profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset;
15660 	profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset;
15661 	profile->rsn_mcastmgmtcipherset =
15662 				ap_profile->profile.rsn_mcastmgmtcipherset;
15663 	profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh;
15664 
15665 	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",
15666 		 profile->flags, profile->rssi_threshold,
15667 		 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid,
15668 		 profile->rsn_authmode, profile->rsn_ucastcipherset,
15669 		 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset,
15670 		 profile->rssi_abs_thresh);
15671 
15672 	buf_ptr += sizeof(wmi_ap_profile);
15673 
15674 	score_param = (wmi_roam_cnd_scoring_param *)buf_ptr;
15675 	WMITLV_SET_HDR(&score_param->tlv_header,
15676 		       WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param,
15677 		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param));
15678 	score_param->disable_bitmap = ap_profile->param.disable_bitmap;
15679 	score_param->rssi_weightage_pcnt =
15680 			ap_profile->param.rssi_weightage;
15681 	score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage;
15682 	score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage;
15683 	score_param->he_weightage_pcnt = ap_profile->param.he_weightage;
15684 	score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage;
15685 	score_param->band_weightage_pcnt = ap_profile->param.band_weightage;
15686 	score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage;
15687 	score_param->esp_qbss_weightage_pcnt =
15688 			ap_profile->param.esp_qbss_weightage;
15689 	score_param->beamforming_weightage_pcnt =
15690 			ap_profile->param.beamforming_weightage;
15691 	score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage;
15692 	score_param->oce_wan_weightage_pcnt =
15693 			ap_profile->param.oce_wan_weightage;
15694 
15695 	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",
15696 		 score_param->disable_bitmap, score_param->rssi_weightage_pcnt,
15697 		 score_param->ht_weightage_pcnt,
15698 		 score_param->vht_weightage_pcnt,
15699 		 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt,
15700 		 score_param->band_weightage_pcnt,
15701 		 score_param->nss_weightage_pcnt,
15702 		 score_param->esp_qbss_weightage_pcnt,
15703 		 score_param->beamforming_weightage_pcnt,
15704 		 score_param->pcl_weightage_pcnt,
15705 		 score_param->oce_wan_weightage_pcnt);
15706 
15707 	score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score;
15708 	score_param->band_scoring.score_pcnt =
15709 			ap_profile->param.band_index_score;
15710 	score_param->nss_scoring.score_pcnt =
15711 			ap_profile->param.nss_index_score;
15712 
15713 	WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x",
15714 		 score_param->bw_scoring.score_pcnt,
15715 		 score_param->band_scoring.score_pcnt,
15716 		 score_param->nss_scoring.score_pcnt);
15717 
15718 	score_param->rssi_scoring.best_rssi_threshold =
15719 		(-1) * ap_profile->param.rssi_scoring.best_rssi_threshold;
15720 	score_param->rssi_scoring.good_rssi_threshold =
15721 		(-1) * ap_profile->param.rssi_scoring.good_rssi_threshold;
15722 	score_param->rssi_scoring.bad_rssi_threshold =
15723 		(-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold;
15724 	score_param->rssi_scoring.good_rssi_pcnt =
15725 		ap_profile->param.rssi_scoring.good_rssi_pcnt;
15726 	score_param->rssi_scoring.bad_rssi_pcnt =
15727 		ap_profile->param.rssi_scoring.bad_rssi_pcnt;
15728 	score_param->rssi_scoring.good_bucket_size =
15729 		ap_profile->param.rssi_scoring.good_bucket_size;
15730 	score_param->rssi_scoring.bad_bucket_size =
15731 		ap_profile->param.rssi_scoring.bad_bucket_size;
15732 	score_param->rssi_scoring.rssi_pref_5g_rssi_thresh =
15733 		(-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh;
15734 
15735 	WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d",
15736 		 score_param->rssi_scoring.best_rssi_threshold,
15737 		 score_param->rssi_scoring.good_rssi_threshold,
15738 		 score_param->rssi_scoring.bad_rssi_threshold,
15739 		 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh);
15740 	WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d",
15741 		 score_param->rssi_scoring.good_rssi_pcnt,
15742 		 score_param->rssi_scoring.bad_rssi_pcnt,
15743 		 score_param->rssi_scoring.good_bucket_size,
15744 		 score_param->rssi_scoring.bad_bucket_size);
15745 
15746 	score_param->esp_qbss_scoring.num_slot =
15747 			ap_profile->param.esp_qbss_scoring.num_slot;
15748 	score_param->esp_qbss_scoring.score_pcnt3_to_0 =
15749 			ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0;
15750 	score_param->esp_qbss_scoring.score_pcnt7_to_4 =
15751 			ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4;
15752 	score_param->esp_qbss_scoring.score_pcnt11_to_8 =
15753 			ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8;
15754 	score_param->esp_qbss_scoring.score_pcnt15_to_12 =
15755 			ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12;
15756 
15757 	WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
15758 		 score_param->esp_qbss_scoring.num_slot,
15759 		 score_param->esp_qbss_scoring.score_pcnt3_to_0,
15760 		 score_param->esp_qbss_scoring.score_pcnt7_to_4,
15761 		 score_param->esp_qbss_scoring.score_pcnt11_to_8,
15762 		 score_param->esp_qbss_scoring.score_pcnt15_to_12);
15763 
15764 	score_param->oce_wan_scoring.num_slot =
15765 			ap_profile->param.oce_wan_scoring.num_slot;
15766 	score_param->oce_wan_scoring.score_pcnt3_to_0 =
15767 			ap_profile->param.oce_wan_scoring.score_pcnt3_to_0;
15768 	score_param->oce_wan_scoring.score_pcnt7_to_4 =
15769 			ap_profile->param.oce_wan_scoring.score_pcnt7_to_4;
15770 	score_param->oce_wan_scoring.score_pcnt11_to_8 =
15771 			ap_profile->param.oce_wan_scoring.score_pcnt11_to_8;
15772 	score_param->oce_wan_scoring.score_pcnt15_to_12 =
15773 			ap_profile->param.oce_wan_scoring.score_pcnt15_to_12;
15774 
15775 	WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
15776 		 score_param->oce_wan_scoring.num_slot,
15777 		 score_param->oce_wan_scoring.score_pcnt3_to_0,
15778 		 score_param->oce_wan_scoring.score_pcnt7_to_4,
15779 		 score_param->oce_wan_scoring.score_pcnt11_to_8,
15780 		 score_param->oce_wan_scoring.score_pcnt15_to_12);
15781 
15782 	wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0);
15783 	status = wmi_unified_cmd_send(wmi_handle, buf,
15784 				      len, WMI_ROAM_AP_PROFILE);
15785 	if (QDF_IS_STATUS_ERROR(status)) {
15786 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d",
15787 			status);
15788 		wmi_buf_free(buf);
15789 	}
15790 
15791 	WMI_LOGD("WMI --> WMI_ROAM_AP_PROFILE and other parameters");
15792 
15793 	return status;
15794 }
15795 
15796 /**
15797  * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period
15798  * @wmi_handle: wmi handle
15799  * @scan_period: scan period
15800  * @scan_age: scan age
15801  * @vdev_id: vdev id
15802  *
15803  * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
15804  *
15805  * Return: CDF status
15806  */
15807 static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle,
15808 					     uint32_t scan_period,
15809 					     uint32_t scan_age,
15810 					     uint32_t vdev_id)
15811 {
15812 	QDF_STATUS status;
15813 	wmi_buf_t buf = NULL;
15814 	int len;
15815 	uint8_t *buf_ptr;
15816 	wmi_roam_scan_period_fixed_param *scan_period_fp;
15817 
15818 	/* Send scan period values */
15819 	len = sizeof(wmi_roam_scan_period_fixed_param);
15820 	buf = wmi_buf_alloc(wmi_handle, len);
15821 	if (!buf) {
15822 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15823 		return QDF_STATUS_E_NOMEM;
15824 	}
15825 
15826 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15827 	scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr;
15828 	WMITLV_SET_HDR(&scan_period_fp->tlv_header,
15829 		       WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param,
15830 		       WMITLV_GET_STRUCT_TLVLEN
15831 			       (wmi_roam_scan_period_fixed_param));
15832 	/* fill in scan period values */
15833 	scan_period_fp->vdev_id = vdev_id;
15834 	scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */
15835 	scan_period_fp->roam_scan_age = scan_age;
15836 
15837 	wmi_mtrace(WMI_ROAM_SCAN_PERIOD, NO_SESSION, 0);
15838 	status = wmi_unified_cmd_send(wmi_handle, buf,
15839 				      len, WMI_ROAM_SCAN_PERIOD);
15840 	if (QDF_IS_STATUS_ERROR(status)) {
15841 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d",
15842 			status);
15843 		goto error;
15844 	}
15845 
15846 	WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d",
15847 		__func__, scan_period, scan_age);
15848 	return QDF_STATUS_SUCCESS;
15849 error:
15850 	wmi_buf_free(buf);
15851 
15852 	return status;
15853 }
15854 
15855 /**
15856  * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list
15857  * @wmi_handle: wmi handle
15858  * @chan_count: channel count
15859  * @chan_list: channel list
15860  * @list_type: list type
15861  * @vdev_id: vdev id
15862  *
15863  * Set roam offload channel list.
15864  *
15865  * Return: CDF status
15866  */
15867 static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
15868 				   uint8_t chan_count,
15869 				   uint32_t *chan_list,
15870 				   uint8_t list_type, uint32_t vdev_id)
15871 {
15872 	wmi_buf_t buf = NULL;
15873 	QDF_STATUS status;
15874 	int len, list_tlv_len;
15875 	int i;
15876 	uint8_t *buf_ptr;
15877 	wmi_roam_chan_list_fixed_param *chan_list_fp;
15878 	uint32_t *roam_chan_list_array;
15879 
15880 	if (chan_count == 0) {
15881 		WMI_LOGD("%s : invalid number of channels %d", __func__,
15882 			 chan_count);
15883 		return QDF_STATUS_E_EMPTY;
15884 	}
15885 	/* Channel list is a table of 2 TLV's */
15886 	list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t);
15887 	len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len;
15888 	buf = wmi_buf_alloc(wmi_handle, len);
15889 	if (!buf) {
15890 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15891 		return QDF_STATUS_E_NOMEM;
15892 	}
15893 
15894 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15895 	chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr;
15896 	WMITLV_SET_HDR(&chan_list_fp->tlv_header,
15897 		       WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param,
15898 		       WMITLV_GET_STRUCT_TLVLEN
15899 			       (wmi_roam_chan_list_fixed_param));
15900 	chan_list_fp->vdev_id = vdev_id;
15901 	chan_list_fp->num_chan = chan_count;
15902 	if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) {
15903 		/* external app is controlling channel list */
15904 		chan_list_fp->chan_list_type =
15905 			WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC;
15906 	} else {
15907 		/* umac supplied occupied channel list in LFR */
15908 		chan_list_fp->chan_list_type =
15909 			WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC;
15910 	}
15911 
15912 	buf_ptr += sizeof(wmi_roam_chan_list_fixed_param);
15913 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
15914 		       (chan_list_fp->num_chan * sizeof(uint32_t)));
15915 	roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
15916 	WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan);
15917 	for (i = 0; ((i < chan_list_fp->num_chan) &&
15918 		     (i < WMI_ROAM_MAX_CHANNELS)); i++) {
15919 		roam_chan_list_array[i] = chan_list[i];
15920 		WMI_LOGD("%d,", roam_chan_list_array[i]);
15921 	}
15922 
15923 	wmi_mtrace(WMI_ROAM_CHAN_LIST, NO_SESSION, 0);
15924 	status = wmi_unified_cmd_send(wmi_handle, buf,
15925 				      len, WMI_ROAM_CHAN_LIST);
15926 	if (QDF_IS_STATUS_ERROR(status)) {
15927 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d",
15928 			status);
15929 		goto error;
15930 	}
15931 
15932 	WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__);
15933 	return QDF_STATUS_SUCCESS;
15934 error:
15935 	wmi_buf_free(buf);
15936 
15937 	return status;
15938 }
15939 
15940 /**
15941  * send_per_roam_config_cmd_tlv() - set per roaming config to FW
15942  * @wmi_handle: wmi handle
15943  * @req_buf: per roam config buffer
15944  *
15945  * Return: QDF status
15946  */
15947 static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle,
15948 		struct wmi_per_roam_config_req *req_buf)
15949 {
15950 	wmi_buf_t buf = NULL;
15951 	QDF_STATUS status;
15952 	int len;
15953 	uint8_t *buf_ptr;
15954 	wmi_roam_per_config_fixed_param *wmi_per_config;
15955 
15956 	len = sizeof(wmi_roam_per_config_fixed_param);
15957 	buf = wmi_buf_alloc(wmi_handle, len);
15958 	if (!buf) {
15959 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15960 		return QDF_STATUS_E_NOMEM;
15961 	}
15962 
15963 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15964 	wmi_per_config =
15965 		(wmi_roam_per_config_fixed_param *) buf_ptr;
15966 	WMITLV_SET_HDR(&wmi_per_config->tlv_header,
15967 			WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param,
15968 			WMITLV_GET_STRUCT_TLVLEN
15969 			(wmi_roam_per_config_fixed_param));
15970 
15971 	/* fill in per roam config values */
15972 	wmi_per_config->vdev_id = req_buf->vdev_id;
15973 
15974 	wmi_per_config->enable = req_buf->per_config.enable;
15975 	wmi_per_config->high_rate_thresh =
15976 		(req_buf->per_config.tx_high_rate_thresh << 16) |
15977 		(req_buf->per_config.rx_high_rate_thresh & 0x0000ffff);
15978 	wmi_per_config->low_rate_thresh =
15979 		(req_buf->per_config.tx_low_rate_thresh << 16) |
15980 		(req_buf->per_config.rx_low_rate_thresh & 0x0000ffff);
15981 	wmi_per_config->pkt_err_rate_thresh_pct =
15982 		(req_buf->per_config.tx_rate_thresh_percnt << 16) |
15983 		(req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff);
15984 	wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time;
15985 	wmi_per_config->pkt_err_rate_mon_time =
15986 			(req_buf->per_config.tx_per_mon_time << 16) |
15987 			(req_buf->per_config.rx_per_mon_time & 0x0000ffff);
15988 	wmi_per_config->min_candidate_rssi =
15989 			req_buf->per_config.min_candidate_rssi;
15990 
15991 	/* Send per roam config parameters */
15992 	wmi_mtrace(WMI_ROAM_PER_CONFIG_CMDID, NO_SESSION, 0);
15993 	status = wmi_unified_cmd_send(wmi_handle, buf,
15994 			len, WMI_ROAM_PER_CONFIG_CMDID);
15995 	if (QDF_IS_STATUS_ERROR(status)) {
15996 		WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d",
15997 			 status);
15998 		wmi_buf_free(buf);
15999 		return status;
16000 	}
16001 	WMI_LOGD(FL("per roam enable=%d, vdev=%d"),
16002 		 req_buf->per_config.enable, req_buf->vdev_id);
16003 
16004 	return QDF_STATUS_SUCCESS;
16005 }
16006 
16007 /**
16008  * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th
16009  * @wmi_handle: wmi handle
16010  * @rssi_change_thresh: RSSI Change threshold
16011  * @bcn_rssi_weight: beacon RSSI weight
16012  * @vdev_id: vdev id
16013  *
16014  * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
16015  *
16016  * Return: CDF status
16017  */
16018 static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle,
16019 	uint32_t vdev_id,
16020 	int32_t rssi_change_thresh,
16021 	uint32_t bcn_rssi_weight,
16022 	uint32_t hirssi_delay_btw_scans)
16023 {
16024 	wmi_buf_t buf = NULL;
16025 	QDF_STATUS status;
16026 	int len;
16027 	uint8_t *buf_ptr;
16028 	wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp;
16029 
16030 	/* Send rssi change parameters */
16031 	len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param);
16032 	buf = wmi_buf_alloc(wmi_handle, len);
16033 	if (!buf) {
16034 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16035 		return QDF_STATUS_E_NOMEM;
16036 	}
16037 
16038 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16039 	rssi_change_fp =
16040 		(wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr;
16041 	WMITLV_SET_HDR(&rssi_change_fp->tlv_header,
16042 		       WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param,
16043 		       WMITLV_GET_STRUCT_TLVLEN
16044 			       (wmi_roam_scan_rssi_change_threshold_fixed_param));
16045 	/* fill in rssi change threshold (hysteresis) values */
16046 	rssi_change_fp->vdev_id = vdev_id;
16047 	rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh;
16048 	rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight;
16049 	rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans;
16050 
16051 	wmi_mtrace(WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, NO_SESSION, 0);
16052 	status = wmi_unified_cmd_send(wmi_handle, buf,
16053 				      len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD);
16054 	if (QDF_IS_STATUS_ERROR(status)) {
16055 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d",
16056 			status);
16057 		goto error;
16058 	}
16059 
16060 	WMI_LOGD(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"),
16061 		 rssi_change_thresh, bcn_rssi_weight);
16062 	WMI_LOGD(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans);
16063 	return QDF_STATUS_SUCCESS;
16064 error:
16065 	wmi_buf_free(buf);
16066 
16067 	return status;
16068 }
16069 
16070 /**
16071  * send_power_dbg_cmd_tlv() - send power debug commands
16072  * @wmi_handle: wmi handle
16073  * @param: wmi power debug parameter
16074  *
16075  * Send WMI_POWER_DEBUG_CMDID parameters to fw.
16076  *
16077  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16078  */
16079 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle,
16080 					 struct wmi_power_dbg_params *param)
16081 {
16082 	wmi_buf_t buf = NULL;
16083 	QDF_STATUS status;
16084 	int len, args_tlv_len;
16085 	uint8_t *buf_ptr;
16086 	uint8_t i;
16087 	wmi_pdev_wal_power_debug_cmd_fixed_param *cmd;
16088 	uint32_t *cmd_args;
16089 
16090 	/* Prepare and send power debug cmd parameters */
16091 	args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t);
16092 	len = sizeof(*cmd) + args_tlv_len;
16093 	buf = wmi_buf_alloc(wmi_handle, len);
16094 	if (!buf) {
16095 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16096 		return QDF_STATUS_E_NOMEM;
16097 	}
16098 
16099 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16100 	cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr;
16101 	WMITLV_SET_HDR(&cmd->tlv_header,
16102 		  WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param,
16103 		  WMITLV_GET_STRUCT_TLVLEN
16104 		  (wmi_pdev_wal_power_debug_cmd_fixed_param));
16105 
16106 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
16107 								param->pdev_id);
16108 	cmd->module_id = param->module_id;
16109 	cmd->num_args = param->num_args;
16110 	buf_ptr += sizeof(*cmd);
16111 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
16112 		       (param->num_args * sizeof(uint32_t)));
16113 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
16114 	WMI_LOGI("%s: %d num of args = ", __func__, param->num_args);
16115 	for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) {
16116 		cmd_args[i] = param->args[i];
16117 		WMI_LOGI("%d,", param->args[i]);
16118 	}
16119 
16120 	wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0);
16121 	status = wmi_unified_cmd_send(wmi_handle, buf,
16122 				      len, WMI_PDEV_WAL_POWER_DEBUG_CMDID);
16123 	if (QDF_IS_STATUS_ERROR(status)) {
16124 		WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d",
16125 			status);
16126 		goto error;
16127 	}
16128 
16129 	return QDF_STATUS_SUCCESS;
16130 error:
16131 	wmi_buf_free(buf);
16132 
16133 	return status;
16134 }
16135 
16136 /**
16137  * send_multiple_vdev_restart_req_cmd_tlv() - send multiple vdev restart req
16138  * @wmi_handle: wmi handle
16139  * @param: wmi multiple vdev restart req param
16140  *
16141  * Send WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID parameters to fw.
16142  *
16143  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16144  */
16145 static QDF_STATUS send_multiple_vdev_restart_req_cmd_tlv(
16146 				wmi_unified_t wmi_handle,
16147 				struct multiple_vdev_restart_params *param)
16148 {
16149 	wmi_buf_t buf;
16150 	QDF_STATUS qdf_status;
16151 	wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *cmd;
16152 	int i;
16153 	uint8_t *buf_ptr;
16154 	uint32_t *vdev_ids;
16155 	wmi_channel *chan_info;
16156 	struct channel_param *tchan_info;
16157 	uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
16158 
16159 	len += sizeof(wmi_channel);
16160 	if (param->num_vdevs)
16161 		len += sizeof(uint32_t) * param->num_vdevs;
16162 
16163 	buf = wmi_buf_alloc(wmi_handle, len);
16164 	if (!buf) {
16165 		WMI_LOGE("Failed to allocate memory\n");
16166 		qdf_status = QDF_STATUS_E_NOMEM;
16167 		goto end;
16168 	}
16169 
16170 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
16171 	cmd = (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *)
16172 	       buf_ptr;
16173 
16174 	WMITLV_SET_HDR(&cmd->tlv_header,
16175 	WMITLV_TAG_STRUC_wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param,
16176 	WMITLV_GET_STRUCT_TLVLEN
16177 		(wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param));
16178 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
16179 								param->pdev_id);
16180 	cmd->requestor_id = param->requestor_id;
16181 	cmd->disable_hw_ack = param->disable_hw_ack;
16182 	cmd->cac_duration_ms = param->cac_duration_ms;
16183 	cmd->num_vdevs = param->num_vdevs;
16184 
16185 	WMI_LOGI("%s:cmd->pdev_id: %d ,cmd->requestor_id: %d ,"
16186 		"cmd->disable_hw_ack: %d , cmd->cac_duration_ms:%d ,"
16187 		" cmd->num_vdevs: %d ",
16188 		__func__, cmd->pdev_id, cmd->requestor_id,
16189 		cmd->disable_hw_ack, cmd->cac_duration_ms, cmd->num_vdevs);
16190 	buf_ptr += sizeof(*cmd);
16191 
16192 	WMITLV_SET_HDR(buf_ptr,
16193 		       WMITLV_TAG_ARRAY_UINT32,
16194 		       sizeof(uint32_t) * param->num_vdevs);
16195 	vdev_ids = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
16196 	for (i = 0; i < param->num_vdevs; i++) {
16197 		vdev_ids[i] = param->vdev_ids[i];
16198 	}
16199 
16200 	buf_ptr += (sizeof(uint32_t) * param->num_vdevs) + WMI_TLV_HDR_SIZE;
16201 
16202 	WMITLV_SET_HDR(buf_ptr,
16203 		       WMITLV_TAG_STRUC_wmi_channel,
16204 		       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
16205 	chan_info = (wmi_channel *)buf_ptr;
16206 	tchan_info = &(param->ch_param);
16207 	chan_info->mhz = tchan_info->mhz;
16208 	chan_info->band_center_freq1 = tchan_info->cfreq1;
16209 	chan_info->band_center_freq2 = tchan_info->cfreq2;
16210 	if (tchan_info->is_chan_passive)
16211 		WMI_SET_CHANNEL_FLAG(chan_info,
16212 				     WMI_CHAN_FLAG_PASSIVE);
16213 	if (tchan_info->dfs_set)
16214 		WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS);
16215 
16216 	if (tchan_info->allow_vht)
16217 		WMI_SET_CHANNEL_FLAG(chan_info,
16218 				     WMI_CHAN_FLAG_ALLOW_VHT);
16219 	else  if (tchan_info->allow_ht)
16220 		WMI_SET_CHANNEL_FLAG(chan_info,
16221 				     WMI_CHAN_FLAG_ALLOW_HT);
16222 	WMI_SET_CHANNEL_MODE(chan_info, tchan_info->phy_mode);
16223 	WMI_SET_CHANNEL_MIN_POWER(chan_info, tchan_info->minpower);
16224 	WMI_SET_CHANNEL_MAX_POWER(chan_info, tchan_info->maxpower);
16225 	WMI_SET_CHANNEL_REG_POWER(chan_info, tchan_info->maxregpower);
16226 	WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, tchan_info->antennamax);
16227 	WMI_SET_CHANNEL_REG_CLASSID(chan_info, tchan_info->reg_class_id);
16228 	WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, tchan_info->maxregpower);
16229 
16230 	WMI_LOGI("%s:tchan_info->is_chan_passive: %d ,"
16231 		"tchan_info->dfs_set : %d ,tchan_info->allow_vht:%d ,"
16232 		"tchan_info->allow_ht: %d ,tchan_info->antennamax: %d ,"
16233 		"tchan_info->phy_mode: %d ,tchan_info->minpower: %d,"
16234 		"tchan_info->maxpower: %d ,tchan_info->maxregpower: %d ,"
16235 		"tchan_info->reg_class_id: %d ,"
16236 		"tchan_info->maxregpower : %d ", __func__,
16237 		tchan_info->is_chan_passive, tchan_info->dfs_set,
16238 		tchan_info->allow_vht, tchan_info->allow_ht,
16239 		tchan_info->antennamax, tchan_info->phy_mode,
16240 		tchan_info->minpower, tchan_info->maxpower,
16241 		tchan_info->maxregpower, tchan_info->reg_class_id,
16242 		tchan_info->maxregpower);
16243 
16244 	wmi_mtrace(WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID, NO_SESSION, 0);
16245 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
16246 				WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID);
16247 
16248 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
16249 		WMI_LOGE("%s: Failed to send\n", __func__);
16250 		wmi_buf_free(buf);
16251 	}
16252 
16253 end:
16254 	return qdf_status;
16255 }
16256 
16257 /**
16258  * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd
16259  * @wmi_handle: wmi handle
16260  * @pdev_id: pdev id
16261  *
16262  * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware.
16263  *
16264  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16265  */
16266 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle,
16267 		uint32_t pdev_id)
16268 {
16269 	wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd;
16270 	wmi_buf_t buf;
16271 	uint16_t len;
16272 	QDF_STATUS ret;
16273 
16274 	len = sizeof(*cmd);
16275 	buf = wmi_buf_alloc(wmi_handle, len);
16276 
16277 	WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id);
16278 
16279 	if (!buf) {
16280 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16281 		return QDF_STATUS_E_NOMEM;
16282 	}
16283 
16284 	cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *)
16285 		wmi_buf_data(buf);
16286 
16287 	WMITLV_SET_HDR(&cmd->tlv_header,
16288 	WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param,
16289 	WMITLV_GET_STRUCT_TLVLEN(
16290 		wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param));
16291 
16292 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
16293 	wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0);
16294 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
16295 			WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID);
16296 	if (QDF_IS_STATUS_ERROR(ret)) {
16297 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d",
16298 			__func__, ret, pdev_id);
16299 		wmi_buf_free(buf);
16300 		return QDF_STATUS_E_FAILURE;
16301 	}
16302 
16303 	return QDF_STATUS_SUCCESS;
16304 }
16305 
16306 /**
16307  * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd
16308  * @wmi_handle: wmi handle
16309  * @pdev_id: pdev id
16310  *
16311  * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware.
16312  *
16313  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16314  */
16315 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle,
16316 		uint32_t pdev_id)
16317 {
16318 	wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd;
16319 	wmi_buf_t buf;
16320 	uint16_t len;
16321 	QDF_STATUS ret;
16322 
16323 	len = sizeof(*cmd);
16324 	buf = wmi_buf_alloc(wmi_handle, len);
16325 
16326 	WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id);
16327 
16328 	if (!buf) {
16329 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16330 		return QDF_STATUS_E_NOMEM;
16331 	}
16332 
16333 	cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *)
16334 		wmi_buf_data(buf);
16335 
16336 	WMITLV_SET_HDR(&cmd->tlv_header,
16337 	WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param,
16338 	WMITLV_GET_STRUCT_TLVLEN(
16339 		wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param));
16340 
16341 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
16342 	wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0);
16343 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
16344 			WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID);
16345 	if (QDF_IS_STATUS_ERROR(ret)) {
16346 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d",
16347 			__func__, ret, pdev_id);
16348 		wmi_buf_free(buf);
16349 		return QDF_STATUS_E_FAILURE;
16350 	}
16351 
16352 	return QDF_STATUS_SUCCESS;
16353 }
16354 
16355 /**
16356  * init_cmd_send_tlv() - send initialization cmd to fw
16357  * @wmi_handle: wmi handle
16358  * @param param: pointer to wmi init param
16359  *
16360  * Return: QDF_STATUS_SUCCESS for success or error code
16361  */
16362 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle,
16363 				struct wmi_init_cmd_param *param)
16364 {
16365 	wmi_buf_t buf;
16366 	wmi_init_cmd_fixed_param *cmd;
16367 	uint8_t *buf_ptr;
16368 	wmi_resource_config *resource_cfg;
16369 	wlan_host_memory_chunk *host_mem_chunks;
16370 	uint32_t mem_chunk_len = 0, hw_mode_len = 0;
16371 	uint16_t idx;
16372 	int len;
16373 	QDF_STATUS ret;
16374 
16375 	len = sizeof(*cmd) + sizeof(wmi_resource_config) +
16376 		WMI_TLV_HDR_SIZE;
16377 	mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS);
16378 
16379 	if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX)
16380 		hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) +
16381 			WMI_TLV_HDR_SIZE +
16382 			(param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac));
16383 
16384 	buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len);
16385 	if (!buf) {
16386 		qdf_print("%s: wmi_buf_alloc failed", __func__);
16387 		return QDF_STATUS_E_FAILURE;
16388 	}
16389 
16390 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16391 	cmd = (wmi_init_cmd_fixed_param *) buf_ptr;
16392 	resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd));
16393 
16394 	host_mem_chunks = (wlan_host_memory_chunk *)
16395 		(buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)
16396 		 + WMI_TLV_HDR_SIZE);
16397 
16398 	WMITLV_SET_HDR(&cmd->tlv_header,
16399 			WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param,
16400 			WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param));
16401 
16402 	wmi_copy_resource_config(resource_cfg, param->res_cfg);
16403 	WMITLV_SET_HDR(&resource_cfg->tlv_header,
16404 			WMITLV_TAG_STRUC_wmi_resource_config,
16405 			WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config));
16406 
16407 	for (idx = 0; idx < param->num_mem_chunks; ++idx) {
16408 		WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header),
16409 				WMITLV_TAG_STRUC_wlan_host_memory_chunk,
16410 				WMITLV_GET_STRUCT_TLVLEN
16411 				(wlan_host_memory_chunk));
16412 		host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr;
16413 		host_mem_chunks[idx].size = param->mem_chunks[idx].len;
16414 		host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id;
16415 		QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG,
16416 				"chunk %d len %d requested ,ptr  0x%x ",
16417 				idx, host_mem_chunks[idx].size,
16418 				host_mem_chunks[idx].ptr);
16419 	}
16420 	cmd->num_host_mem_chunks = param->num_mem_chunks;
16421 	len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk));
16422 
16423 	WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)),
16424 			WMITLV_TAG_ARRAY_STRUC,
16425 			(sizeof(wlan_host_memory_chunk) *
16426 			 param->num_mem_chunks));
16427 
16428 	/* Fill hw mode id config */
16429 	buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param);
16430 
16431 	/* Fill fw_abi_vers */
16432 	copy_fw_abi_version_tlv(wmi_handle, cmd);
16433 
16434 	wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0);
16435 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID);
16436 	if (QDF_IS_STATUS_ERROR(ret)) {
16437 		WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d",
16438 			ret);
16439 		wmi_buf_free(buf);
16440 	}
16441 
16442 	return ret;
16443 
16444 }
16445 
16446 /**
16447  * send_addba_send_cmd_tlv() - send addba send command to fw
16448  * @wmi_handle: wmi handle
16449  * @param: pointer to delba send params
16450  * @macaddr: peer mac address
16451  *
16452  * Send WMI_ADDBA_SEND_CMDID command to firmware
16453  * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error
16454  */
16455 static QDF_STATUS
16456 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle,
16457 				uint8_t macaddr[IEEE80211_ADDR_LEN],
16458 				struct addba_send_params *param)
16459 {
16460 	wmi_addba_send_cmd_fixed_param *cmd;
16461 	wmi_buf_t buf;
16462 	uint16_t len;
16463 	QDF_STATUS ret;
16464 
16465 	len = sizeof(*cmd);
16466 
16467 	buf = wmi_buf_alloc(wmi_handle, len);
16468 	if (!buf) {
16469 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16470 		return QDF_STATUS_E_NOMEM;
16471 	}
16472 
16473 	cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf);
16474 
16475 	WMITLV_SET_HDR(&cmd->tlv_header,
16476 			WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param,
16477 			WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param));
16478 
16479 	cmd->vdev_id = param->vdev_id;
16480 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
16481 	cmd->tid = param->tidno;
16482 	cmd->buffersize = param->buffersize;
16483 
16484 	wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0);
16485 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID);
16486 	if (QDF_IS_STATUS_ERROR(ret)) {
16487 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret);
16488 		wmi_buf_free(buf);
16489 		return QDF_STATUS_E_FAILURE;
16490 	}
16491 
16492 	return QDF_STATUS_SUCCESS;
16493 }
16494 
16495 /**
16496  * send_delba_send_cmd_tlv() - send delba send command to fw
16497  * @wmi_handle: wmi handle
16498  * @param: pointer to delba send params
16499  * @macaddr: peer mac address
16500  *
16501  * Send WMI_DELBA_SEND_CMDID command to firmware
16502  * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error
16503  */
16504 static QDF_STATUS
16505 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle,
16506 				uint8_t macaddr[IEEE80211_ADDR_LEN],
16507 				struct delba_send_params *param)
16508 {
16509 	wmi_delba_send_cmd_fixed_param *cmd;
16510 	wmi_buf_t buf;
16511 	uint16_t len;
16512 	QDF_STATUS ret;
16513 
16514 	len = sizeof(*cmd);
16515 
16516 	buf = wmi_buf_alloc(wmi_handle, len);
16517 	if (!buf) {
16518 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16519 		return QDF_STATUS_E_NOMEM;
16520 	}
16521 
16522 	cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf);
16523 
16524 	WMITLV_SET_HDR(&cmd->tlv_header,
16525 			WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param,
16526 			WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param));
16527 
16528 	cmd->vdev_id = param->vdev_id;
16529 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
16530 	cmd->tid = param->tidno;
16531 	cmd->initiator = param->initiator;
16532 	cmd->reasoncode = param->reasoncode;
16533 
16534 	wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0);
16535 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID);
16536 	if (QDF_IS_STATUS_ERROR(ret)) {
16537 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret);
16538 		wmi_buf_free(buf);
16539 		return QDF_STATUS_E_FAILURE;
16540 	}
16541 
16542 	return QDF_STATUS_SUCCESS;
16543 }
16544 
16545 /**
16546  * send_addba_clearresponse_cmd_tlv() - send addba clear response command
16547  * to fw
16548  * @wmi_handle: wmi handle
16549  * @param: pointer to addba clearresp params
16550  * @macaddr: peer mac address
16551  * Return: 0 for success or error code
16552  */
16553 static QDF_STATUS
16554 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle,
16555 			uint8_t macaddr[IEEE80211_ADDR_LEN],
16556 			struct addba_clearresponse_params *param)
16557 {
16558 	wmi_addba_clear_resp_cmd_fixed_param *cmd;
16559 	wmi_buf_t buf;
16560 	uint16_t len;
16561 	QDF_STATUS ret;
16562 
16563 	len = sizeof(*cmd);
16564 
16565 	buf = wmi_buf_alloc(wmi_handle, len);
16566 	if (!buf) {
16567 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
16568 		return QDF_STATUS_E_FAILURE;
16569 	}
16570 	cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf);
16571 
16572 	WMITLV_SET_HDR(&cmd->tlv_header,
16573 		WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param,
16574 		WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param));
16575 
16576 	cmd->vdev_id = param->vdev_id;
16577 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
16578 
16579 	wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0);
16580 	ret = wmi_unified_cmd_send(wmi_handle,
16581 				buf, len, WMI_ADDBA_CLEAR_RESP_CMDID);
16582 	if (QDF_IS_STATUS_ERROR(ret)) {
16583 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret);
16584 		wmi_buf_free(buf);
16585 		return QDF_STATUS_E_FAILURE;
16586 	}
16587 
16588 	return QDF_STATUS_SUCCESS;
16589 }
16590 
16591 /**
16592  * send_bcn_offload_control_cmd_tlv - send beacon ofload control cmd to fw
16593  * @wmi_handle: wmi handle
16594  * @bcn_ctrl_param: pointer to bcn_offload_control param
16595  *
16596  * Return: QDF_STATUS_SUCCESS for success or error code
16597  */
16598 static
16599 QDF_STATUS send_bcn_offload_control_cmd_tlv(wmi_unified_t wmi_handle,
16600 			struct bcn_offload_control *bcn_ctrl_param)
16601 {
16602 	wmi_buf_t buf;
16603 	wmi_bcn_offload_ctrl_cmd_fixed_param *cmd;
16604 	QDF_STATUS ret;
16605 	uint32_t len;
16606 
16607 	len = sizeof(*cmd);
16608 
16609 	buf = wmi_buf_alloc(wmi_handle, len);
16610 	if (!buf) {
16611 		qdf_print("%s: wmi_buf_alloc failed", __func__);
16612 		return QDF_STATUS_E_FAILURE;
16613 	}
16614 
16615 	cmd = (wmi_bcn_offload_ctrl_cmd_fixed_param *) wmi_buf_data(buf);
16616 	WMITLV_SET_HDR(&cmd->tlv_header,
16617 			WMITLV_TAG_STRUC_wmi_bcn_offload_ctrl_cmd_fixed_param,
16618 			WMITLV_GET_STRUCT_TLVLEN
16619 			(wmi_bcn_offload_ctrl_cmd_fixed_param));
16620 	cmd->vdev_id = bcn_ctrl_param->vdev_id;
16621 	switch (bcn_ctrl_param->bcn_ctrl_op) {
16622 	case BCN_OFFLD_CTRL_TX_DISABLE:
16623 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_DISABLE;
16624 		break;
16625 	case BCN_OFFLD_CTRL_TX_ENABLE:
16626 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_ENABLE;
16627 		break;
16628 	case BCN_OFFLD_CTRL_SWBA_DISABLE:
16629 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_DISABLE;
16630 		break;
16631 	case BCN_OFFLD_CTRL_SWBA_ENABLE:
16632 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_ENABLE;
16633 		break;
16634 	default:
16635 		WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID unknown CTRL Operation %d",
16636 			bcn_ctrl_param->bcn_ctrl_op);
16637 		wmi_buf_free(buf);
16638 		return QDF_STATUS_E_FAILURE;
16639 		break;
16640 	}
16641 	wmi_mtrace(WMI_BCN_OFFLOAD_CTRL_CMDID, cmd->vdev_id, 0);
16642 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
16643 			WMI_BCN_OFFLOAD_CTRL_CMDID);
16644 
16645 	if (QDF_IS_STATUS_ERROR(ret)) {
16646 		WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID send returned Error %d",
16647 				ret);
16648 		wmi_buf_free(buf);
16649 	}
16650 
16651 	return ret;
16652 }
16653 
16654 #ifdef WLAN_FEATURE_NAN_CONVERGENCE
16655 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle,
16656 				struct nan_datapath_initiator_req *ndp_req)
16657 {
16658 	uint16_t len;
16659 	wmi_buf_t buf;
16660 	uint8_t *tlv_ptr;
16661 	QDF_STATUS status;
16662 	wmi_channel *ch_tlv;
16663 	wmi_ndp_initiator_req_fixed_param *cmd;
16664 	uint32_t passphrase_len, service_name_len;
16665 	uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len;
16666 	wmi_ndp_transport_ip_param *tcp_ip_param;
16667 
16668 	/*
16669 	 * WMI command expects 4 byte alligned len:
16670 	 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes
16671 	 */
16672 	ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4);
16673 	ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4);
16674 	pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4);
16675 	passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4);
16676 	service_name_len =
16677 		   qdf_roundup(ndp_req->service_name.service_name_len, 4);
16678 	/* allocated memory for fixed params as well as variable size data */
16679 	len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE)
16680 		+ ndp_cfg_len + ndp_app_info_len + pmk_len
16681 		+ passphrase_len + service_name_len;
16682 
16683 	if (ndp_req->is_ipv6_addr_present)
16684 		len += sizeof(*tcp_ip_param);
16685 
16686 	buf = wmi_buf_alloc(wmi_handle, len);
16687 	if (!buf) {
16688 		WMI_LOGE("wmi_buf_alloc failed");
16689 		return QDF_STATUS_E_NOMEM;
16690 	}
16691 
16692 	cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf);
16693 	WMITLV_SET_HDR(&cmd->tlv_header,
16694 		       WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param,
16695 		       WMITLV_GET_STRUCT_TLVLEN(
16696 				wmi_ndp_initiator_req_fixed_param));
16697 	cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev);
16698 	cmd->transaction_id = ndp_req->transaction_id;
16699 	cmd->service_instance_id = ndp_req->service_instance_id;
16700 	WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes,
16701 				   &cmd->peer_discovery_mac_addr);
16702 
16703 	cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len;
16704 	cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len;
16705 	cmd->ndp_channel_cfg = ndp_req->channel_cfg;
16706 	cmd->nan_pmk_len = ndp_req->pmk.pmk_len;
16707 	cmd->nan_csid = ndp_req->ncs_sk_type;
16708 	cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len;
16709 	cmd->nan_servicename_len = ndp_req->service_name.service_name_len;
16710 
16711 	ch_tlv = (wmi_channel *)&cmd[1];
16712 	WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel,
16713 			WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
16714 	ch_tlv->mhz = ndp_req->channel;
16715 	tlv_ptr = (uint8_t *)&ch_tlv[1];
16716 
16717 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len);
16718 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16719 		     ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len);
16720 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len;
16721 
16722 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len);
16723 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16724 		     ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len);
16725 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len;
16726 
16727 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len);
16728 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk,
16729 		     cmd->nan_pmk_len);
16730 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len;
16731 
16732 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len);
16733 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase,
16734 		     cmd->nan_passphrase_len);
16735 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len;
16736 
16737 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len);
16738 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16739 		     ndp_req->service_name.service_name,
16740 		     cmd->nan_servicename_len);
16741 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len;
16742 
16743 	if (ndp_req->is_ipv6_addr_present) {
16744 		tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr;
16745 		WMITLV_SET_HDR(tcp_ip_param,
16746 			       WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param,
16747 			       WMITLV_GET_STRUCT_TLVLEN(
16748 						wmi_ndp_transport_ip_param));
16749 		tcp_ip_param->ipv6_addr_present = true;
16750 		qdf_mem_copy(tcp_ip_param->ipv6_intf_addr,
16751 			     ndp_req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN);
16752 	}
16753 	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
16754 		 ndp_req->is_ipv6_addr_present, ndp_req->ipv6_addr);
16755 
16756 	WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d",
16757 		 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id,
16758 		 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid);
16759 	WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x",
16760 		 cmd->peer_discovery_mac_addr.mac_addr31to0,
16761 		 cmd->peer_discovery_mac_addr.mac_addr47to32);
16762 
16763 	WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len);
16764 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16765 			   ndp_req->ndp_config.ndp_cfg,
16766 			   ndp_req->ndp_config.ndp_cfg_len);
16767 
16768 	WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len);
16769 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16770 			   ndp_req->ndp_info.ndp_app_info,
16771 			   ndp_req->ndp_info.ndp_app_info_len);
16772 
16773 	WMI_LOGD("pmk len: %d", cmd->nan_pmk_len);
16774 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16775 			   ndp_req->pmk.pmk, cmd->nan_pmk_len);
16776 
16777 	WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len);
16778 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16779 			   ndp_req->passphrase.passphrase,
16780 			   cmd->nan_passphrase_len);
16781 
16782 	WMI_LOGD("service name len: %d", cmd->nan_servicename_len);
16783 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16784 			   ndp_req->service_name.service_name,
16785 			   cmd->nan_servicename_len);
16786 
16787 	WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)",
16788 		 WMI_NDP_INITIATOR_REQ_CMDID);
16789 
16790 	wmi_mtrace(WMI_NDP_INITIATOR_REQ_CMDID, cmd->vdev_id, 0);
16791 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
16792 				      WMI_NDP_INITIATOR_REQ_CMDID);
16793 	if (QDF_IS_STATUS_ERROR(status)) {
16794 		WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status);
16795 		wmi_buf_free(buf);
16796 	}
16797 
16798 	return status;
16799 }
16800 
16801 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle,
16802 					struct nan_datapath_responder_req *req)
16803 {
16804 	uint16_t len;
16805 	wmi_buf_t buf;
16806 	uint8_t *tlv_ptr;
16807 	QDF_STATUS status;
16808 	wmi_ndp_responder_req_fixed_param *cmd;
16809 	wmi_ndp_transport_ip_param *tcp_ip_param;
16810 	uint32_t passphrase_len, service_name_len;
16811 	uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len;
16812 
16813 	vdev_id = wlan_vdev_get_id(req->vdev);
16814 	WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d",
16815 		 vdev_id, req->transaction_id,
16816 		 req->ndp_rsp,
16817 		 req->ndp_instance_id,
16818 		 req->ndp_info.ndp_app_info_len);
16819 
16820 	/*
16821 	 * WMI command expects 4 byte alligned len:
16822 	 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes
16823 	 */
16824 	ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4);
16825 	ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4);
16826 	pmk_len = qdf_roundup(req->pmk.pmk_len, 4);
16827 	passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4);
16828 	service_name_len =
16829 		qdf_roundup(req->service_name.service_name_len, 4);
16830 
16831 	/* allocated memory for fixed params as well as variable size data */
16832 	len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len
16833 		+ pmk_len + passphrase_len + service_name_len;
16834 
16835 	if (req->is_ipv6_addr_present || req->is_port_present ||
16836 	    req->is_protocol_present)
16837 		len += sizeof(*tcp_ip_param);
16838 
16839 	buf = wmi_buf_alloc(wmi_handle, len);
16840 	if (!buf) {
16841 		WMI_LOGE("wmi_buf_alloc failed");
16842 		return QDF_STATUS_E_NOMEM;
16843 	}
16844 	cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf);
16845 	WMITLV_SET_HDR(&cmd->tlv_header,
16846 		       WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param,
16847 		       WMITLV_GET_STRUCT_TLVLEN(
16848 				wmi_ndp_responder_req_fixed_param));
16849 	cmd->vdev_id = vdev_id;
16850 	cmd->transaction_id = req->transaction_id;
16851 	cmd->ndp_instance_id = req->ndp_instance_id;
16852 	cmd->rsp_code = req->ndp_rsp;
16853 	cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len;
16854 	cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len;
16855 	cmd->nan_pmk_len = req->pmk.pmk_len;
16856 	cmd->nan_csid = req->ncs_sk_type;
16857 	cmd->nan_passphrase_len = req->passphrase.passphrase_len;
16858 	cmd->nan_servicename_len = req->service_name.service_name_len;
16859 
16860 	tlv_ptr = (uint8_t *)&cmd[1];
16861 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len);
16862 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16863 		     req->ndp_config.ndp_cfg, cmd->ndp_cfg_len);
16864 
16865 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len;
16866 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len);
16867 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16868 		     req->ndp_info.ndp_app_info,
16869 		     req->ndp_info.ndp_app_info_len);
16870 
16871 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len;
16872 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len);
16873 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk,
16874 		     cmd->nan_pmk_len);
16875 
16876 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len;
16877 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len);
16878 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16879 		     req->passphrase.passphrase,
16880 		     cmd->nan_passphrase_len);
16881 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len;
16882 
16883 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len);
16884 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16885 		     req->service_name.service_name,
16886 		     cmd->nan_servicename_len);
16887 
16888 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len;
16889 
16890 	if (req->is_ipv6_addr_present || req->is_port_present ||
16891 	    req->is_protocol_present) {
16892 		tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr;
16893 		WMITLV_SET_HDR(tcp_ip_param,
16894 			       WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param,
16895 			       WMITLV_GET_STRUCT_TLVLEN(
16896 						wmi_ndp_transport_ip_param));
16897 		tcp_ip_param->ipv6_addr_present = req->is_ipv6_addr_present;
16898 		qdf_mem_copy(tcp_ip_param->ipv6_intf_addr,
16899 			     req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN);
16900 
16901 		tcp_ip_param->trans_port_present = req->is_port_present;
16902 		tcp_ip_param->transport_port = req->port;
16903 
16904 		tcp_ip_param->trans_proto_present = req->is_protocol_present;
16905 		tcp_ip_param->transport_protocol = req->protocol;
16906 	}
16907 	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
16908 		 req->is_ipv6_addr_present, req->ipv6_addr);
16909 	WMI_LOGD(FL("port: %d present: %d"), req->is_port_present, req->port);
16910 	WMI_LOGD(FL("protocol: %d present: %d"),
16911 		 req->is_protocol_present, req->protocol);
16912 
16913 	WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d",
16914 		 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid);
16915 
16916 	WMI_LOGD("ndp_config len: %d",
16917 		 req->ndp_config.ndp_cfg_len);
16918 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16919 			req->ndp_config.ndp_cfg,
16920 			req->ndp_config.ndp_cfg_len);
16921 
16922 	WMI_LOGD("ndp_app_info len: %d",
16923 		 req->ndp_info.ndp_app_info_len);
16924 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16925 			   req->ndp_info.ndp_app_info,
16926 			   req->ndp_info.ndp_app_info_len);
16927 
16928 	WMI_LOGD("pmk len: %d", cmd->nan_pmk_len);
16929 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16930 			   req->pmk.pmk, cmd->nan_pmk_len);
16931 
16932 	WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len);
16933 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16934 			   req->passphrase.passphrase,
16935 			   cmd->nan_passphrase_len);
16936 
16937 	WMI_LOGD("service name len: %d", cmd->nan_servicename_len);
16938 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16939 			   req->service_name.service_name,
16940 			   cmd->nan_servicename_len);
16941 
16942 	WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)",
16943 		 WMI_NDP_RESPONDER_REQ_CMDID);
16944 	wmi_mtrace(WMI_NDP_RESPONDER_REQ_CMDID, cmd->vdev_id, 0);
16945 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
16946 				      WMI_NDP_RESPONDER_REQ_CMDID);
16947 	if (QDF_IS_STATUS_ERROR(status)) {
16948 		WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status);
16949 		wmi_buf_free(buf);
16950 	}
16951 	return status;
16952 }
16953 
16954 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle,
16955 				      struct nan_datapath_end_req *req)
16956 {
16957 	uint16_t len;
16958 	wmi_buf_t buf;
16959 	QDF_STATUS status;
16960 	uint32_t ndp_end_req_len, i;
16961 	wmi_ndp_end_req *ndp_end_req_lst;
16962 	wmi_ndp_end_req_fixed_param *cmd;
16963 
16964 	/* len of tlv following fixed param  */
16965 	ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances;
16966 	/* above comes out to 4 byte alligned already, no need of padding */
16967 	len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE;
16968 	buf = wmi_buf_alloc(wmi_handle, len);
16969 	if (!buf) {
16970 		WMI_LOGE("Malloc failed");
16971 		return QDF_STATUS_E_NOMEM;
16972 	}
16973 
16974 	cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf);
16975 	WMITLV_SET_HDR(&cmd->tlv_header,
16976 		       WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param,
16977 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param));
16978 
16979 	cmd->transaction_id = req->transaction_id;
16980 
16981 	/* set tlv pointer to end of fixed param */
16982 	WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC,
16983 			ndp_end_req_len);
16984 
16985 	ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] +
16986 						WMI_TLV_HDR_SIZE);
16987 	for (i = 0; i < req->num_ndp_instances; i++) {
16988 		WMITLV_SET_HDR(&ndp_end_req_lst[i],
16989 				WMITLV_TAG_ARRAY_FIXED_STRUC,
16990 				(sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE));
16991 
16992 		ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i];
16993 	}
16994 
16995 	WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW");
16996 	wmi_mtrace(WMI_NDP_END_REQ_CMDID, NO_SESSION, 0);
16997 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
16998 				   WMI_NDP_END_REQ_CMDID);
16999 	if (QDF_IS_STATUS_ERROR(status)) {
17000 		WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status);
17001 		wmi_buf_free(buf);
17002 	}
17003 
17004 	return status;
17005 }
17006 
17007 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle,
17008 			uint8_t *data, struct nan_datapath_initiator_rsp *rsp)
17009 {
17010 	WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event;
17011 	wmi_ndp_initiator_rsp_event_fixed_param  *fixed_params;
17012 
17013 	event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data;
17014 	fixed_params = event->fixed_param;
17015 
17016 	rsp->vdev =
17017 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17018 						     fixed_params->vdev_id,
17019 						     WLAN_NAN_ID);
17020 	if (!rsp->vdev) {
17021 		WMI_LOGE("vdev is null");
17022 		return QDF_STATUS_E_INVAL;
17023 	}
17024 
17025 	rsp->transaction_id = fixed_params->transaction_id;
17026 	rsp->ndp_instance_id = fixed_params->ndp_instance_id;
17027 	rsp->status = fixed_params->rsp_status;
17028 	rsp->reason = fixed_params->reason_code;
17029 
17030 	return QDF_STATUS_SUCCESS;
17031 }
17032 
17033 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle,
17034 		uint8_t *data, struct nan_datapath_indication_event *rsp)
17035 {
17036 	WMI_NDP_INDICATION_EVENTID_param_tlvs *event;
17037 	wmi_ndp_indication_event_fixed_param *fixed_params;
17038 	size_t total_array_len;
17039 
17040 	event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data;
17041 	fixed_params =
17042 		(wmi_ndp_indication_event_fixed_param *)event->fixed_param;
17043 
17044 	if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) {
17045 		WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d",
17046 			 fixed_params->ndp_cfg_len, event->num_ndp_cfg);
17047 		return QDF_STATUS_E_INVAL;
17048 	}
17049 
17050 	if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) {
17051 		WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d",
17052 			 fixed_params->ndp_app_info_len,
17053 			 event->num_ndp_app_info);
17054 		return QDF_STATUS_E_INVAL;
17055 	}
17056 
17057 	if (fixed_params->ndp_cfg_len >
17058 		(WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) {
17059 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17060 			 __func__, fixed_params->ndp_cfg_len);
17061 		return QDF_STATUS_E_INVAL;
17062 	}
17063 
17064 	total_array_len = fixed_params->ndp_cfg_len +
17065 					sizeof(*fixed_params);
17066 
17067 	if (fixed_params->ndp_app_info_len >
17068 		(WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
17069 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17070 			 __func__, fixed_params->ndp_app_info_len);
17071 		return QDF_STATUS_E_INVAL;
17072 	}
17073 	total_array_len += fixed_params->ndp_app_info_len;
17074 
17075 	if (fixed_params->nan_scid_len >
17076 		(WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
17077 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17078 			 __func__, fixed_params->nan_scid_len);
17079 		return QDF_STATUS_E_INVAL;
17080 	}
17081 
17082 	rsp->vdev =
17083 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17084 						     fixed_params->vdev_id,
17085 						     WLAN_NAN_ID);
17086 	if (!rsp->vdev) {
17087 		WMI_LOGE("vdev is null");
17088 		return QDF_STATUS_E_INVAL;
17089 	}
17090 	rsp->service_instance_id = fixed_params->service_instance_id;
17091 	rsp->ndp_instance_id = fixed_params->ndp_instance_id;
17092 	rsp->role = fixed_params->self_ndp_role;
17093 	rsp->policy = fixed_params->accept_policy;
17094 
17095 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
17096 				rsp->peer_mac_addr.bytes);
17097 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr,
17098 				rsp->peer_discovery_mac_addr.bytes);
17099 
17100 	WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n"
17101 		"service_instance %d, ndp_instance %d, role %d, policy %d,\n"
17102 		"csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM",
17103 		 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id,
17104 		 fixed_params->service_instance_id,
17105 		 fixed_params->ndp_instance_id, fixed_params->self_ndp_role,
17106 		 fixed_params->accept_policy,
17107 		 fixed_params->nan_csid, fixed_params->nan_scid_len,
17108 		 rsp->peer_mac_addr.bytes,
17109 		 rsp->peer_discovery_mac_addr.bytes);
17110 
17111 	WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len);
17112 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17113 			   &event->ndp_cfg, fixed_params->ndp_cfg_len);
17114 
17115 	WMI_LOGD("ndp_app_info - %d bytes",
17116 			fixed_params->ndp_app_info_len);
17117 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17118 			&event->ndp_app_info, fixed_params->ndp_app_info_len);
17119 
17120 	rsp->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len;
17121 	rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len;
17122 	rsp->ncs_sk_type = fixed_params->nan_csid;
17123 	rsp->scid.scid_len = fixed_params->nan_scid_len;
17124 
17125 	if (rsp->ndp_config.ndp_cfg_len > NDP_QOS_INFO_LEN)
17126 		rsp->ndp_config.ndp_cfg_len = NDP_QOS_INFO_LEN;
17127 	qdf_mem_copy(rsp->ndp_config.ndp_cfg, event->ndp_cfg,
17128 		     rsp->ndp_config.ndp_cfg_len);
17129 
17130 	if (rsp->ndp_info.ndp_app_info_len > NDP_APP_INFO_LEN)
17131 		rsp->ndp_info.ndp_app_info_len = NDP_APP_INFO_LEN;
17132 	qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info,
17133 		     rsp->ndp_info.ndp_app_info_len);
17134 
17135 	if (rsp->scid.scid_len > NDP_SCID_BUF_LEN)
17136 		rsp->scid.scid_len = NDP_SCID_BUF_LEN;
17137 	qdf_mem_copy(rsp->scid.scid, event->ndp_scid, rsp->scid.scid_len);
17138 
17139 	if (event->ndp_transport_ip_param &&
17140 	    event->num_ndp_transport_ip_param) {
17141 		if (event->ndp_transport_ip_param->ipv6_addr_present) {
17142 			rsp->is_ipv6_addr_present = true;
17143 			qdf_mem_copy(rsp->ipv6_addr,
17144 				event->ndp_transport_ip_param->ipv6_intf_addr,
17145 				WMI_NDP_IPV6_INTF_ADDR_LEN);
17146 		}
17147 	}
17148 	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
17149 		 rsp->is_ipv6_addr_present, rsp->ipv6_addr);
17150 
17151 	WMI_LOGD("scid hex dump:");
17152 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17153 			   rsp->scid.scid, rsp->scid.scid_len);
17154 
17155 	return QDF_STATUS_SUCCESS;
17156 }
17157 
17158 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle,
17159 			uint8_t *data, struct nan_datapath_confirm_event *rsp)
17160 {
17161 	uint8_t i;
17162 	WMI_HOST_WLAN_PHY_MODE ch_mode;
17163 	WMI_NDP_CONFIRM_EVENTID_param_tlvs *event;
17164 	wmi_ndp_confirm_event_fixed_param *fixed_params;
17165 	size_t total_array_len;
17166 
17167 	event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data;
17168 	fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param;
17169 	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",
17170 		 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id,
17171 		 fixed_params->ndp_instance_id, fixed_params->rsp_code,
17172 		 fixed_params->reason_code,
17173 		 fixed_params->num_active_ndps_on_peer);
17174 	WMI_LOGE("num_ch: %d", fixed_params->num_ndp_channels);
17175 
17176 	if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) {
17177 		WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d",
17178 			 fixed_params->ndp_cfg_len, event->num_ndp_cfg);
17179 		return QDF_STATUS_E_INVAL;
17180 	}
17181 
17182 	WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len);
17183 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17184 		&event->ndp_cfg, fixed_params->ndp_cfg_len);
17185 
17186 	if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) {
17187 		WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d",
17188 			 fixed_params->ndp_app_info_len,
17189 			 event->num_ndp_app_info);
17190 		return QDF_STATUS_E_INVAL;
17191 	}
17192 
17193 	WMI_LOGD("ndp_app_info - %d bytes",
17194 			fixed_params->ndp_app_info_len);
17195 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17196 		&event->ndp_app_info, fixed_params->ndp_app_info_len);
17197 
17198 	if (fixed_params->ndp_cfg_len >
17199 			(WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) {
17200 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17201 			 __func__, fixed_params->ndp_cfg_len);
17202 		return QDF_STATUS_E_INVAL;
17203 	}
17204 
17205 	total_array_len = fixed_params->ndp_cfg_len +
17206 				sizeof(*fixed_params);
17207 
17208 	if (fixed_params->ndp_app_info_len >
17209 		(WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
17210 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17211 			 __func__, fixed_params->ndp_app_info_len);
17212 		return QDF_STATUS_E_INVAL;
17213 	}
17214 
17215 	rsp->vdev =
17216 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17217 						     fixed_params->vdev_id,
17218 						     WLAN_NAN_ID);
17219 	if (!rsp->vdev) {
17220 		WMI_LOGE("vdev is null");
17221 		return QDF_STATUS_E_INVAL;
17222 	}
17223 	rsp->ndp_instance_id = fixed_params->ndp_instance_id;
17224 	rsp->rsp_code = fixed_params->rsp_code;
17225 	rsp->reason_code = fixed_params->reason_code;
17226 	rsp->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer;
17227 	rsp->num_channels = fixed_params->num_ndp_channels;
17228 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
17229 				   rsp->peer_ndi_mac_addr.bytes);
17230 	rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len;
17231 	qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info,
17232 		     rsp->ndp_info.ndp_app_info_len);
17233 
17234 	if (rsp->num_channels > NAN_CH_INFO_MAX_CHANNELS) {
17235 		WMI_LOGE(FL("too many channels"));
17236 		rsp->num_channels = NAN_CH_INFO_MAX_CHANNELS;
17237 	}
17238 
17239 	for (i = 0; i < rsp->num_channels; i++) {
17240 		rsp->ch[i].channel = event->ndp_channel_list[i].mhz;
17241 		rsp->ch[i].nss = event->nss_list[i];
17242 		ch_mode = WMI_GET_CHANNEL_MODE(&event->ndp_channel_list[i]);
17243 		rsp->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle,
17244 								     ch_mode);
17245 		WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"),
17246 			 rsp->ch[i].channel,
17247 			 rsp->ch[i].ch_width,
17248 			 rsp->ch[i].nss);
17249 	}
17250 
17251 	if (event->ndp_transport_ip_param &&
17252 	    event->num_ndp_transport_ip_param) {
17253 		if (event->ndp_transport_ip_param->ipv6_addr_present) {
17254 			rsp->is_ipv6_addr_present = true;
17255 			qdf_mem_copy(rsp->ipv6_addr,
17256 				event->ndp_transport_ip_param->ipv6_intf_addr,
17257 				WMI_NDP_IPV6_INTF_ADDR_LEN);
17258 		}
17259 
17260 		if (event->ndp_transport_ip_param->trans_port_present) {
17261 			rsp->is_port_present = true;
17262 			rsp->port =
17263 			    event->ndp_transport_ip_param->transport_port;
17264 		}
17265 
17266 		if (event->ndp_transport_ip_param->trans_proto_present) {
17267 			rsp->is_protocol_present = true;
17268 			rsp->protocol =
17269 			    event->ndp_transport_ip_param->transport_protocol;
17270 		}
17271 	}
17272 	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
17273 		 rsp->is_ipv6_addr_present, rsp->ipv6_addr);
17274 	WMI_LOGD(FL("port: %d present: %d"), rsp->port, rsp->is_port_present);
17275 	WMI_LOGD(FL("protocol: %d present: %d"),
17276 		 rsp->protocol, rsp->is_protocol_present);
17277 
17278 	return QDF_STATUS_SUCCESS;
17279 }
17280 
17281 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle,
17282 			uint8_t *data, struct nan_datapath_responder_rsp *rsp)
17283 {
17284 	WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event;
17285 	wmi_ndp_responder_rsp_event_fixed_param  *fixed_params;
17286 
17287 	event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data;
17288 	fixed_params = event->fixed_param;
17289 
17290 	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",
17291 		 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id,
17292 		 rsp->peer_mac_addr.bytes, rsp->transaction_id,
17293 		 rsp->status, rsp->reason, rsp->create_peer);
17294 
17295 	rsp->vdev =
17296 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17297 						     fixed_params->vdev_id,
17298 						     WLAN_NAN_ID);
17299 	if (!rsp->vdev) {
17300 		WMI_LOGE("vdev is null");
17301 		return QDF_STATUS_E_INVAL;
17302 	}
17303 	rsp->transaction_id = fixed_params->transaction_id;
17304 	rsp->reason = fixed_params->reason_code;
17305 	rsp->status = fixed_params->rsp_status;
17306 	rsp->create_peer = fixed_params->create_peer;
17307 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
17308 				rsp->peer_mac_addr.bytes);
17309 
17310 	return QDF_STATUS_SUCCESS;
17311 }
17312 
17313 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle,
17314 			uint8_t *data, struct nan_datapath_end_rsp_event *rsp)
17315 {
17316 	WMI_NDP_END_RSP_EVENTID_param_tlvs *event;
17317 	wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL;
17318 
17319 	event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data;
17320 	fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param;
17321 	WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) received. transaction_id: %d, rsp_status: %d, reason_code: %d",
17322 		 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id,
17323 		 fixed_params->rsp_status, fixed_params->reason_code);
17324 
17325 	rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
17326 			wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID);
17327 	if (!rsp->vdev) {
17328 		WMI_LOGE("vdev is null");
17329 		return QDF_STATUS_E_INVAL;
17330 	}
17331 	rsp->transaction_id = fixed_params->transaction_id;
17332 	rsp->reason = fixed_params->reason_code;
17333 	rsp->status = fixed_params->rsp_status;
17334 
17335 	return QDF_STATUS_SUCCESS;
17336 }
17337 
17338 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle,
17339 		uint8_t *data, struct nan_datapath_end_indication_event **rsp)
17340 {
17341 	uint32_t i, buf_size;
17342 	wmi_ndp_end_indication *ind;
17343 	struct qdf_mac_addr peer_addr;
17344 	WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event;
17345 
17346 	event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data;
17347 	ind = event->ndp_end_indication_list;
17348 
17349 	if (event->num_ndp_end_indication_list == 0) {
17350 		WMI_LOGE("Error: Event ignored, 0 ndp instances");
17351 		return QDF_STATUS_E_INVAL;
17352 	}
17353 
17354 	WMI_LOGD("number of ndp instances = %d",
17355 		 event->num_ndp_end_indication_list);
17356 
17357 	if (event->num_ndp_end_indication_list > ((UINT_MAX - sizeof(**rsp))/
17358 						sizeof((*rsp)->ndp_map[0]))) {
17359 		WMI_LOGE("num_ndp_end_ind_list %d too large",
17360 			 event->num_ndp_end_indication_list);
17361 		return QDF_STATUS_E_INVAL;
17362 	}
17363 
17364 	buf_size = sizeof(**rsp) + event->num_ndp_end_indication_list *
17365 			sizeof((*rsp)->ndp_map[0]);
17366 	*rsp = qdf_mem_malloc(buf_size);
17367 	if (!(*rsp)) {
17368 		WMI_LOGE("Failed to allocate memory");
17369 		return QDF_STATUS_E_NOMEM;
17370 	}
17371 
17372 	(*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
17373 			wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID);
17374 	if (!(*rsp)->vdev) {
17375 		WMI_LOGE("vdev is null");
17376 		qdf_mem_free(*rsp);
17377 		*rsp = NULL;
17378 		return QDF_STATUS_E_INVAL;
17379 	}
17380 
17381 	(*rsp)->num_ndp_ids = event->num_ndp_end_indication_list;
17382 	for (i = 0; i < (*rsp)->num_ndp_ids; i++) {
17383 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr,
17384 					   peer_addr.bytes);
17385 		WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ",
17386 			 i, ind[i].type, ind[i].reason_code,
17387 			 ind[i].ndp_instance_id,
17388 			 ind[i].num_active_ndps_on_peer);
17389 		/* Add each instance entry to the list */
17390 		(*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id;
17391 		(*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id;
17392 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr,
17393 			(*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes);
17394 		(*rsp)->ndp_map[i].num_active_ndp_sessions =
17395 			ind[i].num_active_ndps_on_peer;
17396 		(*rsp)->ndp_map[i].type = ind[i].type;
17397 		(*rsp)->ndp_map[i].reason_code = ind[i].reason_code;
17398 	}
17399 
17400 	return QDF_STATUS_SUCCESS;
17401 }
17402 
17403 static QDF_STATUS extract_ndp_sch_update_tlv(wmi_unified_t wmi_handle,
17404 		uint8_t *data, struct nan_datapath_sch_update_event *ind)
17405 {
17406 	uint8_t i;
17407 	WMI_HOST_WLAN_PHY_MODE ch_mode;
17408 	WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *event;
17409 	wmi_ndl_schedule_update_fixed_param *fixed_params;
17410 
17411 	event = (WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *)data;
17412 	fixed_params = event->fixed_param;
17413 
17414 	WMI_LOGD(FL("flags: %d, num_ch: %d, num_ndp_instances: %d"),
17415 		 fixed_params->flags, fixed_params->num_channels,
17416 		 fixed_params->num_ndp_instances);
17417 
17418 	ind->vdev =
17419 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17420 						     fixed_params->vdev_id,
17421 						     WLAN_NAN_ID);
17422 	if (!ind->vdev) {
17423 		WMI_LOGE("vdev is null");
17424 		return QDF_STATUS_E_INVAL;
17425 	}
17426 
17427 	ind->flags = fixed_params->flags;
17428 	ind->num_channels = fixed_params->num_channels;
17429 	ind->num_ndp_instances = fixed_params->num_ndp_instances;
17430 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_macaddr,
17431 				   ind->peer_addr.bytes);
17432 
17433 	if (ind->num_ndp_instances > NDP_NUM_INSTANCE_ID) {
17434 		WMI_LOGE(FL("uint32 overflow"));
17435 		wlan_objmgr_vdev_release_ref(ind->vdev, WLAN_NAN_ID);
17436 		return QDF_STATUS_E_INVAL;
17437 	}
17438 
17439 	qdf_mem_copy(ind->ndp_instances, event->ndp_instance_list,
17440 		     sizeof(uint32_t) * ind->num_ndp_instances);
17441 
17442 	if (ind->num_channels > NAN_CH_INFO_MAX_CHANNELS) {
17443 		WMI_LOGE(FL("too many channels"));
17444 		ind->num_channels = NAN_CH_INFO_MAX_CHANNELS;
17445 	}
17446 	for (i = 0; i < ind->num_channels; i++) {
17447 		ind->ch[i].channel = event->ndl_channel_list[i].mhz;
17448 		ind->ch[i].nss = event->nss_list[i];
17449 		ch_mode = WMI_GET_CHANNEL_MODE(&event->ndl_channel_list[i]);
17450 		ind->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle,
17451 								     ch_mode);
17452 		WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"),
17453 			 ind->ch[i].channel,
17454 			 ind->ch[i].ch_width,
17455 			 ind->ch[i].nss);
17456 	}
17457 
17458 	for (i = 0; i < fixed_params->num_ndp_instances; i++)
17459 		WMI_LOGD(FL("instance_id[%d]: %d"),
17460 			 i, event->ndp_instance_list[i]);
17461 
17462 	return QDF_STATUS_SUCCESS;
17463 }
17464 
17465 #endif
17466 
17467 #ifdef QCA_SUPPORT_CP_STATS
17468 /**
17469  * extract_cca_stats_tlv - api to extract congestion stats from event buffer
17470  * @wmi_handle: wma handle
17471  * @evt_buf: event buffer
17472  * @out_buff: buffer to populated after stats extraction
17473  *
17474  * Return: status of operation
17475  */
17476 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle,
17477 		void *evt_buf, struct wmi_host_congestion_stats *out_buff)
17478 {
17479 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
17480 	wmi_congestion_stats *congestion_stats;
17481 
17482 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf;
17483 	congestion_stats = param_buf->congestion_stats;
17484 	if (!congestion_stats) {
17485 		WMI_LOGD("%s: no cca stats in event buffer", __func__);
17486 		return QDF_STATUS_E_INVAL;
17487 	}
17488 
17489 	out_buff->vdev_id = congestion_stats->vdev_id;
17490 	out_buff->congestion = congestion_stats->congestion;
17491 
17492 	WMI_LOGD("%s: cca stats event processed", __func__);
17493 	return QDF_STATUS_SUCCESS;
17494 }
17495 #endif /* QCA_SUPPORT_CP_STATS */
17496 
17497 /**
17498  * save_service_bitmap_tlv() - save service bitmap
17499  * @wmi_handle: wmi handle
17500  * @param evt_buf: pointer to event buffer
17501  * @param bitmap_buf: bitmap buffer, for converged legacy support
17502  *
17503  * Return: QDF_STATUS
17504  */
17505 static
17506 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
17507 			     void *bitmap_buf)
17508 {
17509 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17510 	struct wmi_soc *soc = wmi_handle->soc;
17511 
17512 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17513 
17514 	/* If it is already allocated, use that buffer. This can happen
17515 	 * during target stop/start scenarios where host allocation is skipped.
17516 	 */
17517 	if (!soc->wmi_service_bitmap) {
17518 		soc->wmi_service_bitmap =
17519 			qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t));
17520 		if (!soc->wmi_service_bitmap) {
17521 			WMI_LOGE("Failed memory allocation for service bitmap");
17522 			return QDF_STATUS_E_NOMEM;
17523 		}
17524 	}
17525 
17526 	qdf_mem_copy(soc->wmi_service_bitmap,
17527 			param_buf->wmi_service_bitmap,
17528 			(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
17529 
17530 	if (bitmap_buf)
17531 		qdf_mem_copy(bitmap_buf,
17532 			     param_buf->wmi_service_bitmap,
17533 			     (WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
17534 
17535 	return QDF_STATUS_SUCCESS;
17536 }
17537 
17538 /**
17539  * save_ext_service_bitmap_tlv() - save extendend service bitmap
17540  * @wmi_handle: wmi handle
17541  * @param evt_buf: pointer to event buffer
17542  * @param bitmap_buf: bitmap buffer, for converged legacy support
17543  *
17544  * Return: QDF_STATUS
17545  */
17546 static
17547 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
17548 			     void *bitmap_buf)
17549 {
17550 	WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf;
17551 	wmi_service_available_event_fixed_param *ev;
17552 	struct wmi_soc *soc = wmi_handle->soc;
17553 
17554 	param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf;
17555 
17556 	ev = param_buf->fixed_param;
17557 
17558 	/* If it is already allocated, use that buffer. This can happen
17559 	 * during target stop/start scenarios where host allocation is skipped.
17560 	 */
17561 	if (!soc->wmi_ext_service_bitmap) {
17562 		soc->wmi_ext_service_bitmap = qdf_mem_malloc(
17563 			WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t));
17564 		if (!soc->wmi_ext_service_bitmap) {
17565 			WMI_LOGE("Failed memory allocation for service bitmap");
17566 			return QDF_STATUS_E_NOMEM;
17567 		}
17568 	}
17569 
17570 	qdf_mem_copy(soc->wmi_ext_service_bitmap,
17571 			ev->wmi_service_segment_bitmap,
17572 			(WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)));
17573 
17574 	WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n",
17575 			soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1],
17576 			soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]);
17577 
17578 	if (bitmap_buf)
17579 		qdf_mem_copy(bitmap_buf,
17580 			soc->wmi_ext_service_bitmap,
17581 			(WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)));
17582 
17583 	return QDF_STATUS_SUCCESS;
17584 }
17585 /**
17586  * is_service_enabled_tlv() - Check if service enabled
17587  * @param wmi_handle: wmi handle
17588  * @param service_id: service identifier
17589  *
17590  * Return: 1 enabled, 0 disabled
17591  */
17592 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle,
17593 		uint32_t service_id)
17594 {
17595 	struct wmi_soc *soc = wmi_handle->soc;
17596 
17597 	if (!soc->wmi_service_bitmap) {
17598 		WMI_LOGE("WMI service bit map is not saved yet\n");
17599 		return false;
17600 	}
17601 
17602 	/* if wmi_service_enabled was received with extended bitmap,
17603 	 * use WMI_SERVICE_EXT_IS_ENABLED to check the services.
17604 	 */
17605 	if (soc->wmi_ext_service_bitmap)
17606 		return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap,
17607 				soc->wmi_ext_service_bitmap,
17608 				service_id);
17609 
17610 	if (service_id >= WMI_MAX_SERVICE) {
17611 		WMI_LOGE("Service id %d but WMI ext service bitmap is NULL",
17612 			 service_id);
17613 		return false;
17614 	}
17615 
17616 	return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap,
17617 				service_id);
17618 }
17619 
17620 static inline void copy_ht_cap_info(uint32_t ev_target_cap,
17621 		struct wlan_psoc_target_capability_info *cap)
17622 {
17623        /* except LDPC all flags are common betwen legacy and here
17624 	*  also IBFEER is not defined for TLV
17625 	*/
17626 	cap->ht_cap_info |= ev_target_cap & (
17627 					WMI_HT_CAP_ENABLED
17628 					| WMI_HT_CAP_HT20_SGI
17629 					| WMI_HT_CAP_DYNAMIC_SMPS
17630 					| WMI_HT_CAP_TX_STBC
17631 					| WMI_HT_CAP_TX_STBC_MASK_SHIFT
17632 					| WMI_HT_CAP_RX_STBC
17633 					| WMI_HT_CAP_RX_STBC_MASK_SHIFT
17634 					| WMI_HT_CAP_LDPC
17635 					| WMI_HT_CAP_L_SIG_TXOP_PROT
17636 					| WMI_HT_CAP_MPDU_DENSITY
17637 					| WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT
17638 					| WMI_HT_CAP_HT40_SGI);
17639 	if (ev_target_cap & WMI_HT_CAP_LDPC)
17640 		cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC |
17641 			WMI_HOST_HT_CAP_TX_LDPC;
17642 }
17643 /**
17644  * extract_service_ready_tlv() - extract service ready event
17645  * @wmi_handle: wmi handle
17646  * @param evt_buf: pointer to received event buffer
17647  * @param cap: pointer to hold target capability information extracted from even
17648  *
17649  * Return: QDF_STATUS_SUCCESS for success or error code
17650  */
17651 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle,
17652 		void *evt_buf, struct wlan_psoc_target_capability_info *cap)
17653 {
17654 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17655 	wmi_service_ready_event_fixed_param *ev;
17656 
17657 
17658 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17659 
17660 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
17661 	if (!ev) {
17662 		qdf_print("%s: wmi_buf_alloc failed", __func__);
17663 		return QDF_STATUS_E_FAILURE;
17664 	}
17665 
17666 	cap->phy_capability = ev->phy_capability;
17667 	cap->max_frag_entry = ev->max_frag_entry;
17668 	cap->num_rf_chains = ev->num_rf_chains;
17669 	copy_ht_cap_info(ev->ht_cap_info, cap);
17670 	cap->vht_cap_info = ev->vht_cap_info;
17671 	cap->vht_supp_mcs = ev->vht_supp_mcs;
17672 	cap->hw_min_tx_power = ev->hw_min_tx_power;
17673 	cap->hw_max_tx_power = ev->hw_max_tx_power;
17674 	cap->sys_cap_info = ev->sys_cap_info;
17675 	cap->min_pkt_size_enable = ev->min_pkt_size_enable;
17676 	cap->max_bcn_ie_size = ev->max_bcn_ie_size;
17677 	cap->max_num_scan_channels = ev->max_num_scan_channels;
17678 	cap->max_supported_macs = ev->max_supported_macs;
17679 	cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps;
17680 	cap->txrx_chainmask = ev->txrx_chainmask;
17681 	cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index;
17682 	cap->num_msdu_desc = ev->num_msdu_desc;
17683 	cap->fw_version = ev->fw_build_vers;
17684 	/* fw_version_1 is not available in TLV. */
17685 	cap->fw_version_1 = 0;
17686 
17687 	return QDF_STATUS_SUCCESS;
17688 }
17689 
17690 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target
17691  *         to host internal WMI_HOST_REGDMN_MODE values.
17692  *         REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the
17693  *         host currently. Add this in the future if required.
17694  *         11AX (Phase II) : 11ax related values are not currently
17695  *         advertised separately by FW. As part of phase II regulatory bring-up,
17696  *         finalize the advertisement mechanism.
17697  * @target_wireless_mode: target wireless mode received in message
17698  *
17699  * Return: returns the host internal wireless mode.
17700  */
17701 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode)
17702 {
17703 
17704 	uint32_t wireless_modes = 0;
17705 
17706 	if (target_wireless_mode & REGDMN_MODE_11A)
17707 		wireless_modes |= WMI_HOST_REGDMN_MODE_11A;
17708 
17709 	if (target_wireless_mode & REGDMN_MODE_TURBO)
17710 		wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO;
17711 
17712 	if (target_wireless_mode & REGDMN_MODE_11B)
17713 		wireless_modes |= WMI_HOST_REGDMN_MODE_11B;
17714 
17715 	if (target_wireless_mode & REGDMN_MODE_PUREG)
17716 		wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG;
17717 
17718 	if (target_wireless_mode & REGDMN_MODE_11G)
17719 		wireless_modes |= WMI_HOST_REGDMN_MODE_11G;
17720 
17721 	if (target_wireless_mode & REGDMN_MODE_108G)
17722 		wireless_modes |= WMI_HOST_REGDMN_MODE_108G;
17723 
17724 	if (target_wireless_mode & REGDMN_MODE_108A)
17725 		wireless_modes |= WMI_HOST_REGDMN_MODE_108A;
17726 
17727 	if (target_wireless_mode & REGDMN_MODE_XR)
17728 		wireless_modes |= WMI_HOST_REGDMN_MODE_XR;
17729 
17730 	if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE)
17731 		wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE;
17732 
17733 	if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE)
17734 		wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE;
17735 
17736 	if (target_wireless_mode & REGDMN_MODE_11NG_HT20)
17737 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20;
17738 
17739 	if (target_wireless_mode & REGDMN_MODE_11NA_HT20)
17740 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20;
17741 
17742 	if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS)
17743 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS;
17744 
17745 	if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS)
17746 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS;
17747 
17748 	if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS)
17749 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS;
17750 
17751 	if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS)
17752 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS;
17753 
17754 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT20)
17755 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20;
17756 
17757 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS)
17758 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS;
17759 
17760 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS)
17761 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS;
17762 
17763 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT80)
17764 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80;
17765 
17766 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT160)
17767 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160;
17768 
17769 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80)
17770 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80;
17771 
17772 	return wireless_modes;
17773 }
17774 
17775 /**
17776  * extract_hal_reg_cap_tlv() - extract HAL registered capabilities
17777  * @wmi_handle: wmi handle
17778  * @param evt_buf: Pointer to event buffer
17779  * @param cap: pointer to hold HAL reg capabilities
17780  *
17781  * Return: QDF_STATUS_SUCCESS for success or error code
17782  */
17783 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle,
17784 	void *evt_buf, struct wlan_psoc_hal_reg_capability *cap)
17785 {
17786 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17787 
17788 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17789 
17790 	qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) +
17791 		sizeof(uint32_t)),
17792 		sizeof(struct wlan_psoc_hal_reg_capability));
17793 
17794 	cap->wireless_modes = convert_wireless_modes_tlv(
17795 			param_buf->hal_reg_capabilities->wireless_modes);
17796 
17797 	return QDF_STATUS_SUCCESS;
17798 }
17799 
17800 /**
17801  * extract_host_mem_req_tlv() - Extract host memory request event
17802  * @wmi_handle: wmi handle
17803  * @param evt_buf: pointer to event buffer
17804  * @param num_entries: pointer to hold number of entries requested
17805  *
17806  * Return: Number of entries requested
17807  */
17808 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle,
17809 		void *evt_buf, uint8_t *num_entries)
17810 {
17811 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17812 	wmi_service_ready_event_fixed_param *ev;
17813 
17814 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17815 
17816 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
17817 	if (!ev) {
17818 		qdf_print("%s: wmi_buf_alloc failed", __func__);
17819 		return NULL;
17820 	}
17821 
17822 	*num_entries = ev->num_mem_reqs;
17823 
17824 	return (host_mem_req *)param_buf->mem_reqs;
17825 }
17826 
17827 /**
17828  * save_fw_version_in_service_ready_tlv() - Save fw version in service
17829  * ready function
17830  * @wmi_handle: wmi handle
17831  * @param evt_buf: pointer to event buffer
17832  *
17833  * Return: QDF_STATUS_SUCCESS for success or error code
17834  */
17835 static QDF_STATUS
17836 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf)
17837 {
17838 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17839 	wmi_service_ready_event_fixed_param *ev;
17840 
17841 
17842 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17843 
17844 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
17845 	if (!ev) {
17846 		qdf_print("%s: wmi_buf_alloc failed", __func__);
17847 		return QDF_STATUS_E_FAILURE;
17848 	}
17849 
17850 	/*Save fw version from service ready message */
17851 	/*This will be used while sending INIT message */
17852 	qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
17853 			sizeof(wmi_handle->fw_abi_version));
17854 
17855 	return QDF_STATUS_SUCCESS;
17856 }
17857 
17858 /**
17859  * ready_extract_init_status_tlv() - Extract init status from ready event
17860  * @wmi_handle: wmi handle
17861  * @param evt_buf: Pointer to event buffer
17862  *
17863  * Return: ready status
17864  */
17865 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle,
17866 	void *evt_buf)
17867 {
17868 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
17869 	wmi_ready_event_fixed_param *ev = NULL;
17870 
17871 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
17872 	ev = param_buf->fixed_param;
17873 
17874 	qdf_print("%s:%d", __func__, ev->status);
17875 
17876 	return ev->status;
17877 }
17878 
17879 /**
17880  * ready_extract_mac_addr_tlv() - extract mac address from ready event
17881  * @wmi_handle: wmi handle
17882  * @param evt_buf: pointer to event buffer
17883  * @param macaddr: Pointer to hold MAC address
17884  *
17885  * Return: QDF_STATUS_SUCCESS for success or error code
17886  */
17887 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle,
17888 	void *evt_buf, uint8_t *macaddr)
17889 {
17890 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
17891 	wmi_ready_event_fixed_param *ev = NULL;
17892 
17893 
17894 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
17895 	ev = param_buf->fixed_param;
17896 
17897 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr);
17898 
17899 	return QDF_STATUS_SUCCESS;
17900 }
17901 
17902 /**
17903  * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event
17904  * @wmi_handle: wmi handle
17905  * @param evt_buf: pointer to event buffer
17906  * @param macaddr: Pointer to hold number of MAC addresses
17907  *
17908  * Return: Pointer to addr list
17909  */
17910 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle,
17911 	void *evt_buf, uint8_t *num_mac)
17912 {
17913 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
17914 	wmi_ready_event_fixed_param *ev = NULL;
17915 
17916 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
17917 	ev = param_buf->fixed_param;
17918 
17919 	*num_mac = ev->num_extra_mac_addr;
17920 
17921 	return (wmi_host_mac_addr *) param_buf->mac_addr_list;
17922 }
17923 
17924 /**
17925  * extract_ready_params_tlv() - Extract data from ready event apart from
17926  *                     status, macaddr and version.
17927  * @wmi_handle: Pointer to WMI handle.
17928  * @evt_buf: Pointer to Ready event buffer.
17929  * @ev_param: Pointer to host defined struct to copy the data from event.
17930  *
17931  * Return: QDF_STATUS_SUCCESS on success.
17932  */
17933 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle,
17934 		void *evt_buf, struct wmi_host_ready_ev_param *ev_param)
17935 {
17936 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
17937 	wmi_ready_event_fixed_param *ev = NULL;
17938 
17939 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
17940 	ev = param_buf->fixed_param;
17941 
17942 	ev_param->status = ev->status;
17943 	ev_param->num_dscp_table = ev->num_dscp_table;
17944 	ev_param->num_extra_mac_addr = ev->num_extra_mac_addr;
17945 	ev_param->num_total_peer = ev->num_total_peers;
17946 	ev_param->num_extra_peer = ev->num_extra_peers;
17947 	/* Agile_cap in ready event is not supported in TLV target */
17948 	ev_param->agile_capability = false;
17949 
17950 	return QDF_STATUS_SUCCESS;
17951 }
17952 
17953 /**
17954  * extract_dbglog_data_len_tlv() - extract debuglog data length
17955  * @wmi_handle: wmi handle
17956  * @param evt_buf: pointer to event buffer
17957  *
17958  * Return: length
17959  */
17960 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle,
17961 	void *evt_buf, uint32_t *len)
17962 {
17963 	 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf;
17964 
17965 	 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf;
17966 
17967 	 *len = param_buf->num_bufp;
17968 
17969 	 return param_buf->bufp;
17970 }
17971 
17972 /**
17973  * extract_vdev_start_resp_tlv() - extract vdev start response
17974  * @wmi_handle: wmi handle
17975  * @param evt_buf: pointer to event buffer
17976  * @param vdev_rsp: Pointer to hold vdev response
17977  *
17978  * Return: QDF_STATUS_SUCCESS for success or error code
17979  */
17980 static QDF_STATUS extract_vdev_start_resp_tlv(wmi_unified_t wmi_handle,
17981 	void *evt_buf, wmi_host_vdev_start_resp *vdev_rsp)
17982 {
17983 	WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf;
17984 	wmi_vdev_start_response_event_fixed_param *ev;
17985 
17986 	param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) evt_buf;
17987 	if (!param_buf) {
17988 		qdf_print("Invalid start response event buffer");
17989 		return QDF_STATUS_E_INVAL;
17990 	}
17991 
17992 	ev = param_buf->fixed_param;
17993 	if (!ev) {
17994 		qdf_print("Invalid start response event buffer");
17995 		return QDF_STATUS_E_INVAL;
17996 	}
17997 
17998 	qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp));
17999 
18000 	vdev_rsp->vdev_id = ev->vdev_id;
18001 	vdev_rsp->requestor_id = ev->requestor_id;
18002 	switch (ev->resp_type) {
18003 	case WMI_VDEV_START_RESP_EVENT:
18004 		vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT;
18005 		break;
18006 	case WMI_VDEV_RESTART_RESP_EVENT:
18007 		vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT;
18008 		break;
18009 	default:
18010 		qdf_print("Invalid start response event buffer");
18011 		break;
18012 	};
18013 	vdev_rsp->status = ev->status;
18014 	vdev_rsp->chain_mask = ev->chain_mask;
18015 	vdev_rsp->smps_mode = ev->smps_mode;
18016 	vdev_rsp->mac_id = ev->mac_id;
18017 	vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams;
18018 	vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams;
18019 
18020 	return QDF_STATUS_SUCCESS;
18021 }
18022 
18023 /**
18024  * extract_vdev_delete_resp_tlv() - extract vdev delete response
18025  * @wmi_handle: wmi handle
18026  * @param evt_buf: pointer to event buffer
18027  * @param delete_rsp: Pointer to hold vdev delete response
18028  *
18029  * Return: QDF_STATUS_SUCCESS for success or error code
18030  */
18031 static QDF_STATUS extract_vdev_delete_resp_tlv(wmi_unified_t wmi_handle,
18032 	void *evt_buf, struct wmi_host_vdev_delete_resp *delete_rsp)
18033 {
18034 	WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf;
18035 	wmi_vdev_delete_resp_event_fixed_param *ev;
18036 
18037 	param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *) evt_buf;
18038 	if (!param_buf) {
18039 		WMI_LOGE("Invalid vdev delete response event buffer\n");
18040 		return QDF_STATUS_E_INVAL;
18041 	}
18042 
18043 	ev = param_buf->fixed_param;
18044 	if (!ev) {
18045 		WMI_LOGE("Invalid vdev delete response event\n");
18046 		return QDF_STATUS_E_INVAL;
18047 	}
18048 
18049 	qdf_mem_zero(delete_rsp, sizeof(*delete_rsp));
18050 	delete_rsp->vdev_id = ev->vdev_id;
18051 
18052 	return QDF_STATUS_SUCCESS;
18053 }
18054 
18055 
18056 /**
18057  * extract_tbttoffset_num_vdevs_tlv() - extract tbtt offset num vdev
18058  * @wmi_handle: wmi handle
18059  * @param evt_buf: pointer to event buffer
18060  * @param num_vdevs: Pointer to hold num vdev
18061  *
18062  * Return: QDF_STATUS_SUCCESS for success or error code
18063  */
18064 static QDF_STATUS extract_tbttoffset_num_vdevs_tlv(void *wmi_hdl,
18065 	void *evt_buf, uint32_t *num_vdevs)
18066 {
18067 	WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
18068 	wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
18069 	uint32_t vdev_map;
18070 
18071 	param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf;
18072 	if (!param_buf) {
18073 		qdf_print("Invalid tbtt update ext event buffer");
18074 		return QDF_STATUS_E_INVAL;
18075 	}
18076 	tbtt_offset_event = param_buf->fixed_param;
18077 	vdev_map = tbtt_offset_event->vdev_map;
18078 	*num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map);
18079 
18080 	return QDF_STATUS_SUCCESS;
18081 }
18082 
18083 /**
18084  * extract_ext_tbttoffset_num_vdevs_tlv() - extract ext tbtt offset num vdev
18085  * @wmi_handle: wmi handle
18086  * @param evt_buf: pointer to event buffer
18087  * @param num_vdevs: Pointer to hold num vdev
18088  *
18089  * Return: QDF_STATUS_SUCCESS for success or error code
18090  */
18091 static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(void *wmi_hdl,
18092 	void *evt_buf, uint32_t *num_vdevs)
18093 {
18094 	WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf;
18095 	wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event;
18096 
18097 	param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf;
18098 	if (!param_buf) {
18099 		qdf_print("Invalid tbtt update ext event buffer");
18100 		return QDF_STATUS_E_INVAL;
18101 	}
18102 	tbtt_offset_ext_event = param_buf->fixed_param;
18103 
18104 	*num_vdevs = tbtt_offset_ext_event->num_vdevs;
18105 
18106 	return QDF_STATUS_SUCCESS;
18107 }
18108 
18109 /**
18110  * extract_tbttoffset_update_params_tlv() - extract tbtt offset param
18111  * @wmi_handle: wmi handle
18112  * @param evt_buf: pointer to event buffer
18113  * @param idx: Index referring to a vdev
18114  * @param tbtt_param: Pointer to tbttoffset event param
18115  *
18116  * Return: QDF_STATUS_SUCCESS for success or error code
18117  */
18118 static QDF_STATUS extract_tbttoffset_update_params_tlv(void *wmi_hdl,
18119 	void *evt_buf, uint8_t idx,
18120 	struct tbttoffset_params *tbtt_param)
18121 {
18122 	WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
18123 	wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
18124 	uint32_t vdev_map;
18125 
18126 	param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) evt_buf;
18127 	if (!param_buf) {
18128 		qdf_print("Invalid tbtt update event buffer");
18129 		return QDF_STATUS_E_INVAL;
18130 	}
18131 
18132 	tbtt_offset_event = param_buf->fixed_param;
18133 	vdev_map = tbtt_offset_event->vdev_map;
18134 	tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx);
18135 	if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID)
18136 		return QDF_STATUS_E_INVAL;
18137 	tbtt_param->tbttoffset =
18138 		param_buf->tbttoffset_list[tbtt_param->vdev_id];
18139 
18140 	return QDF_STATUS_SUCCESS;
18141 }
18142 
18143 /**
18144  * extract_ext_tbttoffset_update_params_tlv() - extract ext tbtt offset param
18145  * @wmi_handle: wmi handle
18146  * @param evt_buf: pointer to event buffer
18147  * @param idx: Index referring to a vdev
18148  * @param tbtt_param: Pointer to tbttoffset event param
18149  *
18150  * Return: QDF_STATUS_SUCCESS for success or error code
18151  */
18152 static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(void *wmi_hdl,
18153 	void *evt_buf, uint8_t idx,
18154 	struct tbttoffset_params *tbtt_param)
18155 {
18156 	WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf;
18157 	wmi_tbtt_offset_info *tbtt_offset_info;
18158 
18159 	param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf;
18160 	if (!param_buf) {
18161 		qdf_print("Invalid tbtt update event buffer");
18162 		return QDF_STATUS_E_INVAL;
18163 	}
18164 	tbtt_offset_info = &param_buf->tbtt_offset_info[idx];
18165 
18166 	tbtt_param->vdev_id = tbtt_offset_info->vdev_id;
18167 	tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset;
18168 
18169 	return QDF_STATUS_SUCCESS;
18170 }
18171 
18172 #ifdef CONFIG_MCL
18173 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \
18174 			((_status) & WMI_RXERR_DECRYPT)
18175 #else
18176 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false
18177 #endif
18178 
18179 /**
18180  * extract_mgmt_rx_params_tlv() - extract management rx params from event
18181  * @wmi_handle: wmi handle
18182  * @param evt_buf: pointer to event buffer
18183  * @param hdr: Pointer to hold header
18184  * @param bufp: Pointer to hold pointer to rx param buffer
18185  *
18186  * Return: QDF_STATUS_SUCCESS for success or error code
18187  */
18188 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle,
18189 	void *evt_buf, struct mgmt_rx_event_params *hdr,
18190 	uint8_t **bufp)
18191 {
18192 	WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL;
18193 	wmi_mgmt_rx_hdr *ev_hdr = NULL;
18194 	int i;
18195 
18196 	param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf;
18197 	if (!param_tlvs) {
18198 		WMI_LOGE("Get NULL point message from FW");
18199 		return QDF_STATUS_E_INVAL;
18200 	}
18201 
18202 	ev_hdr = param_tlvs->hdr;
18203 	if (!hdr) {
18204 		WMI_LOGE("Rx event is NULL");
18205 		return QDF_STATUS_E_INVAL;
18206 	}
18207 
18208 	if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) {
18209 		WMI_LOGE("%s: RX mgmt frame decrypt error, discard it",
18210 			 __func__);
18211 		return QDF_STATUS_E_INVAL;
18212 	}
18213 
18214 	hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18215 							ev_hdr->pdev_id);
18216 
18217 	hdr->channel = ev_hdr->channel;
18218 	hdr->snr = ev_hdr->snr;
18219 	hdr->rate = ev_hdr->rate;
18220 	hdr->phy_mode = ev_hdr->phy_mode;
18221 	hdr->buf_len = ev_hdr->buf_len;
18222 	hdr->status = ev_hdr->status;
18223 	hdr->flags = ev_hdr->flags;
18224 	hdr->rssi = ev_hdr->rssi;
18225 	hdr->tsf_delta = ev_hdr->tsf_delta;
18226 	for (i = 0; i < ATH_MAX_ANTENNA; i++)
18227 		hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i];
18228 
18229 	*bufp = param_tlvs->bufp;
18230 
18231 	return QDF_STATUS_SUCCESS;
18232 }
18233 
18234 /**
18235  * extract_vdev_stopped_param_tlv() - extract vdev stop param from event
18236  * @wmi_handle: wmi handle
18237  * @param evt_buf: pointer to event buffer
18238  * @param vdev_id: Pointer to hold vdev identifier
18239  *
18240  * Return: QDF_STATUS_SUCCESS for success or error code
18241  */
18242 static QDF_STATUS extract_vdev_stopped_param_tlv(wmi_unified_t wmi_handle,
18243 	void *evt_buf, uint32_t *vdev_id)
18244 {
18245 	WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf;
18246 	wmi_vdev_stopped_event_fixed_param *resp_event;
18247 
18248 	param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) evt_buf;
18249 	if (!param_buf) {
18250 		WMI_LOGE("Invalid event buffer");
18251 		return QDF_STATUS_E_INVAL;
18252 	}
18253 	resp_event = param_buf->fixed_param;
18254 	*vdev_id = resp_event->vdev_id;
18255 
18256 	return QDF_STATUS_SUCCESS;
18257 }
18258 
18259 /**
18260  * extract_vdev_roam_param_tlv() - extract vdev roam param from event
18261  * @wmi_handle: wmi handle
18262  * @param evt_buf: pointer to event buffer
18263  * @param param: Pointer to hold roam param
18264  *
18265  * Return: QDF_STATUS_SUCCESS for success or error code
18266  */
18267 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle,
18268 	void *evt_buf, wmi_host_roam_event *param)
18269 {
18270 	WMI_ROAM_EVENTID_param_tlvs *param_buf;
18271 	wmi_roam_event_fixed_param *evt;
18272 
18273 	param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf;
18274 	if (!param_buf) {
18275 		WMI_LOGE("Invalid roam event buffer");
18276 		return QDF_STATUS_E_INVAL;
18277 	}
18278 
18279 	evt = param_buf->fixed_param;
18280 	qdf_mem_zero(param, sizeof(*param));
18281 
18282 	param->vdev_id = evt->vdev_id;
18283 	param->reason = evt->reason;
18284 	param->rssi = evt->rssi;
18285 
18286 	return QDF_STATUS_SUCCESS;
18287 }
18288 
18289 /**
18290  * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event
18291  * @wmi_handle: wmi handle
18292  * @param evt_buf: pointer to event buffer
18293  * @param param: Pointer to hold vdev scan param
18294  *
18295  * Return: QDF_STATUS_SUCCESS for success or error code
18296  */
18297 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle,
18298 	void *evt_buf, struct scan_event *param)
18299 {
18300 	WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL;
18301 	wmi_scan_event_fixed_param *evt = NULL;
18302 
18303 	param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf;
18304 	evt = param_buf->fixed_param;
18305 
18306 	qdf_mem_zero(param, sizeof(*param));
18307 
18308 	switch (evt->event) {
18309 	case WMI_SCAN_EVENT_STARTED:
18310 		param->type = SCAN_EVENT_TYPE_STARTED;
18311 		break;
18312 	case WMI_SCAN_EVENT_COMPLETED:
18313 		param->type = SCAN_EVENT_TYPE_COMPLETED;
18314 		break;
18315 	case WMI_SCAN_EVENT_BSS_CHANNEL:
18316 		param->type = SCAN_EVENT_TYPE_BSS_CHANNEL;
18317 		break;
18318 	case WMI_SCAN_EVENT_FOREIGN_CHANNEL:
18319 		param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL;
18320 		break;
18321 	case WMI_SCAN_EVENT_DEQUEUED:
18322 		param->type = SCAN_EVENT_TYPE_DEQUEUED;
18323 		break;
18324 	case WMI_SCAN_EVENT_PREEMPTED:
18325 		param->type = SCAN_EVENT_TYPE_PREEMPTED;
18326 		break;
18327 	case WMI_SCAN_EVENT_START_FAILED:
18328 		param->type = SCAN_EVENT_TYPE_START_FAILED;
18329 		break;
18330 	case WMI_SCAN_EVENT_RESTARTED:
18331 		param->type = SCAN_EVENT_TYPE_RESTARTED;
18332 		break;
18333 	case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT:
18334 		param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT;
18335 		break;
18336 	case WMI_SCAN_EVENT_MAX:
18337 	default:
18338 		param->type = SCAN_EVENT_TYPE_MAX;
18339 		break;
18340 	};
18341 
18342 	switch (evt->reason) {
18343 	case WMI_SCAN_REASON_NONE:
18344 		param->reason = SCAN_REASON_NONE;
18345 		break;
18346 	case WMI_SCAN_REASON_COMPLETED:
18347 		param->reason = SCAN_REASON_COMPLETED;
18348 		break;
18349 	case WMI_SCAN_REASON_CANCELLED:
18350 		param->reason = SCAN_REASON_CANCELLED;
18351 		break;
18352 	case WMI_SCAN_REASON_PREEMPTED:
18353 		param->reason = SCAN_REASON_PREEMPTED;
18354 		break;
18355 	case WMI_SCAN_REASON_TIMEDOUT:
18356 		param->reason = SCAN_REASON_TIMEDOUT;
18357 		break;
18358 	case WMI_SCAN_REASON_INTERNAL_FAILURE:
18359 		param->reason = SCAN_REASON_INTERNAL_FAILURE;
18360 		break;
18361 	case WMI_SCAN_REASON_SUSPENDED:
18362 		param->reason = SCAN_REASON_SUSPENDED;
18363 		break;
18364 	case WMI_SCAN_REASON_MAX:
18365 		param->reason = SCAN_REASON_MAX;
18366 		break;
18367 	default:
18368 		param->reason = SCAN_REASON_MAX;
18369 		break;
18370 	};
18371 
18372 	param->chan_freq = evt->channel_freq;
18373 	param->requester = evt->requestor;
18374 	param->scan_id = evt->scan_id;
18375 	param->vdev_id = evt->vdev_id;
18376 	param->timestamp = evt->tsf_timestamp;
18377 
18378 	return QDF_STATUS_SUCCESS;
18379 }
18380 
18381 #ifdef CONVERGED_TDLS_ENABLE
18382 /**
18383  * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event
18384  * @wmi_handle: wmi handle
18385  * @param evt_buf: pointer to event buffer
18386  * @param param: Pointer to hold vdev tdls param
18387  *
18388  * Return: QDF_STATUS_SUCCESS for success or error code
18389  */
18390 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle,
18391 	void *evt_buf, struct tdls_event_info *param)
18392 {
18393 	WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf;
18394 	wmi_tdls_peer_event_fixed_param *evt;
18395 
18396 	param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf;
18397 	if (!param_buf) {
18398 		WMI_LOGE("%s: NULL param_buf", __func__);
18399 		return QDF_STATUS_E_NULL_VALUE;
18400 	}
18401 
18402 	evt = param_buf->fixed_param;
18403 
18404 	qdf_mem_zero(param, sizeof(*param));
18405 
18406 	param->vdev_id = evt->vdev_id;
18407 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr,
18408 				   param->peermac.bytes);
18409 	switch (evt->peer_status) {
18410 	case WMI_TDLS_SHOULD_DISCOVER:
18411 		param->message_type = TDLS_SHOULD_DISCOVER;
18412 		break;
18413 	case WMI_TDLS_SHOULD_TEARDOWN:
18414 		param->message_type = TDLS_SHOULD_TEARDOWN;
18415 		break;
18416 	case WMI_TDLS_PEER_DISCONNECTED:
18417 		param->message_type = TDLS_PEER_DISCONNECTED;
18418 		break;
18419 	case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION:
18420 		param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY;
18421 		break;
18422 	default:
18423 		WMI_LOGE("%s: Discarding unknown tdls event %d from target",
18424 			 __func__, evt->peer_status);
18425 		return QDF_STATUS_E_INVAL;
18426 	};
18427 
18428 	switch (evt->peer_reason) {
18429 	case WMI_TDLS_TEARDOWN_REASON_TX:
18430 		param->peer_reason = TDLS_TEARDOWN_TX;
18431 		break;
18432 	case WMI_TDLS_TEARDOWN_REASON_RSSI:
18433 		param->peer_reason = TDLS_TEARDOWN_RSSI;
18434 		break;
18435 	case WMI_TDLS_TEARDOWN_REASON_SCAN:
18436 		param->peer_reason = TDLS_TEARDOWN_SCAN;
18437 		break;
18438 	case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE:
18439 		param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE;
18440 		break;
18441 	case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
18442 		param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT;
18443 		break;
18444 	case WMI_TDLS_TEARDOWN_REASON_BAD_PTR:
18445 		param->peer_reason = TDLS_TEARDOWN_BAD_PTR;
18446 		break;
18447 	case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
18448 		param->peer_reason = TDLS_TEARDOWN_NO_RSP;
18449 		break;
18450 	case WMI_TDLS_ENTER_BUF_STA:
18451 		param->peer_reason = TDLS_PEER_ENTER_BUF_STA;
18452 		break;
18453 	case WMI_TDLS_EXIT_BUF_STA:
18454 		param->peer_reason = TDLS_PEER_EXIT_BUF_STA;
18455 		break;
18456 	case WMI_TDLS_ENTER_BT_BUSY_MODE:
18457 		param->peer_reason = TDLS_ENTER_BT_BUSY;
18458 		break;
18459 	case WMI_TDLS_EXIT_BT_BUSY_MODE:
18460 		param->peer_reason = TDLS_EXIT_BT_BUSY;
18461 		break;
18462 	case WMI_TDLS_SCAN_STARTED_EVENT:
18463 		param->peer_reason = TDLS_SCAN_STARTED;
18464 		break;
18465 	case WMI_TDLS_SCAN_COMPLETED_EVENT:
18466 		param->peer_reason = TDLS_SCAN_COMPLETED;
18467 		break;
18468 
18469 	default:
18470 		WMI_LOGE("%s: unknown reason %d in tdls event %d from target",
18471 			 __func__, evt->peer_reason, evt->peer_status);
18472 		return QDF_STATUS_E_INVAL;
18473 	};
18474 
18475 	WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d",
18476 		 __func__, param->peermac.bytes, param->message_type,
18477 		 param->peer_reason, param->vdev_id);
18478 
18479 	return QDF_STATUS_SUCCESS;
18480 }
18481 #endif
18482 
18483 /**
18484  * extract_mgmt_tx_compl_param_tlv() - extract MGMT tx completion event params
18485  * @wmi_handle: wmi handle
18486  * @param evt_buf: pointer to event buffer
18487  * @param param: Pointer to hold MGMT TX completion params
18488  *
18489  * Return: QDF_STATUS_SUCCESS for success or error code
18490  */
18491 static QDF_STATUS extract_mgmt_tx_compl_param_tlv(wmi_unified_t wmi_handle,
18492 	void *evt_buf, wmi_host_mgmt_tx_compl_event *param)
18493 {
18494 	WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf;
18495 	wmi_mgmt_tx_compl_event_fixed_param *cmpl_params;
18496 
18497 	param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *)
18498 		evt_buf;
18499 	if (!param_buf) {
18500 		WMI_LOGE("%s: Invalid mgmt Tx completion event", __func__);
18501 		return QDF_STATUS_E_INVAL;
18502 	}
18503 	cmpl_params = param_buf->fixed_param;
18504 
18505 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18506 							cmpl_params->pdev_id);
18507 	param->desc_id = cmpl_params->desc_id;
18508 	param->status = cmpl_params->status;
18509 	param->ppdu_id = cmpl_params->ppdu_id;
18510 
18511 	return QDF_STATUS_SUCCESS;
18512 }
18513 
18514 /**
18515  * extract_offchan_data_tx_compl_param_tlv() -
18516  *            extract Offchan data tx completion event params
18517  * @wmi_handle: wmi handle
18518  * @param evt_buf: pointer to event buffer
18519  * @param param: Pointer to hold offchan data TX completion params
18520  *
18521  * Return: QDF_STATUS_SUCCESS for success or error code
18522  */
18523 static QDF_STATUS extract_offchan_data_tx_compl_param_tlv(
18524 		wmi_unified_t wmi_handle, void *evt_buf,
18525 		struct wmi_host_offchan_data_tx_compl_event *param)
18526 {
18527 	WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *param_buf;
18528 	wmi_offchan_data_tx_compl_event_fixed_param *cmpl_params;
18529 
18530 	param_buf = (WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *)
18531 		evt_buf;
18532 	if (!param_buf) {
18533 		WMI_LOGE("%s: Invalid offchan data Tx compl event", __func__);
18534 		return QDF_STATUS_E_INVAL;
18535 	}
18536 	cmpl_params = param_buf->fixed_param;
18537 
18538 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18539 							cmpl_params->pdev_id);
18540 	param->desc_id = cmpl_params->desc_id;
18541 	param->status = cmpl_params->status;
18542 
18543 	return QDF_STATUS_SUCCESS;
18544 }
18545 
18546 /**
18547  * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count
18548  *                                              status tlv
18549  * @wmi_handle: wmi handle
18550  * @param evt_buf: pointer to event buffer
18551  * @param param: Pointer to hold csa switch count status event param
18552  *
18553  * Return: QDF_STATUS_SUCCESS for success or error code
18554  */
18555 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv(
18556 				wmi_unified_t wmi_handle,
18557 				void *evt_buf,
18558 				struct pdev_csa_switch_count_status *param)
18559 {
18560 	WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf;
18561 	wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status;
18562 
18563 	param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *)
18564 		     evt_buf;
18565 	if (!param_buf) {
18566 		WMI_LOGE("%s: Invalid CSA status event\n", __func__);
18567 		return QDF_STATUS_E_INVAL;
18568 	}
18569 
18570 	csa_status = param_buf->fixed_param;
18571 
18572 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18573 							csa_status->pdev_id);
18574 	param->current_switch_count = csa_status->current_switch_count;
18575 	param->num_vdevs = csa_status->num_vdevs;
18576 	param->vdev_ids = param_buf->vdev_ids;
18577 
18578 	return QDF_STATUS_SUCCESS;
18579 }
18580 
18581 /**
18582  * extract_pdev_tpc_config_ev_param_tlv() - extract pdev tpc configuration
18583  * param from event
18584  * @wmi_handle: wmi handle
18585  * @param evt_buf: pointer to event buffer
18586  * @param param: Pointer to hold tpc configuration
18587  *
18588  * Return: 0 for success or error code
18589  */
18590 static QDF_STATUS extract_pdev_tpc_config_ev_param_tlv(wmi_unified_t wmi_handle,
18591 		void *evt_buf,
18592 		wmi_host_pdev_tpc_config_event *param)
18593 {
18594 	wmi_pdev_tpc_config_event_fixed_param *event =
18595 		(wmi_pdev_tpc_config_event_fixed_param *)evt_buf;
18596 
18597 	if (!event) {
18598 		WMI_LOGE("Invalid event buffer");
18599 		return QDF_STATUS_E_INVAL;
18600 	}
18601 
18602 	param->pdev_id = event->pdev_id;
18603 	param->regDomain = event->regDomain;
18604 	param->chanFreq = event->chanFreq;
18605 	param->phyMode = event->phyMode;
18606 	param->twiceAntennaReduction = event->twiceAntennaReduction;
18607 	param->twiceAntennaGain = event->twiceAntennaGain;
18608 	param->twiceMaxRDPower = event->twiceMaxRDPower;
18609 	param->powerLimit = event->powerLimit;
18610 	param->rateMax = event->rateMax;
18611 	param->numTxChain = event->numTxChain;
18612 	param->ctl = event->ctl;
18613 	param->flags = event->flags;
18614 
18615 	qdf_mem_copy(param->maxRegAllowedPower, event->maxRegAllowedPower,
18616 		sizeof(param->maxRegAllowedPower));
18617 	qdf_mem_copy(param->maxRegAllowedPowerAGCDD,
18618 		event->maxRegAllowedPowerAGCDD,
18619 		sizeof(param->maxRegAllowedPowerAGCDD));
18620 	qdf_mem_copy(param->maxRegAllowedPowerAGSTBC,
18621 		event->maxRegAllowedPowerAGSTBC,
18622 		sizeof(param->maxRegAllowedPowerAGSTBC));
18623 	qdf_mem_copy(param->maxRegAllowedPowerAGTXBF,
18624 		event->maxRegAllowedPowerAGTXBF,
18625 		sizeof(param->maxRegAllowedPowerAGTXBF));
18626 	WMI_LOGD("%s:extract success", __func__);
18627 
18628 	return QDF_STATUS_SUCCESS;
18629 }
18630 
18631 /**
18632  * extract_swba_num_vdevs_tlv() - extract swba num vdevs from event
18633  * @wmi_handle: wmi handle
18634  * @param evt_buf: pointer to event buffer
18635  * @param num_vdevs: Pointer to hold num vdevs
18636  *
18637  * Return: QDF_STATUS_SUCCESS for success or error code
18638  */
18639 static QDF_STATUS extract_swba_num_vdevs_tlv(wmi_unified_t wmi_handle,
18640 	void *evt_buf, uint32_t *num_vdevs)
18641 {
18642 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
18643 	wmi_host_swba_event_fixed_param *swba_event;
18644 	uint32_t vdev_map;
18645 
18646 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf;
18647 	if (!param_buf) {
18648 		WMI_LOGE("Invalid swba event buffer");
18649 		return QDF_STATUS_E_INVAL;
18650 	}
18651 
18652 	swba_event = param_buf->fixed_param;
18653 	*num_vdevs = swba_event->num_vdevs;
18654 	if (!(*num_vdevs)) {
18655 		vdev_map = swba_event->vdev_map;
18656 		*num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map);
18657 	}
18658 
18659 	return QDF_STATUS_SUCCESS;
18660 }
18661 
18662 /**
18663  * extract_swba_tim_info_tlv() - extract swba tim info from event
18664  * @wmi_handle: wmi handle
18665  * @param evt_buf: pointer to event buffer
18666  * @param idx: Index to bcn info
18667  * @param tim_info: Pointer to hold tim info
18668  *
18669  * Return: QDF_STATUS_SUCCESS for success or error code
18670  */
18671 static QDF_STATUS extract_swba_tim_info_tlv(wmi_unified_t wmi_handle,
18672 	void *evt_buf, uint32_t idx, wmi_host_tim_info *tim_info)
18673 {
18674 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
18675 	wmi_tim_info *tim_info_ev;
18676 
18677 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf;
18678 	if (!param_buf) {
18679 		WMI_LOGE("Invalid swba event buffer");
18680 		return QDF_STATUS_E_INVAL;
18681 	}
18682 
18683 	tim_info_ev = &param_buf->tim_info[idx];
18684 
18685 	tim_info->tim_len = tim_info_ev->tim_len;
18686 	tim_info->tim_mcast = tim_info_ev->tim_mcast;
18687 	qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap,
18688 			(sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE));
18689 	tim_info->tim_changed = tim_info_ev->tim_changed;
18690 	tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending;
18691 	tim_info->vdev_id = tim_info_ev->vdev_id;
18692 
18693 	return QDF_STATUS_SUCCESS;
18694 }
18695 
18696 /**
18697  * extract_swba_noa_info_tlv() - extract swba NoA information from event
18698  * @wmi_handle: wmi handle
18699  * @param evt_buf: pointer to event buffer
18700  * @param idx: Index to bcn info
18701  * @param p2p_desc: Pointer to hold p2p NoA info
18702  *
18703  * Return: QDF_STATUS_SUCCESS for success or error code
18704  */
18705 static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle,
18706 	void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc)
18707 {
18708 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
18709 	wmi_p2p_noa_info *p2p_noa_info;
18710 	uint8_t i = 0;
18711 
18712 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf;
18713 	if (!param_buf) {
18714 		WMI_LOGE("Invalid swba event buffer");
18715 		return QDF_STATUS_E_INVAL;
18716 	}
18717 
18718 	p2p_noa_info = &param_buf->p2p_noa_info[idx];
18719 
18720 	p2p_desc->modified = false;
18721 	p2p_desc->num_descriptors = 0;
18722 	if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) {
18723 		p2p_desc->modified = true;
18724 		p2p_desc->index =
18725 			(uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info);
18726 		p2p_desc->oppPS =
18727 			(uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info);
18728 		p2p_desc->ctwindow =
18729 			(uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info);
18730 		p2p_desc->num_descriptors =
18731 			(uint8_t) WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET
18732 							(p2p_noa_info);
18733 		for (i = 0; i < p2p_desc->num_descriptors; i++) {
18734 			p2p_desc->noa_descriptors[i].type_count =
18735 				(uint8_t) p2p_noa_info->noa_descriptors[i].
18736 				type_count;
18737 			p2p_desc->noa_descriptors[i].duration =
18738 				p2p_noa_info->noa_descriptors[i].duration;
18739 			p2p_desc->noa_descriptors[i].interval =
18740 				p2p_noa_info->noa_descriptors[i].interval;
18741 			p2p_desc->noa_descriptors[i].start_time =
18742 				p2p_noa_info->noa_descriptors[i].start_time;
18743 		}
18744 		p2p_desc->vdev_id = p2p_noa_info->vdev_id;
18745 	}
18746 
18747 	return QDF_STATUS_SUCCESS;
18748 }
18749 
18750 #ifdef CONVERGED_P2P_ENABLE
18751 /**
18752  * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event
18753  * @wmi_handle: wmi handle
18754  * @param evt_buf: pointer to event buffer
18755  * @param param: Pointer to hold p2p noa info
18756  *
18757  * Return: QDF_STATUS_SUCCESS for success or error code
18758  */
18759 static QDF_STATUS extract_p2p_noa_ev_param_tlv(
18760 	wmi_unified_t wmi_handle, void *evt_buf,
18761 	struct p2p_noa_info *param)
18762 {
18763 	WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs;
18764 	wmi_p2p_noa_event_fixed_param *fixed_param;
18765 	uint8_t i;
18766 	wmi_p2p_noa_info *wmi_noa_info;
18767 	uint8_t *buf_ptr;
18768 	uint32_t descriptors;
18769 
18770 	param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf;
18771 	if (!param_tlvs) {
18772 		WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__);
18773 		return QDF_STATUS_E_INVAL;
18774 	}
18775 
18776 	if (!param) {
18777 		WMI_LOGE("noa information param is null");
18778 		return QDF_STATUS_E_INVAL;
18779 	}
18780 
18781 	fixed_param = param_tlvs->fixed_param;
18782 	buf_ptr = (uint8_t *) fixed_param;
18783 	buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param);
18784 	wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr);
18785 
18786 	if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) {
18787 		WMI_LOGE("%s: noa attr is not modified", __func__);
18788 		return QDF_STATUS_E_INVAL;
18789 	}
18790 
18791 	param->vdev_id = fixed_param->vdev_id;
18792 	param->index =
18793 		(uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info);
18794 	param->opps_ps =
18795 		(uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info);
18796 	param->ct_window =
18797 		(uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info);
18798 	descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info);
18799 	param->num_desc = (uint8_t) descriptors;
18800 	if (param->num_desc > WMI_P2P_MAX_NOA_DESCRIPTORS) {
18801 		WMI_LOGE("%s: invalid num desc:%d", __func__,
18802 			 param->num_desc);
18803 		return QDF_STATUS_E_INVAL;
18804 	}
18805 
18806 	WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__,
18807 		param->index, param->opps_ps, param->ct_window,
18808 		param->num_desc);
18809 	for (i = 0; i < param->num_desc; i++) {
18810 		param->noa_desc[i].type_count =
18811 			(uint8_t) wmi_noa_info->noa_descriptors[i].
18812 			type_count;
18813 		param->noa_desc[i].duration =
18814 			wmi_noa_info->noa_descriptors[i].duration;
18815 		param->noa_desc[i].interval =
18816 			wmi_noa_info->noa_descriptors[i].interval;
18817 		param->noa_desc[i].start_time =
18818 			wmi_noa_info->noa_descriptors[i].start_time;
18819 		WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u",
18820 			__func__, i, param->noa_desc[i].type_count,
18821 			param->noa_desc[i].duration,
18822 			param->noa_desc[i].interval,
18823 			param->noa_desc[i].start_time);
18824 	}
18825 
18826 	return QDF_STATUS_SUCCESS;
18827 }
18828 
18829 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
18830 /**
18831  * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop
18832  * information from event
18833  * @wmi_handle: wmi handle
18834  * @param evt_buf: pointer to event buffer
18835  * @param param: Pointer to hold p2p lo stop event information
18836  *
18837  * Return: QDF_STATUS_SUCCESS for success or error code
18838  */
18839 static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv(
18840 	wmi_unified_t wmi_handle, void *evt_buf,
18841 	struct p2p_lo_event *param)
18842 {
18843 	WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs;
18844 	wmi_p2p_lo_stopped_event_fixed_param *lo_param;
18845 
18846 	param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *)
18847 					evt_buf;
18848 	if (!param_tlvs) {
18849 		WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__);
18850 		return QDF_STATUS_E_INVAL;
18851 	}
18852 
18853 	if (!param) {
18854 		WMI_LOGE("lo stop event param is null");
18855 		return QDF_STATUS_E_INVAL;
18856 	}
18857 
18858 	lo_param = param_tlvs->fixed_param;
18859 	param->vdev_id = lo_param->vdev_id;
18860 	param->reason_code = lo_param->reason;
18861 	WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__,
18862 		param->vdev_id, param->reason_code);
18863 
18864 	return QDF_STATUS_SUCCESS;
18865 }
18866 #endif
18867 #endif /* End of CONVERGED_P2P_ENABLE */
18868 
18869 /**
18870  * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event
18871  * @wmi_handle: wmi handle
18872  * @param evt_buf: pointer to event buffer
18873  * @param ev: Pointer to hold peer param
18874  *
18875  * Return: QDF_STATUS_SUCCESS for success or error code
18876  */
18877 static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle,
18878 	void *evt_buf, wmi_host_peer_sta_kickout_event *ev)
18879 {
18880 	WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL;
18881 	wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL;
18882 
18883 	param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) evt_buf;
18884 	kickout_event = param_buf->fixed_param;
18885 
18886 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr,
18887 							ev->peer_macaddr);
18888 
18889 	ev->reason = kickout_event->reason;
18890 	ev->rssi = kickout_event->rssi;
18891 
18892 	return QDF_STATUS_SUCCESS;
18893 }
18894 
18895 /**
18896  * extract_all_stats_counts_tlv() - extract all stats count from event
18897  * @wmi_handle: wmi handle
18898  * @param evt_buf: pointer to event buffer
18899  * @param stats_param: Pointer to hold stats count
18900  *
18901  * Return: QDF_STATUS_SUCCESS for success or error code
18902  */
18903 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle,
18904 	void *evt_buf, wmi_host_stats_event *stats_param)
18905 {
18906 	wmi_stats_event_fixed_param *ev;
18907 	wmi_per_chain_rssi_stats *rssi_event;
18908 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
18909 
18910 	qdf_mem_zero(stats_param, sizeof(*stats_param));
18911 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
18912 	ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
18913 	rssi_event = param_buf->chain_stats;
18914 	if (!ev) {
18915 		WMI_LOGE("%s: event fixed param NULL\n", __func__);
18916 		return QDF_STATUS_E_FAILURE;
18917 	}
18918 
18919 	switch (ev->stats_id) {
18920 	case WMI_REQUEST_PEER_STAT:
18921 		stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT;
18922 		break;
18923 
18924 	case WMI_REQUEST_AP_STAT:
18925 		stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT;
18926 		break;
18927 
18928 	case WMI_REQUEST_PDEV_STAT:
18929 		stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT;
18930 		break;
18931 
18932 	case WMI_REQUEST_VDEV_STAT:
18933 		stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT;
18934 		break;
18935 
18936 	case WMI_REQUEST_BCNFLT_STAT:
18937 		stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT;
18938 		break;
18939 
18940 	case WMI_REQUEST_VDEV_RATE_STAT:
18941 		stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT;
18942 		break;
18943 
18944 	case WMI_REQUEST_BCN_STAT:
18945 		stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT;
18946 		break;
18947 
18948 	default:
18949 		stats_param->stats_id = 0;
18950 		break;
18951 
18952 	}
18953 
18954 	stats_param->num_pdev_stats = ev->num_pdev_stats;
18955 	stats_param->num_pdev_ext_stats = 0;
18956 	stats_param->num_vdev_stats = ev->num_vdev_stats;
18957 	stats_param->num_peer_stats = ev->num_peer_stats;
18958 	stats_param->num_bcnflt_stats = ev->num_bcnflt_stats;
18959 	stats_param->num_chan_stats = ev->num_chan_stats;
18960 	stats_param->num_bcn_stats = ev->num_bcn_stats;
18961 	stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18962 							ev->pdev_id);
18963 
18964 	/* if chain_stats is not populated */
18965 	if (!param_buf->chain_stats || !param_buf->num_chain_stats)
18966 		return QDF_STATUS_SUCCESS;
18967 
18968 	if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats !=
18969 	    WMITLV_GET_TLVTAG(rssi_event->tlv_header))
18970 		return QDF_STATUS_SUCCESS;
18971 
18972 	if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) !=
18973 	    WMITLV_GET_TLVLEN(rssi_event->tlv_header))
18974 		return QDF_STATUS_SUCCESS;
18975 
18976 	stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats;
18977 
18978 	return QDF_STATUS_SUCCESS;
18979 }
18980 
18981 /**
18982  * extract_pdev_tx_stats() - extract pdev tx stats from event
18983  */
18984 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, struct wlan_dbg_tx_stats *tx_stats)
18985 {
18986 	/* Tx Stats */
18987 	tx->comp_queued = tx_stats->comp_queued;
18988 	tx->comp_delivered = tx_stats->comp_delivered;
18989 	tx->msdu_enqued = tx_stats->msdu_enqued;
18990 	tx->mpdu_enqued = tx_stats->mpdu_enqued;
18991 	tx->wmm_drop = tx_stats->wmm_drop;
18992 	tx->local_enqued = tx_stats->local_enqued;
18993 	tx->local_freed = tx_stats->local_freed;
18994 	tx->hw_queued = tx_stats->hw_queued;
18995 	tx->hw_reaped = tx_stats->hw_reaped;
18996 	tx->underrun = tx_stats->underrun;
18997 	tx->tx_abort = tx_stats->tx_abort;
18998 	tx->mpdus_requed = tx_stats->mpdus_requed;
18999 	tx->data_rc = tx_stats->data_rc;
19000 	tx->self_triggers = tx_stats->self_triggers;
19001 	tx->sw_retry_failure = tx_stats->sw_retry_failure;
19002 	tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err;
19003 	tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry;
19004 	tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout;
19005 	tx->pdev_resets = tx_stats->pdev_resets;
19006 	tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure;
19007 	tx->phy_underrun = tx_stats->phy_underrun;
19008 	tx->txop_ovf = tx_stats->txop_ovf;
19009 
19010 	return;
19011 }
19012 
19013 
19014 /**
19015  * extract_pdev_rx_stats() - extract pdev rx stats from event
19016  */
19017 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, struct wlan_dbg_rx_stats *rx_stats)
19018 {
19019 	/* Rx Stats */
19020 	rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change;
19021 	rx->status_rcvd = rx_stats->status_rcvd;
19022 	rx->r0_frags = rx_stats->r0_frags;
19023 	rx->r1_frags = rx_stats->r1_frags;
19024 	rx->r2_frags = rx_stats->r2_frags;
19025 	/* Only TLV */
19026 	rx->r3_frags = 0;
19027 	rx->htt_msdus = rx_stats->htt_msdus;
19028 	rx->htt_mpdus = rx_stats->htt_mpdus;
19029 	rx->loc_msdus = rx_stats->loc_msdus;
19030 	rx->loc_mpdus = rx_stats->loc_mpdus;
19031 	rx->oversize_amsdu = rx_stats->oversize_amsdu;
19032 	rx->phy_errs = rx_stats->phy_errs;
19033 	rx->phy_err_drop = rx_stats->phy_err_drop;
19034 	rx->mpdu_errs = rx_stats->mpdu_errs;
19035 
19036 	return;
19037 }
19038 
19039 /**
19040  * extract_pdev_stats_tlv() - extract pdev stats from event
19041  * @wmi_handle: wmi handle
19042  * @param evt_buf: pointer to event buffer
19043  * @param index: Index into pdev stats
19044  * @param pdev_stats: Pointer to hold pdev stats
19045  *
19046  * Return: QDF_STATUS_SUCCESS for success or error code
19047  */
19048 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle,
19049 	void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats)
19050 {
19051 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19052 	wmi_stats_event_fixed_param *ev_param;
19053 	uint8_t *data;
19054 
19055 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19056 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19057 
19058 	data = param_buf->data;
19059 
19060 	if (index < ev_param->num_pdev_stats) {
19061 		wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) +
19062 				(index * sizeof(wmi_pdev_stats)));
19063 
19064 		pdev_stats->chan_nf = ev->chan_nf;
19065 		pdev_stats->tx_frame_count = ev->tx_frame_count;
19066 		pdev_stats->rx_frame_count = ev->rx_frame_count;
19067 		pdev_stats->rx_clear_count = ev->rx_clear_count;
19068 		pdev_stats->cycle_count = ev->cycle_count;
19069 		pdev_stats->phy_err_count = ev->phy_err_count;
19070 		pdev_stats->chan_tx_pwr = ev->chan_tx_pwr;
19071 
19072 		extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx),
19073 			&(ev->pdev_stats.tx));
19074 		extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx),
19075 			&(ev->pdev_stats.rx));
19076 	}
19077 
19078 	return QDF_STATUS_SUCCESS;
19079 }
19080 
19081 /**
19082  * extract_unit_test_tlv() - extract unit test data
19083  * @wmi_handle: wmi handle
19084  * @param evt_buf: pointer to event buffer
19085  * @param unit_test: pointer to hold unit test data
19086  * @param maxspace: Amount of space in evt_buf
19087  *
19088  * Return: QDF_STATUS_SUCCESS for success or error code
19089  */
19090 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle,
19091 	void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace)
19092 {
19093 	WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf;
19094 	wmi_unit_test_event_fixed_param *ev_param;
19095 	uint32_t num_bufp;
19096 	uint32_t copy_size;
19097 	uint8_t *bufp;
19098 
19099 	param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf;
19100 	ev_param = param_buf->fixed_param;
19101 	bufp = param_buf->bufp;
19102 	num_bufp = param_buf->num_bufp;
19103 	unit_test->vdev_id = ev_param->vdev_id;
19104 	unit_test->module_id = ev_param->module_id;
19105 	unit_test->diag_token = ev_param->diag_token;
19106 	unit_test->flag = ev_param->flag;
19107 	unit_test->payload_len = ev_param->payload_len;
19108 	WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d\n", __func__,
19109 			ev_param->vdev_id,
19110 			ev_param->module_id,
19111 			ev_param->diag_token,
19112 			ev_param->flag);
19113 	WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp);
19114 	qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
19115 			bufp, num_bufp);
19116 	copy_size = (num_bufp < maxspace) ? num_bufp : maxspace;
19117 	qdf_mem_copy(unit_test->buffer, bufp, copy_size);
19118 	unit_test->buffer_len = copy_size;
19119 
19120 	return QDF_STATUS_SUCCESS;
19121 }
19122 
19123 /**
19124  * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event
19125  * @wmi_handle: wmi handle
19126  * @param evt_buf: pointer to event buffer
19127  * @param index: Index into extended pdev stats
19128  * @param pdev_ext_stats: Pointer to hold extended pdev stats
19129  *
19130  * Return: QDF_STATUS_SUCCESS for success or error code
19131  */
19132 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle,
19133 	void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats)
19134 {
19135 	return QDF_STATUS_SUCCESS;
19136 }
19137 
19138 /**
19139  * extract_vdev_stats_tlv() - extract vdev stats from event
19140  * @wmi_handle: wmi handle
19141  * @param evt_buf: pointer to event buffer
19142  * @param index: Index into vdev stats
19143  * @param vdev_stats: Pointer to hold vdev stats
19144  *
19145  * Return: QDF_STATUS_SUCCESS for success or error code
19146  */
19147 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle,
19148 	void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats)
19149 {
19150 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19151 	wmi_stats_event_fixed_param *ev_param;
19152 	uint8_t *data;
19153 
19154 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19155 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19156 	data = (uint8_t *) param_buf->data;
19157 
19158 	if (index < ev_param->num_vdev_stats) {
19159 		wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) +
19160 				((ev_param->num_pdev_stats) *
19161 				sizeof(wmi_pdev_stats)) +
19162 				(index * sizeof(wmi_vdev_stats)));
19163 
19164 		vdev_stats->vdev_id = ev->vdev_id;
19165 		vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr;
19166 		vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr;
19167 
19168 		OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt,
19169 			sizeof(ev->tx_frm_cnt));
19170 		vdev_stats->rx_frm_cnt = ev->rx_frm_cnt;
19171 		OS_MEMCPY(vdev_stats->multiple_retry_cnt,
19172 				ev->multiple_retry_cnt,
19173 				sizeof(ev->multiple_retry_cnt));
19174 		OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt,
19175 				sizeof(ev->fail_cnt));
19176 		vdev_stats->rts_fail_cnt = ev->rts_fail_cnt;
19177 		vdev_stats->rts_succ_cnt = ev->rts_succ_cnt;
19178 		vdev_stats->rx_err_cnt = ev->rx_err_cnt;
19179 		vdev_stats->rx_discard_cnt = ev->rx_discard_cnt;
19180 		vdev_stats->ack_fail_cnt = ev->ack_fail_cnt;
19181 		OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history,
19182 			sizeof(ev->tx_rate_history));
19183 		OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history,
19184 			sizeof(ev->bcn_rssi_history));
19185 
19186 	}
19187 
19188 	return QDF_STATUS_SUCCESS;
19189 }
19190 
19191 /**
19192  * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event
19193  * buffer
19194  * @wmi_handle: wmi handle
19195  * @evt_buf: pointer to event buffer
19196  * @index: Index into vdev stats
19197  * @rssi_stats: Pointer to hold rssi stats
19198  *
19199  * Return: QDF_STATUS_SUCCESS for success or error code
19200  */
19201 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle,
19202 			void *evt_buf, uint32_t index,
19203 			struct wmi_host_per_chain_rssi_stats *rssi_stats)
19204 {
19205 	uint8_t *data;
19206 	wmi_rssi_stats *fw_rssi_stats;
19207 	wmi_per_chain_rssi_stats *rssi_event;
19208 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19209 
19210 	if (!evt_buf) {
19211 		WMI_LOGE("evt_buf is null");
19212 		return QDF_STATUS_E_NULL_VALUE;
19213 	}
19214 
19215 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19216 	rssi_event = param_buf->chain_stats;
19217 
19218 	if (index >= rssi_event->num_per_chain_rssi_stats) {
19219 		WMI_LOGE("invalid index");
19220 		return QDF_STATUS_E_INVAL;
19221 	}
19222 
19223 	data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE;
19224 	fw_rssi_stats = &((wmi_rssi_stats *)data)[index];
19225 
19226 	rssi_stats->vdev_id = fw_rssi_stats->vdev_id;
19227 	qdf_mem_copy(rssi_stats->rssi_avg_beacon,
19228 		     fw_rssi_stats->rssi_avg_beacon,
19229 		     sizeof(fw_rssi_stats->rssi_avg_beacon));
19230 	qdf_mem_copy(rssi_stats->rssi_avg_data,
19231 		     fw_rssi_stats->rssi_avg_data,
19232 		     sizeof(fw_rssi_stats->rssi_avg_data));
19233 	qdf_mem_copy(&rssi_stats->peer_macaddr,
19234 		     &fw_rssi_stats->peer_macaddr,
19235 		     sizeof(fw_rssi_stats->peer_macaddr));
19236 
19237 	return QDF_STATUS_SUCCESS;
19238 }
19239 
19240 
19241 
19242 /**
19243  * extract_bcn_stats_tlv() - extract bcn stats from event
19244  * @wmi_handle: wmi handle
19245  * @param evt_buf: pointer to event buffer
19246  * @param index: Index into vdev stats
19247  * @param bcn_stats: Pointer to hold bcn stats
19248  *
19249  * Return: QDF_STATUS_SUCCESS for success or error code
19250  */
19251 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle,
19252 	void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats)
19253 {
19254 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19255 	wmi_stats_event_fixed_param *ev_param;
19256 	uint8_t *data;
19257 
19258 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19259 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19260 	data = (uint8_t *) param_buf->data;
19261 
19262 	if (index < ev_param->num_bcn_stats) {
19263 		wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) +
19264 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19265 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19266 			((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) +
19267 			((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) +
19268 			((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) +
19269 			(index * sizeof(wmi_bcn_stats)));
19270 
19271 		bcn_stats->vdev_id = ev->vdev_id;
19272 		bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt;
19273 		bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt;
19274 	}
19275 
19276 	return QDF_STATUS_SUCCESS;
19277 }
19278 
19279 /**
19280  * extract_peer_stats_tlv() - extract peer stats from event
19281  * @wmi_handle: wmi handle
19282  * @param evt_buf: pointer to event buffer
19283  * @param index: Index into peer stats
19284  * @param peer_stats: Pointer to hold peer stats
19285  *
19286  * Return: QDF_STATUS_SUCCESS for success or error code
19287  */
19288 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle,
19289 	void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats)
19290 {
19291 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19292 	wmi_stats_event_fixed_param *ev_param;
19293 	uint8_t *data;
19294 
19295 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19296 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19297 	data = (uint8_t *) param_buf->data;
19298 
19299 	if (index < ev_param->num_peer_stats) {
19300 		wmi_peer_stats *ev = (wmi_peer_stats *) ((data) +
19301 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19302 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19303 			(index * sizeof(wmi_peer_stats)));
19304 
19305 		OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats));
19306 
19307 		OS_MEMCPY(&(peer_stats->peer_macaddr),
19308 			&(ev->peer_macaddr), sizeof(wmi_mac_addr));
19309 
19310 		peer_stats->peer_rssi = ev->peer_rssi;
19311 		peer_stats->peer_tx_rate = ev->peer_tx_rate;
19312 		peer_stats->peer_rx_rate = ev->peer_rx_rate;
19313 	}
19314 
19315 	return QDF_STATUS_SUCCESS;
19316 }
19317 
19318 /**
19319  * extract_bcnflt_stats_tlv() - extract bcn fault stats from event
19320  * @wmi_handle: wmi handle
19321  * @param evt_buf: pointer to event buffer
19322  * @param index: Index into bcn fault stats
19323  * @param bcnflt_stats: Pointer to hold bcn fault stats
19324  *
19325  * Return: QDF_STATUS_SUCCESS for success or error code
19326  */
19327 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle,
19328 	void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats)
19329 {
19330 	return QDF_STATUS_SUCCESS;
19331 }
19332 
19333 /**
19334  * extract_peer_extd_stats_tlv() - extract extended peer stats from event
19335  * @wmi_handle: wmi handle
19336  * @param evt_buf: pointer to event buffer
19337  * @param index: Index into extended peer stats
19338  * @param peer_extd_stats: Pointer to hold extended peer stats
19339  *
19340  * Return: QDF_STATUS_SUCCESS for success or error code
19341  */
19342 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle,
19343 		void *evt_buf, uint32_t index,
19344 		wmi_host_peer_extd_stats *peer_extd_stats)
19345 {
19346 	return QDF_STATUS_SUCCESS;
19347 }
19348 
19349 /**
19350  * extract_chan_stats_tlv() - extract chan stats from event
19351  * @wmi_handle: wmi handle
19352  * @param evt_buf: pointer to event buffer
19353  * @param index: Index into chan stats
19354  * @param vdev_extd_stats: Pointer to hold chan stats
19355  *
19356  * Return: QDF_STATUS_SUCCESS for success or error code
19357  */
19358 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle,
19359 	void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats)
19360 {
19361 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19362 	wmi_stats_event_fixed_param *ev_param;
19363 	uint8_t *data;
19364 
19365 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19366 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19367 	data = (uint8_t *) param_buf->data;
19368 
19369 	if (index < ev_param->num_chan_stats) {
19370 		wmi_chan_stats *ev = (wmi_chan_stats *) ((data) +
19371 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19372 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19373 			((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) +
19374 			(index * sizeof(wmi_chan_stats)));
19375 
19376 
19377 		/* Non-TLV doesn't have num_chan_stats */
19378 		chan_stats->chan_mhz = ev->chan_mhz;
19379 		chan_stats->sampling_period_us = ev->sampling_period_us;
19380 		chan_stats->rx_clear_count = ev->rx_clear_count;
19381 		chan_stats->tx_duration_us = ev->tx_duration_us;
19382 		chan_stats->rx_duration_us = ev->rx_duration_us;
19383 	}
19384 
19385 	return QDF_STATUS_SUCCESS;
19386 }
19387 
19388 /**
19389  * extract_profile_ctx_tlv() - extract profile context from event
19390  * @wmi_handle: wmi handle
19391  * @param evt_buf: pointer to event buffer
19392  * @idx: profile stats index to extract
19393  * @param profile_ctx: Pointer to hold profile context
19394  *
19395  * Return: QDF_STATUS_SUCCESS for success or error code
19396  */
19397 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle,
19398 	void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx)
19399 {
19400 	return QDF_STATUS_SUCCESS;
19401 }
19402 
19403 /**
19404  * extract_profile_data_tlv() - extract profile data from event
19405  * @wmi_handle: wmi handle
19406  * @param evt_buf: pointer to event buffer
19407  * @param profile_data: Pointer to hold profile data
19408  *
19409  * Return: QDF_STATUS_SUCCESS for success or error code
19410  */
19411 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle,
19412 	void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data)
19413 {
19414 
19415 	return QDF_STATUS_SUCCESS;
19416 }
19417 
19418 /**
19419  * extract_chan_info_event_tlv() - extract chan information from event
19420  * @wmi_handle: wmi handle
19421  * @param evt_buf: pointer to event buffer
19422  * @param chan_info: Pointer to hold chan information
19423  *
19424  * Return: QDF_STATUS_SUCCESS for success or error code
19425  */
19426 static QDF_STATUS extract_chan_info_event_tlv(wmi_unified_t wmi_handle,
19427 	void *evt_buf, wmi_host_chan_info_event *chan_info)
19428 {
19429 	WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf;
19430 	wmi_chan_info_event_fixed_param *ev;
19431 
19432 	param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) evt_buf;
19433 
19434 	ev = (wmi_chan_info_event_fixed_param *) param_buf->fixed_param;
19435 	if (!ev) {
19436 		WMI_LOGE("%s: Failed to allocmemory\n", __func__);
19437 		return QDF_STATUS_E_FAILURE;
19438 	}
19439 
19440 	chan_info->err_code = ev->err_code;
19441 	chan_info->freq = ev->freq;
19442 	chan_info->cmd_flags = ev->cmd_flags;
19443 	chan_info->noise_floor = ev->noise_floor;
19444 	chan_info->rx_clear_count = ev->rx_clear_count;
19445 	chan_info->cycle_count = ev->cycle_count;
19446 	chan_info->tx_frame_cnt = ev->tx_frame_cnt;
19447 	chan_info->mac_clk_mhz = ev->mac_clk_mhz;
19448 	chan_info->pdev_id = wlan_get_pdev_id_from_vdev_id(
19449 			(struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc,
19450 			ev->vdev_id, WLAN_SCAN_ID);
19451 	chan_info->chan_tx_pwr_range = ev->chan_tx_pwr_range;
19452 	chan_info->chan_tx_pwr_tp = ev->chan_tx_pwr_tp;
19453 	chan_info->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count;
19454 	chan_info->rx_11b_mode_data_duration = ev->rx_11b_mode_data_duration;
19455 	chan_info->tx_frame_cnt = ev->tx_frame_cnt;
19456 	chan_info->rx_frame_count = ev->rx_frame_count;
19457 	chan_info->mac_clk_mhz = ev->mac_clk_mhz;
19458 	chan_info->vdev_id = ev->vdev_id;
19459 
19460 	return QDF_STATUS_SUCCESS;
19461 }
19462 
19463 /**
19464  * extract_pdev_utf_event_tlv() - extract UTF data info from event
19465  * @wmi_handle: WMI handle
19466  * @param evt_buf: Pointer to event buffer
19467  * @param param: Pointer to hold data
19468  *
19469  * Return : QDF_STATUS_SUCCESS for success or error code
19470  */
19471 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle,
19472 			     uint8_t *evt_buf,
19473 			     struct wmi_host_pdev_utf_event *event)
19474 {
19475 	WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf;
19476 	struct wmi_host_utf_seg_header_info *seg_hdr;
19477 
19478 	param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf;
19479 	event->data = param_buf->data;
19480 	event->datalen = param_buf->num_data;
19481 
19482 	if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) {
19483 		WMI_LOGE("%s: Invalid datalen: %d ", __func__, event->datalen);
19484 		return QDF_STATUS_E_INVAL;
19485 	}
19486 	seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data;
19487 	/* Set pdev_id=1 until FW adds support to include pdev_id */
19488 	event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19489 							seg_hdr->pdev_id);
19490 
19491 	return QDF_STATUS_SUCCESS;
19492 }
19493 
19494 /**
19495  * extract_chainmask_tables_tlv() - extract chain mask tables from event
19496  * @wmi_handle: wmi handle
19497  * @param evt_buf: pointer to event buffer
19498  * @param param: Pointer to hold evt buf
19499  *
19500  * Return: QDF_STATUS_SUCCESS for success or error code
19501  */
19502 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle,
19503 		uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table)
19504 {
19505 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19506 	WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps;
19507 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19508 	uint8_t i = 0, j = 0;
19509 
19510 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19511 	if (!param_buf)
19512 		return QDF_STATUS_E_INVAL;
19513 
19514 	hw_caps = param_buf->soc_hw_mode_caps;
19515 	if (!hw_caps)
19516 		return QDF_STATUS_E_INVAL;
19517 
19518 	if (!hw_caps->num_chainmask_tables)
19519 		return QDF_STATUS_E_INVAL;
19520 
19521 	chainmask_caps = param_buf->mac_phy_chainmask_caps;
19522 
19523 	if (chainmask_caps == NULL)
19524 		return QDF_STATUS_E_INVAL;
19525 
19526 	for (i = 0; i < hw_caps->num_chainmask_tables; i++) {
19527 
19528 		qdf_print("Dumping chain mask combo data for table : %d", i);
19529 		for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) {
19530 
19531 			chainmask_table[i].cap_list[j].chainmask =
19532 				chainmask_caps->chainmask;
19533 
19534 			chainmask_table[i].cap_list[j].supports_chan_width_20 =
19535 				WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags);
19536 
19537 			chainmask_table[i].cap_list[j].supports_chan_width_40 =
19538 				WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags);
19539 
19540 			chainmask_table[i].cap_list[j].supports_chan_width_80 =
19541 				WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags);
19542 
19543 			chainmask_table[i].cap_list[j].supports_chan_width_160 =
19544 				WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags);
19545 
19546 			chainmask_table[i].cap_list[j].supports_chan_width_80P80 =
19547 				WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags);
19548 
19549 			chainmask_table[i].cap_list[j].chain_mask_2G =
19550 				WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags);
19551 
19552 			chainmask_table[i].cap_list[j].chain_mask_5G =
19553 				WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags);
19554 
19555 			chainmask_table[i].cap_list[j].chain_mask_tx =
19556 				WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags);
19557 
19558 			chainmask_table[i].cap_list[j].chain_mask_rx =
19559 				WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags);
19560 
19561 			chainmask_table[i].cap_list[j].supports_aDFS =
19562 				WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags);
19563 
19564 			qdf_print("supported_flags: 0x%08x  chainmasks: 0x%08x",
19565 				  chainmask_caps->supported_flags,
19566 				  chainmask_caps->chainmask
19567 				 );
19568 			chainmask_caps++;
19569 		}
19570 	}
19571 
19572 	return QDF_STATUS_SUCCESS;
19573 }
19574 
19575 /**
19576  * extract_service_ready_ext_tlv() - extract basic extended service ready params
19577  * from event
19578  * @wmi_handle: wmi handle
19579  * @param evt_buf: pointer to event buffer
19580  * @param param: Pointer to hold evt buf
19581  *
19582  * Return: QDF_STATUS_SUCCESS for success or error code
19583  */
19584 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle,
19585 		uint8_t *event, struct wlan_psoc_host_service_ext_param *param)
19586 {
19587 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19588 	wmi_service_ready_ext_event_fixed_param *ev;
19589 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19590 	WMI_SOC_HAL_REG_CAPABILITIES *reg_caps;
19591 	WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo;
19592 	uint8_t i = 0;
19593 
19594 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19595 	if (!param_buf)
19596 		return QDF_STATUS_E_INVAL;
19597 
19598 	ev = param_buf->fixed_param;
19599 	if (!ev)
19600 		return QDF_STATUS_E_INVAL;
19601 
19602 	/* Move this to host based bitmap */
19603 	param->default_conc_scan_config_bits =
19604 				ev->default_conc_scan_config_bits;
19605 	param->default_fw_config_bits = ev->default_fw_config_bits;
19606 	param->he_cap_info = ev->he_cap_info;
19607 	param->mpdu_density = ev->mpdu_density;
19608 	param->max_bssid_rx_filters = ev->max_bssid_rx_filters;
19609 	param->fw_build_vers_ext = ev->fw_build_vers_ext;
19610 	param->num_dbr_ring_caps = param_buf->num_dma_ring_caps;
19611 	param->max_bssid_indicator = ev->max_bssid_indicator;
19612 	qdf_mem_copy(&param->ppet, &ev->ppet, sizeof(param->ppet));
19613 
19614 	hw_caps = param_buf->soc_hw_mode_caps;
19615 	if (hw_caps)
19616 		param->num_hw_modes = hw_caps->num_hw_modes;
19617 	else
19618 		param->num_hw_modes = 0;
19619 
19620 	reg_caps = param_buf->soc_hal_reg_caps;
19621 	if (reg_caps)
19622 		param->num_phy = reg_caps->num_phy;
19623 	else
19624 		param->num_phy = 0;
19625 
19626 	if (hw_caps) {
19627 		param->num_chainmask_tables = hw_caps->num_chainmask_tables;
19628 		qdf_print("Num chain mask tables: %d", hw_caps->num_chainmask_tables);
19629 	} else
19630 		param->num_chainmask_tables = 0;
19631 
19632 	chain_mask_combo = param_buf->mac_phy_chainmask_combo;
19633 
19634 	if (chain_mask_combo == NULL)
19635 		return QDF_STATUS_SUCCESS;
19636 
19637 	qdf_print("Dumping chain mask combo data");
19638 
19639 	for (i = 0; i < param->num_chainmask_tables; i++) {
19640 
19641 		qdf_print("table_id : %d Num valid chainmasks: %d",
19642 			  chain_mask_combo->chainmask_table_id,
19643 			  chain_mask_combo->num_valid_chainmask
19644 			 );
19645 
19646 		param->chainmask_table[i].table_id =
19647 			chain_mask_combo->chainmask_table_id;
19648 		param->chainmask_table[i].num_valid_chainmasks =
19649 			chain_mask_combo->num_valid_chainmask;
19650 		chain_mask_combo++;
19651 	}
19652 	qdf_print("chain mask combo end");
19653 
19654 	return QDF_STATUS_SUCCESS;
19655 }
19656 
19657 /**
19658  * extract_sar_cap_service_ready_ext_tlv() -
19659  *       extract SAR cap from service ready event
19660  * @wmi_handle: wmi handle
19661  * @event: pointer to event buffer
19662  * @ext_param: extended target info
19663  *
19664  * Return: QDF_STATUS_SUCCESS for success or error code
19665  */
19666 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv(
19667 			wmi_unified_t wmi_handle,
19668 			uint8_t *event,
19669 			struct wlan_psoc_host_service_ext_param *ext_param)
19670 {
19671 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19672 	WMI_SAR_CAPABILITIES *sar_caps;
19673 
19674 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event;
19675 
19676 	if (!param_buf)
19677 		return QDF_STATUS_E_INVAL;
19678 
19679 	sar_caps = param_buf->sar_caps;
19680 	if (sar_caps)
19681 		ext_param->sar_version = sar_caps->active_version;
19682 	else
19683 		ext_param->sar_version = 0;
19684 
19685 	return QDF_STATUS_SUCCESS;
19686 }
19687 
19688 /**
19689  * extract_hw_mode_cap_service_ready_ext_tlv() -
19690  *       extract HW mode cap from service ready event
19691  * @wmi_handle: wmi handle
19692  * @param evt_buf: pointer to event buffer
19693  * @param param: Pointer to hold evt buf
19694  * @param hw_mode_idx: hw mode idx should be less than num_mode
19695  *
19696  * Return: QDF_STATUS_SUCCESS for success or error code
19697  */
19698 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv(
19699 			wmi_unified_t wmi_handle,
19700 			uint8_t *event, uint8_t hw_mode_idx,
19701 			struct wlan_psoc_host_hw_mode_caps *param)
19702 {
19703 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19704 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19705 
19706 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19707 	if (!param_buf)
19708 		return QDF_STATUS_E_INVAL;
19709 
19710 	hw_caps = param_buf->soc_hw_mode_caps;
19711 	if (!hw_caps)
19712 		return QDF_STATUS_E_INVAL;
19713 
19714 	if (hw_mode_idx >= hw_caps->num_hw_modes)
19715 		return QDF_STATUS_E_INVAL;
19716 
19717 	param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id;
19718 	param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map;
19719 
19720 	param->hw_mode_config_type =
19721 		param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type;
19722 
19723 	return QDF_STATUS_SUCCESS;
19724 }
19725 
19726 /**
19727  * extract_mac_phy_cap_service_ready_ext_tlv() -
19728  *       extract MAC phy cap from service ready event
19729  * @wmi_handle: wmi handle
19730  * @param evt_buf: pointer to event buffer
19731  * @param param: Pointer to hold evt buf
19732  * @param hw_mode_idx: hw mode idx should be less than num_mode
19733  * @param phy_id: phy id within hw_mode
19734  *
19735  * Return: QDF_STATUS_SUCCESS for success or error code
19736  */
19737 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv(
19738 			wmi_unified_t wmi_handle,
19739 			uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id,
19740 			struct wlan_psoc_host_mac_phy_caps *param)
19741 {
19742 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19743 	WMI_MAC_PHY_CAPABILITIES *mac_phy_caps;
19744 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19745 	uint32_t phy_map;
19746 	uint8_t hw_idx, phy_idx = 0;
19747 
19748 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19749 	if (!param_buf)
19750 		return QDF_STATUS_E_INVAL;
19751 
19752 	hw_caps = param_buf->soc_hw_mode_caps;
19753 	if (!hw_caps)
19754 		return QDF_STATUS_E_INVAL;
19755 
19756 	for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) {
19757 		if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id)
19758 			break;
19759 
19760 		phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map;
19761 		while (phy_map) {
19762 			phy_map >>= 1;
19763 			phy_idx++;
19764 		}
19765 	}
19766 
19767 	if (hw_idx == hw_caps->num_hw_modes)
19768 		return QDF_STATUS_E_INVAL;
19769 
19770 	phy_idx += phy_id;
19771 	if (phy_idx >= param_buf->num_mac_phy_caps)
19772 		return QDF_STATUS_E_INVAL;
19773 
19774 	mac_phy_caps = &param_buf->mac_phy_caps[phy_idx];
19775 
19776 	param->hw_mode_id = mac_phy_caps->hw_mode_id;
19777 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19778 							mac_phy_caps->pdev_id);
19779 	param->phy_id = mac_phy_caps->phy_id;
19780 	param->supports_11b =
19781 			WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags);
19782 	param->supports_11g =
19783 			WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags);
19784 	param->supports_11a =
19785 			WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags);
19786 	param->supports_11n =
19787 			WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags);
19788 	param->supports_11ac =
19789 			WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags);
19790 	param->supports_11ax =
19791 			WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags);
19792 
19793 	param->supported_bands = mac_phy_caps->supported_bands;
19794 	param->ampdu_density = mac_phy_caps->ampdu_density;
19795 	param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G;
19796 	param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G;
19797 	param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G;
19798 	param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G;
19799 	param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] =
19800 		mac_phy_caps->he_cap_info_2G;
19801 	param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] =
19802 		mac_phy_caps->he_cap_info_2G_ext;
19803 	param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G;
19804 	param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G;
19805 	param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G;
19806 	param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G;
19807 	param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G;
19808 	param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G;
19809 	param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G;
19810 	param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] =
19811 		mac_phy_caps->he_cap_info_5G;
19812 	param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] =
19813 		mac_phy_caps->he_cap_info_5G_ext;
19814 	param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G;
19815 	param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G;
19816 	param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G;
19817 	qdf_mem_copy(&param->he_cap_phy_info_2G,
19818 			&mac_phy_caps->he_cap_phy_info_2G,
19819 			sizeof(param->he_cap_phy_info_2G));
19820 	qdf_mem_copy(&param->he_cap_phy_info_5G,
19821 			&mac_phy_caps->he_cap_phy_info_5G,
19822 			sizeof(param->he_cap_phy_info_5G));
19823 	qdf_mem_copy(&param->he_ppet2G, &mac_phy_caps->he_ppet2G,
19824 				 sizeof(param->he_ppet2G));
19825 	qdf_mem_copy(&param->he_ppet5G, &mac_phy_caps->he_ppet5G,
19826 				sizeof(param->he_ppet5G));
19827 	param->chainmask_table_id = mac_phy_caps->chainmask_table_id;
19828 
19829 	return QDF_STATUS_SUCCESS;
19830 }
19831 
19832 /**
19833  * extract_reg_cap_service_ready_ext_tlv() -
19834  *       extract REG cap from service ready event
19835  * @wmi_handle: wmi handle
19836  * @param evt_buf: pointer to event buffer
19837  * @param param: Pointer to hold evt buf
19838  * @param phy_idx: phy idx should be less than num_mode
19839  *
19840  * Return: QDF_STATUS_SUCCESS for success or error code
19841  */
19842 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv(
19843 			wmi_unified_t wmi_handle,
19844 			uint8_t *event, uint8_t phy_idx,
19845 			struct wlan_psoc_host_hal_reg_capabilities_ext *param)
19846 {
19847 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19848 	WMI_SOC_HAL_REG_CAPABILITIES *reg_caps;
19849 	WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap;
19850 
19851 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19852 	if (!param_buf)
19853 		return QDF_STATUS_E_INVAL;
19854 
19855 	reg_caps = param_buf->soc_hal_reg_caps;
19856 	if (!reg_caps)
19857 		return QDF_STATUS_E_INVAL;
19858 
19859 	if (phy_idx >= reg_caps->num_phy)
19860 		return QDF_STATUS_E_INVAL;
19861 
19862 	ext_reg_cap = &param_buf->hal_reg_caps[phy_idx];
19863 
19864 	param->phy_id = ext_reg_cap->phy_id;
19865 	param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain;
19866 	param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext;
19867 	param->regcap1 = ext_reg_cap->regcap1;
19868 	param->regcap2 = ext_reg_cap->regcap2;
19869 	param->wireless_modes = convert_wireless_modes_tlv(
19870 						ext_reg_cap->wireless_modes);
19871 	param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan;
19872 	param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan;
19873 	param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan;
19874 	param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan;
19875 
19876 	return QDF_STATUS_SUCCESS;
19877 }
19878 
19879 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv(
19880 			wmi_unified_t wmi_handle,
19881 			uint8_t *event, uint8_t idx,
19882 			struct wlan_psoc_host_dbr_ring_caps *param)
19883 {
19884 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19885 	WMI_DMA_RING_CAPABILITIES *dbr_ring_caps;
19886 
19887 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event;
19888 	if (!param_buf)
19889 		return QDF_STATUS_E_INVAL;
19890 
19891 	dbr_ring_caps = &param_buf->dma_ring_caps[idx];
19892 
19893 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19894 				dbr_ring_caps->pdev_id);
19895 	param->mod_id = dbr_ring_caps->mod_id;
19896 	param->ring_elems_min = dbr_ring_caps->ring_elems_min;
19897 	param->min_buf_size = dbr_ring_caps->min_buf_size;
19898 	param->min_buf_align = dbr_ring_caps->min_buf_align;
19899 
19900 	return QDF_STATUS_SUCCESS;
19901 }
19902 
19903 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle,
19904 		uint8_t *event, struct direct_buf_rx_rsp *param)
19905 {
19906 	WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
19907 	wmi_dma_buf_release_fixed_param *ev;
19908 
19909 	param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
19910 	if (!param_buf)
19911 		return QDF_STATUS_E_INVAL;
19912 
19913 	ev = param_buf->fixed_param;
19914 	if (!ev)
19915 		return QDF_STATUS_E_INVAL;
19916 
19917 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19918 								ev->pdev_id);
19919 	param->mod_id = ev->mod_id;
19920 	param->num_buf_release_entry = ev->num_buf_release_entry;
19921 	param->num_meta_data_entry = ev->num_meta_data_entry;
19922 	WMI_LOGD("%s:pdev id %d mod id %d num buf release entry %d\n", __func__,
19923 		 param->pdev_id, param->mod_id, param->num_buf_release_entry);
19924 
19925 	return QDF_STATUS_SUCCESS;
19926 }
19927 
19928 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle,
19929 		uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param)
19930 {
19931 	WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
19932 	wmi_dma_buf_release_entry *entry;
19933 
19934 	param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
19935 	if (!param_buf)
19936 		return QDF_STATUS_E_INVAL;
19937 
19938 	entry = &param_buf->entries[idx];
19939 
19940 	if (!entry) {
19941 		WMI_LOGE("%s: Entry is NULL\n", __func__);
19942 		return QDF_STATUS_E_FAILURE;
19943 	}
19944 
19945 	WMI_LOGD("%s: paddr_lo[%d] = %x\n", __func__, idx, entry->paddr_lo);
19946 
19947 	param->paddr_lo = entry->paddr_lo;
19948 	param->paddr_hi = entry->paddr_hi;
19949 
19950 	return QDF_STATUS_SUCCESS;
19951 }
19952 
19953 static QDF_STATUS extract_dbr_buf_metadata_tlv(
19954 		wmi_unified_t wmi_handle, uint8_t *event,
19955 		uint8_t idx, struct direct_buf_rx_metadata *param)
19956 {
19957 	WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
19958 	wmi_dma_buf_release_spectral_meta_data *entry;
19959 
19960 	param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
19961 	if (!param_buf)
19962 		return QDF_STATUS_E_INVAL;
19963 
19964 	entry = &param_buf->meta_data[idx];
19965 
19966 	if (!entry) {
19967 		WMI_LOGE("%s: Entry is NULL\n", __func__);
19968 		return QDF_STATUS_E_FAILURE;
19969 	}
19970 
19971 	qdf_mem_copy(param->noisefloor, entry->noise_floor,
19972 		     sizeof(entry->noise_floor));
19973 	return QDF_STATUS_SUCCESS;
19974 }
19975 
19976 /**
19977  * extract_dcs_interference_type_tlv() - extract dcs interference type
19978  * from event
19979  * @wmi_handle: wmi handle
19980  * @param evt_buf: pointer to event buffer
19981  * @param param: Pointer to hold dcs interference param
19982  *
19983  * Return: 0 for success or error code
19984  */
19985 static QDF_STATUS extract_dcs_interference_type_tlv(
19986 		wmi_unified_t wmi_handle,
19987 		void *evt_buf, struct wmi_host_dcs_interference_param *param)
19988 {
19989 	WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf;
19990 
19991 	param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf;
19992 	if (!param_buf)
19993 		return QDF_STATUS_E_INVAL;
19994 
19995 	param->interference_type = param_buf->fixed_param->interference_type;
19996 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19997 					param_buf->fixed_param->pdev_id);
19998 
19999 	return QDF_STATUS_SUCCESS;
20000 }
20001 
20002 /*
20003  * extract_dcs_cw_int_tlv() - extract dcs cw interference from event
20004  * @wmi_handle: wmi handle
20005  * @param evt_buf: pointer to event buffer
20006  * @param cw_int: Pointer to hold cw interference
20007  *
20008  * Return: 0 for success or error code
20009  */
20010 static QDF_STATUS extract_dcs_cw_int_tlv(wmi_unified_t wmi_handle,
20011 		void *evt_buf,
20012 		wmi_host_ath_dcs_cw_int *cw_int)
20013 {
20014 	WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf;
20015 	wlan_dcs_cw_int *ev;
20016 
20017 	param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf;
20018 	if (!param_buf)
20019 		return QDF_STATUS_E_INVAL;
20020 
20021 	ev = param_buf->cw_int;
20022 
20023 	cw_int->channel = ev->channel;
20024 
20025 	return QDF_STATUS_SUCCESS;
20026 }
20027 
20028 /**
20029  * extract_dcs_im_tgt_stats_tlv() - extract dcs im target stats from event
20030  * @wmi_handle: wmi handle
20031  * @param evt_buf: pointer to event buffer
20032  * @param wlan_stat: Pointer to hold wlan stats
20033  *
20034  * Return: 0 for success or error code
20035  */
20036 static QDF_STATUS extract_dcs_im_tgt_stats_tlv(wmi_unified_t wmi_handle,
20037 		void *evt_buf,
20038 		wmi_host_dcs_im_tgt_stats_t *wlan_stat)
20039 {
20040 	WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf;
20041 	wlan_dcs_im_tgt_stats_t *ev;
20042 
20043 	param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf;
20044 	if (!param_buf)
20045 		return QDF_STATUS_E_INVAL;
20046 
20047 	ev = param_buf->wlan_stat;
20048 	wlan_stat->reg_tsf32 = ev->reg_tsf32;
20049 	wlan_stat->last_ack_rssi = ev->last_ack_rssi;
20050 	wlan_stat->tx_waste_time = ev->tx_waste_time;
20051 	wlan_stat->rx_time = ev->rx_time;
20052 	wlan_stat->phyerr_cnt = ev->phyerr_cnt;
20053 	wlan_stat->mib_stats.listen_time = ev->listen_time;
20054 	wlan_stat->mib_stats.reg_tx_frame_cnt = ev->reg_tx_frame_cnt;
20055 	wlan_stat->mib_stats.reg_rx_frame_cnt = ev->reg_rx_frame_cnt;
20056 	wlan_stat->mib_stats.reg_rxclr_cnt = ev->reg_rxclr_cnt;
20057 	wlan_stat->mib_stats.reg_cycle_cnt = ev->reg_cycle_cnt;
20058 	wlan_stat->mib_stats.reg_rxclr_ext_cnt = ev->reg_rxclr_ext_cnt;
20059 	wlan_stat->mib_stats.reg_ofdm_phyerr_cnt = ev->reg_ofdm_phyerr_cnt;
20060 	wlan_stat->mib_stats.reg_cck_phyerr_cnt = ev->reg_cck_phyerr_cnt;
20061 	wlan_stat->chan_nf = ev->chan_nf;
20062 	wlan_stat->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count;
20063 
20064 	return QDF_STATUS_SUCCESS;
20065 }
20066 
20067 /**
20068  * extract_thermal_stats_tlv() - extract thermal stats from event
20069  * @wmi_handle: wmi handle
20070  * @param evt_buf: Pointer to event buffer
20071  * @param temp: Pointer to hold extracted temperature
20072  * @param level: Pointer to hold extracted level
20073  *
20074  * Return: 0 for success or error code
20075  */
20076 static QDF_STATUS
20077 extract_thermal_stats_tlv(wmi_unified_t wmi_handle,
20078 		void *evt_buf, uint32_t *temp,
20079 		uint32_t *level, uint32_t *pdev_id)
20080 {
20081 	WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf;
20082 	wmi_therm_throt_stats_event_fixed_param *tt_stats_event;
20083 
20084 	param_buf =
20085 		(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf;
20086 	if (!param_buf)
20087 		return QDF_STATUS_E_INVAL;
20088 
20089 	tt_stats_event = param_buf->fixed_param;
20090 
20091 	*pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20092 						tt_stats_event->pdev_id);
20093 	*temp = tt_stats_event->temp;
20094 	*level = tt_stats_event->level;
20095 
20096 	return QDF_STATUS_SUCCESS;
20097 }
20098 
20099 /**
20100  * extract_thermal_level_stats_tlv() - extract thermal level stats from event
20101  * @wmi_handle: wmi handle
20102  * @param evt_buf: pointer to event buffer
20103  * @param idx: Index to level stats
20104  * @param levelcount: Pointer to hold levelcount
20105  * @param dccount: Pointer to hold dccount
20106  *
20107  * Return: 0 for success or error code
20108  */
20109 static QDF_STATUS
20110 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle,
20111 		void *evt_buf, uint8_t idx, uint32_t *levelcount,
20112 		uint32_t *dccount)
20113 {
20114 	WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf;
20115 	wmi_therm_throt_level_stats_info *tt_level_info;
20116 
20117 	param_buf =
20118 		(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf;
20119 	if (!param_buf)
20120 		return QDF_STATUS_E_INVAL;
20121 
20122 	tt_level_info = param_buf->therm_throt_level_stats_info;
20123 
20124 	if (idx < THERMAL_LEVELS) {
20125 		*levelcount = tt_level_info[idx].level_count;
20126 		*dccount = tt_level_info[idx].dc_count;
20127 		return QDF_STATUS_SUCCESS;
20128 	}
20129 
20130 	return QDF_STATUS_E_FAILURE;
20131 }
20132 #ifdef BIG_ENDIAN_HOST
20133 /**
20134  * fips_conv_data_be() - LE to BE conversion of FIPS ev data
20135  * @param data_len - data length
20136  * @param data - pointer to data
20137  *
20138  * Return: QDF_STATUS - success or error status
20139  */
20140 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data)
20141 {
20142 	uint8_t *data_aligned = NULL;
20143 	int c;
20144 	unsigned char *data_unaligned;
20145 
20146 	data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) +
20147 					FIPS_ALIGN));
20148 	/* Assigning unaligned space to copy the data */
20149 	/* Checking if kmalloc does successful allocation */
20150 	if (data_unaligned == NULL)
20151 		return QDF_STATUS_E_FAILURE;
20152 
20153 	/* Checking if space is alligned */
20154 	if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) {
20155 		/* align the data space */
20156 		data_aligned =
20157 			(uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN);
20158 	} else {
20159 		data_aligned = (u_int8_t *)data_unaligned;
20160 	}
20161 
20162 	/* memset and copy content from data to data aligned */
20163 	OS_MEMSET(data_aligned, 0, data_len);
20164 	OS_MEMCPY(data_aligned, data, data_len);
20165 	/* Endianness to LE */
20166 	for (c = 0; c < data_len/4; c++) {
20167 		*((u_int32_t *)data_aligned + c) =
20168 			qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c));
20169 	}
20170 
20171 	/* Copy content to event->data */
20172 	OS_MEMCPY(data, data_aligned, data_len);
20173 
20174 	/* clean up allocated space */
20175 	qdf_mem_free(data_unaligned);
20176 	data_aligned = NULL;
20177 	data_unaligned = NULL;
20178 
20179 	/*************************************************************/
20180 
20181 	return QDF_STATUS_SUCCESS;
20182 }
20183 #else
20184 /**
20185  * fips_conv_data_be() - DUMMY for LE platform
20186  *
20187  * Return: QDF_STATUS - success
20188  */
20189 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data)
20190 {
20191 	return QDF_STATUS_SUCCESS;
20192 }
20193 #endif
20194 
20195 /**
20196  * extract_fips_event_data_tlv() - extract fips event data
20197  * @wmi_handle: wmi handle
20198  * @param evt_buf: pointer to event buffer
20199  * @param param: pointer FIPS event params
20200  *
20201  * Return: 0 for success or error code
20202  */
20203 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle,
20204 		void *evt_buf, struct wmi_host_fips_event_param *param)
20205 {
20206 	WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf;
20207 	wmi_pdev_fips_event_fixed_param *event;
20208 
20209 	param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf;
20210 	event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param;
20211 
20212 	if (fips_conv_data_be(event->data_len, param_buf->data) !=
20213 							QDF_STATUS_SUCCESS)
20214 		return QDF_STATUS_E_FAILURE;
20215 
20216 	param->data = (uint32_t *)param_buf->data;
20217 	param->data_len = event->data_len;
20218 	param->error_status = event->error_status;
20219 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20220 								event->pdev_id);
20221 
20222 	return QDF_STATUS_SUCCESS;
20223 }
20224 
20225 /*
20226  * extract_peer_delete_response_event_tlv() - extract peer delete response event
20227  * @wmi_handle: wmi handle
20228  * @param evt_buf: pointer to event buffer
20229  * @param vdev_id: Pointer to hold vdev_id
20230  * @param mac_addr: Pointer to hold peer mac address
20231  *
20232  * Return: QDF_STATUS_SUCCESS for success or error code
20233  */
20234 static QDF_STATUS extract_peer_delete_response_event_tlv(wmi_unified_t wmi_hdl,
20235 	void *evt_buf, struct wmi_host_peer_delete_response_event *param)
20236 {
20237 	WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf;
20238 	wmi_peer_delete_resp_event_fixed_param *ev;
20239 
20240 	param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)evt_buf;
20241 
20242 	ev = (wmi_peer_delete_resp_event_fixed_param *) param_buf->fixed_param;
20243 	if (!ev) {
20244 		WMI_LOGE("%s: Invalid peer_delete response\n", __func__);
20245 		return QDF_STATUS_E_FAILURE;
20246 	}
20247 
20248 	param->vdev_id = ev->vdev_id;
20249 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr,
20250 			&param->mac_address.bytes[0]);
20251 
20252 	return QDF_STATUS_SUCCESS;
20253 }
20254 
20255 static bool is_management_record_tlv(uint32_t cmd_id)
20256 {
20257 	if ((cmd_id == WMI_MGMT_TX_COMPLETION_EVENTID) ||
20258 			(cmd_id == WMI_MGMT_TX_SEND_CMDID) ||
20259 			(cmd_id == WMI_OFFCHAN_DATA_TX_SEND_CMDID)) {
20260 		return true;
20261 	}
20262 
20263 	return false;
20264 }
20265 
20266 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf)
20267 {
20268 	wmi_vdev_set_param_cmd_fixed_param *set_cmd;
20269 
20270 	set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf);
20271 
20272 	switch (set_cmd->param_id) {
20273 	case WMI_VDEV_PARAM_LISTEN_INTERVAL:
20274 	case WMI_VDEV_PARAM_DTIM_POLICY:
20275 		return HTC_TX_PACKET_TAG_AUTO_PM;
20276 	default:
20277 		break;
20278 	}
20279 
20280 	return 0;
20281 }
20282 
20283 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf)
20284 {
20285 	wmi_sta_powersave_param_cmd_fixed_param *ps_cmd;
20286 
20287 	ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf);
20288 
20289 	switch (ps_cmd->param) {
20290 	case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD:
20291 	case WMI_STA_PS_PARAM_INACTIVITY_TIME:
20292 	case WMI_STA_PS_ENABLE_QPOWER:
20293 		return HTC_TX_PACKET_TAG_AUTO_PM;
20294 	default:
20295 		break;
20296 	}
20297 
20298 	return 0;
20299 }
20300 
20301 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf,
20302 				   uint32_t cmd_id)
20303 {
20304 	if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended))
20305 		return 0;
20306 
20307 	switch (cmd_id) {
20308 	case WMI_VDEV_SET_PARAM_CMDID:
20309 		return wmi_tag_vdev_set_cmd(wmi_hdl, buf);
20310 	case WMI_STA_POWERSAVE_PARAM_CMDID:
20311 		return wmi_tag_sta_powersave_cmd(wmi_hdl, buf);
20312 	default:
20313 		break;
20314 	}
20315 
20316 	return 0;
20317 }
20318 
20319 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle)
20320 {
20321 	uint16_t tag = 0;
20322 
20323 	if (qdf_atomic_read(&wmi_handle->is_target_suspended)) {
20324 		pr_err("%s: Target is already suspended, Ignore FW Hang Command\n",
20325 			__func__);
20326 		return tag;
20327 	}
20328 
20329 	if (wmi_handle->tag_crash_inject)
20330 		tag = HTC_TX_PACKET_TAG_AUTO_PM;
20331 
20332 	wmi_handle->tag_crash_inject = false;
20333 	return tag;
20334 }
20335 
20336 /**
20337  * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands
20338  * @wmi_handle: WMI handle
20339  * @buf:	WMI buffer
20340  * @cmd_id:	WMI command Id
20341  *
20342  * Return htc_tx_tag
20343  */
20344 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle,
20345 				wmi_buf_t buf,
20346 				uint32_t cmd_id)
20347 {
20348 	uint16_t htc_tx_tag = 0;
20349 
20350 	switch (cmd_id) {
20351 	case WMI_WOW_ENABLE_CMDID:
20352 	case WMI_PDEV_SUSPEND_CMDID:
20353 	case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID:
20354 	case WMI_WOW_ADD_WAKE_PATTERN_CMDID:
20355 	case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID:
20356 	case WMI_PDEV_RESUME_CMDID:
20357 	case WMI_WOW_DEL_WAKE_PATTERN_CMDID:
20358 	case WMI_WOW_SET_ACTION_WAKE_UP_CMDID:
20359 #ifdef FEATURE_WLAN_D0WOW
20360 	case WMI_D0_WOW_ENABLE_DISABLE_CMDID:
20361 #endif
20362 		htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM;
20363 		break;
20364 	case WMI_FORCE_FW_HANG_CMDID:
20365 		htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle);
20366 		break;
20367 	case WMI_VDEV_SET_PARAM_CMDID:
20368 	case WMI_STA_POWERSAVE_PARAM_CMDID:
20369 		htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id);
20370 	default:
20371 		break;
20372 	}
20373 
20374 	return htc_tx_tag;
20375 }
20376 
20377 /**
20378  * extract_channel_hopping_event_tlv() - extract channel hopping param
20379  * from event
20380  * @wmi_handle: wmi handle
20381  * @param evt_buf: pointer to event buffer
20382  * @param ch_hopping: Pointer to hold channel hopping param
20383  *
20384  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20385  */
20386 static QDF_STATUS extract_channel_hopping_event_tlv(
20387 	wmi_unified_t wmi_handle, void *evt_buf,
20388 	wmi_host_pdev_channel_hopping_event *ch_hopping)
20389 {
20390 	WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *param_buf;
20391 	wmi_pdev_channel_hopping_event_fixed_param *event;
20392 
20393 	param_buf = (WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *)evt_buf;
20394 	event = (wmi_pdev_channel_hopping_event_fixed_param *)
20395 						param_buf->fixed_param;
20396 
20397 	ch_hopping->noise_floor_report_iter = event->noise_floor_report_iter;
20398 	ch_hopping->noise_floor_total_iter = event->noise_floor_total_iter;
20399 	ch_hopping->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20400 								event->pdev_id);
20401 
20402 	return QDF_STATUS_SUCCESS;
20403 }
20404 
20405 /**
20406  * extract_pdev_tpc_ev_param_tlv() - extract tpc param from event
20407  * @wmi_handle: wmi handle
20408  * @param evt_buf: pointer to event buffer
20409  * @param param: Pointer to hold tpc param
20410  *
20411  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20412  */
20413 static QDF_STATUS extract_pdev_tpc_ev_param_tlv(wmi_unified_t wmi_handle,
20414 		void *evt_buf,
20415 		wmi_host_pdev_tpc_event *param)
20416 {
20417 	WMI_PDEV_TPC_EVENTID_param_tlvs *param_buf;
20418 	wmi_pdev_tpc_event_fixed_param *event;
20419 
20420 	param_buf = (WMI_PDEV_TPC_EVENTID_param_tlvs *)evt_buf;
20421 	event = (wmi_pdev_tpc_event_fixed_param *)param_buf->fixed_param;
20422 
20423 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20424 								event->pdev_id);
20425 	qdf_mem_copy(param->tpc, param_buf->tpc, sizeof(param->tpc));
20426 
20427 	return QDF_STATUS_SUCCESS;
20428 }
20429 
20430 /**
20431  * extract_nfcal_power_ev_param_tlv() - extract noise floor calibration
20432  * power param from event
20433  * @wmi_handle: wmi handle
20434  * @param evt_buf: pointer to event buffer
20435  * @param param: Pointer to hold nf cal power param
20436  *
20437  * Return: 0 for success or error code
20438  */
20439 static QDF_STATUS
20440 extract_nfcal_power_ev_param_tlv(wmi_unified_t wmi_handle,
20441 				 void *evt_buf,
20442 				 wmi_host_pdev_nfcal_power_all_channels_event *param)
20443 {
20444 	WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *param_buf;
20445 	wmi_pdev_nfcal_power_all_channels_event_fixed_param *event;
20446 	wmi_pdev_nfcal_power_all_channels_nfdBr *ch_nfdbr;
20447 	wmi_pdev_nfcal_power_all_channels_nfdBm *ch_nfdbm;
20448 	wmi_pdev_nfcal_power_all_channels_freqNum *ch_freqnum;
20449 	uint32_t i;
20450 
20451 	param_buf =
20452 		(WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *)evt_buf;
20453 	event = param_buf->fixed_param;
20454 	ch_nfdbr = param_buf->nfdbr;
20455 	ch_nfdbm = param_buf->nfdbm;
20456 	ch_freqnum = param_buf->freqnum;
20457 
20458 	WMI_LOGD("pdev_id[%x], num_nfdbr[%d], num_nfdbm[%d] num_freqnum[%d]\n",
20459 		 event->pdev_id, param_buf->num_nfdbr,
20460 		 param_buf->num_nfdbm, param_buf->num_freqnum);
20461 
20462 	if (param_buf->num_nfdbr >
20463 	    WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) {
20464 		WMI_LOGE("invalid number of nfdBr");
20465 		return QDF_STATUS_E_FAILURE;
20466 	}
20467 
20468 	if (param_buf->num_nfdbm >
20469 	    WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) {
20470 		WMI_LOGE("invalid number of nfdBm");
20471 		return QDF_STATUS_E_FAILURE;
20472 	}
20473 
20474 	if (param_buf->num_freqnum > WMI_HOST_RXG_CAL_CHAN_MAX) {
20475 		WMI_LOGE("invalid number of freqNum");
20476 		return QDF_STATUS_E_FAILURE;
20477 	}
20478 
20479 	for (i = 0; i < param_buf->num_nfdbr; i++) {
20480 		param->nfdbr[i] = (int8_t)ch_nfdbr->nfdBr;
20481 		param->nfdbm[i] = (int8_t)ch_nfdbm->nfdBm;
20482 		ch_nfdbr++;
20483 		ch_nfdbm++;
20484 	}
20485 
20486 	for (i = 0; i < param_buf->num_freqnum; i++) {
20487 		param->freqnum[i] = ch_freqnum->freqNum;
20488 		ch_freqnum++;
20489 	}
20490 
20491 	param->pdev_id = wmi_handle->ops->
20492 		convert_pdev_id_target_to_host(event->pdev_id);
20493 
20494 	return QDF_STATUS_SUCCESS;
20495 }
20496 
20497 
20498 #ifdef BIG_ENDIAN_HOST
20499 /**
20500  * wds_addr_ev_conv_data_be() - LE to BE conversion of wds addr event
20501  * @param data_len - data length
20502  * @param data - pointer to data
20503  *
20504  * Return: QDF_STATUS - success or error status
20505  */
20506 static QDF_STATUS wds_addr_ev_conv_data_be(uint16_t data_len, uint8_t *ev)
20507 {
20508 	uint8_t *datap = (uint8_t *)ev;
20509 	int i;
20510 	/* Skip swapping the first word */
20511 	datap += sizeof(uint32_t);
20512 	for (i = 0; i < ((data_len / sizeof(uint32_t))-1);
20513 			i++, datap += sizeof(uint32_t)) {
20514 		*(uint32_t *)datap = qdf_le32_to_cpu(*(uint32_t *)datap);
20515 	}
20516 
20517 	return QDF_STATUS_SUCCESS;
20518 }
20519 #else
20520 /**
20521  * wds_addr_ev_conv_data_be() - Dummy operation for LE platforms
20522  * @param data_len - data length
20523  * @param data - pointer to data
20524  *
20525  * Return: QDF_STATUS - success or error status
20526  */
20527 static QDF_STATUS wds_addr_ev_conv_data_be(uint32_t data_len, uint8_t *ev)
20528 {
20529 	return QDF_STATUS_SUCCESS;
20530 }
20531 #endif
20532 
20533 /**
20534  * extract_wds_addr_event_tlv() - extract wds address from event
20535  * @wmi_handle: wmi handle
20536  * @param evt_buf: pointer to event buffer
20537  * @param wds_ev: Pointer to hold wds address
20538  *
20539  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20540  */
20541 static QDF_STATUS extract_wds_addr_event_tlv(wmi_unified_t wmi_handle,
20542 		void *evt_buf,
20543 		uint16_t len, wds_addr_event_t *wds_ev)
20544 {
20545 	WMI_WDS_PEER_EVENTID_param_tlvs *param_buf;
20546 	wmi_wds_addr_event_fixed_param *ev;
20547 	int i;
20548 
20549 	param_buf = (WMI_WDS_PEER_EVENTID_param_tlvs *)evt_buf;
20550 	ev = (wmi_wds_addr_event_fixed_param *)param_buf->fixed_param;
20551 
20552 	if (wds_addr_ev_conv_data_be(len, (uint8_t *)ev) != QDF_STATUS_SUCCESS)
20553 		return QDF_STATUS_E_FAILURE;
20554 
20555 	qdf_mem_copy(wds_ev->event_type, ev->event_type,
20556 		     sizeof(wds_ev->event_type));
20557 	for (i = 0; i < 4; i++) {
20558 		wds_ev->peer_mac[i] =
20559 			((u_int8_t *)&(ev->peer_mac.mac_addr31to0))[i];
20560 		wds_ev->dest_mac[i] =
20561 			((u_int8_t *)&(ev->dest_mac.mac_addr31to0))[i];
20562 	}
20563 	for (i = 0; i < 2; i++) {
20564 		wds_ev->peer_mac[4+i] =
20565 			((u_int8_t *)&(ev->peer_mac.mac_addr47to32))[i];
20566 		wds_ev->dest_mac[4+i] =
20567 			((u_int8_t *)&(ev->dest_mac.mac_addr47to32))[i];
20568 	}
20569 	return QDF_STATUS_SUCCESS;
20570 }
20571 
20572 /**
20573  * extract_peer_sta_ps_statechange_ev_tlv() - extract peer sta ps state
20574  * from event
20575  * @wmi_handle: wmi handle
20576  * @param evt_buf: pointer to event buffer
20577  * @param ev: Pointer to hold peer param and ps state
20578  *
20579  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20580  */
20581 static QDF_STATUS extract_peer_sta_ps_statechange_ev_tlv(wmi_unified_t wmi_handle,
20582 		void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev)
20583 {
20584 	WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf;
20585 	wmi_peer_sta_ps_statechange_event_fixed_param *event;
20586 
20587 	param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)evt_buf;
20588 	event = (wmi_peer_sta_ps_statechange_event_fixed_param *)
20589 						param_buf->fixed_param;
20590 
20591 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, ev->peer_macaddr);
20592 	ev->peer_ps_state = event->peer_ps_state;
20593 
20594 	return QDF_STATUS_SUCCESS;
20595 }
20596 
20597 /**
20598  * extract_inst_rssi_stats_event_tlv() - extract inst rssi stats from event
20599  * @wmi_handle: wmi handle
20600  * @param evt_buf: pointer to event buffer
20601  * @param inst_rssi_resp: Pointer to hold inst rssi response
20602  *
20603  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20604  */
20605 static QDF_STATUS extract_inst_rssi_stats_event_tlv(
20606 	wmi_unified_t wmi_handle, void *evt_buf,
20607 	wmi_host_inst_stats_resp *inst_rssi_resp)
20608 {
20609 	WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf;
20610 	wmi_inst_rssi_stats_resp_fixed_param *event;
20611 
20612 	param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf;
20613 	event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param;
20614 
20615 	qdf_mem_copy(&(inst_rssi_resp->peer_macaddr),
20616 		     &(event->peer_macaddr), sizeof(wmi_mac_addr));
20617 	inst_rssi_resp->iRSSI = event->iRSSI;
20618 
20619 	return QDF_STATUS_SUCCESS;
20620 }
20621 
20622 static struct cur_reg_rule
20623 *create_reg_rules_from_wmi(uint32_t num_reg_rules,
20624 		wmi_regulatory_rule_struct *wmi_reg_rule)
20625 {
20626 	struct cur_reg_rule *reg_rule_ptr;
20627 	uint32_t count;
20628 
20629 	reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr));
20630 
20631 	if (NULL == reg_rule_ptr) {
20632 		WMI_LOGE("memory allocation failure");
20633 		return NULL;
20634 	}
20635 
20636 	for (count = 0; count < num_reg_rules; count++) {
20637 		reg_rule_ptr[count].start_freq =
20638 			WMI_REG_RULE_START_FREQ_GET(
20639 					wmi_reg_rule[count].freq_info);
20640 		reg_rule_ptr[count].end_freq =
20641 			WMI_REG_RULE_END_FREQ_GET(
20642 					wmi_reg_rule[count].freq_info);
20643 		reg_rule_ptr[count].max_bw =
20644 			WMI_REG_RULE_MAX_BW_GET(
20645 					wmi_reg_rule[count].bw_pwr_info);
20646 		reg_rule_ptr[count].reg_power =
20647 			WMI_REG_RULE_REG_POWER_GET(
20648 					wmi_reg_rule[count].bw_pwr_info);
20649 		reg_rule_ptr[count].ant_gain =
20650 			WMI_REG_RULE_ANTENNA_GAIN_GET(
20651 					wmi_reg_rule[count].bw_pwr_info);
20652 		reg_rule_ptr[count].flags =
20653 			WMI_REG_RULE_FLAGS_GET(
20654 					wmi_reg_rule[count].flag_info);
20655 	}
20656 
20657 	return reg_rule_ptr;
20658 }
20659 
20660 static QDF_STATUS extract_reg_chan_list_update_event_tlv(
20661 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
20662 	struct cur_regulatory_info *reg_info, uint32_t len)
20663 {
20664 	WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf;
20665 	wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr;
20666 	wmi_regulatory_rule_struct *wmi_reg_rule;
20667 	uint32_t num_2g_reg_rules, num_5g_reg_rules;
20668 
20669 	WMI_LOGD("processing regulatory channel list");
20670 
20671 	param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf;
20672 	if (!param_buf) {
20673 		WMI_LOGE("invalid channel list event buf");
20674 		return QDF_STATUS_E_FAILURE;
20675 	}
20676 
20677 	chan_list_event_hdr = param_buf->fixed_param;
20678 
20679 	reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules;
20680 	reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules;
20681 	qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2),
20682 		     REG_ALPHA2_LEN);
20683 	reg_info->dfs_region = chan_list_event_hdr->dfs_region;
20684 	reg_info->phybitmap = chan_list_event_hdr->phybitmap;
20685 	reg_info->offload_enabled = true;
20686 	reg_info->num_phy = chan_list_event_hdr->num_phy;
20687 	reg_info->phy_id = chan_list_event_hdr->phy_id;
20688 	reg_info->ctry_code = chan_list_event_hdr->country_id;
20689 	reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code;
20690 	if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS)
20691 		reg_info->status_code = REG_SET_CC_STATUS_PASS;
20692 	else if (chan_list_event_hdr->status_code ==
20693 		 WMI_REG_CURRENT_ALPHA2_NOT_FOUND)
20694 		reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND;
20695 	else if (chan_list_event_hdr->status_code ==
20696 		 WMI_REG_INIT_ALPHA2_NOT_FOUND)
20697 		reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND;
20698 	else if (chan_list_event_hdr->status_code ==
20699 		 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED)
20700 		reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED;
20701 	else if (chan_list_event_hdr->status_code ==
20702 		 WMI_REG_SET_CC_STATUS_NO_MEMORY)
20703 		reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY;
20704 	else if (chan_list_event_hdr->status_code ==
20705 		 WMI_REG_SET_CC_STATUS_FAIL)
20706 		reg_info->status_code = REG_SET_CC_STATUS_FAIL;
20707 
20708 	reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g;
20709 	reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g;
20710 	reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g;
20711 	reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g;
20712 
20713 	num_2g_reg_rules = reg_info->num_2g_reg_rules;
20714 	num_5g_reg_rules = reg_info->num_5g_reg_rules;
20715 
20716 	WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d",
20717 			__func__, reg_info->alpha2, reg_info->dfs_region,
20718 			reg_info->min_bw_2g, reg_info->max_bw_2g,
20719 			reg_info->min_bw_5g, reg_info->max_bw_5g);
20720 
20721 	WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__,
20722 			num_2g_reg_rules, num_5g_reg_rules);
20723 	wmi_reg_rule =
20724 		(wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr
20725 			+ sizeof(wmi_reg_chan_list_cc_event_fixed_param)
20726 			+ WMI_TLV_HDR_SIZE);
20727 	reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules,
20728 			wmi_reg_rule);
20729 	wmi_reg_rule += num_2g_reg_rules;
20730 
20731 	reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules,
20732 			wmi_reg_rule);
20733 
20734 	WMI_LOGD("processed regulatory channel list");
20735 
20736 	return QDF_STATUS_SUCCESS;
20737 }
20738 
20739 static QDF_STATUS extract_reg_11d_new_country_event_tlv(
20740 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
20741 	struct reg_11d_new_country *reg_11d_country, uint32_t len)
20742 {
20743 	wmi_11d_new_country_event_fixed_param *reg_11d_country_event;
20744 	WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf;
20745 
20746 	param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf;
20747 	if (!param_buf) {
20748 		WMI_LOGE("invalid 11d country event buf");
20749 		return QDF_STATUS_E_FAILURE;
20750 	}
20751 
20752 	reg_11d_country_event = param_buf->fixed_param;
20753 
20754 	qdf_mem_copy(reg_11d_country->alpha2,
20755 			&reg_11d_country_event->new_alpha2, REG_ALPHA2_LEN);
20756 
20757 	WMI_LOGD("processed 11d country event, new cc %s",
20758 			reg_11d_country->alpha2);
20759 
20760 	return QDF_STATUS_SUCCESS;
20761 }
20762 
20763 static QDF_STATUS extract_reg_ch_avoid_event_tlv(
20764 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
20765 	struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len)
20766 {
20767 	wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param;
20768 	wmi_avoid_freq_range_desc *afr_desc;
20769 	uint32_t num_freq_ranges, freq_range_idx;
20770 	WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf =
20771 		(WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf;
20772 
20773 	if (!param_buf) {
20774 		WMI_LOGE("Invalid channel avoid event buffer");
20775 		return QDF_STATUS_E_INVAL;
20776 	}
20777 
20778 	afr_fixed_param = param_buf->fixed_param;
20779 	if (!afr_fixed_param) {
20780 		WMI_LOGE("Invalid channel avoid event fixed param buffer");
20781 		return QDF_STATUS_E_INVAL;
20782 	}
20783 
20784 	if (!ch_avoid_ind) {
20785 		WMI_LOGE("Invalid channel avoid indication buffer");
20786 		return QDF_STATUS_E_INVAL;
20787 	}
20788 	num_freq_ranges = (afr_fixed_param->num_freq_ranges >
20789 			CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE :
20790 			afr_fixed_param->num_freq_ranges;
20791 
20792 	WMI_LOGD("Channel avoid event received with %d ranges",
20793 		 num_freq_ranges);
20794 
20795 	ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges;
20796 	afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range);
20797 	for (freq_range_idx = 0; freq_range_idx < num_freq_ranges;
20798 	     freq_range_idx++) {
20799 		ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq =
20800 			afr_desc->start_freq;
20801 		ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq =
20802 			afr_desc->end_freq;
20803 		WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u",
20804 				freq_range_idx, afr_desc->tlv_header,
20805 				afr_desc->start_freq, afr_desc->end_freq);
20806 		afr_desc++;
20807 	}
20808 
20809 	return QDF_STATUS_SUCCESS;
20810 }
20811 #ifdef DFS_COMPONENT_ENABLE
20812 /**
20813  * extract_dfs_cac_complete_event_tlv() - extract cac complete event
20814  * @wmi_handle: wma handle
20815  * @evt_buf: event buffer
20816  * @vdev_id: vdev id
20817  * @len: length of buffer
20818  *
20819  * Return: 0 for success or error code
20820  */
20821 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle,
20822 		uint8_t *evt_buf,
20823 		uint32_t *vdev_id,
20824 		uint32_t len)
20825 {
20826 	WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs;
20827 	wmi_vdev_dfs_cac_complete_event_fixed_param  *cac_event;
20828 
20829 	param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf;
20830 	if (!param_tlvs) {
20831 		WMI_LOGE("invalid cac complete event buf");
20832 		return QDF_STATUS_E_FAILURE;
20833 	}
20834 
20835 	cac_event = param_tlvs->fixed_param;
20836 	*vdev_id = cac_event->vdev_id;
20837 	WMI_LOGD("processed cac complete event vdev %d", *vdev_id);
20838 
20839 	return QDF_STATUS_SUCCESS;
20840 }
20841 
20842 /**
20843  * extract_dfs_radar_detection_event_tlv() - extract radar found event
20844  * @wmi_handle: wma handle
20845  * @evt_buf: event buffer
20846  * @radar_found: radar found event info
20847  * @len: length of buffer
20848  *
20849  * Return: 0 for success or error code
20850  */
20851 static QDF_STATUS extract_dfs_radar_detection_event_tlv(
20852 		wmi_unified_t wmi_handle,
20853 		uint8_t *evt_buf,
20854 		struct radar_found_info *radar_found,
20855 		uint32_t len)
20856 {
20857 	WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv;
20858 	wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event;
20859 
20860 	param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf;
20861 	if (!param_tlv) {
20862 		WMI_LOGE("invalid radar detection event buf");
20863 		return QDF_STATUS_E_FAILURE;
20864 	}
20865 
20866 	radar_event = param_tlv->fixed_param;
20867 	radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id(
20868 			radar_event->pdev_id);
20869 	radar_found->detection_mode = radar_event->detection_mode;
20870 	radar_found->chan_freq = radar_event->chan_freq;
20871 	radar_found->chan_width = radar_event->chan_width;
20872 	radar_found->detector_id = radar_event->detector_id;
20873 	radar_found->segment_id = radar_event->segment_id;
20874 	radar_found->timestamp = radar_event->timestamp;
20875 	radar_found->is_chirp = radar_event->is_chirp;
20876 	radar_found->freq_offset = radar_event->freq_offset;
20877 	radar_found->sidx = radar_event->sidx;
20878 
20879 	WMI_LOGI("processed radar found event pdev %d,"
20880 		"Radar Event Info:pdev_id %d,timestamp %d,chan_freq  (dur) %d,"
20881 		"chan_width (RSSI) %d,detector_id (false_radar) %d,"
20882 		"freq_offset (radar_check) %d,segment_id %d,sidx %d,"
20883 		"is_chirp %d,detection mode %d\n",
20884 		radar_event->pdev_id, radar_found->pdev_id,
20885 		radar_event->timestamp, radar_event->chan_freq,
20886 		radar_event->chan_width, radar_event->detector_id,
20887 		radar_event->freq_offset, radar_event->segment_id,
20888 		radar_event->sidx, radar_event->is_chirp,
20889 		radar_event->detection_mode);
20890 
20891 	return QDF_STATUS_SUCCESS;
20892 }
20893 
20894 #ifdef QCA_MCL_DFS_SUPPORT
20895 /**
20896  * extract_wlan_radar_event_info_tlv() - extract radar pulse event
20897  * @wmi_handle: wma handle
20898  * @evt_buf: event buffer
20899  * @wlan_radar_event: Pointer to struct radar_event_info
20900  * @len: length of buffer
20901  *
20902  * Return: QDF_STATUS
20903  */
20904 static QDF_STATUS extract_wlan_radar_event_info_tlv(
20905 		wmi_unified_t wmi_handle,
20906 		uint8_t *evt_buf,
20907 		struct radar_event_info *wlan_radar_event,
20908 		uint32_t len)
20909 {
20910 	WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv;
20911 	wmi_dfs_radar_event_fixed_param *radar_event;
20912 
20913 	param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf;
20914 	if (!param_tlv) {
20915 		WMI_LOGE("invalid wlan radar event buf");
20916 		return QDF_STATUS_E_FAILURE;
20917 	}
20918 
20919 	radar_event = param_tlv->fixed_param;
20920 	wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp;
20921 	wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq;
20922 	wlan_radar_event->pulse_duration = radar_event->pulse_duration;
20923 	wlan_radar_event->rssi = radar_event->rssi;
20924 	wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts;
20925 	wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high;
20926 	wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low;
20927 	wlan_radar_event->peak_sidx = radar_event->peak_sidx;
20928 	wlan_radar_event->delta_peak = radar_event->pulse_delta_peak;
20929 	wlan_radar_event->delta_diff = radar_event->pulse_delta_diff;
20930 	if (radar_event->pulse_flags &
20931 			WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) {
20932 		wlan_radar_event->is_psidx_diff_valid = true;
20933 		wlan_radar_event->psidx_diff = radar_event->psidx_diff;
20934 	} else {
20935 		wlan_radar_event->is_psidx_diff_valid = false;
20936 	}
20937 
20938 	wlan_radar_event->pdev_id = radar_event->pdev_id;
20939 
20940 	return QDF_STATUS_SUCCESS;
20941 }
20942 #else
20943 static QDF_STATUS extract_wlan_radar_event_info_tlv(
20944 		wmi_unified_t wmi_handle,
20945 		uint8_t *evt_buf,
20946 		struct radar_event_info *wlan_radar_event,
20947 		uint32_t len)
20948 {
20949 	return QDF_STATUS_SUCCESS;
20950 }
20951 #endif
20952 #endif
20953 
20954 /**
20955  * send_get_rcpi_cmd_tlv() - send request for rcpi value
20956  * @wmi_handle: wmi handle
20957  * @get_rcpi_param: rcpi params
20958  *
20959  * Return: QDF status
20960  */
20961 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle,
20962 					struct rcpi_req  *get_rcpi_param)
20963 {
20964 	wmi_buf_t buf;
20965 	wmi_request_rcpi_cmd_fixed_param *cmd;
20966 	uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param);
20967 
20968 	buf = wmi_buf_alloc(wmi_handle, len);
20969 	if (!buf) {
20970 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
20971 		return QDF_STATUS_E_NOMEM;
20972 	}
20973 
20974 	cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf);
20975 	WMITLV_SET_HDR(&cmd->tlv_header,
20976 		       WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param,
20977 		       WMITLV_GET_STRUCT_TLVLEN
20978 		       (wmi_request_rcpi_cmd_fixed_param));
20979 
20980 	cmd->vdev_id = get_rcpi_param->vdev_id;
20981 	WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr,
20982 				   &cmd->peer_macaddr);
20983 
20984 	switch (get_rcpi_param->measurement_type) {
20985 
20986 	case RCPI_MEASUREMENT_TYPE_AVG_MGMT:
20987 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT;
20988 		break;
20989 
20990 	case RCPI_MEASUREMENT_TYPE_AVG_DATA:
20991 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA;
20992 		break;
20993 
20994 	case RCPI_MEASUREMENT_TYPE_LAST_MGMT:
20995 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT;
20996 		break;
20997 
20998 	case RCPI_MEASUREMENT_TYPE_LAST_DATA:
20999 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA;
21000 		break;
21001 
21002 	default:
21003 		/*
21004 		 * invalid rcpi measurement type, fall back to
21005 		 * RCPI_MEASUREMENT_TYPE_AVG_MGMT
21006 		 */
21007 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT;
21008 		break;
21009 	}
21010 	WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id);
21011 	wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0);
21012 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21013 				 WMI_REQUEST_RCPI_CMDID)) {
21014 
21015 		WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID",
21016 			 __func__);
21017 		wmi_buf_free(buf);
21018 		return QDF_STATUS_E_FAILURE;
21019 	}
21020 
21021 	return QDF_STATUS_SUCCESS;
21022 }
21023 
21024 /**
21025  * extract_rcpi_response_event_tlv() - Extract RCPI event params
21026  * @wmi_handle: wmi handle
21027  * @evt_buf: pointer to event buffer
21028  * @res: pointer to hold rcpi response from firmware
21029  *
21030  * Return: QDF_STATUS_SUCCESS for successful event parse
21031  *         else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE
21032  */
21033 static QDF_STATUS
21034 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle,
21035 				void *evt_buf, struct rcpi_res *res)
21036 {
21037 	WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf;
21038 	wmi_update_rcpi_event_fixed_param *event;
21039 
21040 	param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf;
21041 	if (!param_buf) {
21042 		WMI_LOGE(FL("Invalid rcpi event"));
21043 		return QDF_STATUS_E_INVAL;
21044 	}
21045 
21046 	event = param_buf->fixed_param;
21047 	res->vdev_id = event->vdev_id;
21048 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr);
21049 
21050 	switch (event->measurement_type) {
21051 
21052 	case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT:
21053 		res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT;
21054 		break;
21055 
21056 	case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA:
21057 		res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA;
21058 		break;
21059 
21060 	case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT:
21061 		res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT;
21062 		break;
21063 
21064 	case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA:
21065 		res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA;
21066 		break;
21067 
21068 	default:
21069 		WMI_LOGE(FL("Invalid rcpi measurement type from firmware"));
21070 		res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID;
21071 		return QDF_STATUS_E_FAILURE;
21072 	}
21073 
21074 	if (event->status)
21075 		return QDF_STATUS_E_FAILURE;
21076 	else
21077 		return QDF_STATUS_SUCCESS;
21078 }
21079 
21080 /**
21081  * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from
21082  *           host to target defines. For legacy there is not conversion
21083  *           required. Just return pdev_id as it is.
21084  * @param pdev_id: host pdev_id to be converted.
21085  * Return: target pdev_id after conversion.
21086  */
21087 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy(
21088 							uint32_t pdev_id)
21089 {
21090 	if (pdev_id == WMI_HOST_PDEV_ID_SOC)
21091 		return WMI_PDEV_ID_SOC;
21092 
21093 	/*No conversion required*/
21094 	return pdev_id;
21095 }
21096 
21097 /**
21098  * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from
21099  *           target to host defines. For legacy there is not conversion
21100  *           required. Just return pdev_id as it is.
21101  * @param pdev_id: target pdev_id to be converted.
21102  * Return: host pdev_id after conversion.
21103  */
21104 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy(
21105 							uint32_t pdev_id)
21106 {
21107 	/*No conversion required*/
21108 	return pdev_id;
21109 }
21110 
21111 /**
21112  *  send_set_country_cmd_tlv() - WMI scan channel list function
21113  *  @param wmi_handle      : handle to WMI.
21114  *  @param param    : pointer to hold scan channel list parameter
21115  *
21116  *  Return: 0  on success and -ve on failure.
21117  */
21118 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle,
21119 				struct set_country *params)
21120 {
21121 	wmi_buf_t buf;
21122 	QDF_STATUS qdf_status;
21123 	wmi_set_current_country_cmd_fixed_param *cmd;
21124 	uint16_t len = sizeof(*cmd);
21125 
21126 	buf = wmi_buf_alloc(wmi_handle, len);
21127 	if (!buf) {
21128 		WMI_LOGE("Failed to allocate memory");
21129 		qdf_status = QDF_STATUS_E_NOMEM;
21130 		goto end;
21131 	}
21132 
21133 	cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf);
21134 	WMITLV_SET_HDR(&cmd->tlv_header,
21135 		       WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param,
21136 		       WMITLV_GET_STRUCT_TLVLEN
21137 			       (wmi_set_current_country_cmd_fixed_param));
21138 
21139 	WMI_LOGD("setting cuurnet country to  %s", params->country);
21140 
21141 	qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3);
21142 
21143 	cmd->pdev_id = params->pdev_id;
21144 
21145 	wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0);
21146 	qdf_status = wmi_unified_cmd_send(wmi_handle,
21147 			buf, len, WMI_SET_CURRENT_COUNTRY_CMDID);
21148 
21149 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
21150 		WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID");
21151 		wmi_buf_free(buf);
21152 	}
21153 
21154 end:
21155 	return qdf_status;
21156 }
21157 
21158 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2)          do { \
21159 	    WMI_SET_BITS(alpha, 0, 8, val0); \
21160 	    WMI_SET_BITS(alpha, 8, 8, val1); \
21161 	    WMI_SET_BITS(alpha, 16, 8, val2); \
21162 	    } while (0)
21163 
21164 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle,
21165 		uint8_t pdev_id, struct cc_regdmn_s *rd)
21166 {
21167 	wmi_set_init_country_cmd_fixed_param *cmd;
21168 	uint16_t len;
21169 	wmi_buf_t buf;
21170 	int ret;
21171 
21172 	len = sizeof(wmi_set_init_country_cmd_fixed_param);
21173 	buf = wmi_buf_alloc(wmi_handle, len);
21174 	if (!buf) {
21175 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
21176 		return QDF_STATUS_E_NOMEM;
21177 	}
21178 	cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf);
21179 	WMITLV_SET_HDR(&cmd->tlv_header,
21180 			WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param,
21181 			WMITLV_GET_STRUCT_TLVLEN
21182 			(wmi_set_init_country_cmd_fixed_param));
21183 
21184 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
21185 
21186 	if (rd->flags == CC_IS_SET) {
21187 		cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID;
21188 		cmd->country_code.country_id = rd->cc.country_code;
21189 	} else if (rd->flags == ALPHA_IS_SET) {
21190 		cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2;
21191 		WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2,
21192 				rd->cc.alpha[0],
21193 				rd->cc.alpha[1],
21194 				rd->cc.alpha[2]);
21195 	} else if (rd->flags == REGDMN_IS_SET) {
21196 		cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE;
21197 		cmd->country_code.domain_code = rd->cc.regdmn_id;
21198 	}
21199 
21200 	wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0);
21201 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
21202 			WMI_SET_INIT_COUNTRY_CMDID);
21203 	if (ret) {
21204 		WMI_LOGE("Failed to config wow wakeup event");
21205 		wmi_buf_free(buf);
21206 		return QDF_STATUS_E_FAILURE;
21207 	}
21208 
21209 	return QDF_STATUS_SUCCESS;
21210 }
21211 
21212 /**
21213  * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan
21214  * configuration params
21215  * @wmi_handle: wmi handler
21216  * @limit_off_chan_param: pointer to wmi_off_chan_param
21217  *
21218  * Return: 0 for success and non zero for failure
21219  */
21220 static
21221 QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle,
21222 		struct wmi_limit_off_chan_param *limit_off_chan_param)
21223 {
21224 	wmi_vdev_limit_offchan_cmd_fixed_param *cmd;
21225 	wmi_buf_t buf;
21226 	uint32_t len = sizeof(*cmd);
21227 	int err;
21228 
21229 	buf = wmi_buf_alloc(wmi_handle, len);
21230 	if (!buf) {
21231 		WMI_LOGP("%s: failed to allocate memory for limit off chan cmd",
21232 				__func__);
21233 		return QDF_STATUS_E_NOMEM;
21234 	}
21235 
21236 	cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf);
21237 
21238 	WMITLV_SET_HDR(&cmd->tlv_header,
21239 			WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param,
21240 			WMITLV_GET_STRUCT_TLVLEN(
21241 				wmi_vdev_limit_offchan_cmd_fixed_param));
21242 
21243 	cmd->vdev_id = limit_off_chan_param->vdev_id;
21244 
21245 	cmd->flags &= 0;
21246 	if (limit_off_chan_param->status)
21247 		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE;
21248 	if (limit_off_chan_param->skip_dfs_chans)
21249 		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS;
21250 
21251 	cmd->max_offchan_time = limit_off_chan_param->max_offchan_time;
21252 	cmd->rest_time = limit_off_chan_param->rest_time;
21253 
21254 	WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d",
21255 			__func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time,
21256 			cmd->rest_time);
21257 
21258 	wmi_mtrace(WMI_VDEV_LIMIT_OFFCHAN_CMDID, cmd->vdev_id, 0);
21259 	err = wmi_unified_cmd_send(wmi_handle, buf,
21260 			len, WMI_VDEV_LIMIT_OFFCHAN_CMDID);
21261 	if (QDF_IS_STATUS_ERROR(err)) {
21262 		WMI_LOGE("Failed to send limit off chan cmd err=%d", err);
21263 		wmi_buf_free(buf);
21264 		return QDF_STATUS_E_FAILURE;
21265 	}
21266 
21267 	return QDF_STATUS_SUCCESS;
21268 }
21269 
21270 /**
21271  * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request
21272  * @wmi_handle: wmi handler
21273  * @req_buf: set arp stats request buffer
21274  *
21275  * Return: 0 for success and non zero for failure
21276  */
21277 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
21278 					  struct set_arp_stats *req_buf)
21279 {
21280 	wmi_buf_t buf = NULL;
21281 	QDF_STATUS status;
21282 	int len;
21283 	uint8_t *buf_ptr;
21284 	wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp;
21285 
21286 	len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
21287 	if (req_buf->pkt_type_bitmap) {
21288 		len += WMI_TLV_HDR_SIZE;
21289 		len += sizeof(wmi_vdev_set_connectivity_check_stats);
21290 	}
21291 	buf = wmi_buf_alloc(wmi_handle, len);
21292 	if (!buf) {
21293 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
21294 		return QDF_STATUS_E_NOMEM;
21295 	}
21296 
21297 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21298 	wmi_set_arp =
21299 		(wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr;
21300 	WMITLV_SET_HDR(&wmi_set_arp->tlv_header,
21301 		       WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param,
21302 		       WMITLV_GET_STRUCT_TLVLEN
21303 		       (wmi_vdev_set_arp_stats_cmd_fixed_param));
21304 
21305 	/* fill in per roam config values */
21306 	wmi_set_arp->vdev_id = req_buf->vdev_id;
21307 
21308 	wmi_set_arp->set_clr = req_buf->flag;
21309 	wmi_set_arp->pkt_type = req_buf->pkt_type;
21310 	wmi_set_arp->ipv4 = req_buf->ip_addr;
21311 
21312 	WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u",
21313 			 wmi_set_arp->vdev_id, wmi_set_arp->set_clr,
21314 			 wmi_set_arp->pkt_type, wmi_set_arp->ipv4);
21315 
21316 	/*
21317 	 * pkt_type_bitmap should be non-zero to ensure
21318 	 * presence of additional stats.
21319 	 */
21320 	if (req_buf->pkt_type_bitmap) {
21321 		wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats;
21322 
21323 		buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
21324 		WMITLV_SET_HDR(buf_ptr,
21325 			   WMITLV_TAG_ARRAY_STRUC,
21326 			   sizeof(wmi_vdev_set_connectivity_check_stats));
21327 		buf_ptr += WMI_TLV_HDR_SIZE;
21328 		wmi_set_connect_stats =
21329 			(wmi_vdev_set_connectivity_check_stats *)buf_ptr;
21330 		WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header,
21331 			WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats,
21332 			WMITLV_GET_STRUCT_TLVLEN(
21333 					wmi_vdev_set_connectivity_check_stats));
21334 		wmi_set_connect_stats->pkt_type_bitmap =
21335 						req_buf->pkt_type_bitmap;
21336 		wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port;
21337 		wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port;
21338 		wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4;
21339 
21340 		WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u",
21341 			 wmi_set_connect_stats->pkt_type_bitmap,
21342 			 wmi_set_connect_stats->tcp_src_port,
21343 			 wmi_set_connect_stats->tcp_dst_port,
21344 			 wmi_set_connect_stats->icmp_ipv4);
21345 	}
21346 
21347 	/* Send per roam config parameters */
21348 	wmi_mtrace(WMI_VDEV_SET_ARP_STAT_CMDID, NO_SESSION, 0);
21349 	status = wmi_unified_cmd_send(wmi_handle, buf,
21350 				      len, WMI_VDEV_SET_ARP_STAT_CMDID);
21351 	if (QDF_IS_STATUS_ERROR(status)) {
21352 		WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d",
21353 			 status);
21354 		goto error;
21355 	}
21356 
21357 	WMI_LOGD(FL("set arp stats flag=%d, vdev=%d"),
21358 		 req_buf->flag, req_buf->vdev_id);
21359 	return QDF_STATUS_SUCCESS;
21360 error:
21361 	wmi_buf_free(buf);
21362 
21363 	return status;
21364 }
21365 
21366 /**
21367  * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request
21368  * @wmi_handle: wmi handler
21369  * @req_buf: get arp stats request buffer
21370  *
21371  * Return: 0 for success and non zero for failure
21372  */
21373 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
21374 					  struct get_arp_stats *req_buf)
21375 {
21376 	wmi_buf_t buf = NULL;
21377 	QDF_STATUS status;
21378 	int len;
21379 	uint8_t *buf_ptr;
21380 	wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats;
21381 
21382 	len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param);
21383 	buf = wmi_buf_alloc(wmi_handle, len);
21384 	if (!buf) {
21385 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
21386 		return QDF_STATUS_E_NOMEM;
21387 	}
21388 
21389 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21390 	get_arp_stats =
21391 		(wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr;
21392 	WMITLV_SET_HDR(&get_arp_stats->tlv_header,
21393 		       WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param,
21394 		       WMITLV_GET_STRUCT_TLVLEN
21395 		       (wmi_vdev_get_arp_stats_cmd_fixed_param));
21396 
21397 	/* fill in arp stats req cmd values */
21398 	get_arp_stats->vdev_id = req_buf->vdev_id;
21399 
21400 	WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id);
21401 	/* Send per roam config parameters */
21402 	wmi_mtrace(WMI_VDEV_GET_ARP_STAT_CMDID, NO_SESSION, 0);
21403 	status = wmi_unified_cmd_send(wmi_handle, buf,
21404 				      len, WMI_VDEV_GET_ARP_STAT_CMDID);
21405 	if (QDF_IS_STATUS_ERROR(status)) {
21406 		WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d",
21407 			 status);
21408 		goto error;
21409 	}
21410 
21411 	return QDF_STATUS_SUCCESS;
21412 error:
21413 	wmi_buf_free(buf);
21414 
21415 	return status;
21416 }
21417 
21418 /**
21419  * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid
21420  * @wmi_handle: wmi handler
21421  * @pmk_info: pointer to PMK cache entry
21422  * @vdev_id: vdev id
21423  *
21424  * Return: 0 for success and non zero for failure
21425  */
21426 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle,
21427 				struct wmi_unified_pmk_cache *pmk_info)
21428 {
21429 	wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd;
21430 	wmi_buf_t buf;
21431 	QDF_STATUS status;
21432 	uint8_t *buf_ptr;
21433 	wmi_pmk_cache *pmksa;
21434 	uint32_t len = sizeof(*cmd);
21435 
21436 	if (pmk_info->pmk_len)
21437 		len += WMI_TLV_HDR_SIZE + sizeof(*pmksa);
21438 
21439 	buf = wmi_buf_alloc(wmi_handle, len);
21440 	if (!buf) {
21441 		WMI_LOGP("%s: failed to allocate memory for set del pmkid cache",
21442 			 __func__);
21443 		return QDF_STATUS_E_NOMEM;
21444 	}
21445 
21446 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21447 	cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr;
21448 
21449 	WMITLV_SET_HDR(&cmd->tlv_header,
21450 		 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param,
21451 		 WMITLV_GET_STRUCT_TLVLEN(
21452 			wmi_pdev_update_pmk_cache_cmd_fixed_param));
21453 
21454 	cmd->vdev_id = pmk_info->session_id;
21455 
21456 	/* If pmk_info->pmk_len is 0, this is a flush request */
21457 	if (!pmk_info->pmk_len) {
21458 		cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL;
21459 		cmd->num_cache = 0;
21460 		goto send_cmd;
21461 	}
21462 
21463 	cmd->num_cache = 1;
21464 	buf_ptr += sizeof(*cmd);
21465 
21466 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
21467 			sizeof(*pmksa));
21468 	buf_ptr += WMI_TLV_HDR_SIZE;
21469 
21470 	pmksa = (wmi_pmk_cache *)buf_ptr;
21471 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache,
21472 			WMITLV_GET_STRUCT_TLVLEN
21473 				(wmi_pmk_cache));
21474 	pmksa->pmk_len = pmk_info->pmk_len;
21475 	qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len);
21476 	pmksa->pmkid_len = pmk_info->pmkid_len;
21477 	qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len);
21478 	qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr));
21479 	pmksa->ssid.ssid_len = pmk_info->ssid.length;
21480 	qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid),
21481 			pmksa->ssid.ssid_len);
21482 	pmksa->cache_id = pmk_info->cache_id;
21483 	pmksa->cat_flag = pmk_info->cat_flag;
21484 	pmksa->action_flag = pmk_info->action_flag;
21485 
21486 send_cmd:
21487 	wmi_mtrace(WMI_PDEV_UPDATE_PMK_CACHE_CMDID, cmd->vdev_id, 0);
21488 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
21489 			WMI_PDEV_UPDATE_PMK_CACHE_CMDID);
21490 	if (status != QDF_STATUS_SUCCESS) {
21491 		WMI_LOGE("%s: failed to send set del pmkid cache command %d",
21492 			 __func__, status);
21493 		wmi_buf_free(buf);
21494 	}
21495 
21496 	return status;
21497 }
21498 
21499 /**
21500  * send_pdev_caldata_version_check_cmd_tlv() - send caldata check cmd to fw
21501  * @wmi_handle: wmi handle
21502  * @param:	reserved param
21503  *
21504  * Return: 0 for success or error code
21505  */
21506 static QDF_STATUS
21507 send_pdev_caldata_version_check_cmd_tlv(wmi_unified_t wmi_handle,
21508 						uint32_t param)
21509 {
21510 	wmi_pdev_check_cal_version_cmd_fixed_param *cmd;
21511 	wmi_buf_t buf;
21512 	int32_t len = sizeof(wmi_pdev_check_cal_version_cmd_fixed_param);
21513 
21514 	buf = wmi_buf_alloc(wmi_handle, len);
21515 	if (!buf) {
21516 		qdf_print("%s:wmi_buf_alloc failed", __func__);
21517 		return QDF_STATUS_E_FAILURE;
21518 	}
21519 	cmd = (wmi_pdev_check_cal_version_cmd_fixed_param *)wmi_buf_data(buf);
21520 	WMITLV_SET_HDR(&cmd->tlv_header,
21521 			WMITLV_TAG_STRUC_wmi_pdev_check_cal_version_cmd_fixed_param,
21522 			WMITLV_GET_STRUCT_TLVLEN
21523 			(wmi_pdev_check_cal_version_cmd_fixed_param));
21524 	cmd->pdev_id = param; /* set to 0x0 as expected from FW */
21525 	wmi_mtrace(WMI_PDEV_CHECK_CAL_VERSION_CMDID, NO_SESSION, 0);
21526 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21527 			WMI_PDEV_CHECK_CAL_VERSION_CMDID)) {
21528 		wmi_buf_free(buf);
21529 		return QDF_STATUS_E_FAILURE;
21530 	}
21531 
21532 	return QDF_STATUS_SUCCESS;
21533 }
21534 
21535 /**
21536  * extract_pdev_caldata_version_check_ev_param_tlv() - extract caldata from event
21537  * @wmi_handle: wmi handle
21538  * @param evt_buf: pointer to event buffer
21539  * @param param: Pointer to hold peer caldata version data
21540  *
21541  * Return: 0 for success or error code
21542  */
21543 static QDF_STATUS extract_pdev_caldata_version_check_ev_param_tlv(
21544 			wmi_unified_t wmi_handle,
21545 			void *evt_buf,
21546 			wmi_host_pdev_check_cal_version_event *param)
21547 {
21548 	WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *param_tlvs;
21549 	wmi_pdev_check_cal_version_event_fixed_param *event;
21550 
21551 	param_tlvs = (WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *) evt_buf;
21552 	if (!param_tlvs) {
21553 		WMI_LOGE("invalid cal version event buf");
21554 		return QDF_STATUS_E_FAILURE;
21555 	}
21556 	event =  param_tlvs->fixed_param;
21557 	if (event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] != '\0')
21558 		event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] = '\0';
21559 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(param->board_mcn_detail,
21560 			event->board_mcn_detail, WMI_BOARD_MCN_STRING_BUF_SIZE);
21561 
21562 	param->software_cal_version = event->software_cal_version;
21563 	param->board_cal_version = event->board_cal_version;
21564 	param->cal_ok  = event->cal_status;
21565 
21566 	return QDF_STATUS_SUCCESS;
21567 }
21568 
21569 /*
21570  * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config
21571  * @wmi_handle: wmi handle
21572  * @params: pointer to wmi_btm_config
21573  *
21574  * Return: QDF_STATUS
21575  */
21576 static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle,
21577 					  struct wmi_btm_config *params)
21578 {
21579 
21580 	wmi_btm_config_fixed_param *cmd;
21581 	wmi_buf_t buf;
21582 	uint32_t len;
21583 
21584 	len = sizeof(*cmd);
21585 	buf = wmi_buf_alloc(wmi_handle, len);
21586 	if (!buf) {
21587 		qdf_print("%s:wmi_buf_alloc failed", __func__);
21588 		return QDF_STATUS_E_NOMEM;
21589 	}
21590 
21591 	cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf);
21592 	WMITLV_SET_HDR(&cmd->tlv_header,
21593 		       WMITLV_TAG_STRUC_wmi_btm_config_fixed_param,
21594 		       WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param));
21595 	cmd->vdev_id = params->vdev_id;
21596 	cmd->flags = params->btm_offload_config;
21597 	cmd->max_attempt_cnt = params->btm_max_attempt_cnt;
21598 	cmd->solicited_timeout_ms = params->btm_solicited_timeout;
21599 	cmd->stick_time_seconds = params->btm_sticky_time;
21600 
21601 	wmi_mtrace(WMI_ROAM_BTM_CONFIG_CMDID, cmd->vdev_id, 0);
21602 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21603 	    WMI_ROAM_BTM_CONFIG_CMDID)) {
21604 		WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID",
21605 			 __func__);
21606 		wmi_buf_free(buf);
21607 		return QDF_STATUS_E_FAILURE;
21608 	}
21609 
21610 	return QDF_STATUS_SUCCESS;
21611 }
21612 
21613 /**
21614  * send_obss_detection_cfg_cmd_tlv() - send obss detection
21615  *   configurations to firmware.
21616  * @wmi_handle: wmi handle
21617  * @obss_cfg_param: obss detection configurations
21618  *
21619  * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw.
21620  *
21621  * Return: QDF_STATUS
21622  */
21623 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle,
21624 		struct wmi_obss_detection_cfg_param *obss_cfg_param)
21625 {
21626 	wmi_buf_t buf;
21627 	wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd;
21628 	uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param);
21629 
21630 	buf = wmi_buf_alloc(wmi_handle, len);
21631 	if (!buf) {
21632 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
21633 		return QDF_STATUS_E_NOMEM;
21634 	}
21635 
21636 	cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf);
21637 	WMITLV_SET_HDR(&cmd->tlv_header,
21638 		WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param,
21639 		       WMITLV_GET_STRUCT_TLVLEN
21640 		       (wmi_sap_obss_detection_cfg_cmd_fixed_param));
21641 
21642 	cmd->vdev_id = obss_cfg_param->vdev_id;
21643 	cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms;
21644 	cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode;
21645 	cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode;
21646 	cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode;
21647 	cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode;
21648 	cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode;
21649 	cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode;
21650 	cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode;
21651 
21652 	wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0);
21653 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21654 				 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) {
21655 		WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID");
21656 		wmi_buf_free(buf);
21657 		return QDF_STATUS_E_FAILURE;
21658 	}
21659 
21660 	return QDF_STATUS_SUCCESS;
21661 }
21662 
21663 /**
21664  * extract_obss_detection_info_tlv() - Extract obss detection info
21665  *   received from firmware.
21666  * @evt_buf: pointer to event buffer
21667  * @obss_detection: Pointer to hold obss detection info
21668  *
21669  * Return: QDF_STATUS
21670  */
21671 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf,
21672 						  struct wmi_obss_detect_info
21673 						  *obss_detection)
21674 {
21675 	WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf;
21676 	wmi_sap_obss_detection_info_evt_fixed_param *fix_param;
21677 
21678 	if (!obss_detection) {
21679 		WMI_LOGE("%s: Invalid obss_detection event buffer", __func__);
21680 		return QDF_STATUS_E_INVAL;
21681 	}
21682 
21683 	param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf;
21684 	if (!param_buf) {
21685 		WMI_LOGE("%s: Invalid evt_buf", __func__);
21686 		return QDF_STATUS_E_INVAL;
21687 	}
21688 
21689 	fix_param = param_buf->fixed_param;
21690 	obss_detection->vdev_id = fix_param->vdev_id;
21691 	obss_detection->matched_detection_masks =
21692 		fix_param->matched_detection_masks;
21693 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr,
21694 				   &obss_detection->matched_bssid_addr[0]);
21695 	switch (fix_param->reason) {
21696 	case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT:
21697 		obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED;
21698 		break;
21699 	case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY:
21700 		obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT;
21701 		break;
21702 	case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT:
21703 		obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT;
21704 		break;
21705 	default:
21706 		WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason);
21707 		return QDF_STATUS_E_INVAL;
21708 	}
21709 
21710 	return QDF_STATUS_SUCCESS;
21711 }
21712 
21713 /**
21714  * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw
21715  * @wmi_handle: wmi handle
21716  * @params: pointer to request structure
21717  *
21718  * Return: QDF_STATUS
21719  */
21720 static QDF_STATUS
21721 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle,
21722 			     struct wmi_roam_scan_stats_req *params)
21723 {
21724 	wmi_buf_t buf;
21725 	wmi_request_roam_scan_stats_cmd_fixed_param *cmd;
21726 	WMITLV_TAG_ID tag;
21727 	uint32_t size;
21728 	uint32_t len = sizeof(*cmd);
21729 
21730 	buf = wmi_buf_alloc(wmi_handle, len);
21731 	if (!buf) {
21732 		WMI_LOGE(FL("Failed to allocate wmi buffer"));
21733 		return QDF_STATUS_E_FAILURE;
21734 	}
21735 
21736 	cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf);
21737 
21738 	tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param;
21739 	size = WMITLV_GET_STRUCT_TLVLEN(
21740 			wmi_request_roam_scan_stats_cmd_fixed_param);
21741 	WMITLV_SET_HDR(&cmd->tlv_header, tag, size);
21742 
21743 	cmd->vdev_id = params->vdev_id;
21744 
21745 	WMI_LOGD(FL("Roam Scan Stats Req vdev_id: %u"), cmd->vdev_id);
21746 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21747 				 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) {
21748 		WMI_LOGE("%s: Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID",
21749 			 __func__);
21750 		wmi_buf_free(buf);
21751 		return QDF_STATUS_E_FAILURE;
21752 	}
21753 
21754 	return QDF_STATUS_SUCCESS;
21755 }
21756 
21757 /**
21758  * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event
21759  * @wmi_handle: wmi handle
21760  * @evt_buf: pointer to event buffer
21761  * @vdev_id: output pointer to hold vdev id
21762  * @res_param: output pointer to hold the allocated response
21763  *
21764  * Return: QDF_STATUS
21765  */
21766 static QDF_STATUS
21767 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf,
21768 				    uint32_t *vdev_id,
21769 				    struct wmi_roam_scan_stats_res **res_param)
21770 {
21771 	WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf;
21772 	wmi_roam_scan_stats_event_fixed_param *fixed_param;
21773 	uint32_t *client_id = NULL;
21774 	wmi_roaming_timestamp *timestamp = NULL;
21775 	uint32_t *num_channels = NULL;
21776 	uint32_t *chan_info = NULL;
21777 	wmi_mac_addr *old_bssid = NULL;
21778 	uint32_t *is_roaming_success = NULL;
21779 	wmi_mac_addr *new_bssid = NULL;
21780 	uint32_t *num_roam_candidates = NULL;
21781 	wmi_roam_scan_trigger_reason *roam_reason = NULL;
21782 	wmi_mac_addr *bssid = NULL;
21783 	uint32_t *score = NULL;
21784 	uint32_t *channel = NULL;
21785 	uint32_t *rssi = NULL;
21786 	int chan_idx = 0, cand_idx = 0;
21787 	uint32_t total_len;
21788 	struct wmi_roam_scan_stats_res *res;
21789 	uint32_t i, j;
21790 	uint32_t num_scans;
21791 
21792 	*res_param = NULL;
21793 	*vdev_id = 0xFF; /* Initialize to invalid vdev id */
21794 	param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf;
21795 	if (!param_buf) {
21796 		WMI_LOGE(FL("Invalid roam scan stats event"));
21797 		return QDF_STATUS_E_INVAL;
21798 	}
21799 
21800 	fixed_param = param_buf->fixed_param;
21801 	total_len = sizeof(*res) + fixed_param->num_roam_scans *
21802 		    sizeof(struct wmi_roam_scan_stats_params);
21803 
21804 	*vdev_id = fixed_param->vdev_id;
21805 	num_scans = fixed_param->num_roam_scans;
21806 
21807 	res = qdf_mem_malloc(total_len);
21808 	if (!res) {
21809 		WMI_LOGE("Failed to allocate roam scan stats response memory");
21810 		return QDF_STATUS_E_NOMEM;
21811 	}
21812 
21813 	if (!num_scans) {
21814 		*res_param = res;
21815 		return QDF_STATUS_SUCCESS;
21816 	}
21817 
21818 	if (param_buf->client_id &&
21819 	    param_buf->num_client_id == num_scans)
21820 		client_id = param_buf->client_id;
21821 
21822 	if (param_buf->timestamp &&
21823 	    param_buf->num_timestamp == num_scans)
21824 		timestamp = param_buf->timestamp;
21825 
21826 	if (param_buf->old_bssid &&
21827 	    param_buf->num_old_bssid == num_scans)
21828 		old_bssid = param_buf->old_bssid;
21829 
21830 	if (param_buf->new_bssid &&
21831 	    param_buf->num_new_bssid == num_scans)
21832 		new_bssid = param_buf->new_bssid;
21833 
21834 	if (param_buf->is_roaming_success &&
21835 	    param_buf->num_is_roaming_success == num_scans)
21836 		is_roaming_success = param_buf->is_roaming_success;
21837 
21838 	if (param_buf->roam_reason &&
21839 	    param_buf->num_roam_reason == num_scans)
21840 		roam_reason = param_buf->roam_reason;
21841 
21842 	if (param_buf->num_channels &&
21843 	    param_buf->num_num_channels == num_scans) {
21844 		uint32_t count, chan_info_sum = 0;
21845 
21846 		num_channels = param_buf->num_channels;
21847 		for (count = 0; count < param_buf->num_num_channels; count++)
21848 			chan_info_sum += param_buf->num_channels[count];
21849 
21850 		if (param_buf->chan_info &&
21851 		    param_buf->num_chan_info == chan_info_sum)
21852 			chan_info = param_buf->chan_info;
21853 	}
21854 
21855 	if (param_buf->num_roam_candidates &&
21856 	    param_buf->num_num_roam_candidates == num_scans) {
21857 		uint32_t count, roam_cand_sum = 0;
21858 
21859 		num_roam_candidates = param_buf->num_roam_candidates;
21860 		for (count = 0; count < param_buf->num_num_roam_candidates;
21861 		     count++)
21862 			roam_cand_sum += param_buf->num_roam_candidates[count];
21863 
21864 		if (param_buf->bssid &&
21865 		    param_buf->num_bssid == roam_cand_sum)
21866 			bssid = param_buf->bssid;
21867 
21868 		if (param_buf->score &&
21869 		    param_buf->num_score == roam_cand_sum)
21870 			score = param_buf->score;
21871 
21872 		if (param_buf->channel &&
21873 		    param_buf->num_channel == roam_cand_sum)
21874 			channel = param_buf->channel;
21875 
21876 		if (param_buf->rssi &&
21877 		    param_buf->num_rssi == roam_cand_sum)
21878 			rssi = param_buf->rssi;
21879 	}
21880 
21881 	res->num_roam_scans = num_scans;
21882 	for (i = 0; i < num_scans; i++) {
21883 		struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i];
21884 
21885 		if (timestamp)
21886 			roam->time_stamp = timestamp[i].lower32bit |
21887 						(timestamp[i].upper32bit << 31);
21888 
21889 		if (client_id)
21890 			roam->client_id = client_id[i];
21891 
21892 		if (num_channels) {
21893 			roam->num_scan_chans = num_channels[i];
21894 			if (chan_info) {
21895 				for (j = 0; j < num_channels[i]; j++)
21896 					roam->scan_freqs[j] =
21897 							chan_info[chan_idx++];
21898 			}
21899 		}
21900 
21901 		if (is_roaming_success)
21902 			roam->is_roam_successful = is_roaming_success[i];
21903 
21904 		if (roam_reason) {
21905 			roam->trigger_id = roam_reason[i].trigger_id;
21906 			roam->trigger_value = roam_reason[i].trigger_value;
21907 		}
21908 
21909 		if (num_roam_candidates) {
21910 			roam->num_roam_candidates = num_roam_candidates[i];
21911 
21912 			for (j = 0; j < num_roam_candidates[i]; j++) {
21913 				if (score)
21914 					roam->cand[j].score = score[cand_idx];
21915 				if (rssi)
21916 					roam->cand[j].rssi = rssi[cand_idx];
21917 				if (channel)
21918 					roam->cand[j].freq =
21919 						channel[cand_idx];
21920 
21921 				if (bssid)
21922 					WMI_MAC_ADDR_TO_CHAR_ARRAY(
21923 							&bssid[cand_idx],
21924 							roam->cand[j].bssid);
21925 
21926 				cand_idx++;
21927 			}
21928 		}
21929 
21930 		if (old_bssid)
21931 			WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i],
21932 						   roam->old_bssid);
21933 
21934 		if (new_bssid)
21935 			WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i],
21936 						   roam->new_bssid);
21937 	}
21938 
21939 	*res_param = res;
21940 
21941 	return QDF_STATUS_SUCCESS;
21942 }
21943 
21944 /**
21945  * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params
21946  * @wmi_handle: wmi handler
21947  * @params: pointer to 11k offload params
21948  *
21949  * Return: 0 for success and non zero for failure
21950  */
21951 static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle,
21952 				struct wmi_11k_offload_params *params)
21953 {
21954 	wmi_11k_offload_report_fixed_param *cmd;
21955 	wmi_buf_t buf;
21956 	QDF_STATUS status;
21957 	uint8_t *buf_ptr;
21958 	wmi_neighbor_report_11k_offload_tlv_param
21959 					*neighbor_report_offload_params;
21960 	wmi_neighbor_report_offload *neighbor_report_offload;
21961 
21962 	uint32_t len = sizeof(*cmd);
21963 
21964 	if (params->offload_11k_bitmask &
21965 	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ)
21966 		len += WMI_TLV_HDR_SIZE +
21967 			sizeof(wmi_neighbor_report_11k_offload_tlv_param);
21968 
21969 	buf = wmi_buf_alloc(wmi_handle, len);
21970 	if (!buf) {
21971 		WMI_LOGP("%s: failed to allocate memory for 11k offload params",
21972 			 __func__);
21973 		return QDF_STATUS_E_NOMEM;
21974 	}
21975 
21976 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21977 	cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr;
21978 
21979 	WMITLV_SET_HDR(&cmd->tlv_header,
21980 		 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param,
21981 		 WMITLV_GET_STRUCT_TLVLEN(
21982 			wmi_11k_offload_report_fixed_param));
21983 
21984 	cmd->vdev_id = params->vdev_id;
21985 	cmd->offload_11k = params->offload_11k_bitmask;
21986 
21987 	if (params->offload_11k_bitmask &
21988 	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) {
21989 		buf_ptr += sizeof(wmi_11k_offload_report_fixed_param);
21990 
21991 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
21992 			sizeof(wmi_neighbor_report_11k_offload_tlv_param));
21993 		buf_ptr += WMI_TLV_HDR_SIZE;
21994 
21995 		neighbor_report_offload_params =
21996 			(wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr;
21997 		WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header,
21998 			WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param,
21999 			WMITLV_GET_STRUCT_TLVLEN(
22000 			wmi_neighbor_report_11k_offload_tlv_param));
22001 
22002 		neighbor_report_offload = &neighbor_report_offload_params->
22003 			neighbor_rep_ofld_params;
22004 
22005 		neighbor_report_offload->time_offset =
22006 			params->neighbor_report_params.time_offset;
22007 		neighbor_report_offload->low_rssi_offset =
22008 			params->neighbor_report_params.low_rssi_offset;
22009 		neighbor_report_offload->bmiss_count_trigger =
22010 			params->neighbor_report_params.bmiss_count_trigger;
22011 		neighbor_report_offload->per_threshold_offset =
22012 			params->neighbor_report_params.per_threshold_offset;
22013 		neighbor_report_offload->neighbor_report_cache_timeout =
22014 			params->neighbor_report_params.
22015 			neighbor_report_cache_timeout;
22016 		neighbor_report_offload->max_neighbor_report_req_cap =
22017 			params->neighbor_report_params.
22018 			max_neighbor_report_req_cap;
22019 		neighbor_report_offload->ssid.ssid_len =
22020 			params->neighbor_report_params.ssid.length;
22021 		qdf_mem_copy(neighbor_report_offload->ssid.ssid,
22022 			&params->neighbor_report_params.ssid.mac_ssid,
22023 			neighbor_report_offload->ssid.ssid_len);
22024 	}
22025 
22026 	wmi_mtrace(WMI_11K_OFFLOAD_REPORT_CMDID, cmd->vdev_id, 0);
22027 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
22028 			WMI_11K_OFFLOAD_REPORT_CMDID);
22029 	if (status != QDF_STATUS_SUCCESS) {
22030 		WMI_LOGE("%s: failed to send 11k offload command %d",
22031 			 __func__, status);
22032 		wmi_buf_free(buf);
22033 	}
22034 
22035 	return status;
22036 }
22037 
22038 /**
22039  * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report
22040  * command
22041  * @wmi_handle: wmi handler
22042  * @params: pointer to neighbor report invoke params
22043  *
22044  * Return: 0 for success and non zero for failure
22045  */
22046 static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle,
22047 			struct wmi_invoke_neighbor_report_params *params)
22048 {
22049 	wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd;
22050 	wmi_buf_t buf;
22051 	QDF_STATUS status;
22052 	uint8_t *buf_ptr;
22053 	uint32_t len = sizeof(*cmd);
22054 
22055 	buf = wmi_buf_alloc(wmi_handle, len);
22056 	if (!buf) {
22057 		WMI_LOGP("%s:failed to allocate memory for neighbor invoke cmd",
22058 			 __func__);
22059 		return QDF_STATUS_E_NOMEM;
22060 	}
22061 
22062 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
22063 	cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr;
22064 
22065 	WMITLV_SET_HDR(&cmd->tlv_header,
22066 		 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param,
22067 		 WMITLV_GET_STRUCT_TLVLEN(
22068 			wmi_11k_offload_invoke_neighbor_report_fixed_param));
22069 
22070 	cmd->vdev_id = params->vdev_id;
22071 	cmd->flags = params->send_resp_to_host;
22072 
22073 	cmd->ssid.ssid_len = params->ssid.length;
22074 	qdf_mem_copy(cmd->ssid.ssid,
22075 		     &params->ssid.mac_ssid,
22076 		     cmd->ssid.ssid_len);
22077 
22078 	wmi_mtrace(WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID, cmd->vdev_id, 0);
22079 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
22080 			WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID);
22081 	if (status != QDF_STATUS_SUCCESS) {
22082 		WMI_LOGE("%s: failed to send invoke neighbor report command %d",
22083 			 __func__, status);
22084 		wmi_buf_free(buf);
22085 	}
22086 
22087 	return status;
22088 }
22089 
22090 #ifdef WLAN_SUPPORT_GREEN_AP
22091 static QDF_STATUS extract_green_ap_egap_status_info_tlv(
22092 		uint8_t *evt_buf,
22093 		struct wlan_green_ap_egap_status_info *egap_status_info_params)
22094 {
22095 	WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf;
22096 	wmi_ap_ps_egap_info_event_fixed_param  *egap_info_event;
22097 	wmi_ap_ps_egap_info_chainmask_list *chainmask_event;
22098 
22099 	param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf;
22100 	if (!param_buf) {
22101 		WMI_LOGE("Invalid EGAP Info status event buffer");
22102 		return QDF_STATUS_E_INVAL;
22103 	}
22104 
22105 	egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *)
22106 				param_buf->fixed_param;
22107 	chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *)
22108 				param_buf->chainmask_list;
22109 
22110 	egap_status_info_params->status = egap_info_event->status;
22111 	egap_status_info_params->mac_id = chainmask_event->mac_id;
22112 	egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask;
22113 	egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask;
22114 
22115 	return QDF_STATUS_SUCCESS;
22116 }
22117 #endif
22118 
22119 /*
22120  * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of
22121  * updating bss color change within firmware when AP announces bss color change.
22122  * @wmi_handle: wmi handle
22123  * @vdev_id: vdev ID
22124  * @enable: enable bss color change within firmware
22125  *
22126  * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw.
22127  *
22128  * Return: QDF_STATUS
22129  */
22130 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle,
22131 						       uint32_t vdev_id,
22132 						       bool enable)
22133 {
22134 	wmi_buf_t buf;
22135 	wmi_bss_color_change_enable_fixed_param *cmd;
22136 	uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param);
22137 
22138 	buf = wmi_buf_alloc(wmi_handle, len);
22139 	if (!buf) {
22140 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
22141 		return QDF_STATUS_E_NOMEM;
22142 	}
22143 
22144 	cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf);
22145 	WMITLV_SET_HDR(&cmd->tlv_header,
22146 		WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param,
22147 		       WMITLV_GET_STRUCT_TLVLEN
22148 		       (wmi_bss_color_change_enable_fixed_param));
22149 	cmd->vdev_id = vdev_id;
22150 	cmd->enable = enable;
22151 	wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0);
22152 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
22153 				 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) {
22154 		WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID");
22155 		wmi_buf_free(buf);
22156 		return QDF_STATUS_E_FAILURE;
22157 	}
22158 
22159 	return QDF_STATUS_SUCCESS;
22160 }
22161 
22162 /**
22163  * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection
22164  *   configurations to firmware.
22165  * @wmi_handle: wmi handle
22166  * @cfg_param: obss detection configurations
22167  *
22168  * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw.
22169  *
22170  * Return: QDF_STATUS
22171  */
22172 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv(
22173 		wmi_unified_t wmi_handle,
22174 		struct wmi_obss_color_collision_cfg_param *cfg_param)
22175 {
22176 	wmi_buf_t buf;
22177 	wmi_obss_color_collision_det_config_fixed_param *cmd;
22178 	uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param);
22179 
22180 	buf = wmi_buf_alloc(wmi_handle, len);
22181 	if (!buf) {
22182 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
22183 		return QDF_STATUS_E_NOMEM;
22184 	}
22185 
22186 	cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data(
22187 			buf);
22188 	WMITLV_SET_HDR(&cmd->tlv_header,
22189 	WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param,
22190 		       WMITLV_GET_STRUCT_TLVLEN
22191 		       (wmi_obss_color_collision_det_config_fixed_param));
22192 	cmd->vdev_id = cfg_param->vdev_id;
22193 	cmd->flags = cfg_param->flags;
22194 	cmd->current_bss_color = cfg_param->current_bss_color;
22195 	cmd->detection_period_ms = cfg_param->detection_period_ms;
22196 	cmd->scan_period_ms = cfg_param->scan_period_ms;
22197 	cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms;
22198 
22199 	switch (cfg_param->evt_type) {
22200 	case OBSS_COLOR_COLLISION_DETECTION_DISABLE:
22201 		cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE;
22202 		break;
22203 	case OBSS_COLOR_COLLISION_DETECTION:
22204 		cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION;
22205 		break;
22206 	case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY:
22207 		cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY;
22208 		break;
22209 	case OBSS_COLOR_FREE_SLOT_AVAILABLE:
22210 		cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE;
22211 		break;
22212 	default:
22213 		WMI_LOGE("%s: invalid event type: %d",
22214 			 __func__, cfg_param->evt_type);
22215 		wmi_buf_free(buf);
22216 		return QDF_STATUS_E_FAILURE;
22217 	}
22218 
22219 	wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0);
22220 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
22221 				 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) {
22222 		WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d",
22223 			 __func__, cfg_param->vdev_id);
22224 		wmi_buf_free(buf);
22225 		return QDF_STATUS_E_FAILURE;
22226 	}
22227 
22228 	return QDF_STATUS_SUCCESS;
22229 }
22230 
22231 /**
22232  * extract_obss_color_collision_info_tlv() - Extract bss color collision info
22233  *   received from firmware.
22234  * @evt_buf: pointer to event buffer
22235  * @info: Pointer to hold bss collision  info
22236  *
22237  * Return: QDF_STATUS
22238  */
22239 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf,
22240 		struct wmi_obss_color_collision_info *info)
22241 {
22242 	WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf;
22243 	wmi_obss_color_collision_evt_fixed_param *fix_param;
22244 
22245 	if (!info) {
22246 		WMI_LOGE("%s: Invalid obss color buffer", __func__);
22247 		return QDF_STATUS_E_INVAL;
22248 	}
22249 
22250 	param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *)
22251 		    evt_buf;
22252 	if (!param_buf) {
22253 		WMI_LOGE("%s: Invalid evt_buf", __func__);
22254 		return QDF_STATUS_E_INVAL;
22255 	}
22256 
22257 	fix_param = param_buf->fixed_param;
22258 	info->vdev_id = fix_param->vdev_id;
22259 	info->obss_color_bitmap_bit0to31 = fix_param->bss_color_bitmap_bit0to31;
22260 	info->obss_color_bitmap_bit32to63 =
22261 		fix_param->bss_color_bitmap_bit32to63;
22262 
22263 	switch (fix_param->evt_type) {
22264 	case WMI_BSS_COLOR_COLLISION_DISABLE:
22265 		info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE;
22266 		break;
22267 	case WMI_BSS_COLOR_COLLISION_DETECTION:
22268 		info->evt_type = OBSS_COLOR_COLLISION_DETECTION;
22269 		break;
22270 	case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY:
22271 		info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY;
22272 		break;
22273 	case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE:
22274 		info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE;
22275 		break;
22276 	default:
22277 		WMI_LOGE("%s: invalid event type: %d, vdev_id: %d",
22278 			 __func__, fix_param->evt_type, fix_param->vdev_id);
22279 		return QDF_STATUS_E_FAILURE;
22280 	}
22281 
22282 	return QDF_STATUS_SUCCESS;
22283 }
22284 
22285 /*
22286  * extract_comb_phyerr_tlv() - extract comb phy error from event
22287  * @wmi_handle: wmi handle
22288  * @evt_buf: pointer to event buffer
22289  * @datalen: data length of event buffer
22290  * @buf_offset: Pointer to hold value of current event buffer offset
22291  * post extraction
22292  * @phyerr: Pointer to hold phyerr
22293  *
22294  * Return: QDF_STATUS
22295  */
22296 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle,
22297 					  void *evt_buf,
22298 					  uint16_t datalen,
22299 					  uint16_t *buf_offset,
22300 					  wmi_host_phyerr_t *phyerr)
22301 {
22302 	WMI_PHYERR_EVENTID_param_tlvs *param_tlvs;
22303 	wmi_comb_phyerr_rx_hdr *pe_hdr;
22304 
22305 	param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf;
22306 	if (!param_tlvs) {
22307 		WMI_LOGD("%s: Received null data from FW", __func__);
22308 		return QDF_STATUS_E_FAILURE;
22309 	}
22310 
22311 	pe_hdr = param_tlvs->hdr;
22312 	if (!pe_hdr) {
22313 		WMI_LOGD("%s: Received Data PE Header is NULL", __func__);
22314 		return QDF_STATUS_E_FAILURE;
22315 	}
22316 
22317 	/* Ensure it's at least the size of the header */
22318 	if (datalen < sizeof(*pe_hdr)) {
22319 		WMI_LOGD("%s: Expected minimum size %zu, received %d",
22320 			 __func__, sizeof(*pe_hdr), datalen);
22321 		return QDF_STATUS_E_FAILURE;
22322 	}
22323 
22324 	phyerr->pdev_id = wmi_handle->ops->
22325 		convert_pdev_id_target_to_host(pe_hdr->pdev_id);
22326 	phyerr->tsf64 = pe_hdr->tsf_l32;
22327 	phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32);
22328 	phyerr->bufp = param_tlvs->bufp;
22329 	phyerr->buf_len = pe_hdr->buf_len;
22330 	phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0;
22331 	phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1;
22332 	*buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t);
22333 
22334 	return QDF_STATUS_SUCCESS;
22335 }
22336 
22337 /**
22338  * extract_single_phyerr_tlv() - extract single phy error from event
22339  * @wmi_handle: wmi handle
22340  * @evt_buf: pointer to event buffer
22341  * @datalen: data length of event buffer
22342  * @buf_offset: Pointer to hold value of current event buffer offset
22343  * post extraction
22344  * @phyerr: Pointer to hold phyerr
22345  *
22346  * Return: QDF_STATUS
22347  */
22348 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle,
22349 					    void *evt_buf,
22350 					    uint16_t datalen,
22351 					    uint16_t *buf_offset,
22352 					    wmi_host_phyerr_t *phyerr)
22353 {
22354 	wmi_single_phyerr_rx_event *ev;
22355 	uint16_t n = *buf_offset;
22356 	uint8_t *data = (uint8_t *)evt_buf;
22357 
22358 	if (n < datalen) {
22359 		if ((datalen - n) < sizeof(ev->hdr)) {
22360 			WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu",
22361 				 __func__, datalen, n, sizeof(ev->hdr));
22362 			return QDF_STATUS_E_FAILURE;
22363 		}
22364 
22365 		/*
22366 		 * Obtain a pointer to the beginning of the current event.
22367 		 * data[0] is the beginning of the WMI payload.
22368 		 */
22369 		ev = (wmi_single_phyerr_rx_event *)&data[n];
22370 
22371 		/*
22372 		 * Sanity check the buffer length of the event against
22373 		 * what we currently have.
22374 		 *
22375 		 * Since buf_len is 32 bits, we check if it overflows
22376 		 * a large 32 bit value.  It's not 0x7fffffff because
22377 		 * we increase n by (buf_len + sizeof(hdr)), which would
22378 		 * in itself cause n to overflow.
22379 		 *
22380 		 * If "int" is 64 bits then this becomes a moot point.
22381 		 */
22382 		if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) {
22383 			WMI_LOGD("%s: buf_len is garbage 0x%x",
22384 				 __func__, ev->hdr.buf_len);
22385 			return QDF_STATUS_E_FAILURE;
22386 		}
22387 
22388 		if ((n + ev->hdr.buf_len) > datalen) {
22389 			WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d",
22390 				 __func__, n, ev->hdr.buf_len, datalen);
22391 			return QDF_STATUS_E_FAILURE;
22392 		}
22393 
22394 		phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr);
22395 		phyerr->tsf_timestamp = ev->hdr.tsf_timestamp;
22396 		phyerr->bufp = &ev->bufp[0];
22397 		phyerr->buf_len = ev->hdr.buf_len;
22398 		phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr);
22399 
22400 		/*
22401 		 * Advance the buffer pointer to the next PHY error.
22402 		 * buflen is the length of this payload, so we need to
22403 		 * advance past the current header _AND_ the payload.
22404 		 */
22405 		n += sizeof(*ev) + ev->hdr.buf_len;
22406 	}
22407 	*buf_offset = n;
22408 
22409 	return QDF_STATUS_SUCCESS;
22410 }
22411 
22412 /**
22413  * extract_esp_estimation_ev_param_tlv() - extract air time from event
22414  * @wmi_handle: wmi handle
22415  * @evt_buf: pointer to event buffer
22416  * @param: Pointer to hold esp event
22417  *
22418  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure
22419  */
22420 static QDF_STATUS
22421 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle,
22422 				    void *evt_buf,
22423 				    struct esp_estimation_event *param)
22424 {
22425 	WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf;
22426 	wmi_esp_estimate_event_fixed_param *esp_event;
22427 
22428 	param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf;
22429 	if (!param_buf) {
22430 		WMI_LOGE("Invalid ESP Estimate Event buffer");
22431 		return QDF_STATUS_E_INVAL;
22432 	}
22433 	esp_event = param_buf->fixed_param;
22434 	param->ac_airtime_percentage = esp_event->ac_airtime_percentage;
22435 	param->pdev_id = convert_target_pdev_id_to_host_pdev_id(
22436 				esp_event->pdev_id);
22437 
22438 	return QDF_STATUS_SUCCESS;
22439 }
22440 
22441 struct wmi_ops tlv_ops =  {
22442 	.send_vdev_create_cmd = send_vdev_create_cmd_tlv,
22443 	.send_vdev_delete_cmd = send_vdev_delete_cmd_tlv,
22444 	.send_vdev_down_cmd = send_vdev_down_cmd_tlv,
22445 	.send_vdev_start_cmd = send_vdev_start_cmd_tlv,
22446 	.send_hidden_ssid_vdev_restart_cmd =
22447 		send_hidden_ssid_vdev_restart_cmd_tlv,
22448 	.send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv,
22449 	.send_peer_param_cmd = send_peer_param_cmd_tlv,
22450 	.send_vdev_up_cmd = send_vdev_up_cmd_tlv,
22451 	.send_vdev_stop_cmd = send_vdev_stop_cmd_tlv,
22452 	.send_peer_create_cmd = send_peer_create_cmd_tlv,
22453 	.send_peer_delete_cmd = send_peer_delete_cmd_tlv,
22454 	.send_peer_rx_reorder_queue_setup_cmd =
22455 		send_peer_rx_reorder_queue_setup_cmd_tlv,
22456 	.send_peer_rx_reorder_queue_remove_cmd =
22457 		send_peer_rx_reorder_queue_remove_cmd_tlv,
22458 	.send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv,
22459 	.send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv,
22460 	.send_peer_update_wds_entry_cmd = send_peer_update_wds_entry_cmd_tlv,
22461 	.send_pdev_utf_cmd = send_pdev_utf_cmd_tlv,
22462 	.send_pdev_param_cmd = send_pdev_param_cmd_tlv,
22463 	.send_pdev_get_tpc_config_cmd = send_pdev_get_tpc_config_cmd_tlv,
22464 	.send_suspend_cmd = send_suspend_cmd_tlv,
22465 	.send_resume_cmd = send_resume_cmd_tlv,
22466 #ifdef FEATURE_WLAN_D0WOW
22467 	.send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv,
22468 	.send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv,
22469 #endif
22470 	.send_wow_enable_cmd = send_wow_enable_cmd_tlv,
22471 	.send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv,
22472 	.send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv,
22473 	.send_crash_inject_cmd = send_crash_inject_cmd_tlv,
22474 #ifdef FEATURE_FW_LOG_PARSING
22475 	.send_dbglog_cmd = send_dbglog_cmd_tlv,
22476 #endif
22477 	.send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv,
22478 	.send_stats_request_cmd = send_stats_request_cmd_tlv,
22479 	.send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv,
22480 	.send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv,
22481 	.send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv,
22482 	.send_beacon_send_cmd = send_beacon_send_cmd_tlv,
22483 	.send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv,
22484 	.send_peer_assoc_cmd = send_peer_assoc_cmd_tlv,
22485 	.send_scan_start_cmd = send_scan_start_cmd_tlv,
22486 	.send_scan_stop_cmd = send_scan_stop_cmd_tlv,
22487 	.send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv,
22488 	.send_mgmt_cmd = send_mgmt_cmd_tlv,
22489 	.send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv,
22490 	.send_modem_power_state_cmd = send_modem_power_state_cmd_tlv,
22491 	.send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv,
22492 	.send_set_sta_uapsd_auto_trig_cmd =
22493 		send_set_sta_uapsd_auto_trig_cmd_tlv,
22494 	.send_get_temperature_cmd = send_get_temperature_cmd_tlv,
22495 	.send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv,
22496 	.send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv,
22497 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
22498 	.send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv,
22499 	.send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv,
22500 #endif
22501 	.send_set_smps_params_cmd = send_set_smps_params_cmd_tlv,
22502 	.send_set_mimops_cmd = send_set_mimops_cmd_tlv,
22503 #ifdef WLAN_FEATURE_DSRC
22504 	.send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv,
22505 	.send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv,
22506 	.send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv,
22507 	.send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv,
22508 	.send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv,
22509 	.send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv,
22510 	.send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv,
22511 	.send_ocb_start_timing_advert_cmd =
22512 		send_ocb_start_timing_advert_cmd_tlv,
22513 	.extract_ocb_chan_config_resp = extract_ocb_channel_config_resp_tlv,
22514 	.extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv,
22515 	.extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv,
22516 	.extract_dcc_stats = extract_ocb_dcc_stats_tlv,
22517 #endif
22518 	.send_set_enable_disable_mcc_adaptive_scheduler_cmd =
22519 		 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv,
22520 	.send_set_mcc_channel_time_latency_cmd =
22521 			 send_set_mcc_channel_time_latency_cmd_tlv,
22522 	.send_set_mcc_channel_time_quota_cmd =
22523 			 send_set_mcc_channel_time_quota_cmd_tlv,
22524 	.send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv,
22525 	.send_lro_config_cmd = send_lro_config_cmd_tlv,
22526 	.send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv,
22527 	.send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv,
22528 	.send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv,
22529 	.send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv,
22530 	.send_probe_rsp_tmpl_send_cmd =
22531 				send_probe_rsp_tmpl_send_cmd_tlv,
22532 	.send_p2p_go_set_beacon_ie_cmd =
22533 				send_p2p_go_set_beacon_ie_cmd_tlv,
22534 	.send_setup_install_key_cmd =
22535 				send_setup_install_key_cmd_tlv,
22536 	.send_set_gateway_params_cmd =
22537 				send_set_gateway_params_cmd_tlv,
22538 	.send_set_rssi_monitoring_cmd =
22539 			 send_set_rssi_monitoring_cmd_tlv,
22540 	.send_scan_probe_setoui_cmd =
22541 				send_scan_probe_setoui_cmd_tlv,
22542 	.send_roam_scan_offload_rssi_thresh_cmd =
22543 			send_roam_scan_offload_rssi_thresh_cmd_tlv,
22544 	.send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv,
22545 	.send_roam_scan_filter_cmd =
22546 			send_roam_scan_filter_cmd_tlv,
22547 #ifdef IPA_OFFLOAD
22548 	.send_ipa_offload_control_cmd =
22549 			 send_ipa_offload_control_cmd_tlv,
22550 #endif
22551 	.send_plm_stop_cmd = send_plm_stop_cmd_tlv,
22552 	.send_plm_start_cmd = send_plm_start_cmd_tlv,
22553 	.send_pno_stop_cmd = send_pno_stop_cmd_tlv,
22554 	.send_pno_start_cmd = send_pno_start_cmd_tlv,
22555 	.send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv,
22556 	.send_set_ric_req_cmd = send_set_ric_req_cmd_tlv,
22557 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
22558 	.send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv,
22559 	.send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv,
22560 	.send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv,
22561 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/
22562 	.send_congestion_cmd = send_congestion_cmd_tlv,
22563 	.send_snr_request_cmd = send_snr_request_cmd_tlv,
22564 	.send_snr_cmd = send_snr_cmd_tlv,
22565 	.send_link_status_req_cmd = send_link_status_req_cmd_tlv,
22566 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
22567 	.send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv,
22568 	.send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv,
22569 	.send_enable_arp_ns_offload_cmd = send_enable_arp_ns_offload_cmd_tlv,
22570 	.send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv,
22571 	.send_multiple_add_clear_mcbc_filter_cmd =
22572 		send_multiple_add_clear_mcbc_filter_cmd_tlv,
22573 	.send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv,
22574 	.send_gtk_offload_cmd = send_gtk_offload_cmd_tlv,
22575 	.send_process_gtk_offload_getinfo_cmd =
22576 		send_process_gtk_offload_getinfo_cmd_tlv,
22577 	.send_enable_enhance_multicast_offload_cmd =
22578 		send_enable_enhance_multicast_offload_tlv,
22579 	.extract_gtk_rsp_event = extract_gtk_rsp_event_tlv,
22580 #ifdef FEATURE_WLAN_RA_FILTERING
22581 	.send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv,
22582 #endif
22583 	.send_action_frame_patterns_cmd = send_action_frame_patterns_cmd_tlv,
22584 	.send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv,
22585 	.send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv,
22586 	.send_lphb_config_tcp_pkt_filter_cmd =
22587 		send_lphb_config_tcp_pkt_filter_cmd_tlv,
22588 	.send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv,
22589 	.send_lphb_config_udp_pkt_filter_cmd =
22590 		send_lphb_config_udp_pkt_filter_cmd_tlv,
22591 #ifdef WLAN_FEATURE_PACKET_FILTERING
22592 	.send_enable_disable_packet_filter_cmd =
22593 		send_enable_disable_packet_filter_cmd_tlv,
22594 	.send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv,
22595 #endif
22596 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */
22597 #ifdef CONFIG_MCL
22598 	.send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv,
22599 	.send_get_link_speed_cmd = send_get_link_speed_cmd_tlv,
22600 	.send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv,
22601 	.send_roam_scan_offload_mode_cmd =
22602 			send_roam_scan_offload_mode_cmd_tlv,
22603 #ifndef REMOVE_PKT_LOG
22604 	.send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv,
22605 #endif
22606 	.send_roam_scan_offload_ap_profile_cmd =
22607 			send_roam_scan_offload_ap_profile_cmd_tlv,
22608 #endif
22609 #ifdef WLAN_SUPPORT_GREEN_AP
22610 	.send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv,
22611 	.send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv,
22612 	.extract_green_ap_egap_status_info =
22613 			extract_green_ap_egap_status_info_tlv,
22614 #endif
22615 	.send_fw_profiling_cmd = send_fw_profiling_cmd_tlv,
22616 	.send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv,
22617 	.send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv,
22618 	.send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv,
22619 	.send_start_oem_data_cmd = send_start_oem_data_cmd_tlv,
22620 #ifdef WLAN_FEATURE_CIF_CFR
22621 	.send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv,
22622 #endif
22623 	.send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv,
22624 	.send_dfs_phyerr_filter_offload_en_cmd =
22625 		 send_dfs_phyerr_filter_offload_en_cmd_tlv,
22626 	.send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv,
22627 	.send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv,
22628 	.send_del_ts_cmd = send_del_ts_cmd_tlv,
22629 	.send_aggr_qos_cmd = send_aggr_qos_cmd_tlv,
22630 	.send_add_ts_cmd = send_add_ts_cmd_tlv,
22631 	.send_process_add_periodic_tx_ptrn_cmd =
22632 		send_process_add_periodic_tx_ptrn_cmd_tlv,
22633 	.send_process_del_periodic_tx_ptrn_cmd =
22634 		send_process_del_periodic_tx_ptrn_cmd_tlv,
22635 	.send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv,
22636 	.send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv,
22637 	.send_set_app_type2_params_in_fw_cmd =
22638 		send_set_app_type2_params_in_fw_cmd_tlv,
22639 	.send_set_auto_shutdown_timer_cmd =
22640 		send_set_auto_shutdown_timer_cmd_tlv,
22641 	.send_nan_req_cmd = send_nan_req_cmd_tlv,
22642 	.send_process_dhcpserver_offload_cmd =
22643 		send_process_dhcpserver_offload_cmd_tlv,
22644 	.send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv,
22645 	.send_process_ch_avoid_update_cmd =
22646 		send_process_ch_avoid_update_cmd_tlv,
22647 	.send_pdev_set_regdomain_cmd =
22648 				send_pdev_set_regdomain_cmd_tlv,
22649 	.send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv,
22650 	.send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv,
22651 	.send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv,
22652 	.send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv,
22653 	.send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv,
22654 	.save_fw_version_cmd = save_fw_version_cmd_tlv,
22655 	.check_and_update_fw_version =
22656 		 check_and_update_fw_version_cmd_tlv,
22657 	.send_set_base_macaddr_indicate_cmd =
22658 		 send_set_base_macaddr_indicate_cmd_tlv,
22659 	.send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv,
22660 	.send_enable_specific_fw_logs_cmd =
22661 		 send_enable_specific_fw_logs_cmd_tlv,
22662 	.send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv,
22663 	.send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv,
22664 	.send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv,
22665 #ifdef WLAN_POLICY_MGR_ENABLE
22666 	.send_pdev_set_dual_mac_config_cmd =
22667 		 send_pdev_set_dual_mac_config_cmd_tlv,
22668 #endif
22669 	.send_app_type1_params_in_fw_cmd =
22670 		 send_app_type1_params_in_fw_cmd_tlv,
22671 	.send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv,
22672 	.send_process_roam_synch_complete_cmd =
22673 		 send_process_roam_synch_complete_cmd_tlv,
22674 	.send_unit_test_cmd = send_unit_test_cmd_tlv,
22675 	.send_roam_invoke_cmd = send_roam_invoke_cmd_tlv,
22676 	.send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv,
22677 	.send_roam_scan_offload_scan_period_cmd =
22678 		 send_roam_scan_offload_scan_period_cmd_tlv,
22679 	.send_roam_scan_offload_chan_list_cmd =
22680 		 send_roam_scan_offload_chan_list_cmd_tlv,
22681 	.send_roam_scan_offload_rssi_change_cmd =
22682 		 send_roam_scan_offload_rssi_change_cmd_tlv,
22683 #ifdef FEATURE_WLAN_APF
22684 	.send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv,
22685 	.send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv,
22686 	.send_apf_write_work_memory_cmd =
22687 				wmi_send_apf_write_work_memory_cmd_tlv,
22688 	.send_apf_read_work_memory_cmd =
22689 				wmi_send_apf_read_work_memory_cmd_tlv,
22690 	.extract_apf_read_memory_resp_event =
22691 				wmi_extract_apf_read_memory_resp_event_tlv,
22692 #endif /* FEATURE_WLAN_APF */
22693 	.send_adapt_dwelltime_params_cmd =
22694 		send_adapt_dwelltime_params_cmd_tlv,
22695 	.send_dbs_scan_sel_params_cmd =
22696 		send_dbs_scan_sel_params_cmd_tlv,
22697 	.init_cmd_send = init_cmd_send_tlv,
22698 	.send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv,
22699 	.send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv,
22700 	.send_set_ctl_table_cmd = send_set_ctl_table_cmd_tlv,
22701 	.send_set_mimogain_table_cmd = send_set_mimogain_table_cmd_tlv,
22702 	.send_packet_power_info_get_cmd = send_packet_power_info_get_cmd_tlv,
22703 	.send_vdev_config_ratemask_cmd = send_vdev_config_ratemask_cmd_tlv,
22704 	.send_vdev_set_custom_aggr_size_cmd =
22705 		send_vdev_set_custom_aggr_size_cmd_tlv,
22706 	.send_vdev_set_qdepth_thresh_cmd =
22707 		send_vdev_set_qdepth_thresh_cmd_tlv,
22708 	.send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv,
22709 	.send_vdev_set_neighbour_rx_cmd = send_vdev_set_neighbour_rx_cmd_tlv,
22710 	.send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_tlv,
22711 	.send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_tlv,
22712 	.send_smart_ant_set_training_info_cmd =
22713 		send_smart_ant_set_training_info_cmd_tlv,
22714 	.send_smart_ant_set_node_config_cmd =
22715 		send_smart_ant_set_node_config_cmd_tlv,
22716 #ifdef WLAN_ATF_ENABLE
22717 	.send_set_atf_cmd = send_set_atf_cmd_tlv,
22718 #endif
22719 	.send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv,
22720 	.send_set_qboost_param_cmd = send_set_qboost_param_cmd_tlv,
22721 	.send_gpio_config_cmd = send_gpio_config_cmd_tlv,
22722 	.send_gpio_output_cmd = send_gpio_output_cmd_tlv,
22723 	.send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv,
22724 	.send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv,
22725 	.send_periodic_chan_stats_config_cmd =
22726 		send_periodic_chan_stats_config_cmd_tlv,
22727 	.send_nf_dbr_dbm_info_get_cmd = send_nf_dbr_dbm_info_get_cmd_tlv,
22728 	.send_set_ht_ie_cmd = send_set_ht_ie_cmd_tlv,
22729 	.send_set_vht_ie_cmd = send_set_vht_ie_cmd_tlv,
22730 	.send_set_quiet_mode_cmd = send_set_quiet_mode_cmd_tlv,
22731 	.send_set_bwf_cmd = send_set_bwf_cmd_tlv,
22732 	.send_mcast_group_update_cmd = send_mcast_group_update_cmd_tlv,
22733 	.send_vdev_spectral_configure_cmd =
22734 				send_vdev_spectral_configure_cmd_tlv,
22735 	.send_vdev_spectral_enable_cmd =
22736 				send_vdev_spectral_enable_cmd_tlv,
22737 	.send_thermal_mitigation_param_cmd =
22738 		send_thermal_mitigation_param_cmd_tlv,
22739 	.send_pdev_qvit_cmd = send_pdev_qvit_cmd_tlv,
22740 	.send_wmm_update_cmd = send_wmm_update_cmd_tlv,
22741 	.send_process_update_edca_param_cmd =
22742 				 send_process_update_edca_param_cmd_tlv,
22743 	.send_coex_config_cmd = send_coex_config_cmd_tlv,
22744 	.send_set_country_cmd = send_set_country_cmd_tlv,
22745 	.send_bcn_offload_control_cmd = send_bcn_offload_control_cmd_tlv,
22746 	.send_addba_send_cmd = send_addba_send_cmd_tlv,
22747 	.send_delba_send_cmd = send_delba_send_cmd_tlv,
22748 	.send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv,
22749 	.get_target_cap_from_service_ready = extract_service_ready_tlv,
22750 	.extract_hal_reg_cap = extract_hal_reg_cap_tlv,
22751 	.extract_host_mem_req = extract_host_mem_req_tlv,
22752 	.save_service_bitmap = save_service_bitmap_tlv,
22753 	.save_ext_service_bitmap = save_ext_service_bitmap_tlv,
22754 	.is_service_enabled = is_service_enabled_tlv,
22755 	.save_fw_version = save_fw_version_in_service_ready_tlv,
22756 	.ready_extract_init_status = ready_extract_init_status_tlv,
22757 	.ready_extract_mac_addr = ready_extract_mac_addr_tlv,
22758 	.ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv,
22759 	.extract_ready_event_params = extract_ready_event_params_tlv,
22760 	.extract_dbglog_data_len = extract_dbglog_data_len_tlv,
22761 	.extract_vdev_start_resp = extract_vdev_start_resp_tlv,
22762 	.extract_vdev_delete_resp = extract_vdev_delete_resp_tlv,
22763 	.extract_tbttoffset_update_params =
22764 				extract_tbttoffset_update_params_tlv,
22765 	.extract_ext_tbttoffset_update_params =
22766 				extract_ext_tbttoffset_update_params_tlv,
22767 	.extract_tbttoffset_num_vdevs =
22768 				extract_tbttoffset_num_vdevs_tlv,
22769 	.extract_ext_tbttoffset_num_vdevs =
22770 				extract_ext_tbttoffset_num_vdevs_tlv,
22771 	.extract_mgmt_rx_params = extract_mgmt_rx_params_tlv,
22772 	.extract_vdev_stopped_param = extract_vdev_stopped_param_tlv,
22773 	.extract_vdev_roam_param = extract_vdev_roam_param_tlv,
22774 	.extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv,
22775 #ifdef CONVERGED_TDLS_ENABLE
22776 	.extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv,
22777 #endif
22778 	.extract_mgmt_tx_compl_param = extract_mgmt_tx_compl_param_tlv,
22779 	.extract_swba_num_vdevs = extract_swba_num_vdevs_tlv,
22780 	.extract_swba_tim_info = extract_swba_tim_info_tlv,
22781 	.extract_swba_noa_info = extract_swba_noa_info_tlv,
22782 #ifdef CONVERGED_P2P_ENABLE
22783 	.extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv,
22784 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
22785 	.extract_p2p_lo_stop_ev_param =
22786 				extract_p2p_lo_stop_ev_param_tlv,
22787 #endif
22788 #endif
22789 	.extract_offchan_data_tx_compl_param =
22790 				extract_offchan_data_tx_compl_param_tlv,
22791 	.extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv,
22792 	.extract_all_stats_count = extract_all_stats_counts_tlv,
22793 	.extract_pdev_stats = extract_pdev_stats_tlv,
22794 	.extract_unit_test = extract_unit_test_tlv,
22795 	.extract_pdev_ext_stats = extract_pdev_ext_stats_tlv,
22796 	.extract_vdev_stats = extract_vdev_stats_tlv,
22797 	.extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv,
22798 	.extract_peer_stats = extract_peer_stats_tlv,
22799 	.extract_bcn_stats = extract_bcn_stats_tlv,
22800 	.extract_bcnflt_stats = extract_bcnflt_stats_tlv,
22801 	.extract_peer_extd_stats = extract_peer_extd_stats_tlv,
22802 	.extract_chan_stats = extract_chan_stats_tlv,
22803 	.extract_profile_ctx = extract_profile_ctx_tlv,
22804 	.extract_profile_data = extract_profile_data_tlv,
22805 	.extract_chan_info_event = extract_chan_info_event_tlv,
22806 	.extract_channel_hopping_event = extract_channel_hopping_event_tlv,
22807 	.send_fw_test_cmd = send_fw_test_cmd_tlv,
22808 #ifdef WLAN_FEATURE_DISA
22809 	.send_encrypt_decrypt_send_cmd =
22810 				send_encrypt_decrypt_send_cmd_tlv,
22811 	.extract_encrypt_decrypt_resp_event =
22812 				extract_encrypt_decrypt_resp_event_tlv,
22813 #endif
22814 	.send_sar_limit_cmd = send_sar_limit_cmd_tlv,
22815 	.get_sar_limit_cmd = get_sar_limit_cmd_tlv,
22816 	.extract_sar_limit_event = extract_sar_limit_event_tlv,
22817 	.extract_sar2_result_event = extract_sar2_result_event_tlv,
22818 	.send_power_dbg_cmd = send_power_dbg_cmd_tlv,
22819 	.send_multiple_vdev_restart_req_cmd =
22820 				send_multiple_vdev_restart_req_cmd_tlv,
22821 	.extract_service_ready_ext = extract_service_ready_ext_tlv,
22822 	.extract_hw_mode_cap_service_ready_ext =
22823 				extract_hw_mode_cap_service_ready_ext_tlv,
22824 	.extract_mac_phy_cap_service_ready_ext =
22825 				extract_mac_phy_cap_service_ready_ext_tlv,
22826 	.extract_reg_cap_service_ready_ext =
22827 				extract_reg_cap_service_ready_ext_tlv,
22828 	.extract_dbr_ring_cap_service_ready_ext =
22829 				extract_dbr_ring_cap_service_ready_ext_tlv,
22830 	.extract_sar_cap_service_ready_ext =
22831 				extract_sar_cap_service_ready_ext_tlv,
22832 	.extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv,
22833 	.extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv,
22834 	.extract_dbr_buf_metadata = extract_dbr_buf_metadata_tlv,
22835 	.extract_pdev_utf_event = extract_pdev_utf_event_tlv,
22836 	.wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv,
22837 	.extract_dcs_interference_type = extract_dcs_interference_type_tlv,
22838 	.extract_dcs_cw_int = extract_dcs_cw_int_tlv,
22839 	.extract_dcs_im_tgt_stats = extract_dcs_im_tgt_stats_tlv,
22840 	.extract_fips_event_data = extract_fips_event_data_tlv,
22841 	.send_pdev_fips_cmd = send_pdev_fips_cmd_tlv,
22842 	.extract_peer_delete_response_event =
22843 				extract_peer_delete_response_event_tlv,
22844 	.is_management_record = is_management_record_tlv,
22845 	.extract_pdev_csa_switch_count_status =
22846 				extract_pdev_csa_switch_count_status_tlv,
22847 	.extract_pdev_tpc_ev_param = extract_pdev_tpc_ev_param_tlv,
22848 	.extract_pdev_tpc_config_ev_param =
22849 			extract_pdev_tpc_config_ev_param_tlv,
22850 	.extract_nfcal_power_ev_param = extract_nfcal_power_ev_param_tlv,
22851 	.extract_wds_addr_event = extract_wds_addr_event_tlv,
22852 	.extract_peer_sta_ps_statechange_ev =
22853 		extract_peer_sta_ps_statechange_ev_tlv,
22854 	.extract_inst_rssi_stats_event = extract_inst_rssi_stats_event_tlv,
22855 	.send_per_roam_config_cmd = send_per_roam_config_cmd_tlv,
22856 #ifdef WLAN_FEATURE_ACTION_OUI
22857 	.send_action_oui_cmd = send_action_oui_cmd_tlv,
22858 #endif
22859 	.send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv,
22860 	.send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv,
22861 	.extract_reg_chan_list_update_event =
22862 		extract_reg_chan_list_update_event_tlv,
22863 	.extract_chainmask_tables =
22864 		extract_chainmask_tables_tlv,
22865 	.extract_thermal_stats = extract_thermal_stats_tlv,
22866 	.extract_thermal_level_stats = extract_thermal_level_stats_tlv,
22867 	.send_get_rcpi_cmd = send_get_rcpi_cmd_tlv,
22868 	.extract_rcpi_response_event = extract_rcpi_response_event_tlv,
22869 #ifdef DFS_COMPONENT_ENABLE
22870 	.extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv,
22871 	.extract_dfs_radar_detection_event =
22872 		extract_dfs_radar_detection_event_tlv,
22873 	.extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv,
22874 #endif
22875 	.convert_pdev_id_host_to_target =
22876 		convert_host_pdev_id_to_target_pdev_id_legacy,
22877 	.convert_pdev_id_target_to_host =
22878 		convert_target_pdev_id_to_host_pdev_id_legacy,
22879 
22880 	.send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv,
22881 	.send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv,
22882 	.extract_reg_11d_new_country_event =
22883 		extract_reg_11d_new_country_event_tlv,
22884 	.send_user_country_code_cmd = send_user_country_code_cmd_tlv,
22885 	.send_limit_off_chan_cmd =
22886 		send_limit_off_chan_cmd_tlv,
22887 	.extract_reg_ch_avoid_event =
22888 		extract_reg_ch_avoid_event_tlv,
22889 	.send_pdev_caldata_version_check_cmd =
22890 			send_pdev_caldata_version_check_cmd_tlv,
22891 	.extract_pdev_caldata_version_check_ev_param =
22892 			extract_pdev_caldata_version_check_ev_param_tlv,
22893 	.send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv,
22894 	.send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv,
22895 	.send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv,
22896 #if defined(WLAN_FEATURE_FILS_SK)
22897 	.send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv,
22898 #endif
22899 	.send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv,
22900 #ifdef WLAN_FEATURE_NAN_CONVERGENCE
22901 	.send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv,
22902 	.send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv,
22903 	.send_ndp_end_req_cmd = nan_ndp_end_req_tlv,
22904 	.extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv,
22905 	.extract_ndp_ind = extract_ndp_ind_tlv,
22906 	.extract_ndp_confirm = extract_ndp_confirm_tlv,
22907 	.extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv,
22908 	.extract_ndp_end_rsp = extract_ndp_end_rsp_tlv,
22909 	.extract_ndp_end_ind = extract_ndp_end_ind_tlv,
22910 	.extract_ndp_sch_update = extract_ndp_sch_update_tlv,
22911 #endif
22912 	.send_btm_config = send_btm_config_cmd_tlv,
22913 	.send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv,
22914 	.extract_obss_detection_info = extract_obss_detection_info_tlv,
22915 #ifdef WLAN_SUPPORT_FILS
22916 	.send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_tlv,
22917 	.extract_swfda_vdev_id = extract_swfda_vdev_id_tlv,
22918 	.send_fils_discovery_send_cmd = send_fils_discovery_send_cmd_tlv,
22919 #endif /* WLAN_SUPPORT_FILS */
22920 	.send_offload_11k_cmd = send_offload_11k_cmd_tlv,
22921 	.send_invoke_neighbor_report_cmd = send_invoke_neighbor_report_cmd_tlv,
22922 	.wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable,
22923 	.wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs,
22924 	.wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs,
22925 	.wmi_check_command_params = wmitlv_check_command_tlv_params,
22926 	.send_bss_color_change_enable_cmd =
22927 		send_bss_color_change_enable_cmd_tlv,
22928 	.send_obss_color_collision_cfg_cmd =
22929 		send_obss_color_collision_cfg_cmd_tlv,
22930 	.extract_obss_color_collision_info =
22931 		extract_obss_color_collision_info_tlv,
22932 	.extract_comb_phyerr = extract_comb_phyerr_tlv,
22933 	.extract_single_phyerr = extract_single_phyerr_tlv,
22934 #ifdef QCA_SUPPORT_CP_STATS
22935 	.extract_cca_stats = extract_cca_stats_tlv,
22936 #endif
22937 	.extract_esp_estimation_ev_param =
22938 				extract_esp_estimation_ev_param_tlv,
22939 	.send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv,
22940 	.extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv,
22941 };
22942 
22943 /**
22944  * populate_tlv_event_id() - populates wmi event ids
22945  *
22946  * @param event_ids: Pointer to hold event ids
22947  * Return: None
22948  */
22949 static void populate_tlv_events_id(uint32_t *event_ids)
22950 {
22951 	event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID;
22952 	event_ids[wmi_ready_event_id] = WMI_READY_EVENTID;
22953 	event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID;
22954 	event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID;
22955 	event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID;
22956 	event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID;
22957 	event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID;
22958 	event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID;
22959 	event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID;
22960 	event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID;
22961 	event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID;
22962 	event_ids[wmi_service_ready_ext_event_id] =
22963 						WMI_SERVICE_READY_EXT_EVENTID;
22964 	event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID;
22965 	event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID;
22966 	event_ids[wmi_vdev_install_key_complete_event_id] =
22967 				WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID;
22968 	event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] =
22969 				WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID;
22970 
22971 	event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID;
22972 	event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID;
22973 	event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID;
22974 	event_ids[wmi_peer_tx_fail_cnt_thr_event_id] =
22975 				WMI_PEER_TX_FAIL_CNT_THR_EVENTID;
22976 	event_ids[wmi_peer_estimated_linkspeed_event_id] =
22977 				WMI_PEER_ESTIMATED_LINKSPEED_EVENTID;
22978 	event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID;
22979 	event_ids[wmi_peer_delete_response_event_id] =
22980 					WMI_PEER_DELETE_RESP_EVENTID;
22981 	event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID;
22982 	event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID;
22983 	event_ids[wmi_tbttoffset_update_event_id] =
22984 					WMI_TBTTOFFSET_UPDATE_EVENTID;
22985 	event_ids[wmi_ext_tbttoffset_update_event_id] =
22986 					WMI_TBTTOFFSET_EXT_UPDATE_EVENTID;
22987 	event_ids[wmi_offload_bcn_tx_status_event_id] =
22988 				WMI_OFFLOAD_BCN_TX_STATUS_EVENTID;
22989 	event_ids[wmi_offload_prob_resp_tx_status_event_id] =
22990 				WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID;
22991 	event_ids[wmi_mgmt_tx_completion_event_id] =
22992 				WMI_MGMT_TX_COMPLETION_EVENTID;
22993 	event_ids[wmi_pdev_nfcal_power_all_channels_event_id] =
22994 				WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID;
22995 	event_ids[wmi_tx_delba_complete_event_id] =
22996 					WMI_TX_DELBA_COMPLETE_EVENTID;
22997 	event_ids[wmi_tx_addba_complete_event_id] =
22998 					WMI_TX_ADDBA_COMPLETE_EVENTID;
22999 	event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID;
23000 
23001 	event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID;
23002 
23003 	event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID;
23004 	event_ids[wmi_profile_match] = WMI_PROFILE_MATCH;
23005 
23006 	event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID;
23007 	event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID;
23008 
23009 	event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID;
23010 
23011 	event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID;
23012 	event_ids[wmi_p2p_lo_stop_event_id] =
23013 				WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID;
23014 	event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID;
23015 	event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID;
23016 	event_ids[wmi_d0_wow_disable_ack_event_id] =
23017 				WMI_D0_WOW_DISABLE_ACK_EVENTID;
23018 	event_ids[wmi_wow_initial_wakeup_event_id] =
23019 				WMI_WOW_INITIAL_WAKEUP_EVENTID;
23020 
23021 	event_ids[wmi_rtt_meas_report_event_id] =
23022 				WMI_RTT_MEASUREMENT_REPORT_EVENTID;
23023 	event_ids[wmi_tsf_meas_report_event_id] =
23024 				WMI_TSF_MEASUREMENT_REPORT_EVENTID;
23025 	event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID;
23026 	event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID;
23027 	event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID;
23028 	event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID;
23029 	event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID;
23030 	event_ids[wmi_diag_event_id_log_supported_event_id] =
23031 				WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID;
23032 	event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID;
23033 	event_ids[wmi_nlo_scan_complete_event_id] =
23034 					WMI_NLO_SCAN_COMPLETE_EVENTID;
23035 	event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID;
23036 	event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID;
23037 
23038 	event_ids[wmi_gtk_offload_status_event_id] =
23039 				WMI_GTK_OFFLOAD_STATUS_EVENTID;
23040 	event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID;
23041 	event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID;
23042 	event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID;
23043 
23044 	event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID;
23045 
23046 	event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID;
23047 
23048 	event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID;
23049 	event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID;
23050 	event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID;
23051 	event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID;
23052 	event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID;
23053 	event_ids[wmi_wlan_profile_data_event_id] =
23054 						WMI_WLAN_PROFILE_DATA_EVENTID;
23055 	event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID;
23056 	event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID;
23057 	event_ids[wmi_vdev_get_keepalive_event_id] =
23058 				WMI_VDEV_GET_KEEPALIVE_EVENTID;
23059 	event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID;
23060 
23061 	event_ids[wmi_diag_container_event_id] =
23062 						WMI_DIAG_DATA_CONTAINER_EVENTID;
23063 
23064 	event_ids[wmi_host_auto_shutdown_event_id] =
23065 				WMI_HOST_AUTO_SHUTDOWN_EVENTID;
23066 
23067 	event_ids[wmi_update_whal_mib_stats_event_id] =
23068 				WMI_UPDATE_WHAL_MIB_STATS_EVENTID;
23069 
23070 	/*update ht/vht info based on vdev (rx and tx NSS and preamble) */
23071 	event_ids[wmi_update_vdev_rate_stats_event_id] =
23072 				WMI_UPDATE_VDEV_RATE_STATS_EVENTID;
23073 
23074 	event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID;
23075 	event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID;
23076 
23077 	/** Set OCB Sched Response, deprecated */
23078 	event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID;
23079 
23080 	event_ids[wmi_dbg_mesg_flush_complete_event_id] =
23081 				WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID;
23082 	event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID;
23083 
23084 	/* GPIO Event */
23085 	event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID;
23086 	event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID;
23087 
23088 	event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID;
23089 	event_ids[wmi_rfkill_state_change_event_id] =
23090 				WMI_RFKILL_STATE_CHANGE_EVENTID;
23091 
23092 	/* TDLS Event */
23093 	event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID;
23094 
23095 	event_ids[wmi_batch_scan_enabled_event_id] =
23096 				WMI_BATCH_SCAN_ENABLED_EVENTID;
23097 	event_ids[wmi_batch_scan_result_event_id] =
23098 				WMI_BATCH_SCAN_RESULT_EVENTID;
23099 	/* OEM Event */
23100 	event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID;
23101 	event_ids[wmi_oem_meas_report_event_id] =
23102 				WMI_OEM_MEASUREMENT_REPORT_EVENTID;
23103 	event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID;
23104 
23105 	/* NAN Event */
23106 	event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID;
23107 
23108 	/* LPI Event */
23109 	event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID;
23110 	event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID;
23111 	event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID;
23112 
23113 	/* ExtScan events */
23114 	event_ids[wmi_extscan_start_stop_event_id] =
23115 				WMI_EXTSCAN_START_STOP_EVENTID;
23116 	event_ids[wmi_extscan_operation_event_id] =
23117 				WMI_EXTSCAN_OPERATION_EVENTID;
23118 	event_ids[wmi_extscan_table_usage_event_id] =
23119 				WMI_EXTSCAN_TABLE_USAGE_EVENTID;
23120 	event_ids[wmi_extscan_cached_results_event_id] =
23121 				WMI_EXTSCAN_CACHED_RESULTS_EVENTID;
23122 	event_ids[wmi_extscan_wlan_change_results_event_id] =
23123 				WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID;
23124 	event_ids[wmi_extscan_hotlist_match_event_id] =
23125 				WMI_EXTSCAN_HOTLIST_MATCH_EVENTID;
23126 	event_ids[wmi_extscan_capabilities_event_id] =
23127 				WMI_EXTSCAN_CAPABILITIES_EVENTID;
23128 	event_ids[wmi_extscan_hotlist_ssid_match_event_id] =
23129 				WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID;
23130 
23131 	/* mDNS offload events */
23132 	event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID;
23133 
23134 	/* SAP Authentication offload events */
23135 	event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID;
23136 	event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID;
23137 
23138 	/** Out-of-context-of-bss (OCB) events */
23139 	event_ids[wmi_ocb_set_config_resp_event_id] =
23140 				WMI_OCB_SET_CONFIG_RESP_EVENTID;
23141 	event_ids[wmi_ocb_get_tsf_timer_resp_event_id] =
23142 				WMI_OCB_GET_TSF_TIMER_RESP_EVENTID;
23143 	event_ids[wmi_dcc_get_stats_resp_event_id] =
23144 				WMI_DCC_GET_STATS_RESP_EVENTID;
23145 	event_ids[wmi_dcc_update_ndl_resp_event_id] =
23146 				WMI_DCC_UPDATE_NDL_RESP_EVENTID;
23147 	event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID;
23148 	/* System-On-Chip events */
23149 	event_ids[wmi_soc_set_hw_mode_resp_event_id] =
23150 				WMI_SOC_SET_HW_MODE_RESP_EVENTID;
23151 	event_ids[wmi_soc_hw_mode_transition_event_id] =
23152 				WMI_SOC_HW_MODE_TRANSITION_EVENTID;
23153 	event_ids[wmi_soc_set_dual_mac_config_resp_event_id] =
23154 				WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID;
23155 	event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID;
23156 	event_ids[wmi_pdev_csa_switch_count_status_event_id] =
23157 				WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID;
23158 	event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID;
23159 	event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID;
23160 	event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID;
23161 	event_ids[wmi_peer_sta_ps_statechg_event_id] =
23162 					WMI_PEER_STA_PS_STATECHG_EVENTID;
23163 	event_ids[wmi_pdev_channel_hopping_event_id] =
23164 					WMI_PDEV_CHANNEL_HOPPING_EVENTID;
23165 	event_ids[wmi_offchan_data_tx_completion_event] =
23166 				WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID;
23167 	event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID;
23168 	event_ids[wmi_dfs_radar_detection_event_id] =
23169 		WMI_PDEV_DFS_RADAR_DETECTION_EVENTID;
23170 	event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID;
23171 	event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID;
23172 	event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID;
23173 	event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID;
23174 	event_ids[wmi_service_available_event_id] =
23175 						WMI_SERVICE_AVAILABLE_EVENTID;
23176 	event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID;
23177 	event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID;
23178 	/* NDP events */
23179 	event_ids[wmi_ndp_initiator_rsp_event_id] =
23180 		WMI_NDP_INITIATOR_RSP_EVENTID;
23181 	event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID;
23182 	event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID;
23183 	event_ids[wmi_ndp_responder_rsp_event_id] =
23184 		WMI_NDP_RESPONDER_RSP_EVENTID;
23185 	event_ids[wmi_ndp_end_indication_event_id] =
23186 		WMI_NDP_END_INDICATION_EVENTID;
23187 	event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID;
23188 	event_ids[wmi_ndl_schedule_update_event_id] =
23189 					WMI_NDL_SCHEDULE_UPDATE_EVENTID;
23190 
23191 	event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID;
23192 	event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID;
23193 	event_ids[wmi_pdev_chip_power_stats_event_id] =
23194 		WMI_PDEV_CHIP_POWER_STATS_EVENTID;
23195 	event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID;
23196 	event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID;
23197 	event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID;
23198 	event_ids[wmi_apf_capability_info_event_id] =
23199 		WMI_BPF_CAPABILIY_INFO_EVENTID;
23200 	event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] =
23201 		WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID;
23202 	event_ids[wmi_report_rx_aggr_failure_event_id] =
23203 		WMI_REPORT_RX_AGGR_FAILURE_EVENTID;
23204 	event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] =
23205 		WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID;
23206 	event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID;
23207 	event_ids[wmi_pdev_set_hw_mode_rsp_event_id] =
23208 		WMI_PDEV_SET_HW_MODE_RESP_EVENTID;
23209 	event_ids[wmi_pdev_hw_mode_transition_event_id] =
23210 		WMI_PDEV_HW_MODE_TRANSITION_EVENTID;
23211 	event_ids[wmi_pdev_set_mac_config_resp_event_id] =
23212 		WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID;
23213 	event_ids[wmi_coex_bt_activity_event_id] =
23214 		WMI_WLAN_COEX_BT_ACTIVITY_EVENTID;
23215 	event_ids[wmi_mgmt_tx_bundle_completion_event_id] =
23216 		WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID;
23217 	event_ids[wmi_radio_tx_power_level_stats_event_id] =
23218 		WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID;
23219 	event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID;
23220 	event_ids[wmi_dma_buf_release_event_id] =
23221 					WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID;
23222 	event_ids[wmi_sap_obss_detection_report_event_id] =
23223 		WMI_SAP_OBSS_DETECTION_REPORT_EVENTID;
23224 	event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID;
23225 	event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID;
23226 	event_ids[wmi_obss_color_collision_report_event_id] =
23227 		WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID;
23228 	event_ids[wmi_pdev_div_rssi_antid_event_id] =
23229 		WMI_PDEV_DIV_RSSI_ANTID_EVENTID;
23230 	event_ids[wmi_twt_enable_complete_event_id] =
23231 		WMI_TWT_ENABLE_COMPLETE_EVENTID;
23232 	event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] =
23233 		WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID;
23234 	event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID;
23235 	event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID;
23236 	event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID;
23237 }
23238 
23239 /**
23240  * populate_tlv_service() - populates wmi services
23241  *
23242  * @param wmi_service: Pointer to hold wmi_service
23243  * Return: None
23244  */
23245 static void populate_tlv_service(uint32_t *wmi_service)
23246 {
23247 	wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD;
23248 	wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT;
23249 	wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD;
23250 	wmi_service[wmi_service_roam_scan_offload] =
23251 					WMI_SERVICE_ROAM_SCAN_OFFLOAD;
23252 	wmi_service[wmi_service_bcn_miss_offload] =
23253 					WMI_SERVICE_BCN_MISS_OFFLOAD;
23254 	wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE;
23255 	wmi_service[wmi_service_sta_advanced_pwrsave] =
23256 				WMI_SERVICE_STA_ADVANCED_PWRSAVE;
23257 	wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD;
23258 	wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS;
23259 	wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC;
23260 	wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK;
23261 	wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR;
23262 	wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER;
23263 	wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT;
23264 	wmi_service[wmi_service_wow] = WMI_SERVICE_WOW;
23265 	wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE;
23266 	wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS;
23267 	wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD;
23268 	wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO;
23269 	wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD;
23270 	wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH;
23271 	wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD;
23272 	wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER;
23273 	wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID;
23274 	wmi_service[wmi_service_packet_power_save] =
23275 					WMI_SERVICE_PACKET_POWER_SAVE;
23276 	wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG;
23277 	wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO;
23278 	wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] =
23279 				WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM;
23280 	wmi_service[wmi_sta_uapsd_basic_auto_trig] =
23281 					WMI_STA_UAPSD_BASIC_AUTO_TRIG;
23282 	wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG;
23283 	wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE;
23284 	wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP;
23285 	wmi_service[wmi_service_ap_ps_detect_out_of_sync] =
23286 				WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC;
23287 	wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX;
23288 	wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS;
23289 	wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST;
23290 	wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC;
23291 	wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS;
23292 	wmi_service[wmi_service_burst] = WMI_SERVICE_BURST;
23293 	wmi_service[wmi_service_mcc_bcn_interval_change] =
23294 				WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE;
23295 	wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS;
23296 	wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT;
23297 	wmi_service[wmi_service_filter_ipsec_natkeepalive] =
23298 				WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE;
23299 	wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB;
23300 	wmi_service[wmi_service_lte_ant_share_support] =
23301 				WMI_SERVICE_LTE_ANT_SHARE_SUPPORT;
23302 	wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN;
23303 	wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER;
23304 	wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ;
23305 	wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT;
23306 	wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC;
23307 	wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD;
23308 	wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR;
23309 	wmi_service[wmi_service_bcn_txrate_override] =
23310 				WMI_SERVICE_BCN_TXRATE_OVERRIDE;
23311 	wmi_service[wmi_service_nan] = WMI_SERVICE_NAN;
23312 	wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT;
23313 	wmi_service[wmi_service_estimate_linkspeed] =
23314 				WMI_SERVICE_ESTIMATE_LINKSPEED;
23315 	wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN;
23316 	wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN;
23317 	wmi_service[wmi_service_tdls_uapsd_buffer_sta] =
23318 				WMI_SERVICE_TDLS_UAPSD_BUFFER_STA;
23319 	wmi_service[wmi_service_tdls_uapsd_sleep_sta] =
23320 				WMI_SERVICE_TDLS_UAPSD_SLEEP_STA;
23321 	wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE;
23322 	wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS;
23323 	wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN;
23324 	wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW;
23325 	wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD;
23326 	wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD;
23327 	wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER;
23328 	wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD;
23329 	wmi_service[wmi_service_sta_rx_ipa_offload_support] =
23330 				WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT;
23331 	wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD;
23332 	wmi_service[wmi_service_sap_auth_offload] =
23333 					WMI_SERVICE_SAP_AUTH_OFFLOAD;
23334 	wmi_service[wmi_service_dual_band_simultaneous_support] =
23335 				WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT;
23336 	wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB;
23337 	wmi_service[wmi_service_ap_arpns_offload] =
23338 					WMI_SERVICE_AP_ARPNS_OFFLOAD;
23339 	wmi_service[wmi_service_per_band_chainmask_support] =
23340 				WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT;
23341 	wmi_service[wmi_service_packet_filter_offload] =
23342 				WMI_SERVICE_PACKET_FILTER_OFFLOAD;
23343 	wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT;
23344 	wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI;
23345 	wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG;
23346 	wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC;
23347 	wmi_service[wmi_service_multiple_vdev_restart] =
23348 			WMI_SERVICE_MULTIPLE_VDEV_RESTART;
23349 
23350 	wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE;
23351 	wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE;
23352 	wmi_service[wmi_service_smart_antenna_sw_support] =
23353 				WMI_SERVICE_UNAVAILABLE;
23354 	wmi_service[wmi_service_smart_antenna_hw_support] =
23355 				WMI_SERVICE_UNAVAILABLE;
23356 	wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE;
23357 	wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT;
23358 	wmi_service[wmi_service_atf] = WMI_SERVICE_ATF;
23359 	wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE;
23360 	wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE;
23361 	wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE;
23362 	wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE;
23363 	wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE;
23364 	wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE;
23365 	wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE;
23366 	wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE;
23367 	wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE;
23368 	wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE;
23369 	wmi_service[wmi_service_periodic_chan_stat_support] =
23370 			WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT;
23371 	wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE;
23372 	wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE;
23373 	wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE;
23374 	wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE;
23375 	wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE;
23376 	wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH;
23377 	wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF;
23378 	wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP;
23379 	wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD;
23380 	wmi_service[wmi_service_unified_wow_capability] =
23381 				WMI_SERVICE_UNIFIED_WOW_CAPABILITY;
23382 	wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH;
23383 	wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD;
23384 	wmi_service[wmi_service_sync_delete_cmds] =
23385 				WMI_SERVICE_SYNC_DELETE_CMDS;
23386 	wmi_service[wmi_service_ratectrl_limit_max_min_rates] =
23387 				WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES;
23388 	wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA;
23389 	wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT;
23390 	wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX;
23391 	wmi_service[wmi_service_deprecated_replace] =
23392 				WMI_SERVICE_DEPRECATED_REPLACE;
23393 	wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] =
23394 				WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE;
23395 	wmi_service[wmi_service_enhanced_mcast_filter] =
23396 				WMI_SERVICE_ENHANCED_MCAST_FILTER;
23397 	wmi_service[wmi_service_half_rate_quarter_rate_support] =
23398 				WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT;
23399 	wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER;
23400 	wmi_service[wmi_service_p2p_listen_offload_support] =
23401 				WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT;
23402 	wmi_service[wmi_service_mark_first_wakeup_packet] =
23403 				WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET;
23404 	wmi_service[wmi_service_multiple_mcast_filter_set] =
23405 				WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET;
23406 	wmi_service[wmi_service_host_managed_rx_reorder] =
23407 				WMI_SERVICE_HOST_MANAGED_RX_REORDER;
23408 	wmi_service[wmi_service_flash_rdwr_support] =
23409 				WMI_SERVICE_FLASH_RDWR_SUPPORT;
23410 	wmi_service[wmi_service_wlan_stats_report] =
23411 				WMI_SERVICE_WLAN_STATS_REPORT;
23412 	wmi_service[wmi_service_tx_msdu_id_new_partition_support] =
23413 				WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT;
23414 	wmi_service[wmi_service_dfs_phyerr_offload] =
23415 				WMI_SERVICE_DFS_PHYERR_OFFLOAD;
23416 	wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT;
23417 	wmi_service[wmi_service_fw_mem_dump_support] =
23418 				WMI_SERVICE_FW_MEM_DUMP_SUPPORT;
23419 	wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO;
23420 	wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB;
23421 	wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD;
23422 	wmi_service[wmi_service_hw_data_filtering] =
23423 				WMI_SERVICE_HW_DATA_FILTERING;
23424 	wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING;
23425 	wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI;
23426 	wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO;
23427 	wmi_service[wmi_service_extended_nss_support] =
23428 				WMI_SERVICE_EXTENDED_NSS_SUPPORT;
23429 	wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT;
23430 	wmi_service[wmi_service_bcn_offload_start_stop_support] =
23431 				WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT;
23432 	wmi_service[wmi_service_offchan_data_tid_support] =
23433 				WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT;
23434 	wmi_service[wmi_service_support_dma] =
23435 				WMI_SERVICE_SUPPORT_DIRECT_DMA;
23436 	wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE;
23437 	wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT;
23438 	wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT;
23439 	wmi_service[wmi_service_wow_wakeup_by_timer_pattern] =
23440 				WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN;
23441 	wmi_service[wmi_service_11k_neighbour_report_support] =
23442 				WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT;
23443 	wmi_service[wmi_service_ap_obss_detection_offload] =
23444 				WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD;
23445 	wmi_service[wmi_service_bss_color_offload] =
23446 				WMI_SERVICE_BSS_COLOR_OFFLOAD;
23447 	wmi_service[wmi_service_gmac_offload_support] =
23448 				WMI_SERVICE_GMAC_OFFLOAD_SUPPORT;
23449 	wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] =
23450 			WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT;
23451 	wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] =
23452 			WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT;
23453 	wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT;
23454 	wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT;
23455 	wmi_service[wmi_service_listen_interval_offload_support] =
23456 			WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT;
23457 
23458 }
23459 
23460 #ifndef CONFIG_MCL
23461 
23462 /**
23463  * populate_pdev_param_tlv() - populates pdev params
23464  *
23465  * @param pdev_param: Pointer to hold pdev params
23466  * Return: None
23467  */
23468 static void populate_pdev_param_tlv(uint32_t *pdev_param)
23469 {
23470 	pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK;
23471 	pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK;
23472 	pdev_param[wmi_pdev_param_txpower_limit2g] =
23473 				WMI_PDEV_PARAM_TXPOWER_LIMIT2G;
23474 	pdev_param[wmi_pdev_param_txpower_limit5g] =
23475 				WMI_PDEV_PARAM_TXPOWER_LIMIT5G;
23476 	pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE;
23477 	pdev_param[wmi_pdev_param_beacon_gen_mode] =
23478 				WMI_PDEV_PARAM_BEACON_GEN_MODE;
23479 	pdev_param[wmi_pdev_param_beacon_tx_mode] =
23480 				WMI_PDEV_PARAM_BEACON_TX_MODE;
23481 	pdev_param[wmi_pdev_param_resmgr_offchan_mode] =
23482 				WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE;
23483 	pdev_param[wmi_pdev_param_protection_mode] =
23484 				WMI_PDEV_PARAM_PROTECTION_MODE;
23485 	pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW;
23486 	pdev_param[wmi_pdev_param_non_agg_sw_retry_th] =
23487 				WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH;
23488 	pdev_param[wmi_pdev_param_agg_sw_retry_th] =
23489 				WMI_PDEV_PARAM_AGG_SW_RETRY_TH;
23490 	pdev_param[wmi_pdev_param_sta_kickout_th] =
23491 				WMI_PDEV_PARAM_STA_KICKOUT_TH;
23492 	pdev_param[wmi_pdev_param_ac_aggrsize_scaling] =
23493 				WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING;
23494 	pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE;
23495 	pdev_param[wmi_pdev_param_ltr_ac_latency_be] =
23496 				WMI_PDEV_PARAM_LTR_AC_LATENCY_BE;
23497 	pdev_param[wmi_pdev_param_ltr_ac_latency_bk] =
23498 				WMI_PDEV_PARAM_LTR_AC_LATENCY_BK;
23499 	pdev_param[wmi_pdev_param_ltr_ac_latency_vi] =
23500 				WMI_PDEV_PARAM_LTR_AC_LATENCY_VI;
23501 	pdev_param[wmi_pdev_param_ltr_ac_latency_vo] =
23502 				WMI_PDEV_PARAM_LTR_AC_LATENCY_VO;
23503 	pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] =
23504 				WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT;
23505 	pdev_param[wmi_pdev_param_ltr_sleep_override] =
23506 				WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE;
23507 	pdev_param[wmi_pdev_param_ltr_rx_override] =
23508 				WMI_PDEV_PARAM_LTR_RX_OVERRIDE;
23509 	pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] =
23510 				WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT;
23511 	pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE;
23512 	pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE;
23513 	pdev_param[wmi_pdev_param_pcielp_txbuf_flush] =
23514 				WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH;
23515 	pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] =
23516 				WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK;
23517 	pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] =
23518 				WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN;
23519 	pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] =
23520 				WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE;
23521 	pdev_param[wmi_pdev_param_pdev_stats_update_period] =
23522 				WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD;
23523 	pdev_param[wmi_pdev_param_vdev_stats_update_period] =
23524 				WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD;
23525 	pdev_param[wmi_pdev_param_peer_stats_update_period] =
23526 				WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD;
23527 	pdev_param[wmi_pdev_param_bcnflt_stats_update_period] =
23528 				WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD;
23529 	pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS;
23530 	pdev_param[wmi_pdev_param_arp_ac_override] =
23531 				WMI_PDEV_PARAM_ARP_AC_OVERRIDE;
23532 	pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS;
23533 	pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE;
23534 	pdev_param[wmi_pdev_param_ani_poll_period] =
23535 				WMI_PDEV_PARAM_ANI_POLL_PERIOD;
23536 	pdev_param[wmi_pdev_param_ani_listen_period] =
23537 				WMI_PDEV_PARAM_ANI_LISTEN_PERIOD;
23538 	pdev_param[wmi_pdev_param_ani_ofdm_level] =
23539 				WMI_PDEV_PARAM_ANI_OFDM_LEVEL;
23540 	pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL;
23541 	pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN;
23542 	pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA;
23543 	pdev_param[wmi_pdev_param_idle_ps_config] =
23544 				WMI_PDEV_PARAM_IDLE_PS_CONFIG;
23545 	pdev_param[wmi_pdev_param_power_gating_sleep] =
23546 				WMI_PDEV_PARAM_POWER_GATING_SLEEP;
23547 	pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE;
23548 	pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR;
23549 	pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE;
23550 	pdev_param[wmi_pdev_param_hw_rfkill_config] =
23551 				WMI_PDEV_PARAM_HW_RFKILL_CONFIG;
23552 	pdev_param[wmi_pdev_param_low_power_rf_enable] =
23553 				WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE;
23554 	pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK;
23555 	pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN;
23556 	pdev_param[wmi_pdev_param_power_collapse_enable] =
23557 				WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE;
23558 	pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE;
23559 	pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE;
23560 	pdev_param[wmi_pdev_param_audio_over_wlan_latency] =
23561 				WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY;
23562 	pdev_param[wmi_pdev_param_audio_over_wlan_enable] =
23563 				WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE;
23564 	pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] =
23565 				WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE;
23566 	pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] =
23567 				WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD;
23568 	pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW;
23569 	pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG;
23570 	pdev_param[wmi_pdev_param_adaptive_early_rx_enable] =
23571 				WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE;
23572 	pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] =
23573 				WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP;
23574 	pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] =
23575 				WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP;
23576 	pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] =
23577 				WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP;
23578 	pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] =
23579 				WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE;
23580 	pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] =
23581 				WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT;
23582 	pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] =
23583 				WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP;
23584 	pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] =
23585 				WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT;
23586 	pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] =
23587 				WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE;
23588 	pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] =
23589 				WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE;
23590 	pdev_param[wmi_pdev_param_tx_chain_mask_2g] =
23591 				WMI_PDEV_PARAM_TX_CHAIN_MASK_2G;
23592 	pdev_param[wmi_pdev_param_rx_chain_mask_2g] =
23593 				WMI_PDEV_PARAM_RX_CHAIN_MASK_2G;
23594 	pdev_param[wmi_pdev_param_tx_chain_mask_5g] =
23595 				WMI_PDEV_PARAM_TX_CHAIN_MASK_5G;
23596 	pdev_param[wmi_pdev_param_rx_chain_mask_5g] =
23597 				WMI_PDEV_PARAM_RX_CHAIN_MASK_5G;
23598 	pdev_param[wmi_pdev_param_tx_chain_mask_cck] =
23599 				WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK;
23600 	pdev_param[wmi_pdev_param_tx_chain_mask_1ss] =
23601 				WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS;
23602 	pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER;
23603 	pdev_param[wmi_pdev_set_mcast_to_ucast_tid] =
23604 				WMI_PDEV_SET_MCAST_TO_UCAST_TID;
23605 	pdev_param[wmi_pdev_param_mgmt_retry_limit] =
23606 					WMI_PDEV_PARAM_MGMT_RETRY_LIMIT;
23607 	pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST;
23608 	pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] =
23609 					WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE;
23610 	pdev_param[wmi_pdev_param_proxy_sta_mode] =
23611 				WMI_PDEV_PARAM_PROXY_STA_MODE;
23612 	pdev_param[wmi_pdev_param_mu_group_policy] =
23613 				WMI_PDEV_PARAM_MU_GROUP_POLICY;
23614 	pdev_param[wmi_pdev_param_noise_detection] =
23615 				WMI_PDEV_PARAM_NOISE_DETECTION;
23616 	pdev_param[wmi_pdev_param_noise_threshold] =
23617 				WMI_PDEV_PARAM_NOISE_THRESHOLD;
23618 	pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE;
23619 	pdev_param[wmi_pdev_param_set_mcast_bcast_echo] =
23620 				WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO;
23621 	pdev_param[wmi_pdev_param_atf_strict_sch] =
23622 		WMI_PDEV_PARAM_ATF_STRICT_SCH;
23623 	pdev_param[wmi_pdev_param_atf_sched_duration] =
23624 		WMI_PDEV_PARAM_ATF_SCHED_DURATION;
23625 	pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN;
23626 	pdev_param[wmi_pdev_param_sensitivity_level] =
23627 				WMI_PDEV_PARAM_SENSITIVITY_LEVEL;
23628 	pdev_param[wmi_pdev_param_signed_txpower_2g] =
23629 				WMI_PDEV_PARAM_SIGNED_TXPOWER_2G;
23630 	pdev_param[wmi_pdev_param_signed_txpower_5g] =
23631 				WMI_PDEV_PARAM_SIGNED_TXPOWER_5G;
23632 	pdev_param[wmi_pdev_param_enable_per_tid_amsdu] =
23633 		WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU;
23634 	pdev_param[wmi_pdev_param_enable_per_tid_ampdu] =
23635 		WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU;
23636 	pdev_param[wmi_pdev_param_cca_threshold] =
23637 				WMI_PDEV_PARAM_CCA_THRESHOLD;
23638 	pdev_param[wmi_pdev_param_rts_fixed_rate] =
23639 				WMI_PDEV_PARAM_RTS_FIXED_RATE;
23640 	pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM;
23641 	pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET;
23642 	pdev_param[wmi_pdev_param_wapi_mbssid_offset] =
23643 				WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET;
23644 	pdev_param[wmi_pdev_param_arp_srcaddr] =
23645 				WMI_PDEV_PARAM_ARP_DBG_SRCADDR;
23646 	pdev_param[wmi_pdev_param_arp_dstaddr] =
23647 				WMI_PDEV_PARAM_ARP_DBG_DSTADDR;
23648 	pdev_param[wmi_pdev_param_txpower_decr_db] =
23649 				WMI_PDEV_PARAM_TXPOWER_DECR_DB;
23650 	pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM;
23651 	pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM;
23652 	pdev_param[wmi_pdev_param_atf_obss_noise_sch] =
23653 		WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH;
23654 	pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] =
23655 		WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR;
23656 	pdev_param[wmi_pdev_param_cust_txpower_scale] =
23657 				WMI_PDEV_PARAM_CUST_TXPOWER_SCALE;
23658 	pdev_param[wmi_pdev_param_atf_dynamic_enable] =
23659 		WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE;
23660 	pdev_param[wmi_pdev_param_atf_ssid_group_policy] =
23661 						WMI_UNAVAILABLE_PARAM;
23662 	pdev_param[wmi_pdev_param_igmpmld_override] =
23663 					WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE;
23664 	pdev_param[wmi_pdev_param_igmpmld_tid] =
23665 					WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE;
23666 	pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN;
23667 	pdev_param[wmi_pdev_param_block_interbss] =
23668 				WMI_PDEV_PARAM_BLOCK_INTERBSS;
23669 	pdev_param[wmi_pdev_param_set_disable_reset_cmdid] =
23670 				WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID;
23671 	pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] =
23672 				WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID;
23673 	pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] =
23674 				WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID;
23675 	pdev_param[wmi_pdev_param_set_burst_mode_cmdid] =
23676 					WMI_PDEV_PARAM_SET_BURST_MODE_CMDID;
23677 	pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS;
23678 	pdev_param[wmi_pdev_param_mesh_mcast_enable] =
23679 					WMI_PDEV_PARAM_MESH_MCAST_ENABLE;
23680 	pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] =
23681 					WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID;
23682 	pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] =
23683 					WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID;
23684 	pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] =
23685 				WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER;
23686 	pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] =
23687 				WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER;
23688 	pdev_param[wmi_pdev_param_set_mcast2ucast_mode] =
23689 				WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE;
23690 	pdev_param[wmi_pdev_param_smart_antenna_default_antenna] =
23691 				WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA;
23692 	pdev_param[wmi_pdev_param_fast_channel_reset] =
23693 				WMI_PDEV_PARAM_FAST_CHANNEL_RESET;
23694 	pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE;
23695 	pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT;
23696 	pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE;
23697 	pdev_param[wmi_pdev_param_antenna_gain_half_db] =
23698 		WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB;
23699 	pdev_param[wmi_pdev_param_esp_indication_period] =
23700 				WMI_PDEV_PARAM_ESP_INDICATION_PERIOD;
23701 #ifdef WLAN_RU26_SUPPORT
23702 	pdev_param[wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_RU26_ALLOWED;
23703 #endif
23704 }
23705 
23706 /**
23707  * populate_vdev_param_tlv() - populates vdev params
23708  *
23709  * @param vdev_param: Pointer to hold vdev params
23710  * Return: None
23711  */
23712 static void populate_vdev_param_tlv(uint32_t *vdev_param)
23713 {
23714 	vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD;
23715 	vdev_param[wmi_vdev_param_fragmentation_threshold] =
23716 				WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD;
23717 	vdev_param[wmi_vdev_param_beacon_interval] =
23718 				WMI_VDEV_PARAM_BEACON_INTERVAL;
23719 	vdev_param[wmi_vdev_param_listen_interval] =
23720 				WMI_VDEV_PARAM_LISTEN_INTERVAL;
23721 	vdev_param[wmi_vdev_param_multicast_rate] =
23722 				WMI_VDEV_PARAM_MULTICAST_RATE;
23723 	vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE;
23724 	vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME;
23725 	vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE;
23726 	vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME;
23727 	vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD;
23728 	vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME;
23729 	vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL;
23730 	vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD;
23731 	vdev_param[wmi_vdev_oc_scheduler_air_time_limit] =
23732 				WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT;
23733 	vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS;
23734 	vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW;
23735 	vdev_param[wmi_vdev_param_bmiss_count_max] =
23736 				WMI_VDEV_PARAM_BMISS_COUNT_MAX;
23737 	vdev_param[wmi_vdev_param_bmiss_first_bcnt] =
23738 				WMI_VDEV_PARAM_BMISS_FIRST_BCNT;
23739 	vdev_param[wmi_vdev_param_bmiss_final_bcnt] =
23740 				WMI_VDEV_PARAM_BMISS_FINAL_BCNT;
23741 	vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM;
23742 	vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH;
23743 	vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET;
23744 	vdev_param[wmi_vdev_param_disable_htprotection] =
23745 				WMI_VDEV_PARAM_DISABLE_HTPROTECTION;
23746 	vdev_param[wmi_vdev_param_sta_quickkickout] =
23747 				WMI_VDEV_PARAM_STA_QUICKKICKOUT;
23748 	vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE;
23749 	vdev_param[wmi_vdev_param_protection_mode] =
23750 				WMI_VDEV_PARAM_PROTECTION_MODE;
23751 	vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE;
23752 	vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI;
23753 	vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC;
23754 	vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC;
23755 	vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC;
23756 	vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD;
23757 	vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID;
23758 	vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS;
23759 	vdev_param[wmi_vdev_param_bcast_data_rate] =
23760 				WMI_VDEV_PARAM_BCAST_DATA_RATE;
23761 	vdev_param[wmi_vdev_param_mcast_data_rate] =
23762 				WMI_VDEV_PARAM_MCAST_DATA_RATE;
23763 	vdev_param[wmi_vdev_param_mcast_indicate] =
23764 				WMI_VDEV_PARAM_MCAST_INDICATE;
23765 	vdev_param[wmi_vdev_param_dhcp_indicate] =
23766 				WMI_VDEV_PARAM_DHCP_INDICATE;
23767 	vdev_param[wmi_vdev_param_unknown_dest_indicate] =
23768 				WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE;
23769 	vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] =
23770 		WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS;
23771 	vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] =
23772 		WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS;
23773 	vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] =
23774 		WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS;
23775 	vdev_param[wmi_vdev_param_ap_enable_nawds] =
23776 				WMI_VDEV_PARAM_AP_ENABLE_NAWDS;
23777 	vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS;
23778 	vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF;
23779 	vdev_param[wmi_vdev_param_packet_powersave] =
23780 				WMI_VDEV_PARAM_PACKET_POWERSAVE;
23781 	vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY;
23782 	vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
23783 	vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] =
23784 		WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS;
23785 	vdev_param[wmi_vdev_param_early_rx_adjust_enable] =
23786 				WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE;
23787 	vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] =
23788 				WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM;
23789 	vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] =
23790 				WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE;
23791 	vdev_param[wmi_vdev_param_early_rx_slop_step] =
23792 				WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP;
23793 	vdev_param[wmi_vdev_param_early_rx_init_slop] =
23794 				WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP;
23795 	vdev_param[wmi_vdev_param_early_rx_adjust_pause] =
23796 				WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE;
23797 	vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT;
23798 	vdev_param[wmi_vdev_param_snr_num_for_cal] =
23799 				WMI_VDEV_PARAM_SNR_NUM_FOR_CAL;
23800 	vdev_param[wmi_vdev_param_roam_fw_offload] =
23801 				WMI_VDEV_PARAM_ROAM_FW_OFFLOAD;
23802 	vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC;
23803 	vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] =
23804 				WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS;
23805 	vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE;
23806 	vdev_param[wmi_vdev_param_early_rx_drift_sample] =
23807 				WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE;
23808 	vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] =
23809 				WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR;
23810 	vdev_param[wmi_vdev_param_ebt_resync_timeout] =
23811 				WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT;
23812 	vdev_param[wmi_vdev_param_aggr_trig_event_enable] =
23813 				WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE;
23814 	vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] =
23815 				WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED;
23816 	vdev_param[wmi_vdev_param_is_power_collapse_allowed] =
23817 				WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED;
23818 	vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] =
23819 				WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED;
23820 	vdev_param[wmi_vdev_param_inactivity_cnt] =
23821 		WMI_VDEV_PARAM_INACTIVITY_CNT;
23822 	vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] =
23823 				WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS;
23824 	vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY;
23825 	vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] =
23826 				WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS;
23827 	vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] =
23828 			WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE;
23829 	vdev_param[wmi_vdev_param_rx_leak_window] =
23830 			WMI_VDEV_PARAM_RX_LEAK_WINDOW;
23831 	vdev_param[wmi_vdev_param_stats_avg_factor] =
23832 				WMI_VDEV_PARAM_STATS_AVG_FACTOR;
23833 	vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH;
23834 	vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE;
23835 	vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] =
23836 				WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE;
23837 	vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] =
23838 				WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE;
23839 	vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER;
23840 	vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE;
23841 	vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE;
23842 	vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM;
23843 	vdev_param[wmi_vdev_param_he_range_ext_enable] =
23844 				 WMI_VDEV_PARAM_HE_RANGE_EXT;
23845 	vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR;
23846 	vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE;
23847 	vdev_param[wmi_vdev_param_set_he_sounding_mode]
23848 					= WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE;
23849 	vdev_param[wmi_vdev_param_set_heop]      = WMI_VDEV_PARAM_HEOPS_0_31;
23850 	vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP;
23851 	vdev_param[wmi_vdev_param_dtim_enable_cts] =
23852 					WMI_VDEV_PARAM_DTIM_ENABLE_CTS;
23853 	vdev_param[wmi_vdev_param_atf_ssid_sched_policy] =
23854 					WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY;
23855 	vdev_param[wmi_vdev_param_disable_dyn_bw_rts] =
23856 					WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS;
23857 	vdev_param[wmi_vdev_param_mcast2ucast_set] =
23858 					WMI_VDEV_PARAM_MCAST2UCAST_SET;
23859 	vdev_param[wmi_vdev_param_rc_num_retries] =
23860 					WMI_VDEV_PARAM_RC_NUM_RETRIES;
23861 	vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR;
23862 	vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET;
23863 	vdev_param[wmi_vdev_param_rts_fixed_rate] =
23864 					WMI_VDEV_PARAM_RTS_FIXED_RATE;
23865 	vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK;
23866 	vdev_param[wmi_vdev_param_vht80_ratemask] =
23867 					WMI_VDEV_PARAM_VHT80_RATEMASK;
23868 	vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA;
23869 	vdev_param[wmi_vdev_param_bw_nss_ratemask] =
23870 					WMI_VDEV_PARAM_BW_NSS_RATEMASK;
23871 	vdev_param[wmi_vdev_param_set_he_ltf] =
23872 					WMI_VDEV_PARAM_HE_LTF;
23873 	vdev_param[wmi_vdev_param_disable_cabq] =
23874 					WMI_VDEV_PARAM_DISABLE_CABQ;
23875 	vdev_param[wmi_vdev_param_rate_dropdown_bmap] =
23876 					WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP;
23877 	vdev_param[wmi_vdev_param_set_ba_mode] =
23878 					WMI_VDEV_PARAM_BA_MODE;
23879 	vdev_param[wmi_vdev_param_capabilities] =
23880 					WMI_VDEV_PARAM_CAPABILITIES;
23881 	vdev_param[wmi_vdev_param_autorate_misc_cfg] =
23882 					WMI_VDEV_PARAM_AUTORATE_MISC_CFG;
23883 }
23884 #endif
23885 
23886 /**
23887  * populate_target_defines_tlv() - Populate target defines and params
23888  * @wmi_handle: pointer to wmi handle
23889  *
23890  * Return: None
23891  */
23892 #ifndef CONFIG_MCL
23893 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle)
23894 {
23895 	populate_pdev_param_tlv(wmi_handle->pdev_param);
23896 	populate_vdev_param_tlv(wmi_handle->vdev_param);
23897 }
23898 #else
23899 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle)
23900 { }
23901 #endif
23902 
23903 /**
23904  * wmi_ocb_ut_attach() - Attach OCB test framework
23905  * @wmi_handle: wmi handle
23906  *
23907  * Return: None
23908  */
23909 #ifdef WLAN_OCB_UT
23910 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle);
23911 #else
23912 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle)
23913 {
23914 	return;
23915 }
23916 #endif
23917 
23918 /**
23919  * wmi_tlv_attach() - Attach TLV APIs
23920  *
23921  * Return: None
23922  */
23923 void wmi_tlv_attach(wmi_unified_t wmi_handle)
23924 {
23925 	wmi_handle->ops = &tlv_ops;
23926 	wmi_ocb_ut_attach(wmi_handle);
23927 	wmi_handle->soc->svc_ids = &multi_svc_ids[0];
23928 #ifdef WMI_INTERFACE_EVENT_LOGGING
23929 	/* Skip saving WMI_CMD_HDR and TLV HDR */
23930 	wmi_handle->log_info.buf_offset_command = 8;
23931 	/* WMI_CMD_HDR is already stripped, skip saving TLV HDR */
23932 	wmi_handle->log_info.buf_offset_event = 4;
23933 #endif
23934 	populate_tlv_events_id(wmi_handle->wmi_events);
23935 	populate_tlv_service(wmi_handle->services);
23936 	populate_target_defines_tlv(wmi_handle);
23937 	wmi_twt_attach_tlv(wmi_handle);
23938 	wmi_extscan_attach_tlv(wmi_handle);
23939 }
23940 qdf_export_symbol(wmi_tlv_attach);
23941 
23942 /**
23943  * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine
23944  *
23945  * Return: None
23946  */
23947 void wmi_tlv_init(void)
23948 {
23949 	wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach);
23950 }
23951