xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_tlv.c (revision 302a1d9701784af5f4797b1a9fe07ae820b51907)
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 = param->peer_he_cap_macinfo;
2481 	cmd->peer_he_ops = param->peer_he_ops;
2482 	qdf_mem_copy(&cmd->peer_he_cap_phy, &param->peer_he_cap_phyinfo,
2483 				sizeof(param->peer_he_cap_phyinfo));
2484 	qdf_mem_copy(&cmd->peer_ppet, &param->peer_ppet,
2485 				sizeof(param->peer_ppet));
2486 
2487 	/* Update peer legacy rate information */
2488 	buf_ptr += sizeof(*cmd);
2489 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
2490 				peer_legacy_rates_align);
2491 	buf_ptr += WMI_TLV_HDR_SIZE;
2492 	cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates;
2493 	qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates,
2494 		     param->peer_legacy_rates.num_rates);
2495 
2496 	/* Update peer HT rate information */
2497 	buf_ptr += peer_legacy_rates_align;
2498 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
2499 			  peer_ht_rates_align);
2500 	buf_ptr += WMI_TLV_HDR_SIZE;
2501 	cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates;
2502 	qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates,
2503 				 param->peer_ht_rates.num_rates);
2504 
2505 	/* VHT Rates */
2506 	buf_ptr += peer_ht_rates_align;
2507 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set,
2508 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set));
2509 
2510 	cmd->peer_nss = param->peer_nss;
2511 
2512 	/* Update bandwidth-NSS mapping */
2513 	cmd->peer_bw_rxnss_override = 0;
2514 	cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override;
2515 
2516 	mcs = (wmi_vht_rate_set *) buf_ptr;
2517 	if (param->vht_capable) {
2518 		mcs->rx_max_rate = param->rx_max_rate;
2519 		mcs->rx_mcs_set = param->rx_mcs_set;
2520 		mcs->tx_max_rate = param->tx_max_rate;
2521 		mcs->tx_mcs_set = param->tx_mcs_set;
2522 	}
2523 
2524 	/* HE Rates */
2525 	cmd->peer_he_mcs = param->peer_he_mcs_count;
2526 	buf_ptr += sizeof(wmi_vht_rate_set);
2527 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2528 		(param->peer_he_mcs_count * sizeof(wmi_he_rate_set)));
2529 	buf_ptr += WMI_TLV_HDR_SIZE;
2530 
2531 	/* Loop through the HE rate set */
2532 	for (i = 0; i < param->peer_he_mcs_count; i++) {
2533 		he_mcs = (wmi_he_rate_set *) buf_ptr;
2534 		WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set,
2535 			WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set));
2536 
2537 		he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i];
2538 		he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i];
2539 		WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__,
2540 			i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set);
2541 		buf_ptr += sizeof(wmi_he_rate_set);
2542 	}
2543 
2544 
2545 	WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x "
2546 		 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d "
2547 		 "nss %d phymode %d peer_mpdu_density %d "
2548 		 "cmd->peer_vht_caps %x "
2549 		 "HE cap_info %x ops %x "
2550 		 "HE phy %x  %x  %x  "
2551 		 "peer_bw_rxnss_override %x", __func__,
2552 		 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags,
2553 		 cmd->peer_rate_caps, cmd->peer_caps,
2554 		 cmd->peer_listen_intval, cmd->peer_ht_caps,
2555 		 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode,
2556 		 cmd->peer_mpdu_density,
2557 		 cmd->peer_vht_caps, cmd->peer_he_cap_info,
2558 		 cmd->peer_he_ops, cmd->peer_he_cap_phy[0],
2559 		 cmd->peer_he_cap_phy[1], cmd->peer_he_cap_phy[2],
2560 		 cmd->peer_bw_rxnss_override);
2561 
2562 	wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0);
2563 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2564 				   WMI_PEER_ASSOC_CMDID);
2565 	if (QDF_IS_STATUS_ERROR(ret)) {
2566 		WMI_LOGP("%s: Failed to send peer assoc command ret = %d",
2567 			 __func__, ret);
2568 		wmi_buf_free(buf);
2569 	}
2570 
2571 	return ret;
2572 }
2573 
2574 /* copy_scan_notify_events() - Helper routine to copy scan notify events
2575  */
2576 static inline void copy_scan_event_cntrl_flags(
2577 		wmi_start_scan_cmd_fixed_param * cmd,
2578 		struct scan_req_params *param)
2579 {
2580 
2581 	/* Scan events subscription */
2582 	if (param->scan_ev_started)
2583 		cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED;
2584 	if (param->scan_ev_completed)
2585 		cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED;
2586 	if (param->scan_ev_bss_chan)
2587 		cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL;
2588 	if (param->scan_ev_foreign_chan)
2589 		cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL;
2590 	if (param->scan_ev_dequeued)
2591 		cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED;
2592 	if (param->scan_ev_preempted)
2593 		cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED;
2594 	if (param->scan_ev_start_failed)
2595 		cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED;
2596 	if (param->scan_ev_restarted)
2597 		cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED;
2598 	if (param->scan_ev_foreign_chn_exit)
2599 		cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT;
2600 	if (param->scan_ev_suspended)
2601 		cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED;
2602 	if (param->scan_ev_resumed)
2603 		cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED;
2604 
2605 	/** Set scan control flags */
2606 	cmd->scan_ctrl_flags = 0;
2607 	if (param->scan_f_passive)
2608 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
2609 	if (param->scan_f_strict_passive_pch)
2610 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN;
2611 	if (param->scan_f_promisc_mode)
2612 		cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS;
2613 	if (param->scan_f_capture_phy_err)
2614 		cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR;
2615 	if (param->scan_f_half_rate)
2616 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT;
2617 	if (param->scan_f_quarter_rate)
2618 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT;
2619 	if (param->scan_f_cck_rates)
2620 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES;
2621 	if (param->scan_f_ofdm_rates)
2622 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES;
2623 	if (param->scan_f_chan_stat_evnt)
2624 		cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT;
2625 	if (param->scan_f_filter_prb_req)
2626 		cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
2627 	if (param->scan_f_bcast_probe)
2628 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ;
2629 	if (param->scan_f_offchan_mgmt_tx)
2630 		cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX;
2631 	if (param->scan_f_offchan_data_tx)
2632 		cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX;
2633 	if (param->scan_f_force_active_dfs_chn)
2634 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS;
2635 	if (param->scan_f_add_tpc_ie_in_probe)
2636 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ;
2637 	if (param->scan_f_add_ds_ie_in_probe)
2638 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
2639 	if (param->scan_f_add_spoofed_mac_in_probe)
2640 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ;
2641 	if (param->scan_f_add_rand_seq_in_probe)
2642 		cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ;
2643 	if (param->scan_f_en_ie_whitelist_in_probe)
2644 		cmd->scan_ctrl_flags |=
2645 			WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ;
2646 
2647 	/* for adaptive scan mode using 3 bits (21 - 23 bits) */
2648 	WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags,
2649 		param->adaptive_dwell_time_mode);
2650 }
2651 
2652 /* scan_copy_ie_buffer() - Copy scan ie_data */
2653 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr,
2654 				struct scan_req_params *params)
2655 {
2656 	qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len);
2657 }
2658 
2659 /**
2660  * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer
2661  * @mac: random mac addr
2662  * @mask: random mac mask
2663  * @mac_addr: wmi random mac
2664  * @mac_mask: wmi random mac mask
2665  *
2666  * Return None.
2667  */
2668 static inline
2669 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask,
2670 			      wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask)
2671 {
2672 	WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr);
2673 	WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask);
2674 }
2675 
2676 /*
2677  * wmi_fill_vendor_oui() - fill vendor OUIs
2678  * @buf_ptr: pointer to wmi tlv buffer
2679  * @num_vendor_oui: number of vendor OUIs to be filled
2680  * @param_voui: pointer to OUI buffer
2681  *
2682  * This function populates the wmi tlv buffer when vendor specific OUIs are
2683  * present.
2684  *
2685  * Return: None
2686  */
2687 static inline
2688 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui,
2689 			 uint32_t *pvoui)
2690 {
2691 	wmi_vendor_oui *voui = NULL;
2692 	uint32_t i;
2693 
2694 	voui = (wmi_vendor_oui *)buf_ptr;
2695 
2696 	for (i = 0; i < num_vendor_oui; i++) {
2697 		WMITLV_SET_HDR(&voui[i].tlv_header,
2698 			       WMITLV_TAG_STRUC_wmi_vendor_oui,
2699 			       WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui));
2700 		voui[i].oui_type_subtype = pvoui[i];
2701 	}
2702 }
2703 
2704 /*
2705  * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs
2706  * @ie_bitmap: output pointer to ie bit map in cmd
2707  * @num_vendor_oui: output pointer to num vendor OUIs
2708  * @ie_whitelist: input parameter
2709  *
2710  * This function populates the IE whitelist attrs of scan, pno and
2711  * scan oui commands for ie_whitelist parameter.
2712  *
2713  * Return: None
2714  */
2715 static inline
2716 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap,
2717 				 uint32_t *num_vendor_oui,
2718 				 struct probe_req_whitelist_attr *ie_whitelist)
2719 {
2720 	uint32_t i = 0;
2721 
2722 	for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++)
2723 		ie_bitmap[i] = ie_whitelist->ie_bitmap[i];
2724 
2725 	*num_vendor_oui = ie_whitelist->num_vendor_oui;
2726 }
2727 
2728 /**
2729  *  send_scan_start_cmd_tlv() - WMI scan start function
2730  *  @param wmi_handle      : handle to WMI.
2731  *  @param param    : pointer to hold scan start cmd parameter
2732  *
2733  *  Return: 0  on success and -ve on failure.
2734  */
2735 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle,
2736 				struct scan_req_params *params)
2737 {
2738 	int32_t ret = 0;
2739 	int32_t i;
2740 	wmi_buf_t wmi_buf;
2741 	wmi_start_scan_cmd_fixed_param *cmd;
2742 	uint8_t *buf_ptr;
2743 	uint32_t *tmp_ptr;
2744 	wmi_ssid *ssid = NULL;
2745 	wmi_mac_addr *bssid;
2746 	int len = sizeof(*cmd);
2747 	uint8_t extraie_len_with_pad = 0;
2748 	uint8_t phymode_roundup = 0;
2749 	struct probe_req_whitelist_attr *ie_whitelist = &params->ie_whitelist;
2750 
2751 	/* Length TLV placeholder for array of uint32_t */
2752 	len += WMI_TLV_HDR_SIZE;
2753 	/* calculate the length of buffer required */
2754 	if (params->chan_list.num_chan)
2755 		len += params->chan_list.num_chan * sizeof(uint32_t);
2756 
2757 	/* Length TLV placeholder for array of wmi_ssid structures */
2758 	len += WMI_TLV_HDR_SIZE;
2759 	if (params->num_ssids)
2760 		len += params->num_ssids * sizeof(wmi_ssid);
2761 
2762 	/* Length TLV placeholder for array of wmi_mac_addr structures */
2763 	len += WMI_TLV_HDR_SIZE;
2764 	if (params->num_bssid)
2765 		len += sizeof(wmi_mac_addr) * params->num_bssid;
2766 
2767 	/* Length TLV placeholder for array of bytes */
2768 	len += WMI_TLV_HDR_SIZE;
2769 	if (params->extraie.len)
2770 		extraie_len_with_pad =
2771 		roundup(params->extraie.len, sizeof(uint32_t));
2772 	len += extraie_len_with_pad;
2773 
2774 	len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */
2775 	if (ie_whitelist->num_vendor_oui)
2776 		len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui);
2777 
2778 	len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */
2779 	if (params->scan_f_wide_band)
2780 		phymode_roundup =
2781 			qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t),
2782 					sizeof(uint32_t));
2783 	len += phymode_roundup;
2784 
2785 	/* Allocate the memory */
2786 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
2787 	if (!wmi_buf) {
2788 		WMI_LOGP("%s: failed to allocate memory for start scan cmd",
2789 			 __func__);
2790 		return QDF_STATUS_E_FAILURE;
2791 	}
2792 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
2793 	cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr;
2794 	WMITLV_SET_HDR(&cmd->tlv_header,
2795 		       WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
2796 		       WMITLV_GET_STRUCT_TLVLEN
2797 			       (wmi_start_scan_cmd_fixed_param));
2798 
2799 	cmd->scan_id = params->scan_id;
2800 	cmd->scan_req_id = params->scan_req_id;
2801 	cmd->vdev_id = params->vdev_id;
2802 	cmd->scan_priority = params->scan_priority;
2803 
2804 	copy_scan_event_cntrl_flags(cmd, params);
2805 
2806 	cmd->dwell_time_active = params->dwell_time_active;
2807 	cmd->dwell_time_active_2g = params->dwell_time_active_2g;
2808 	cmd->dwell_time_passive = params->dwell_time_passive;
2809 	cmd->min_rest_time = params->min_rest_time;
2810 	cmd->max_rest_time = params->max_rest_time;
2811 	cmd->repeat_probe_time = params->repeat_probe_time;
2812 	cmd->probe_spacing_time = params->probe_spacing_time;
2813 	cmd->idle_time = params->idle_time;
2814 	cmd->max_scan_time = params->max_scan_time;
2815 	cmd->probe_delay = params->probe_delay;
2816 	cmd->burst_duration = params->burst_duration;
2817 	cmd->num_chan = params->chan_list.num_chan;
2818 	cmd->num_bssid = params->num_bssid;
2819 	cmd->num_ssids = params->num_ssids;
2820 	cmd->ie_len = params->extraie.len;
2821 	cmd->n_probes = params->n_probes;
2822 	cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext;
2823 
2824 	WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext);
2825 
2826 	if (params->scan_random.randomize)
2827 		wmi_copy_scan_random_mac(params->scan_random.mac_addr,
2828 					 params->scan_random.mac_mask,
2829 					 &cmd->mac_addr,
2830 					 &cmd->mac_mask);
2831 
2832 	if (ie_whitelist->white_list)
2833 		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
2834 					    &cmd->num_vendor_oui,
2835 					    ie_whitelist);
2836 
2837 	buf_ptr += sizeof(*cmd);
2838 	tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
2839 	for (i = 0; i < params->chan_list.num_chan; ++i)
2840 		tmp_ptr[i] = params->chan_list.chan[i].freq;
2841 
2842 	WMITLV_SET_HDR(buf_ptr,
2843 		       WMITLV_TAG_ARRAY_UINT32,
2844 		       (params->chan_list.num_chan * sizeof(uint32_t)));
2845 	buf_ptr += WMI_TLV_HDR_SIZE +
2846 			(params->chan_list.num_chan * sizeof(uint32_t));
2847 
2848 	if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) {
2849 		WMI_LOGE("Invalid value for numSsid");
2850 		goto error;
2851 	}
2852 
2853 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
2854 	       (params->num_ssids * sizeof(wmi_ssid)));
2855 
2856 	if (params->num_ssids) {
2857 		ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE);
2858 		for (i = 0; i < params->num_ssids; ++i) {
2859 			ssid->ssid_len = params->ssid[i].length;
2860 			qdf_mem_copy(ssid->ssid, params->ssid[i].ssid,
2861 				     params->ssid[i].length);
2862 			ssid++;
2863 		}
2864 	}
2865 	buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid));
2866 
2867 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
2868 		       (params->num_bssid * sizeof(wmi_mac_addr)));
2869 	bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE);
2870 
2871 	if (params->num_bssid) {
2872 		for (i = 0; i < params->num_bssid; ++i) {
2873 			WMI_CHAR_ARRAY_TO_MAC_ADDR(
2874 				&params->bssid_list[i].bytes[0], bssid);
2875 			bssid++;
2876 		}
2877 	}
2878 
2879 	buf_ptr += WMI_TLV_HDR_SIZE +
2880 		(params->num_bssid * sizeof(wmi_mac_addr));
2881 
2882 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad);
2883 	if (params->extraie.len)
2884 		scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE,
2885 			     params);
2886 
2887 	buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad;
2888 
2889 	/* probe req ie whitelisting */
2890 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2891 		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
2892 
2893 	buf_ptr += WMI_TLV_HDR_SIZE;
2894 
2895 	if (cmd->num_vendor_oui) {
2896 		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
2897 				    ie_whitelist->voui);
2898 		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
2899 	}
2900 
2901 	/* Add phy mode TLV if it's a wide band scan */
2902 	if (params->scan_f_wide_band) {
2903 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup);
2904 		buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
2905 		for (i = 0; i < params->chan_list.num_chan; ++i)
2906 			buf_ptr[i] =
2907 				WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode);
2908 		buf_ptr += phymode_roundup;
2909 	} else {
2910 		/* Add ZERO legth phy mode TLV */
2911 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0);
2912 	}
2913 
2914 	wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0);
2915 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf,
2916 				   len, WMI_START_SCAN_CMDID);
2917 	if (ret) {
2918 		WMI_LOGE("%s: Failed to start scan: %d", __func__, ret);
2919 		wmi_buf_free(wmi_buf);
2920 	}
2921 	return ret;
2922 error:
2923 	wmi_buf_free(wmi_buf);
2924 	return QDF_STATUS_E_FAILURE;
2925 }
2926 
2927 /**
2928  *  send_scan_stop_cmd_tlv() - WMI scan start function
2929  *  @param wmi_handle      : handle to WMI.
2930  *  @param param    : pointer to hold scan cancel cmd parameter
2931  *
2932  *  Return: 0  on success and -ve on failure.
2933  */
2934 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle,
2935 				struct scan_cancel_param *param)
2936 {
2937 	wmi_stop_scan_cmd_fixed_param *cmd;
2938 	int ret;
2939 	int len = sizeof(*cmd);
2940 	wmi_buf_t wmi_buf;
2941 
2942 	/* Allocate the memory */
2943 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
2944 	if (!wmi_buf) {
2945 		WMI_LOGP("%s: failed to allocate memory for stop scan cmd",
2946 			 __func__);
2947 		ret = QDF_STATUS_E_NOMEM;
2948 		goto error;
2949 	}
2950 
2951 	cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf);
2952 	WMITLV_SET_HDR(&cmd->tlv_header,
2953 		       WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param,
2954 		       WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param));
2955 	cmd->vdev_id = param->vdev_id;
2956 	cmd->requestor = param->requester;
2957 	cmd->scan_id = param->scan_id;
2958 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
2959 								param->pdev_id);
2960 	/* stop the scan with the corresponding scan_id */
2961 	if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) {
2962 		/* Cancelling all scans */
2963 		cmd->req_type = WMI_SCAN_STOP_ALL;
2964 	} else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) {
2965 		/* Cancelling VAP scans */
2966 		cmd->req_type = WMI_SCN_STOP_VAP_ALL;
2967 	} else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) {
2968 		/* Cancelling specific scan */
2969 		cmd->req_type = WMI_SCAN_STOP_ONE;
2970 	} else {
2971 		WMI_LOGE("%s: Invalid Command : ", __func__);
2972 		wmi_buf_free(wmi_buf);
2973 		return QDF_STATUS_E_INVAL;
2974 	}
2975 
2976 	wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0);
2977 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf,
2978 				   len, WMI_STOP_SCAN_CMDID);
2979 	if (ret) {
2980 		WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret);
2981 		wmi_buf_free(wmi_buf);
2982 	}
2983 
2984 error:
2985 	return ret;
2986 }
2987 
2988 #ifdef CONFIG_MCL
2989 /**
2990  *  send_scan_chan_list_cmd_tlv() - WMI scan channel list function
2991  *  @param wmi_handle      : handle to WMI.
2992  *  @param param    : pointer to hold scan channel list parameter
2993  *
2994  *  Return: 0  on success and -ve on failure.
2995  */
2996 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
2997 				struct scan_chan_list_params *chan_list)
2998 {
2999 	wmi_buf_t buf;
3000 	QDF_STATUS qdf_status;
3001 	wmi_scan_chan_list_cmd_fixed_param *cmd;
3002 	int i;
3003 	uint8_t *buf_ptr;
3004 	wmi_channel_param *chan_info, *tchan_info;
3005 	uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
3006 
3007 	len += sizeof(wmi_channel) * chan_list->num_scan_chans;
3008 	buf = wmi_buf_alloc(wmi_handle, len);
3009 	if (!buf) {
3010 		WMI_LOGE("Failed to allocate memory");
3011 		qdf_status = QDF_STATUS_E_NOMEM;
3012 		goto end;
3013 	}
3014 
3015 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3016 	cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr;
3017 	WMITLV_SET_HDR(&cmd->tlv_header,
3018 		       WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param,
3019 		       WMITLV_GET_STRUCT_TLVLEN
3020 			       (wmi_scan_chan_list_cmd_fixed_param));
3021 
3022 	WMI_LOGD("no of channels = %d, len = %d", chan_list->num_scan_chans, len);
3023 
3024 	cmd->num_scan_chans = chan_list->num_scan_chans;
3025 	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)),
3026 		       WMITLV_TAG_ARRAY_STRUC,
3027 		       sizeof(wmi_channel) * chan_list->num_scan_chans);
3028 	chan_info = (wmi_channel_param *)
3029 			(buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE);
3030 	tchan_info = chan_list->chan_info;
3031 
3032 	for (i = 0; i < chan_list->num_scan_chans; ++i) {
3033 		WMITLV_SET_HDR(&chan_info->tlv_header,
3034 			       WMITLV_TAG_STRUC_wmi_channel,
3035 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
3036 		chan_info->mhz = tchan_info->mhz;
3037 		chan_info->band_center_freq1 =
3038 				 tchan_info->band_center_freq1;
3039 		chan_info->band_center_freq2 =
3040 				tchan_info->band_center_freq2;
3041 		chan_info->info = tchan_info->info;
3042 		chan_info->reg_info_1 = tchan_info->reg_info_1;
3043 		chan_info->reg_info_2 = tchan_info->reg_info_2;
3044 		WMI_LOGD("chan[%d] = %u", i, chan_info->mhz);
3045 
3046 		/*TODO: Set WMI_SET_CHANNEL_MIN_POWER */
3047 		/*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */
3048 		/*TODO: WMI_SET_CHANNEL_REG_CLASSID */
3049 		tchan_info++;
3050 		chan_info++;
3051 	}
3052 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
3053 							chan_list->pdev_id);
3054 
3055 	wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, NO_SESSION, 0);
3056 	qdf_status = wmi_unified_cmd_send(wmi_handle,
3057 			buf, len, WMI_SCAN_CHAN_LIST_CMDID);
3058 
3059 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
3060 		WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
3061 		wmi_buf_free(buf);
3062 	}
3063 
3064 end:
3065 	return qdf_status;
3066 }
3067 #else
3068 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
3069 				struct scan_chan_list_params *chan_list)
3070 {
3071 	wmi_buf_t buf;
3072 	QDF_STATUS qdf_status;
3073 	wmi_scan_chan_list_cmd_fixed_param *cmd;
3074 	int i;
3075 	uint8_t *buf_ptr;
3076 	wmi_channel *chan_info;
3077 	struct channel_param *tchan_info;
3078 	uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
3079 
3080 	len += sizeof(wmi_channel) * chan_list->nallchans;
3081 	buf = wmi_buf_alloc(wmi_handle, len);
3082 	if (!buf) {
3083 		WMI_LOGE("Failed to allocate memory");
3084 		qdf_status = QDF_STATUS_E_NOMEM;
3085 		goto end;
3086 	}
3087 
3088 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3089 	cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr;
3090 	WMITLV_SET_HDR(&cmd->tlv_header,
3091 		       WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param,
3092 		       WMITLV_GET_STRUCT_TLVLEN
3093 			       (wmi_scan_chan_list_cmd_fixed_param));
3094 
3095 	WMI_LOGD("no of channels = %d, len = %d", chan_list->nallchans, len);
3096 
3097 	if (chan_list->append)
3098 		cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST;
3099 
3100 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
3101 							chan_list->pdev_id);
3102 	cmd->num_scan_chans = chan_list->nallchans;
3103 	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)),
3104 		       WMITLV_TAG_ARRAY_STRUC,
3105 		       sizeof(wmi_channel) * chan_list->nallchans);
3106 	chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE);
3107 	tchan_info = &(chan_list->ch_param[0]);
3108 
3109 	for (i = 0; i < chan_list->nallchans; ++i) {
3110 		WMITLV_SET_HDR(&chan_info->tlv_header,
3111 			       WMITLV_TAG_STRUC_wmi_channel,
3112 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
3113 		chan_info->mhz = tchan_info->mhz;
3114 		chan_info->band_center_freq1 =
3115 				 tchan_info->cfreq1;
3116 		chan_info->band_center_freq2 =
3117 				tchan_info->cfreq2;
3118 
3119 		if (tchan_info->is_chan_passive)
3120 			WMI_SET_CHANNEL_FLAG(chan_info,
3121 					WMI_CHAN_FLAG_PASSIVE);
3122 
3123 		if (tchan_info->allow_vht)
3124 			WMI_SET_CHANNEL_FLAG(chan_info,
3125 					WMI_CHAN_FLAG_ALLOW_VHT);
3126 		else  if (tchan_info->allow_ht)
3127 			WMI_SET_CHANNEL_FLAG(chan_info,
3128 					WMI_CHAN_FLAG_ALLOW_HT);
3129 		WMI_SET_CHANNEL_MODE(chan_info,
3130 				tchan_info->phy_mode);
3131 
3132 		if (tchan_info->half_rate)
3133 			WMI_SET_CHANNEL_FLAG(chan_info,
3134 					WMI_CHAN_FLAG_HALF_RATE);
3135 
3136 		if (tchan_info->quarter_rate)
3137 			WMI_SET_CHANNEL_FLAG(chan_info,
3138 					WMI_CHAN_FLAG_QUARTER_RATE);
3139 
3140 		/* also fill in power information */
3141 		WMI_SET_CHANNEL_MIN_POWER(chan_info,
3142 				tchan_info->minpower);
3143 		WMI_SET_CHANNEL_MAX_POWER(chan_info,
3144 				tchan_info->maxpower);
3145 		WMI_SET_CHANNEL_REG_POWER(chan_info,
3146 				tchan_info->maxregpower);
3147 		WMI_SET_CHANNEL_ANTENNA_MAX(chan_info,
3148 				tchan_info->antennamax);
3149 		WMI_SET_CHANNEL_REG_CLASSID(chan_info,
3150 				tchan_info->reg_class_id);
3151 		WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
3152 				tchan_info->maxregpower);
3153 
3154 		WMI_LOGD("chan[%d] = %u", i, chan_info->mhz);
3155 
3156 		tchan_info++;
3157 		chan_info++;
3158 	}
3159 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
3160 							chan_list->pdev_id);
3161 
3162 	wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0);
3163 	qdf_status = wmi_unified_cmd_send(
3164 			wmi_handle,
3165 			buf, len, WMI_SCAN_CHAN_LIST_CMDID);
3166 
3167 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
3168 		WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
3169 		wmi_buf_free(buf);
3170 	}
3171 
3172 end:
3173 	return qdf_status;
3174 }
3175 #endif
3176 
3177 /**
3178  * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx
3179  *
3180  * @bufp: Pointer to buffer
3181  * @param: Pointer to tx param
3182  *
3183  * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure
3184  */
3185 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp,
3186 					 struct tx_send_params param)
3187 {
3188 	wmi_tx_send_params *tx_param;
3189 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3190 
3191 	if (!bufp) {
3192 		status = QDF_STATUS_E_FAILURE;
3193 		return status;
3194 	}
3195 	tx_param = (wmi_tx_send_params *)bufp;
3196 	WMITLV_SET_HDR(&tx_param->tlv_header,
3197 		       WMITLV_TAG_STRUC_wmi_tx_send_params,
3198 		       WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params));
3199 	WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr);
3200 	WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0,
3201 				       param.mcs_mask);
3202 	WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0,
3203 				       param.nss_mask);
3204 	WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0,
3205 					  param.retry_limit);
3206 	WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1,
3207 					 param.chain_mask);
3208 	WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1,
3209 				      param.bw_mask);
3210 	WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1,
3211 				       param.preamble_type);
3212 	WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1,
3213 					 param.frame_type);
3214 
3215 	return status;
3216 }
3217 
3218 #ifdef CONFIG_HL_SUPPORT
3219 /**
3220  *  send_mgmt_cmd_tlv() - WMI scan start function
3221  *  @wmi_handle      : handle to WMI.
3222  *  @param    : pointer to hold mgmt cmd parameter
3223  *
3224  *  Return: 0  on success and -ve on failure.
3225  */
3226 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
3227 				struct wmi_mgmt_params *param)
3228 {
3229 	wmi_buf_t buf;
3230 	uint8_t *bufp;
3231 	int32_t cmd_len;
3232 	wmi_mgmt_tx_send_cmd_fixed_param *cmd;
3233 	int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len :
3234 		mgmt_tx_dl_frm_len;
3235 
3236 	if (param->frm_len > mgmt_tx_dl_frm_len) {
3237 		WMI_LOGE("%s:mgmt frame len %u exceeds %u",
3238 			 __func__, param->frm_len, mgmt_tx_dl_frm_len);
3239 		return QDF_STATUS_E_INVAL;
3240 	}
3241 
3242 	cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) +
3243 		  WMI_TLV_HDR_SIZE +
3244 		  roundup(bufp_len, sizeof(uint32_t));
3245 
3246 	buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len);
3247 	if (!buf) {
3248 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3249 		return QDF_STATUS_E_NOMEM;
3250 	}
3251 
3252 	cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf);
3253 	bufp = (uint8_t *) cmd;
3254 	WMITLV_SET_HDR(&cmd->tlv_header,
3255 		WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param,
3256 		WMITLV_GET_STRUCT_TLVLEN
3257 		(wmi_mgmt_tx_send_cmd_fixed_param));
3258 
3259 	cmd->vdev_id = param->vdev_id;
3260 
3261 	cmd->desc_id = param->desc_id;
3262 	cmd->chanfreq = param->chanfreq;
3263 	bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param);
3264 	WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
3265 							    sizeof(uint32_t)));
3266 	bufp += WMI_TLV_HDR_SIZE;
3267 	qdf_mem_copy(bufp, param->pdata, bufp_len);
3268 
3269 	cmd->frame_len = param->frm_len;
3270 	cmd->buf_len = bufp_len;
3271 	cmd->tx_params_valid = param->tx_params_valid;
3272 
3273 	wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID,
3274 			bufp, cmd->vdev_id, cmd->chanfreq);
3275 
3276 	bufp += roundup(bufp_len, sizeof(uint32_t));
3277 	if (param->tx_params_valid) {
3278 		if (populate_tx_send_params(bufp, param->tx_param) !=
3279 		    QDF_STATUS_SUCCESS) {
3280 			WMI_LOGE("%s: Populate TX send params failed",
3281 				 __func__);
3282 			goto free_buf;
3283 		}
3284 		cmd_len += sizeof(wmi_tx_send_params);
3285 	}
3286 
3287 	wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0);
3288 	if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
3289 				      WMI_MGMT_TX_SEND_CMDID)) {
3290 		WMI_LOGE("%s: Failed to send mgmt Tx", __func__);
3291 		goto free_buf;
3292 	}
3293 	return QDF_STATUS_SUCCESS;
3294 
3295 free_buf:
3296 	wmi_buf_free(buf);
3297 	return QDF_STATUS_E_FAILURE;
3298 }
3299 #else
3300 /**
3301  *  send_mgmt_cmd_tlv() - WMI scan start function
3302  *  @wmi_handle      : handle to WMI.
3303  *  @param    : pointer to hold mgmt cmd parameter
3304  *
3305  *  Return: 0  on success and -ve on failure.
3306  */
3307 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
3308 				struct wmi_mgmt_params *param)
3309 {
3310 	wmi_buf_t buf;
3311 	wmi_mgmt_tx_send_cmd_fixed_param *cmd;
3312 	int32_t cmd_len;
3313 	uint64_t dma_addr;
3314 	void *qdf_ctx = param->qdf_ctx;
3315 	uint8_t *bufp;
3316 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3317 	int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len :
3318 		mgmt_tx_dl_frm_len;
3319 
3320 	cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) +
3321 		  WMI_TLV_HDR_SIZE +
3322 		  roundup(bufp_len, sizeof(uint32_t));
3323 
3324 	buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len);
3325 	if (!buf) {
3326 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3327 		return QDF_STATUS_E_NOMEM;
3328 	}
3329 
3330 	cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf);
3331 	bufp = (uint8_t *) cmd;
3332 	WMITLV_SET_HDR(&cmd->tlv_header,
3333 		WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param,
3334 		WMITLV_GET_STRUCT_TLVLEN
3335 		(wmi_mgmt_tx_send_cmd_fixed_param));
3336 
3337 	cmd->vdev_id = param->vdev_id;
3338 
3339 	cmd->desc_id = param->desc_id;
3340 	cmd->chanfreq = param->chanfreq;
3341 	bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param);
3342 	WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
3343 							    sizeof(uint32_t)));
3344 	bufp += WMI_TLV_HDR_SIZE;
3345 	qdf_mem_copy(bufp, param->pdata, bufp_len);
3346 
3347 	status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame,
3348 				     QDF_DMA_TO_DEVICE);
3349 	if (status != QDF_STATUS_SUCCESS) {
3350 		WMI_LOGE("%s: wmi buf map failed", __func__);
3351 		goto free_buf;
3352 	}
3353 
3354 	dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0);
3355 	cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff);
3356 #if defined(HTT_PADDR64)
3357 	cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F);
3358 #endif
3359 	cmd->frame_len = param->frm_len;
3360 	cmd->buf_len = bufp_len;
3361 	cmd->tx_params_valid = param->tx_params_valid;
3362 
3363 	wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID,
3364 			bufp, cmd->vdev_id, cmd->chanfreq);
3365 
3366 	bufp += roundup(bufp_len, sizeof(uint32_t));
3367 	if (param->tx_params_valid) {
3368 		status = populate_tx_send_params(bufp, param->tx_param);
3369 		if (status != QDF_STATUS_SUCCESS) {
3370 			WMI_LOGE("%s: Populate TX send params failed",
3371 				 __func__);
3372 			goto unmap_tx_frame;
3373 		}
3374 		cmd_len += sizeof(wmi_tx_send_params);
3375 	}
3376 
3377 	wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0);
3378 	if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
3379 				      WMI_MGMT_TX_SEND_CMDID)) {
3380 		WMI_LOGE("%s: Failed to send mgmt Tx", __func__);
3381 		goto unmap_tx_frame;
3382 	}
3383 	return QDF_STATUS_SUCCESS;
3384 
3385 unmap_tx_frame:
3386 	qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame,
3387 				     QDF_DMA_TO_DEVICE);
3388 free_buf:
3389 	wmi_buf_free(buf);
3390 	return QDF_STATUS_E_FAILURE;
3391 }
3392 #endif /* CONFIG_HL_SUPPORT */
3393 
3394 /**
3395  *  send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data
3396  *  @wmi_handle      : handle to WMI.
3397  *  @param    : pointer to offchan data tx cmd parameter
3398  *
3399  *  Return: QDF_STATUS_SUCCESS  on success and error on failure.
3400  */
3401 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle,
3402 				struct wmi_offchan_data_tx_params *param)
3403 {
3404 	wmi_buf_t buf;
3405 	wmi_offchan_data_tx_send_cmd_fixed_param *cmd;
3406 	int32_t cmd_len;
3407 	uint64_t dma_addr;
3408 	void *qdf_ctx = param->qdf_ctx;
3409 	uint8_t *bufp;
3410 	int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ?
3411 					param->frm_len : mgmt_tx_dl_frm_len;
3412 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3413 
3414 	cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) +
3415 		  WMI_TLV_HDR_SIZE +
3416 		  roundup(bufp_len, sizeof(uint32_t));
3417 
3418 	buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len);
3419 	if (!buf) {
3420 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3421 		return QDF_STATUS_E_NOMEM;
3422 	}
3423 
3424 	cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf);
3425 	bufp = (uint8_t *) cmd;
3426 	WMITLV_SET_HDR(&cmd->tlv_header,
3427 		WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param,
3428 		WMITLV_GET_STRUCT_TLVLEN
3429 		(wmi_offchan_data_tx_send_cmd_fixed_param));
3430 
3431 	cmd->vdev_id = param->vdev_id;
3432 
3433 	cmd->desc_id = param->desc_id;
3434 	cmd->chanfreq = param->chanfreq;
3435 	bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param);
3436 	WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
3437 							    sizeof(uint32_t)));
3438 	bufp += WMI_TLV_HDR_SIZE;
3439 	qdf_mem_copy(bufp, param->pdata, bufp_len);
3440 	qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE);
3441 	dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0);
3442 	cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff);
3443 #if defined(HTT_PADDR64)
3444 	cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F);
3445 #endif
3446 	cmd->frame_len = param->frm_len;
3447 	cmd->buf_len = bufp_len;
3448 	cmd->tx_params_valid = param->tx_params_valid;
3449 
3450 	wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID,
3451 			bufp, cmd->vdev_id, cmd->chanfreq);
3452 
3453 	bufp += roundup(bufp_len, sizeof(uint32_t));
3454 	if (param->tx_params_valid) {
3455 		status = populate_tx_send_params(bufp, param->tx_param);
3456 		if (status != QDF_STATUS_SUCCESS) {
3457 			WMI_LOGE("%s: Populate TX send params failed",
3458 				 __func__);
3459 			goto err1;
3460 		}
3461 		cmd_len += sizeof(wmi_tx_send_params);
3462 	}
3463 
3464 	wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0);
3465 	if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
3466 				WMI_OFFCHAN_DATA_TX_SEND_CMDID)) {
3467 		WMI_LOGE("%s: Failed to offchan data Tx", __func__);
3468 		goto err1;
3469 	}
3470 
3471 	return QDF_STATUS_SUCCESS;
3472 
3473 err1:
3474 	wmi_buf_free(buf);
3475 	return QDF_STATUS_E_FAILURE;
3476 }
3477 
3478 /**
3479  * send_modem_power_state_cmd_tlv() - set modem power state to fw
3480  * @wmi_handle: wmi handle
3481  * @param_value: parameter value
3482  *
3483  * Return: QDF_STATUS_SUCCESS for success or error code
3484  */
3485 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle,
3486 		uint32_t param_value)
3487 {
3488 	QDF_STATUS ret;
3489 	wmi_modem_power_state_cmd_param *cmd;
3490 	wmi_buf_t buf;
3491 	uint16_t len = sizeof(*cmd);
3492 
3493 	buf = wmi_buf_alloc(wmi_handle, len);
3494 	if (!buf) {
3495 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3496 		return QDF_STATUS_E_NOMEM;
3497 	}
3498 	cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf);
3499 	WMITLV_SET_HDR(&cmd->tlv_header,
3500 		       WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param,
3501 		       WMITLV_GET_STRUCT_TLVLEN
3502 			       (wmi_modem_power_state_cmd_param));
3503 	cmd->modem_power_state = param_value;
3504 	WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__,
3505 		 param_value);
3506 	wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0);
3507 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3508 				     WMI_MODEM_POWER_STATE_CMDID);
3509 	if (QDF_IS_STATUS_ERROR(ret)) {
3510 		WMI_LOGE("Failed to send notify cmd ret = %d", ret);
3511 		wmi_buf_free(buf);
3512 	}
3513 
3514 	return ret;
3515 }
3516 
3517 /**
3518  * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw
3519  * @wmi_handle: wmi handle
3520  * @vdev_id: vdev id
3521  * @val: value
3522  *
3523  * Return: QDF_STATUS_SUCCESS for success or error code.
3524  */
3525 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle,
3526 			       uint32_t vdev_id, uint8_t val)
3527 {
3528 	wmi_sta_powersave_mode_cmd_fixed_param *cmd;
3529 	wmi_buf_t buf;
3530 	int32_t len = sizeof(*cmd);
3531 
3532 	WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val);
3533 
3534 	buf = wmi_buf_alloc(wmi_handle, len);
3535 	if (!buf) {
3536 		WMI_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__);
3537 		return QDF_STATUS_E_NOMEM;
3538 	}
3539 	cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf);
3540 	WMITLV_SET_HDR(&cmd->tlv_header,
3541 		       WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param,
3542 		       WMITLV_GET_STRUCT_TLVLEN
3543 			       (wmi_sta_powersave_mode_cmd_fixed_param));
3544 	cmd->vdev_id = vdev_id;
3545 	if (val)
3546 		cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED;
3547 	else
3548 		cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED;
3549 
3550 	wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0);
3551 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
3552 				 WMI_STA_POWERSAVE_MODE_CMDID)) {
3553 		WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d",
3554 			 vdev_id, val);
3555 		wmi_buf_free(buf);
3556 		return QDF_STATUS_E_FAILURE;
3557 	}
3558 	return 0;
3559 }
3560 
3561 /**
3562  * send_set_mimops_cmd_tlv() - set MIMO powersave
3563  * @wmi_handle: wmi handle
3564  * @vdev_id: vdev id
3565  * @value: value
3566  *
3567  * Return: QDF_STATUS_SUCCESS for success or error code.
3568  */
3569 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle,
3570 			uint8_t vdev_id, int value)
3571 {
3572 	QDF_STATUS ret;
3573 	wmi_sta_smps_force_mode_cmd_fixed_param *cmd;
3574 	wmi_buf_t buf;
3575 	uint16_t len = sizeof(*cmd);
3576 
3577 	buf = wmi_buf_alloc(wmi_handle, len);
3578 	if (!buf) {
3579 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3580 		return QDF_STATUS_E_NOMEM;
3581 	}
3582 	cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf);
3583 	WMITLV_SET_HDR(&cmd->tlv_header,
3584 		       WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param,
3585 		       WMITLV_GET_STRUCT_TLVLEN
3586 			       (wmi_sta_smps_force_mode_cmd_fixed_param));
3587 
3588 	cmd->vdev_id = vdev_id;
3589 
3590 	/* WMI_SMPS_FORCED_MODE values do not directly map
3591 	 * to SM power save values defined in the specification.
3592 	 * Make sure to send the right mapping.
3593 	 */
3594 	switch (value) {
3595 	case 0:
3596 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE;
3597 		break;
3598 	case 1:
3599 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED;
3600 		break;
3601 	case 2:
3602 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC;
3603 		break;
3604 	case 3:
3605 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC;
3606 		break;
3607 	default:
3608 		WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__);
3609 		wmi_buf_free(buf);
3610 		return QDF_STATUS_E_FAILURE;
3611 	}
3612 
3613 	WMI_LOGD("Setting vdev %d value = %u", vdev_id, value);
3614 
3615 	wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0);
3616 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3617 				   WMI_STA_SMPS_FORCE_MODE_CMDID);
3618 	if (QDF_IS_STATUS_ERROR(ret)) {
3619 		WMI_LOGE("Failed to send set Mimo PS ret = %d", ret);
3620 		wmi_buf_free(buf);
3621 	}
3622 
3623 	return ret;
3624 }
3625 
3626 /**
3627  * send_set_smps_params_cmd_tlv() - set smps params
3628  * @wmi_handle: wmi handle
3629  * @vdev_id: vdev id
3630  * @value: value
3631  *
3632  * Return: QDF_STATUS_SUCCESS for success or error code.
3633  */
3634 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
3635 			       int value)
3636 {
3637 	QDF_STATUS ret;
3638 	wmi_sta_smps_param_cmd_fixed_param *cmd;
3639 	wmi_buf_t buf;
3640 	uint16_t len = sizeof(*cmd);
3641 
3642 	buf = wmi_buf_alloc(wmi_handle, len);
3643 	if (!buf) {
3644 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3645 		return QDF_STATUS_E_NOMEM;
3646 	}
3647 	cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf);
3648 	WMITLV_SET_HDR(&cmd->tlv_header,
3649 		       WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param,
3650 		       WMITLV_GET_STRUCT_TLVLEN
3651 			       (wmi_sta_smps_param_cmd_fixed_param));
3652 
3653 	cmd->vdev_id = vdev_id;
3654 	cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS;
3655 	cmd->param =
3656 		(value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS;
3657 
3658 	WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value,
3659 		 cmd->param);
3660 
3661 	wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0);
3662 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3663 				   WMI_STA_SMPS_PARAM_CMDID);
3664 	if (QDF_IS_STATUS_ERROR(ret)) {
3665 		WMI_LOGE("Failed to send set Mimo PS ret = %d", ret);
3666 		wmi_buf_free(buf);
3667 	}
3668 
3669 	return ret;
3670 }
3671 
3672 /**
3673  * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw
3674  * @wmi_handle: wmi handle
3675  * @noa: p2p power save parameters
3676  *
3677  * Return: CDF status
3678  */
3679 static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle,
3680 			struct p2p_ps_params *noa)
3681 {
3682 	wmi_p2p_set_noa_cmd_fixed_param *cmd;
3683 	wmi_p2p_noa_descriptor *noa_discriptor;
3684 	wmi_buf_t buf;
3685 	uint8_t *buf_ptr;
3686 	uint16_t len;
3687 	QDF_STATUS status;
3688 	uint32_t duration;
3689 
3690 	WMI_LOGD("%s: Enter", __func__);
3691 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor);
3692 	buf = wmi_buf_alloc(wmi_handle, len);
3693 	if (!buf) {
3694 		WMI_LOGE("Failed to allocate memory");
3695 		status = QDF_STATUS_E_FAILURE;
3696 		goto end;
3697 	}
3698 
3699 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3700 	cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr;
3701 	WMITLV_SET_HDR(&cmd->tlv_header,
3702 		       WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param,
3703 		       WMITLV_GET_STRUCT_TLVLEN
3704 			       (wmi_p2p_set_noa_cmd_fixed_param));
3705 	duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration;
3706 	cmd->vdev_id = noa->session_id;
3707 	cmd->enable = (duration) ? true : false;
3708 	cmd->num_noa = 1;
3709 
3710 	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)),
3711 		       WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor));
3712 	noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr +
3713 						     sizeof
3714 						     (wmi_p2p_set_noa_cmd_fixed_param)
3715 						     + WMI_TLV_HDR_SIZE);
3716 	WMITLV_SET_HDR(&noa_discriptor->tlv_header,
3717 		       WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor,
3718 		       WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor));
3719 	noa_discriptor->type_count = noa->count;
3720 	noa_discriptor->duration = duration;
3721 	noa_discriptor->interval = noa->interval;
3722 	noa_discriptor->start_time = 0;
3723 
3724 	WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d",
3725 		 cmd->vdev_id, noa->count, noa_discriptor->duration,
3726 		 noa->interval);
3727 	wmi_mtrace(WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID, cmd->vdev_id, 0);
3728 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
3729 				      WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID);
3730 	if (QDF_IS_STATUS_ERROR(status)) {
3731 		WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID");
3732 		wmi_buf_free(buf);
3733 	}
3734 
3735 end:
3736 	WMI_LOGD("%s: Exit", __func__);
3737 	return status;
3738 }
3739 
3740 
3741 /**
3742  * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw
3743  * @wmi_handle: wmi handle
3744  * @noa: p2p opp power save parameters
3745  *
3746  * Return: CDF status
3747  */
3748 static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle,
3749 		struct p2p_ps_params *oppps)
3750 {
3751 	wmi_p2p_set_oppps_cmd_fixed_param *cmd;
3752 	wmi_buf_t buf;
3753 	QDF_STATUS status;
3754 
3755 	WMI_LOGD("%s: Enter", __func__);
3756 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
3757 	if (!buf) {
3758 		WMI_LOGE("Failed to allocate memory");
3759 		status = QDF_STATUS_E_FAILURE;
3760 		goto end;
3761 	}
3762 
3763 	cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf);
3764 	WMITLV_SET_HDR(&cmd->tlv_header,
3765 		       WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param,
3766 		       WMITLV_GET_STRUCT_TLVLEN
3767 			       (wmi_p2p_set_oppps_cmd_fixed_param));
3768 	cmd->vdev_id = oppps->session_id;
3769 	if (oppps->ctwindow)
3770 		WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd);
3771 
3772 	WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow);
3773 	WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d",
3774 		 cmd->vdev_id, oppps->ctwindow);
3775 	wmi_mtrace(WMI_P2P_SET_OPPPS_PARAM_CMDID, cmd->vdev_id, 0);
3776 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
3777 				      WMI_P2P_SET_OPPPS_PARAM_CMDID);
3778 	if (QDF_IS_STATUS_ERROR(status)) {
3779 		WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID");
3780 		wmi_buf_free(buf);
3781 	}
3782 
3783 end:
3784 	WMI_LOGD("%s: Exit", __func__);
3785 	return status;
3786 }
3787 
3788 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
3789 /**
3790  * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw
3791  * @wmi_handle: wmi handle
3792  * @param: p2p listen offload start parameters
3793  *
3794  * Return: QDF status
3795  */
3796 static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle,
3797 	struct p2p_lo_start *param)
3798 {
3799 	wmi_buf_t buf;
3800 	wmi_p2p_lo_start_cmd_fixed_param *cmd;
3801 	int32_t len = sizeof(*cmd);
3802 	uint8_t *buf_ptr;
3803 	QDF_STATUS status;
3804 	int device_types_len_aligned;
3805 	int probe_resp_len_aligned;
3806 
3807 	if (!param) {
3808 		WMI_LOGE("lo start param is null");
3809 		return QDF_STATUS_E_INVAL;
3810 	}
3811 
3812 	WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id);
3813 
3814 	device_types_len_aligned =
3815 		qdf_roundup(param->dev_types_len,
3816 			sizeof(uint32_t));
3817 	probe_resp_len_aligned =
3818 		qdf_roundup(param->probe_resp_len,
3819 			sizeof(uint32_t));
3820 
3821 	len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned +
3822 			probe_resp_len_aligned;
3823 
3824 	buf = wmi_buf_alloc(wmi_handle, len);
3825 	if (!buf) {
3826 		WMI_LOGE("%s: Failed to allocate memory for p2p lo start",
3827 			__func__);
3828 		return QDF_STATUS_E_NOMEM;
3829 	}
3830 
3831 	cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf);
3832 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3833 
3834 	WMITLV_SET_HDR(&cmd->tlv_header,
3835 		 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param,
3836 		 WMITLV_GET_STRUCT_TLVLEN(
3837 			wmi_p2p_lo_start_cmd_fixed_param));
3838 
3839 	cmd->vdev_id = param->vdev_id;
3840 	cmd->ctl_flags = param->ctl_flags;
3841 	cmd->channel = param->freq;
3842 	cmd->period = param->period;
3843 	cmd->interval = param->interval;
3844 	cmd->count = param->count;
3845 	cmd->device_types_len = param->dev_types_len;
3846 	cmd->prob_resp_len = param->probe_resp_len;
3847 
3848 	buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param);
3849 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
3850 				device_types_len_aligned);
3851 	buf_ptr += WMI_TLV_HDR_SIZE;
3852 	qdf_mem_copy(buf_ptr, param->device_types,
3853 			param->dev_types_len);
3854 
3855 	buf_ptr += device_types_len_aligned;
3856 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
3857 			probe_resp_len_aligned);
3858 	buf_ptr += WMI_TLV_HDR_SIZE;
3859 	qdf_mem_copy(buf_ptr, param->probe_resp_tmplt,
3860 			param->probe_resp_len);
3861 
3862 	WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__,
3863 	cmd->channel, cmd->period, cmd->interval, cmd->count);
3864 
3865 	wmi_mtrace(WMI_P2P_LISTEN_OFFLOAD_START_CMDID, cmd->vdev_id, 0);
3866 	status = wmi_unified_cmd_send(wmi_handle,
3867 				buf, len,
3868 				WMI_P2P_LISTEN_OFFLOAD_START_CMDID);
3869 	if (status != QDF_STATUS_SUCCESS) {
3870 		WMI_LOGE("%s: Failed to send p2p lo start: %d",
3871 			__func__, status);
3872 		wmi_buf_free(buf);
3873 		return status;
3874 	}
3875 
3876 	WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__);
3877 
3878 	return QDF_STATUS_SUCCESS;
3879 }
3880 
3881 /**
3882  * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw
3883  * @wmi_handle: wmi handle
3884  * @param: p2p listen offload stop parameters
3885  *
3886  * Return: QDF status
3887  */
3888 static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle,
3889 	uint8_t vdev_id)
3890 {
3891 	wmi_buf_t buf;
3892 	wmi_p2p_lo_stop_cmd_fixed_param *cmd;
3893 	int32_t len;
3894 	QDF_STATUS status;
3895 
3896 	WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id);
3897 
3898 	len = sizeof(*cmd);
3899 	buf = wmi_buf_alloc(wmi_handle, len);
3900 	if (!buf) {
3901 		qdf_print("%s: Failed to allocate memory for p2p lo stop",
3902 			__func__);
3903 		return QDF_STATUS_E_NOMEM;
3904 	}
3905 	cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf);
3906 
3907 	WMITLV_SET_HDR(&cmd->tlv_header,
3908 		WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param,
3909 		WMITLV_GET_STRUCT_TLVLEN(
3910 			wmi_p2p_lo_stop_cmd_fixed_param));
3911 
3912 	cmd->vdev_id = vdev_id;
3913 
3914 	WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__);
3915 
3916 	wmi_mtrace(WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID, cmd->vdev_id, 0);
3917 	status = wmi_unified_cmd_send(wmi_handle,
3918 				buf, len,
3919 				WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID);
3920 	if (status != QDF_STATUS_SUCCESS) {
3921 		WMI_LOGE("%s: Failed to send p2p lo stop: %d",
3922 			__func__, status);
3923 		wmi_buf_free(buf);
3924 		return status;
3925 	}
3926 
3927 	WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__);
3928 
3929 	return QDF_STATUS_SUCCESS;
3930 }
3931 #endif /* End of FEATURE_P2P_LISTEN_OFFLOAD */
3932 
3933 /**
3934  * send_get_temperature_cmd_tlv() - get pdev temperature req
3935  * @wmi_handle: wmi handle
3936  *
3937  * Return: QDF_STATUS_SUCCESS for success or error code.
3938  */
3939 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle)
3940 {
3941 	wmi_pdev_get_temperature_cmd_fixed_param *cmd;
3942 	wmi_buf_t wmi_buf;
3943 	uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param);
3944 	uint8_t *buf_ptr;
3945 
3946 	if (!wmi_handle) {
3947 		WMI_LOGE(FL("WMI is closed, can not issue cmd"));
3948 		return QDF_STATUS_E_INVAL;
3949 	}
3950 
3951 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
3952 	if (!wmi_buf) {
3953 		WMI_LOGE(FL("wmi_buf_alloc failed"));
3954 		return QDF_STATUS_E_NOMEM;
3955 	}
3956 
3957 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
3958 
3959 	cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr;
3960 	WMITLV_SET_HDR(&cmd->tlv_header,
3961 		       WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param,
3962 		       WMITLV_GET_STRUCT_TLVLEN
3963 			       (wmi_pdev_get_temperature_cmd_fixed_param));
3964 
3965 	wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0);
3966 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
3967 				 WMI_PDEV_GET_TEMPERATURE_CMDID)) {
3968 		WMI_LOGE(FL("failed to send get temperature command"));
3969 		wmi_buf_free(wmi_buf);
3970 		return QDF_STATUS_E_FAILURE;
3971 	}
3972 
3973 	return QDF_STATUS_SUCCESS;
3974 }
3975 
3976 /**
3977  * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command
3978  * @wmi_handle: wmi handle
3979  * @vdevid: vdev id
3980  * @peer_addr: peer mac address
3981  * @auto_triggerparam: auto trigger parameters
3982  * @num_ac: number of access category
3983  *
3984  * This function sets the trigger
3985  * uapsd params such as service interval, delay interval
3986  * and suspend interval which will be used by the firmware
3987  * to send trigger frames periodically when there is no
3988  * traffic on the transmit side.
3989  *
3990  * Return: QDF_STATUS_SUCCESS for success or error code.
3991  */
3992 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle,
3993 				struct sta_uapsd_trig_params *param)
3994 {
3995 	wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd;
3996 	QDF_STATUS ret;
3997 	uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param);
3998 	uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE;
3999 	uint32_t i;
4000 	wmi_buf_t buf;
4001 	uint8_t *buf_ptr;
4002 	struct sta_uapsd_params *uapsd_param;
4003 	wmi_sta_uapsd_auto_trig_param *trig_param;
4004 
4005 	buf = wmi_buf_alloc(wmi_handle, cmd_len);
4006 	if (!buf) {
4007 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
4008 		return QDF_STATUS_E_NOMEM;
4009 	}
4010 
4011 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
4012 	cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr;
4013 	WMITLV_SET_HDR(&cmd->tlv_header,
4014 		       WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param,
4015 		       WMITLV_GET_STRUCT_TLVLEN
4016 			       (wmi_sta_uapsd_auto_trig_cmd_fixed_param));
4017 	cmd->vdev_id = param->vdevid;
4018 	cmd->num_ac = param->num_ac;
4019 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
4020 
4021 	/* TLV indicating array of structures to follow */
4022 	buf_ptr += sizeof(*cmd);
4023 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len);
4024 
4025 	buf_ptr += WMI_TLV_HDR_SIZE;
4026 
4027 	/*
4028 	 * Update tag and length for uapsd auto trigger params (this will take
4029 	 * care of updating tag and length if it is not pre-filled by caller).
4030 	 */
4031 	uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam;
4032 	trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr;
4033 	for (i = 0; i < param->num_ac; i++) {
4034 		WMITLV_SET_HDR((buf_ptr +
4035 				(i * sizeof(wmi_sta_uapsd_auto_trig_param))),
4036 			       WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param,
4037 			       WMITLV_GET_STRUCT_TLVLEN
4038 				       (wmi_sta_uapsd_auto_trig_param));
4039 		trig_param->wmm_ac = uapsd_param->wmm_ac;
4040 		trig_param->user_priority = uapsd_param->user_priority;
4041 		trig_param->service_interval = uapsd_param->service_interval;
4042 		trig_param->suspend_interval = uapsd_param->suspend_interval;
4043 		trig_param->delay_interval = uapsd_param->delay_interval;
4044 		trig_param++;
4045 		uapsd_param++;
4046 	}
4047 
4048 	wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0);
4049 	ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
4050 				   WMI_STA_UAPSD_AUTO_TRIG_CMDID);
4051 	if (QDF_IS_STATUS_ERROR(ret)) {
4052 		WMI_LOGE("Failed to send set uapsd param ret = %d", ret);
4053 		wmi_buf_free(buf);
4054 	}
4055 
4056 	return ret;
4057 }
4058 
4059 #ifdef WLAN_FEATURE_DSRC
4060 /**
4061  * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware
4062  * @wmi_handle: pointer to the wmi handle
4063  * @utc: pointer to the UTC time struct
4064  *
4065  * Return: 0 on succes
4066  */
4067 static QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle,
4068 				struct ocb_utc_param *utc)
4069 {
4070 	QDF_STATUS ret;
4071 	wmi_ocb_set_utc_time_cmd_fixed_param *cmd;
4072 	uint8_t *buf_ptr;
4073 	uint32_t len, i;
4074 	wmi_buf_t buf;
4075 
4076 	len = sizeof(*cmd);
4077 	buf = wmi_buf_alloc(wmi_handle, len);
4078 	if (!buf) {
4079 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4080 		return QDF_STATUS_E_NOMEM;
4081 	}
4082 
4083 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4084 	cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr;
4085 	WMITLV_SET_HDR(&cmd->tlv_header,
4086 		WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param,
4087 		WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param));
4088 	cmd->vdev_id = utc->vdev_id;
4089 
4090 	for (i = 0; i < SIZE_UTC_TIME; i++)
4091 		WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]);
4092 
4093 	for (i = 0; i < SIZE_UTC_TIME_ERROR; i++)
4094 		WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]);
4095 
4096 	wmi_mtrace(WMI_OCB_SET_UTC_TIME_CMDID, cmd->vdev_id, 0);
4097 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4098 				   WMI_OCB_SET_UTC_TIME_CMDID);
4099 	if (QDF_IS_STATUS_ERROR(ret)) {
4100 		WMI_LOGE(FL("Failed to set OCB UTC time"));
4101 		wmi_buf_free(buf);
4102 	}
4103 
4104 	return ret;
4105 }
4106 
4107 /**
4108  * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement
4109  *				   frames on a channel
4110  * @wmi_handle: pointer to the wmi handle
4111  * @timing_advert: pointer to the timing advertisement struct
4112  *
4113  * Return: 0 on succes
4114  */
4115 static QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
4116 	struct ocb_timing_advert_param *timing_advert)
4117 {
4118 	QDF_STATUS ret;
4119 	wmi_ocb_start_timing_advert_cmd_fixed_param *cmd;
4120 	uint8_t *buf_ptr;
4121 	uint32_t len, len_template;
4122 	wmi_buf_t buf;
4123 
4124 	len = sizeof(*cmd) +
4125 		     WMI_TLV_HDR_SIZE;
4126 
4127 	len_template = timing_advert->template_length;
4128 	/* Add padding to the template if needed */
4129 	if (len_template % 4 != 0)
4130 		len_template += 4 - (len_template % 4);
4131 	len += len_template;
4132 
4133 	buf = wmi_buf_alloc(wmi_handle, len);
4134 	if (!buf) {
4135 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4136 		return QDF_STATUS_E_NOMEM;
4137 	}
4138 
4139 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4140 	cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr;
4141 	WMITLV_SET_HDR(&cmd->tlv_header,
4142 		WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param,
4143 		WMITLV_GET_STRUCT_TLVLEN(
4144 			wmi_ocb_start_timing_advert_cmd_fixed_param));
4145 	cmd->vdev_id = timing_advert->vdev_id;
4146 	cmd->repeat_rate = timing_advert->repeat_rate;
4147 	cmd->channel_freq = timing_advert->chan_freq;
4148 	cmd->timestamp_offset = timing_advert->timestamp_offset;
4149 	cmd->time_value_offset = timing_advert->time_value_offset;
4150 	cmd->timing_advert_template_length = timing_advert->template_length;
4151 	buf_ptr += sizeof(*cmd);
4152 
4153 	/* Add the timing advert template */
4154 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
4155 		       len_template);
4156 	qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
4157 		     (uint8_t *)timing_advert->template_value,
4158 		     timing_advert->template_length);
4159 
4160 	wmi_mtrace(WMI_OCB_START_TIMING_ADVERT_CMDID, cmd->vdev_id, 0);
4161 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4162 				   WMI_OCB_START_TIMING_ADVERT_CMDID);
4163 	if (QDF_IS_STATUS_ERROR(ret)) {
4164 		WMI_LOGE(FL("Failed to start OCB timing advert"));
4165 		wmi_buf_free(buf);
4166 	}
4167 
4168 	return ret;
4169 }
4170 
4171 /**
4172  * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames
4173  *				  on a channel
4174  * @wmi_handle: pointer to the wmi handle
4175  * @timing_advert: pointer to the timing advertisement struct
4176  *
4177  * Return: 0 on succes
4178  */
4179 static QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
4180 	struct ocb_timing_advert_param *timing_advert)
4181 {
4182 	QDF_STATUS ret;
4183 	wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd;
4184 	uint8_t *buf_ptr;
4185 	uint32_t len;
4186 	wmi_buf_t buf;
4187 
4188 	len = sizeof(*cmd);
4189 	buf = wmi_buf_alloc(wmi_handle, len);
4190 	if (!buf) {
4191 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4192 		return QDF_STATUS_E_NOMEM;
4193 	}
4194 
4195 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4196 	cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr;
4197 	WMITLV_SET_HDR(&cmd->tlv_header,
4198 		WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param,
4199 		WMITLV_GET_STRUCT_TLVLEN(
4200 			wmi_ocb_stop_timing_advert_cmd_fixed_param));
4201 	cmd->vdev_id = timing_advert->vdev_id;
4202 	cmd->channel_freq = timing_advert->chan_freq;
4203 
4204 	wmi_mtrace(WMI_OCB_STOP_TIMING_ADVERT_CMDID, cmd->vdev_id, 0);
4205 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4206 				   WMI_OCB_STOP_TIMING_ADVERT_CMDID);
4207 	if (QDF_IS_STATUS_ERROR(ret)) {
4208 		WMI_LOGE(FL("Failed to stop OCB timing advert"));
4209 		wmi_buf_free(buf);
4210 	}
4211 
4212 	return ret;
4213 }
4214 
4215 /**
4216  * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val
4217  * @wmi_handle: pointer to the wmi handle
4218  * @request: pointer to the request
4219  *
4220  * Return: 0 on succes
4221  */
4222 static QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle,
4223 			  uint8_t vdev_id)
4224 {
4225 	QDF_STATUS ret;
4226 	wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd;
4227 	uint8_t *buf_ptr;
4228 	wmi_buf_t buf;
4229 	int32_t len;
4230 
4231 	len = sizeof(*cmd);
4232 	buf = wmi_buf_alloc(wmi_handle, len);
4233 	if (!buf) {
4234 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4235 		return QDF_STATUS_E_NOMEM;
4236 	}
4237 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4238 
4239 	cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr;
4240 	qdf_mem_zero(cmd, len);
4241 	WMITLV_SET_HDR(&cmd->tlv_header,
4242 		WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param,
4243 		WMITLV_GET_STRUCT_TLVLEN(
4244 			wmi_ocb_get_tsf_timer_cmd_fixed_param));
4245 	cmd->vdev_id = vdev_id;
4246 
4247 	/* Send the WMI command */
4248 	wmi_mtrace(WMI_OCB_GET_TSF_TIMER_CMDID, cmd->vdev_id, 0);
4249 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4250 				   WMI_OCB_GET_TSF_TIMER_CMDID);
4251 	/* If there is an error, set the completion event */
4252 	if (QDF_IS_STATUS_ERROR(ret)) {
4253 		WMI_LOGE(FL("Failed to send WMI message: %d"), ret);
4254 		wmi_buf_free(buf);
4255 	}
4256 
4257 	return ret;
4258 }
4259 
4260 /**
4261  * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats
4262  * @wmi_handle: pointer to the wmi handle
4263  * @get_stats_param: pointer to the dcc stats
4264  *
4265  * Return: 0 on succes
4266  */
4267 static QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle,
4268 		     struct ocb_dcc_get_stats_param *get_stats_param)
4269 {
4270 	QDF_STATUS ret;
4271 	wmi_dcc_get_stats_cmd_fixed_param *cmd;
4272 	wmi_dcc_channel_stats_request *channel_stats_array;
4273 	wmi_buf_t buf;
4274 	uint8_t *buf_ptr;
4275 	uint32_t len;
4276 	uint32_t i;
4277 
4278 	/* Validate the input */
4279 	if (get_stats_param->request_array_len !=
4280 	    get_stats_param->channel_count * sizeof(*channel_stats_array)) {
4281 		WMI_LOGE(FL("Invalid parameter"));
4282 		return QDF_STATUS_E_INVAL;
4283 	}
4284 
4285 	/* Allocate memory for the WMI command */
4286 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
4287 		get_stats_param->request_array_len;
4288 
4289 	buf = wmi_buf_alloc(wmi_handle, len);
4290 	if (!buf) {
4291 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4292 		return QDF_STATUS_E_NOMEM;
4293 	}
4294 
4295 	buf_ptr = wmi_buf_data(buf);
4296 	qdf_mem_zero(buf_ptr, len);
4297 
4298 	/* Populate the WMI command */
4299 	cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr;
4300 	buf_ptr += sizeof(*cmd);
4301 
4302 	WMITLV_SET_HDR(&cmd->tlv_header,
4303 		       WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param,
4304 		       WMITLV_GET_STRUCT_TLVLEN(
4305 			   wmi_dcc_get_stats_cmd_fixed_param));
4306 	cmd->vdev_id = get_stats_param->vdev_id;
4307 	cmd->num_channels = get_stats_param->channel_count;
4308 
4309 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4310 		       get_stats_param->request_array_len);
4311 	buf_ptr += WMI_TLV_HDR_SIZE;
4312 
4313 	channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr;
4314 	qdf_mem_copy(channel_stats_array, get_stats_param->request_array,
4315 		     get_stats_param->request_array_len);
4316 	for (i = 0; i < cmd->num_channels; i++)
4317 		WMITLV_SET_HDR(&channel_stats_array[i].tlv_header,
4318 			WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request,
4319 			WMITLV_GET_STRUCT_TLVLEN(
4320 			    wmi_dcc_channel_stats_request));
4321 
4322 	/* Send the WMI command */
4323 	wmi_mtrace(WMI_DCC_GET_STATS_CMDID, cmd->vdev_id, 0);
4324 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4325 				   WMI_DCC_GET_STATS_CMDID);
4326 
4327 	if (QDF_IS_STATUS_ERROR(ret)) {
4328 		WMI_LOGE(FL("Failed to send WMI message: %d"), ret);
4329 		wmi_buf_free(buf);
4330 	}
4331 
4332 	return ret;
4333 }
4334 
4335 /**
4336  * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats
4337  * @wmi_handle: pointer to the wmi handle
4338  * @vdev_id: vdev id
4339  * @dcc_stats_bitmap: dcc status bitmap
4340  *
4341  * Return: 0 on succes
4342  */
4343 static QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle,
4344 				uint32_t vdev_id, uint32_t dcc_stats_bitmap)
4345 {
4346 	QDF_STATUS ret;
4347 	wmi_dcc_clear_stats_cmd_fixed_param *cmd;
4348 	wmi_buf_t buf;
4349 	uint8_t *buf_ptr;
4350 	uint32_t len;
4351 
4352 	/* Allocate memory for the WMI command */
4353 	len = sizeof(*cmd);
4354 
4355 	buf = wmi_buf_alloc(wmi_handle, len);
4356 	if (!buf) {
4357 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4358 		return QDF_STATUS_E_NOMEM;
4359 	}
4360 
4361 	buf_ptr = wmi_buf_data(buf);
4362 	qdf_mem_zero(buf_ptr, len);
4363 
4364 	/* Populate the WMI command */
4365 	cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr;
4366 
4367 	WMITLV_SET_HDR(&cmd->tlv_header,
4368 		       WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param,
4369 		       WMITLV_GET_STRUCT_TLVLEN(
4370 			   wmi_dcc_clear_stats_cmd_fixed_param));
4371 	cmd->vdev_id = vdev_id;
4372 	cmd->dcc_stats_bitmap = dcc_stats_bitmap;
4373 
4374 	/* Send the WMI command */
4375 	wmi_mtrace(WMI_DCC_CLEAR_STATS_CMDID, cmd->vdev_id, 0);
4376 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4377 				   WMI_DCC_CLEAR_STATS_CMDID);
4378 	if (QDF_IS_STATUS_ERROR(ret)) {
4379 		WMI_LOGE(FL("Failed to send the WMI command"));
4380 		wmi_buf_free(buf);
4381 	}
4382 
4383 	return ret;
4384 }
4385 
4386 /**
4387  * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data
4388  * @wmi_handle: pointer to the wmi handle
4389  * @update_ndl_param: pointer to the request parameters
4390  *
4391  * Return: 0 on success
4392  */
4393 static QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle,
4394 		       struct ocb_dcc_update_ndl_param *update_ndl_param)
4395 {
4396 	QDF_STATUS qdf_status;
4397 	wmi_dcc_update_ndl_cmd_fixed_param *cmd;
4398 	wmi_dcc_ndl_chan *ndl_chan_array;
4399 	wmi_dcc_ndl_active_state_config *ndl_active_state_array;
4400 	uint32_t active_state_count;
4401 	wmi_buf_t buf;
4402 	uint8_t *buf_ptr;
4403 	uint32_t len;
4404 	uint32_t i;
4405 
4406 	/* validate the input */
4407 	if (update_ndl_param->dcc_ndl_chan_list_len !=
4408 	    update_ndl_param->channel_count * sizeof(*ndl_chan_array)) {
4409 		WMI_LOGE(FL("Invalid parameter"));
4410 		return QDF_STATUS_E_INVAL;
4411 	}
4412 	active_state_count = 0;
4413 	ndl_chan_array = update_ndl_param->dcc_ndl_chan_list;
4414 	for (i = 0; i < update_ndl_param->channel_count; i++)
4415 		active_state_count +=
4416 			WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]);
4417 	if (update_ndl_param->dcc_ndl_active_state_list_len !=
4418 	    active_state_count * sizeof(*ndl_active_state_array)) {
4419 		WMI_LOGE(FL("Invalid parameter"));
4420 		return QDF_STATUS_E_INVAL;
4421 	}
4422 
4423 	/* Allocate memory for the WMI command */
4424 	len = sizeof(*cmd) +
4425 		WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len +
4426 		WMI_TLV_HDR_SIZE +
4427 		update_ndl_param->dcc_ndl_active_state_list_len;
4428 
4429 	buf = wmi_buf_alloc(wmi_handle, len);
4430 	if (!buf) {
4431 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4432 		return QDF_STATUS_E_NOMEM;
4433 	}
4434 
4435 	buf_ptr = wmi_buf_data(buf);
4436 	qdf_mem_zero(buf_ptr, len);
4437 
4438 	/* Populate the WMI command */
4439 	cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr;
4440 	buf_ptr += sizeof(*cmd);
4441 
4442 	WMITLV_SET_HDR(&cmd->tlv_header,
4443 		       WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param,
4444 		       WMITLV_GET_STRUCT_TLVLEN(
4445 			   wmi_dcc_update_ndl_cmd_fixed_param));
4446 	cmd->vdev_id = update_ndl_param->vdev_id;
4447 	cmd->num_channel = update_ndl_param->channel_count;
4448 
4449 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4450 		       update_ndl_param->dcc_ndl_chan_list_len);
4451 	buf_ptr += WMI_TLV_HDR_SIZE;
4452 
4453 	ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr;
4454 	qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list,
4455 		     update_ndl_param->dcc_ndl_chan_list_len);
4456 	for (i = 0; i < cmd->num_channel; i++)
4457 		WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header,
4458 			WMITLV_TAG_STRUC_wmi_dcc_ndl_chan,
4459 			WMITLV_GET_STRUCT_TLVLEN(
4460 			    wmi_dcc_ndl_chan));
4461 	buf_ptr += update_ndl_param->dcc_ndl_chan_list_len;
4462 
4463 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4464 		       update_ndl_param->dcc_ndl_active_state_list_len);
4465 	buf_ptr += WMI_TLV_HDR_SIZE;
4466 
4467 	ndl_active_state_array = (wmi_dcc_ndl_active_state_config *) buf_ptr;
4468 	qdf_mem_copy(ndl_active_state_array,
4469 		     update_ndl_param->dcc_ndl_active_state_list,
4470 		     update_ndl_param->dcc_ndl_active_state_list_len);
4471 	for (i = 0; i < active_state_count; i++) {
4472 		WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header,
4473 			WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config,
4474 			WMITLV_GET_STRUCT_TLVLEN(
4475 			    wmi_dcc_ndl_active_state_config));
4476 	}
4477 	buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len;
4478 
4479 	/* Send the WMI command */
4480 	wmi_mtrace(WMI_DCC_UPDATE_NDL_CMDID, cmd->vdev_id, 0);
4481 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
4482 				   WMI_DCC_UPDATE_NDL_CMDID);
4483 	/* If there is an error, set the completion event */
4484 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4485 		WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status);
4486 		wmi_buf_free(buf);
4487 	}
4488 
4489 	return qdf_status;
4490 }
4491 
4492 /**
4493  * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW
4494  * @wmi_handle: pointer to the wmi handle
4495  * @config: the OCB configuration
4496  *
4497  * Return: 0 on success
4498  */
4499 static QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle,
4500 				struct ocb_config *config)
4501 {
4502 	QDF_STATUS ret;
4503 	wmi_ocb_set_config_cmd_fixed_param *cmd;
4504 	wmi_channel *chan;
4505 	wmi_ocb_channel *ocb_chan;
4506 	wmi_qos_parameter *qos_param;
4507 	wmi_dcc_ndl_chan *ndl_chan;
4508 	wmi_dcc_ndl_active_state_config *ndl_active_config;
4509 	wmi_ocb_schedule_element *sched_elem;
4510 	uint8_t *buf_ptr;
4511 	wmi_buf_t buf;
4512 	int32_t len;
4513 	int32_t i, j, active_state_count;
4514 
4515 	/*
4516 	 * Validate the dcc_ndl_chan_list_len and count the number of active
4517 	 * states. Validate dcc_ndl_active_state_list_len.
4518 	 */
4519 	active_state_count = 0;
4520 	if (config->dcc_ndl_chan_list_len) {
4521 		if (!config->dcc_ndl_chan_list ||
4522 			config->dcc_ndl_chan_list_len !=
4523 			config->channel_count * sizeof(wmi_dcc_ndl_chan)) {
4524 			WMI_LOGE(FL("NDL channel is invalid. List len: %d"),
4525 				 config->dcc_ndl_chan_list_len);
4526 			return QDF_STATUS_E_INVAL;
4527 		}
4528 
4529 		for (i = 0, ndl_chan = config->dcc_ndl_chan_list;
4530 				i < config->channel_count; ++i, ++ndl_chan)
4531 			active_state_count +=
4532 				WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan);
4533 
4534 		if (active_state_count) {
4535 			if (!config->dcc_ndl_active_state_list ||
4536 				config->dcc_ndl_active_state_list_len !=
4537 				active_state_count *
4538 				sizeof(wmi_dcc_ndl_active_state_config)) {
4539 				WMI_LOGE(FL("NDL active state is invalid."));
4540 				return QDF_STATUS_E_INVAL;
4541 			}
4542 		}
4543 	}
4544 
4545 	len = sizeof(*cmd) +
4546 		WMI_TLV_HDR_SIZE + config->channel_count *
4547 			sizeof(wmi_channel) +
4548 		WMI_TLV_HDR_SIZE + config->channel_count *
4549 			sizeof(wmi_ocb_channel) +
4550 		WMI_TLV_HDR_SIZE + config->channel_count *
4551 			sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC +
4552 		WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len +
4553 		WMI_TLV_HDR_SIZE + active_state_count *
4554 			sizeof(wmi_dcc_ndl_active_state_config) +
4555 		WMI_TLV_HDR_SIZE + config->schedule_size *
4556 			sizeof(wmi_ocb_schedule_element);
4557 	buf = wmi_buf_alloc(wmi_handle, len);
4558 	if (!buf) {
4559 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4560 		return QDF_STATUS_E_NOMEM;
4561 	}
4562 
4563 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4564 	cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr;
4565 	WMITLV_SET_HDR(&cmd->tlv_header,
4566 		WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param,
4567 		WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param));
4568 	cmd->vdev_id = config->vdev_id;
4569 	cmd->channel_count = config->channel_count;
4570 	cmd->schedule_size = config->schedule_size;
4571 	cmd->flags = config->flags;
4572 	buf_ptr += sizeof(*cmd);
4573 
4574 	/* Add the wmi_channel info */
4575 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4576 		       config->channel_count*sizeof(wmi_channel));
4577 	buf_ptr += WMI_TLV_HDR_SIZE;
4578 	for (i = 0; i < config->channel_count; i++) {
4579 		chan = (wmi_channel *)buf_ptr;
4580 		WMITLV_SET_HDR(&chan->tlv_header,
4581 				WMITLV_TAG_STRUC_wmi_channel,
4582 				WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
4583 		chan->mhz = config->channels[i].chan_freq;
4584 		chan->band_center_freq1 = config->channels[i].chan_freq;
4585 		chan->band_center_freq2 = 0;
4586 		chan->info = 0;
4587 
4588 		WMI_SET_CHANNEL_MODE(chan, config->channels[i].ch_mode);
4589 		WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr);
4590 		WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr);
4591 		WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr);
4592 		WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr);
4593 		WMI_SET_CHANNEL_ANTENNA_MAX(chan,
4594 					    config->channels[i].antenna_max);
4595 
4596 		if (config->channels[i].bandwidth < 10)
4597 			WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
4598 		else if (config->channels[i].bandwidth < 20)
4599 			WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
4600 		buf_ptr += sizeof(*chan);
4601 	}
4602 
4603 	/* Add the wmi_ocb_channel info */
4604 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4605 		       config->channel_count*sizeof(wmi_ocb_channel));
4606 	buf_ptr += WMI_TLV_HDR_SIZE;
4607 	for (i = 0; i < config->channel_count; i++) {
4608 		ocb_chan = (wmi_ocb_channel *)buf_ptr;
4609 		WMITLV_SET_HDR(&ocb_chan->tlv_header,
4610 			       WMITLV_TAG_STRUC_wmi_ocb_channel,
4611 			       WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel));
4612 		ocb_chan->bandwidth = config->channels[i].bandwidth;
4613 		WMI_CHAR_ARRAY_TO_MAC_ADDR(
4614 					config->channels[i].mac_address.bytes,
4615 					&ocb_chan->mac_address);
4616 		buf_ptr += sizeof(*ocb_chan);
4617 	}
4618 
4619 	/* Add the wmi_qos_parameter info */
4620 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4621 		config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC);
4622 	buf_ptr += WMI_TLV_HDR_SIZE;
4623 	/* WMI_MAX_NUM_AC parameters for each channel */
4624 	for (i = 0; i < config->channel_count; i++) {
4625 		for (j = 0; j < WMI_MAX_NUM_AC; j++) {
4626 			qos_param = (wmi_qos_parameter *)buf_ptr;
4627 			WMITLV_SET_HDR(&qos_param->tlv_header,
4628 				WMITLV_TAG_STRUC_wmi_qos_parameter,
4629 				WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter));
4630 			qos_param->aifsn =
4631 				config->channels[i].qos_params[j].aifsn;
4632 			qos_param->cwmin =
4633 				config->channels[i].qos_params[j].cwmin;
4634 			qos_param->cwmax =
4635 				config->channels[i].qos_params[j].cwmax;
4636 			buf_ptr += sizeof(*qos_param);
4637 		}
4638 	}
4639 
4640 	/* Add the wmi_dcc_ndl_chan (per channel) */
4641 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4642 		       config->dcc_ndl_chan_list_len);
4643 	buf_ptr += WMI_TLV_HDR_SIZE;
4644 	if (config->dcc_ndl_chan_list_len) {
4645 		ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr;
4646 		qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list,
4647 			     config->dcc_ndl_chan_list_len);
4648 		for (i = 0; i < config->channel_count; i++)
4649 			WMITLV_SET_HDR(&(ndl_chan[i].tlv_header),
4650 				WMITLV_TAG_STRUC_wmi_dcc_ndl_chan,
4651 				WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan));
4652 		buf_ptr += config->dcc_ndl_chan_list_len;
4653 	}
4654 
4655 	/* Add the wmi_dcc_ndl_active_state_config */
4656 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count *
4657 		       sizeof(wmi_dcc_ndl_active_state_config));
4658 	buf_ptr += WMI_TLV_HDR_SIZE;
4659 	if (active_state_count) {
4660 		ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr;
4661 		qdf_mem_copy(ndl_active_config,
4662 			config->dcc_ndl_active_state_list,
4663 			active_state_count * sizeof(*ndl_active_config));
4664 		for (i = 0; i < active_state_count; ++i)
4665 			WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header),
4666 			  WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config,
4667 			  WMITLV_GET_STRUCT_TLVLEN(
4668 				wmi_dcc_ndl_active_state_config));
4669 		buf_ptr += active_state_count *
4670 			sizeof(*ndl_active_config);
4671 	}
4672 
4673 	/* Add the wmi_ocb_schedule_element info */
4674 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4675 		config->schedule_size * sizeof(wmi_ocb_schedule_element));
4676 	buf_ptr += WMI_TLV_HDR_SIZE;
4677 	for (i = 0; i < config->schedule_size; i++) {
4678 		sched_elem = (wmi_ocb_schedule_element *)buf_ptr;
4679 		WMITLV_SET_HDR(&sched_elem->tlv_header,
4680 			WMITLV_TAG_STRUC_wmi_ocb_schedule_element,
4681 			WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element));
4682 		sched_elem->channel_freq = config->schedule[i].chan_freq;
4683 		sched_elem->total_duration = config->schedule[i].total_duration;
4684 		sched_elem->guard_interval = config->schedule[i].guard_interval;
4685 		buf_ptr += sizeof(*sched_elem);
4686 	}
4687 
4688 
4689 	wmi_mtrace(WMI_OCB_SET_CONFIG_CMDID, cmd->vdev_id, 0);
4690 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4691 				   WMI_OCB_SET_CONFIG_CMDID);
4692 	if (QDF_IS_STATUS_ERROR(ret)) {
4693 		WMI_LOGE("Failed to set OCB config");
4694 		wmi_buf_free(buf);
4695 	}
4696 
4697 	return ret;
4698 }
4699 
4700 /**
4701  * extract_ocb_channel_config_resp_tlv() - extract ocb channel config resp
4702  * @wmi_handle: wmi handle
4703  * @evt_buf: wmi event buffer
4704  * @status: status buffer
4705  *
4706  * Return: QDF_STATUS_SUCCESS on success
4707  */
4708 static QDF_STATUS extract_ocb_channel_config_resp_tlv(wmi_unified_t wmi_handle,
4709 						      void *evt_buf,
4710 						      uint32_t *status)
4711 {
4712 	WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs;
4713 	wmi_ocb_set_config_resp_event_fixed_param *fix_param;
4714 
4715 	param_tlvs = evt_buf;
4716 	fix_param = param_tlvs->fixed_param;
4717 
4718 	*status = fix_param->status;
4719 	return QDF_STATUS_SUCCESS;
4720 }
4721 
4722 /**
4723  * extract_ocb_tsf_timer_tlv() - extract TSF timer from event buffer
4724  * @wmi_handle: wmi handle
4725  * @evt_buf: wmi event buffer
4726  * @resp: response buffer
4727  *
4728  * Return: QDF_STATUS_SUCCESS on success
4729  */
4730 static QDF_STATUS extract_ocb_tsf_timer_tlv(wmi_unified_t wmi_handle,
4731 			void *evt_buf, struct ocb_get_tsf_timer_response *resp)
4732 {
4733 	WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs;
4734 	wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param;
4735 
4736 	param_tlvs = evt_buf;
4737 	fix_param = param_tlvs->fixed_param;
4738 	resp->vdev_id = fix_param->vdev_id;
4739 	resp->timer_high = fix_param->tsf_timer_high;
4740 	resp->timer_low = fix_param->tsf_timer_low;
4741 
4742 	return QDF_STATUS_SUCCESS;
4743 }
4744 
4745 /**
4746  * extract_ocb_ndl_resp_tlv() - extract TSF timer from event buffer
4747  * @wmi_handle: wmi handle
4748  * @evt_buf: wmi event buffer
4749  * @resp: response buffer
4750  *
4751  * Return: QDF_STATUS_SUCCESS on success
4752  */
4753 static QDF_STATUS extract_ocb_ndl_resp_tlv(wmi_unified_t wmi_handle,
4754 		void *evt_buf, struct ocb_dcc_update_ndl_response *resp)
4755 {
4756 	WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs;
4757 	wmi_dcc_update_ndl_resp_event_fixed_param *fix_param;
4758 
4759 	param_tlvs = evt_buf;
4760 	fix_param = param_tlvs->fixed_param;
4761 	resp->vdev_id = fix_param->vdev_id;
4762 	resp->status = fix_param->status;
4763 	return QDF_STATUS_SUCCESS;
4764 }
4765 
4766 /**
4767  * extract_ocb_dcc_stats_tlv() - extract DCC stats from event buffer
4768  * @wmi_handle: wmi handle
4769  * @evt_buf: wmi event buffer
4770  * @resp: response buffer
4771  *
4772  * Since length of stats is variable, buffer for DCC stats will be allocated
4773  * in this function. The caller must free the buffer.
4774  *
4775  * Return: QDF_STATUS_SUCCESS on success
4776  */
4777 static QDF_STATUS extract_ocb_dcc_stats_tlv(wmi_unified_t wmi_handle,
4778 		void *evt_buf, struct ocb_dcc_get_stats_response **resp)
4779 {
4780 	struct ocb_dcc_get_stats_response *response;
4781 	WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs;
4782 	wmi_dcc_get_stats_resp_event_fixed_param *fix_param;
4783 
4784 	param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)evt_buf;
4785 	fix_param = param_tlvs->fixed_param;
4786 
4787 	/* Allocate and populate the response */
4788 	if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE -
4789 	    sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) {
4790 		WMI_LOGE("%s: too many channels:%d", __func__,
4791 			 fix_param->num_channels);
4792 		QDF_ASSERT(0);
4793 		*resp = NULL;
4794 		return QDF_STATUS_E_INVAL;
4795 	}
4796 	response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels *
4797 		sizeof(wmi_dcc_ndl_stats_per_channel));
4798 	*resp = response;
4799 	if (!response)
4800 		return  QDF_STATUS_E_NOMEM;
4801 
4802 	response->vdev_id = fix_param->vdev_id;
4803 	response->num_channels = fix_param->num_channels;
4804 	response->channel_stats_array_len =
4805 		fix_param->num_channels *
4806 		sizeof(wmi_dcc_ndl_stats_per_channel);
4807 	response->channel_stats_array = ((uint8_t *)response) +
4808 					sizeof(*response);
4809 	qdf_mem_copy(response->channel_stats_array,
4810 		     param_tlvs->stats_per_channel_list,
4811 		     response->channel_stats_array_len);
4812 
4813 	return QDF_STATUS_SUCCESS;
4814 }
4815 #endif
4816 
4817 /**
4818  * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable mcc scheduler
4819  * @wmi_handle: wmi handle
4820  * @mcc_adaptive_scheduler: enable/disable
4821  *
4822  * This function enable/disable mcc adaptive scheduler in fw.
4823  *
4824  * Return: QDF_STATUS_SUCCESS for success or error code
4825  */
4826 static QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv(
4827 		wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler,
4828 		uint32_t pdev_id)
4829 {
4830 	QDF_STATUS ret;
4831 	wmi_buf_t buf = 0;
4832 	wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL;
4833 	uint16_t len =
4834 		sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param);
4835 
4836 	buf = wmi_buf_alloc(wmi_handle, len);
4837 	if (!buf) {
4838 		WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
4839 		return QDF_STATUS_E_NOMEM;
4840 	}
4841 	cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *)
4842 		wmi_buf_data(buf);
4843 
4844 	WMITLV_SET_HDR(&cmd->tlv_header,
4845 		       WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param,
4846 		       WMITLV_GET_STRUCT_TLVLEN
4847 			       (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param));
4848 	cmd->enable = mcc_adaptive_scheduler;
4849 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
4850 
4851 	wmi_mtrace(WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID, NO_SESSION, 0);
4852 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4853 				   WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID);
4854 	if (QDF_IS_STATUS_ERROR(ret)) {
4855 		WMI_LOGP("%s: Failed to send enable/disable MCC"
4856 			 " adaptive scheduler command", __func__);
4857 		wmi_buf_free(buf);
4858 	}
4859 
4860 	return ret;
4861 }
4862 
4863 /**
4864  * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency
4865  * @wmi: wmi handle
4866  * @mcc_channel: mcc channel
4867  * @mcc_channel_time_latency: MCC channel time latency.
4868  *
4869  * Currently used to set time latency for an MCC vdev/adapter using operating
4870  * channel of it and channel number. The info is provided run time using
4871  * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>.
4872  *
4873  * Return: CDF status
4874  */
4875 static QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(wmi_unified_t wmi_handle,
4876 	uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency)
4877 {
4878 	QDF_STATUS ret;
4879 	wmi_buf_t buf = 0;
4880 	wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL;
4881 	uint16_t len = 0;
4882 	uint8_t *buf_ptr = NULL;
4883 	wmi_resmgr_chan_latency chan_latency;
4884 	/* Note: we only support MCC time latency for a single channel */
4885 	uint32_t num_channels = 1;
4886 	uint32_t chan1_freq = mcc_channel_freq;
4887 	uint32_t latency_chan1 = mcc_channel_time_latency;
4888 
4889 
4890 	/* If 0ms latency is provided, then FW will set to a default.
4891 	 * Otherwise, latency must be at least 30ms.
4892 	 */
4893 	if ((latency_chan1 > 0) &&
4894 	    (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) {
4895 		WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms "
4896 			 "Minimum is 30ms (or 0 to use default value by "
4897 			 "firmware)", __func__, latency_chan1);
4898 		return QDF_STATUS_E_INVAL;
4899 	}
4900 
4901 	/*   Set WMI CMD for channel time latency here */
4902 	len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) +
4903 	      WMI_TLV_HDR_SIZE +  /*Place holder for chan_time_latency array */
4904 	      num_channels * sizeof(wmi_resmgr_chan_latency);
4905 	buf = wmi_buf_alloc(wmi_handle, len);
4906 	if (!buf) {
4907 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
4908 		return QDF_STATUS_E_NOMEM;
4909 	}
4910 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
4911 	cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *)
4912 		wmi_buf_data(buf);
4913 	WMITLV_SET_HDR(&cmdTL->tlv_header,
4914 		WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param,
4915 		       WMITLV_GET_STRUCT_TLVLEN
4916 		       (wmi_resmgr_set_chan_latency_cmd_fixed_param));
4917 	cmdTL->num_chans = num_channels;
4918 	/* Update channel time latency information for home channel(s) */
4919 	buf_ptr += sizeof(*cmdTL);
4920 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
4921 		       num_channels * sizeof(wmi_resmgr_chan_latency));
4922 	buf_ptr += WMI_TLV_HDR_SIZE;
4923 	chan_latency.chan_mhz = chan1_freq;
4924 	chan_latency.latency = latency_chan1;
4925 	qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency));
4926 	wmi_mtrace(WMI_RESMGR_SET_CHAN_LATENCY_CMDID, NO_SESSION, 0);
4927 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4928 				   WMI_RESMGR_SET_CHAN_LATENCY_CMDID);
4929 	if (QDF_IS_STATUS_ERROR(ret)) {
4930 		WMI_LOGE("%s: Failed to send MCC Channel Time Latency command",
4931 			 __func__);
4932 		wmi_buf_free(buf);
4933 		QDF_ASSERT(0);
4934 	}
4935 
4936 	return ret;
4937 }
4938 
4939 /**
4940  * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota
4941  * @wmi: wmi handle
4942  * @adapter_1_chan_number: adapter 1 channel number
4943  * @adapter_1_quota: adapter 1 quota
4944  * @adapter_2_chan_number: adapter 2 channel number
4945  *
4946  * Return: CDF status
4947  */
4948 static QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(wmi_unified_t wmi_handle,
4949 	uint32_t adapter_1_chan_freq,
4950 	uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq)
4951 {
4952 	QDF_STATUS ret;
4953 	wmi_buf_t buf = 0;
4954 	uint16_t len = 0;
4955 	uint8_t *buf_ptr = NULL;
4956 	wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL;
4957 	wmi_resmgr_chan_time_quota chan_quota;
4958 	uint32_t quota_chan1 = adapter_1_quota;
4959 	/* Knowing quota of 1st chan., derive quota for 2nd chan. */
4960 	uint32_t quota_chan2 = 100 - quota_chan1;
4961 	/* Note: setting time quota for MCC requires info for 2 channels */
4962 	uint32_t num_channels = 2;
4963 	uint32_t chan1_freq = adapter_1_chan_freq;
4964 	uint32_t chan2_freq = adapter_2_chan_freq;
4965 
4966 	WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, "
4967 		 "freq2:%dMHz, Quota2:%dms", __func__,
4968 		 chan1_freq, quota_chan1, chan2_freq,
4969 		 quota_chan2);
4970 
4971 	/*
4972 	 * Perform sanity check on time quota values provided.
4973 	 */
4974 	if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA ||
4975 	    quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) {
4976 		WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum "
4977 			 "is 20ms & maximum is 80ms", __func__, quota_chan1);
4978 		return QDF_STATUS_E_INVAL;
4979 	}
4980 	/* Set WMI CMD for channel time quota here */
4981 	len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) +
4982 	      WMI_TLV_HDR_SIZE +       /* Place holder for chan_time_quota array */
4983 	      num_channels * sizeof(wmi_resmgr_chan_time_quota);
4984 	buf = wmi_buf_alloc(wmi_handle, len);
4985 	if (!buf) {
4986 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
4987 		QDF_ASSERT(0);
4988 		return QDF_STATUS_E_NOMEM;
4989 	}
4990 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
4991 	cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *)
4992 		wmi_buf_data(buf);
4993 	WMITLV_SET_HDR(&cmdTQ->tlv_header,
4994 		       WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param,
4995 		       WMITLV_GET_STRUCT_TLVLEN
4996 			       (wmi_resmgr_set_chan_time_quota_cmd_fixed_param));
4997 	cmdTQ->num_chans = num_channels;
4998 
4999 	/* Update channel time quota information for home channel(s) */
5000 	buf_ptr += sizeof(*cmdTQ);
5001 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5002 		       num_channels * sizeof(wmi_resmgr_chan_time_quota));
5003 	buf_ptr += WMI_TLV_HDR_SIZE;
5004 	chan_quota.chan_mhz = chan1_freq;
5005 	chan_quota.channel_time_quota = quota_chan1;
5006 	qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
5007 	/* Construct channel and quota record for the 2nd MCC mode. */
5008 	buf_ptr += sizeof(chan_quota);
5009 	chan_quota.chan_mhz = chan2_freq;
5010 	chan_quota.channel_time_quota = quota_chan2;
5011 	qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
5012 
5013 	wmi_mtrace(WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID, NO_SESSION, 0);
5014 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5015 				   WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID);
5016 	if (QDF_IS_STATUS_ERROR(ret)) {
5017 		WMI_LOGE("Failed to send MCC Channel Time Quota command");
5018 		wmi_buf_free(buf);
5019 		QDF_ASSERT(0);
5020 	}
5021 
5022 	return ret;
5023 }
5024 
5025 /**
5026  * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw
5027  * @wmi_handle: Pointer to wmi handle
5028  * @thermal_info: Thermal command information
5029  *
5030  * This function sends the thermal management command
5031  * to the firmware
5032  *
5033  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5034  */
5035 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
5036 				struct thermal_cmd_params *thermal_info)
5037 {
5038 	wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL;
5039 	wmi_buf_t buf = NULL;
5040 	QDF_STATUS status;
5041 	uint32_t len = 0;
5042 
5043 	len = sizeof(*cmd);
5044 
5045 	buf = wmi_buf_alloc(wmi_handle, len);
5046 	if (!buf) {
5047 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
5048 		return QDF_STATUS_E_FAILURE;
5049 	}
5050 
5051 	cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf);
5052 
5053 	WMITLV_SET_HDR(&cmd->tlv_header,
5054 		       WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param,
5055 		       WMITLV_GET_STRUCT_TLVLEN
5056 			       (wmi_thermal_mgmt_cmd_fixed_param));
5057 
5058 	cmd->lower_thresh_degreeC = thermal_info->min_temp;
5059 	cmd->upper_thresh_degreeC = thermal_info->max_temp;
5060 	cmd->enable = thermal_info->thermal_enable;
5061 
5062 	WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d",
5063 		cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable);
5064 
5065 	wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0);
5066 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
5067 				      WMI_THERMAL_MGMT_CMDID);
5068 	if (QDF_IS_STATUS_ERROR(status)) {
5069 		wmi_buf_free(buf);
5070 		WMI_LOGE("%s:Failed to send thermal mgmt command", __func__);
5071 	}
5072 
5073 	return status;
5074 }
5075 
5076 
5077 /**
5078  * send_lro_config_cmd_tlv() - process the LRO config command
5079  * @wmi_handle: Pointer to WMI handle
5080  * @wmi_lro_cmd: Pointer to LRO configuration parameters
5081  *
5082  * This function sends down the LRO configuration parameters to
5083  * the firmware to enable LRO, sets the TCP flags and sets the
5084  * seed values for the toeplitz hash generation
5085  *
5086  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5087  */
5088 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle,
5089 	 struct wmi_lro_config_cmd_t *wmi_lro_cmd)
5090 {
5091 	wmi_lro_info_cmd_fixed_param *cmd;
5092 	wmi_buf_t buf;
5093 	QDF_STATUS status;
5094 
5095 
5096 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
5097 	if (!buf) {
5098 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
5099 		return QDF_STATUS_E_FAILURE;
5100 	}
5101 
5102 	cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf);
5103 
5104 	WMITLV_SET_HDR(&cmd->tlv_header,
5105 		 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param,
5106 		 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param));
5107 
5108 	cmd->lro_enable = wmi_lro_cmd->lro_enable;
5109 	WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32,
5110 		 wmi_lro_cmd->tcp_flag);
5111 	WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32,
5112 		 wmi_lro_cmd->tcp_flag_mask);
5113 	cmd->toeplitz_hash_ipv4_0_3 =
5114 		 wmi_lro_cmd->toeplitz_hash_ipv4[0];
5115 	cmd->toeplitz_hash_ipv4_4_7 =
5116 		 wmi_lro_cmd->toeplitz_hash_ipv4[1];
5117 	cmd->toeplitz_hash_ipv4_8_11 =
5118 		 wmi_lro_cmd->toeplitz_hash_ipv4[2];
5119 	cmd->toeplitz_hash_ipv4_12_15 =
5120 		 wmi_lro_cmd->toeplitz_hash_ipv4[3];
5121 	cmd->toeplitz_hash_ipv4_16 =
5122 		 wmi_lro_cmd->toeplitz_hash_ipv4[4];
5123 
5124 	cmd->toeplitz_hash_ipv6_0_3 =
5125 		 wmi_lro_cmd->toeplitz_hash_ipv6[0];
5126 	cmd->toeplitz_hash_ipv6_4_7 =
5127 		 wmi_lro_cmd->toeplitz_hash_ipv6[1];
5128 	cmd->toeplitz_hash_ipv6_8_11 =
5129 		 wmi_lro_cmd->toeplitz_hash_ipv6[2];
5130 	cmd->toeplitz_hash_ipv6_12_15 =
5131 		 wmi_lro_cmd->toeplitz_hash_ipv6[3];
5132 	cmd->toeplitz_hash_ipv6_16_19 =
5133 		 wmi_lro_cmd->toeplitz_hash_ipv6[4];
5134 	cmd->toeplitz_hash_ipv6_20_23 =
5135 		 wmi_lro_cmd->toeplitz_hash_ipv6[5];
5136 	cmd->toeplitz_hash_ipv6_24_27 =
5137 		 wmi_lro_cmd->toeplitz_hash_ipv6[6];
5138 	cmd->toeplitz_hash_ipv6_28_31 =
5139 		 wmi_lro_cmd->toeplitz_hash_ipv6[7];
5140 	cmd->toeplitz_hash_ipv6_32_35 =
5141 		 wmi_lro_cmd->toeplitz_hash_ipv6[8];
5142 	cmd->toeplitz_hash_ipv6_36_39 =
5143 		 wmi_lro_cmd->toeplitz_hash_ipv6[9];
5144 	cmd->toeplitz_hash_ipv6_40 =
5145 		 wmi_lro_cmd->toeplitz_hash_ipv6[10];
5146 
5147 	WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x",
5148 		cmd->lro_enable, cmd->tcp_flag_u32);
5149 
5150 	wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0);
5151 	status = wmi_unified_cmd_send(wmi_handle, buf,
5152 		 sizeof(*cmd), WMI_LRO_CONFIG_CMDID);
5153 	if (QDF_IS_STATUS_ERROR(status)) {
5154 		wmi_buf_free(buf);
5155 		WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__);
5156 	}
5157 
5158 	return status;
5159 }
5160 
5161 /**
5162  * send_peer_rate_report_cmd_tlv() - process the peer rate report command
5163  * @wmi_handle: Pointer to wmi handle
5164  * @rate_report_params: Pointer to peer rate report parameters
5165  *
5166  *
5167  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5168  */
5169 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle,
5170 	 struct wmi_peer_rate_report_params *rate_report_params)
5171 {
5172 	wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL;
5173 	wmi_buf_t buf = NULL;
5174 	QDF_STATUS status = 0;
5175 	uint32_t len = 0;
5176 	uint32_t i, j;
5177 
5178 	len = sizeof(*cmd);
5179 
5180 	buf = wmi_buf_alloc(wmi_handle, len);
5181 	if (!buf) {
5182 		WMI_LOGE("Failed to alloc buf to peer_set_condition cmd\n");
5183 		return QDF_STATUS_E_FAILURE;
5184 	}
5185 
5186 	cmd = (wmi_peer_set_rate_report_condition_fixed_param *)
5187 		wmi_buf_data(buf);
5188 
5189 	WMITLV_SET_HDR(
5190 	&cmd->tlv_header,
5191 	WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param,
5192 	WMITLV_GET_STRUCT_TLVLEN(
5193 		wmi_peer_set_rate_report_condition_fixed_param));
5194 
5195 	cmd->enable_rate_report  = rate_report_params->rate_report_enable;
5196 	cmd->report_backoff_time = rate_report_params->backoff_time;
5197 	cmd->report_timer_period = rate_report_params->timer_period;
5198 	for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) {
5199 		cmd->cond_per_phy[i].val_cond_flags        =
5200 			rate_report_params->report_per_phy[i].cond_flags;
5201 		cmd->cond_per_phy[i].rate_delta.min_delta  =
5202 			rate_report_params->report_per_phy[i].delta.delta_min;
5203 		cmd->cond_per_phy[i].rate_delta.percentage =
5204 			rate_report_params->report_per_phy[i].delta.percent;
5205 		for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) {
5206 			cmd->cond_per_phy[i].rate_threshold[j] =
5207 			rate_report_params->report_per_phy[i].
5208 						report_rate_threshold[j];
5209 		}
5210 	}
5211 
5212 	WMI_LOGE("%s enable %d backoff_time %d period %d\n", __func__,
5213 		 cmd->enable_rate_report,
5214 		 cmd->report_backoff_time, cmd->report_timer_period);
5215 
5216 	wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0);
5217 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
5218 			WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID);
5219 	if (QDF_IS_STATUS_ERROR(status)) {
5220 		wmi_buf_free(buf);
5221 		WMI_LOGE("%s:Failed to send peer_set_report_cond command",
5222 			 __func__);
5223 	}
5224 	return status;
5225 }
5226 
5227 /**
5228  * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL
5229  * @wmi_handle: wmi handle
5230  * @param: bcn ll cmd parameter
5231  *
5232  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5233  */
5234 static QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle,
5235 			wmi_bcn_send_from_host_cmd_fixed_param *param)
5236 {
5237 	wmi_bcn_send_from_host_cmd_fixed_param *cmd;
5238 	wmi_buf_t wmi_buf;
5239 	QDF_STATUS ret;
5240 
5241 	wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
5242 	if (!wmi_buf) {
5243 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
5244 		return QDF_STATUS_E_FAILURE;
5245 	}
5246 
5247 	cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf);
5248 	WMITLV_SET_HDR(&cmd->tlv_header,
5249 		       WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param,
5250 		       WMITLV_GET_STRUCT_TLVLEN
5251 			       (wmi_bcn_send_from_host_cmd_fixed_param));
5252 	cmd->vdev_id = param->vdev_id;
5253 	cmd->data_len = param->data_len;
5254 	cmd->frame_ctrl = param->frame_ctrl;
5255 	cmd->frag_ptr = param->frag_ptr;
5256 	cmd->dtim_flag = param->dtim_flag;
5257 
5258 	wmi_mtrace(WMI_PDEV_SEND_BCN_CMDID, cmd->vdev_id, 0);
5259 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd),
5260 				      WMI_PDEV_SEND_BCN_CMDID);
5261 
5262 	if (QDF_IS_STATUS_ERROR(ret)) {
5263 		WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command");
5264 		wmi_buf_free(wmi_buf);
5265 	}
5266 
5267 	return ret;
5268 }
5269 
5270 /**
5271  * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters
5272  * @wmi_handle: wmi handle
5273  * @vdev_id: vdev id
5274  * @max_retries: max retries
5275  * @retry_interval: retry interval
5276  * This function sets sta query related parameters in fw.
5277  *
5278  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5279  */
5280 
5281 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle,
5282 				       uint8_t vdev_id, uint32_t max_retries,
5283 					   uint32_t retry_interval)
5284 {
5285 	wmi_buf_t buf;
5286 	WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd;
5287 	int len;
5288 
5289 	len = sizeof(*cmd);
5290 	buf = wmi_buf_alloc(wmi_handle, len);
5291 	if (!buf) {
5292 		WMI_LOGE(FL("wmi_buf_alloc failed"));
5293 		return QDF_STATUS_E_FAILURE;
5294 	}
5295 
5296 	cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf);
5297 	WMITLV_SET_HDR(&cmd->tlv_header,
5298 		WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param,
5299 		WMITLV_GET_STRUCT_TLVLEN
5300 		(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param));
5301 
5302 
5303 	cmd->vdev_id = vdev_id;
5304 	cmd->sa_query_max_retry_count = max_retries;
5305 	cmd->sa_query_retry_interval = retry_interval;
5306 
5307 	WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"),
5308 		 vdev_id, retry_interval, max_retries);
5309 
5310 	wmi_mtrace(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID, cmd->vdev_id, 0);
5311 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
5312 				 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) {
5313 		WMI_LOGE(FL("Failed to offload STA SA Query"));
5314 		wmi_buf_free(buf);
5315 		return QDF_STATUS_E_FAILURE;
5316 	}
5317 
5318 	WMI_LOGD(FL("Exit :"));
5319 	return 0;
5320 }
5321 
5322 /**
5323  * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters
5324  * @wmi_handle: wmi handle
5325  * @params: sta keep alive parameter
5326  *
5327  * This function sets keep alive related parameters in fw.
5328  *
5329  * Return: CDF status
5330  */
5331 static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle,
5332 				struct sta_params *params)
5333 {
5334 	wmi_buf_t buf;
5335 	WMI_STA_KEEPALIVE_CMD_fixed_param *cmd;
5336 	WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp;
5337 	uint8_t *buf_ptr;
5338 	int len;
5339 	QDF_STATUS ret;
5340 
5341 	WMI_LOGD("%s: Enter", __func__);
5342 
5343 	len = sizeof(*cmd) + sizeof(*arp_rsp);
5344 	buf = wmi_buf_alloc(wmi_handle, len);
5345 	if (!buf) {
5346 		WMI_LOGE("wmi_buf_alloc failed");
5347 		return QDF_STATUS_E_FAILURE;
5348 	}
5349 
5350 	cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf);
5351 	buf_ptr = (uint8_t *) cmd;
5352 	WMITLV_SET_HDR(&cmd->tlv_header,
5353 		       WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param,
5354 		       WMITLV_GET_STRUCT_TLVLEN
5355 			       (WMI_STA_KEEPALIVE_CMD_fixed_param));
5356 	cmd->interval = params->timeperiod;
5357 	cmd->enable = (params->timeperiod) ? 1 : 0;
5358 	cmd->vdev_id = params->vdev_id;
5359 	WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id,
5360 		 params->timeperiod, params->method);
5361 	arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd));
5362 	WMITLV_SET_HDR(&arp_rsp->tlv_header,
5363 		       WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE,
5364 		       WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE));
5365 
5366 	if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) ||
5367 	    (params->method ==
5368 	     WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) {
5369 		if ((NULL == params->hostv4addr) ||
5370 			(NULL == params->destv4addr) ||
5371 			(NULL == params->destmac)) {
5372 			WMI_LOGE("%s: received null pointer, hostv4addr:%pK "
5373 			   "destv4addr:%pK destmac:%pK ", __func__,
5374 			   params->hostv4addr, params->destv4addr, params->destmac);
5375 			wmi_buf_free(buf);
5376 			return QDF_STATUS_E_FAILURE;
5377 		}
5378 		cmd->method = params->method;
5379 		qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr,
5380 			     WMI_IPV4_ADDR_LEN);
5381 		qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr,
5382 			     WMI_IPV4_ADDR_LEN);
5383 		WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr);
5384 	} else {
5385 		cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
5386 	}
5387 
5388 	wmi_mtrace(WMI_STA_KEEPALIVE_CMDID, cmd->vdev_id, 0);
5389 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5390 				 WMI_STA_KEEPALIVE_CMDID);
5391 	if (QDF_IS_STATUS_ERROR(ret)) {
5392 		WMI_LOGE("Failed to set KeepAlive");
5393 		wmi_buf_free(buf);
5394 	}
5395 
5396 	WMI_LOGD("%s: Exit", __func__);
5397 	return ret;
5398 }
5399 
5400 /**
5401  * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params
5402  * @wmi_handle: wmi handle
5403  * @if_id: vdev id
5404  * @gtx_info: GTX config params
5405  *
5406  * This function set GTX related params in firmware.
5407  *
5408  * Return: QDF_STATUS_SUCCESS for success or error code
5409  */
5410 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id,
5411 				  struct wmi_gtx_config *gtx_info)
5412 {
5413 	wmi_vdev_set_gtx_params_cmd_fixed_param *cmd;
5414 	wmi_buf_t buf;
5415 	QDF_STATUS ret;
5416 	int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param);
5417 
5418 	buf = wmi_buf_alloc(wmi_handle, len);
5419 	if (!buf) {
5420 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
5421 		return QDF_STATUS_E_NOMEM;
5422 	}
5423 	cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf);
5424 	WMITLV_SET_HDR(&cmd->tlv_header,
5425 		       WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param,
5426 		       WMITLV_GET_STRUCT_TLVLEN
5427 			       (wmi_vdev_set_gtx_params_cmd_fixed_param));
5428 	cmd->vdev_id = if_id;
5429 
5430 	cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0];
5431 	cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1];
5432 	cmd->userGtxMask = gtx_info->gtx_usrcfg;
5433 	cmd->gtxPERThreshold = gtx_info->gtx_threshold;
5434 	cmd->gtxPERMargin = gtx_info->gtx_margin;
5435 	cmd->gtxTPCstep = gtx_info->gtx_tpcstep;
5436 	cmd->gtxTPCMin = gtx_info->gtx_tpcmin;
5437 	cmd->gtxBWMask = gtx_info->gtx_bwmask;
5438 
5439 	WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \
5440 		gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \
5441 		gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1],
5442 		 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin,
5443 		 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask);
5444 
5445 	wmi_mtrace(WMI_VDEV_SET_GTX_PARAMS_CMDID, cmd->vdev_id, 0);
5446 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5447 				    WMI_VDEV_SET_GTX_PARAMS_CMDID);
5448 	if (QDF_IS_STATUS_ERROR(ret)) {
5449 		WMI_LOGE("Failed to set GTX PARAMS");
5450 		wmi_buf_free(buf);
5451 	}
5452 	return ret;
5453 }
5454 
5455 /**
5456  * send_process_update_edca_param_cmd_tlv() - update EDCA params
5457  * @wmi_handle: wmi handle
5458  * @vdev_id: vdev id.
5459  * @wmm_vparams: edca parameters
5460  *
5461  * This function updates EDCA parameters to the target
5462  *
5463  * Return: CDF Status
5464  */
5465 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle,
5466 				    uint8_t vdev_id, bool mu_edca_param,
5467 				    struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC])
5468 {
5469 	uint8_t *buf_ptr;
5470 	wmi_buf_t buf;
5471 	wmi_vdev_set_wmm_params_cmd_fixed_param *cmd;
5472 	wmi_wmm_vparams *wmm_param;
5473 	struct wmi_host_wme_vparams *twmm_param;
5474 	int len = sizeof(*cmd);
5475 	int ac;
5476 
5477 	buf = wmi_buf_alloc(wmi_handle, len);
5478 
5479 	if (!buf) {
5480 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
5481 		return QDF_STATUS_E_NOMEM;
5482 	}
5483 
5484 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
5485 	cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr;
5486 	WMITLV_SET_HDR(&cmd->tlv_header,
5487 		       WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param,
5488 		       WMITLV_GET_STRUCT_TLVLEN
5489 			       (wmi_vdev_set_wmm_params_cmd_fixed_param));
5490 	cmd->vdev_id = vdev_id;
5491 	cmd->wmm_param_type = mu_edca_param;
5492 
5493 	for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) {
5494 		wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]);
5495 		twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]);
5496 		WMITLV_SET_HDR(&wmm_param->tlv_header,
5497 			       WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param,
5498 			       WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams));
5499 		wmm_param->cwmin = twmm_param->cwmin;
5500 		wmm_param->cwmax = twmm_param->cwmax;
5501 		wmm_param->aifs = twmm_param->aifs;
5502 		if (mu_edca_param)
5503 			wmm_param->mu_edca_timer = twmm_param->mu_edca_timer;
5504 		else
5505 			wmm_param->txoplimit = twmm_param->txoplimit;
5506 		wmm_param->acm = twmm_param->acm;
5507 		wmm_param->no_ack = twmm_param->noackpolicy;
5508 	}
5509 
5510 	wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0);
5511 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
5512 				 WMI_VDEV_SET_WMM_PARAMS_CMDID))
5513 		goto fail;
5514 
5515 	return QDF_STATUS_SUCCESS;
5516 
5517 fail:
5518 	wmi_buf_free(buf);
5519 	WMI_LOGE("%s: Failed to set WMM Paremeters", __func__);
5520 	return QDF_STATUS_E_FAILURE;
5521 }
5522 
5523 /**
5524  * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw
5525  * @wmi_handle: wmi handle
5526  * @vdev_id: vdev id
5527  * @probe_rsp_info: probe response info
5528  *
5529  * Return: QDF_STATUS_SUCCESS for success or error code
5530  */
5531 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle,
5532 				   uint8_t vdev_id,
5533 				   struct wmi_probe_resp_params *probe_rsp_info)
5534 {
5535 	wmi_prb_tmpl_cmd_fixed_param *cmd;
5536 	wmi_bcn_prb_info *bcn_prb_info;
5537 	wmi_buf_t wmi_buf;
5538 	uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len;
5539 	uint8_t *buf_ptr;
5540 	QDF_STATUS ret;
5541 
5542 	WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id);
5543 
5544 	tmpl_len = probe_rsp_info->prb_rsp_template_len;
5545 	tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t));
5546 
5547 	wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) +
5548 			sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE +
5549 			tmpl_len_aligned;
5550 
5551 	if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) {
5552 		WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"),
5553 		wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE);
5554 		return QDF_STATUS_E_INVAL;
5555 	}
5556 
5557 	wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
5558 	if (!wmi_buf) {
5559 		WMI_LOGE(FL("wmi_buf_alloc failed"));
5560 		return QDF_STATUS_E_NOMEM;
5561 	}
5562 
5563 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
5564 
5565 	cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr;
5566 	WMITLV_SET_HDR(&cmd->tlv_header,
5567 		       WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param,
5568 		       WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param));
5569 	cmd->vdev_id = vdev_id;
5570 	cmd->buf_len = tmpl_len;
5571 	buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param);
5572 
5573 	bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr;
5574 	WMITLV_SET_HDR(&bcn_prb_info->tlv_header,
5575 		       WMITLV_TAG_STRUC_wmi_bcn_prb_info,
5576 		       WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info));
5577 	bcn_prb_info->caps = 0;
5578 	bcn_prb_info->erp = 0;
5579 	buf_ptr += sizeof(wmi_bcn_prb_info);
5580 
5581 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned);
5582 	buf_ptr += WMI_TLV_HDR_SIZE;
5583 	qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len);
5584 
5585 	wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0);
5586 	ret = wmi_unified_cmd_send(wmi_handle,
5587 				   wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID);
5588 	if (QDF_IS_STATUS_ERROR(ret)) {
5589 		WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret);
5590 		wmi_buf_free(wmi_buf);
5591 	}
5592 
5593 	return ret;
5594 }
5595 
5596 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI)
5597 #define WPI_IV_LEN 16
5598 
5599 /**
5600  * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters
5601  *
5602  * @dest_tx: destination address of tsc key counter
5603  * @src_tx: source address of tsc key counter
5604  * @dest_rx: destination address of rsc key counter
5605  * @src_rx: source address of rsc key counter
5606  *
5607  * This function copies WAPI tsc and rsc key counters in the wmi buffer.
5608  *
5609  * Return: None
5610  *
5611  */
5612 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx,
5613 					uint8_t *dest_rx, uint8_t *src_rx)
5614 {
5615 	qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN);
5616 	qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN);
5617 }
5618 #else
5619 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx,
5620 					uint8_t *dest_rx, uint8_t *src_rx)
5621 {
5622 	return;
5623 }
5624 #endif
5625 
5626 /**
5627  * send_setup_install_key_cmd_tlv() - set key parameters
5628  * @wmi_handle: wmi handle
5629  * @key_params: key parameters
5630  *
5631  * This function fills structure from information
5632  * passed in key_params.
5633  *
5634  * Return: QDF_STATUS_SUCCESS - success
5635  *         QDF_STATUS_E_FAILURE - failure
5636  *         QDF_STATUS_E_NOMEM - not able to allocate buffer
5637  */
5638 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle,
5639 					   struct set_key_params *key_params)
5640 {
5641 	wmi_vdev_install_key_cmd_fixed_param *cmd;
5642 	wmi_buf_t buf;
5643 	uint8_t *buf_ptr;
5644 	uint32_t len;
5645 	uint8_t *key_data;
5646 	QDF_STATUS status;
5647 
5648 	len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) +
5649 	       WMI_TLV_HDR_SIZE;
5650 
5651 	buf = wmi_buf_alloc(wmi_handle, len);
5652 	if (!buf) {
5653 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
5654 		return QDF_STATUS_E_NOMEM;
5655 	}
5656 
5657 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
5658 	cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr;
5659 	WMITLV_SET_HDR(&cmd->tlv_header,
5660 		       WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param,
5661 		       WMITLV_GET_STRUCT_TLVLEN
5662 			       (wmi_vdev_install_key_cmd_fixed_param));
5663 	cmd->vdev_id = key_params->vdev_id;
5664 	cmd->key_ix = key_params->key_idx;
5665 
5666 
5667 	WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr);
5668 	cmd->key_flags |= key_params->key_flags;
5669 	cmd->key_cipher = key_params->key_cipher;
5670 	if ((key_params->key_txmic_len) &&
5671 			(key_params->key_rxmic_len)) {
5672 		cmd->key_txmic_len = key_params->key_txmic_len;
5673 		cmd->key_rxmic_len = key_params->key_rxmic_len;
5674 	}
5675 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI)
5676 	wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter,
5677 				   key_params->tx_iv,
5678 				   cmd->wpi_key_rsc_counter,
5679 				   key_params->rx_iv);
5680 #endif
5681 	buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param);
5682 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5683 		       roundup(key_params->key_len, sizeof(uint32_t)));
5684 	key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
5685 	qdf_mem_copy((void *)key_data,
5686 		     (const void *)key_params->key_data, key_params->key_len);
5687 	if (key_params->key_rsc_counter)
5688 	    qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter,
5689 			 sizeof(wmi_key_seq_counter));
5690 	cmd->key_len = key_params->key_len;
5691 
5692 	wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0);
5693 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
5694 					      WMI_VDEV_INSTALL_KEY_CMDID);
5695 	if (QDF_IS_STATUS_ERROR(status))
5696 		wmi_buf_free(buf);
5697 
5698 	return status;
5699 }
5700 
5701 /**
5702  * send_sar_limit_cmd_tlv() - send sar limit cmd to fw
5703  * @wmi_handle: wmi handle
5704  * @params: sar limit params
5705  *
5706  * Return: QDF_STATUS_SUCCESS for success or error code
5707  */
5708 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle,
5709 		struct sar_limit_cmd_params *sar_limit_params)
5710 {
5711 	wmi_buf_t buf;
5712 	QDF_STATUS qdf_status;
5713 	wmi_sar_limits_cmd_fixed_param *cmd;
5714 	int i;
5715 	uint8_t *buf_ptr;
5716 	wmi_sar_limit_cmd_row *wmi_sar_rows_list;
5717 	struct sar_limit_cmd_row *sar_rows_list;
5718 	uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
5719 
5720 	len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows;
5721 	buf = wmi_buf_alloc(wmi_handle, len);
5722 	if (!buf) {
5723 		WMI_LOGE("Failed to allocate memory");
5724 		qdf_status = QDF_STATUS_E_NOMEM;
5725 		goto end;
5726 	}
5727 
5728 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
5729 	cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr;
5730 	WMITLV_SET_HDR(&cmd->tlv_header,
5731 		       WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param,
5732 		       WMITLV_GET_STRUCT_TLVLEN
5733 		       (wmi_sar_limits_cmd_fixed_param));
5734 	cmd->sar_enable = sar_limit_params->sar_enable;
5735 	cmd->commit_limits = sar_limit_params->commit_limits;
5736 	cmd->num_limit_rows = sar_limit_params->num_limit_rows;
5737 
5738 	WMI_LOGD("no of sar rows = %d, len = %d",
5739 		 sar_limit_params->num_limit_rows, len);
5740 	buf_ptr += sizeof(*cmd);
5741 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5742 		       sizeof(wmi_sar_limit_cmd_row) *
5743 			       sar_limit_params->num_limit_rows);
5744 	if (cmd->num_limit_rows == 0)
5745 		goto send_sar_limits;
5746 
5747 	wmi_sar_rows_list = (wmi_sar_limit_cmd_row *)
5748 			(buf_ptr + WMI_TLV_HDR_SIZE);
5749 	sar_rows_list = sar_limit_params->sar_limit_row_list;
5750 
5751 	for (i = 0; i < sar_limit_params->num_limit_rows; i++) {
5752 		WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header,
5753 			       WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row,
5754 			       WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row));
5755 		wmi_sar_rows_list->band_id = sar_rows_list->band_id;
5756 		wmi_sar_rows_list->chain_id = sar_rows_list->chain_id;
5757 		wmi_sar_rows_list->mod_id = sar_rows_list->mod_id;
5758 		wmi_sar_rows_list->limit_value = sar_rows_list->limit_value;
5759 		wmi_sar_rows_list->validity_bitmap =
5760 						sar_rows_list->validity_bitmap;
5761 		WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d",
5762 			 i, wmi_sar_rows_list->band_id,
5763 			 wmi_sar_rows_list->chain_id,
5764 			 wmi_sar_rows_list->mod_id,
5765 			 wmi_sar_rows_list->limit_value,
5766 			 wmi_sar_rows_list->validity_bitmap);
5767 		sar_rows_list++;
5768 		wmi_sar_rows_list++;
5769 	}
5770 send_sar_limits:
5771 	wmi_mtrace(WMI_SAR_LIMITS_CMDID, NO_SESSION, 0);
5772 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
5773 				      WMI_SAR_LIMITS_CMDID);
5774 
5775 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
5776 		WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID");
5777 		wmi_buf_free(buf);
5778 	}
5779 
5780 end:
5781 	return qdf_status;
5782 }
5783 
5784 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle)
5785 {
5786 	wmi_sar_get_limits_cmd_fixed_param *cmd;
5787 	wmi_buf_t wmi_buf;
5788 	uint32_t len;
5789 	QDF_STATUS status;
5790 
5791 	WMI_LOGD(FL("Enter"));
5792 
5793 	len = sizeof(*cmd);
5794 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
5795 	if (!wmi_buf) {
5796 		WMI_LOGP(FL("failed to allocate memory for msg"));
5797 		return QDF_STATUS_E_NOMEM;
5798 	}
5799 
5800 	cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf);
5801 
5802 	WMITLV_SET_HDR(&cmd->tlv_header,
5803 		       WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param,
5804 		       WMITLV_GET_STRUCT_TLVLEN
5805 				(wmi_sar_get_limits_cmd_fixed_param));
5806 
5807 	cmd->reserved = 0;
5808 
5809 	wmi_mtrace(WMI_SAR_GET_LIMITS_CMDID, NO_SESSION, 0);
5810 	status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
5811 				      WMI_SAR_GET_LIMITS_CMDID);
5812 	if (QDF_IS_STATUS_ERROR(status)) {
5813 		WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status);
5814 		wmi_buf_free(wmi_buf);
5815 	}
5816 
5817 	WMI_LOGD(FL("Exit"));
5818 
5819 	return status;
5820 }
5821 
5822 /**
5823  * wmi_sar2_result_string() - return string conversion of sar2 result
5824  * @result: sar2 result value
5825  *
5826  * This utility function helps log string conversion of sar2 result.
5827  *
5828  * Return: string conversion of sar 2 result, if match found;
5829  *	   "Unknown response" otherwise.
5830  */
5831 static const char *wmi_sar2_result_string(uint32_t result)
5832 {
5833 	switch (result) {
5834 	CASE_RETURN_STRING(WMI_SAR2_SUCCESS);
5835 	CASE_RETURN_STRING(WMI_SAR2_INVALID_ANTENNA_INDEX);
5836 	CASE_RETURN_STRING(WMI_SAR2_INVALID_TABLE_INDEX);
5837 	CASE_RETURN_STRING(WMI_SAR2_STATE_ERROR);
5838 	CASE_RETURN_STRING(WMI_SAR2_BDF_NO_TABLE);
5839 	default:
5840 		return "Unknown response";
5841 	}
5842 }
5843 
5844 /**
5845  * extract_sar2_result_event_tlv() -  process sar response event from FW.
5846  * @handle: wma handle
5847  * @event: event buffer
5848  * @len: buffer length
5849  *
5850  * Return: 0 for success or error code
5851  */
5852 static QDF_STATUS extract_sar2_result_event_tlv(void *handle,
5853 						uint8_t *event,
5854 						uint32_t len)
5855 {
5856 	wmi_sar2_result_event_fixed_param *sar2_fixed_param;
5857 
5858 	WMI_SAR2_RESULT_EVENTID_param_tlvs *param_buf =
5859 		(WMI_SAR2_RESULT_EVENTID_param_tlvs *)event;
5860 
5861 	if (!param_buf) {
5862 		WMI_LOGI("Invalid sar2 result event buffer");
5863 		return QDF_STATUS_E_INVAL;
5864 	}
5865 
5866 	sar2_fixed_param = param_buf->fixed_param;
5867 	if (!sar2_fixed_param) {
5868 		WMI_LOGI("Invalid sar2 result event fixed param buffer");
5869 		return QDF_STATUS_E_INVAL;
5870 	}
5871 
5872 	WMI_LOGI("SAR2 result: %s",
5873 		 wmi_sar2_result_string(sar2_fixed_param->result));
5874 
5875 	return QDF_STATUS_SUCCESS;
5876 }
5877 
5878 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle,
5879 					      uint8_t *evt_buf,
5880 					      struct sar_limit_event *event)
5881 {
5882 	wmi_sar_get_limits_event_fixed_param *fixed_param;
5883 	WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf;
5884 	wmi_sar_get_limit_event_row *row_in;
5885 	struct sar_limit_event_row *row_out;
5886 	uint32_t row;
5887 
5888 	if (!evt_buf) {
5889 		WMI_LOGE(FL("input event is NULL"));
5890 		return QDF_STATUS_E_INVAL;
5891 	}
5892 	if (!event) {
5893 		WMI_LOGE(FL("output event is NULL"));
5894 		return QDF_STATUS_E_INVAL;
5895 	}
5896 
5897 	param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf;
5898 
5899 	fixed_param = param_buf->fixed_param;
5900 	if (!fixed_param) {
5901 		WMI_LOGE(FL("Invalid fixed param"));
5902 		return QDF_STATUS_E_INVAL;
5903 	}
5904 
5905 	event->sar_enable = fixed_param->sar_enable;
5906 	event->num_limit_rows = fixed_param->num_limit_rows;
5907 
5908 	if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) {
5909 		QDF_ASSERT(0);
5910 		WMI_LOGE(FL("Num rows %d exceeds max of %d"),
5911 			 event->num_limit_rows,
5912 			 MAX_SAR_LIMIT_ROWS_SUPPORTED);
5913 		event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED;
5914 	}
5915 
5916 	row_in = param_buf->sar_get_limits;
5917 	row_out = &event->sar_limit_row[0];
5918 	for (row = 0; row < event->num_limit_rows; row++) {
5919 		row_out->band_id = row_in->band_id;
5920 		row_out->chain_id = row_in->chain_id;
5921 		row_out->mod_id = row_in->mod_id;
5922 		row_out->limit_value = row_in->limit_value;
5923 		row_out++;
5924 		row_in++;
5925 	}
5926 
5927 	return QDF_STATUS_SUCCESS;
5928 }
5929 
5930 #ifdef WLAN_FEATURE_DISA
5931 /**
5932  * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw
5933  * @wmi_handle: wmi handle
5934  * @params: encrypt/decrypt params
5935  *
5936  * Return: QDF_STATUS_SUCCESS for success or error code
5937  */
5938 static
5939 QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle,
5940 		struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params)
5941 {
5942 	wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd;
5943 	wmi_buf_t wmi_buf;
5944 	uint8_t *buf_ptr;
5945 	QDF_STATUS ret;
5946 	uint32_t len;
5947 
5948 	WMI_LOGD(FL("Send encrypt decrypt cmd"));
5949 
5950 	len = sizeof(*cmd) +
5951 		roundup(encrypt_decrypt_params->data_len, sizeof(uint32_t)) +
5952 		WMI_TLV_HDR_SIZE;
5953 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
5954 	if (!wmi_buf) {
5955 		WMI_LOGP("%s: failed to allocate memory for encrypt/decrypt msg",
5956 			 __func__);
5957 		return QDF_STATUS_E_NOMEM;
5958 	}
5959 
5960 	buf_ptr = wmi_buf_data(wmi_buf);
5961 	cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr;
5962 
5963 	WMITLV_SET_HDR(&cmd->tlv_header,
5964 		WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param,
5965 		WMITLV_GET_STRUCT_TLVLEN(
5966 			wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param));
5967 
5968 	cmd->vdev_id = encrypt_decrypt_params->vdev_id;
5969 	cmd->key_flag = encrypt_decrypt_params->key_flag;
5970 	cmd->key_idx = encrypt_decrypt_params->key_idx;
5971 	cmd->key_cipher = encrypt_decrypt_params->key_cipher;
5972 	cmd->key_len = encrypt_decrypt_params->key_len;
5973 	cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len;
5974 	cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len;
5975 
5976 	qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data,
5977 				encrypt_decrypt_params->key_len);
5978 
5979 	qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header,
5980 				MAX_MAC_HEADER_LEN);
5981 
5982 	cmd->data_len = encrypt_decrypt_params->data_len;
5983 
5984 	if (cmd->data_len) {
5985 		buf_ptr += sizeof(*cmd);
5986 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5987 				roundup(encrypt_decrypt_params->data_len,
5988 					sizeof(uint32_t)));
5989 		buf_ptr += WMI_TLV_HDR_SIZE;
5990 		qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data,
5991 					encrypt_decrypt_params->data_len);
5992 	}
5993 
5994 	/* This conversion is to facilitate data to FW in little endian */
5995 	cmd->pn[5] = encrypt_decrypt_params->pn[0];
5996 	cmd->pn[4] = encrypt_decrypt_params->pn[1];
5997 	cmd->pn[3] = encrypt_decrypt_params->pn[2];
5998 	cmd->pn[2] = encrypt_decrypt_params->pn[3];
5999 	cmd->pn[1] = encrypt_decrypt_params->pn[4];
6000 	cmd->pn[0] = encrypt_decrypt_params->pn[5];
6001 
6002 	wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0);
6003 	ret = wmi_unified_cmd_send(wmi_handle,
6004 				   wmi_buf, len,
6005 				   WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID);
6006 	if (QDF_IS_STATUS_ERROR(ret)) {
6007 		WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret);
6008 		wmi_buf_free(wmi_buf);
6009 	}
6010 
6011 	return ret;
6012 }
6013 
6014 /**
6015  * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp
6016  *	params from event
6017  * @wmi_handle: wmi handle
6018  * @evt_buf: pointer to event buffer
6019  * @resp: Pointer to hold resp parameters
6020  *
6021  * Return: QDF_STATUS_SUCCESS for success or error code
6022  */
6023 static
6024 QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle,
6025 	void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp)
6026 {
6027 	WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf;
6028 	wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event;
6029 
6030 	param_buf = evt_buf;
6031 	if (!param_buf) {
6032 		WMI_LOGE("encrypt decrypt resp evt_buf is NULL");
6033 		return QDF_STATUS_E_INVAL;
6034 	}
6035 
6036 	data_event = param_buf->fixed_param;
6037 
6038 	resp->vdev_id = data_event->vdev_id;
6039 	resp->status = data_event->status;
6040 
6041 	if ((data_event->data_length > param_buf->num_enc80211_frame) ||
6042 	    (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE -
6043 	     sizeof(*data_event))) {
6044 		WMI_LOGE("FW msg data_len %d more than TLV hdr %d",
6045 			 data_event->data_length,
6046 			 param_buf->num_enc80211_frame);
6047 		return QDF_STATUS_E_INVAL;
6048 	}
6049 
6050 	resp->data_len = data_event->data_length;
6051 
6052 	if (resp->data_len)
6053 		resp->data = (uint8_t *)param_buf->enc80211_frame;
6054 
6055 	return QDF_STATUS_SUCCESS;
6056 }
6057 #endif
6058 
6059 /**
6060  * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go
6061  * @wmi_handle: wmi handle
6062  * @vdev_id: vdev id
6063  * @p2p_ie: p2p IE
6064  *
6065  * Return: QDF_STATUS_SUCCESS for success or error code
6066  */
6067 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle,
6068 				    uint32_t vdev_id, uint8_t *p2p_ie)
6069 {
6070 	QDF_STATUS ret;
6071 	wmi_p2p_go_set_beacon_ie_fixed_param *cmd;
6072 	wmi_buf_t wmi_buf;
6073 	uint32_t ie_len, ie_len_aligned, wmi_buf_len;
6074 	uint8_t *buf_ptr;
6075 
6076 	ie_len = (uint32_t) (p2p_ie[1] + 2);
6077 
6078 	/* More than one P2P IE may be included in a single frame.
6079 	   If multiple P2P IEs are present, the complete P2P attribute
6080 	   data consists of the concatenation of the P2P Attribute
6081 	   fields of the P2P IEs. The P2P Attributes field of each
6082 	   P2P IE may be any length up to the maximum (251 octets).
6083 	   In this case host sends one P2P IE to firmware so the length
6084 	   should not exceed more than 251 bytes
6085 	 */
6086 	if (ie_len > 251) {
6087 		WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len);
6088 		return QDF_STATUS_E_INVAL;
6089 	}
6090 
6091 	ie_len_aligned = roundup(ie_len, sizeof(uint32_t));
6092 
6093 	wmi_buf_len =
6094 		sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned +
6095 		WMI_TLV_HDR_SIZE;
6096 
6097 	wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
6098 	if (!wmi_buf) {
6099 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6100 		return QDF_STATUS_E_NOMEM;
6101 	}
6102 
6103 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
6104 
6105 	cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr;
6106 	WMITLV_SET_HDR(&cmd->tlv_header,
6107 		       WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param,
6108 		       WMITLV_GET_STRUCT_TLVLEN
6109 			       (wmi_p2p_go_set_beacon_ie_fixed_param));
6110 	cmd->vdev_id = vdev_id;
6111 	cmd->ie_buf_len = ie_len;
6112 
6113 	buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param);
6114 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
6115 	buf_ptr += WMI_TLV_HDR_SIZE;
6116 	qdf_mem_copy(buf_ptr, p2p_ie, ie_len);
6117 
6118 	WMI_LOGD("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__);
6119 
6120 	wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0);
6121 	ret = wmi_unified_cmd_send(wmi_handle,
6122 				   wmi_buf, wmi_buf_len,
6123 				   WMI_P2P_GO_SET_BEACON_IE);
6124 	if (QDF_IS_STATUS_ERROR(ret)) {
6125 		WMI_LOGE("Failed to send bcn tmpl: %d", ret);
6126 		wmi_buf_free(wmi_buf);
6127 	}
6128 
6129 	WMI_LOGD("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__);
6130 	return ret;
6131 }
6132 
6133 /**
6134  * send_set_gateway_params_cmd_tlv() - set gateway parameters
6135  * @wmi_handle: wmi handle
6136  * @req: gateway parameter update request structure
6137  *
6138  * This function reads the incoming @req and fill in the destination
6139  * WMI structure and sends down the gateway configs down to the firmware
6140  *
6141  * Return: QDF_STATUS
6142  */
6143 static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle,
6144 				struct gateway_update_req_param *req)
6145 {
6146 	wmi_roam_subnet_change_config_fixed_param *cmd;
6147 	wmi_buf_t buf;
6148 	QDF_STATUS ret;
6149 	int len = sizeof(*cmd);
6150 
6151 	buf = wmi_buf_alloc(wmi_handle, len);
6152 	if (!buf) {
6153 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
6154 		return QDF_STATUS_E_NOMEM;
6155 	}
6156 
6157 	cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf);
6158 	WMITLV_SET_HDR(&cmd->tlv_header,
6159 		WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param,
6160 		WMITLV_GET_STRUCT_TLVLEN(
6161 			wmi_roam_subnet_change_config_fixed_param));
6162 
6163 	cmd->vdev_id = req->session_id;
6164 	qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr,
6165 		QDF_IPV4_ADDR_SIZE);
6166 	qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr,
6167 		QDF_IPV6_ADDR_SIZE);
6168 	WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes,
6169 		&cmd->inet_gw_mac_addr);
6170 	cmd->max_retries = req->max_retries;
6171 	cmd->timeout = req->timeout;
6172 	cmd->num_skip_subnet_change_detection_bssid_list = 0;
6173 	cmd->flag = 0;
6174 	if (req->ipv4_addr_type)
6175 		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag);
6176 
6177 	if (req->ipv6_addr_type)
6178 		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag);
6179 
6180 	wmi_mtrace(WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID, cmd->vdev_id, 0);
6181 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6182 				WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID);
6183 	if (QDF_IS_STATUS_ERROR(ret)) {
6184 		WMI_LOGE("Failed to send gw config parameter to fw, ret: %d",
6185 			ret);
6186 		wmi_buf_free(buf);
6187 	}
6188 
6189 	return ret;
6190 }
6191 
6192 /**
6193  * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring
6194  * @wmi_handle: wmi handle
6195  * @req: rssi monitoring request structure
6196  *
6197  * This function reads the incoming @req and fill in the destination
6198  * WMI structure and send down the rssi monitoring configs down to the firmware
6199  *
6200  * Return: 0 on success; error number otherwise
6201  */
6202 static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle,
6203 					struct rssi_monitor_param *req)
6204 {
6205 	wmi_rssi_breach_monitor_config_fixed_param *cmd;
6206 	wmi_buf_t buf;
6207 	QDF_STATUS ret;
6208 	uint32_t len = sizeof(*cmd);
6209 
6210 	buf = wmi_buf_alloc(wmi_handle, len);
6211 	if (!buf) {
6212 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
6213 		return QDF_STATUS_E_NOMEM;
6214 	}
6215 
6216 	cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf);
6217 	WMITLV_SET_HDR(&cmd->tlv_header,
6218 		WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param,
6219 		WMITLV_GET_STRUCT_TLVLEN(
6220 			wmi_rssi_breach_monitor_config_fixed_param));
6221 
6222 	cmd->vdev_id = req->session_id;
6223 	cmd->request_id = req->request_id;
6224 	cmd->lo_rssi_reenable_hysteresis = 0;
6225 	cmd->hi_rssi_reenable_histeresis = 0;
6226 	cmd->min_report_interval = 0;
6227 	cmd->max_num_report = 1;
6228 	if (req->control) {
6229 		/* enable one threshold for each min/max */
6230 		cmd->enabled_bitmap = 0x09;
6231 		cmd->low_rssi_breach_threshold[0] = req->min_rssi;
6232 		cmd->hi_rssi_breach_threshold[0] = req->max_rssi;
6233 	} else {
6234 		cmd->enabled_bitmap = 0;
6235 		cmd->low_rssi_breach_threshold[0] = 0;
6236 		cmd->hi_rssi_breach_threshold[0] = 0;
6237 	}
6238 
6239 	wmi_mtrace(WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID, cmd->vdev_id, 0);
6240 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6241 				   WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID);
6242 	if (QDF_IS_STATUS_ERROR(ret)) {
6243 		WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID");
6244 		wmi_buf_free(buf);
6245 	}
6246 
6247 	WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW");
6248 
6249 	return ret;
6250 }
6251 
6252 /**
6253  * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI
6254  * @wmi_handle: wmi handle
6255  * @psetoui: OUI parameters
6256  *
6257  * set scan probe OUI parameters in firmware
6258  *
6259  * Return: CDF status
6260  */
6261 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle,
6262 			  struct scan_mac_oui *psetoui)
6263 {
6264 	wmi_scan_prob_req_oui_cmd_fixed_param *cmd;
6265 	wmi_buf_t wmi_buf;
6266 	uint32_t len;
6267 	uint8_t *buf_ptr;
6268 	uint32_t *oui_buf;
6269 	struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist;
6270 
6271 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
6272 		ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui);
6273 
6274 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
6275 	if (!wmi_buf) {
6276 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
6277 		return QDF_STATUS_E_NOMEM;
6278 	}
6279 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
6280 	cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr;
6281 	WMITLV_SET_HDR(&cmd->tlv_header,
6282 		       WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param,
6283 		       WMITLV_GET_STRUCT_TLVLEN
6284 			       (wmi_scan_prob_req_oui_cmd_fixed_param));
6285 
6286 	oui_buf = &cmd->prob_req_oui;
6287 	qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui));
6288 	*oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8
6289 		   | psetoui->oui[2];
6290 	WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__,
6291 		 cmd->prob_req_oui);
6292 
6293 	cmd->vdev_id = psetoui->vdev_id;
6294 	cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ;
6295 	if (psetoui->enb_probe_req_sno_randomization)
6296 		cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ;
6297 
6298 	if (ie_whitelist->white_list) {
6299 		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
6300 					    &cmd->num_vendor_oui,
6301 					    ie_whitelist);
6302 		cmd->flags |=
6303 			WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ;
6304 	}
6305 
6306 	buf_ptr += sizeof(*cmd);
6307 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6308 		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
6309 	buf_ptr += WMI_TLV_HDR_SIZE;
6310 
6311 	if (cmd->num_vendor_oui != 0) {
6312 		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
6313 				    ie_whitelist->voui);
6314 		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
6315 	}
6316 
6317 	wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0);
6318 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
6319 				 WMI_SCAN_PROB_REQ_OUI_CMDID)) {
6320 		WMI_LOGE("%s: failed to send command", __func__);
6321 		wmi_buf_free(wmi_buf);
6322 		return QDF_STATUS_E_FAILURE;
6323 	}
6324 	return QDF_STATUS_SUCCESS;
6325 }
6326 
6327 #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
6328 /**
6329  * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command
6330  * @wmi_handle: wmi handle
6331  * @roam_req: Roam scan offload params
6332  * @buf_ptr: command buffer to send
6333  * @fils_tlv_len: fils tlv length
6334  *
6335  * Return: Updated buffer pointer
6336  */
6337 static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
6338 			     struct roam_offload_scan_params *roam_req,
6339 			     uint8_t *buf_ptr, uint32_t fils_tlv_len)
6340 {
6341 	wmi_roam_fils_offload_tlv_param *fils_tlv;
6342 	wmi_erp_info *erp_info;
6343 	struct roam_fils_params *roam_fils_params;
6344 
6345 	if (!roam_req->add_fils_tlv)
6346 		return buf_ptr;
6347 
6348 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6349 			sizeof(*fils_tlv));
6350 	buf_ptr += WMI_TLV_HDR_SIZE;
6351 
6352 	fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr;
6353 	WMITLV_SET_HDR(&fils_tlv->tlv_header,
6354 			WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param,
6355 			WMITLV_GET_STRUCT_TLVLEN
6356 				(wmi_roam_fils_offload_tlv_param));
6357 
6358 	roam_fils_params = &roam_req->roam_fils_params;
6359 	erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info);
6360 
6361 	erp_info->username_length = roam_fils_params->username_length;
6362 	qdf_mem_copy(erp_info->username, roam_fils_params->username,
6363 				erp_info->username_length);
6364 
6365 	erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num;
6366 
6367 	erp_info->rRk_length = roam_fils_params->rrk_length;
6368 	qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk,
6369 				erp_info->rRk_length);
6370 
6371 	erp_info->rIk_length = roam_fils_params->rik_length;
6372 	qdf_mem_copy(erp_info->rIk, roam_fils_params->rik,
6373 				erp_info->rIk_length);
6374 
6375 	erp_info->realm_len = roam_fils_params->realm_len;
6376 	qdf_mem_copy(erp_info->realm, roam_fils_params->realm,
6377 				erp_info->realm_len);
6378 
6379 	buf_ptr += sizeof(*fils_tlv);
6380 	return buf_ptr;
6381 }
6382 #else
6383 static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
6384 				struct roam_offload_scan_params *roam_req,
6385 				uint8_t *buf_ptr, uint32_t fils_tlv_len)
6386 {
6387 	return buf_ptr;
6388 }
6389 #endif
6390 /**
6391  * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw
6392  * @wmi_handle: wmi handle
6393  * @scan_cmd_fp: start scan command ptr
6394  * @roam_req: roam request param
6395  *
6396  * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
6397  * of WMI_ROAM_SCAN_MODE.
6398  *
6399  * Return: QDF status
6400  */
6401 static QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle,
6402 				      wmi_start_scan_cmd_fixed_param *
6403 				      scan_cmd_fp,
6404 				      struct roam_offload_scan_params *roam_req)
6405 {
6406 	wmi_buf_t buf = NULL;
6407 	QDF_STATUS status;
6408 	int len;
6409 	uint8_t *buf_ptr;
6410 	wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp;
6411 
6412 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6413 	int auth_mode = roam_req->auth_mode;
6414 	wmi_roam_offload_tlv_param *roam_offload_params;
6415 	wmi_roam_11i_offload_tlv_param *roam_offload_11i;
6416 	wmi_roam_11r_offload_tlv_param *roam_offload_11r;
6417 	wmi_roam_ese_offload_tlv_param *roam_offload_ese;
6418 	wmi_tlv_buf_len_param *assoc_ies;
6419 	uint32_t fils_tlv_len = 0;
6420 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6421 	/* Need to create a buf with roam_scan command at
6422 	 * front and piggyback with scan command */
6423 	len = sizeof(wmi_roam_scan_mode_fixed_param) +
6424 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6425 	      (2 * WMI_TLV_HDR_SIZE) +
6426 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6427 	      sizeof(wmi_start_scan_cmd_fixed_param);
6428 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6429 	WMI_LOGD("auth_mode = %d", auth_mode);
6430 		if (roam_req->is_roam_req_valid &&
6431 				roam_req->roam_offload_enabled) {
6432 			len += sizeof(wmi_roam_offload_tlv_param);
6433 			len += WMI_TLV_HDR_SIZE;
6434 			if ((auth_mode != WMI_AUTH_NONE) &&
6435 				((auth_mode != WMI_AUTH_OPEN) ||
6436 				 (auth_mode == WMI_AUTH_OPEN &&
6437 				  roam_req->mdid.mdie_present &&
6438 				  roam_req->is_11r_assoc) ||
6439 				  roam_req->is_ese_assoc)) {
6440 				len += WMI_TLV_HDR_SIZE;
6441 				if (roam_req->is_ese_assoc)
6442 					len +=
6443 					sizeof(wmi_roam_ese_offload_tlv_param);
6444 				else if (auth_mode == WMI_AUTH_FT_RSNA ||
6445 					 auth_mode == WMI_AUTH_FT_RSNA_PSK ||
6446 					 (auth_mode == WMI_AUTH_OPEN &&
6447 					  roam_req->mdid.mdie_present &&
6448 					  roam_req->is_11r_assoc))
6449 					len +=
6450 					sizeof(wmi_roam_11r_offload_tlv_param);
6451 				else
6452 					len +=
6453 					sizeof(wmi_roam_11i_offload_tlv_param);
6454 			} else {
6455 				len += WMI_TLV_HDR_SIZE;
6456 			}
6457 
6458 			len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE)
6459 					+ roundup(roam_req->assoc_ie_length,
6460 					sizeof(uint32_t)));
6461 
6462 			if (roam_req->add_fils_tlv) {
6463 				fils_tlv_len = sizeof(
6464 					wmi_roam_fils_offload_tlv_param);
6465 				len += WMI_TLV_HDR_SIZE + fils_tlv_len;
6466 			}
6467 		} else {
6468 			if (roam_req->is_roam_req_valid)
6469 				WMI_LOGD("%s : roam offload = %d",
6470 				     __func__, roam_req->roam_offload_enabled);
6471 			else
6472 				WMI_LOGD("%s : roam_req is NULL", __func__);
6473 			len += (4 * WMI_TLV_HDR_SIZE);
6474 		}
6475 		if (roam_req->is_roam_req_valid &&
6476 				roam_req->roam_offload_enabled) {
6477 			roam_req->mode = roam_req->mode |
6478 				WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
6479 		}
6480 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6481 
6482 	if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE
6483 				|WMI_ROAM_SCAN_MODE_ROAMOFFLOAD))
6484 		len = sizeof(wmi_roam_scan_mode_fixed_param);
6485 
6486 	buf = wmi_buf_alloc(wmi_handle, len);
6487 	if (!buf) {
6488 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6489 		return QDF_STATUS_E_NOMEM;
6490 	}
6491 
6492 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6493 	roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr;
6494 	WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header,
6495 		       WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param,
6496 		       WMITLV_GET_STRUCT_TLVLEN
6497 			       (wmi_roam_scan_mode_fixed_param));
6498 
6499 	roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask =
6500 			roam_req->roam_trigger_reason_bitmask;
6501 	roam_scan_mode_fp->min_delay_btw_scans =
6502 			WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans);
6503 	roam_scan_mode_fp->roam_scan_mode = roam_req->mode;
6504 	roam_scan_mode_fp->vdev_id = roam_req->vdev_id;
6505 	if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE |
6506 			WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) {
6507 		roam_scan_mode_fp->flags |=
6508 			WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS;
6509 		goto send_roam_scan_mode_cmd;
6510 	}
6511 
6512 	/* Fill in scan parameters suitable for roaming scan */
6513 	buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param);
6514 
6515 	qdf_mem_copy(buf_ptr, scan_cmd_fp,
6516 		     sizeof(wmi_start_scan_cmd_fixed_param));
6517 	/* Ensure there is no additional IEs */
6518 	scan_cmd_fp->ie_len = 0;
6519 	WMITLV_SET_HDR(buf_ptr,
6520 		       WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
6521 		       WMITLV_GET_STRUCT_TLVLEN
6522 			       (wmi_start_scan_cmd_fixed_param));
6523 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6524 	buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param);
6525 	if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) {
6526 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6527 			       sizeof(wmi_roam_offload_tlv_param));
6528 		buf_ptr += WMI_TLV_HDR_SIZE;
6529 		roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr;
6530 		WMITLV_SET_HDR(buf_ptr,
6531 			       WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param,
6532 			       WMITLV_GET_STRUCT_TLVLEN
6533 				       (wmi_roam_offload_tlv_param));
6534 		roam_offload_params->prefer_5g = roam_req->prefer_5ghz;
6535 		roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap;
6536 		roam_offload_params->select_5g_margin =
6537 			roam_req->select_5ghz_margin;
6538 		roam_offload_params->handoff_delay_for_rx =
6539 			roam_req->roam_offload_params.ho_delay_for_rx;
6540 		roam_offload_params->reassoc_failure_timeout =
6541 			roam_req->reassoc_failure_timeout;
6542 
6543 		/* Fill the capabilities */
6544 		roam_offload_params->capability =
6545 				roam_req->roam_offload_params.capability;
6546 		roam_offload_params->ht_caps_info =
6547 				roam_req->roam_offload_params.ht_caps_info;
6548 		roam_offload_params->ampdu_param =
6549 				roam_req->roam_offload_params.ampdu_param;
6550 		roam_offload_params->ht_ext_cap =
6551 				roam_req->roam_offload_params.ht_ext_cap;
6552 		roam_offload_params->ht_txbf =
6553 				roam_req->roam_offload_params.ht_txbf;
6554 		roam_offload_params->asel_cap =
6555 				roam_req->roam_offload_params.asel_cap;
6556 		roam_offload_params->qos_caps =
6557 				roam_req->roam_offload_params.qos_caps;
6558 		roam_offload_params->qos_enabled =
6559 				roam_req->roam_offload_params.qos_enabled;
6560 		roam_offload_params->wmm_caps =
6561 				roam_req->roam_offload_params.wmm_caps;
6562 		qdf_mem_copy((uint8_t *)roam_offload_params->mcsset,
6563 				(uint8_t *)roam_req->roam_offload_params.mcsset,
6564 				ROAM_OFFLOAD_NUM_MCS_SET);
6565 
6566 		buf_ptr += sizeof(wmi_roam_offload_tlv_param);
6567 		/* The TLV's are in the order of 11i, 11R, ESE. Hence,
6568 		 * they are filled in the same order.Depending on the
6569 		 * authentication type, the other mode TLV's are nullified
6570 		 * and only headers are filled.*/
6571 		if ((auth_mode != WMI_AUTH_NONE) &&
6572 		    ((auth_mode != WMI_AUTH_OPEN) ||
6573 		     (auth_mode == WMI_AUTH_OPEN
6574 		      && roam_req->mdid.mdie_present &&
6575 		      roam_req->is_11r_assoc) ||
6576 			roam_req->is_ese_assoc)) {
6577 			if (roam_req->is_ese_assoc) {
6578 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6579 					       WMITLV_GET_STRUCT_TLVLEN(0));
6580 				buf_ptr += WMI_TLV_HDR_SIZE;
6581 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6582 					       WMITLV_GET_STRUCT_TLVLEN(0));
6583 				buf_ptr += WMI_TLV_HDR_SIZE;
6584 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6585 					sizeof(wmi_roam_ese_offload_tlv_param));
6586 				buf_ptr += WMI_TLV_HDR_SIZE;
6587 				roam_offload_ese =
6588 				    (wmi_roam_ese_offload_tlv_param *) buf_ptr;
6589 				qdf_mem_copy(roam_offload_ese->krk,
6590 					     roam_req->krk,
6591 					     sizeof(roam_req->krk));
6592 				qdf_mem_copy(roam_offload_ese->btk,
6593 					     roam_req->btk,
6594 					     sizeof(roam_req->btk));
6595 				WMITLV_SET_HDR(&roam_offload_ese->tlv_header,
6596 				WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param,
6597 				WMITLV_GET_STRUCT_TLVLEN
6598 				(wmi_roam_ese_offload_tlv_param));
6599 				buf_ptr +=
6600 					sizeof(wmi_roam_ese_offload_tlv_param);
6601 			} else if (auth_mode == WMI_AUTH_FT_RSNA
6602 				   || auth_mode == WMI_AUTH_FT_RSNA_PSK
6603 				   || (auth_mode == WMI_AUTH_OPEN
6604 				       && roam_req->mdid.mdie_present &&
6605 				       roam_req->is_11r_assoc)) {
6606 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6607 					       0);
6608 				buf_ptr += WMI_TLV_HDR_SIZE;
6609 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6610 					sizeof(wmi_roam_11r_offload_tlv_param));
6611 				buf_ptr += WMI_TLV_HDR_SIZE;
6612 				roam_offload_11r =
6613 				    (wmi_roam_11r_offload_tlv_param *) buf_ptr;
6614 				roam_offload_11r->r0kh_id_len =
6615 					roam_req->rokh_id_length;
6616 				qdf_mem_copy(roam_offload_11r->r0kh_id,
6617 					     roam_req->rokh_id,
6618 					     roam_offload_11r->r0kh_id_len);
6619 				qdf_mem_copy(roam_offload_11r->psk_msk,
6620 					     roam_req->psk_pmk,
6621 					     sizeof(roam_req->psk_pmk));
6622 				roam_offload_11r->psk_msk_len =
6623 					roam_req->pmk_len;
6624 				roam_offload_11r->mdie_present =
6625 					roam_req->mdid.mdie_present;
6626 				roam_offload_11r->mdid =
6627 					roam_req->mdid.mobility_domain;
6628 				if (auth_mode == WMI_AUTH_OPEN) {
6629 					/* If FT-Open ensure pmk length
6630 					   and r0khid len are zero */
6631 					roam_offload_11r->r0kh_id_len = 0;
6632 					roam_offload_11r->psk_msk_len = 0;
6633 				}
6634 				WMITLV_SET_HDR(&roam_offload_11r->tlv_header,
6635 				WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param,
6636 				WMITLV_GET_STRUCT_TLVLEN
6637 				(wmi_roam_11r_offload_tlv_param));
6638 				buf_ptr +=
6639 					sizeof(wmi_roam_11r_offload_tlv_param);
6640 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6641 					       WMITLV_GET_STRUCT_TLVLEN(0));
6642 				buf_ptr += WMI_TLV_HDR_SIZE;
6643 				WMI_LOGD("psk_msk_len = %d",
6644 					roam_offload_11r->psk_msk_len);
6645 				if (roam_offload_11r->psk_msk_len)
6646 					QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
6647 						QDF_TRACE_LEVEL_DEBUG,
6648 						roam_offload_11r->psk_msk,
6649 						roam_offload_11r->psk_msk_len);
6650 			} else {
6651 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6652 					sizeof(wmi_roam_11i_offload_tlv_param));
6653 				buf_ptr += WMI_TLV_HDR_SIZE;
6654 				roam_offload_11i =
6655 				     (wmi_roam_11i_offload_tlv_param *) buf_ptr;
6656 
6657 				if (roam_req->roam_key_mgmt_offload_enabled &&
6658 				    roam_req->fw_okc) {
6659 					WMI_SET_ROAM_OFFLOAD_OKC_ENABLED
6660 						(roam_offload_11i->flags);
6661 					WMI_LOGI("LFR3:OKC enabled");
6662 				} else {
6663 					WMI_SET_ROAM_OFFLOAD_OKC_DISABLED
6664 						(roam_offload_11i->flags);
6665 					WMI_LOGI("LFR3:OKC disabled");
6666 				}
6667 				if (roam_req->roam_key_mgmt_offload_enabled &&
6668 				    roam_req->fw_pmksa_cache) {
6669 					WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED
6670 						(roam_offload_11i->flags);
6671 					WMI_LOGI("LFR3:PMKSA caching enabled");
6672 				} else {
6673 					WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED
6674 						(roam_offload_11i->flags);
6675 					WMI_LOGI("LFR3:PMKSA caching disabled");
6676 				}
6677 
6678 				qdf_mem_copy(roam_offload_11i->pmk,
6679 					     roam_req->psk_pmk,
6680 					     sizeof(roam_req->psk_pmk));
6681 				roam_offload_11i->pmk_len = roam_req->pmk_len;
6682 				WMITLV_SET_HDR(&roam_offload_11i->tlv_header,
6683 				WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param,
6684 				WMITLV_GET_STRUCT_TLVLEN
6685 				(wmi_roam_11i_offload_tlv_param));
6686 				buf_ptr +=
6687 					sizeof(wmi_roam_11i_offload_tlv_param);
6688 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6689 					       0);
6690 				buf_ptr += WMI_TLV_HDR_SIZE;
6691 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6692 					       0);
6693 				buf_ptr += WMI_TLV_HDR_SIZE;
6694 				WMI_LOGD("pmk_len = %d",
6695 					roam_offload_11i->pmk_len);
6696 				if (roam_offload_11i->pmk_len)
6697 					QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
6698 						QDF_TRACE_LEVEL_DEBUG,
6699 						roam_offload_11i->pmk,
6700 						roam_offload_11i->pmk_len);
6701 			}
6702 		} else {
6703 			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6704 				       WMITLV_GET_STRUCT_TLVLEN(0));
6705 			buf_ptr += WMI_TLV_HDR_SIZE;
6706 			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6707 				       WMITLV_GET_STRUCT_TLVLEN(0));
6708 			buf_ptr += WMI_TLV_HDR_SIZE;
6709 			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6710 				       WMITLV_GET_STRUCT_TLVLEN(0));
6711 			buf_ptr += WMI_TLV_HDR_SIZE;
6712 		}
6713 
6714 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6715 					sizeof(*assoc_ies));
6716 		buf_ptr += WMI_TLV_HDR_SIZE;
6717 
6718 		assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr;
6719 		WMITLV_SET_HDR(&assoc_ies->tlv_header,
6720 			WMITLV_TAG_STRUC_wmi_tlv_buf_len_param,
6721 			WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param));
6722 		assoc_ies->buf_len = roam_req->assoc_ie_length;
6723 
6724 		buf_ptr += sizeof(*assoc_ies);
6725 
6726 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
6727 				roundup(assoc_ies->buf_len, sizeof(uint32_t)));
6728 		buf_ptr += WMI_TLV_HDR_SIZE;
6729 
6730 		if (assoc_ies->buf_len != 0) {
6731 			qdf_mem_copy(buf_ptr, roam_req->assoc_ie,
6732 					assoc_ies->buf_len);
6733 		}
6734 		buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t));
6735 		buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req,
6736 						buf_ptr, fils_tlv_len);
6737 	} else {
6738 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6739 			       WMITLV_GET_STRUCT_TLVLEN(0));
6740 		buf_ptr += WMI_TLV_HDR_SIZE;
6741 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6742 			       WMITLV_GET_STRUCT_TLVLEN(0));
6743 		buf_ptr += WMI_TLV_HDR_SIZE;
6744 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6745 			       WMITLV_GET_STRUCT_TLVLEN(0));
6746 		buf_ptr += WMI_TLV_HDR_SIZE;
6747 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6748 			       WMITLV_GET_STRUCT_TLVLEN(0));
6749 		buf_ptr += WMI_TLV_HDR_SIZE;
6750 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6751 				WMITLV_GET_STRUCT_TLVLEN(0));
6752 		buf_ptr += WMI_TLV_HDR_SIZE;
6753 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
6754 				WMITLV_GET_STRUCT_TLVLEN(0));
6755 	}
6756 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6757 
6758 send_roam_scan_mode_cmd:
6759 	wmi_mtrace(WMI_ROAM_SCAN_MODE, NO_SESSION, 0);
6760 	status = wmi_unified_cmd_send(wmi_handle, buf,
6761 				      len, WMI_ROAM_SCAN_MODE);
6762 	if (QDF_IS_STATUS_ERROR(status)) {
6763 		WMI_LOGE(
6764 		    "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d",
6765 			status);
6766 		wmi_buf_free(buf);
6767 	}
6768 
6769 	return status;
6770 }
6771 
6772 static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle,
6773 		struct wmi_mawc_roam_params *params)
6774 {
6775 	wmi_buf_t buf = NULL;
6776 	QDF_STATUS status;
6777 	int len;
6778 	uint8_t *buf_ptr;
6779 	wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params;
6780 
6781 	len = sizeof(*wmi_roam_mawc_params);
6782 	buf = wmi_buf_alloc(wmi_handle, len);
6783 	if (!buf) {
6784 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6785 		return QDF_STATUS_E_NOMEM;
6786 	}
6787 
6788 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6789 	wmi_roam_mawc_params =
6790 		(wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr;
6791 	WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header,
6792 		       WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param,
6793 		       WMITLV_GET_STRUCT_TLVLEN
6794 			       (wmi_roam_configure_mawc_cmd_fixed_param));
6795 	wmi_roam_mawc_params->vdev_id = params->vdev_id;
6796 	if (params->enable)
6797 		wmi_roam_mawc_params->enable = 1;
6798 	else
6799 		wmi_roam_mawc_params->enable = 0;
6800 	wmi_roam_mawc_params->traffic_load_threshold =
6801 		params->traffic_load_threshold;
6802 	wmi_roam_mawc_params->best_ap_rssi_threshold =
6803 		params->best_ap_rssi_threshold;
6804 	wmi_roam_mawc_params->rssi_stationary_high_adjust =
6805 		params->rssi_stationary_high_adjust;
6806 	wmi_roam_mawc_params->rssi_stationary_low_adjust =
6807 		params->rssi_stationary_low_adjust;
6808 	WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"),
6809 		wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id,
6810 		wmi_roam_mawc_params->traffic_load_threshold,
6811 		wmi_roam_mawc_params->best_ap_rssi_threshold,
6812 		wmi_roam_mawc_params->rssi_stationary_high_adjust,
6813 		wmi_roam_mawc_params->rssi_stationary_low_adjust);
6814 
6815 	wmi_mtrace(WMI_ROAM_CONFIGURE_MAWC_CMDID, NO_SESSION, 0);
6816 	status = wmi_unified_cmd_send(wmi_handle, buf,
6817 				      len, WMI_ROAM_CONFIGURE_MAWC_CMDID);
6818 	if (QDF_IS_STATUS_ERROR(status)) {
6819 		WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d",
6820 			status);
6821 		wmi_buf_free(buf);
6822 		return status;
6823 	}
6824 
6825 	return QDF_STATUS_SUCCESS;
6826 }
6827 
6828 /**
6829  * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload
6830  *                                                rssi threashold
6831  * @wmi_handle: wmi handle
6832  * @roam_req:   Roaming request buffer
6833  *
6834  * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
6835  *
6836  * Return: QDF status
6837  */
6838 static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle,
6839 				struct roam_offload_scan_rssi_params *roam_req)
6840 {
6841 	wmi_buf_t buf = NULL;
6842 	QDF_STATUS status;
6843 	int len;
6844 	uint8_t *buf_ptr;
6845 	wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp;
6846 	wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL;
6847 	wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL;
6848 	wmi_roam_dense_thres_param *dense_thresholds = NULL;
6849 	wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL;
6850 
6851 	len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
6852 	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
6853 	len += sizeof(wmi_roam_scan_extended_threshold_param);
6854 	len += WMI_TLV_HDR_SIZE;
6855 	len += sizeof(wmi_roam_earlystop_rssi_thres_param);
6856 	len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/
6857 	len += sizeof(wmi_roam_dense_thres_param);
6858 	len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/
6859 	len += sizeof(wmi_roam_bg_scan_roaming_param);
6860 	buf = wmi_buf_alloc(wmi_handle, len);
6861 	if (!buf) {
6862 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6863 		return QDF_STATUS_E_NOMEM;
6864 	}
6865 
6866 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6867 	rssi_threshold_fp =
6868 		(wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr;
6869 	WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header,
6870 		      WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param,
6871 		      WMITLV_GET_STRUCT_TLVLEN
6872 			       (wmi_roam_scan_rssi_threshold_fixed_param));
6873 	/* fill in threshold values */
6874 	rssi_threshold_fp->vdev_id = roam_req->session_id;
6875 	rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh;
6876 	rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff;
6877 	rssi_threshold_fp->hirssi_scan_max_count =
6878 			roam_req->hi_rssi_scan_max_count;
6879 	rssi_threshold_fp->hirssi_scan_delta =
6880 			roam_req->hi_rssi_scan_rssi_delta;
6881 	rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub;
6882 	rssi_threshold_fp->rssi_thresh_offset_5g =
6883 		roam_req->rssi_thresh_offset_5g;
6884 
6885 	buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
6886 	WMITLV_SET_HDR(buf_ptr,
6887 			WMITLV_TAG_ARRAY_STRUC,
6888 			sizeof(wmi_roam_scan_extended_threshold_param));
6889 	buf_ptr += WMI_TLV_HDR_SIZE;
6890 	ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr;
6891 
6892 	ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g;
6893 	if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT)
6894 		ext_thresholds->boost_threshold_5g =
6895 					roam_req->boost_threshold_5g;
6896 
6897 	ext_thresholds->boost_algorithm_5g =
6898 		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
6899 	ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g;
6900 	ext_thresholds->penalty_algorithm_5g =
6901 		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
6902 	ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g;
6903 	ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g;
6904 	ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g;
6905 	ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold;
6906 
6907 	WMITLV_SET_HDR(&ext_thresholds->tlv_header,
6908 		WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param,
6909 		WMITLV_GET_STRUCT_TLVLEN
6910 		(wmi_roam_scan_extended_threshold_param));
6911 	buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param);
6912 	WMITLV_SET_HDR(buf_ptr,
6913 			WMITLV_TAG_ARRAY_STRUC,
6914 			sizeof(wmi_roam_earlystop_rssi_thres_param));
6915 	buf_ptr += WMI_TLV_HDR_SIZE;
6916 	early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr;
6917 	early_stop_thresholds->roam_earlystop_thres_min =
6918 		roam_req->roam_earlystop_thres_min;
6919 	early_stop_thresholds->roam_earlystop_thres_max =
6920 		roam_req->roam_earlystop_thres_max;
6921 	WMITLV_SET_HDR(&early_stop_thresholds->tlv_header,
6922 		WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param,
6923 		WMITLV_GET_STRUCT_TLVLEN
6924 		(wmi_roam_earlystop_rssi_thres_param));
6925 
6926 	buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param);
6927 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6928 			 sizeof(wmi_roam_dense_thres_param));
6929 	buf_ptr += WMI_TLV_HDR_SIZE;
6930 	dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr;
6931 	dense_thresholds->roam_dense_rssi_thres_offset =
6932 			roam_req->dense_rssi_thresh_offset;
6933 	dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt;
6934 	dense_thresholds->roam_dense_traffic_thres =
6935 			roam_req->traffic_threshold;
6936 	dense_thresholds->roam_dense_status = roam_req->initial_dense_status;
6937 	WMITLV_SET_HDR(&dense_thresholds->tlv_header,
6938 			WMITLV_TAG_STRUC_wmi_roam_dense_thres_param,
6939 			WMITLV_GET_STRUCT_TLVLEN
6940 			(wmi_roam_dense_thres_param));
6941 
6942 	buf_ptr += sizeof(wmi_roam_dense_thres_param);
6943 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6944 			 sizeof(wmi_roam_bg_scan_roaming_param));
6945 	buf_ptr += WMI_TLV_HDR_SIZE;
6946 	bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr;
6947 	bg_scan_params->roam_bg_scan_bad_rssi_thresh =
6948 		roam_req->bg_scan_bad_rssi_thresh;
6949 	bg_scan_params->roam_bg_scan_client_bitmap =
6950 		roam_req->bg_scan_client_bitmap;
6951 	bg_scan_params->bad_rssi_thresh_offset_2g =
6952 		roam_req->roam_bad_rssi_thresh_offset_2g;
6953 	bg_scan_params->flags = roam_req->flags;
6954 	WMITLV_SET_HDR(&bg_scan_params->tlv_header,
6955 			WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param,
6956 			WMITLV_GET_STRUCT_TLVLEN
6957 			(wmi_roam_bg_scan_roaming_param));
6958 
6959 	wmi_mtrace(WMI_ROAM_SCAN_RSSI_THRESHOLD, NO_SESSION, 0);
6960 	status = wmi_unified_cmd_send(wmi_handle, buf,
6961 				      len, WMI_ROAM_SCAN_RSSI_THRESHOLD);
6962 	if (QDF_IS_STATUS_ERROR(status)) {
6963 		WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d",
6964 					status);
6965 		wmi_buf_free(buf);
6966 	}
6967 
6968 	return status;
6969 }
6970 
6971 /**
6972  * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime
6973  * configuration params
6974  * @wma_handle:  wma handler
6975  * @dwelltime_params: pointer to dwelltime_params
6976  *
6977  * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
6978  */
6979 static
6980 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle,
6981 		struct wmi_adaptive_dwelltime_params *dwelltime_params)
6982 {
6983 	wmi_scan_adaptive_dwell_config_fixed_param *dwell_param;
6984 	wmi_scan_adaptive_dwell_parameters_tlv *cmd;
6985 	wmi_buf_t buf;
6986 	uint8_t *buf_ptr;
6987 	int32_t err;
6988 	int len;
6989 
6990 	len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
6991 	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
6992 	len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv);
6993 	buf = wmi_buf_alloc(wmi_handle, len);
6994 	if (!buf) {
6995 		WMI_LOGE("%s :Failed to allocate buffer to send cmd",
6996 				__func__);
6997 		return QDF_STATUS_E_NOMEM;
6998 	}
6999 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7000 	dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr;
7001 	WMITLV_SET_HDR(&dwell_param->tlv_header,
7002 		WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param,
7003 		WMITLV_GET_STRUCT_TLVLEN
7004 		(wmi_scan_adaptive_dwell_config_fixed_param));
7005 
7006 	dwell_param->enable = dwelltime_params->is_enabled;
7007 	buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
7008 	WMITLV_SET_HDR(buf_ptr,
7009 			WMITLV_TAG_ARRAY_STRUC,
7010 			sizeof(wmi_scan_adaptive_dwell_parameters_tlv));
7011 	buf_ptr += WMI_TLV_HDR_SIZE;
7012 
7013 	cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr;
7014 	WMITLV_SET_HDR(&cmd->tlv_header,
7015 			WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv,
7016 			WMITLV_GET_STRUCT_TLVLEN(
7017 				wmi_scan_adaptive_dwell_parameters_tlv));
7018 
7019 	cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode;
7020 	cmd->adapative_lpf_weight = dwelltime_params->lpf_weight;
7021 	cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval;
7022 	cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold;
7023 	wmi_mtrace(WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID, NO_SESSION, 0);
7024 	err = wmi_unified_cmd_send(wmi_handle, buf,
7025 			len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID);
7026 	if (err) {
7027 		WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err);
7028 		wmi_buf_free(buf);
7029 		return QDF_STATUS_E_FAILURE;
7030 	}
7031 
7032 	return QDF_STATUS_SUCCESS;
7033 }
7034 
7035 /**
7036  * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection
7037  * configuration params
7038  * @wmi_handle: wmi handler
7039  * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params
7040  *
7041  * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
7042  */
7043 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle,
7044 			struct wmi_dbs_scan_sel_params *dbs_scan_params)
7045 {
7046 	wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param;
7047 	wmi_scan_dbs_duty_cycle_tlv_param *cmd;
7048 	wmi_buf_t buf;
7049 	uint8_t *buf_ptr;
7050 	QDF_STATUS err;
7051 	uint32_t i;
7052 	int len;
7053 
7054 	len = sizeof(*dbs_scan_param);
7055 	len += WMI_TLV_HDR_SIZE;
7056 	len += dbs_scan_params->num_clients * sizeof(*cmd);
7057 
7058 	buf = wmi_buf_alloc(wmi_handle, len);
7059 	if (!buf) {
7060 		WMI_LOGE("%s:Failed to allocate buffer to send cmd", __func__);
7061 		return QDF_STATUS_E_NOMEM;
7062 	}
7063 
7064 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7065 	dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr;
7066 	WMITLV_SET_HDR(&dbs_scan_param->tlv_header,
7067 		       WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param,
7068 		       WMITLV_GET_STRUCT_TLVLEN
7069 		       (wmi_scan_dbs_duty_cycle_fixed_param));
7070 
7071 	dbs_scan_param->num_clients = dbs_scan_params->num_clients;
7072 	dbs_scan_param->pdev_id = dbs_scan_params->pdev_id;
7073 	buf_ptr += sizeof(*dbs_scan_param);
7074 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7075 		       (sizeof(*cmd) * dbs_scan_params->num_clients));
7076 	buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE;
7077 
7078 	for (i = 0; i < dbs_scan_params->num_clients; i++) {
7079 		cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr;
7080 		WMITLV_SET_HDR(&cmd->tlv_header,
7081 			WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv,
7082 			WMITLV_GET_STRUCT_TLVLEN(
7083 					wmi_scan_dbs_duty_cycle_tlv_param));
7084 		cmd->module_id = dbs_scan_params->module_id[i];
7085 		cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i];
7086 		cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i];
7087 		buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd);
7088 	}
7089 
7090 	wmi_mtrace(WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID, NO_SESSION, 0);
7091 	err = wmi_unified_cmd_send(wmi_handle, buf,
7092 				   len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID);
7093 	if (QDF_IS_STATUS_ERROR(err)) {
7094 		WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err);
7095 		wmi_buf_free(buf);
7096 		return QDF_STATUS_E_FAILURE;
7097 	}
7098 
7099 	return QDF_STATUS_SUCCESS;
7100 }
7101 
7102 /**
7103  * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming
7104  * @wmi_handle:     wmi handle
7105  * @roam_req:       Request which contains the filters
7106  *
7107  * There are filters such as whitelist, blacklist and preferred
7108  * list that need to be applied to the scan results to form the
7109  * probable candidates for roaming.
7110  *
7111  * Return: Return success upon successfully passing the
7112  *         parameters to the firmware, otherwise failure.
7113  */
7114 static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle,
7115 				struct roam_scan_filter_params *roam_req)
7116 {
7117 	wmi_buf_t buf = NULL;
7118 	QDF_STATUS status;
7119 	uint32_t i;
7120 	uint32_t len, blist_len = 0;
7121 	uint8_t *buf_ptr;
7122 	wmi_roam_filter_fixed_param *roam_filter;
7123 	uint8_t *bssid_src_ptr = NULL;
7124 	wmi_mac_addr *bssid_dst_ptr = NULL;
7125 	wmi_ssid *ssid_ptr = NULL;
7126 	uint32_t *bssid_preferred_factor_ptr = NULL;
7127 	wmi_roam_lca_disallow_config_tlv_param *blist_param;
7128 	wmi_roam_rssi_rejection_oce_config_param *rssi_rej;
7129 
7130 	len = sizeof(wmi_roam_filter_fixed_param);
7131 
7132 	len += WMI_TLV_HDR_SIZE;
7133 	if (roam_req->num_bssid_black_list)
7134 		len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr);
7135 	len += WMI_TLV_HDR_SIZE;
7136 	if (roam_req->num_ssid_white_list)
7137 		len += roam_req->num_ssid_white_list * sizeof(wmi_ssid);
7138 	len += 2 * WMI_TLV_HDR_SIZE;
7139 	if (roam_req->num_bssid_preferred_list) {
7140 		len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr);
7141 		len += roam_req->num_bssid_preferred_list * sizeof(uint32_t);
7142 	}
7143 	len += WMI_TLV_HDR_SIZE;
7144 	if (roam_req->lca_disallow_config_present) {
7145 		len += sizeof(*blist_param);
7146 		blist_len = sizeof(*blist_param);
7147 	}
7148 
7149 	len += WMI_TLV_HDR_SIZE;
7150 	if (roam_req->num_rssi_rejection_ap)
7151 		len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej);
7152 
7153 	buf = wmi_buf_alloc(wmi_handle, len);
7154 	if (!buf) {
7155 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
7156 		return QDF_STATUS_E_NOMEM;
7157 	}
7158 
7159 	buf_ptr = (u_int8_t *) wmi_buf_data(buf);
7160 	roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr;
7161 	WMITLV_SET_HDR(&roam_filter->tlv_header,
7162 		WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param,
7163 		WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param));
7164 	/* fill in fixed values */
7165 	roam_filter->vdev_id = roam_req->session_id;
7166 	roam_filter->flags = 0;
7167 	roam_filter->op_bitmap = roam_req->op_bitmap;
7168 	roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list;
7169 	roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list;
7170 	roam_filter->num_bssid_preferred_list =
7171 			roam_req->num_bssid_preferred_list;
7172 	roam_filter->num_rssi_rejection_ap =
7173 			roam_req->num_rssi_rejection_ap;
7174 	buf_ptr += sizeof(wmi_roam_filter_fixed_param);
7175 
7176 	WMITLV_SET_HDR((buf_ptr),
7177 		WMITLV_TAG_ARRAY_FIXED_STRUC,
7178 		(roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)));
7179 	bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list;
7180 	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
7181 	for (i = 0; i < roam_req->num_bssid_black_list; i++) {
7182 		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr);
7183 		bssid_src_ptr += ATH_MAC_LEN;
7184 		bssid_dst_ptr++;
7185 	}
7186 	buf_ptr += WMI_TLV_HDR_SIZE +
7187 		(roam_req->num_bssid_black_list * sizeof(wmi_mac_addr));
7188 	WMITLV_SET_HDR((buf_ptr),
7189 		WMITLV_TAG_ARRAY_FIXED_STRUC,
7190 		(roam_req->num_ssid_white_list * sizeof(wmi_ssid)));
7191 	ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE);
7192 	for (i = 0; i < roam_req->num_ssid_white_list; i++) {
7193 		qdf_mem_copy(&ssid_ptr->ssid,
7194 			&roam_req->ssid_allowed_list[i].mac_ssid,
7195 			roam_req->ssid_allowed_list[i].length);
7196 		ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length;
7197 		ssid_ptr++;
7198 	}
7199 	buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list *
7200 							sizeof(wmi_ssid));
7201 	WMITLV_SET_HDR((buf_ptr),
7202 		WMITLV_TAG_ARRAY_FIXED_STRUC,
7203 		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)));
7204 	bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored;
7205 	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
7206 	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
7207 		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr,
7208 				(wmi_mac_addr *)bssid_dst_ptr);
7209 		bssid_src_ptr += ATH_MAC_LEN;
7210 		bssid_dst_ptr++;
7211 	}
7212 	buf_ptr += WMI_TLV_HDR_SIZE +
7213 		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr));
7214 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
7215 		(roam_req->num_bssid_preferred_list * sizeof(uint32_t)));
7216 	bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
7217 	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
7218 		*bssid_preferred_factor_ptr =
7219 			roam_req->bssid_favored_factor[i];
7220 		bssid_preferred_factor_ptr++;
7221 	}
7222 	buf_ptr += WMI_TLV_HDR_SIZE +
7223 		(roam_req->num_bssid_preferred_list * sizeof(uint32_t));
7224 
7225 	WMITLV_SET_HDR(buf_ptr,
7226 			WMITLV_TAG_ARRAY_STRUC, blist_len);
7227 	buf_ptr += WMI_TLV_HDR_SIZE;
7228 	if (roam_req->lca_disallow_config_present) {
7229 		blist_param =
7230 			(wmi_roam_lca_disallow_config_tlv_param *) buf_ptr;
7231 		WMITLV_SET_HDR(&blist_param->tlv_header,
7232 			WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param,
7233 			WMITLV_GET_STRUCT_TLVLEN(
7234 				wmi_roam_lca_disallow_config_tlv_param));
7235 
7236 		blist_param->disallow_duration = roam_req->disallow_duration;
7237 		blist_param->rssi_channel_penalization =
7238 				roam_req->rssi_channel_penalization;
7239 		blist_param->num_disallowed_aps = roam_req->num_disallowed_aps;
7240 		blist_param->disallow_lca_enable_source_bitmap =
7241 			(WMI_ROAM_LCA_DISALLOW_SOURCE_PER |
7242 			WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND);
7243 		buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param));
7244 	}
7245 
7246 	WMITLV_SET_HDR(buf_ptr,
7247 			WMITLV_TAG_ARRAY_STRUC,
7248 			(roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej)));
7249 	buf_ptr += WMI_TLV_HDR_SIZE;
7250 	for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) {
7251 		rssi_rej =
7252 		(wmi_roam_rssi_rejection_oce_config_param *) buf_ptr;
7253 		WMITLV_SET_HDR(&rssi_rej->tlv_header,
7254 			WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param,
7255 			WMITLV_GET_STRUCT_TLVLEN(
7256 			wmi_roam_rssi_rejection_oce_config_param));
7257 		WMI_CHAR_ARRAY_TO_MAC_ADDR(
7258 			roam_req->rssi_rejection_ap[i].bssid.bytes,
7259 			&rssi_rej->bssid);
7260 		rssi_rej->remaining_disallow_duration =
7261 			roam_req->rssi_rejection_ap[i].remaining_duration;
7262 		rssi_rej->requested_rssi =
7263 			(int32_t)roam_req->rssi_rejection_ap[i].expected_rssi;
7264 		buf_ptr +=
7265 			(sizeof(wmi_roam_rssi_rejection_oce_config_param));
7266 	}
7267 
7268 	wmi_mtrace(WMI_ROAM_FILTER_CMDID, NO_SESSION, 0);
7269 	status = wmi_unified_cmd_send(wmi_handle, buf,
7270 		len, WMI_ROAM_FILTER_CMDID);
7271 	if (QDF_IS_STATUS_ERROR(status)) {
7272 		WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d",
7273 				status);
7274 		wmi_buf_free(buf);
7275 	}
7276 
7277 	return status;
7278 }
7279 
7280 #if defined(WLAN_FEATURE_FILS_SK)
7281 static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle,
7282 						  struct hlp_params *params)
7283 {
7284 	uint32_t len;
7285 	uint8_t *buf_ptr;
7286 	wmi_buf_t buf = NULL;
7287 	wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params;
7288 
7289 	len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param);
7290 	len += WMI_TLV_HDR_SIZE;
7291 	len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t));
7292 
7293 	buf = wmi_buf_alloc(wmi_handle, len);
7294 	if (!buf) {
7295 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
7296 		return QDF_STATUS_E_NOMEM;
7297 	}
7298 
7299 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7300 	hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr;
7301 	WMITLV_SET_HDR(&hlp_params->tlv_header,
7302 		WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param,
7303 		WMITLV_GET_STRUCT_TLVLEN(
7304 			wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param));
7305 
7306 	hlp_params->vdev_id = params->vdev_id;
7307 	hlp_params->size = params->hlp_ie_len;
7308 	hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER;
7309 
7310 	buf_ptr += sizeof(*hlp_params);
7311 
7312 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
7313 				round_up(params->hlp_ie_len,
7314 				sizeof(uint32_t)));
7315 	buf_ptr += WMI_TLV_HDR_SIZE;
7316 	qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len);
7317 
7318 	WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"),
7319 			hlp_params->vdev_id, hlp_params->size);
7320 	wmi_mtrace(WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID, NO_SESSION, 0);
7321 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
7322 				WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) {
7323 		WMI_LOGE(FL("Failed to send FILS HLP pkt cmd"));
7324 		wmi_buf_free(buf);
7325 		return QDF_STATUS_E_FAILURE;
7326 	}
7327 
7328 	return QDF_STATUS_SUCCESS;
7329 }
7330 #endif
7331 
7332 #ifdef IPA_OFFLOAD
7333 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter
7334  * @wmi_handle: wmi handle
7335  * @ipa_offload: ipa offload control parameter
7336  *
7337  * Returns: 0 on success, error number otherwise
7338  */
7339 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle,
7340 		struct ipa_uc_offload_control_params *ipa_offload)
7341 {
7342 	wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd;
7343 	wmi_buf_t wmi_buf;
7344 	uint32_t len;
7345 	u_int8_t *buf_ptr;
7346 
7347 	len  = sizeof(*cmd);
7348 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
7349 	if (!wmi_buf) {
7350 		WMI_LOGE("%s: wmi_buf_alloc failed (len=%d)", __func__, len);
7351 		return QDF_STATUS_E_NOMEM;
7352 	}
7353 
7354 	WMI_LOGD("%s: offload_type=%d, enable=%d", __func__,
7355 		ipa_offload->offload_type, ipa_offload->enable);
7356 
7357 	buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf);
7358 
7359 	cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr;
7360 	WMITLV_SET_HDR(&cmd->tlv_header,
7361 		WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param,
7362 		WMITLV_GET_STRUCT_TLVLEN(
7363 		wmi_ipa_offload_enable_disable_cmd_fixed_param));
7364 
7365 	cmd->offload_type = ipa_offload->offload_type;
7366 	cmd->vdev_id = ipa_offload->vdev_id;
7367 	cmd->enable = ipa_offload->enable;
7368 
7369 	wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0);
7370 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
7371 		WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) {
7372 		WMI_LOGE("%s: failed to command", __func__);
7373 		wmi_buf_free(wmi_buf);
7374 		return QDF_STATUS_E_FAILURE;
7375 	}
7376 
7377 	return QDF_STATUS_SUCCESS;
7378 }
7379 #endif
7380 
7381 /**
7382  * send_plm_stop_cmd_tlv() - plm stop request
7383  * @wmi_handle: wmi handle
7384  * @plm: plm request parameters
7385  *
7386  * This function request FW to stop PLM.
7387  *
7388  * Return: CDF status
7389  */
7390 static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle,
7391 			  const struct plm_req_params *plm)
7392 {
7393 	wmi_vdev_plmreq_stop_cmd_fixed_param *cmd;
7394 	int32_t len;
7395 	wmi_buf_t buf;
7396 	uint8_t *buf_ptr;
7397 	int ret;
7398 
7399 	len = sizeof(*cmd);
7400 	buf = wmi_buf_alloc(wmi_handle, len);
7401 	if (!buf) {
7402 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7403 		return QDF_STATUS_E_NOMEM;
7404 	}
7405 
7406 	cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf);
7407 
7408 	buf_ptr = (uint8_t *) cmd;
7409 
7410 	WMITLV_SET_HDR(&cmd->tlv_header,
7411 		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param,
7412 		       WMITLV_GET_STRUCT_TLVLEN
7413 		       (wmi_vdev_plmreq_stop_cmd_fixed_param));
7414 
7415 	cmd->vdev_id = plm->session_id;
7416 
7417 	cmd->meas_token = plm->meas_token;
7418 	WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token);
7419 
7420 	wmi_mtrace(WMI_VDEV_PLMREQ_STOP_CMDID, cmd->vdev_id, 0);
7421 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7422 				   WMI_VDEV_PLMREQ_STOP_CMDID);
7423 	if (ret) {
7424 		WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__);
7425 		wmi_buf_free(buf);
7426 		return QDF_STATUS_E_FAILURE;
7427 	}
7428 
7429 	return QDF_STATUS_SUCCESS;
7430 }
7431 
7432 /**
7433  * send_plm_start_cmd_tlv() - plm start request
7434  * @wmi_handle: wmi handle
7435  * @plm: plm request parameters
7436  *
7437  * This function request FW to start PLM.
7438  *
7439  * Return: CDF status
7440  */
7441 static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle,
7442 			  const struct plm_req_params *plm,
7443 			  uint32_t *gchannel_list)
7444 {
7445 	wmi_vdev_plmreq_start_cmd_fixed_param *cmd;
7446 	uint32_t *channel_list;
7447 	int32_t len;
7448 	wmi_buf_t buf;
7449 	uint8_t *buf_ptr;
7450 	uint8_t count;
7451 	int ret;
7452 
7453 	/* TLV place holder for channel_list */
7454 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
7455 	len += sizeof(uint32_t) * plm->plm_num_ch;
7456 
7457 	buf = wmi_buf_alloc(wmi_handle, len);
7458 	if (!buf) {
7459 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7460 		return QDF_STATUS_E_NOMEM;
7461 	}
7462 	cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf);
7463 
7464 	buf_ptr = (uint8_t *) cmd;
7465 
7466 	WMITLV_SET_HDR(&cmd->tlv_header,
7467 		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param,
7468 		       WMITLV_GET_STRUCT_TLVLEN
7469 			       (wmi_vdev_plmreq_start_cmd_fixed_param));
7470 
7471 	cmd->vdev_id = plm->session_id;
7472 
7473 	cmd->meas_token = plm->meas_token;
7474 	cmd->dialog_token = plm->diag_token;
7475 	cmd->number_bursts = plm->num_bursts;
7476 	cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int);
7477 	cmd->off_duration = plm->meas_duration;
7478 	cmd->burst_cycle = plm->burst_len;
7479 	cmd->tx_power = plm->desired_tx_pwr;
7480 	WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac);
7481 	cmd->num_chans = plm->plm_num_ch;
7482 
7483 	buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param);
7484 
7485 	WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token);
7486 	WMI_LOGD("dialog_token: %d", cmd->dialog_token);
7487 	WMI_LOGD("number_bursts: %d", cmd->number_bursts);
7488 	WMI_LOGD("burst_interval: %d", cmd->burst_interval);
7489 	WMI_LOGD("off_duration: %d", cmd->off_duration);
7490 	WMI_LOGD("burst_cycle: %d", cmd->burst_cycle);
7491 	WMI_LOGD("tx_power: %d", cmd->tx_power);
7492 	WMI_LOGD("Number of channels : %d", cmd->num_chans);
7493 
7494 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
7495 		       (cmd->num_chans * sizeof(uint32_t)));
7496 
7497 	buf_ptr += WMI_TLV_HDR_SIZE;
7498 	if (cmd->num_chans) {
7499 		channel_list = (uint32_t *) buf_ptr;
7500 		for (count = 0; count < cmd->num_chans; count++) {
7501 			channel_list[count] = plm->plm_ch_list[count];
7502 			if (channel_list[count] < WMI_NLO_FREQ_THRESH)
7503 				channel_list[count] =
7504 					gchannel_list[count];
7505 			WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]);
7506 		}
7507 		buf_ptr += cmd->num_chans * sizeof(uint32_t);
7508 	}
7509 
7510 	wmi_mtrace(WMI_VDEV_PLMREQ_START_CMDID, cmd->vdev_id, 0);
7511 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7512 				   WMI_VDEV_PLMREQ_START_CMDID);
7513 	if (ret) {
7514 		WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__);
7515 		wmi_buf_free(buf);
7516 		return QDF_STATUS_E_FAILURE;
7517 	}
7518 
7519 	return QDF_STATUS_SUCCESS;
7520 }
7521 
7522 /**
7523  * send_pno_stop_cmd_tlv() - PNO stop request
7524  * @wmi_handle: wmi handle
7525  * @vdev_id: vdev id
7526  *
7527  * This function request FW to stop ongoing PNO operation.
7528  *
7529  * Return: CDF status
7530  */
7531 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
7532 {
7533 	wmi_nlo_config_cmd_fixed_param *cmd;
7534 	int32_t len = sizeof(*cmd);
7535 	wmi_buf_t buf;
7536 	uint8_t *buf_ptr;
7537 	int ret;
7538 
7539 	/*
7540 	 * TLV place holder for array of structures nlo_configured_parameters
7541 	 * TLV place holder for array of uint32_t channel_list
7542 	 * TLV place holder for chnl prediction cfg
7543 	 */
7544 	len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE;
7545 	buf = wmi_buf_alloc(wmi_handle, len);
7546 	if (!buf) {
7547 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7548 		return QDF_STATUS_E_NOMEM;
7549 	}
7550 
7551 	cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf);
7552 	buf_ptr = (uint8_t *) cmd;
7553 
7554 	WMITLV_SET_HDR(&cmd->tlv_header,
7555 		       WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param,
7556 		       WMITLV_GET_STRUCT_TLVLEN
7557 			       (wmi_nlo_config_cmd_fixed_param));
7558 
7559 	cmd->vdev_id = vdev_id;
7560 	cmd->flags = WMI_NLO_CONFIG_STOP;
7561 	buf_ptr += sizeof(*cmd);
7562 
7563 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
7564 	buf_ptr += WMI_TLV_HDR_SIZE;
7565 
7566 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
7567 	buf_ptr += WMI_TLV_HDR_SIZE;
7568 
7569 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
7570 	buf_ptr += WMI_TLV_HDR_SIZE;
7571 
7572 
7573 	wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0);
7574 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7575 				   WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
7576 	if (ret) {
7577 		WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__);
7578 		wmi_buf_free(buf);
7579 		return QDF_STATUS_E_FAILURE;
7580 	}
7581 
7582 	return QDF_STATUS_SUCCESS;
7583 }
7584 
7585 /**
7586  * wmi_set_pno_channel_prediction() - Set PNO channel prediction
7587  * @buf_ptr:      Buffer passed by upper layers
7588  * @pno:          Buffer to be sent to the firmware
7589  *
7590  * Copy the PNO Channel prediction configuration parameters
7591  * passed by the upper layers to a WMI format TLV and send it
7592  * down to the firmware.
7593  *
7594  * Return: None
7595  */
7596 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr,
7597 		struct pno_scan_req_params *pno)
7598 {
7599 	nlo_channel_prediction_cfg *channel_prediction_cfg =
7600 		(nlo_channel_prediction_cfg *) buf_ptr;
7601 	WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header,
7602 			WMITLV_TAG_ARRAY_BYTE,
7603 			WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg));
7604 #ifdef FEATURE_WLAN_SCAN_PNO
7605 	channel_prediction_cfg->enable = pno->pno_channel_prediction;
7606 	channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels;
7607 	channel_prediction_cfg->stationary_threshold = pno->stationary_thresh;
7608 	channel_prediction_cfg->full_scan_period_ms =
7609 		pno->channel_prediction_full_scan;
7610 #endif
7611 	buf_ptr += sizeof(nlo_channel_prediction_cfg);
7612 	WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d",
7613 			channel_prediction_cfg->enable,
7614 			channel_prediction_cfg->top_k_num,
7615 			channel_prediction_cfg->stationary_threshold,
7616 			channel_prediction_cfg->full_scan_period_ms);
7617 }
7618 
7619 /**
7620  * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration
7621  * @wmi_handle: wmi handle
7622  * @params: configuration parameters
7623  *
7624  * Return: QDF_STATUS
7625  */
7626 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle,
7627 		struct nlo_mawc_params *params)
7628 {
7629 	wmi_buf_t buf = NULL;
7630 	QDF_STATUS status;
7631 	int len;
7632 	uint8_t *buf_ptr;
7633 	wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params;
7634 
7635 	len = sizeof(*wmi_nlo_mawc_params);
7636 	buf = wmi_buf_alloc(wmi_handle, len);
7637 	if (!buf) {
7638 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
7639 		return QDF_STATUS_E_NOMEM;
7640 	}
7641 
7642 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7643 	wmi_nlo_mawc_params =
7644 		(wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr;
7645 	WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header,
7646 		       WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param,
7647 		       WMITLV_GET_STRUCT_TLVLEN
7648 			       (wmi_nlo_configure_mawc_cmd_fixed_param));
7649 	wmi_nlo_mawc_params->vdev_id = params->vdev_id;
7650 	if (params->enable)
7651 		wmi_nlo_mawc_params->enable = 1;
7652 	else
7653 		wmi_nlo_mawc_params->enable = 0;
7654 	wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio;
7655 	wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval;
7656 	wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval;
7657 	WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"),
7658 		wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id,
7659 		wmi_nlo_mawc_params->exp_backoff_ratio,
7660 		wmi_nlo_mawc_params->init_scan_interval,
7661 		wmi_nlo_mawc_params->max_scan_interval);
7662 
7663 	wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0);
7664 	status = wmi_unified_cmd_send(wmi_handle, buf,
7665 				      len, WMI_NLO_CONFIGURE_MAWC_CMDID);
7666 	if (QDF_IS_STATUS_ERROR(status)) {
7667 		WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d",
7668 			status);
7669 		wmi_buf_free(buf);
7670 		return QDF_STATUS_E_FAILURE;
7671 	}
7672 
7673 	return QDF_STATUS_SUCCESS;
7674 }
7675 
7676 /**
7677  * send_pno_start_cmd_tlv() - PNO start request
7678  * @wmi_handle: wmi handle
7679  * @pno: PNO request
7680  *
7681  * This function request FW to start PNO request.
7682  * Request: CDF status
7683  */
7684 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle,
7685 		   struct pno_scan_req_params *pno)
7686 {
7687 	wmi_nlo_config_cmd_fixed_param *cmd;
7688 	nlo_configured_parameters *nlo_list;
7689 	uint32_t *channel_list;
7690 	int32_t len;
7691 	wmi_buf_t buf;
7692 	uint8_t *buf_ptr;
7693 	uint8_t i;
7694 	int ret;
7695 	struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist;
7696 	connected_nlo_rssi_params *nlo_relative_rssi;
7697 	connected_nlo_bss_band_rssi_pref *nlo_band_rssi;
7698 
7699 	/*
7700 	 * TLV place holder for array nlo_configured_parameters(nlo_list)
7701 	 * TLV place holder for array of uint32_t channel_list
7702 	 * TLV place holder for chnnl prediction cfg
7703 	 * TLV place holder for array of wmi_vendor_oui
7704 	 * TLV place holder for array of connected_nlo_bss_band_rssi_pref
7705 	 */
7706 	len = sizeof(*cmd) +
7707 		WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE +
7708 		WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE;
7709 
7710 	len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt,
7711 					  WMI_NLO_MAX_CHAN);
7712 	len += sizeof(nlo_configured_parameters) *
7713 	       QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS);
7714 	len += sizeof(nlo_channel_prediction_cfg);
7715 	len += sizeof(enlo_candidate_score_params);
7716 	len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui;
7717 	len += sizeof(connected_nlo_rssi_params);
7718 	len += sizeof(connected_nlo_bss_band_rssi_pref);
7719 
7720 	buf = wmi_buf_alloc(wmi_handle, len);
7721 	if (!buf) {
7722 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7723 		return QDF_STATUS_E_NOMEM;
7724 	}
7725 
7726 	cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf);
7727 
7728 	buf_ptr = (uint8_t *) cmd;
7729 	WMITLV_SET_HDR(&cmd->tlv_header,
7730 		       WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param,
7731 		       WMITLV_GET_STRUCT_TLVLEN
7732 			       (wmi_nlo_config_cmd_fixed_param));
7733 	cmd->vdev_id = pno->vdev_id;
7734 	cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN;
7735 
7736 #ifdef FEATURE_WLAN_SCAN_PNO
7737 	WMI_SCAN_SET_DWELL_MODE(cmd->flags,
7738 			pno->adaptive_dwell_mode);
7739 #endif
7740 	/* Current FW does not support min-max range for dwell time */
7741 	cmd->active_dwell_time = pno->active_dwell_time;
7742 	cmd->passive_dwell_time = pno->passive_dwell_time;
7743 
7744 	if (pno->do_passive_scan)
7745 		cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE;
7746 	/* Copy scan interval */
7747 	cmd->fast_scan_period = pno->fast_scan_period;
7748 	cmd->slow_scan_period = pno->slow_scan_period;
7749 	cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time);
7750 	cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles;
7751 	cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier;
7752 	WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec",
7753 			cmd->fast_scan_period, cmd->slow_scan_period);
7754 	WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles);
7755 
7756 	/* mac randomization attributes */
7757 	if (pno->scan_random.randomize) {
7758 		cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ |
7759 				WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ;
7760 		wmi_copy_scan_random_mac(pno->scan_random.mac_addr,
7761 					 pno->scan_random.mac_mask,
7762 					 &cmd->mac_addr,
7763 					 &cmd->mac_mask);
7764 	}
7765 
7766 	buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param);
7767 
7768 	cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS);
7769 	WMI_LOGD("SSID count : %d", cmd->no_of_ssids);
7770 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7771 		       cmd->no_of_ssids * sizeof(nlo_configured_parameters));
7772 	buf_ptr += WMI_TLV_HDR_SIZE;
7773 
7774 	nlo_list = (nlo_configured_parameters *) buf_ptr;
7775 	for (i = 0; i < cmd->no_of_ssids; i++) {
7776 		WMITLV_SET_HDR(&nlo_list[i].tlv_header,
7777 			       WMITLV_TAG_ARRAY_BYTE,
7778 			       WMITLV_GET_STRUCT_TLVLEN
7779 				       (nlo_configured_parameters));
7780 		/* Copy ssid and it's length */
7781 		nlo_list[i].ssid.valid = true;
7782 		nlo_list[i].ssid.ssid.ssid_len =
7783 			pno->networks_list[i].ssid.length;
7784 		qdf_mem_copy(nlo_list[i].ssid.ssid.ssid,
7785 			     pno->networks_list[i].ssid.ssid,
7786 			     nlo_list[i].ssid.ssid.ssid_len);
7787 		WMI_LOGD("index: %d ssid: %.*s len: %d", i,
7788 			 nlo_list[i].ssid.ssid.ssid_len,
7789 			 (char *)nlo_list[i].ssid.ssid.ssid,
7790 			 nlo_list[i].ssid.ssid.ssid_len);
7791 
7792 		/* Copy rssi threshold */
7793 		if (pno->networks_list[i].rssi_thresh &&
7794 		    pno->networks_list[i].rssi_thresh >
7795 		    WMI_RSSI_THOLD_DEFAULT) {
7796 			nlo_list[i].rssi_cond.valid = true;
7797 			nlo_list[i].rssi_cond.rssi =
7798 				pno->networks_list[i].rssi_thresh;
7799 			WMI_LOGD("RSSI threshold : %d dBm",
7800 				 nlo_list[i].rssi_cond.rssi);
7801 		}
7802 		nlo_list[i].bcast_nw_type.valid = true;
7803 		nlo_list[i].bcast_nw_type.bcast_nw_type =
7804 			pno->networks_list[i].bc_new_type;
7805 		WMI_LOGD("Broadcast NW type (%u)",
7806 			 nlo_list[i].bcast_nw_type.bcast_nw_type);
7807 	}
7808 	buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters);
7809 
7810 	/* Copy channel info */
7811 	cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt,
7812 				       WMI_NLO_MAX_CHAN);
7813 	WMI_LOGD("Channel count: %d", cmd->num_of_channels);
7814 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
7815 		       (cmd->num_of_channels * sizeof(uint32_t)));
7816 	buf_ptr += WMI_TLV_HDR_SIZE;
7817 
7818 	channel_list = (uint32_t *) buf_ptr;
7819 	for (i = 0; i < cmd->num_of_channels; i++) {
7820 		channel_list[i] = pno->networks_list[0].channels[i];
7821 
7822 		if (channel_list[i] < WMI_NLO_FREQ_THRESH)
7823 			channel_list[i] =
7824 				wlan_chan_to_freq(pno->
7825 					networks_list[0].channels[i]);
7826 
7827 		WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]);
7828 	}
7829 	buf_ptr += cmd->num_of_channels * sizeof(uint32_t);
7830 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7831 			sizeof(nlo_channel_prediction_cfg));
7832 	buf_ptr += WMI_TLV_HDR_SIZE;
7833 	wmi_set_pno_channel_prediction(buf_ptr, pno);
7834 	buf_ptr += sizeof(nlo_channel_prediction_cfg);
7835 	/** TODO: Discrete firmware doesn't have command/option to configure
7836 	 * App IE which comes from wpa_supplicant as of part PNO start request.
7837 	 */
7838 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param,
7839 		       WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params));
7840 	buf_ptr += sizeof(enlo_candidate_score_params);
7841 
7842 	if (ie_whitelist->white_list) {
7843 		cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ;
7844 		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
7845 					    &cmd->num_vendor_oui,
7846 					    ie_whitelist);
7847 	}
7848 
7849 	/* ie white list */
7850 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7851 		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
7852 	buf_ptr += WMI_TLV_HDR_SIZE;
7853 	if (cmd->num_vendor_oui != 0) {
7854 		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
7855 				    ie_whitelist->voui);
7856 		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
7857 	}
7858 
7859 	if (pno->relative_rssi_set)
7860 		cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG;
7861 
7862 	/*
7863 	 * Firmware calculation using connected PNO params:
7864 	 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref)
7865 	 * deduction of rssi_pref for chosen band_pref and
7866 	 * addition of rssi_pref for remaining bands (other than chosen band).
7867 	 */
7868 	nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr;
7869 	WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header,
7870 		WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params,
7871 		WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params));
7872 	nlo_relative_rssi->relative_rssi = pno->relative_rssi;
7873 	WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi);
7874 	buf_ptr += sizeof(*nlo_relative_rssi);
7875 
7876 	/*
7877 	 * As of now Kernel and Host supports one band and rssi preference.
7878 	 * Firmware supports array of band and rssi preferences
7879 	 */
7880 	cmd->num_cnlo_band_pref = 1;
7881 	WMITLV_SET_HDR(buf_ptr,
7882 		WMITLV_TAG_ARRAY_STRUC,
7883 		cmd->num_cnlo_band_pref *
7884 		sizeof(connected_nlo_bss_band_rssi_pref));
7885 	buf_ptr += WMI_TLV_HDR_SIZE;
7886 
7887 	nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr;
7888 	for (i = 0; i < cmd->num_cnlo_band_pref; i++) {
7889 		WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header,
7890 			WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref,
7891 			WMITLV_GET_STRUCT_TLVLEN(
7892 				connected_nlo_bss_band_rssi_pref));
7893 		nlo_band_rssi[i].band = pno->band_rssi_pref.band;
7894 		nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi;
7895 		WMI_LOGI("band_pref %d, rssi_pref %d",
7896 			nlo_band_rssi[i].band,
7897 			nlo_band_rssi[i].rssi_pref);
7898 	}
7899 	buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi);
7900 
7901 	wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0);
7902 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7903 				   WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
7904 	if (ret) {
7905 		WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__);
7906 		wmi_buf_free(buf);
7907 		return QDF_STATUS_E_FAILURE;
7908 	}
7909 
7910 	return QDF_STATUS_SUCCESS;
7911 }
7912 
7913 /* send_set_ric_req_cmd_tlv() - set ric request element
7914  * @wmi_handle: wmi handle
7915  * @msg: message
7916  * @is_add_ts: is addts required
7917  *
7918  * This function sets ric request element for 11r roaming.
7919  *
7920  * Return: CDF status
7921  */
7922 static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle,
7923 			void *msg, uint8_t is_add_ts)
7924 {
7925 	wmi_ric_request_fixed_param *cmd;
7926 	wmi_ric_tspec *tspec_param;
7927 	wmi_buf_t buf;
7928 	uint8_t *buf_ptr;
7929 	struct mac_tspec_ie *ptspecIE = NULL;
7930 	int32_t len = sizeof(wmi_ric_request_fixed_param) +
7931 		      WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec);
7932 
7933 	buf = wmi_buf_alloc(wmi_handle, len);
7934 	if (!buf) {
7935 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
7936 		return QDF_STATUS_E_NOMEM;
7937 	}
7938 
7939 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7940 
7941 	cmd = (wmi_ric_request_fixed_param *) buf_ptr;
7942 	WMITLV_SET_HDR(&cmd->tlv_header,
7943 		   WMITLV_TAG_STRUC_wmi_ric_request_fixed_param,
7944 		   WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param));
7945 	if (is_add_ts)
7946 		cmd->vdev_id = ((struct add_ts_param *) msg)->sme_session_id;
7947 	else
7948 		cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId;
7949 	cmd->num_ric_request = 1;
7950 	cmd->is_add_ric = is_add_ts;
7951 
7952 	buf_ptr += sizeof(wmi_ric_request_fixed_param);
7953 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec));
7954 
7955 	buf_ptr += WMI_TLV_HDR_SIZE;
7956 	tspec_param = (wmi_ric_tspec *) buf_ptr;
7957 	WMITLV_SET_HDR(&tspec_param->tlv_header,
7958 		       WMITLV_TAG_STRUC_wmi_ric_tspec,
7959 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec));
7960 
7961 	if (is_add_ts)
7962 		ptspecIE = &(((struct add_ts_param *) msg)->tspec);
7963 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
7964 	else
7965 		ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec);
7966 #endif
7967 	if (ptspecIE) {
7968 		/* Fill the tsinfo in the format expected by firmware */
7969 #ifndef ANI_LITTLE_BIT_ENDIAN
7970 		qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1,
7971 			     ((uint8_t *) &ptspecIE->tsinfo) + 1, 2);
7972 #else
7973 		qdf_mem_copy(((uint8_t *) &tspec_param->ts_info),
7974 			     ((uint8_t *) &ptspecIE->tsinfo) + 1, 2);
7975 #endif /* ANI_LITTLE_BIT_ENDIAN */
7976 
7977 		tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz;
7978 		tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz;
7979 		tspec_param->min_service_interval = ptspecIE->minSvcInterval;
7980 		tspec_param->max_service_interval = ptspecIE->maxSvcInterval;
7981 		tspec_param->inactivity_interval = ptspecIE->inactInterval;
7982 		tspec_param->suspension_interval = ptspecIE->suspendInterval;
7983 		tspec_param->svc_start_time = ptspecIE->svcStartTime;
7984 		tspec_param->min_data_rate = ptspecIE->minDataRate;
7985 		tspec_param->mean_data_rate = ptspecIE->meanDataRate;
7986 		tspec_param->peak_data_rate = ptspecIE->peakDataRate;
7987 		tspec_param->max_burst_size = ptspecIE->maxBurstSz;
7988 		tspec_param->delay_bound = ptspecIE->delayBound;
7989 		tspec_param->min_phy_rate = ptspecIE->minPhyRate;
7990 		tspec_param->surplus_bw_allowance = ptspecIE->surplusBw;
7991 		tspec_param->medium_time = 0;
7992 	}
7993 	WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts);
7994 
7995 	wmi_mtrace(WMI_ROAM_SET_RIC_REQUEST_CMDID, cmd->vdev_id, 0);
7996 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
7997 				 WMI_ROAM_SET_RIC_REQUEST_CMDID)) {
7998 		WMI_LOGP("%s: Failed to send vdev Set RIC Req command",
7999 			 __func__);
8000 		if (is_add_ts)
8001 			((struct add_ts_param *) msg)->status =
8002 					    QDF_STATUS_E_FAILURE;
8003 		wmi_buf_free(buf);
8004 		return QDF_STATUS_E_FAILURE;
8005 	}
8006 
8007 	return QDF_STATUS_SUCCESS;
8008 }
8009 
8010 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
8011 /**
8012  * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats
8013  * @wmi_handle: wmi handle
8014  * @clear_req: ll stats clear request command params
8015  *
8016  * Return: QDF_STATUS_SUCCESS for success or error code
8017  */
8018 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle,
8019 		const struct ll_stats_clear_params *clear_req,
8020 		uint8_t addr[IEEE80211_ADDR_LEN])
8021 {
8022 	wmi_clear_link_stats_cmd_fixed_param *cmd;
8023 	int32_t len;
8024 	wmi_buf_t buf;
8025 	uint8_t *buf_ptr;
8026 	int ret;
8027 
8028 	len = sizeof(*cmd);
8029 	buf = wmi_buf_alloc(wmi_handle, len);
8030 
8031 	if (!buf) {
8032 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8033 		return QDF_STATUS_E_NOMEM;
8034 	}
8035 
8036 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8037 	qdf_mem_zero(buf_ptr, len);
8038 	cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr;
8039 
8040 	WMITLV_SET_HDR(&cmd->tlv_header,
8041 		       WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param,
8042 		       WMITLV_GET_STRUCT_TLVLEN
8043 			       (wmi_clear_link_stats_cmd_fixed_param));
8044 
8045 	cmd->stop_stats_collection_req = clear_req->stop_req;
8046 	cmd->vdev_id = clear_req->sta_id;
8047 	cmd->stats_clear_req_mask = clear_req->stats_clear_mask;
8048 
8049 	WMI_CHAR_ARRAY_TO_MAC_ADDR(addr,
8050 				   &cmd->peer_macaddr);
8051 
8052 	WMI_LOGD("LINK_LAYER_STATS - Clear Request Params");
8053 	WMI_LOGD("StopReq         : %d", cmd->stop_stats_collection_req);
8054 	WMI_LOGD("Vdev Id         : %d", cmd->vdev_id);
8055 	WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask);
8056 	/* WMI_LOGD("Peer MAC Addr   : %pM",
8057 		 cmd->peer_macaddr); */
8058 
8059 	wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0);
8060 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8061 				   WMI_CLEAR_LINK_STATS_CMDID);
8062 	if (ret) {
8063 		WMI_LOGE("%s: Failed to send clear link stats req", __func__);
8064 		wmi_buf_free(buf);
8065 		return QDF_STATUS_E_FAILURE;
8066 	}
8067 
8068 	WMI_LOGD("Clear Link Layer Stats request sent successfully");
8069 	return QDF_STATUS_SUCCESS;
8070 }
8071 
8072 /**
8073  * send_process_ll_stats_set_cmd_tlv() - link layer stats set request
8074  * @wmi_handle:       wmi handle
8075  * @setReq:  ll stats set request command params
8076  *
8077  * Return: QDF_STATUS_SUCCESS for success or error code
8078  */
8079 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle,
8080 		const struct ll_stats_set_params *set_req)
8081 {
8082 	wmi_start_link_stats_cmd_fixed_param *cmd;
8083 	int32_t len;
8084 	wmi_buf_t buf;
8085 	uint8_t *buf_ptr;
8086 	int ret;
8087 
8088 	len = sizeof(*cmd);
8089 	buf = wmi_buf_alloc(wmi_handle, len);
8090 
8091 	if (!buf) {
8092 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8093 		return QDF_STATUS_E_NOMEM;
8094 	}
8095 
8096 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8097 	qdf_mem_zero(buf_ptr, len);
8098 	cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr;
8099 
8100 	WMITLV_SET_HDR(&cmd->tlv_header,
8101 		       WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param,
8102 		       WMITLV_GET_STRUCT_TLVLEN
8103 			       (wmi_start_link_stats_cmd_fixed_param));
8104 
8105 	cmd->mpdu_size_threshold = set_req->mpdu_size_threshold;
8106 	cmd->aggressive_statistics_gathering =
8107 		set_req->aggressive_statistics_gathering;
8108 
8109 	WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params");
8110 	WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold);
8111 	WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering);
8112 
8113 	wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0);
8114 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8115 				   WMI_START_LINK_STATS_CMDID);
8116 	if (ret) {
8117 		WMI_LOGE("%s: Failed to send set link stats request", __func__);
8118 		wmi_buf_free(buf);
8119 		return QDF_STATUS_E_FAILURE;
8120 	}
8121 
8122 	return QDF_STATUS_SUCCESS;
8123 }
8124 
8125 /**
8126  * send_process_ll_stats_get_cmd_tlv() - link layer stats get request
8127  * @wmi_handle:wmi handle
8128  * @get_req:ll stats get request command params
8129  * @addr: mac address
8130  *
8131  * Return: QDF_STATUS_SUCCESS for success or error code
8132  */
8133 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle,
8134 		 const struct ll_stats_get_params  *get_req,
8135 		 uint8_t addr[IEEE80211_ADDR_LEN])
8136 {
8137 	wmi_request_link_stats_cmd_fixed_param *cmd;
8138 	int32_t len;
8139 	wmi_buf_t buf;
8140 	uint8_t *buf_ptr;
8141 	int ret;
8142 
8143 	len = sizeof(*cmd);
8144 	buf = wmi_buf_alloc(wmi_handle, len);
8145 
8146 	if (!buf) {
8147 		WMI_LOGE("%s: buf allocation failed", __func__);
8148 		return QDF_STATUS_E_NOMEM;
8149 	}
8150 
8151 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8152 	qdf_mem_zero(buf_ptr, len);
8153 	cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr;
8154 
8155 	WMITLV_SET_HDR(&cmd->tlv_header,
8156 		       WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param,
8157 		       WMITLV_GET_STRUCT_TLVLEN
8158 			       (wmi_request_link_stats_cmd_fixed_param));
8159 
8160 	cmd->request_id = get_req->req_id;
8161 	cmd->stats_type = get_req->param_id_mask;
8162 	cmd->vdev_id = get_req->sta_id;
8163 
8164 	WMI_CHAR_ARRAY_TO_MAC_ADDR(addr,
8165 				   &cmd->peer_macaddr);
8166 
8167 	WMI_LOGD("LINK_LAYER_STATS - Get Request Params");
8168 	WMI_LOGD("Request ID      : %u", cmd->request_id);
8169 	WMI_LOGD("Stats Type      : %0x", cmd->stats_type);
8170 	WMI_LOGD("Vdev ID         : %d", cmd->vdev_id);
8171 	WMI_LOGD("Peer MAC Addr   : %pM", addr);
8172 
8173 	wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0);
8174 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8175 				   WMI_REQUEST_LINK_STATS_CMDID);
8176 	if (ret) {
8177 		WMI_LOGE("%s: Failed to send get link stats request", __func__);
8178 		wmi_buf_free(buf);
8179 		return QDF_STATUS_E_FAILURE;
8180 	}
8181 
8182 	return QDF_STATUS_SUCCESS;
8183 }
8184 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */
8185 
8186 /**
8187  * send_congestion_cmd_tlv() - send request to fw to get CCA
8188  * @wmi_handle: wmi handle
8189  * @vdev_id: vdev id
8190  *
8191  * Return: CDF status
8192  */
8193 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle,
8194 			uint8_t vdev_id)
8195 {
8196 	wmi_buf_t buf;
8197 	wmi_request_stats_cmd_fixed_param *cmd;
8198 	uint8_t len;
8199 	uint8_t *buf_ptr;
8200 
8201 	len = sizeof(*cmd);
8202 	buf = wmi_buf_alloc(wmi_handle, len);
8203 	if (!buf) {
8204 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
8205 		return QDF_STATUS_E_FAILURE;
8206 	}
8207 
8208 	buf_ptr = wmi_buf_data(buf);
8209 	cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr;
8210 	WMITLV_SET_HDR(&cmd->tlv_header,
8211 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8212 		       WMITLV_GET_STRUCT_TLVLEN
8213 			       (wmi_request_stats_cmd_fixed_param));
8214 
8215 	cmd->stats_id = WMI_REQUEST_CONGESTION_STAT;
8216 	cmd->vdev_id = vdev_id;
8217 	WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->",
8218 			cmd->vdev_id, cmd->stats_id);
8219 
8220 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
8221 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8222 				 WMI_REQUEST_STATS_CMDID)) {
8223 		WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID",
8224 			 __func__);
8225 		wmi_buf_free(buf);
8226 		return QDF_STATUS_E_FAILURE;
8227 	}
8228 
8229 	return QDF_STATUS_SUCCESS;
8230 }
8231 
8232 /**
8233  * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats
8234  * @wmi_handle: wmi handle
8235  * @rssi_req: get RSSI request
8236  *
8237  * Return: CDF status
8238  */
8239 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle)
8240 {
8241 	wmi_buf_t buf;
8242 	wmi_request_stats_cmd_fixed_param *cmd;
8243 	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
8244 
8245 	buf = wmi_buf_alloc(wmi_handle, len);
8246 	if (!buf) {
8247 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8248 		return QDF_STATUS_E_FAILURE;
8249 	}
8250 
8251 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
8252 	WMITLV_SET_HDR(&cmd->tlv_header,
8253 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8254 		       WMITLV_GET_STRUCT_TLVLEN
8255 			       (wmi_request_stats_cmd_fixed_param));
8256 	cmd->stats_id = WMI_REQUEST_VDEV_STAT;
8257 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
8258 	if (wmi_unified_cmd_send
8259 		    (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) {
8260 		WMI_LOGE("Failed to send host stats request to fw");
8261 		wmi_buf_free(buf);
8262 		return QDF_STATUS_E_FAILURE;
8263 	}
8264 
8265 	return QDF_STATUS_SUCCESS;
8266 }
8267 
8268 /**
8269  * send_snr_cmd_tlv() - get RSSI from fw
8270  * @wmi_handle: wmi handle
8271  * @vdev_id: vdev id
8272  *
8273  * Return: CDF status
8274  */
8275 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
8276 {
8277 	wmi_buf_t buf;
8278 	wmi_request_stats_cmd_fixed_param *cmd;
8279 	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
8280 
8281 	buf = wmi_buf_alloc(wmi_handle, len);
8282 	if (!buf) {
8283 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8284 		return QDF_STATUS_E_FAILURE;
8285 	}
8286 
8287 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
8288 	cmd->vdev_id = vdev_id;
8289 
8290 	WMITLV_SET_HDR(&cmd->tlv_header,
8291 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8292 		       WMITLV_GET_STRUCT_TLVLEN
8293 			       (wmi_request_stats_cmd_fixed_param));
8294 	cmd->stats_id = WMI_REQUEST_VDEV_STAT;
8295 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
8296 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8297 				 WMI_REQUEST_STATS_CMDID)) {
8298 		WMI_LOGE("Failed to send host stats request to fw");
8299 		wmi_buf_free(buf);
8300 		return QDF_STATUS_E_FAILURE;
8301 	}
8302 
8303 	return QDF_STATUS_SUCCESS;
8304 }
8305 
8306 /**
8307  * send_link_status_req_cmd_tlv() - process link status request from UMAC
8308  * @wmi_handle: wmi handle
8309  * @link_status: get link params
8310  *
8311  * Return: CDF status
8312  */
8313 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle,
8314 				 struct link_status_params *link_status)
8315 {
8316 	wmi_buf_t buf;
8317 	wmi_request_stats_cmd_fixed_param *cmd;
8318 	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
8319 
8320 	buf = wmi_buf_alloc(wmi_handle, len);
8321 	if (!buf) {
8322 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8323 		return QDF_STATUS_E_FAILURE;
8324 	}
8325 
8326 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
8327 	WMITLV_SET_HDR(&cmd->tlv_header,
8328 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8329 		       WMITLV_GET_STRUCT_TLVLEN
8330 			       (wmi_request_stats_cmd_fixed_param));
8331 	cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT;
8332 	cmd->vdev_id = link_status->session_id;
8333 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
8334 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8335 				 WMI_REQUEST_STATS_CMDID)) {
8336 		WMI_LOGE("Failed to send WMI link  status request to fw");
8337 		wmi_buf_free(buf);
8338 		return QDF_STATUS_E_FAILURE;
8339 	}
8340 
8341 	return QDF_STATUS_SUCCESS;
8342 }
8343 
8344 /**
8345  * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME
8346  * @wmi_handle: wmi handle
8347  * @ta_dhcp_ind: DHCP indication parameter
8348  *
8349  * Return: CDF Status
8350  */
8351 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle,
8352 				wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind)
8353 {
8354 	QDF_STATUS status;
8355 	wmi_buf_t buf = NULL;
8356 	uint8_t *buf_ptr;
8357 	wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp;
8358 	int len = sizeof(wmi_peer_set_param_cmd_fixed_param);
8359 
8360 
8361 	buf = wmi_buf_alloc(wmi_handle, len);
8362 	if (!buf) {
8363 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
8364 		return QDF_STATUS_E_NOMEM;
8365 	}
8366 
8367 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8368 	peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr;
8369 	WMITLV_SET_HDR(&peer_set_param_fp->tlv_header,
8370 		       WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
8371 		       WMITLV_GET_STRUCT_TLVLEN
8372 			       (wmi_peer_set_param_cmd_fixed_param));
8373 
8374 	/* fill in values */
8375 	peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id;
8376 	peer_set_param_fp->param_id = ta_dhcp_ind->param_id;
8377 	peer_set_param_fp->param_value = ta_dhcp_ind->param_value;
8378 	qdf_mem_copy(&peer_set_param_fp->peer_macaddr,
8379 				   &ta_dhcp_ind->peer_macaddr,
8380 				   sizeof(ta_dhcp_ind->peer_macaddr));
8381 
8382 	wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, NO_SESSION, 0);
8383 	status = wmi_unified_cmd_send(wmi_handle, buf,
8384 				      len, WMI_PEER_SET_PARAM_CMDID);
8385 	if (QDF_IS_STATUS_ERROR(status)) {
8386 		WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
8387 			 " returned Error %d", __func__, status);
8388 		wmi_buf_free(buf);
8389 	}
8390 
8391 	return status;
8392 }
8393 
8394 /**
8395  * send_get_link_speed_cmd_tlv() -send command to get linkspeed
8396  * @wmi_handle: wmi handle
8397  * @pLinkSpeed: link speed info
8398  *
8399  * Return: CDF status
8400  */
8401 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle,
8402 		wmi_mac_addr peer_macaddr)
8403 {
8404 	wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd;
8405 	wmi_buf_t wmi_buf;
8406 	uint32_t len;
8407 	uint8_t *buf_ptr;
8408 
8409 	len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param);
8410 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
8411 	if (!wmi_buf) {
8412 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8413 		return QDF_STATUS_E_NOMEM;
8414 	}
8415 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
8416 
8417 	cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr;
8418 	WMITLV_SET_HDR(&cmd->tlv_header,
8419 	       WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param,
8420 	       WMITLV_GET_STRUCT_TLVLEN
8421 	       (wmi_peer_get_estimated_linkspeed_cmd_fixed_param));
8422 
8423 	/* Copy the peer macaddress to the wma buffer */
8424 	qdf_mem_copy(&cmd->peer_macaddr,
8425 				   &peer_macaddr,
8426 				   sizeof(peer_macaddr));
8427 
8428 
8429 	wmi_mtrace(WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID, cmd->vdev_id, 0);
8430 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
8431 				 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) {
8432 		WMI_LOGE("%s: failed to send link speed command", __func__);
8433 		wmi_buf_free(wmi_buf);
8434 		return QDF_STATUS_E_FAILURE;
8435 	}
8436 	return QDF_STATUS_SUCCESS;
8437 }
8438 
8439 #ifdef WLAN_SUPPORT_GREEN_AP
8440 /**
8441  * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params
8442  * @wmi_handle:	 wmi handler
8443  * @egap_params: pointer to egap_params
8444  *
8445  * Return:	 0 for success, otherwise appropriate error code
8446  */
8447 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle,
8448 		     struct wlan_green_ap_egap_params *egap_params)
8449 {
8450 	wmi_ap_ps_egap_param_cmd_fixed_param *cmd;
8451 	wmi_buf_t buf;
8452 	int32_t err;
8453 
8454 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
8455 	if (!buf) {
8456 		WMI_LOGE("Failed to allocate buffer to send ap_ps_egap cmd");
8457 		return QDF_STATUS_E_NOMEM;
8458 	}
8459 	cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf);
8460 	WMITLV_SET_HDR(&cmd->tlv_header,
8461 		       WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param,
8462 		       WMITLV_GET_STRUCT_TLVLEN(
8463 			       wmi_ap_ps_egap_param_cmd_fixed_param));
8464 
8465 	cmd->enable = egap_params->host_enable_egap;
8466 	cmd->inactivity_time = egap_params->egap_inactivity_time;
8467 	cmd->wait_time = egap_params->egap_wait_time;
8468 	cmd->flags = egap_params->egap_feature_flags;
8469 	wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0);
8470 	err = wmi_unified_cmd_send(wmi_handle, buf,
8471 				   sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID);
8472 	if (err) {
8473 		WMI_LOGE("Failed to send ap_ps_egap cmd");
8474 		wmi_buf_free(buf);
8475 		return QDF_STATUS_E_FAILURE;
8476 	}
8477 
8478 	return QDF_STATUS_SUCCESS;
8479 }
8480 #endif
8481 
8482 /**
8483  * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW
8484  * @wmi_handl: wmi handle
8485  * @cmd: Profiling command index
8486  * @value1: parameter1 value
8487  * @value2: parameter2 value
8488  *
8489  * Return: QDF_STATUS_SUCCESS for success else error code
8490  */
8491 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle,
8492 			uint32_t cmd, uint32_t value1, uint32_t value2)
8493 {
8494 	wmi_buf_t buf;
8495 	int32_t len = 0;
8496 	int ret;
8497 	wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd;
8498 	wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd;
8499 	wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd;
8500 	wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd;
8501 
8502 	switch (cmd) {
8503 	case WMI_WLAN_PROFILE_TRIGGER_CMDID:
8504 		len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param);
8505 		buf = wmi_buf_alloc(wmi_handle, len);
8506 		if (!buf) {
8507 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
8508 			return QDF_STATUS_E_NOMEM;
8509 		}
8510 		prof_trig_cmd =
8511 			(wmi_wlan_profile_trigger_cmd_fixed_param *)
8512 				wmi_buf_data(buf);
8513 		WMITLV_SET_HDR(&prof_trig_cmd->tlv_header,
8514 		     WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param,
8515 		     WMITLV_GET_STRUCT_TLVLEN
8516 		    (wmi_wlan_profile_trigger_cmd_fixed_param));
8517 		prof_trig_cmd->enable = value1;
8518 		wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0);
8519 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8520 				WMI_WLAN_PROFILE_TRIGGER_CMDID);
8521 		if (ret) {
8522 			WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d",
8523 					value1);
8524 			wmi_buf_free(buf);
8525 			return ret;
8526 		}
8527 		break;
8528 
8529 	case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
8530 		len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param);
8531 		buf = wmi_buf_alloc(wmi_handle, len);
8532 		if (!buf) {
8533 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
8534 			return QDF_STATUS_E_NOMEM;
8535 		}
8536 		profile_getdata_cmd =
8537 			(wmi_wlan_profile_get_prof_data_cmd_fixed_param *)
8538 				wmi_buf_data(buf);
8539 		WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header,
8540 		      WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param,
8541 		      WMITLV_GET_STRUCT_TLVLEN
8542 		      (wmi_wlan_profile_get_prof_data_cmd_fixed_param));
8543 		wmi_mtrace(WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
8544 			   NO_SESSION, 0);
8545 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8546 				WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID);
8547 		if (ret) {
8548 			WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d",
8549 					value1, value2);
8550 			wmi_buf_free(buf);
8551 			return ret;
8552 		}
8553 		break;
8554 
8555 	case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
8556 		len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param);
8557 		buf = wmi_buf_alloc(wmi_handle, len);
8558 		if (!buf) {
8559 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
8560 			return QDF_STATUS_E_NOMEM;
8561 		}
8562 		hist_intvl_cmd =
8563 			(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *)
8564 				wmi_buf_data(buf);
8565 		WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header,
8566 		      WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param,
8567 		      WMITLV_GET_STRUCT_TLVLEN
8568 		      (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param));
8569 		hist_intvl_cmd->profile_id = value1;
8570 		hist_intvl_cmd->value = value2;
8571 		wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
8572 			   NO_SESSION, 0);
8573 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8574 				WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID);
8575 		if (ret) {
8576 			WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d",
8577 					value1, value2);
8578 			wmi_buf_free(buf);
8579 			return ret;
8580 		}
8581 		break;
8582 
8583 	case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
8584 		len =
8585 		sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param);
8586 		buf = wmi_buf_alloc(wmi_handle, len);
8587 		if (!buf) {
8588 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
8589 			return QDF_STATUS_E_NOMEM;
8590 		}
8591 		profile_enable_cmd =
8592 			(wmi_wlan_profile_enable_profile_id_cmd_fixed_param *)
8593 				wmi_buf_data(buf);
8594 		WMITLV_SET_HDR(&profile_enable_cmd->tlv_header,
8595 		      WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param,
8596 		      WMITLV_GET_STRUCT_TLVLEN
8597 		      (wmi_wlan_profile_enable_profile_id_cmd_fixed_param));
8598 		profile_enable_cmd->profile_id = value1;
8599 		profile_enable_cmd->enable = value2;
8600 		wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
8601 			   NO_SESSION, 0);
8602 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8603 				WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID);
8604 		if (ret) {
8605 			WMI_LOGE("enable cmd Failed for id %d value %d",
8606 					value1, value2);
8607 			wmi_buf_free(buf);
8608 			return ret;
8609 		}
8610 		break;
8611 
8612 	default:
8613 		WMI_LOGD("%s: invalid profiling command", __func__);
8614 		break;
8615 	}
8616 
8617 	return 0;
8618 }
8619 
8620 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle,
8621 				struct wlm_latency_level_param *params)
8622 {
8623 	wmi_wlm_config_cmd_fixed_param *cmd;
8624 	wmi_buf_t buf;
8625 	uint32_t len = sizeof(*cmd);
8626 	static uint32_t ll[4] = {100, 60, 40, 20};
8627 
8628 	buf = wmi_buf_alloc(wmi_handle, len);
8629 	if (!buf) {
8630 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
8631 		return QDF_STATUS_E_NOMEM;
8632 	}
8633 	cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf);
8634 	WMITLV_SET_HDR(&cmd->tlv_header,
8635 		       WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param,
8636 		       WMITLV_GET_STRUCT_TLVLEN
8637 		       (wmi_wlm_config_cmd_fixed_param));
8638 	cmd->vdev_id = params->vdev_id;
8639 	cmd->latency_level = params->wlm_latency_level;
8640 	cmd->ul_latency = ll[params->wlm_latency_level];
8641 	cmd->dl_latency = ll[params->wlm_latency_level];
8642 	cmd->flags = params->wlm_latency_flags;
8643 	wmi_mtrace(WMI_WLM_CONFIG_CMDID, cmd->vdev_id, 0);
8644 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8645 				 WMI_WLM_CONFIG_CMDID)) {
8646 		WMI_LOGE("%s: Failed to send setting latency config command",
8647 			 __func__);
8648 		wmi_buf_free(buf);
8649 		return QDF_STATUS_E_FAILURE;
8650 	}
8651 
8652 	return 0;
8653 }
8654 /**
8655  * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter
8656  * @wmi_handle: wmi handle
8657  * @vdev_id: vdev id
8658  *
8659  * Return: QDF_STATUS_SUCCESS for success or error code
8660  */
8661 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
8662 {
8663 	WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd;
8664 	wmi_buf_t buf;
8665 	int32_t len = sizeof(*cmd);
8666 
8667 	WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
8668 	buf = wmi_buf_alloc(wmi_handle, len);
8669 	if (!buf) {
8670 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
8671 		return QDF_STATUS_E_NOMEM;
8672 	}
8673 	cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *)
8674 		wmi_buf_data(buf);
8675 	WMITLV_SET_HDR(&cmd->tlv_header,
8676 	WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param,
8677 		  WMITLV_GET_STRUCT_TLVLEN
8678 		  (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param));
8679 	cmd->vdev_id = vdev_id;
8680 	cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE;
8681 	wmi_mtrace(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID, cmd->vdev_id, 0);
8682 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8683 				 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) {
8684 		WMI_LOGP("%s: Failed to send NAT keepalive enable command",
8685 			 __func__);
8686 		wmi_buf_free(buf);
8687 		return QDF_STATUS_E_FAILURE;
8688 	}
8689 
8690 	return 0;
8691 }
8692 
8693 /**
8694  * wmi_unified_csa_offload_enable() - sen CSA offload enable command
8695  * @wmi_handle: wmi handle
8696  * @vdev_id: vdev id
8697  *
8698  * Return: QDF_STATUS_SUCCESS for success or error code
8699  */
8700 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle,
8701 			uint8_t vdev_id)
8702 {
8703 	wmi_csa_offload_enable_cmd_fixed_param *cmd;
8704 	wmi_buf_t buf;
8705 	int32_t len = sizeof(*cmd);
8706 
8707 	WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
8708 	buf = wmi_buf_alloc(wmi_handle, len);
8709 	if (!buf) {
8710 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
8711 		return QDF_STATUS_E_NOMEM;
8712 	}
8713 	cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf);
8714 	WMITLV_SET_HDR(&cmd->tlv_header,
8715 		       WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param,
8716 		       WMITLV_GET_STRUCT_TLVLEN
8717 			       (wmi_csa_offload_enable_cmd_fixed_param));
8718 	cmd->vdev_id = vdev_id;
8719 	cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE;
8720 	wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0);
8721 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8722 				 WMI_CSA_OFFLOAD_ENABLE_CMDID)) {
8723 		WMI_LOGP("%s: Failed to send CSA offload enable command",
8724 			 __func__);
8725 		wmi_buf_free(buf);
8726 		return QDF_STATUS_E_FAILURE;
8727 	}
8728 
8729 	return 0;
8730 }
8731 
8732 #ifdef WLAN_FEATURE_CIF_CFR
8733 /**
8734  * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings
8735  * @wmi_handle: wmi handle
8736  * @data_len: len of dma cfg req
8737  * @data: dma cfg req
8738  *
8739  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
8740  */
8741 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle,
8742 				wmi_oem_dma_ring_cfg_req_fixed_param *cfg)
8743 {
8744 	wmi_buf_t buf;
8745 	uint8_t *cmd;
8746 	QDF_STATUS ret;
8747 
8748 	WMITLV_SET_HDR(cfg,
8749 		WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param,
8750 		(sizeof(*cfg) - WMI_TLV_HDR_SIZE));
8751 
8752 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg));
8753 	if (!buf) {
8754 		WMI_LOGE(FL("wmi_buf_alloc failed"));
8755 		return QDF_STATUS_E_FAILURE;
8756 	}
8757 
8758 	cmd = (uint8_t *) wmi_buf_data(buf);
8759 	qdf_mem_copy(cmd, cfg, sizeof(*cfg));
8760 	WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"),
8761 		sizeof(*cfg));
8762 	wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0);
8763 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg),
8764 				WMI_OEM_DMA_RING_CFG_REQ_CMDID);
8765 	if (QDF_IS_STATUS_ERROR(ret)) {
8766 		WMI_LOGE(FL(":wmi cmd send failed"));
8767 		wmi_buf_free(buf);
8768 	}
8769 
8770 	return ret;
8771 }
8772 #endif
8773 
8774 /**
8775  * send_dbr_cfg_cmd_tlv() - configure DMA rings for Direct Buf RX
8776  * @wmi_handle: wmi handle
8777  * @data_len: len of dma cfg req
8778  * @data: dma cfg req
8779  *
8780  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
8781  */
8782 static QDF_STATUS send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle,
8783 				struct direct_buf_rx_cfg_req *cfg)
8784 {
8785 	wmi_buf_t buf;
8786 	wmi_dma_ring_cfg_req_fixed_param *cmd;
8787 	QDF_STATUS ret;
8788 	int32_t len = sizeof(*cmd);
8789 
8790 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
8791 	if (!buf) {
8792 		WMI_LOGE(FL("wmi_buf_alloc failed"));
8793 		return QDF_STATUS_E_FAILURE;
8794 	}
8795 
8796 	cmd = (wmi_dma_ring_cfg_req_fixed_param *)wmi_buf_data(buf);
8797 
8798 	WMITLV_SET_HDR(&cmd->tlv_header,
8799 		WMITLV_TAG_STRUC_wmi_dma_ring_cfg_req_fixed_param,
8800 		WMITLV_GET_STRUCT_TLVLEN(wmi_dma_ring_cfg_req_fixed_param));
8801 
8802 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
8803 						cfg->pdev_id);
8804 	cmd->mod_id = cfg->mod_id;
8805 	cmd->base_paddr_lo = cfg->base_paddr_lo;
8806 	cmd->base_paddr_hi = cfg->base_paddr_hi;
8807 	cmd->head_idx_paddr_lo = cfg->head_idx_paddr_lo;
8808 	cmd->head_idx_paddr_hi = cfg->head_idx_paddr_hi;
8809 	cmd->tail_idx_paddr_lo = cfg->tail_idx_paddr_lo;
8810 	cmd->tail_idx_paddr_hi = cfg->tail_idx_paddr_hi;
8811 	cmd->num_elems = cfg->num_elems;
8812 	cmd->buf_size = cfg->buf_size;
8813 	cmd->num_resp_per_event = cfg->num_resp_per_event;
8814 	cmd->event_timeout_ms = cfg->event_timeout_ms;
8815 
8816 	WMI_LOGD("%s: wmi_dma_ring_cfg_req_fixed_param pdev id %d mod id %d"
8817 		  "base paddr lo %x base paddr hi %x head idx paddr lo %x"
8818 		  "head idx paddr hi %x tail idx paddr lo %x"
8819 		  "tail idx addr hi %x num elems %d buf size %d num resp %d"
8820 		  "event timeout %d\n", __func__, cmd->pdev_id,
8821 		  cmd->mod_id, cmd->base_paddr_lo, cmd->base_paddr_hi,
8822 		  cmd->head_idx_paddr_lo, cmd->head_idx_paddr_hi,
8823 		  cmd->tail_idx_paddr_lo, cmd->tail_idx_paddr_hi,
8824 		  cmd->num_elems, cmd->buf_size, cmd->num_resp_per_event,
8825 		  cmd->event_timeout_ms);
8826 	wmi_mtrace(WMI_PDEV_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0);
8827 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8828 				WMI_PDEV_DMA_RING_CFG_REQ_CMDID);
8829 	if (QDF_IS_STATUS_ERROR(ret)) {
8830 		WMI_LOGE(FL(":wmi cmd send failed"));
8831 		wmi_buf_free(buf);
8832 	}
8833 
8834 	return ret;
8835 }
8836 
8837 /**
8838  * send_start_11d_scan_cmd_tlv() - start 11d scan request
8839  * @wmi_handle: wmi handle
8840  * @start_11d_scan: 11d scan start request parameters
8841  *
8842  * This function request FW to start 11d scan.
8843  *
8844  * Return: QDF status
8845  */
8846 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle,
8847 			  struct reg_start_11d_scan_req *start_11d_scan)
8848 {
8849 	wmi_11d_scan_start_cmd_fixed_param *cmd;
8850 	int32_t len;
8851 	wmi_buf_t buf;
8852 	int ret;
8853 
8854 	len = sizeof(*cmd);
8855 	buf = wmi_buf_alloc(wmi_handle, len);
8856 	if (!buf) {
8857 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8858 		return QDF_STATUS_E_NOMEM;
8859 	}
8860 
8861 	cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf);
8862 
8863 	WMITLV_SET_HDR(&cmd->tlv_header,
8864 		       WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param,
8865 		       WMITLV_GET_STRUCT_TLVLEN
8866 		       (wmi_11d_scan_start_cmd_fixed_param));
8867 
8868 	cmd->vdev_id = start_11d_scan->vdev_id;
8869 	cmd->scan_period_msec = start_11d_scan->scan_period_msec;
8870 	cmd->start_interval_msec = start_11d_scan->start_interval_msec;
8871 
8872 	WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id);
8873 
8874 	wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0);
8875 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8876 				   WMI_11D_SCAN_START_CMDID);
8877 	if (ret) {
8878 		WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__);
8879 		wmi_buf_free(buf);
8880 		return QDF_STATUS_E_FAILURE;
8881 	}
8882 
8883 	return QDF_STATUS_SUCCESS;
8884 }
8885 
8886 /**
8887  * send_stop_11d_scan_cmd_tlv() - stop 11d scan request
8888  * @wmi_handle: wmi handle
8889  * @start_11d_scan: 11d scan stop request parameters
8890  *
8891  * This function request FW to stop 11d scan.
8892  *
8893  * Return: QDF status
8894  */
8895 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle,
8896 			  struct reg_stop_11d_scan_req *stop_11d_scan)
8897 {
8898 	wmi_11d_scan_stop_cmd_fixed_param *cmd;
8899 	int32_t len;
8900 	wmi_buf_t buf;
8901 	int ret;
8902 
8903 	len = sizeof(*cmd);
8904 	buf = wmi_buf_alloc(wmi_handle, len);
8905 	if (!buf) {
8906 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8907 		return QDF_STATUS_E_NOMEM;
8908 	}
8909 
8910 	cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf);
8911 
8912 	WMITLV_SET_HDR(&cmd->tlv_header,
8913 		       WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param,
8914 		       WMITLV_GET_STRUCT_TLVLEN
8915 		       (wmi_11d_scan_stop_cmd_fixed_param));
8916 
8917 	cmd->vdev_id = stop_11d_scan->vdev_id;
8918 
8919 	WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id);
8920 
8921 	wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0);
8922 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8923 				   WMI_11D_SCAN_STOP_CMDID);
8924 	if (ret) {
8925 		WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__);
8926 		wmi_buf_free(buf);
8927 		return QDF_STATUS_E_FAILURE;
8928 	}
8929 
8930 	return QDF_STATUS_SUCCESS;
8931 }
8932 
8933 /**
8934  * send_start_oem_data_cmd_tlv() - start OEM data request to target
8935  * @wmi_handle: wmi handle
8936  * @startOemDataReq: start request params
8937  *
8938  * Return: CDF status
8939  */
8940 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle,
8941 			  uint32_t data_len,
8942 			  uint8_t *data)
8943 {
8944 	wmi_buf_t buf;
8945 	uint8_t *cmd;
8946 	QDF_STATUS ret;
8947 
8948 	buf = wmi_buf_alloc(wmi_handle,
8949 			    (data_len + WMI_TLV_HDR_SIZE));
8950 	if (!buf) {
8951 		WMI_LOGE(FL("wmi_buf_alloc failed"));
8952 		return QDF_STATUS_E_FAILURE;
8953 	}
8954 
8955 	cmd = (uint8_t *) wmi_buf_data(buf);
8956 
8957 	WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len);
8958 	cmd += WMI_TLV_HDR_SIZE;
8959 	qdf_mem_copy(cmd, data,
8960 		     data_len);
8961 
8962 	WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"),
8963 		 data_len);
8964 
8965 	wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0);
8966 	ret = wmi_unified_cmd_send(wmi_handle, buf,
8967 				   (data_len +
8968 				    WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID);
8969 
8970 	if (QDF_IS_STATUS_ERROR(ret)) {
8971 		WMI_LOGE(FL(":wmi cmd send failed"));
8972 		wmi_buf_free(buf);
8973 	}
8974 
8975 	return ret;
8976 }
8977 
8978 /**
8979  * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter
8980  * @wmi_handle: wmi handle
8981  * @dfs_phyerr_filter_offload: is dfs phyerr filter offload
8982  *
8983  * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or
8984  * WMI_DFS_PHYERR_FILTER_DIS_CMDID command
8985  * to firmware based on phyerr filtering
8986  * offload status.
8987  *
8988  * Return: 1 success, 0 failure
8989  */
8990 static QDF_STATUS
8991 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle,
8992 			bool dfs_phyerr_filter_offload)
8993 {
8994 	wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd;
8995 	wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd;
8996 	wmi_buf_t buf;
8997 	uint16_t len;
8998 	QDF_STATUS ret;
8999 
9000 
9001 	if (false == dfs_phyerr_filter_offload) {
9002 		WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini",
9003 			 __func__);
9004 		len = sizeof(*disable_phyerr_offload_cmd);
9005 		buf = wmi_buf_alloc(wmi_handle, len);
9006 		if (!buf) {
9007 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9008 			return 0;
9009 		}
9010 		disable_phyerr_offload_cmd =
9011 			(wmi_dfs_phyerr_filter_dis_cmd_fixed_param *)
9012 			wmi_buf_data(buf);
9013 
9014 		WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header,
9015 		     WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param,
9016 		     WMITLV_GET_STRUCT_TLVLEN
9017 		     (wmi_dfs_phyerr_filter_dis_cmd_fixed_param));
9018 
9019 		/*
9020 		 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID
9021 		 * to the firmware to disable the phyerror
9022 		 * filtering offload.
9023 		 */
9024 		wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0);
9025 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9026 					   WMI_DFS_PHYERR_FILTER_DIS_CMDID);
9027 		if (QDF_IS_STATUS_ERROR(ret)) {
9028 			WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d",
9029 				__func__, ret);
9030 			wmi_buf_free(buf);
9031 		return QDF_STATUS_E_FAILURE;
9032 		}
9033 		WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success",
9034 			 __func__);
9035 	} else {
9036 		WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini",
9037 			 __func__);
9038 
9039 		len = sizeof(*enable_phyerr_offload_cmd);
9040 		buf = wmi_buf_alloc(wmi_handle, len);
9041 		if (!buf) {
9042 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9043 		return QDF_STATUS_E_FAILURE;
9044 		}
9045 
9046 		enable_phyerr_offload_cmd =
9047 			(wmi_dfs_phyerr_filter_ena_cmd_fixed_param *)
9048 			wmi_buf_data(buf);
9049 
9050 		WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header,
9051 		     WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param,
9052 		     WMITLV_GET_STRUCT_TLVLEN
9053 		     (wmi_dfs_phyerr_filter_ena_cmd_fixed_param));
9054 
9055 		/*
9056 		 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID
9057 		 * to the firmware to enable the phyerror
9058 		 * filtering offload.
9059 		 */
9060 		wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0);
9061 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9062 					   WMI_DFS_PHYERR_FILTER_ENA_CMDID);
9063 
9064 		if (QDF_IS_STATUS_ERROR(ret)) {
9065 			WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d",
9066 				__func__, ret);
9067 			wmi_buf_free(buf);
9068 		return QDF_STATUS_E_FAILURE;
9069 		}
9070 		WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success",
9071 			 __func__);
9072 	}
9073 
9074 	return QDF_STATUS_SUCCESS;
9075 }
9076 
9077 /**
9078  * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware
9079  * will wake up host after specified time is elapsed
9080  * @wmi_handle: wmi handle
9081  * @vdev_id: vdev id
9082  * @cookie: value to identify reason why host set up wake call.
9083  * @time: time in ms
9084  *
9085  * Return: QDF status
9086  */
9087 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle,
9088 				uint8_t vdev_id, uint32_t cookie, uint32_t time)
9089 {
9090 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
9091 	wmi_buf_t buf;
9092 	uint8_t *buf_ptr;
9093 	int32_t len;
9094 	int ret;
9095 
9096 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
9097 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) +
9098 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
9099 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
9100 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
9101 		WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) +
9102 		WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
9103 
9104 	buf = wmi_buf_alloc(wmi_handle, len);
9105 	if (!buf) {
9106 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9107 		return QDF_STATUS_E_NOMEM;
9108 	}
9109 
9110 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
9111 	buf_ptr = (uint8_t *) cmd;
9112 
9113 	WMITLV_SET_HDR(&cmd->tlv_header,
9114 		WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
9115 		WMITLV_GET_STRUCT_TLVLEN
9116 			(WMI_WOW_ADD_PATTERN_CMD_fixed_param));
9117 	cmd->vdev_id = vdev_id;
9118 	cmd->pattern_id = cookie,
9119 	cmd->pattern_type = WOW_TIMER_PATTERN;
9120 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
9121 
9122 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
9123 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9124 	buf_ptr += WMI_TLV_HDR_SIZE;
9125 
9126 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
9127 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9128 	buf_ptr += WMI_TLV_HDR_SIZE;
9129 
9130 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
9131 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9132 	buf_ptr += WMI_TLV_HDR_SIZE;
9133 
9134 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
9135 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9136 	buf_ptr += WMI_TLV_HDR_SIZE;
9137 
9138 	/* Fill TLV for pattern_info_timeout, and time value */
9139 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
9140 	buf_ptr += WMI_TLV_HDR_SIZE;
9141 	*((uint32_t *) buf_ptr) = time;
9142 	buf_ptr += sizeof(uint32_t);
9143 
9144 	/* Fill TLV for ra_ratelimit_interval. with dummy 0 value */
9145 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
9146 	buf_ptr += WMI_TLV_HDR_SIZE;
9147 	*((uint32_t *) buf_ptr) = 0;
9148 
9149 	WMI_LOGD("%s: send wake timer pattern with time[%d] to fw vdev = %d",
9150 		__func__, time, vdev_id);
9151 
9152 	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
9153 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9154 				WMI_WOW_ADD_WAKE_PATTERN_CMDID);
9155 	if (ret) {
9156 		WMI_LOGE("%s: Failed to send wake timer pattern to fw",
9157 			__func__);
9158 		wmi_buf_free(buf);
9159 		return QDF_STATUS_E_FAILURE;
9160 	}
9161 
9162 	return QDF_STATUS_SUCCESS;
9163 }
9164 
9165 #if !defined(REMOVE_PKT_LOG)
9166 /**
9167  * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target
9168  * @wmi_handle: wmi handle
9169  * @pktlog_event: pktlog event
9170  * @cmd_id: pktlog cmd id
9171  *
9172  * Return: CDF status
9173  */
9174 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle,
9175 				   WMI_PKTLOG_EVENT pktlog_event,
9176 				   WMI_CMD_ID cmd_id, uint8_t user_triggered)
9177 {
9178 	WMI_PKTLOG_EVENT PKTLOG_EVENT;
9179 	WMI_CMD_ID CMD_ID;
9180 	wmi_pdev_pktlog_enable_cmd_fixed_param *cmd;
9181 	wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd;
9182 	int len = 0;
9183 	wmi_buf_t buf;
9184 
9185 	PKTLOG_EVENT = pktlog_event;
9186 	CMD_ID = cmd_id;
9187 
9188 	switch (CMD_ID) {
9189 	case WMI_PDEV_PKTLOG_ENABLE_CMDID:
9190 		len = sizeof(*cmd);
9191 		buf = wmi_buf_alloc(wmi_handle, len);
9192 		if (!buf) {
9193 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9194 			return QDF_STATUS_E_NOMEM;
9195 		}
9196 		cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *)
9197 			wmi_buf_data(buf);
9198 		WMITLV_SET_HDR(&cmd->tlv_header,
9199 		       WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param,
9200 		       WMITLV_GET_STRUCT_TLVLEN
9201 		       (wmi_pdev_pktlog_enable_cmd_fixed_param));
9202 		cmd->evlist = PKTLOG_EVENT;
9203 		cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE
9204 					: WMI_PKTLOG_ENABLE_AUTO;
9205 		cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
9206 							WMI_HOST_PDEV_ID_SOC);
9207 		wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0);
9208 		if (wmi_unified_cmd_send(wmi_handle, buf, len,
9209 					 WMI_PDEV_PKTLOG_ENABLE_CMDID)) {
9210 			WMI_LOGE("failed to send pktlog enable cmdid");
9211 			goto wmi_send_failed;
9212 		}
9213 		break;
9214 	case WMI_PDEV_PKTLOG_DISABLE_CMDID:
9215 		len = sizeof(*disable_cmd);
9216 		buf = wmi_buf_alloc(wmi_handle, len);
9217 		if (!buf) {
9218 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9219 			return QDF_STATUS_E_NOMEM;
9220 		}
9221 		disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *)
9222 			      wmi_buf_data(buf);
9223 		WMITLV_SET_HDR(&disable_cmd->tlv_header,
9224 		     WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param,
9225 		     WMITLV_GET_STRUCT_TLVLEN
9226 		     (wmi_pdev_pktlog_disable_cmd_fixed_param));
9227 		disable_cmd->pdev_id =
9228 			wmi_handle->ops->convert_pdev_id_host_to_target(
9229 							WMI_HOST_PDEV_ID_SOC);
9230 		wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0);
9231 		if (wmi_unified_cmd_send(wmi_handle, buf, len,
9232 					 WMI_PDEV_PKTLOG_DISABLE_CMDID)) {
9233 			WMI_LOGE("failed to send pktlog disable cmdid");
9234 			goto wmi_send_failed;
9235 		}
9236 		break;
9237 	default:
9238 		WMI_LOGD("%s: invalid PKTLOG command", __func__);
9239 		break;
9240 	}
9241 
9242 	return QDF_STATUS_SUCCESS;
9243 
9244 wmi_send_failed:
9245 	wmi_buf_free(buf);
9246 	return QDF_STATUS_E_FAILURE;
9247 }
9248 #endif /* REMOVE_PKT_LOG */
9249 
9250 /**
9251  * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target
9252  * @wmi_handle: wmi handle
9253  * @ptrn_id: pattern id
9254  * @vdev_id: vdev id
9255  *
9256  * Return: CDF status
9257  */
9258 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle,
9259 			uint8_t ptrn_id, uint8_t vdev_id)
9260 {
9261 	WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd;
9262 	wmi_buf_t buf;
9263 	int32_t len;
9264 	int ret;
9265 
9266 	len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param);
9267 
9268 
9269 	buf = wmi_buf_alloc(wmi_handle, len);
9270 	if (!buf) {
9271 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9272 		return QDF_STATUS_E_NOMEM;
9273 	}
9274 
9275 	cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
9276 
9277 	WMITLV_SET_HDR(&cmd->tlv_header,
9278 		       WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param,
9279 		       WMITLV_GET_STRUCT_TLVLEN(
9280 				WMI_WOW_DEL_PATTERN_CMD_fixed_param));
9281 	cmd->vdev_id = vdev_id;
9282 	cmd->pattern_id = ptrn_id;
9283 	cmd->pattern_type = WOW_BITMAP_PATTERN;
9284 
9285 	WMI_LOGI("Deleting pattern id: %d vdev id %d in fw",
9286 		cmd->pattern_id, vdev_id);
9287 
9288 	wmi_mtrace(WMI_WOW_DEL_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
9289 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9290 				   WMI_WOW_DEL_WAKE_PATTERN_CMDID);
9291 	if (ret) {
9292 		WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__);
9293 		wmi_buf_free(buf);
9294 		return QDF_STATUS_E_FAILURE;
9295 	}
9296 
9297 	return QDF_STATUS_SUCCESS;
9298 }
9299 
9300 /**
9301  * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw
9302  * @wmi_handle: wmi handle
9303  *
9304  * Sends host wakeup indication to FW. On receiving this indication,
9305  * FW will come out of WOW.
9306  *
9307  * Return: CDF status
9308  */
9309 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle)
9310 {
9311 	wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd;
9312 	wmi_buf_t buf;
9313 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
9314 	int32_t len;
9315 	int ret;
9316 
9317 	len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param);
9318 
9319 	buf = wmi_buf_alloc(wmi_handle, len);
9320 	if (!buf) {
9321 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9322 		return QDF_STATUS_E_NOMEM;
9323 	}
9324 
9325 	cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *)
9326 	      wmi_buf_data(buf);
9327 	WMITLV_SET_HDR(&cmd->tlv_header,
9328 		WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param,
9329 		WMITLV_GET_STRUCT_TLVLEN
9330 	       (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param));
9331 
9332 
9333 	wmi_mtrace(WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, NO_SESSION, 0);
9334 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9335 				   WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID);
9336 	if (ret) {
9337 		WMI_LOGE("Failed to send host wakeup indication to fw");
9338 		wmi_buf_free(buf);
9339 		return QDF_STATUS_E_FAILURE;
9340 	}
9341 
9342 	return qdf_status;
9343 }
9344 
9345 /**
9346  * send_del_ts_cmd_tlv() - send DELTS request to fw
9347  * @wmi_handle: wmi handle
9348  * @msg: delts params
9349  *
9350  * Return: CDF status
9351  */
9352 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
9353 				uint8_t ac)
9354 {
9355 	wmi_vdev_wmm_delts_cmd_fixed_param *cmd;
9356 	wmi_buf_t buf;
9357 	int32_t len = sizeof(*cmd);
9358 
9359 	buf = wmi_buf_alloc(wmi_handle, len);
9360 	if (!buf) {
9361 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9362 		return QDF_STATUS_E_NOMEM;
9363 	}
9364 	cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf);
9365 	WMITLV_SET_HDR(&cmd->tlv_header,
9366 		       WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param,
9367 		       WMITLV_GET_STRUCT_TLVLEN
9368 			       (wmi_vdev_wmm_delts_cmd_fixed_param));
9369 	cmd->vdev_id = vdev_id;
9370 	cmd->ac = ac;
9371 
9372 	WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d",
9373 		 cmd->vdev_id, cmd->ac, __func__, __LINE__);
9374 	wmi_mtrace(WMI_VDEV_WMM_DELTS_CMDID, cmd->vdev_id, 0);
9375 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
9376 				 WMI_VDEV_WMM_DELTS_CMDID)) {
9377 		WMI_LOGP("%s: Failed to send vdev DELTS command", __func__);
9378 		wmi_buf_free(buf);
9379 		return QDF_STATUS_E_FAILURE;
9380 	}
9381 
9382 	return QDF_STATUS_SUCCESS;
9383 }
9384 
9385 /**
9386  * send_aggr_qos_cmd_tlv() - send aggr qos request to fw
9387  * @wmi_handle: handle to wmi
9388  * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests.
9389  *
9390  * A function to handle WMI_AGGR_QOS_REQ. This will send out
9391  * ADD_TS requestes to firmware in loop for all the ACs with
9392  * active flow.
9393  *
9394  * Return: CDF status
9395  */
9396 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle,
9397 		      struct aggr_add_ts_param *aggr_qos_rsp_msg)
9398 {
9399 	int i = 0;
9400 	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
9401 	wmi_buf_t buf;
9402 	int32_t len = sizeof(*cmd);
9403 
9404 	for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) {
9405 		/* if flow in this AC is active */
9406 		if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) {
9407 			/*
9408 			 * as per implementation of wma_add_ts_req() we
9409 			 * are not waiting any response from firmware so
9410 			 * apart from sending ADDTS to firmware just send
9411 			 * success to upper layers
9412 			 */
9413 			aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS;
9414 
9415 			buf = wmi_buf_alloc(wmi_handle, len);
9416 			if (!buf) {
9417 				WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9418 				return QDF_STATUS_E_NOMEM;
9419 			}
9420 			cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *)
9421 				wmi_buf_data(buf);
9422 			WMITLV_SET_HDR(&cmd->tlv_header,
9423 			       WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
9424 			       WMITLV_GET_STRUCT_TLVLEN
9425 				       (wmi_vdev_wmm_addts_cmd_fixed_param));
9426 			cmd->vdev_id = aggr_qos_rsp_msg->vdev_id;
9427 			cmd->ac =
9428 				WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo.
9429 					      traffic.userPrio);
9430 			cmd->medium_time_us =
9431 				aggr_qos_rsp_msg->tspec[i].mediumTime * 32;
9432 			cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO;
9433 			WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d",
9434 				__func__, __LINE__, cmd->vdev_id, cmd->ac,
9435 				cmd->medium_time_us, cmd->downgrade_type);
9436 			wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
9437 			if (wmi_unified_cmd_send
9438 				    (wmi_handle, buf, len,
9439 				    WMI_VDEV_WMM_ADDTS_CMDID)) {
9440 				WMI_LOGP("%s: Failed to send vdev ADDTS command",
9441 					__func__);
9442 				aggr_qos_rsp_msg->status[i] =
9443 					QDF_STATUS_E_FAILURE;
9444 				wmi_buf_free(buf);
9445 				return QDF_STATUS_E_FAILURE;
9446 			}
9447 		}
9448 	}
9449 
9450 	return QDF_STATUS_SUCCESS;
9451 }
9452 
9453 /**
9454  * send_add_ts_cmd_tlv() - send ADDTS request to fw
9455  * @wmi_handle: wmi handle
9456  * @msg: ADDTS params
9457  *
9458  * Return: CDF status
9459  */
9460 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle,
9461 		 struct add_ts_param *msg)
9462 {
9463 	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
9464 	wmi_buf_t buf;
9465 	int32_t len = sizeof(*cmd);
9466 
9467 	msg->status = QDF_STATUS_SUCCESS;
9468 
9469 	buf = wmi_buf_alloc(wmi_handle, len);
9470 	if (!buf) {
9471 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9472 		return QDF_STATUS_E_NOMEM;
9473 	}
9474 	cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf);
9475 	WMITLV_SET_HDR(&cmd->tlv_header,
9476 		       WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
9477 		       WMITLV_GET_STRUCT_TLVLEN
9478 			       (wmi_vdev_wmm_addts_cmd_fixed_param));
9479 	cmd->vdev_id = msg->sme_session_id;
9480 	cmd->ac = msg->tspec.tsinfo.traffic.userPrio;
9481 	cmd->medium_time_us = msg->tspec.mediumTime * 32;
9482 	cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP;
9483 	WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d",
9484 		 cmd->vdev_id, cmd->ac, cmd->medium_time_us,
9485 		 cmd->downgrade_type, __func__, __LINE__);
9486 	wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
9487 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
9488 				 WMI_VDEV_WMM_ADDTS_CMDID)) {
9489 		WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__);
9490 		msg->status = QDF_STATUS_E_FAILURE;
9491 		wmi_buf_free(buf);
9492 		return QDF_STATUS_E_FAILURE;
9493 	}
9494 
9495 	return QDF_STATUS_SUCCESS;
9496 }
9497 
9498 /**
9499  * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn
9500  * @wmi_handle: wmi handle
9501  * @pAddPeriodicTxPtrnParams: tx ptrn params
9502  *
9503  * Retrun: CDF status
9504  */
9505 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
9506 						struct periodic_tx_pattern  *
9507 						pAddPeriodicTxPtrnParams,
9508 						uint8_t vdev_id)
9509 {
9510 	WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
9511 	wmi_buf_t wmi_buf;
9512 	uint32_t len;
9513 	uint8_t *buf_ptr;
9514 	uint32_t ptrn_len, ptrn_len_aligned;
9515 	int j;
9516 
9517 	ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize;
9518 	ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t));
9519 	len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) +
9520 	      WMI_TLV_HDR_SIZE + ptrn_len_aligned;
9521 
9522 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
9523 	if (!wmi_buf) {
9524 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
9525 		return QDF_STATUS_E_NOMEM;
9526 	}
9527 
9528 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
9529 
9530 	cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr;
9531 	WMITLV_SET_HDR(&cmd->tlv_header,
9532 	       WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
9533 	       WMITLV_GET_STRUCT_TLVLEN
9534 	       (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
9535 
9536 	/* Pass the pattern id to delete for the corresponding vdev id */
9537 	cmd->vdev_id = vdev_id;
9538 	cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId;
9539 	cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs;
9540 	cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize;
9541 
9542 	/* Pattern info */
9543 	buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
9544 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned);
9545 	buf_ptr += WMI_TLV_HDR_SIZE;
9546 	qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len);
9547 	for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++)
9548 		WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff);
9549 
9550 	WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d",
9551 		 __func__, cmd->pattern_id, cmd->vdev_id);
9552 
9553 	wmi_mtrace(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
9554 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
9555 				 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
9556 		WMI_LOGE("%s: failed to add pattern set state command",
9557 			 __func__);
9558 		wmi_buf_free(wmi_buf);
9559 		return QDF_STATUS_E_FAILURE;
9560 	}
9561 	return QDF_STATUS_SUCCESS;
9562 }
9563 
9564 /**
9565  * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn
9566  * @wmi_handle: wmi handle
9567  * @vdev_id: vdev id
9568  * @pattern_id: pattern id
9569  *
9570  * Retrun: CDF status
9571  */
9572 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
9573 						uint8_t vdev_id,
9574 						uint8_t pattern_id)
9575 {
9576 	WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
9577 	wmi_buf_t wmi_buf;
9578 	uint32_t len =
9579 		sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
9580 
9581 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
9582 	if (!wmi_buf) {
9583 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
9584 		return QDF_STATUS_E_NOMEM;
9585 	}
9586 
9587 	cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)
9588 		wmi_buf_data(wmi_buf);
9589 	WMITLV_SET_HDR(&cmd->tlv_header,
9590 	       WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
9591 	       WMITLV_GET_STRUCT_TLVLEN
9592 	       (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
9593 
9594 	/* Pass the pattern id to delete for the corresponding vdev id */
9595 	cmd->vdev_id = vdev_id;
9596 	cmd->pattern_id = pattern_id;
9597 	WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d",
9598 		 __func__, cmd->pattern_id, cmd->vdev_id);
9599 
9600 	wmi_mtrace(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
9601 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
9602 				 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
9603 		WMI_LOGE("%s: failed to send del pattern command", __func__);
9604 		wmi_buf_free(wmi_buf);
9605 		return QDF_STATUS_E_FAILURE;
9606 	}
9607 	return QDF_STATUS_SUCCESS;
9608 }
9609 
9610 /**
9611  * send_stats_ext_req_cmd_tlv() - request ext stats from fw
9612  * @wmi_handle: wmi handle
9613  * @preq: stats ext params
9614  *
9615  * Return: CDF status
9616  */
9617 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle,
9618 			struct stats_ext_params *preq)
9619 {
9620 	QDF_STATUS ret;
9621 	wmi_req_stats_ext_cmd_fixed_param *cmd;
9622 	wmi_buf_t buf;
9623 	size_t len;
9624 	uint8_t *buf_ptr;
9625 
9626 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len;
9627 
9628 	buf = wmi_buf_alloc(wmi_handle, len);
9629 	if (!buf) {
9630 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9631 		return QDF_STATUS_E_NOMEM;
9632 	}
9633 
9634 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
9635 	cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr;
9636 
9637 	WMITLV_SET_HDR(&cmd->tlv_header,
9638 		       WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param,
9639 		       WMITLV_GET_STRUCT_TLVLEN
9640 			       (wmi_req_stats_ext_cmd_fixed_param));
9641 	cmd->vdev_id = preq->vdev_id;
9642 	cmd->data_len = preq->request_data_len;
9643 
9644 	WMI_LOGD("%s: The data len value is %u and vdev id set is %u ",
9645 		 __func__, preq->request_data_len, preq->vdev_id);
9646 
9647 	buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param);
9648 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len);
9649 
9650 	buf_ptr += WMI_TLV_HDR_SIZE;
9651 	qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len);
9652 
9653 	wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0);
9654 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9655 				   WMI_REQUEST_STATS_EXT_CMDID);
9656 	if (QDF_IS_STATUS_ERROR(ret)) {
9657 		WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__,
9658 			 ret);
9659 		wmi_buf_free(buf);
9660 	}
9661 
9662 	return ret;
9663 }
9664 
9665 /**
9666  * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw
9667  * @wmi_handle: wmi handle
9668  * @params: ext wow params
9669  *
9670  * Return:0 for success or error code
9671  */
9672 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle,
9673 			struct ext_wow_params *params)
9674 {
9675 	wmi_extwow_enable_cmd_fixed_param *cmd;
9676 	wmi_buf_t buf;
9677 	int32_t len;
9678 	int ret;
9679 
9680 	len = sizeof(wmi_extwow_enable_cmd_fixed_param);
9681 	buf = wmi_buf_alloc(wmi_handle, len);
9682 	if (!buf) {
9683 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9684 		return QDF_STATUS_E_NOMEM;
9685 	}
9686 
9687 	cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf);
9688 
9689 	WMITLV_SET_HDR(&cmd->tlv_header,
9690 		       WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param,
9691 		       WMITLV_GET_STRUCT_TLVLEN
9692 			       (wmi_extwow_enable_cmd_fixed_param));
9693 
9694 	cmd->vdev_id = params->vdev_id;
9695 	cmd->type = params->type;
9696 	cmd->wakeup_pin_num = params->wakeup_pin_num;
9697 
9698 	WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x",
9699 		 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num);
9700 
9701 	wmi_mtrace(WMI_EXTWOW_ENABLE_CMDID, cmd->vdev_id, 0);
9702 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9703 				   WMI_EXTWOW_ENABLE_CMDID);
9704 	if (ret) {
9705 		WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__);
9706 		wmi_buf_free(buf);
9707 		return QDF_STATUS_E_FAILURE;
9708 	}
9709 
9710 	return QDF_STATUS_SUCCESS;
9711 
9712 }
9713 
9714 /**
9715  * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw
9716  * @wmi_handle: wmi handle
9717  * @app_type1_params: app type1 params
9718  *
9719  * Return: CDF status
9720  */
9721 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
9722 				   struct app_type1_params *app_type1_params)
9723 {
9724 	wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd;
9725 	wmi_buf_t buf;
9726 	int32_t len;
9727 	int ret;
9728 
9729 	len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param);
9730 	buf = wmi_buf_alloc(wmi_handle, len);
9731 	if (!buf) {
9732 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9733 		return QDF_STATUS_E_NOMEM;
9734 	}
9735 
9736 	cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *)
9737 	      wmi_buf_data(buf);
9738 
9739 	WMITLV_SET_HDR(&cmd->tlv_header,
9740 	       WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param,
9741 	       WMITLV_GET_STRUCT_TLVLEN
9742 	       (wmi_extwow_set_app_type1_params_cmd_fixed_param));
9743 
9744 	cmd->vdev_id = app_type1_params->vdev_id;
9745 	WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes,
9746 				   &cmd->wakee_mac);
9747 	qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8);
9748 	cmd->ident_len = app_type1_params->id_length;
9749 	qdf_mem_copy(cmd->passwd, app_type1_params->password, 16);
9750 	cmd->passwd_len = app_type1_params->pass_length;
9751 
9752 	WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM "
9753 		 "identification_id %.8s id_length %u "
9754 		 "password %.16s pass_length %u",
9755 		 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes,
9756 		 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len);
9757 
9758 	wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID, cmd->vdev_id, 0);
9759 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9760 				   WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID);
9761 	if (ret) {
9762 		WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__);
9763 		wmi_buf_free(buf);
9764 		return QDF_STATUS_E_FAILURE;
9765 	}
9766 
9767 	return QDF_STATUS_SUCCESS;
9768 }
9769 
9770 /**
9771  * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw
9772  * @wmi_handle: wmi handle
9773  * @appType2Params: app type2 params
9774  *
9775  * Return: CDF status
9776  */
9777 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
9778 			  struct app_type2_params *appType2Params)
9779 {
9780 	wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd;
9781 	wmi_buf_t buf;
9782 	int32_t len;
9783 	int ret;
9784 
9785 	len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param);
9786 	buf = wmi_buf_alloc(wmi_handle, len);
9787 	if (!buf) {
9788 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9789 		return QDF_STATUS_E_NOMEM;
9790 	}
9791 
9792 	cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *)
9793 	      wmi_buf_data(buf);
9794 
9795 	WMITLV_SET_HDR(&cmd->tlv_header,
9796 	       WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param,
9797 	       WMITLV_GET_STRUCT_TLVLEN
9798 	       (wmi_extwow_set_app_type2_params_cmd_fixed_param));
9799 
9800 	cmd->vdev_id = appType2Params->vdev_id;
9801 
9802 	qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16);
9803 	cmd->rc4_key_len = appType2Params->rc4_key_len;
9804 
9805 	cmd->ip_id = appType2Params->ip_id;
9806 	cmd->ip_device_ip = appType2Params->ip_device_ip;
9807 	cmd->ip_server_ip = appType2Params->ip_server_ip;
9808 
9809 	cmd->tcp_src_port = appType2Params->tcp_src_port;
9810 	cmd->tcp_dst_port = appType2Params->tcp_dst_port;
9811 	cmd->tcp_seq = appType2Params->tcp_seq;
9812 	cmd->tcp_ack_seq = appType2Params->tcp_ack_seq;
9813 
9814 	cmd->keepalive_init = appType2Params->keepalive_init;
9815 	cmd->keepalive_min = appType2Params->keepalive_min;
9816 	cmd->keepalive_max = appType2Params->keepalive_max;
9817 	cmd->keepalive_inc = appType2Params->keepalive_inc;
9818 
9819 	WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes,
9820 				   &cmd->gateway_mac);
9821 	cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val;
9822 	cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val;
9823 
9824 	WMI_LOGD("%s: vdev_id %d gateway_mac %pM "
9825 		 "rc4_key %.16s rc4_key_len %u "
9826 		 "ip_id %x ip_device_ip %x ip_server_ip %x "
9827 		 "tcp_src_port %u tcp_dst_port %u tcp_seq %u "
9828 		 "tcp_ack_seq %u keepalive_init %u keepalive_min %u "
9829 		 "keepalive_max %u keepalive_inc %u "
9830 		 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u",
9831 		 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes,
9832 		 cmd->rc4_key, cmd->rc4_key_len,
9833 		 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip,
9834 		 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq,
9835 		 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min,
9836 		 cmd->keepalive_max, cmd->keepalive_inc,
9837 		 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val);
9838 
9839 	wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID, cmd->vdev_id, 0);
9840 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9841 				   WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID);
9842 	if (ret) {
9843 		WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__);
9844 		wmi_buf_free(buf);
9845 		return QDF_STATUS_E_FAILURE;
9846 	}
9847 
9848 	return QDF_STATUS_SUCCESS;
9849 
9850 }
9851 
9852 /**
9853  * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware
9854  * @wmi_handle: wmi handle
9855  * @timer_val: auto shutdown timer value
9856  *
9857  * Return: CDF status
9858  */
9859 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle,
9860 						  uint32_t timer_val)
9861 {
9862 	QDF_STATUS status;
9863 	wmi_buf_t buf = NULL;
9864 	uint8_t *buf_ptr;
9865 	wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd;
9866 	int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param);
9867 
9868 	WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d",
9869 		 __func__, timer_val);
9870 
9871 	buf = wmi_buf_alloc(wmi_handle, len);
9872 	if (!buf) {
9873 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
9874 		return QDF_STATUS_E_NOMEM;
9875 	}
9876 
9877 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
9878 	wmi_auto_sh_cmd =
9879 		(wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr;
9880 	wmi_auto_sh_cmd->timer_value = timer_val;
9881 
9882 	WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header,
9883 	       WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param,
9884 	       WMITLV_GET_STRUCT_TLVLEN
9885 	       (wmi_host_auto_shutdown_cfg_cmd_fixed_param));
9886 
9887 	wmi_mtrace(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID, NO_SESSION, 0);
9888 	status = wmi_unified_cmd_send(wmi_handle, buf,
9889 				      len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID);
9890 	if (QDF_IS_STATUS_ERROR(status)) {
9891 		WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d",
9892 			 __func__, status);
9893 		wmi_buf_free(buf);
9894 	}
9895 
9896 	return status;
9897 }
9898 
9899 /**
9900  * send_nan_req_cmd_tlv() - to send nan request to target
9901  * @wmi_handle: wmi handle
9902  * @nan_req: request data which will be non-null
9903  *
9904  * Return: CDF status
9905  */
9906 static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle,
9907 			struct nan_req_params *nan_req)
9908 {
9909 	QDF_STATUS ret;
9910 	wmi_nan_cmd_param *cmd;
9911 	wmi_buf_t buf;
9912 	uint16_t len = sizeof(*cmd);
9913 	uint16_t nan_data_len, nan_data_len_aligned;
9914 	uint8_t *buf_ptr;
9915 
9916 	/*
9917 	 *    <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ---->
9918 	 *    +------------+----------+-----------------------+--------------+
9919 	 *    | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data |
9920 	 *    +------------+----------+-----------------------+--------------+
9921 	 */
9922 	if (!nan_req) {
9923 		WMI_LOGE("%s:nan req is not valid", __func__);
9924 		return QDF_STATUS_E_FAILURE;
9925 	}
9926 	nan_data_len = nan_req->request_data_len;
9927 	nan_data_len_aligned = roundup(nan_req->request_data_len,
9928 				       sizeof(uint32_t));
9929 	if (nan_data_len_aligned < nan_req->request_data_len) {
9930 		WMI_LOGE("%s: integer overflow while rounding up data_len",
9931 			 __func__);
9932 		return QDF_STATUS_E_FAILURE;
9933 	}
9934 
9935 	if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) {
9936 		WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen",
9937 			 __func__);
9938 		return QDF_STATUS_E_FAILURE;
9939 	}
9940 
9941 	len += WMI_TLV_HDR_SIZE + nan_data_len_aligned;
9942 	buf = wmi_buf_alloc(wmi_handle, len);
9943 	if (!buf) {
9944 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9945 		return QDF_STATUS_E_NOMEM;
9946 	}
9947 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
9948 	cmd = (wmi_nan_cmd_param *) buf_ptr;
9949 	WMITLV_SET_HDR(&cmd->tlv_header,
9950 		       WMITLV_TAG_STRUC_wmi_nan_cmd_param,
9951 		       WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param));
9952 	cmd->data_len = nan_req->request_data_len;
9953 	WMI_LOGD("%s: The data len value is %u",
9954 		 __func__, nan_req->request_data_len);
9955 	buf_ptr += sizeof(wmi_nan_cmd_param);
9956 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned);
9957 	buf_ptr += WMI_TLV_HDR_SIZE;
9958 	qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len);
9959 
9960 	wmi_mtrace(WMI_NAN_CMDID, NO_SESSION, 0);
9961 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9962 				   WMI_NAN_CMDID);
9963 	if (QDF_IS_STATUS_ERROR(ret)) {
9964 		WMI_LOGE("%s Failed to send set param command ret = %d",
9965 			 __func__, ret);
9966 		wmi_buf_free(buf);
9967 	}
9968 
9969 	return ret;
9970 }
9971 
9972 /**
9973  * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload
9974  * @wmi_handle: wmi handle
9975  * @params: DHCP server offload info
9976  *
9977  * Return: QDF_STATUS_SUCCESS for success or error code
9978  */
9979 static QDF_STATUS
9980 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle,
9981 					struct dhcp_offload_info_params *params)
9982 {
9983 	wmi_set_dhcp_server_offload_cmd_fixed_param *cmd;
9984 	wmi_buf_t buf;
9985 	QDF_STATUS status;
9986 
9987 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
9988 	if (!buf) {
9989 		WMI_LOGE("Failed to allocate buffer to send "
9990 			 "set_dhcp_server_offload cmd");
9991 		return QDF_STATUS_E_NOMEM;
9992 	}
9993 
9994 	cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf);
9995 
9996 	WMITLV_SET_HDR(&cmd->tlv_header,
9997 	       WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param,
9998 	       WMITLV_GET_STRUCT_TLVLEN
9999 	       (wmi_set_dhcp_server_offload_cmd_fixed_param));
10000 	cmd->vdev_id = params->vdev_id;
10001 	cmd->enable = params->dhcp_offload_enabled;
10002 	cmd->num_client = params->dhcp_client_num;
10003 	cmd->srv_ipv4 = params->dhcp_srv_addr;
10004 	cmd->start_lsb = 0;
10005 	wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0);
10006 	status = wmi_unified_cmd_send(wmi_handle, buf,
10007 				   sizeof(*cmd),
10008 				   WMI_SET_DHCP_SERVER_OFFLOAD_CMDID);
10009 	if (QDF_IS_STATUS_ERROR(status)) {
10010 		WMI_LOGE("Failed to send set_dhcp_server_offload cmd");
10011 		wmi_buf_free(buf);
10012 		return QDF_STATUS_E_FAILURE;
10013 	}
10014 	WMI_LOGD("Set dhcp server offload to vdevId %d",
10015 		 params->vdev_id);
10016 
10017 	return status;
10018 }
10019 
10020 /**
10021  * send_set_led_flashing_cmd_tlv() - set led flashing in fw
10022  * @wmi_handle: wmi handle
10023  * @flashing: flashing request
10024  *
10025  * Return: CDF status
10026  */
10027 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle,
10028 				struct flashing_req_params *flashing)
10029 {
10030 	wmi_set_led_flashing_cmd_fixed_param *cmd;
10031 	QDF_STATUS status;
10032 	wmi_buf_t buf;
10033 	uint8_t *buf_ptr;
10034 	int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param);
10035 
10036 	buf = wmi_buf_alloc(wmi_handle, len);
10037 	if (!buf) {
10038 		WMI_LOGP(FL("wmi_buf_alloc failed"));
10039 		return QDF_STATUS_E_NOMEM;
10040 	}
10041 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
10042 	cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr;
10043 	WMITLV_SET_HDR(&cmd->tlv_header,
10044 		       WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param,
10045 		       WMITLV_GET_STRUCT_TLVLEN
10046 			       (wmi_set_led_flashing_cmd_fixed_param));
10047 	cmd->pattern_id = flashing->pattern_id;
10048 	cmd->led_x0 = flashing->led_x0;
10049 	cmd->led_x1 = flashing->led_x1;
10050 
10051 	wmi_mtrace(WMI_PDEV_SET_LED_FLASHING_CMDID, NO_SESSION, 0);
10052 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
10053 				      WMI_PDEV_SET_LED_FLASHING_CMDID);
10054 	if (QDF_IS_STATUS_ERROR(status)) {
10055 		WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
10056 			 " returned Error %d", __func__, status);
10057 		wmi_buf_free(buf);
10058 	}
10059 
10060 	return status;
10061 }
10062 
10063 /**
10064  * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request
10065  * @wmi_handle: wmi handle
10066  * @ch_avoid_update_req: channel avoid update params
10067  *
10068  * Return: CDF status
10069  */
10070 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle)
10071 {
10072 	QDF_STATUS status;
10073 	wmi_buf_t buf = NULL;
10074 	uint8_t *buf_ptr;
10075 	wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp;
10076 	int len = sizeof(wmi_chan_avoid_update_cmd_param);
10077 
10078 
10079 	buf = wmi_buf_alloc(wmi_handle, len);
10080 	if (!buf) {
10081 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
10082 		return QDF_STATUS_E_NOMEM;
10083 	}
10084 
10085 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
10086 	ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr;
10087 	WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header,
10088 		       WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param,
10089 		       WMITLV_GET_STRUCT_TLVLEN
10090 			       (wmi_chan_avoid_update_cmd_param));
10091 
10092 	wmi_mtrace(WMI_CHAN_AVOID_UPDATE_CMDID, NO_SESSION, 0);
10093 	status = wmi_unified_cmd_send(wmi_handle, buf,
10094 				      len, WMI_CHAN_AVOID_UPDATE_CMDID);
10095 	if (QDF_IS_STATUS_ERROR(status)) {
10096 		WMI_LOGE("wmi_unified_cmd_send"
10097 			 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE"
10098 			 " returned Error %d", status);
10099 		wmi_buf_free(buf);
10100 	}
10101 
10102 	return status;
10103 }
10104 
10105 /**
10106  * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw
10107  * @wmi_handle: wmi handle
10108  * @param: pointer to pdev regdomain params
10109  *
10110  * Return: 0 for success or error code
10111  */
10112 static QDF_STATUS
10113 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle,
10114 				struct pdev_set_regdomain_params *param)
10115 {
10116 	wmi_buf_t buf;
10117 	wmi_pdev_set_regdomain_cmd_fixed_param *cmd;
10118 	int32_t len = sizeof(*cmd);
10119 
10120 
10121 	buf = wmi_buf_alloc(wmi_handle, len);
10122 	if (!buf) {
10123 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
10124 		return QDF_STATUS_E_NOMEM;
10125 	}
10126 	cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf);
10127 	WMITLV_SET_HDR(&cmd->tlv_header,
10128 		       WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param,
10129 		       WMITLV_GET_STRUCT_TLVLEN
10130 			       (wmi_pdev_set_regdomain_cmd_fixed_param));
10131 
10132 	cmd->reg_domain = param->currentRDinuse;
10133 	cmd->reg_domain_2G = param->currentRD2G;
10134 	cmd->reg_domain_5G = param->currentRD5G;
10135 	cmd->conformance_test_limit_2G = param->ctl_2G;
10136 	cmd->conformance_test_limit_5G = param->ctl_5G;
10137 	cmd->dfs_domain = param->dfsDomain;
10138 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10139 							param->pdev_id);
10140 
10141 	wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0);
10142 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10143 				 WMI_PDEV_SET_REGDOMAIN_CMDID)) {
10144 		WMI_LOGE("%s: Failed to send pdev set regdomain command",
10145 			 __func__);
10146 		wmi_buf_free(buf);
10147 		return QDF_STATUS_E_FAILURE;
10148 	}
10149 
10150 	return QDF_STATUS_SUCCESS;
10151 }
10152 
10153 /**
10154  * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw
10155  * @wmi_handle: wmi handle
10156  * @reg_dmn: reg domain
10157  * @regdmn2G: 2G reg domain
10158  * @regdmn5G: 5G reg domain
10159  * @ctl2G: 2G test limit
10160  * @ctl5G: 5G test limit
10161  *
10162  * Return: none
10163  */
10164 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle,
10165 				   uint32_t reg_dmn, uint16_t regdmn2G,
10166 				   uint16_t regdmn5G, uint8_t ctl2G,
10167 				   uint8_t ctl5G)
10168 {
10169 	wmi_buf_t buf;
10170 	wmi_pdev_set_regdomain_cmd_fixed_param *cmd;
10171 	int32_t len = sizeof(*cmd);
10172 
10173 
10174 	buf = wmi_buf_alloc(wmi_handle, len);
10175 	if (!buf) {
10176 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
10177 		return QDF_STATUS_E_NOMEM;
10178 	}
10179 	cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf);
10180 	WMITLV_SET_HDR(&cmd->tlv_header,
10181 		       WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param,
10182 		       WMITLV_GET_STRUCT_TLVLEN
10183 			       (wmi_pdev_set_regdomain_cmd_fixed_param));
10184 	cmd->reg_domain = reg_dmn;
10185 	cmd->reg_domain_2G = regdmn2G;
10186 	cmd->reg_domain_5G = regdmn5G;
10187 	cmd->conformance_test_limit_2G = ctl2G;
10188 	cmd->conformance_test_limit_5G = ctl5G;
10189 
10190 	wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0);
10191 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10192 				 WMI_PDEV_SET_REGDOMAIN_CMDID)) {
10193 		WMI_LOGP("%s: Failed to send pdev set regdomain command",
10194 			 __func__);
10195 		wmi_buf_free(buf);
10196 		return QDF_STATUS_E_FAILURE;
10197 	}
10198 
10199 	return QDF_STATUS_SUCCESS;
10200 }
10201 
10202 
10203 /**
10204  * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode
10205  * @wmi_handle: wmi handle
10206  * @chan_switch_params: Pointer to tdls channel switch parameter structure
10207  *
10208  * This function sets tdls off channel mode
10209  *
10210  * Return: 0 on success; Negative errno otherwise
10211  */
10212 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle,
10213 	      struct tdls_channel_switch_params *chan_switch_params)
10214 {
10215 	wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd;
10216 	wmi_buf_t wmi_buf;
10217 	u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param);
10218 
10219 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10220 	if (!wmi_buf) {
10221 		WMI_LOGE(FL("wmi_buf_alloc failed"));
10222 		return QDF_STATUS_E_FAILURE;
10223 	}
10224 	cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *)
10225 		wmi_buf_data(wmi_buf);
10226 	WMITLV_SET_HDR(&cmd->tlv_header,
10227 		WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param,
10228 		WMITLV_GET_STRUCT_TLVLEN(
10229 			wmi_tdls_set_offchan_mode_cmd_fixed_param));
10230 
10231 	WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr,
10232 				&cmd->peer_macaddr);
10233 	cmd->vdev_id = chan_switch_params->vdev_id;
10234 	cmd->offchan_mode = chan_switch_params->tdls_sw_mode;
10235 	cmd->is_peer_responder = chan_switch_params->is_responder;
10236 	cmd->offchan_num = chan_switch_params->tdls_off_ch;
10237 	cmd->offchan_bw_bitmap = chan_switch_params->tdls_off_ch_bw_offset;
10238 	cmd->offchan_oper_class = chan_switch_params->oper_class;
10239 
10240 	WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"),
10241 		 cmd->peer_macaddr.mac_addr31to0,
10242 		 cmd->peer_macaddr.mac_addr47to32);
10243 
10244 	WMI_LOGD(FL(
10245 		 "vdev_id: %d, off channel mode: %d, off channel Num: %d, "
10246 		 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d"
10247 		  ),
10248 		 cmd->vdev_id,
10249 		 cmd->offchan_mode,
10250 		 cmd->offchan_num,
10251 		 cmd->offchan_bw_bitmap,
10252 		 cmd->is_peer_responder,
10253 		 cmd->offchan_oper_class);
10254 
10255 	wmi_mtrace(WMI_TDLS_SET_OFFCHAN_MODE_CMDID, cmd->vdev_id, 0);
10256 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10257 		WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) {
10258 		WMI_LOGP(FL("failed to send tdls off chan command"));
10259 		wmi_buf_free(wmi_buf);
10260 		return QDF_STATUS_E_FAILURE;
10261 	}
10262 
10263 
10264 	return QDF_STATUS_SUCCESS;
10265 }
10266 
10267 /**
10268  * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev
10269  * @wmi_handle: wmi handle
10270  * @pwmaTdlsparams: TDLS params
10271  *
10272  * Return: 0 for success or error code
10273  */
10274 static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle,
10275 					 void *tdls_param, uint8_t tdls_state)
10276 {
10277 	wmi_tdls_set_state_cmd_fixed_param *cmd;
10278 	wmi_buf_t wmi_buf;
10279 
10280 	struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param;
10281 	uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param);
10282 
10283 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10284 	if (!wmi_buf) {
10285 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
10286 		return QDF_STATUS_E_FAILURE;
10287 	}
10288 	cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf);
10289 	WMITLV_SET_HDR(&cmd->tlv_header,
10290 		  WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param,
10291 		  WMITLV_GET_STRUCT_TLVLEN
10292 		  (wmi_tdls_set_state_cmd_fixed_param));
10293 	cmd->vdev_id = wmi_tdls->vdev_id;
10294 	cmd->state = tdls_state;
10295 	cmd->notification_interval_ms = wmi_tdls->notification_interval_ms;
10296 	cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold;
10297 	cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold;
10298 	cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold;
10299 	cmd->rssi_delta = wmi_tdls->rssi_delta;
10300 	cmd->tdls_options = wmi_tdls->tdls_options;
10301 	cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window;
10302 	cmd->tdls_peer_traffic_response_timeout_ms =
10303 		wmi_tdls->peer_traffic_response_timeout;
10304 	cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask;
10305 	cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time;
10306 	cmd->tdls_puapsd_rx_frame_threshold =
10307 		wmi_tdls->puapsd_rx_frame_threshold;
10308 	cmd->teardown_notification_ms =
10309 		wmi_tdls->teardown_notification_ms;
10310 	cmd->tdls_peer_kickout_threshold =
10311 		wmi_tdls->tdls_peer_kickout_threshold;
10312 
10313 	WMI_LOGD("%s: tdls_state: %d, state: %d, "
10314 		 "notification_interval_ms: %d, "
10315 		 "tx_discovery_threshold: %d, "
10316 		 "tx_teardown_threshold: %d, "
10317 		 "rssi_teardown_threshold: %d, "
10318 		 "rssi_delta: %d, "
10319 		 "tdls_options: 0x%x, "
10320 		 "tdls_peer_traffic_ind_window: %d, "
10321 		 "tdls_peer_traffic_response_timeout: %d, "
10322 		 "tdls_puapsd_mask: 0x%x, "
10323 		 "tdls_puapsd_inactivity_time: %d, "
10324 		 "tdls_puapsd_rx_frame_threshold: %d, "
10325 		 "teardown_notification_ms: %d, "
10326 		 "tdls_peer_kickout_threshold: %d",
10327 		 __func__, tdls_state, cmd->state,
10328 		 cmd->notification_interval_ms,
10329 		 cmd->tx_discovery_threshold,
10330 		 cmd->tx_teardown_threshold,
10331 		 cmd->rssi_teardown_threshold,
10332 		 cmd->rssi_delta,
10333 		 cmd->tdls_options,
10334 		 cmd->tdls_peer_traffic_ind_window,
10335 		 cmd->tdls_peer_traffic_response_timeout_ms,
10336 		 cmd->tdls_puapsd_mask,
10337 		 cmd->tdls_puapsd_inactivity_time_ms,
10338 		 cmd->tdls_puapsd_rx_frame_threshold,
10339 		 cmd->teardown_notification_ms,
10340 		 cmd->tdls_peer_kickout_threshold);
10341 
10342 	wmi_mtrace(WMI_TDLS_SET_STATE_CMDID, cmd->vdev_id, 0);
10343 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10344 				 WMI_TDLS_SET_STATE_CMDID)) {
10345 		WMI_LOGP("%s: failed to send tdls set state command", __func__);
10346 		wmi_buf_free(wmi_buf);
10347 		return QDF_STATUS_E_FAILURE;
10348 	}
10349 	WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id);
10350 
10351 	return QDF_STATUS_SUCCESS;
10352 }
10353 
10354 /**
10355  * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state
10356  * @wmi_handle: wmi handle
10357  * @peerStateParams: TDLS peer state params
10358  *
10359  * Return: QDF_STATUS_SUCCESS for success or error code
10360  */
10361 static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle,
10362 			       struct tdls_peer_state_params *peerStateParams,
10363 				   uint32_t *ch_mhz)
10364 {
10365 	wmi_tdls_peer_update_cmd_fixed_param *cmd;
10366 	wmi_tdls_peer_capabilities *peer_cap;
10367 	wmi_channel *chan_info;
10368 	wmi_buf_t wmi_buf;
10369 	uint8_t *buf_ptr;
10370 	uint32_t i;
10371 	int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) +
10372 		      sizeof(wmi_tdls_peer_capabilities);
10373 
10374 
10375 	len += WMI_TLV_HDR_SIZE +
10376 	       sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen;
10377 
10378 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10379 	if (!wmi_buf) {
10380 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
10381 		return QDF_STATUS_E_FAILURE;
10382 	}
10383 
10384 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
10385 	cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr;
10386 	WMITLV_SET_HDR(&cmd->tlv_header,
10387 		       WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param,
10388 		       WMITLV_GET_STRUCT_TLVLEN
10389 			       (wmi_tdls_peer_update_cmd_fixed_param));
10390 
10391 	cmd->vdev_id = peerStateParams->vdevId;
10392 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr,
10393 				   &cmd->peer_macaddr);
10394 
10395 
10396 	cmd->peer_state = peerStateParams->peerState;
10397 
10398 	WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, "
10399 		 "peer_macaddr.mac_addr31to0: 0x%x, "
10400 		 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d",
10401 		 __func__, cmd->vdev_id, peerStateParams->peerMacAddr,
10402 		 cmd->peer_macaddr.mac_addr31to0,
10403 		 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state);
10404 
10405 	buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param);
10406 	peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr;
10407 	WMITLV_SET_HDR(&peer_cap->tlv_header,
10408 		       WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities,
10409 		       WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities));
10410 
10411 	if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3)
10412 		WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap);
10413 	if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2)
10414 		WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap);
10415 	if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1)
10416 		WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap);
10417 	if (peerStateParams->peerCap.peerUapsdQueue & 0x01)
10418 		WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap);
10419 
10420 	/* Ack and More Data Ack are sent as 0, so no need to set
10421 	 * but fill SP
10422 	 */
10423 	WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap,
10424 				   peerStateParams->peerCap.peerMaxSp);
10425 
10426 	peer_cap->buff_sta_support =
10427 		peerStateParams->peerCap.peerBuffStaSupport;
10428 	peer_cap->off_chan_support =
10429 		peerStateParams->peerCap.peerOffChanSupport;
10430 	peer_cap->peer_curr_operclass =
10431 		peerStateParams->peerCap.peerCurrOperClass;
10432 	/* self curr operclass is not being used and so pass op class for
10433 	 * preferred off chan in it.
10434 	 */
10435 	peer_cap->self_curr_operclass =
10436 		peerStateParams->peerCap.opClassForPrefOffChan;
10437 	peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen;
10438 	peer_cap->peer_operclass_len =
10439 		peerStateParams->peerCap.peerOperClassLen;
10440 
10441 	WMI_LOGD("%s: peer_operclass_len: %d",
10442 		 __func__, peer_cap->peer_operclass_len);
10443 	for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) {
10444 		peer_cap->peer_operclass[i] =
10445 			peerStateParams->peerCap.peerOperClass[i];
10446 		WMI_LOGD("%s: peer_operclass[%d]: %d",
10447 			 __func__, i, peer_cap->peer_operclass[i]);
10448 	}
10449 
10450 	peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder;
10451 	peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum;
10452 	peer_cap->pref_offchan_bw =
10453 		peerStateParams->peerCap.prefOffChanBandwidth;
10454 
10455 	WMI_LOGD
10456 		("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, "
10457 		 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: "
10458 		 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:"
10459 		 " %d, pref_offchan_bw: %d",
10460 		__func__, peer_cap->peer_qos, peer_cap->buff_sta_support,
10461 		peer_cap->off_chan_support, peer_cap->peer_curr_operclass,
10462 		peer_cap->self_curr_operclass, peer_cap->peer_chan_len,
10463 		peer_cap->peer_operclass_len, peer_cap->is_peer_responder,
10464 		peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw);
10465 
10466 	/* next fill variable size array of peer chan info */
10467 	buf_ptr += sizeof(wmi_tdls_peer_capabilities);
10468 	WMITLV_SET_HDR(buf_ptr,
10469 		       WMITLV_TAG_ARRAY_STRUC,
10470 		       sizeof(wmi_channel) *
10471 		       peerStateParams->peerCap.peerChanLen);
10472 	chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE);
10473 
10474 	for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) {
10475 		WMITLV_SET_HDR(&chan_info->tlv_header,
10476 			       WMITLV_TAG_STRUC_wmi_channel,
10477 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
10478 		chan_info->mhz = ch_mhz[i];
10479 		chan_info->band_center_freq1 = chan_info->mhz;
10480 		chan_info->band_center_freq2 = 0;
10481 
10482 		WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz);
10483 
10484 		if (peerStateParams->peerCap.peerChan[i].dfsSet) {
10485 			WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE);
10486 			WMI_LOGI("chan[%d] DFS[%d]\n",
10487 				 peerStateParams->peerCap.peerChan[i].chanId,
10488 				 peerStateParams->peerCap.peerChan[i].dfsSet);
10489 		}
10490 
10491 		if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ)
10492 			WMI_SET_CHANNEL_MODE(chan_info, MODE_11G);
10493 		else
10494 			WMI_SET_CHANNEL_MODE(chan_info, MODE_11A);
10495 
10496 		WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
10497 					     peerStateParams->peerCap.
10498 					     peerChan[i].pwr);
10499 
10500 		WMI_SET_CHANNEL_REG_POWER(chan_info,
10501 					  peerStateParams->peerCap.peerChan[i].
10502 					  pwr);
10503 		WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz,
10504 			 peerStateParams->peerCap.peerChan[i].pwr);
10505 
10506 		chan_info++;
10507 	}
10508 
10509 	wmi_mtrace(WMI_TDLS_PEER_UPDATE_CMDID, cmd->vdev_id, 0);
10510 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10511 				 WMI_TDLS_PEER_UPDATE_CMDID)) {
10512 		WMI_LOGE("%s: failed to send tdls peer update state command",
10513 			 __func__);
10514 		wmi_buf_free(wmi_buf);
10515 		return QDF_STATUS_E_FAILURE;
10516 	}
10517 
10518 
10519 	return QDF_STATUS_SUCCESS;
10520 }
10521 
10522 /*
10523  * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware
10524  * @wmi_handle:    Pointer to WMi handle
10525  * @ie_data:       Pointer for ie data
10526  *
10527  * This function sends IE information to firmware
10528  *
10529  * Return: QDF_STATUS_SUCCESS for success otherwise failure
10530  *
10531  */
10532 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle,
10533 				   struct vdev_ie_info_param *ie_info)
10534 {
10535 	wmi_vdev_set_ie_cmd_fixed_param *cmd;
10536 	wmi_buf_t buf;
10537 	uint8_t *buf_ptr;
10538 	uint32_t len, ie_len_aligned;
10539 	QDF_STATUS ret;
10540 
10541 
10542 	ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t));
10543 	/* Allocate memory for the WMI command */
10544 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned;
10545 
10546 	buf = wmi_buf_alloc(wmi_handle, len);
10547 	if (!buf) {
10548 		WMI_LOGE(FL("wmi_buf_alloc failed"));
10549 		return QDF_STATUS_E_NOMEM;
10550 	}
10551 
10552 	buf_ptr = wmi_buf_data(buf);
10553 	qdf_mem_zero(buf_ptr, len);
10554 
10555 	/* Populate the WMI command */
10556 	cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr;
10557 
10558 	WMITLV_SET_HDR(&cmd->tlv_header,
10559 		       WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param,
10560 		       WMITLV_GET_STRUCT_TLVLEN(
10561 			wmi_vdev_set_ie_cmd_fixed_param));
10562 	cmd->vdev_id = ie_info->vdev_id;
10563 	cmd->ie_id = ie_info->ie_id;
10564 	cmd->ie_len = ie_info->length;
10565 	cmd->band = ie_info->band;
10566 
10567 	WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id,
10568 		 ie_info->length, ie_info->vdev_id);
10569 
10570 	buf_ptr += sizeof(*cmd);
10571 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
10572 	buf_ptr += WMI_TLV_HDR_SIZE;
10573 
10574 	qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len);
10575 
10576 	wmi_mtrace(WMI_VDEV_SET_IE_CMDID, cmd->vdev_id, 0);
10577 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
10578 				   WMI_VDEV_SET_IE_CMDID);
10579 	if (QDF_IS_STATUS_ERROR(ret)) {
10580 		WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret);
10581 		wmi_buf_free(buf);
10582 	}
10583 
10584 	return ret;
10585 }
10586 
10587 /**
10588  *  send_smart_ant_enable_cmd_tlv() - WMI smart ant enable function
10589  *
10590  *  @param wmi_handle  : handle to WMI.
10591  *  @param param       : pointer to antenna param
10592  *
10593  *  This function sends smart antenna enable command to FW
10594  *
10595  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10596  */
10597 static QDF_STATUS send_smart_ant_enable_cmd_tlv(wmi_unified_t wmi_handle,
10598 				struct smart_ant_enable_params *param)
10599 {
10600 	/* Send WMI COMMAND to Enable */
10601 	wmi_pdev_smart_ant_enable_cmd_fixed_param *cmd;
10602 	wmi_pdev_smart_ant_gpio_handle *gpio_param;
10603 	wmi_buf_t buf;
10604 	uint8_t *buf_ptr;
10605 	int len = 0;
10606 	QDF_STATUS ret;
10607 	int loop = 0;
10608 
10609 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
10610 	len += WMI_HAL_MAX_SANTENNA * sizeof(wmi_pdev_smart_ant_gpio_handle);
10611 	buf = wmi_buf_alloc(wmi_handle, len);
10612 
10613 	if (!buf) {
10614 			WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
10615 			return QDF_STATUS_E_NOMEM;
10616 		}
10617 
10618 	buf_ptr = wmi_buf_data(buf);
10619 	qdf_mem_zero(buf_ptr, len);
10620 	cmd = (wmi_pdev_smart_ant_enable_cmd_fixed_param *)buf_ptr;
10621 
10622 	WMITLV_SET_HDR(&cmd->tlv_header,
10623 		WMITLV_TAG_STRUC_wmi_pdev_smart_ant_enable_cmd_fixed_param,
10624 		WMITLV_GET_STRUCT_TLVLEN(
10625 				wmi_pdev_smart_ant_enable_cmd_fixed_param));
10626 
10627 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10628 								param->pdev_id);
10629 	cmd->enable = param->enable;
10630 	cmd->mode = param->mode;
10631 	cmd->rx_antenna = param->rx_antenna;
10632 	cmd->tx_default_antenna = param->rx_antenna;
10633 
10634 	/* TLV indicating array of structures to follow */
10635 	buf_ptr += sizeof(wmi_pdev_smart_ant_enable_cmd_fixed_param);
10636 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
10637 		       WMI_HAL_MAX_SANTENNA *
10638 		       sizeof(wmi_pdev_smart_ant_gpio_handle));
10639 
10640 	buf_ptr += WMI_TLV_HDR_SIZE;
10641 	gpio_param = (wmi_pdev_smart_ant_gpio_handle *)buf_ptr;
10642 
10643 	for (loop = 0; loop < WMI_HAL_MAX_SANTENNA; loop++) {
10644 		WMITLV_SET_HDR(&gpio_param->tlv_header,
10645 			       WMITLV_TAG_STRUC_wmi_pdev_smart_ant_gpio_handle,
10646 			       WMITLV_GET_STRUCT_TLVLEN(
10647 			       wmi_pdev_smart_ant_gpio_handle));
10648 		if (param->mode == SMART_ANT_MODE_SERIAL) {
10649 			if (loop < WMI_HOST_MAX_SERIAL_ANTENNA) {
10650 				gpio_param->gpio_pin = param->gpio_pin[loop];
10651 				gpio_param->gpio_func = param->gpio_func[loop];
10652 			} else {
10653 				gpio_param->gpio_pin = 0;
10654 				gpio_param->gpio_func = 0;
10655 			}
10656 		} else if (param->mode == SMART_ANT_MODE_PARALLEL) {
10657 			gpio_param->gpio_pin = param->gpio_pin[loop];
10658 			gpio_param->gpio_func = param->gpio_func[loop];
10659 		}
10660 		/* Setting it to 0 for now */
10661 		gpio_param->pdev_id =
10662 			wmi_handle->ops->convert_pdev_id_host_to_target(
10663 								param->pdev_id);
10664 		gpio_param++;
10665 	}
10666 
10667 	wmi_mtrace(WMI_PDEV_SMART_ANT_ENABLE_CMDID, NO_SESSION, 0);
10668 	ret = wmi_unified_cmd_send(wmi_handle,
10669 				buf,
10670 				len,
10671 				WMI_PDEV_SMART_ANT_ENABLE_CMDID);
10672 
10673 	if (ret != 0) {
10674 		WMI_LOGE(" %s :WMI Failed\n", __func__);
10675 		WMI_LOGE("enable:%d mode:%d  rx_antenna: 0x%08x PINS: [%d %d %d %d] Func[%d %d %d %d] cmdstatus=%d\n",
10676 			 cmd->enable,
10677 			 cmd->mode,
10678 			 cmd->rx_antenna,
10679 			 param->gpio_pin[0], param->gpio_pin[1],
10680 			 param->gpio_pin[2], param->gpio_pin[3],
10681 			 param->gpio_func[0], param->gpio_func[1],
10682 			 param->gpio_func[2], param->gpio_func[3],
10683 			 ret);
10684 		wmi_buf_free(buf);
10685 	}
10686 
10687 	return ret;
10688 }
10689 
10690 /**
10691  *  send_smart_ant_set_rx_ant_cmd_tlv() - WMI set rx antenna function
10692  *
10693  *  @param wmi_handle     : handle to WMI.
10694  *  @param param          : pointer to rx antenna param
10695  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10696  */
10697 static QDF_STATUS send_smart_ant_set_rx_ant_cmd_tlv(wmi_unified_t wmi_handle,
10698 				struct smart_ant_rx_ant_params *param)
10699 {
10700 	wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *cmd;
10701 	wmi_buf_t buf;
10702 	uint8_t *buf_ptr;
10703 	uint32_t len;
10704 	QDF_STATUS ret;
10705 
10706 	len = sizeof(*cmd);
10707 	buf = wmi_buf_alloc(wmi_handle, len);
10708 	WMI_LOGD("%s:\n", __func__);
10709 	if (!buf) {
10710 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
10711 		return QDF_STATUS_E_NOMEM;
10712 	}
10713 
10714 	buf_ptr = wmi_buf_data(buf);
10715 	cmd = (wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *)buf_ptr;
10716 	WMITLV_SET_HDR(&cmd->tlv_header,
10717 	    WMITLV_TAG_STRUC_wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param,
10718 	    WMITLV_GET_STRUCT_TLVLEN(
10719 		wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param));
10720 	cmd->rx_antenna = param->antenna;
10721 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10722 								param->pdev_id);
10723 
10724 	wmi_mtrace(WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID, NO_SESSION, 0);
10725 	ret = wmi_unified_cmd_send(wmi_handle,
10726 				buf,
10727 				len,
10728 				WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID);
10729 
10730 	if (ret != 0) {
10731 		WMI_LOGE(" %s :WMI Failed\n", __func__);
10732 		WMI_LOGE("%s: rx_antenna: 0x%08x cmdstatus=%d\n",
10733 			 __func__,
10734 			 cmd->rx_antenna,
10735 			 ret);
10736 		wmi_buf_free(buf);
10737 	}
10738 
10739 	return ret;
10740 }
10741 
10742 /**
10743  * send_set_ctl_table_cmd_tlv() - send ctl table cmd to fw
10744  * @wmi_handle: wmi handle
10745  * @param: pointer to hold ctl table param
10746  *
10747  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10748  */
10749 static QDF_STATUS
10750 send_set_ctl_table_cmd_tlv(wmi_unified_t wmi_handle,
10751 			   struct ctl_table_params *param)
10752 {
10753 	uint16_t len, ctl_tlv_len;
10754 	uint8_t *buf_ptr;
10755 	wmi_buf_t buf;
10756 	wmi_pdev_set_ctl_table_cmd_fixed_param *cmd;
10757 	uint32_t *ctl_array;
10758 
10759 	if (!param->ctl_array)
10760 		return QDF_STATUS_E_FAILURE;
10761 
10762 	ctl_tlv_len = WMI_TLV_HDR_SIZE +
10763 		roundup(param->ctl_cmd_len, sizeof(uint32_t));
10764 	len = sizeof(*cmd) + ctl_tlv_len;
10765 
10766 	buf = wmi_buf_alloc(wmi_handle, len);
10767 	if (!buf) {
10768 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
10769 		return QDF_STATUS_E_FAILURE;
10770 	}
10771 
10772 	buf_ptr = wmi_buf_data(buf);
10773 	qdf_mem_zero(buf_ptr, len);
10774 
10775 	cmd = (wmi_pdev_set_ctl_table_cmd_fixed_param *)buf_ptr;
10776 
10777 	WMITLV_SET_HDR(&cmd->tlv_header,
10778 		       WMITLV_TAG_STRUC_wmi_pdev_set_ctl_table_cmd_fixed_param,
10779 		       WMITLV_GET_STRUCT_TLVLEN(
10780 				wmi_pdev_set_ctl_table_cmd_fixed_param));
10781 	cmd->ctl_len = param->ctl_cmd_len;
10782 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10783 								param->pdev_id);
10784 
10785 	buf_ptr += sizeof(*cmd);
10786 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
10787 		       (cmd->ctl_len));
10788 	buf_ptr += WMI_TLV_HDR_SIZE;
10789 	ctl_array = (uint32_t *)buf_ptr;
10790 
10791 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[0], &param->ctl_band,
10792 					sizeof(param->ctl_band));
10793 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[1], param->ctl_array,
10794 					param->ctl_cmd_len -
10795 					sizeof(param->ctl_band));
10796 
10797 	wmi_mtrace(WMI_PDEV_SET_CTL_TABLE_CMDID, NO_SESSION, 0);
10798 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10799 				 WMI_PDEV_SET_CTL_TABLE_CMDID)) {
10800 		WMI_LOGE("%s:Failed to send command\n", __func__);
10801 		wmi_buf_free(buf);
10802 		return QDF_STATUS_E_FAILURE;
10803 	}
10804 
10805 	return QDF_STATUS_SUCCESS;
10806 }
10807 
10808 /**
10809  * send_set_mimogain_table_cmd_tlv() - send mimogain table cmd to fw
10810  * @wmi_handle: wmi handle
10811  * @param: pointer to hold mimogain table param
10812  *
10813  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10814  */
10815 static QDF_STATUS
10816 send_set_mimogain_table_cmd_tlv(wmi_unified_t wmi_handle,
10817 				struct mimogain_table_params *param)
10818 {
10819 	uint16_t len, table_tlv_len;
10820 	wmi_buf_t buf;
10821 	uint8_t *buf_ptr;
10822 	wmi_pdev_set_mimogain_table_cmd_fixed_param *cmd;
10823 	uint32_t *gain_table;
10824 
10825 	if (!param->array_gain)
10826 		return QDF_STATUS_E_FAILURE;
10827 
10828 	/* len must be multiple of a single array gain table */
10829 	if (param->tbl_len %
10830 	    ((WMI_HOST_TX_NUM_CHAIN-1) * WMI_HOST_TPC_REGINDEX_MAX *
10831 	     WMI_HOST_ARRAY_GAIN_NUM_STREAMS) != 0) {
10832 		WMI_LOGE("Array gain table len not correct\n");
10833 		return QDF_STATUS_E_FAILURE;
10834 	}
10835 
10836 	table_tlv_len = WMI_TLV_HDR_SIZE +
10837 		roundup(param->tbl_len, sizeof(uint32_t));
10838 	len = sizeof(*cmd) + table_tlv_len;
10839 
10840 	buf = wmi_buf_alloc(wmi_handle, len);
10841 	if (!buf) {
10842 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
10843 		return QDF_STATUS_E_FAILURE;
10844 	}
10845 
10846 	buf_ptr = wmi_buf_data(buf);
10847 	qdf_mem_zero(buf_ptr, len);
10848 
10849 	cmd = (wmi_pdev_set_mimogain_table_cmd_fixed_param *)buf_ptr;
10850 
10851 	WMITLV_SET_HDR(&cmd->tlv_header,
10852 		WMITLV_TAG_STRUC_wmi_pdev_set_mimogain_table_cmd_fixed_param,
10853 		WMITLV_GET_STRUCT_TLVLEN(
10854 		       wmi_pdev_set_mimogain_table_cmd_fixed_param));
10855 
10856 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10857 								param->pdev_id);
10858 	WMI_MIMOGAIN_ARRAY_GAIN_LEN_SET(cmd->mimogain_info, param->tbl_len);
10859 	WMI_MIMOGAIN_MULTI_CHAIN_BYPASS_SET(cmd->mimogain_info,
10860 					    param->multichain_gain_bypass);
10861 
10862 	buf_ptr += sizeof(*cmd);
10863 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
10864 		       (param->tbl_len));
10865 	buf_ptr += WMI_TLV_HDR_SIZE;
10866 	gain_table = (uint32_t *)buf_ptr;
10867 
10868 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(gain_table,
10869 					param->array_gain,
10870 					param->tbl_len);
10871 
10872 	wmi_mtrace(WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID, NO_SESSION, 0);
10873 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10874 				 WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID)) {
10875 		return QDF_STATUS_E_FAILURE;
10876 	}
10877 
10878 	return QDF_STATUS_SUCCESS;
10879 }
10880 
10881 /**
10882  * enum packet_power_tlv_flags: target defined
10883  * packet power rate flags for TLV
10884  * @WMI_TLV_FLAG_ONE_CHAIN: one chain
10885  * @WMI_TLV_FLAG_TWO_CHAIN: two chain
10886  * @WMI_TLV_FLAG_THREE_CHAIN: three chain
10887  * @WMI_TLV_FLAG_FOUR_CHAIN: four chain
10888  * @WMI_TLV_FLAG_FIVE_CHAIN: five chain
10889  * @WMI_TLV_FLAG_SIX_CHAIN: six chain
10890  * @WMI_TLV_FLAG_SEVEN_CHAIN: seven chain
10891  * @WMI_TLV_FLAG_EIGHT_CHAIN:eight chain
10892  * @WMI_TLV_FLAG_STBC: STBC is set
10893  * @WMI_TLV_FLAG_40MHZ: 40MHz chan width
10894  * @WMI_TLV_FLAG_80MHZ: 80MHz chan width
10895  * @WMI_TLV_FLAG_160MHZ: 160MHz chan width
10896  * @WMI_TLV_FLAG_TXBF: Tx Bf enabled
10897  * @WMI_TLV_FLAG_RTSENA: RTS enabled
10898  * @WMI_TLV_FLAG_CTSENA: CTS enabled
10899  * @WMI_TLV_FLAG_LDPC: LDPC is set
10900  * @WMI_TLV_FLAG_SGI: Short gaurd interval
10901  * @WMI_TLV_FLAG_SU: SU Data
10902  * @WMI_TLV_FLAG_DL_MU_MIMO_AC: DL AC MU data
10903  * @WMI_TLV_FLAG_DL_MU_MIMO_AX: DL AX MU data
10904  * @WMI_TLV_FLAG_DL_OFDMA: DL OFDMA data
10905  * @WMI_TLV_FLAG_UL_OFDMA: UL OFDMA data
10906  * @WMI_TLV_FLAG_UL_MU_MIMO: UL MU data
10907  *
10908  * @WMI_TLV_FLAG_BW_MASK: bandwidth mask
10909  * @WMI_TLV_FLAG_BW_SHIFT: bandwidth shift
10910  * @WMI_TLV_FLAG_SU_MU_OFDMA_MASK: su/mu/ofdma mask
10911  * @WMI_TLV_FLAG_SU_MU_OFDMA_shift: su/mu/ofdma shift
10912  */
10913 enum packet_power_tlv_flags {
10914 	WMI_TLV_FLAG_ONE_CHAIN         = 0x00000001,
10915 	WMI_TLV_FLAG_TWO_CHAIN         = 0x00000003,
10916 	WMI_TLV_FLAG_THREE_CHAIN       = 0x00000007,
10917 	WMI_TLV_FLAG_FOUR_CHAIN        = 0x0000000F,
10918 	WMI_TLV_FLAG_FIVE_CHAIN        = 0x0000001F,
10919 	WMI_TLV_FLAG_SIX_CHAIN         = 0x0000003F,
10920 	WMI_TLV_FLAG_SEVEN_CHAIN       = 0x0000007F,
10921 	WMI_TLV_FLAG_EIGHT_CHAIN       = 0x0000008F,
10922 	WMI_TLV_FLAG_STBC              = 0x00000100,
10923 	WMI_TLV_FLAG_40MHZ             = 0x00000200,
10924 	WMI_TLV_FLAG_80MHZ             = 0x00000300,
10925 	WMI_TLV_FLAG_160MHZ            = 0x00000400,
10926 	WMI_TLV_FLAG_TXBF              = 0x00000800,
10927 	WMI_TLV_FLAG_RTSENA            = 0x00001000,
10928 	WMI_TLV_FLAG_CTSENA            = 0x00002000,
10929 	WMI_TLV_FLAG_LDPC              = 0x00004000,
10930 	WMI_TLV_FLAG_SGI               = 0x00008000,
10931 	WMI_TLV_FLAG_SU                = 0x00100000,
10932 	WMI_TLV_FLAG_DL_MU_MIMO_AC     = 0x00200000,
10933 	WMI_TLV_FLAG_DL_MU_MIMO_AX     = 0x00300000,
10934 	WMI_TLV_FLAG_DL_OFDMA          = 0x00400000,
10935 	WMI_TLV_FLAG_UL_OFDMA          = 0x00500000,
10936 	WMI_TLV_FLAG_UL_MU_MIMO        = 0x00600000,
10937 
10938 	WMI_TLV_FLAG_CHAIN_MASK        = 0xff,
10939 	WMI_TLV_FLAG_BW_MASK           = 0x3,
10940 	WMI_TLV_FLAG_BW_SHIFT          = 9,
10941 	WMI_TLV_FLAG_SU_MU_OFDMA_MASK  = 0x7,
10942 	WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT = 20,
10943 };
10944 
10945 /**
10946  * convert_to_power_info_rate_flags() - convert packet_power_info_params
10947  * to FW understandable format
10948  * @param: pointer to hold packet power info param
10949  *
10950  * @return FW understandable 32 bit rate flags
10951  */
10952 static uint32_t
10953 convert_to_power_info_rate_flags(struct packet_power_info_params *param)
10954 {
10955 	uint32_t rateflags = 0;
10956 
10957 	if (param->chainmask)
10958 		rateflags |=
10959 			(param->chainmask & WMI_TLV_FLAG_CHAIN_MASK);
10960 	if (param->chan_width)
10961 		rateflags |=
10962 			((param->chan_width & WMI_TLV_FLAG_BW_MASK)
10963 			 << WMI_TLV_FLAG_BW_SHIFT);
10964 	if (param->su_mu_ofdma)
10965 		rateflags |=
10966 			((param->su_mu_ofdma & WMI_TLV_FLAG_SU_MU_OFDMA_MASK)
10967 			 << WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT);
10968 	if (param->rate_flags & WMI_HOST_FLAG_STBC)
10969 		rateflags |= WMI_TLV_FLAG_STBC;
10970 	if (param->rate_flags & WMI_HOST_FLAG_LDPC)
10971 		rateflags |= WMI_TLV_FLAG_LDPC;
10972 	if (param->rate_flags & WMI_HOST_FLAG_TXBF)
10973 		rateflags |= WMI_TLV_FLAG_TXBF;
10974 	if (param->rate_flags & WMI_HOST_FLAG_RTSENA)
10975 		rateflags |= WMI_TLV_FLAG_RTSENA;
10976 	if (param->rate_flags & WMI_HOST_FLAG_CTSENA)
10977 		rateflags |= WMI_TLV_FLAG_CTSENA;
10978 	if (param->rate_flags & WMI_HOST_FLAG_SGI)
10979 		rateflags |= WMI_TLV_FLAG_SGI;
10980 
10981 	return rateflags;
10982 }
10983 
10984 /**
10985  * send_packet_power_info_get_cmd_tlv() - send request to get packet power
10986  * info to fw
10987  * @wmi_handle: wmi handle
10988  * @param: pointer to hold packet power info param
10989  *
10990  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
10991  */
10992 static QDF_STATUS
10993 send_packet_power_info_get_cmd_tlv(wmi_unified_t wmi_handle,
10994 				   struct packet_power_info_params *param)
10995 {
10996 	wmi_pdev_get_tpc_cmd_fixed_param *cmd;
10997 	wmi_buf_t wmibuf;
10998 	uint8_t *buf_ptr;
10999 	u_int32_t len = sizeof(wmi_pdev_get_tpc_cmd_fixed_param);
11000 
11001 	wmibuf = wmi_buf_alloc(wmi_handle, len);
11002 	if (wmibuf == NULL)
11003 		return QDF_STATUS_E_NOMEM;
11004 
11005 	buf_ptr = (uint8_t *)wmi_buf_data(wmibuf);
11006 
11007 	cmd = (wmi_pdev_get_tpc_cmd_fixed_param *)buf_ptr;
11008 	WMITLV_SET_HDR(&cmd->tlv_header,
11009 		       WMITLV_TAG_STRUC_wmi_pdev_get_tpc_cmd_fixed_param,
11010 		       WMITLV_GET_STRUCT_TLVLEN(
11011 				wmi_pdev_get_tpc_cmd_fixed_param));
11012 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
11013 								param->pdev_id);
11014 	cmd->rate_flags = convert_to_power_info_rate_flags(param);
11015 	cmd->nss = param->nss;
11016 	cmd->preamble = param->preamble;
11017 	cmd->hw_rate = param->hw_rate;
11018 
11019 	WMI_LOGI("%s[%d] commandID %d, wmi_pdev_get_tpc_cmd=0x%x,"
11020 		"rate_flags: 0x%x, nss: %d, preamble: %d, hw_rate: %d\n",
11021 		__func__, __LINE__, WMI_PDEV_GET_TPC_CMDID, *((u_int32_t *)cmd),
11022 		cmd->rate_flags, cmd->nss, cmd->preamble, cmd->hw_rate);
11023 
11024 	wmi_mtrace(WMI_PDEV_GET_TPC_CMDID, NO_SESSION, 0);
11025 	if (wmi_unified_cmd_send(wmi_handle, wmibuf, len,
11026 				 WMI_PDEV_GET_TPC_CMDID)) {
11027 			WMI_LOGE(FL("Failed to get tpc command\n"));
11028 			wmi_buf_free(wmibuf);
11029 			return QDF_STATUS_E_FAILURE;
11030 	}
11031 
11032 	return QDF_STATUS_SUCCESS;
11033 }
11034 
11035 /**
11036  * send_vdev_config_ratemask_cmd_tlv() - config ratemask param in fw
11037  * @wmi_handle: wmi handle
11038  * @param: pointer to hold config ratemask params
11039  *
11040  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11041  */
11042 static QDF_STATUS send_vdev_config_ratemask_cmd_tlv(wmi_unified_t wmi_handle,
11043 					struct config_ratemask_params *param)
11044 {
11045 	wmi_vdev_config_ratemask_cmd_fixed_param *cmd;
11046 	wmi_buf_t buf;
11047 	int32_t len = sizeof(*cmd);
11048 
11049 	buf = wmi_buf_alloc(wmi_handle, len);
11050 	if (!buf) {
11051 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11052 		return QDF_STATUS_E_FAILURE;
11053 	}
11054 	cmd = (wmi_vdev_config_ratemask_cmd_fixed_param *)wmi_buf_data(buf);
11055 	WMITLV_SET_HDR(&cmd->tlv_header,
11056 		       WMITLV_TAG_STRUC_wmi_vdev_config_ratemask_fixed_param,
11057 		       WMITLV_GET_STRUCT_TLVLEN(
11058 				wmi_vdev_config_ratemask_cmd_fixed_param));
11059 	cmd->vdev_id = param->vdev_id;
11060 	cmd->type = param->type;
11061 	cmd->mask_lower32 = param->lower32;
11062 	cmd->mask_higher32 = param->higher32;
11063 	cmd->mask_lower32_2 = param->lower32_2;
11064 	WMI_LOGI("Setting vdev ratemask vdev id = 0x%X, type = 0x%X"
11065 		"mask_l32 = 0x%X mask_h32 = 0x%X mask_l32_2 = 0x%X\n",
11066 		param->vdev_id, param->type, param->lower32,
11067 		param->higher32, param->lower32_2);
11068 
11069 	wmi_mtrace(WMI_VDEV_RATEMASK_CMDID, cmd->vdev_id, 0);
11070 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11071 				 WMI_VDEV_RATEMASK_CMDID)) {
11072 			WMI_LOGE("Seting vdev ratemask failed\n");
11073 			wmi_buf_free(buf);
11074 			return QDF_STATUS_E_FAILURE;
11075 	}
11076 
11077 	return QDF_STATUS_SUCCESS;
11078 }
11079 
11080 /**
11081  * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs
11082  * @param: param sent from the host side
11083  * @cmd: param to be sent to the fw side
11084  */
11085 static inline void copy_custom_aggr_bitmap(
11086 		struct set_custom_aggr_size_params *param,
11087 		wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd)
11088 {
11089 	WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap,
11090 				    param->ac);
11091 	WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap,
11092 				      param->aggr_type);
11093 	WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap,
11094 					   param->tx_aggr_size_disable);
11095 	WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap,
11096 					   param->rx_aggr_size_disable);
11097 	WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap,
11098 				     param->tx_ac_enable);
11099 }
11100 
11101 /**
11102  * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw
11103  * @wmi_handle: wmi handle
11104  * @param: pointer to hold custom aggr size params
11105  *
11106  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11107  */
11108 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv(
11109 			wmi_unified_t wmi_handle,
11110 			struct set_custom_aggr_size_params *param)
11111 {
11112 	wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd;
11113 	wmi_buf_t buf;
11114 	int32_t len = sizeof(*cmd);
11115 
11116 	buf = wmi_buf_alloc(wmi_handle, len);
11117 	if (!buf) {
11118 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11119 		return QDF_STATUS_E_FAILURE;
11120 	}
11121 	cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *)
11122 		wmi_buf_data(buf);
11123 	WMITLV_SET_HDR(&cmd->tlv_header,
11124 		WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param,
11125 		WMITLV_GET_STRUCT_TLVLEN(
11126 		wmi_vdev_set_custom_aggr_size_cmd_fixed_param));
11127 	cmd->vdev_id = param->vdev_id;
11128 	cmd->tx_aggr_size = param->tx_aggr_size;
11129 	cmd->rx_aggr_size = param->rx_aggr_size;
11130 	copy_custom_aggr_bitmap(param, cmd);
11131 
11132 	WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X "
11133 		"rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X "
11134 		"tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X "
11135 		"tx_ac_enable=0x%X\n",
11136 		param->vdev_id, param->tx_aggr_size, param->rx_aggr_size,
11137 		param->ac, param->aggr_type, param->tx_aggr_size_disable,
11138 		param->rx_aggr_size_disable, param->tx_ac_enable);
11139 
11140 	wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0);
11141 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11142 				 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) {
11143 		WMI_LOGE("Seting custom aggregation size failed\n");
11144 		wmi_buf_free(buf);
11145 		return QDF_STATUS_E_FAILURE;
11146 	}
11147 
11148 	return QDF_STATUS_SUCCESS;
11149 }
11150 
11151 /**
11152  *  send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold
11153  *  @param wmi_handle  : handle to WMI.
11154  *  @param param       : pointer to tx antenna param
11155  *
11156  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11157  */
11158 
11159 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle,
11160 				struct set_qdepth_thresh_params *param)
11161 {
11162 	wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd;
11163 	wmi_msduq_qdepth_thresh_update *cmd_update;
11164 	wmi_buf_t buf;
11165 	int32_t len = 0;
11166 	int i;
11167 	uint8_t *buf_ptr;
11168 	QDF_STATUS ret;
11169 
11170 	if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) {
11171 		WMI_LOGE("%s: Invalid Update Count!\n", __func__);
11172 		return QDF_STATUS_E_INVAL;
11173 	}
11174 
11175 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11176 	len += (sizeof(wmi_msduq_qdepth_thresh_update) *
11177 			param->num_of_msduq_updates);
11178 	buf = wmi_buf_alloc(wmi_handle, len);
11179 
11180 	if (!buf) {
11181 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11182 		return QDF_STATUS_E_NOMEM;
11183 	}
11184 
11185 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11186 	cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *)
11187 								buf_ptr;
11188 
11189 	WMITLV_SET_HDR(&cmd->tlv_header,
11190 	WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param
11191 	 , WMITLV_GET_STRUCT_TLVLEN(
11192 		wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param));
11193 
11194 	cmd->pdev_id =
11195 		wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id);
11196 	cmd->vdev_id = param->vdev_id;
11197 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address);
11198 	cmd->num_of_msduq_updates = param->num_of_msduq_updates;
11199 
11200 	buf_ptr += sizeof(
11201 		wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param);
11202 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11203 			param->num_of_msduq_updates *
11204 			sizeof(wmi_msduq_qdepth_thresh_update));
11205 	buf_ptr += WMI_TLV_HDR_SIZE;
11206 	cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr;
11207 
11208 	for (i = 0; i < cmd->num_of_msduq_updates; i++) {
11209 		WMITLV_SET_HDR(&cmd_update->tlv_header,
11210 		    WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update,
11211 		    WMITLV_GET_STRUCT_TLVLEN(
11212 				wmi_msduq_qdepth_thresh_update));
11213 		cmd_update->tid_num = param->update_params[i].tid_num;
11214 		cmd_update->msduq_update_mask =
11215 				param->update_params[i].msduq_update_mask;
11216 		cmd_update->qdepth_thresh_value =
11217 				param->update_params[i].qdepth_thresh_value;
11218 		WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X "
11219 			 "mac_addr_upper4=%X, mac_addr_lower2:%X,"
11220 			 " update mask=0x%X thresh val=0x%X\n",
11221 			 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num,
11222 			 cmd->peer_mac_address.mac_addr31to0,
11223 			 cmd->peer_mac_address.mac_addr47to32,
11224 			 cmd_update->msduq_update_mask,
11225 			 cmd_update->qdepth_thresh_value);
11226 		cmd_update++;
11227 	}
11228 
11229 	wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID,
11230 		   cmd->vdev_id, 0);
11231 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
11232 				WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID);
11233 
11234 	if (ret != 0) {
11235 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11236 		wmi_buf_free(buf);
11237 	}
11238 
11239 	return ret;
11240 }
11241 
11242 /**
11243  * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw
11244  * @wmi_handle: wmi handle
11245  * @param: pointer to hold vap dscp tid map param
11246  *
11247  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11248  */
11249 static QDF_STATUS
11250 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle,
11251 				  struct vap_dscp_tid_map_params *param)
11252 {
11253 	wmi_buf_t buf;
11254 	wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd;
11255 	int32_t len = sizeof(*cmd);
11256 
11257 	buf = wmi_buf_alloc(wmi_handle, len);
11258 	if (!buf) {
11259 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11260 		return QDF_STATUS_E_FAILURE;
11261 	}
11262 
11263 	cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf);
11264 	qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map,
11265 		     sizeof(uint32_t) * WMI_DSCP_MAP_MAX);
11266 
11267 	cmd->vdev_id = param->vdev_id;
11268 	cmd->enable_override = 0;
11269 
11270 	WMI_LOGI("Setting dscp for vap id: %d\n", cmd->vdev_id);
11271 	wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0);
11272 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11273 				 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) {
11274 			WMI_LOGE("Failed to set dscp cmd\n");
11275 			wmi_buf_free(buf);
11276 			return QDF_STATUS_E_FAILURE;
11277 	}
11278 
11279 	return QDF_STATUS_SUCCESS;
11280 }
11281 
11282 /**
11283  * send_vdev_set_neighbour_rx_cmd_tlv() - set neighbour rx param in fw
11284  * @wmi_handle: wmi handle
11285  * @macaddr: vdev mac address
11286  * @param: pointer to hold neigbour rx param
11287  *
11288  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11289  */
11290 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle,
11291 					uint8_t macaddr[IEEE80211_ADDR_LEN],
11292 					struct set_neighbour_rx_params *param)
11293 {
11294 	wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd;
11295 	wmi_buf_t buf;
11296 	int32_t len = sizeof(*cmd);
11297 
11298 	buf = wmi_buf_alloc(wmi_handle, len);
11299 	if (!buf) {
11300 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11301 		return QDF_STATUS_E_FAILURE;
11302 	}
11303 	cmd = (wmi_vdev_filter_nrp_config_cmd_fixed_param *)wmi_buf_data(buf);
11304 	WMITLV_SET_HDR(&cmd->tlv_header,
11305 		WMITLV_TAG_STRUC_wmi_vdev_filter_nrp_config_cmd_fixed_param,
11306 		WMITLV_GET_STRUCT_TLVLEN(
11307 			wmi_vdev_filter_nrp_config_cmd_fixed_param));
11308 	cmd->vdev_id = param->vdev_id;
11309 	cmd->bssid_idx = param->idx;
11310 	cmd->action = param->action;
11311 	cmd->type = param->type;
11312 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->addr);
11313 	cmd->flag = 0;
11314 
11315 	wmi_mtrace(WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID, cmd->vdev_id, 0);
11316 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11317 				 WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID)) {
11318 			WMI_LOGE("Failed to set neighbour rx param\n");
11319 			wmi_buf_free(buf);
11320 			return QDF_STATUS_E_FAILURE;
11321 	}
11322 
11323 	return QDF_STATUS_SUCCESS;
11324 }
11325 
11326 /**
11327  *  send_smart_ant_set_tx_ant_cmd_tlv() - WMI set tx antenna function
11328  *  @param wmi_handle  : handle to WMI.
11329  *  @param macaddr     : vdev mac address
11330  *  @param param       : pointer to tx antenna param
11331  *
11332  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11333  */
11334 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle,
11335 				uint8_t macaddr[IEEE80211_ADDR_LEN],
11336 				struct smart_ant_tx_ant_params *param)
11337 {
11338 	wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd;
11339 	wmi_peer_smart_ant_set_tx_antenna_series *ant_tx_series;
11340 	wmi_buf_t buf;
11341 	int32_t len = 0;
11342 	int i;
11343 	uint8_t *buf_ptr;
11344 	QDF_STATUS ret;
11345 
11346 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11347 	len += (WMI_SMART_ANT_MAX_RATE_SERIES) *
11348 		sizeof(wmi_peer_smart_ant_set_tx_antenna_series);
11349 	buf = wmi_buf_alloc(wmi_handle, len);
11350 
11351 	if (!buf) {
11352 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11353 		return QDF_STATUS_E_NOMEM;
11354 	}
11355 
11356 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11357 	qdf_mem_zero(buf_ptr, len);
11358 	cmd = (wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *)buf_ptr;
11359 
11360 	WMITLV_SET_HDR(&cmd->tlv_header,
11361 	    WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param,
11362 	    WMITLV_GET_STRUCT_TLVLEN(
11363 			wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param));
11364 
11365 	cmd->vdev_id = param->vdev_id;
11366 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11367 
11368 	buf_ptr += sizeof(wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param);
11369 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11370 		       sizeof(wmi_peer_smart_ant_set_tx_antenna_series));
11371 	buf_ptr += WMI_TLV_HDR_SIZE;
11372 	ant_tx_series = (wmi_peer_smart_ant_set_tx_antenna_series *)buf_ptr;
11373 
11374 	for (i = 0; i < WMI_SMART_ANT_MAX_RATE_SERIES; i++) {
11375 		WMITLV_SET_HDR(&ant_tx_series->tlv_header,
11376 		    WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_series,
11377 		    WMITLV_GET_STRUCT_TLVLEN(
11378 				wmi_peer_smart_ant_set_tx_antenna_series));
11379 		ant_tx_series->antenna_series = param->antenna_array[i];
11380 		ant_tx_series++;
11381 	}
11382 
11383 	wmi_mtrace(WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID, cmd->vdev_id, 0);
11384 	ret = wmi_unified_cmd_send(wmi_handle,
11385 				   buf,
11386 				   len,
11387 				   WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID);
11388 
11389 	if (ret != 0) {
11390 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11391 		wmi_buf_free(buf);
11392 	}
11393 
11394 	return ret;
11395 }
11396 
11397 /**
11398  * send_set_ant_switch_tbl_cmd_tlv() - send ant switch tbl cmd to fw
11399  * @wmi_handle: wmi handle
11400  * @param: pointer to hold ant switch tbl param
11401  *
11402  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11403  */
11404 static QDF_STATUS
11405 send_set_ant_switch_tbl_cmd_tlv(wmi_unified_t wmi_handle,
11406 				struct ant_switch_tbl_params *param)
11407 {
11408 	uint8_t len;
11409 	wmi_buf_t buf;
11410 	wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *cmd;
11411 	wmi_pdev_set_ant_ctrl_chain *ctrl_chain;
11412 	uint8_t *buf_ptr;
11413 
11414 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11415 	len += sizeof(wmi_pdev_set_ant_ctrl_chain);
11416 	buf = wmi_buf_alloc(wmi_handle, len);
11417 
11418 	if (!buf) {
11419 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11420 		return QDF_STATUS_E_NOMEM;
11421 	}
11422 
11423 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11424 	qdf_mem_zero(buf_ptr, len);
11425 	cmd = (wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *)buf_ptr;
11426 
11427 	WMITLV_SET_HDR(&cmd->tlv_header,
11428 		WMITLV_TAG_STRUC_wmi_pdev_set_ant_switch_tbl_cmd_fixed_param,
11429 		WMITLV_GET_STRUCT_TLVLEN(
11430 			wmi_pdev_set_ant_switch_tbl_cmd_fixed_param));
11431 
11432 	cmd->antCtrlCommon1 = param->ant_ctrl_common1;
11433 	cmd->antCtrlCommon2 = param->ant_ctrl_common2;
11434 	cmd->mac_id =
11435 		wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id);
11436 
11437 	/* TLV indicating array of structures to follow */
11438 	buf_ptr += sizeof(wmi_pdev_set_ant_switch_tbl_cmd_fixed_param);
11439 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11440 		       sizeof(wmi_pdev_set_ant_ctrl_chain));
11441 	buf_ptr += WMI_TLV_HDR_SIZE;
11442 	ctrl_chain = (wmi_pdev_set_ant_ctrl_chain *)buf_ptr;
11443 
11444 	ctrl_chain->pdev_id =
11445 		wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id);
11446 	ctrl_chain->antCtrlChain = param->antCtrlChain;
11447 
11448 	wmi_mtrace(WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID, NO_SESSION, 0);
11449 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11450 				 WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) {
11451 		wmi_buf_free(buf);
11452 		return QDF_STATUS_E_FAILURE;
11453 	}
11454 
11455 	return QDF_STATUS_SUCCESS;
11456 }
11457 
11458 /**
11459  *  send_smart_ant_set_training_info_cmd_tlv() - WMI set smart antenna
11460  *  training information function
11461  *  @param wmi_handle  : handle to WMI.
11462  *  @macaddr           : vdev mac address
11463  *  @param param       : pointer to tx antenna param
11464  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11465  */
11466 static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv(
11467 				wmi_unified_t wmi_handle,
11468 				uint8_t macaddr[IEEE80211_ADDR_LEN],
11469 				struct smart_ant_training_info_params *param)
11470 {
11471 	wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd;
11472 	wmi_peer_smart_ant_set_train_antenna_param *train_param;
11473 	wmi_buf_t buf;
11474 	uint8_t *buf_ptr;
11475 	int32_t len = 0;
11476 	QDF_STATUS ret;
11477 	int loop;
11478 
11479 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11480 	len += (WMI_SMART_ANT_MAX_RATE_SERIES) *
11481 		 sizeof(wmi_peer_smart_ant_set_train_antenna_param);
11482 	buf = wmi_buf_alloc(wmi_handle, len);
11483 
11484 	if (!buf) {
11485 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11486 		return QDF_STATUS_E_NOMEM;
11487 	}
11488 
11489 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11490 	qdf_mem_zero(buf_ptr, len);
11491 	cmd = (wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *)buf_ptr;
11492 
11493 	WMITLV_SET_HDR(&cmd->tlv_header,
11494 	WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param,
11495 		WMITLV_GET_STRUCT_TLVLEN(
11496 			wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param));
11497 
11498 	cmd->vdev_id = param->vdev_id;
11499 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11500 	cmd->num_pkts = param->numpkts;
11501 
11502 	buf_ptr += sizeof(wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param);
11503 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11504 		       sizeof(wmi_peer_smart_ant_set_train_antenna_param) *
11505 		       WMI_SMART_ANT_MAX_RATE_SERIES);
11506 
11507 	buf_ptr += WMI_TLV_HDR_SIZE;
11508 	train_param = (wmi_peer_smart_ant_set_train_antenna_param *)buf_ptr;
11509 
11510 	for (loop = 0; loop < WMI_SMART_ANT_MAX_RATE_SERIES; loop++) {
11511 		WMITLV_SET_HDR(&train_param->tlv_header,
11512 		WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_param,
11513 			    WMITLV_GET_STRUCT_TLVLEN(
11514 				wmi_peer_smart_ant_set_train_antenna_param));
11515 		train_param->train_rate_series = param->rate_array[loop];
11516 		train_param->train_antenna_series = param->antenna_array[loop];
11517 		train_param->rc_flags = 0;
11518 		WMI_LOGI(FL("Series number:%d\n"), loop);
11519 		WMI_LOGI(FL("Rate [0x%02x] Tx_Antenna [0x%08x]\n"),
11520 			 train_param->train_rate_series,
11521 			 train_param->train_antenna_series);
11522 		train_param++;
11523 	}
11524 
11525 	wmi_mtrace(WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID, cmd->vdev_id, 0);
11526 	ret = wmi_unified_cmd_send(wmi_handle,
11527 				buf,
11528 				len,
11529 				WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID);
11530 
11531 	if (ret != 0) {
11532 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11533 		wmi_buf_free(buf);
11534 		return QDF_STATUS_E_FAILURE;
11535 	}
11536 
11537 	return ret;
11538 }
11539 
11540 /**
11541  *  send_smart_ant_set_node_config_cmd_tlv() - WMI set node
11542  *  configuration function
11543  *  @param wmi_handle		   : handle to WMI.
11544  *  @macaddr			   : vdev mad address
11545  *  @param param		   : pointer to tx antenna param
11546  *
11547  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11548  */
11549 static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv(
11550 				wmi_unified_t wmi_handle,
11551 				uint8_t macaddr[IEEE80211_ADDR_LEN],
11552 				struct smart_ant_node_config_params *param)
11553 {
11554 	wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd;
11555 	wmi_buf_t buf;
11556 	uint8_t *buf_ptr;
11557 	int32_t len = 0, args_tlv_len;
11558 	int ret;
11559 	int i = 0;
11560 	uint32_t *node_config_args;
11561 
11562 	args_tlv_len = WMI_TLV_HDR_SIZE + param->args_count * sizeof(uint32_t);
11563 	len = sizeof(*cmd) + args_tlv_len;
11564 
11565 	if (param->args_count == 0) {
11566 		WMI_LOGE("%s: Can't send a command with %d arguments\n",
11567 			  __func__, param->args_count);
11568 		return QDF_STATUS_E_FAILURE;
11569 	}
11570 
11571 	buf = wmi_buf_alloc(wmi_handle, len);
11572 	if (!buf) {
11573 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11574 		return QDF_STATUS_E_NOMEM;
11575 	}
11576 
11577 	cmd = (wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *)
11578 						wmi_buf_data(buf);
11579 	buf_ptr = (uint8_t *)cmd;
11580 	WMITLV_SET_HDR(&cmd->tlv_header,
11581 	WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param,
11582 		WMITLV_GET_STRUCT_TLVLEN(
11583 		wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param));
11584 	cmd->vdev_id = param->vdev_id;
11585 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11586 	cmd->cmd_id = param->cmd_id;
11587 	cmd->args_count = param->args_count;
11588 	buf_ptr += sizeof(
11589 		wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param);
11590 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
11591 			(cmd->args_count * sizeof(uint32_t)));
11592 	buf_ptr += WMI_TLV_HDR_SIZE;
11593 	node_config_args = (uint32_t *)buf_ptr;
11594 
11595 	for (i = 0; i < param->args_count; i++) {
11596 		node_config_args[i] = param->args_arr[i];
11597 		WMI_LOGI("%d", param->args_arr[i]);
11598 	}
11599 
11600 	wmi_mtrace(WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID,
11601 		   cmd->vdev_id, 0);
11602 	ret = wmi_unified_cmd_send(wmi_handle,
11603 			   buf,
11604 			   len,
11605 			   WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID);
11606 
11607 	if (ret != 0) {
11608 		WMI_LOGE("%s: WMI FAILED:Sent cmd_id: 0x%x\n Node: %02x:%02x:%02x:%02x:%02x:%02x cmdstatus=%d\n",
11609 			 __func__, param->cmd_id, macaddr[0],
11610 			 macaddr[1], macaddr[2], macaddr[3],
11611 			 macaddr[4], macaddr[5], ret);
11612 		wmi_buf_free(buf);
11613 	}
11614 
11615 	return ret;
11616 }
11617 
11618 #ifdef WLAN_ATF_ENABLE
11619 /**
11620  * send_set_atf_cmd_tlv() - send set atf command to fw
11621  * @wmi_handle: wmi handle
11622  * @param: pointer to set atf param
11623  *
11624  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11625  */
11626 static QDF_STATUS
11627 send_set_atf_cmd_tlv(wmi_unified_t wmi_handle,
11628 		     struct set_atf_params *param)
11629 {
11630 	wmi_atf_peer_info *peer_info;
11631 	wmi_peer_atf_request_fixed_param *cmd;
11632 	wmi_buf_t buf;
11633 	uint8_t *buf_ptr;
11634 	int i;
11635 	int32_t len = 0;
11636 	QDF_STATUS retval;
11637 
11638 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11639 	len += param->num_peers * sizeof(wmi_atf_peer_info);
11640 	buf = wmi_buf_alloc(wmi_handle, len);
11641 	if (!buf) {
11642 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11643 		return QDF_STATUS_E_FAILURE;
11644 	}
11645 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11646 	cmd = (wmi_peer_atf_request_fixed_param *)buf_ptr;
11647 	WMITLV_SET_HDR(&cmd->tlv_header,
11648 		       WMITLV_TAG_STRUC_wmi_peer_atf_request_fixed_param,
11649 		       WMITLV_GET_STRUCT_TLVLEN(
11650 				wmi_peer_atf_request_fixed_param));
11651 	cmd->num_peers = param->num_peers;
11652 
11653 	buf_ptr += sizeof(*cmd);
11654 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11655 		       sizeof(wmi_atf_peer_info) *
11656 		       cmd->num_peers);
11657 	buf_ptr += WMI_TLV_HDR_SIZE;
11658 	peer_info = (wmi_atf_peer_info *)buf_ptr;
11659 
11660 	for (i = 0; i < cmd->num_peers; i++) {
11661 		WMITLV_SET_HDR(&peer_info->tlv_header,
11662 			    WMITLV_TAG_STRUC_wmi_atf_peer_info,
11663 			    WMITLV_GET_STRUCT_TLVLEN(
11664 				wmi_atf_peer_info));
11665 		qdf_mem_copy(&(peer_info->peer_macaddr),
11666 				&(param->peer_info[i].peer_macaddr),
11667 				sizeof(wmi_mac_addr));
11668 		peer_info->atf_units = param->peer_info[i].percentage_peer;
11669 		peer_info->vdev_id = param->peer_info[i].vdev_id;
11670 		peer_info->pdev_id =
11671 			wmi_handle->ops->convert_pdev_id_host_to_target(
11672 				param->peer_info[i].pdev_id);
11673 		/*
11674 		 * TLV definition for peer atf request fixed param combines
11675 		 * extension stats. Legacy FW for WIN (Non-TLV) has peer atf
11676 		 * stats and atf extension stats as two different
11677 		 * implementations.
11678 		 * Need to discuss with FW on this.
11679 		 *
11680 		 * peer_info->atf_groupid = param->peer_ext_info[i].group_index;
11681 		 * peer_info->atf_units_reserved =
11682 		 *		param->peer_ext_info[i].atf_index_reserved;
11683 		 */
11684 		peer_info++;
11685 	}
11686 
11687 	wmi_mtrace(WMI_PEER_ATF_REQUEST_CMDID, NO_SESSION, 0);
11688 	retval = wmi_unified_cmd_send(wmi_handle, buf, len,
11689 		WMI_PEER_ATF_REQUEST_CMDID);
11690 
11691 	if (retval != QDF_STATUS_SUCCESS) {
11692 		WMI_LOGE("%s : WMI Failed\n", __func__);
11693 		wmi_buf_free(buf);
11694 	}
11695 
11696 	return retval;
11697 }
11698 #endif
11699 
11700 /**
11701  * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw
11702  * @wmi_handle: wmi handle
11703  * @param: pointer to hold fwtest param
11704  *
11705  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11706  */
11707 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle,
11708 				struct set_fwtest_params *param)
11709 {
11710 	wmi_fwtest_set_param_cmd_fixed_param *cmd;
11711 	wmi_buf_t buf;
11712 	int32_t len = sizeof(*cmd);
11713 
11714 	buf = wmi_buf_alloc(wmi_handle, len);
11715 
11716 	if (!buf) {
11717 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11718 		return QDF_STATUS_E_FAILURE;
11719 	}
11720 
11721 	cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf);
11722 	WMITLV_SET_HDR(&cmd->tlv_header,
11723 		       WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param,
11724 		       WMITLV_GET_STRUCT_TLVLEN(
11725 				wmi_fwtest_set_param_cmd_fixed_param));
11726 	cmd->param_id = param->arg;
11727 	cmd->param_value = param->value;
11728 
11729 	wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0);
11730 	if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) {
11731 		WMI_LOGE("Setting FW test param failed\n");
11732 		wmi_buf_free(buf);
11733 		return QDF_STATUS_E_FAILURE;
11734 	}
11735 
11736 	return QDF_STATUS_SUCCESS;
11737 }
11738 
11739 /**
11740  * send_set_qboost_param_cmd_tlv() - send set qboost command to fw
11741  * @wmi_handle: wmi handle
11742  * @param: pointer to qboost params
11743  * @macaddr: vdev mac address
11744  *
11745  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11746  */
11747 static QDF_STATUS
11748 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle,
11749 			      uint8_t macaddr[IEEE80211_ADDR_LEN],
11750 			      struct set_qboost_params *param)
11751 {
11752 	WMI_QBOOST_CFG_CMD_fixed_param *cmd;
11753 	wmi_buf_t buf;
11754 	int32_t len;
11755 	QDF_STATUS ret;
11756 
11757 	len = sizeof(*cmd);
11758 
11759 	buf = wmi_buf_alloc(wmi_handle, len);
11760 	if (!buf) {
11761 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11762 		return QDF_STATUS_E_FAILURE;
11763 	}
11764 
11765 	cmd = (WMI_QBOOST_CFG_CMD_fixed_param *)wmi_buf_data(buf);
11766 	WMITLV_SET_HDR(&cmd->tlv_header,
11767 		       WMITLV_TAG_STRUC_WMI_QBOOST_CFG_CMD_fixed_param,
11768 		       WMITLV_GET_STRUCT_TLVLEN(
11769 				WMI_QBOOST_CFG_CMD_fixed_param));
11770 	cmd->vdev_id = param->vdev_id;
11771 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11772 	cmd->qb_enable = param->value;
11773 
11774 	wmi_mtrace(WMI_QBOOST_CFG_CMDID, cmd->vdev_id, 0);
11775 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11776 			WMI_QBOOST_CFG_CMDID);
11777 
11778 	if (ret != 0) {
11779 		WMI_LOGE("Setting qboost cmd failed\n");
11780 		wmi_buf_free(buf);
11781 	}
11782 
11783 	return ret;
11784 }
11785 
11786 /**
11787  * send_gpio_config_cmd_tlv() - send gpio config to fw
11788  * @wmi_handle: wmi handle
11789  * @param: pointer to hold gpio config param
11790  *
11791  * Return: 0 for success or error code
11792  */
11793 static QDF_STATUS
11794 send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle,
11795 			 struct gpio_config_params *param)
11796 {
11797 	wmi_gpio_config_cmd_fixed_param *cmd;
11798 	wmi_buf_t buf;
11799 	int32_t len;
11800 	QDF_STATUS ret;
11801 
11802 	len = sizeof(*cmd);
11803 
11804 	/* Sanity Checks */
11805 	if (param->pull_type > WMI_GPIO_PULL_DOWN ||
11806 	    param->intr_mode > WMI_GPIO_INTTYPE_LEVEL_HIGH) {
11807 		return QDF_STATUS_E_FAILURE;
11808 	}
11809 
11810 	buf = wmi_buf_alloc(wmi_handle, len);
11811 	if (!buf) {
11812 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11813 		return QDF_STATUS_E_FAILURE;
11814 	}
11815 
11816 	cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf);
11817 	WMITLV_SET_HDR(&cmd->tlv_header,
11818 		       WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param,
11819 		       WMITLV_GET_STRUCT_TLVLEN(
11820 				wmi_gpio_config_cmd_fixed_param));
11821 	cmd->gpio_num = param->gpio_num;
11822 	cmd->input = param->input;
11823 	cmd->pull_type = param->pull_type;
11824 	cmd->intr_mode = param->intr_mode;
11825 
11826 	wmi_mtrace(WMI_GPIO_CONFIG_CMDID, NO_SESSION, 0);
11827 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11828 			WMI_GPIO_CONFIG_CMDID);
11829 
11830 	if (ret != 0) {
11831 		WMI_LOGE("Sending GPIO config cmd failed\n");
11832 		wmi_buf_free(buf);
11833 	}
11834 
11835 	return ret;
11836 }
11837 
11838 /**
11839  * send_gpio_output_cmd_tlv() - send gpio output to fw
11840  * @wmi_handle: wmi handle
11841  * @param: pointer to hold gpio output param
11842  *
11843  * Return: 0 for success or error code
11844  */
11845 static QDF_STATUS
11846 send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle,
11847 			 struct gpio_output_params *param)
11848 {
11849 	wmi_gpio_output_cmd_fixed_param *cmd;
11850 	wmi_buf_t buf;
11851 	int32_t len;
11852 	QDF_STATUS ret;
11853 
11854 	len = sizeof(*cmd);
11855 
11856 	buf = wmi_buf_alloc(wmi_handle, len);
11857 	if (!buf) {
11858 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11859 		return QDF_STATUS_E_FAILURE;
11860 	}
11861 
11862 	cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf);
11863 	WMITLV_SET_HDR(&cmd->tlv_header,
11864 		       WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param,
11865 		       WMITLV_GET_STRUCT_TLVLEN(
11866 				wmi_gpio_output_cmd_fixed_param));
11867 	cmd->gpio_num = param->gpio_num;
11868 	cmd->set = param->set;
11869 
11870 	wmi_mtrace(WMI_GPIO_OUTPUT_CMDID, NO_SESSION, 0);
11871 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11872 			WMI_GPIO_OUTPUT_CMDID);
11873 
11874 	if (ret != 0) {
11875 		WMI_LOGE("Sending GPIO output cmd failed\n");
11876 		wmi_buf_free(buf);
11877 	}
11878 
11879 	return ret;
11880 
11881 }
11882 
11883 /**
11884  *  send_phyerr_disable_cmd_tlv() - WMI phyerr disable function
11885  *
11886  *  @param wmi_handle     : handle to WMI.
11887  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11888  */
11889 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle)
11890 {
11891 	wmi_pdev_dfs_disable_cmd_fixed_param *cmd;
11892 	wmi_buf_t buf;
11893 	QDF_STATUS ret;
11894 	int32_t len;
11895 
11896 	len = sizeof(*cmd);
11897 
11898 	buf = wmi_buf_alloc(wmi_handle, len);
11899 	if (!buf) {
11900 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11901 		return QDF_STATUS_E_FAILURE;
11902 	}
11903 
11904 	cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf);
11905 	WMITLV_SET_HDR(&cmd->tlv_header,
11906 		       WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param,
11907 		       WMITLV_GET_STRUCT_TLVLEN(
11908 				wmi_pdev_dfs_disable_cmd_fixed_param));
11909 	/* Filling it with WMI_PDEV_ID_SOC for now */
11910 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
11911 							WMI_HOST_PDEV_ID_SOC);
11912 
11913 	wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0);
11914 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11915 			WMI_PDEV_DFS_DISABLE_CMDID);
11916 
11917 	if (ret != 0) {
11918 		WMI_LOGE("Sending PDEV DFS disable cmd failed\n");
11919 		wmi_buf_free(buf);
11920 	}
11921 
11922 	return ret;
11923 }
11924 
11925 /**
11926  *  send_phyerr_enable_cmd_tlv() - WMI phyerr disable function
11927  *
11928  *  @param wmi_handle     : handle to WMI.
11929  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11930  */
11931 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle)
11932 {
11933 	wmi_pdev_dfs_enable_cmd_fixed_param *cmd;
11934 	wmi_buf_t buf;
11935 	QDF_STATUS ret;
11936 	int32_t len;
11937 
11938 	len = sizeof(*cmd);
11939 
11940 	buf = wmi_buf_alloc(wmi_handle, len);
11941 	if (!buf) {
11942 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11943 		return QDF_STATUS_E_FAILURE;
11944 	}
11945 
11946 	cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf);
11947 	WMITLV_SET_HDR(&cmd->tlv_header,
11948 		       WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param,
11949 		       WMITLV_GET_STRUCT_TLVLEN(
11950 				wmi_pdev_dfs_enable_cmd_fixed_param));
11951 	/* Reserved for future use */
11952 	cmd->reserved0 = 0;
11953 
11954 	wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0);
11955 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
11956 			WMI_PDEV_DFS_ENABLE_CMDID);
11957 
11958 	if (ret != 0) {
11959 		WMI_LOGE("Sending PDEV DFS enable cmd failed\n");
11960 		wmi_buf_free(buf);
11961 	}
11962 
11963 	return ret;
11964 }
11965 
11966 /**
11967  * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd
11968  * to fw
11969  * @wmi_handle: wmi handle
11970  * @param: pointer to hold periodic chan stats param
11971  *
11972  * Return: 0 for success or error code
11973  */
11974 static QDF_STATUS
11975 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle,
11976 				struct periodic_chan_stats_params *param)
11977 {
11978 	wmi_set_periodic_channel_stats_config_fixed_param *cmd;
11979 	wmi_buf_t buf;
11980 	QDF_STATUS ret;
11981 	int32_t len;
11982 
11983 	len = sizeof(*cmd);
11984 
11985 	buf = wmi_buf_alloc(wmi_handle, len);
11986 	if (!buf) {
11987 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
11988 		return QDF_STATUS_E_FAILURE;
11989 	}
11990 
11991 	cmd = (wmi_set_periodic_channel_stats_config_fixed_param *)
11992 					wmi_buf_data(buf);
11993 	WMITLV_SET_HDR(&cmd->tlv_header,
11994 	WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param,
11995 		WMITLV_GET_STRUCT_TLVLEN(
11996 		wmi_set_periodic_channel_stats_config_fixed_param));
11997 	cmd->enable = param->enable;
11998 	cmd->stats_period = param->stats_period;
11999 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
12000 						param->pdev_id);
12001 
12002 	wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0);
12003 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
12004 			WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID);
12005 
12006 	if (ret != 0) {
12007 		WMI_LOGE("Sending periodic chan stats config failed");
12008 		wmi_buf_free(buf);
12009 	}
12010 
12011 	return ret;
12012 }
12013 
12014 /**
12015  * send_nf_dbr_dbm_info_get_cmd_tlv() - send request to get nf to fw
12016  * @wmi_handle: wmi handle
12017  * @mac_id: radio context
12018  *
12019  * Return: 0 for success or error code
12020  */
12021 static QDF_STATUS
12022 send_nf_dbr_dbm_info_get_cmd_tlv(wmi_unified_t wmi_handle, uint8_t mac_id)
12023 {
12024 	wmi_buf_t buf;
12025 	QDF_STATUS ret;
12026 	wmi_pdev_get_nfcal_power_fixed_param *cmd;
12027 	int32_t len = sizeof(*cmd);
12028 
12029 	buf = wmi_buf_alloc(wmi_handle, len);
12030 	if (buf == NULL)
12031 		return QDF_STATUS_E_NOMEM;
12032 
12033 	cmd = (wmi_pdev_get_nfcal_power_fixed_param *)wmi_buf_data(buf);
12034 	WMITLV_SET_HDR(&cmd->tlv_header,
12035 		       WMITLV_TAG_STRUC_wmi_pdev_get_nfcal_power_fixed_param,
12036 		       WMITLV_GET_STRUCT_TLVLEN
12037 				(wmi_pdev_get_nfcal_power_fixed_param));
12038 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
12039 
12040 	wmi_mtrace(WMI_PDEV_GET_NFCAL_POWER_CMDID, NO_SESSION, 0);
12041 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12042 				   WMI_PDEV_GET_NFCAL_POWER_CMDID);
12043 	if (ret != 0) {
12044 		WMI_LOGE("Sending get nfcal power cmd failed\n");
12045 		wmi_buf_free(buf);
12046 	}
12047 
12048 	return ret;
12049 }
12050 
12051 /**
12052  * send_set_ht_ie_cmd_tlv() - send ht ie command to fw
12053  * @wmi_handle: wmi handle
12054  * @param: pointer to ht ie param
12055  *
12056  * Return: 0 for success or error code
12057  */
12058 static QDF_STATUS
12059 send_set_ht_ie_cmd_tlv(wmi_unified_t wmi_handle,
12060 		       struct ht_ie_params *param)
12061 {
12062 	wmi_pdev_set_ht_ie_cmd_fixed_param *cmd;
12063 	wmi_buf_t buf;
12064 	QDF_STATUS ret;
12065 	int32_t len;
12066 	uint8_t *buf_ptr;
12067 
12068 	len = sizeof(*cmd)  + WMI_TLV_HDR_SIZE +
12069 	      roundup(param->ie_len, sizeof(uint32_t));
12070 
12071 	buf = wmi_buf_alloc(wmi_handle, len);
12072 	if (!buf) {
12073 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12074 		return QDF_STATUS_E_FAILURE;
12075 	}
12076 
12077 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12078 	cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *)buf_ptr;
12079 	WMITLV_SET_HDR(&cmd->tlv_header,
12080 		       WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param,
12081 		       WMITLV_GET_STRUCT_TLVLEN(
12082 				wmi_pdev_set_ht_ie_cmd_fixed_param));
12083 	cmd->reserved0 = 0;
12084 	cmd->ie_len = param->ie_len;
12085 	cmd->tx_streams = param->tx_streams;
12086 	cmd->rx_streams = param->rx_streams;
12087 
12088 	buf_ptr += sizeof(*cmd);
12089 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len);
12090 	buf_ptr += WMI_TLV_HDR_SIZE;
12091 	if (param->ie_len)
12092 		WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data,
12093 						cmd->ie_len);
12094 
12095 	wmi_mtrace(WMI_PDEV_SET_HT_CAP_IE_CMDID, NO_SESSION, 0);
12096 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12097 				   WMI_PDEV_SET_HT_CAP_IE_CMDID);
12098 
12099 	if (ret != 0) {
12100 		WMI_LOGE("Sending set ht ie cmd failed\n");
12101 		wmi_buf_free(buf);
12102 	}
12103 
12104 	return ret;
12105 }
12106 
12107 /**
12108  * send_set_vht_ie_cmd_tlv() - send vht ie command to fw
12109  * @wmi_handle: wmi handle
12110  * @param: pointer to vht ie param
12111  *
12112  * Return: 0 for success or error code
12113  */
12114 static QDF_STATUS
12115 send_set_vht_ie_cmd_tlv(wmi_unified_t wmi_handle,
12116 			struct vht_ie_params *param)
12117 {
12118 	wmi_pdev_set_vht_ie_cmd_fixed_param *cmd;
12119 	wmi_buf_t buf;
12120 	QDF_STATUS ret;
12121 	int32_t len;
12122 	uint8_t *buf_ptr;
12123 
12124 	len = sizeof(*cmd)  + WMI_TLV_HDR_SIZE +
12125 	      roundup(param->ie_len, sizeof(uint32_t));
12126 
12127 	buf = wmi_buf_alloc(wmi_handle, len);
12128 	if (!buf) {
12129 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12130 		return QDF_STATUS_E_FAILURE;
12131 	}
12132 
12133 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12134 	cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *)buf_ptr;
12135 	WMITLV_SET_HDR(&cmd->tlv_header,
12136 		       WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param,
12137 		       WMITLV_GET_STRUCT_TLVLEN(
12138 				wmi_pdev_set_vht_ie_cmd_fixed_param));
12139 	cmd->reserved0 = 0;
12140 	cmd->ie_len = param->ie_len;
12141 	cmd->tx_streams = param->tx_streams;
12142 	cmd->rx_streams = param->rx_streams;
12143 
12144 	buf_ptr += sizeof(*cmd);
12145 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len);
12146 	buf_ptr += WMI_TLV_HDR_SIZE;
12147 	if (param->ie_len)
12148 		WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data,
12149 						cmd->ie_len);
12150 
12151 	wmi_mtrace(WMI_PDEV_SET_VHT_CAP_IE_CMDID, NO_SESSION, 0);
12152 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12153 				   WMI_PDEV_SET_VHT_CAP_IE_CMDID);
12154 
12155 	if (ret != 0) {
12156 		WMI_LOGE("Sending set vht ie cmd failed\n");
12157 		wmi_buf_free(buf);
12158 	}
12159 
12160 	return ret;
12161 }
12162 
12163 /**
12164  * send_set_quiet_mode_cmd_tlv() - send set quiet mode command to fw
12165  * @wmi_handle: wmi handle
12166  * @param: pointer to quiet mode params
12167  *
12168  * Return: 0 for success or error code
12169  */
12170 static QDF_STATUS
12171 send_set_quiet_mode_cmd_tlv(wmi_unified_t wmi_handle,
12172 			    struct set_quiet_mode_params *param)
12173 {
12174 	wmi_pdev_set_quiet_cmd_fixed_param *quiet_cmd;
12175 	wmi_buf_t buf;
12176 	QDF_STATUS ret;
12177 	int32_t len;
12178 
12179 	len = sizeof(*quiet_cmd);
12180 	buf = wmi_buf_alloc(wmi_handle, len);
12181 	if (!buf) {
12182 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12183 		return QDF_STATUS_E_FAILURE;
12184 	}
12185 
12186 	quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf);
12187 	WMITLV_SET_HDR(&quiet_cmd->tlv_header,
12188 		       WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param,
12189 		       WMITLV_GET_STRUCT_TLVLEN(
12190 				wmi_pdev_set_quiet_cmd_fixed_param));
12191 	quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf);
12192 	quiet_cmd->enabled = param->enabled;
12193 	quiet_cmd->period = (param->period)*(param->intval);
12194 	quiet_cmd->duration = param->duration;
12195 	quiet_cmd->next_start = param->offset;
12196 	quiet_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
12197 							WMI_HOST_PDEV_ID_SOC);
12198 
12199 	wmi_mtrace(WMI_PDEV_SET_QUIET_MODE_CMDID, NO_SESSION, 0);
12200 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12201 				   WMI_PDEV_SET_QUIET_MODE_CMDID);
12202 
12203 	if (ret != 0) {
12204 		WMI_LOGE("Sending set quiet cmd failed\n");
12205 		wmi_buf_free(buf);
12206 	}
12207 
12208 	return ret;
12209 }
12210 
12211 /**
12212  * send_set_bwf_cmd_tlv() - send set bwf command to fw
12213  * @wmi_handle: wmi handle
12214  * @param: pointer to set bwf param
12215  *
12216  * Return: 0 for success or error code
12217  */
12218 static QDF_STATUS
12219 send_set_bwf_cmd_tlv(wmi_unified_t wmi_handle,
12220 		     struct set_bwf_params *param)
12221 {
12222 	wmi_bwf_peer_info *peer_info;
12223 	wmi_peer_bwf_request_fixed_param *cmd;
12224 	wmi_buf_t buf;
12225 	QDF_STATUS retval;
12226 	int32_t len;
12227 	uint8_t *buf_ptr;
12228 	int i;
12229 
12230 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
12231 	len += param->num_peers * sizeof(wmi_bwf_peer_info);
12232 	buf = wmi_buf_alloc(wmi_handle, len);
12233 	if (!buf) {
12234 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
12235 		return QDF_STATUS_E_FAILURE;
12236 	}
12237 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12238 	cmd = (wmi_peer_bwf_request_fixed_param *)buf_ptr;
12239 	WMITLV_SET_HDR(&cmd->tlv_header,
12240 		       WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param,
12241 		       WMITLV_GET_STRUCT_TLVLEN(
12242 				wmi_peer_bwf_request_fixed_param));
12243 	cmd->num_peers = param->num_peers;
12244 
12245 	buf_ptr += sizeof(*cmd);
12246 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
12247 		       sizeof(wmi_bwf_peer_info) *
12248 		       cmd->num_peers);
12249 	buf_ptr += WMI_TLV_HDR_SIZE;
12250 	peer_info = (wmi_bwf_peer_info *)buf_ptr;
12251 
12252 	for (i = 0; i < cmd->num_peers; i++) {
12253 		WMITLV_SET_HDR(&peer_info->tlv_header,
12254 			       WMITLV_TAG_STRUC_wmi_bwf_peer_info,
12255 			       WMITLV_GET_STRUCT_TLVLEN(wmi_bwf_peer_info));
12256 		peer_info->bwf_guaranteed_bandwidth =
12257 				param->peer_info[i].throughput;
12258 		peer_info->bwf_max_airtime =
12259 				param->peer_info[i].max_airtime;
12260 		peer_info->bwf_peer_priority =
12261 				param->peer_info[i].priority;
12262 		qdf_mem_copy(&peer_info->peer_macaddr,
12263 			     &param->peer_info[i].peer_macaddr,
12264 			     sizeof(param->peer_info[i].peer_macaddr));
12265 		peer_info->vdev_id =
12266 				param->peer_info[i].vdev_id;
12267 		peer_info->pdev_id =
12268 			wmi_handle->ops->convert_pdev_id_host_to_target(
12269 				param->peer_info[i].pdev_id);
12270 		peer_info++;
12271 	}
12272 
12273 	wmi_mtrace(WMI_PEER_BWF_REQUEST_CMDID, NO_SESSION, 0);
12274 	retval = wmi_unified_cmd_send(wmi_handle, buf, len,
12275 				      WMI_PEER_BWF_REQUEST_CMDID);
12276 
12277 	if (retval != QDF_STATUS_SUCCESS) {
12278 		WMI_LOGE("%s : WMI Failed\n", __func__);
12279 		wmi_buf_free(buf);
12280 	}
12281 
12282 	return retval;
12283 }
12284 
12285 /**
12286  * send_mcast_group_update_cmd_tlv() - send mcast group update cmd to fw
12287  * @wmi_handle: wmi handle
12288  * @param: pointer to hold mcast update param
12289  *
12290  * Return: 0 for success or error code
12291  */
12292 static QDF_STATUS
12293 send_mcast_group_update_cmd_tlv(wmi_unified_t wmi_handle,
12294 				struct mcast_group_update_params *param)
12295 {
12296 	wmi_peer_mcast_group_cmd_fixed_param *cmd;
12297 	wmi_buf_t buf;
12298 	QDF_STATUS ret;
12299 	int32_t len;
12300 	int offset = 0;
12301 	static char dummymask[4] = { 0xFF, 0xFF, 0xFF, 0xFF};
12302 
12303 	len = sizeof(*cmd);
12304 	buf = wmi_buf_alloc(wmi_handle, len);
12305 	if (!buf) {
12306 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12307 		return QDF_STATUS_E_FAILURE;
12308 	}
12309 	cmd = (wmi_peer_mcast_group_cmd_fixed_param *)wmi_buf_data(buf);
12310 	WMITLV_SET_HDR(&cmd->tlv_header,
12311 		       WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param,
12312 		       WMITLV_GET_STRUCT_TLVLEN(
12313 				wmi_peer_mcast_group_cmd_fixed_param));
12314 	/* confirm the buffer is 4-byte aligned */
12315 	QDF_ASSERT((((size_t) cmd) & 0x3) == 0);
12316 	qdf_mem_zero(cmd, sizeof(*cmd));
12317 
12318 	cmd->vdev_id = param->vap_id;
12319 	/* construct the message assuming our endianness matches the target */
12320 	cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_ACTION_M &
12321 		(param->action << WMI_PEER_MCAST_GROUP_FLAG_ACTION_S);
12322 	cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M &
12323 		(param->wildcard << WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S);
12324 	if (param->is_action_delete)
12325 		cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_DELETEALL_M;
12326 
12327 	if (param->is_mcast_addr_len)
12328 		cmd->flags |=  WMI_PEER_MCAST_GROUP_FLAG_IPV6_M;
12329 
12330 	if (param->is_filter_mode_snoop)
12331 		cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_SRC_FILTER_EXCLUDE_M;
12332 
12333 	/* unicast address spec only applies for non-wildcard cases */
12334 	if (!param->wildcard && param->ucast_mac_addr) {
12335 		WMI_CHAR_ARRAY_TO_MAC_ADDR(param->ucast_mac_addr,
12336 					   &cmd->ucast_mac_addr);
12337 	}
12338 
12339 	if (param->mcast_ip_addr) {
12340 		QDF_ASSERT(param->mcast_ip_addr_bytes <=
12341 			   sizeof(cmd->mcast_ip_addr));
12342 		offset = sizeof(cmd->mcast_ip_addr) -
12343 			 param->mcast_ip_addr_bytes;
12344 		qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_addr) + offset,
12345 			     param->mcast_ip_addr,
12346 			     param->mcast_ip_addr_bytes);
12347 	}
12348 	if (!param->mask)
12349 		param->mask = &dummymask[0];
12350 
12351 	qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_mask) + offset,
12352 		     param->mask,
12353 		     param->mcast_ip_addr_bytes);
12354 
12355 	if (param->srcs && param->nsrcs) {
12356 		cmd->num_filter_addr = param->nsrcs;
12357 		QDF_ASSERT((param->nsrcs * param->mcast_ip_addr_bytes) <=
12358 			sizeof(cmd->filter_addr));
12359 
12360 		qdf_mem_copy(((uint8_t *) &cmd->filter_addr), param->srcs,
12361 			     param->nsrcs * param->mcast_ip_addr_bytes);
12362 	}
12363 
12364 	wmi_mtrace(WMI_PEER_MCAST_GROUP_CMDID, cmd->vdev_id, 0);
12365 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12366 				      WMI_PEER_MCAST_GROUP_CMDID);
12367 
12368 	if (ret != QDF_STATUS_SUCCESS) {
12369 		WMI_LOGE("%s : WMI Failed\n", __func__);
12370 		wmi_buf_free(buf);
12371 	}
12372 
12373 	return ret;
12374 }
12375 
12376 /**
12377  * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure
12378  * command to fw
12379  * @wmi_handle: wmi handle
12380  * @param: pointer to hold spectral config parameter
12381  *
12382  * Return: 0 for success or error code
12383  */
12384 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle,
12385 				struct vdev_spectral_configure_params *param)
12386 {
12387 	wmi_vdev_spectral_configure_cmd_fixed_param *cmd;
12388 	wmi_buf_t buf;
12389 	QDF_STATUS ret;
12390 	int32_t len;
12391 
12392 	len = sizeof(*cmd);
12393 	buf = wmi_buf_alloc(wmi_handle, len);
12394 	if (!buf) {
12395 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12396 		return QDF_STATUS_E_FAILURE;
12397 	}
12398 
12399 	cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf);
12400 	WMITLV_SET_HDR(&cmd->tlv_header,
12401 		WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param,
12402 		WMITLV_GET_STRUCT_TLVLEN(
12403 		wmi_vdev_spectral_configure_cmd_fixed_param));
12404 
12405 	cmd->vdev_id = param->vdev_id;
12406 	cmd->spectral_scan_count = param->count;
12407 	cmd->spectral_scan_period = param->period;
12408 	cmd->spectral_scan_priority = param->spectral_pri;
12409 	cmd->spectral_scan_fft_size = param->fft_size;
12410 	cmd->spectral_scan_gc_ena = param->gc_enable;
12411 	cmd->spectral_scan_restart_ena = param->restart_enable;
12412 	cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref;
12413 	cmd->spectral_scan_init_delay = param->init_delay;
12414 	cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr;
12415 	cmd->spectral_scan_str_bin_thr = param->str_bin_thr;
12416 	cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode;
12417 	cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode;
12418 	cmd->spectral_scan_rssi_thr = param->rssi_thr;
12419 	cmd->spectral_scan_pwr_format = param->pwr_format;
12420 	cmd->spectral_scan_rpt_mode = param->rpt_mode;
12421 	cmd->spectral_scan_bin_scale = param->bin_scale;
12422 	cmd->spectral_scan_dBm_adj = param->dbm_adj;
12423 	cmd->spectral_scan_chn_mask = param->chn_mask;
12424 
12425 	wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0);
12426 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12427 				   WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID);
12428 
12429 	if (ret != 0) {
12430 		WMI_LOGE("Sending set quiet cmd failed\n");
12431 		wmi_buf_free(buf);
12432 	}
12433 
12434 	WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID\n",
12435 		 __func__);
12436 
12437 	WMI_LOGI("vdev_id = %u\n"
12438 		 "spectral_scan_count = %u\n"
12439 		 "spectral_scan_period = %u\n"
12440 		 "spectral_scan_priority = %u\n"
12441 		 "spectral_scan_fft_size = %u\n"
12442 		 "spectral_scan_gc_ena = %u\n"
12443 		 "spectral_scan_restart_ena = %u\n"
12444 		 "spectral_scan_noise_floor_ref = %u\n"
12445 		 "spectral_scan_init_delay = %u\n"
12446 		 "spectral_scan_nb_tone_thr = %u\n"
12447 		 "spectral_scan_str_bin_thr = %u\n"
12448 		 "spectral_scan_wb_rpt_mode = %u\n"
12449 		 "spectral_scan_rssi_rpt_mode = %u\n"
12450 		 "spectral_scan_rssi_thr = %u\n"
12451 		 "spectral_scan_pwr_format = %u\n"
12452 		 "spectral_scan_rpt_mode = %u\n"
12453 		 "spectral_scan_bin_scale = %u\n"
12454 		 "spectral_scan_dBm_adj = %u\n"
12455 		 "spectral_scan_chn_mask = %u\n",
12456 		 param->vdev_id,
12457 		 param->count,
12458 		 param->period,
12459 		 param->spectral_pri,
12460 		 param->fft_size,
12461 		 param->gc_enable,
12462 		 param->restart_enable,
12463 		 param->noise_floor_ref,
12464 		 param->init_delay,
12465 		 param->nb_tone_thr,
12466 		 param->str_bin_thr,
12467 		 param->wb_rpt_mode,
12468 		 param->rssi_rpt_mode,
12469 		 param->rssi_thr,
12470 		 param->pwr_format,
12471 		 param->rpt_mode,
12472 		 param->bin_scale,
12473 		 param->dbm_adj,
12474 		 param->chn_mask);
12475 	WMI_LOGI("%s: Status: %d\n\n", __func__, ret);
12476 
12477 	return ret;
12478 }
12479 
12480 /**
12481  * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure
12482  * command to fw
12483  * @wmi_handle: wmi handle
12484  * @param: pointer to hold spectral enable parameter
12485  *
12486  * Return: 0 for success or error code
12487  */
12488 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle,
12489 				struct vdev_spectral_enable_params *param)
12490 {
12491 	wmi_vdev_spectral_enable_cmd_fixed_param *cmd;
12492 	wmi_buf_t buf;
12493 	QDF_STATUS ret;
12494 	int32_t len;
12495 
12496 	len = sizeof(*cmd);
12497 	buf = wmi_buf_alloc(wmi_handle, len);
12498 	if (!buf) {
12499 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12500 		return QDF_STATUS_E_FAILURE;
12501 	}
12502 
12503 	cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf);
12504 	WMITLV_SET_HDR(&cmd->tlv_header,
12505 		WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param,
12506 		WMITLV_GET_STRUCT_TLVLEN(
12507 		wmi_vdev_spectral_enable_cmd_fixed_param));
12508 
12509 	cmd->vdev_id = param->vdev_id;
12510 
12511 	if (param->active_valid) {
12512 		cmd->trigger_cmd = param->active ? 1 : 2;
12513 		/* 1: Trigger, 2: Clear Trigger */
12514 	} else {
12515 		cmd->trigger_cmd = 0; /* 0: Ignore */
12516 	}
12517 
12518 	if (param->enabled_valid) {
12519 		cmd->enable_cmd = param->enabled ? 1 : 2;
12520 		/* 1: Enable 2: Disable */
12521 	} else {
12522 		cmd->enable_cmd = 0; /* 0: Ignore */
12523 	}
12524 
12525 	wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0);
12526 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12527 				   WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID);
12528 
12529 	if (ret != 0) {
12530 		WMI_LOGE("Sending scan enable CMD failed\n");
12531 		wmi_buf_free(buf);
12532 	}
12533 
12534 	WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID\n", __func__);
12535 
12536 	WMI_LOGI("vdev_id = %u\n"
12537 				 "trigger_cmd = %u\n"
12538 				 "enable_cmd = %u\n",
12539 				 cmd->vdev_id,
12540 				 cmd->trigger_cmd,
12541 				 cmd->enable_cmd);
12542 
12543 	WMI_LOGI("%s: Status: %d\n\n", __func__, ret);
12544 
12545 	return ret;
12546 }
12547 
12548 /**
12549  * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params
12550  * @param wmi_handle : handle to WMI.
12551  * @param param : pointer to hold thermal mitigation param
12552  *
12553  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
12554  */
12555 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv(
12556 		wmi_unified_t wmi_handle,
12557 		struct thermal_mitigation_params *param)
12558 {
12559 	wmi_therm_throt_config_request_fixed_param *tt_conf = NULL;
12560 	wmi_therm_throt_level_config_info *lvl_conf = NULL;
12561 	wmi_buf_t buf = NULL;
12562 	uint8_t *buf_ptr = NULL;
12563 	int error;
12564 	int32_t len;
12565 	int i;
12566 
12567 	len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE +
12568 			THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info);
12569 
12570 	buf = wmi_buf_alloc(wmi_handle, len);
12571 	if (!buf) {
12572 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
12573 		return QDF_STATUS_E_NOMEM;
12574 	}
12575 	tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf);
12576 
12577 	/* init fixed params */
12578 	WMITLV_SET_HDR(tt_conf,
12579 		WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param,
12580 		(WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param)));
12581 
12582 	tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
12583 								param->pdev_id);
12584 	tt_conf->enable = param->enable;
12585 	tt_conf->dc = param->dc;
12586 	tt_conf->dc_per_event = param->dc_per_event;
12587 	tt_conf->therm_throt_levels = THERMAL_LEVELS;
12588 
12589 	buf_ptr = (uint8_t *) ++tt_conf;
12590 	/* init TLV params */
12591 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
12592 			(THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info)));
12593 
12594 	lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr +  WMI_TLV_HDR_SIZE);
12595 	for (i = 0; i < THERMAL_LEVELS; i++) {
12596 		WMITLV_SET_HDR(&lvl_conf->tlv_header,
12597 			WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info,
12598 			WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info));
12599 		lvl_conf->temp_lwm = param->levelconf[i].tmplwm;
12600 		lvl_conf->temp_hwm = param->levelconf[i].tmphwm;
12601 		lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent;
12602 		lvl_conf->prio = param->levelconf[i].priority;
12603 		lvl_conf++;
12604 	}
12605 
12606 	wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0);
12607 	error = wmi_unified_cmd_send(wmi_handle, buf, len,
12608 			WMI_THERM_THROT_SET_CONF_CMDID);
12609 	if (QDF_IS_STATUS_ERROR(error)) {
12610 		wmi_buf_free(buf);
12611 		WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command");
12612 	}
12613 
12614 	return error;
12615 }
12616 
12617 /**
12618  * send_pdev_qvit_cmd_tlv() - send qvit command to fw
12619  * @wmi_handle: wmi handle
12620  * @param: pointer to pdev_qvit_params
12621  *
12622  * Return: 0 for success or error code
12623  */
12624 static QDF_STATUS
12625 send_pdev_qvit_cmd_tlv(wmi_unified_t wmi_handle,
12626 		       struct pdev_qvit_params *param)
12627 {
12628 	wmi_buf_t buf;
12629 	QDF_STATUS ret = QDF_STATUS_E_INVAL;
12630 	uint8_t *cmd;
12631 	static uint8_t msgref = 1;
12632 	uint8_t segnumber = 0, seginfo, numsegments;
12633 	uint16_t chunk_len, total_bytes;
12634 	uint8_t *bufpos;
12635 	QVIT_SEG_HDR_INFO_STRUCT seghdrinfo;
12636 
12637 	bufpos = param->utf_payload;
12638 	total_bytes = param->len;
12639 	ASSERT(total_bytes / MAX_WMI_QVIT_LEN ==
12640 	       (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN));
12641 	numsegments = (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN);
12642 
12643 	if (param->len - (numsegments * MAX_WMI_QVIT_LEN))
12644 		numsegments++;
12645 
12646 	while (param->len) {
12647 		if (param->len > MAX_WMI_QVIT_LEN)
12648 			chunk_len = MAX_WMI_QVIT_LEN;    /* MAX message */
12649 		else
12650 			chunk_len = param->len;
12651 
12652 		buf = wmi_buf_alloc(wmi_handle,
12653 				    (chunk_len + sizeof(seghdrinfo) +
12654 				     WMI_TLV_HDR_SIZE));
12655 		if (!buf) {
12656 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
12657 			return QDF_STATUS_E_NOMEM;
12658 		}
12659 
12660 		cmd = (uint8_t *) wmi_buf_data(buf);
12661 
12662 		seghdrinfo.len = total_bytes;
12663 		seghdrinfo.msgref = msgref;
12664 		seginfo = ((numsegments << 4) & 0xF0) | (segnumber & 0xF);
12665 		seghdrinfo.segmentInfo = seginfo;
12666 
12667 		segnumber++;
12668 
12669 		WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE,
12670 			       (chunk_len + sizeof(seghdrinfo)));
12671 		cmd += WMI_TLV_HDR_SIZE;
12672 		qdf_mem_copy(cmd, &seghdrinfo, sizeof(seghdrinfo));
12673 		qdf_mem_copy(&cmd[sizeof(seghdrinfo)], bufpos, chunk_len);
12674 
12675 		wmi_mtrace(WMI_PDEV_QVIT_CMDID, NO_SESSION, 0);
12676 		ret = wmi_unified_cmd_send(wmi_handle, buf,
12677 					   (chunk_len + sizeof(seghdrinfo) +
12678 					    WMI_TLV_HDR_SIZE),
12679 					   WMI_PDEV_QVIT_CMDID);
12680 
12681 		if (ret != 0) {
12682 			WMI_LOGE("Failed to send WMI_PDEV_QVIT_CMDID command");
12683 			wmi_buf_free(buf);
12684 			break;
12685 		}
12686 
12687 		param->len -= chunk_len;
12688 		bufpos += chunk_len;
12689 	}
12690 	msgref++;
12691 
12692 	return ret;
12693 }
12694 
12695 /**
12696  * send_wmm_update_cmd_tlv() - send wmm update command to fw
12697  * @wmi_handle: wmi handle
12698  * @param: pointer to wmm update param
12699  *
12700  * Return: 0 for success or error code
12701  */
12702 static QDF_STATUS
12703 send_wmm_update_cmd_tlv(wmi_unified_t wmi_handle,
12704 			struct wmm_update_params *param)
12705 {
12706 	wmi_pdev_set_wmm_params_cmd_fixed_param *cmd;
12707 	wmi_wmm_params *wmm_param;
12708 	wmi_buf_t buf;
12709 	QDF_STATUS ret;
12710 	int32_t len;
12711 	int ac = 0;
12712 	struct wmi_host_wmeParams *wmep;
12713 	uint8_t *buf_ptr;
12714 
12715 	len = sizeof(*cmd) + (WME_NUM_AC * sizeof(*wmm_param));
12716 	buf = wmi_buf_alloc(wmi_handle, len);
12717 	if (!buf) {
12718 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12719 		return QDF_STATUS_E_FAILURE;
12720 	}
12721 
12722 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
12723 	cmd = (wmi_pdev_set_wmm_params_cmd_fixed_param *) buf_ptr;
12724 	WMITLV_SET_HDR(&cmd->tlv_header,
12725 		       WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param,
12726 		       WMITLV_GET_STRUCT_TLVLEN
12727 			       (wmi_pdev_set_wmm_params_cmd_fixed_param));
12728 
12729 	cmd->reserved0 = WMI_HOST_PDEV_ID_SOC;
12730 
12731 	buf_ptr += sizeof(wmi_pdev_set_wmm_params_cmd_fixed_param);
12732 
12733 	for (ac = 0; ac < WME_NUM_AC; ac++) {
12734 		wmep = &param->wmep_array[ac];
12735 		wmm_param = (wmi_wmm_params *)buf_ptr;
12736 		WMITLV_SET_HDR(&wmm_param->tlv_header,
12737 			WMITLV_TAG_STRUC_wmi_wmm_params,
12738 			WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params));
12739 		wmm_param->aifs = wmep->wmep_aifsn;
12740 		wmm_param->cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
12741 		wmm_param->cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
12742 		wmm_param->txoplimit = ATH_TXOP_TO_US(wmep->wmep_txopLimit);
12743 		wmm_param->acm = wmep->wmep_acm;
12744 		wmm_param->no_ack = wmep->wmep_noackPolicy;
12745 		buf_ptr += sizeof(wmi_wmm_params);
12746 	}
12747 	wmi_mtrace(WMI_PDEV_SET_WMM_PARAMS_CMDID, NO_SESSION, 0);
12748 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12749 				   WMI_PDEV_SET_WMM_PARAMS_CMDID);
12750 
12751 	if (ret != 0) {
12752 		WMI_LOGE("Sending WMM update CMD failed\n");
12753 		wmi_buf_free(buf);
12754 	}
12755 
12756 	return ret;
12757 }
12758 
12759 /**
12760  * send_coex_config_cmd_tlv() - send coex config command to fw
12761  * @wmi_handle: wmi handle
12762  * @param: pointer to coex config param
12763  *
12764  * Return: 0 for success or error code
12765  */
12766 static QDF_STATUS
12767 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle,
12768 			 struct coex_config_params *param)
12769 {
12770 	WMI_COEX_CONFIG_CMD_fixed_param *cmd;
12771 	wmi_buf_t buf;
12772 	QDF_STATUS ret;
12773 	int32_t len;
12774 
12775 	len = sizeof(*cmd);
12776 	buf = wmi_buf_alloc(wmi_handle, len);
12777 	if (!buf) {
12778 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12779 		return QDF_STATUS_E_FAILURE;
12780 	}
12781 
12782 	cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf);
12783 	WMITLV_SET_HDR(&cmd->tlv_header,
12784 		       WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param,
12785 		       WMITLV_GET_STRUCT_TLVLEN(
12786 		       WMI_COEX_CONFIG_CMD_fixed_param));
12787 
12788 	cmd->vdev_id = param->vdev_id;
12789 	cmd->config_type = param->config_type;
12790 	cmd->config_arg1 = param->config_arg1;
12791 	cmd->config_arg2 = param->config_arg2;
12792 	cmd->config_arg3 = param->config_arg3;
12793 	cmd->config_arg4 = param->config_arg4;
12794 	cmd->config_arg5 = param->config_arg5;
12795 	cmd->config_arg6 = param->config_arg6;
12796 
12797 	wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0);
12798 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12799 				   WMI_COEX_CONFIG_CMDID);
12800 
12801 	if (ret != 0) {
12802 		WMI_LOGE("Sending COEX CONFIG CMD failed\n");
12803 		wmi_buf_free(buf);
12804 	}
12805 
12806 	return ret;
12807 }
12808 
12809 
12810 #ifdef WLAN_SUPPORT_TWT
12811 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg,
12812 					target_resource_config *tgt_res_cfg)
12813 {
12814 	resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count;
12815 	resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count;
12816 }
12817 #else
12818 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg,
12819 					target_resource_config *tgt_res_cfg)
12820 {
12821 	resource_cfg->twt_ap_pdev_count = 0;
12822 	resource_cfg->twt_ap_sta_count = 0;
12823 }
12824 #endif
12825 
12826 static
12827 void wmi_copy_resource_config(wmi_resource_config *resource_cfg,
12828 				target_resource_config *tgt_res_cfg)
12829 {
12830 	resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs;
12831 	resource_cfg->num_peers = tgt_res_cfg->num_peers;
12832 	resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers;
12833 	resource_cfg->num_offload_reorder_buffs =
12834 			tgt_res_cfg->num_offload_reorder_buffs;
12835 	resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys;
12836 	resource_cfg->num_tids = tgt_res_cfg->num_tids;
12837 	resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit;
12838 	resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask;
12839 	resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask;
12840 	resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0];
12841 	resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1];
12842 	resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2];
12843 	resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3];
12844 	resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode;
12845 	resource_cfg->scan_max_pending_req =
12846 			tgt_res_cfg->scan_max_pending_req;
12847 	resource_cfg->bmiss_offload_max_vdev =
12848 			tgt_res_cfg->bmiss_offload_max_vdev;
12849 	resource_cfg->roam_offload_max_vdev =
12850 			tgt_res_cfg->roam_offload_max_vdev;
12851 	resource_cfg->roam_offload_max_ap_profiles =
12852 			tgt_res_cfg->roam_offload_max_ap_profiles;
12853 	resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups;
12854 	resource_cfg->num_mcast_table_elems =
12855 			tgt_res_cfg->num_mcast_table_elems;
12856 	resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode;
12857 	resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size;
12858 	resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries;
12859 	resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size;
12860 	resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim;
12861 	resource_cfg->rx_skip_defrag_timeout_dup_detection_check =
12862 		tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check;
12863 	resource_cfg->vow_config = tgt_res_cfg->vow_config;
12864 	resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev;
12865 	resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc;
12866 	resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries;
12867 	resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs;
12868 	resource_cfg->num_tdls_conn_table_entries =
12869 			tgt_res_cfg->num_tdls_conn_table_entries;
12870 	resource_cfg->beacon_tx_offload_max_vdev =
12871 			tgt_res_cfg->beacon_tx_offload_max_vdev;
12872 	resource_cfg->num_multicast_filter_entries =
12873 			tgt_res_cfg->num_multicast_filter_entries;
12874 	resource_cfg->num_wow_filters =
12875 			tgt_res_cfg->num_wow_filters;
12876 	resource_cfg->num_keep_alive_pattern =
12877 			tgt_res_cfg->num_keep_alive_pattern;
12878 	resource_cfg->keep_alive_pattern_size =
12879 			tgt_res_cfg->keep_alive_pattern_size;
12880 	resource_cfg->max_tdls_concurrent_sleep_sta =
12881 			tgt_res_cfg->max_tdls_concurrent_sleep_sta;
12882 	resource_cfg->max_tdls_concurrent_buffer_sta =
12883 			tgt_res_cfg->max_tdls_concurrent_buffer_sta;
12884 	resource_cfg->wmi_send_separate =
12885 			tgt_res_cfg->wmi_send_separate;
12886 	resource_cfg->num_ocb_vdevs =
12887 			tgt_res_cfg->num_ocb_vdevs;
12888 	resource_cfg->num_ocb_channels =
12889 			tgt_res_cfg->num_ocb_channels;
12890 	resource_cfg->num_ocb_schedules =
12891 			tgt_res_cfg->num_ocb_schedules;
12892 	resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size;
12893 	resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters;
12894 	resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id;
12895 	resource_cfg->max_num_dbs_scan_duty_cycle =
12896 		tgt_res_cfg->max_num_dbs_scan_duty_cycle;
12897 	resource_cfg->sched_params = tgt_res_cfg->scheduler_params;
12898 	resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters;
12899 	resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs;
12900 	resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator;
12901 	if (tgt_res_cfg->atf_config)
12902 		WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1);
12903 	if (tgt_res_cfg->mgmt_comp_evt_bundle_support)
12904 		WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET(
12905 			resource_cfg->flag1, 1);
12906 	if (tgt_res_cfg->tx_msdu_new_partition_id_support)
12907 		WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET(
12908 			resource_cfg->flag1, 1);
12909 	if (tgt_res_cfg->cce_disable)
12910 		WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1);
12911 
12912 	wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg);
12913 }
12914 
12915 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd
12916  * @wmi_handle: pointer to wmi handle
12917  * @buf_ptr: pointer to current position in init command buffer
12918  * @len: pointer to length. This will be updated with current length of cmd
12919  * @param: point host parameters for init command
12920  *
12921  * Return: Updated pointer of buf_ptr.
12922  */
12923 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle,
12924 		uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param)
12925 {
12926 	uint16_t idx;
12927 
12928 	if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) {
12929 		wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode;
12930 		wmi_pdev_band_to_mac *band_to_mac;
12931 
12932 		hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *)
12933 			(buf_ptr + sizeof(wmi_init_cmd_fixed_param) +
12934 			 sizeof(wmi_resource_config) +
12935 			 WMI_TLV_HDR_SIZE + (param->num_mem_chunks *
12936 				 sizeof(wlan_host_memory_chunk)));
12937 
12938 		WMITLV_SET_HDR(&hw_mode->tlv_header,
12939 			WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param,
12940 			(WMITLV_GET_STRUCT_TLVLEN
12941 			 (wmi_pdev_set_hw_mode_cmd_fixed_param)));
12942 
12943 		hw_mode->hw_mode_index = param->hw_mode_id;
12944 		hw_mode->num_band_to_mac = param->num_band_to_mac;
12945 
12946 		buf_ptr = (uint8_t *) (hw_mode + 1);
12947 		band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr +
12948 				WMI_TLV_HDR_SIZE);
12949 		for (idx = 0; idx < param->num_band_to_mac; idx++) {
12950 			WMITLV_SET_HDR(&band_to_mac[idx].tlv_header,
12951 					WMITLV_TAG_STRUC_wmi_pdev_band_to_mac,
12952 					WMITLV_GET_STRUCT_TLVLEN
12953 					(wmi_pdev_band_to_mac));
12954 			band_to_mac[idx].pdev_id =
12955 				wmi_handle->ops->convert_pdev_id_host_to_target(
12956 					param->band_to_mac[idx].pdev_id);
12957 			band_to_mac[idx].start_freq =
12958 				param->band_to_mac[idx].start_freq;
12959 			band_to_mac[idx].end_freq =
12960 				param->band_to_mac[idx].end_freq;
12961 		}
12962 		*len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) +
12963 			(param->num_band_to_mac *
12964 			 sizeof(wmi_pdev_band_to_mac)) +
12965 			WMI_TLV_HDR_SIZE;
12966 
12967 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
12968 				(param->num_band_to_mac *
12969 				 sizeof(wmi_pdev_band_to_mac)));
12970 	}
12971 
12972 	return buf_ptr;
12973 }
12974 
12975 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle,
12976 		wmi_init_cmd_fixed_param *cmd)
12977 {
12978 	int num_whitelist;
12979 	wmi_abi_version my_vers;
12980 
12981 	num_whitelist = sizeof(version_whitelist) /
12982 		sizeof(wmi_whitelist_version_info);
12983 	my_vers.abi_version_0 = WMI_ABI_VERSION_0;
12984 	my_vers.abi_version_1 = WMI_ABI_VERSION_1;
12985 	my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0;
12986 	my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1;
12987 	my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2;
12988 	my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3;
12989 
12990 	wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist,
12991 			&my_vers,
12992 			(struct _wmi_abi_version *)&wmi_handle->fw_abi_version,
12993 			&cmd->host_abi_vers);
12994 
12995 	qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x",
12996 			__func__,
12997 			WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0),
12998 			WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0),
12999 			cmd->host_abi_vers.abi_version_ns_0,
13000 			cmd->host_abi_vers.abi_version_ns_1,
13001 			cmd->host_abi_vers.abi_version_ns_2,
13002 			cmd->host_abi_vers.abi_version_ns_3);
13003 
13004 	/* Save version sent from host -
13005 	 * Will be used to check ready event
13006 	 */
13007 	qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers,
13008 			sizeof(wmi_abi_version));
13009 }
13010 
13011 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf)
13012 {
13013 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
13014 	wmi_service_ready_event_fixed_param *ev;
13015 
13016 
13017 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
13018 
13019 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
13020 	if (!ev)
13021 		return QDF_STATUS_E_FAILURE;
13022 
13023 	/*Save fw version from service ready message */
13024 	/*This will be used while sending INIT message */
13025 	qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
13026 			sizeof(wmi_handle->fw_abi_version));
13027 
13028 	return QDF_STATUS_SUCCESS;
13029 }
13030 
13031 /**
13032  * wmi_unified_save_fw_version_cmd() - save fw version
13033  * @wmi_handle:      pointer to wmi handle
13034  * @res_cfg:         resource config
13035  * @num_mem_chunks:  no of mem chunck
13036  * @mem_chunk:       pointer to mem chunck structure
13037  *
13038  * This function sends IE information to firmware
13039  *
13040  * Return: QDF_STATUS_SUCCESS for success otherwise failure
13041  *
13042  */
13043 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle,
13044 					  void *evt_buf)
13045 {
13046 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
13047 	wmi_ready_event_fixed_param *ev = NULL;
13048 
13049 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
13050 	ev = param_buf->fixed_param;
13051 	if (!wmi_versions_are_compatible((struct _wmi_abi_version *)
13052 				&wmi_handle->final_abi_vers,
13053 				&ev->fw_abi_vers)) {
13054 		/*
13055 		 * Error: Our host version and the given firmware version
13056 		 * are incompatible.
13057 		 **/
13058 		WMI_LOGD("%s: Error: Incompatible WMI version."
13059 			"Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n",
13060 				__func__,
13061 			WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers.
13062 				abi_version_0),
13063 			WMI_VER_GET_MINOR(wmi_handle->final_abi_vers.
13064 				abi_version_0),
13065 			wmi_handle->final_abi_vers.abi_version_ns_0,
13066 			wmi_handle->final_abi_vers.abi_version_ns_1,
13067 			wmi_handle->final_abi_vers.abi_version_ns_2,
13068 			wmi_handle->final_abi_vers.abi_version_ns_3,
13069 			WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0),
13070 			WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0),
13071 			ev->fw_abi_vers.abi_version_ns_0,
13072 			ev->fw_abi_vers.abi_version_ns_1,
13073 			ev->fw_abi_vers.abi_version_ns_2,
13074 			ev->fw_abi_vers.abi_version_ns_3);
13075 
13076 		return QDF_STATUS_E_FAILURE;
13077 	}
13078 	qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers,
13079 			sizeof(wmi_abi_version));
13080 	qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
13081 			sizeof(wmi_abi_version));
13082 
13083 	return QDF_STATUS_SUCCESS;
13084 }
13085 
13086 /**
13087  * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw
13088  * @wmi_handle: wmi handle
13089  * @custom_addr: base mac address
13090  *
13091  * Return: QDF_STATUS_SUCCESS for success or error code
13092  */
13093 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle,
13094 					 uint8_t *custom_addr)
13095 {
13096 	wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd;
13097 	wmi_buf_t buf;
13098 	int err;
13099 
13100 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
13101 	if (!buf) {
13102 		WMI_LOGE("Failed to allocate buffer to send base macaddr cmd");
13103 		return QDF_STATUS_E_NOMEM;
13104 	}
13105 
13106 	cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf);
13107 	qdf_mem_zero(cmd, sizeof(*cmd));
13108 
13109 	WMITLV_SET_HDR(&cmd->tlv_header,
13110 		   WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param,
13111 		       WMITLV_GET_STRUCT_TLVLEN
13112 			       (wmi_pdev_set_base_macaddr_cmd_fixed_param));
13113 	WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr);
13114 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13115 							WMI_HOST_PDEV_ID_SOC);
13116 	wmi_mtrace(WMI_PDEV_SET_BASE_MACADDR_CMDID, NO_SESSION, 0);
13117 	err = wmi_unified_cmd_send(wmi_handle, buf,
13118 				   sizeof(*cmd),
13119 				   WMI_PDEV_SET_BASE_MACADDR_CMDID);
13120 	if (err) {
13121 		WMI_LOGE("Failed to send set_base_macaddr cmd");
13122 		wmi_buf_free(buf);
13123 		return QDF_STATUS_E_FAILURE;
13124 	}
13125 
13126 	return 0;
13127 }
13128 
13129 /**
13130  * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events
13131  * @handle: wmi handle
13132  * @event:  Event received from FW
13133  * @len:    Length of the event
13134  *
13135  * Enables the low frequency events and disables the high frequency
13136  * events. Bit 17 indicates if the event if low/high frequency.
13137  * 1 - high frequency, 0 - low frequency
13138  *
13139  * Return: 0 on successfully enabling/disabling the events
13140  */
13141 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle,
13142 		uint8_t *event,
13143 		uint32_t len)
13144 {
13145 	uint32_t num_of_diag_events_logs;
13146 	wmi_diag_event_log_config_fixed_param *cmd;
13147 	wmi_buf_t buf;
13148 	uint8_t *buf_ptr;
13149 	uint32_t *cmd_args, *evt_args;
13150 	uint32_t buf_len, i;
13151 
13152 	WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf;
13153 	wmi_diag_event_log_supported_event_fixed_params *wmi_event;
13154 
13155 	WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID");
13156 
13157 	param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event;
13158 	if (!param_buf) {
13159 		WMI_LOGE("Invalid log supported event buffer");
13160 		return QDF_STATUS_E_INVAL;
13161 	}
13162 	wmi_event = param_buf->fixed_param;
13163 	num_of_diag_events_logs = wmi_event->num_of_diag_events_logs;
13164 
13165 	if (num_of_diag_events_logs >
13166 	    param_buf->num_diag_events_logs_list) {
13167 		WMI_LOGE("message number of events %d is more than tlv hdr content %d",
13168 			 num_of_diag_events_logs,
13169 			 param_buf->num_diag_events_logs_list);
13170 		return QDF_STATUS_E_INVAL;
13171 	}
13172 
13173 	evt_args = param_buf->diag_events_logs_list;
13174 	if (!evt_args) {
13175 		WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d",
13176 				__func__, num_of_diag_events_logs);
13177 		return QDF_STATUS_E_INVAL;
13178 	}
13179 
13180 	WMI_LOGD("%s: num_of_diag_events_logs=%d",
13181 			__func__, num_of_diag_events_logs);
13182 
13183 	/* Free any previous allocation */
13184 	if (wmi_handle->events_logs_list)
13185 		qdf_mem_free(wmi_handle->events_logs_list);
13186 
13187 	if (num_of_diag_events_logs >
13188 		(WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) {
13189 		WMI_LOGE("%s: excess num of logs:%d", __func__,
13190 			num_of_diag_events_logs);
13191 		QDF_ASSERT(0);
13192 		return QDF_STATUS_E_INVAL;
13193 	}
13194 	/* Store the event list for run time enable/disable */
13195 	wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs *
13196 			sizeof(uint32_t));
13197 	if (!wmi_handle->events_logs_list) {
13198 		WMI_LOGE("%s: event log list memory allocation failed",
13199 				__func__);
13200 		return QDF_STATUS_E_NOMEM;
13201 	}
13202 	wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs;
13203 
13204 	/* Prepare the send buffer */
13205 	buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
13206 		(num_of_diag_events_logs * sizeof(uint32_t));
13207 
13208 	buf = wmi_buf_alloc(wmi_handle, buf_len);
13209 	if (!buf) {
13210 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13211 		qdf_mem_free(wmi_handle->events_logs_list);
13212 		wmi_handle->events_logs_list = NULL;
13213 		return QDF_STATUS_E_NOMEM;
13214 	}
13215 
13216 	cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf);
13217 	buf_ptr = (uint8_t *) cmd;
13218 
13219 	WMITLV_SET_HDR(&cmd->tlv_header,
13220 			WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param,
13221 			WMITLV_GET_STRUCT_TLVLEN(
13222 				wmi_diag_event_log_config_fixed_param));
13223 
13224 	cmd->num_of_diag_events_logs = num_of_diag_events_logs;
13225 
13226 	buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param);
13227 
13228 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
13229 			(num_of_diag_events_logs * sizeof(uint32_t)));
13230 
13231 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
13232 
13233 	/* Populate the events */
13234 	for (i = 0; i < num_of_diag_events_logs; i++) {
13235 		/* Low freq (0) - Enable (1) the event
13236 		 * High freq (1) - Disable (0) the event
13237 		 */
13238 		WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i],
13239 				!(WMI_DIAG_FREQUENCY_GET(evt_args[i])));
13240 		/* Set the event ID */
13241 		WMI_DIAG_ID_SET(cmd_args[i],
13242 				WMI_DIAG_ID_GET(evt_args[i]));
13243 		/* Set the type */
13244 		WMI_DIAG_TYPE_SET(cmd_args[i],
13245 				WMI_DIAG_TYPE_GET(evt_args[i]));
13246 		/* Storing the event/log list in WMI */
13247 		wmi_handle->events_logs_list[i] = evt_args[i];
13248 	}
13249 
13250 	wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0);
13251 	if (wmi_unified_cmd_send(wmi_handle, buf, buf_len,
13252 				WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) {
13253 		WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed",
13254 				__func__);
13255 		wmi_buf_free(buf);
13256 		/* Not clearing events_logs_list, though wmi cmd failed.
13257 		 * Host can still have this list
13258 		 */
13259 		return QDF_STATUS_E_INVAL;
13260 	}
13261 
13262 	return 0;
13263 }
13264 
13265 /**
13266  * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id
13267  * @wmi_handle: wmi handle
13268  * @start_log: Start logging related parameters
13269  *
13270  * Send the command to the FW based on which specific logging of diag
13271  * event/log id can be started/stopped
13272  *
13273  * Return: None
13274  */
13275 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle,
13276 		struct wmi_wifi_start_log *start_log)
13277 {
13278 	wmi_diag_event_log_config_fixed_param *cmd;
13279 	wmi_buf_t buf;
13280 	uint8_t *buf_ptr;
13281 	uint32_t len, count, log_level, i;
13282 	uint32_t *cmd_args;
13283 	uint32_t total_len;
13284 	count = 0;
13285 
13286 	if (!wmi_handle->events_logs_list) {
13287 		WMI_LOGD("%s: Not received event/log list from FW, yet",
13288 			 __func__);
13289 		return QDF_STATUS_E_NOMEM;
13290 	}
13291 	/* total_len stores the number of events where BITS 17 and 18 are set.
13292 	 * i.e., events of high frequency (17) and for extended debugging (18)
13293 	 */
13294 	total_len = 0;
13295 	for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) {
13296 		if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) &&
13297 		    (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i])))
13298 			total_len++;
13299 	}
13300 
13301 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
13302 		(total_len * sizeof(uint32_t));
13303 
13304 	buf = wmi_buf_alloc(wmi_handle, len);
13305 	if (!buf) {
13306 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13307 		return QDF_STATUS_E_NOMEM;
13308 	}
13309 	cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf);
13310 	buf_ptr = (uint8_t *) cmd;
13311 
13312 	WMITLV_SET_HDR(&cmd->tlv_header,
13313 			WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param,
13314 			WMITLV_GET_STRUCT_TLVLEN(
13315 				wmi_diag_event_log_config_fixed_param));
13316 
13317 	cmd->num_of_diag_events_logs = total_len;
13318 
13319 	buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param);
13320 
13321 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
13322 			(total_len * sizeof(uint32_t)));
13323 
13324 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
13325 
13326 	if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE)
13327 		log_level = 1;
13328 	else
13329 		log_level = 0;
13330 
13331 	WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level);
13332 	for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) {
13333 		uint32_t val = wmi_handle->events_logs_list[i];
13334 		if ((WMI_DIAG_FREQUENCY_GET(val)) &&
13335 				(WMI_DIAG_EXT_FEATURE_GET(val))) {
13336 
13337 			WMI_DIAG_ID_SET(cmd_args[count],
13338 					WMI_DIAG_ID_GET(val));
13339 			WMI_DIAG_TYPE_SET(cmd_args[count],
13340 					WMI_DIAG_TYPE_GET(val));
13341 			WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count],
13342 					log_level);
13343 			WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val);
13344 			count++;
13345 		}
13346 	}
13347 
13348 	wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0);
13349 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13350 				WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) {
13351 		WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed",
13352 				__func__);
13353 		wmi_buf_free(buf);
13354 		return QDF_STATUS_E_INVAL;
13355 	}
13356 
13357 	return QDF_STATUS_SUCCESS;
13358 }
13359 
13360 /**
13361  * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW
13362  * @wmi_handle: WMI handle
13363  *
13364  * This function is used to send the flush command to the FW,
13365  * that will flush the fw logs that are residue in the FW
13366  *
13367  * Return: None
13368  */
13369 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle)
13370 {
13371 	wmi_debug_mesg_flush_fixed_param *cmd;
13372 	wmi_buf_t buf;
13373 	int len = sizeof(*cmd);
13374 	QDF_STATUS ret;
13375 
13376 	buf = wmi_buf_alloc(wmi_handle, len);
13377 	if (!buf) {
13378 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
13379 		return QDF_STATUS_E_NOMEM;
13380 	}
13381 
13382 	cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf);
13383 	WMITLV_SET_HDR(&cmd->tlv_header,
13384 			WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param,
13385 			WMITLV_GET_STRUCT_TLVLEN(
13386 				wmi_debug_mesg_flush_fixed_param));
13387 	cmd->reserved0 = 0;
13388 
13389 	wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0);
13390 	ret = wmi_unified_cmd_send(wmi_handle,
13391 			buf,
13392 			len,
13393 			WMI_DEBUG_MESG_FLUSH_CMDID);
13394 	if (QDF_IS_STATUS_ERROR(ret)) {
13395 		WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID");
13396 		wmi_buf_free(buf);
13397 		return QDF_STATUS_E_INVAL;
13398 	}
13399 	WMI_LOGD("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW");
13400 
13401 	return ret;
13402 }
13403 
13404 /**
13405  * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW
13406  * @wmi_handle: wmi handle
13407  * @msg: PCL structure containing the PCL and the number of channels
13408  *
13409  * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
13410  * firmware. The DBS Manager is the consumer of this information in the WLAN
13411  * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
13412  * to migrate to a new channel without host driver involvement. An example of
13413  * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
13414  * manage the channel selection without firmware involvement.
13415  *
13416  * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual
13417  * channel list. The weights corresponds to the channels sent in
13418  * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
13419  * weightage compared to the non PCL channels.
13420  *
13421  * Return: Success if the cmd is sent successfully to the firmware
13422  */
13423 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle,
13424 				struct wmi_pcl_chan_weights *msg)
13425 {
13426 	wmi_pdev_set_pcl_cmd_fixed_param *cmd;
13427 	wmi_buf_t buf;
13428 	uint8_t *buf_ptr;
13429 	uint32_t *cmd_args, i, len;
13430 	uint32_t chan_len;
13431 
13432 	chan_len = msg->saved_num_chan;
13433 
13434 	len = sizeof(*cmd) +
13435 		WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t));
13436 
13437 	buf = wmi_buf_alloc(wmi_handle, len);
13438 	if (!buf) {
13439 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13440 		return QDF_STATUS_E_NOMEM;
13441 	}
13442 
13443 	cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf);
13444 	buf_ptr = (uint8_t *) cmd;
13445 	WMITLV_SET_HDR(&cmd->tlv_header,
13446 		WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param,
13447 		WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param));
13448 
13449 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13450 							WMI_HOST_PDEV_ID_SOC);
13451 	cmd->num_chan = chan_len;
13452 	WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan);
13453 
13454 	buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param);
13455 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
13456 			(chan_len * sizeof(uint32_t)));
13457 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
13458 	for (i = 0; i < chan_len ; i++) {
13459 		cmd_args[i] = msg->weighed_valid_list[i];
13460 		WMI_LOGD("%s: chan:%d weight:%d", __func__,
13461 			msg->saved_chan_list[i], cmd_args[i]);
13462 	}
13463 	wmi_mtrace(WMI_PDEV_SET_PCL_CMDID, NO_SESSION, 0);
13464 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13465 				WMI_PDEV_SET_PCL_CMDID)) {
13466 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__);
13467 		wmi_buf_free(buf);
13468 		return QDF_STATUS_E_FAILURE;
13469 	}
13470 	return QDF_STATUS_SUCCESS;
13471 }
13472 
13473 /**
13474  * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW
13475  * @wmi_handle: wmi handle
13476  * @msg: Structure containing the following parameters
13477  *
13478  * - hw_mode_index: The HW_Mode field is a enumerated type that is selected
13479  * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID.
13480  *
13481  * Provides notification to the WLAN firmware that host driver is requesting a
13482  * HardWare (HW) Mode change. This command is needed to support iHelium in the
13483  * configurations that include the Dual Band Simultaneous (DBS) feature.
13484  *
13485  * Return: Success if the cmd is sent successfully to the firmware
13486  */
13487 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle,
13488 				uint32_t hw_mode_index)
13489 {
13490 	wmi_pdev_set_hw_mode_cmd_fixed_param *cmd;
13491 	wmi_buf_t buf;
13492 	uint32_t len;
13493 
13494 	len = sizeof(*cmd);
13495 
13496 	buf = wmi_buf_alloc(wmi_handle, len);
13497 	if (!buf) {
13498 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13499 		return QDF_STATUS_E_NOMEM;
13500 	}
13501 
13502 	cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf);
13503 	WMITLV_SET_HDR(&cmd->tlv_header,
13504 		WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param,
13505 		WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param));
13506 
13507 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13508 							WMI_HOST_PDEV_ID_SOC);
13509 	cmd->hw_mode_index = hw_mode_index;
13510 	WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index);
13511 
13512 	wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0);
13513 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13514 				WMI_PDEV_SET_HW_MODE_CMDID)) {
13515 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID",
13516 			__func__);
13517 		wmi_buf_free(buf);
13518 		return QDF_STATUS_E_FAILURE;
13519 	}
13520 
13521 	return QDF_STATUS_SUCCESS;
13522 }
13523 
13524 #ifdef WLAN_POLICY_MGR_ENABLE
13525 /**
13526  * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW
13527  * @wmi_handle: wmi handle
13528  * @msg: Dual MAC config parameters
13529  *
13530  * Configures WLAN firmware with the dual MAC features
13531  *
13532  * Return: QDF_STATUS. 0 on success.
13533  */
13534 static
13535 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle,
13536 		struct policy_mgr_dual_mac_config *msg)
13537 {
13538 	wmi_pdev_set_mac_config_cmd_fixed_param *cmd;
13539 	wmi_buf_t buf;
13540 	uint32_t len;
13541 
13542 	len = sizeof(*cmd);
13543 
13544 	buf = wmi_buf_alloc(wmi_handle, len);
13545 	if (!buf) {
13546 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13547 		return QDF_STATUS_E_FAILURE;
13548 	}
13549 
13550 	cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf);
13551 	WMITLV_SET_HDR(&cmd->tlv_header,
13552 		WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param,
13553 		WMITLV_GET_STRUCT_TLVLEN(
13554 			wmi_pdev_set_mac_config_cmd_fixed_param));
13555 
13556 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13557 							WMI_HOST_PDEV_ID_SOC);
13558 	cmd->concurrent_scan_config_bits = msg->scan_config;
13559 	cmd->fw_mode_config_bits = msg->fw_mode_config;
13560 	WMI_LOGD("%s: scan_config:%x fw_mode_config:%x",
13561 		 __func__, msg->scan_config, msg->fw_mode_config);
13562 
13563 	wmi_mtrace(WMI_PDEV_SET_MAC_CONFIG_CMDID, NO_SESSION, 0);
13564 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13565 				WMI_PDEV_SET_MAC_CONFIG_CMDID)) {
13566 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID",
13567 				__func__);
13568 		wmi_buf_free(buf);
13569 	}
13570 	return QDF_STATUS_SUCCESS;
13571 }
13572 #endif
13573 
13574 #ifdef BIG_ENDIAN_HOST
13575 /**
13576 * fips_conv_data_be() - LE to BE conversion of FIPS ev data
13577 * @param data_len - data length
13578 * @param data - pointer to data
13579 *
13580 * Return: QDF_STATUS - success or error status
13581 */
13582 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle,
13583 			struct fips_params *param)
13584 {
13585 	unsigned char *key_unaligned, *data_unaligned;
13586 	int c;
13587 	u_int8_t *key_aligned = NULL;
13588 	u_int8_t *data_aligned = NULL;
13589 
13590 	/* Assigning unaligned space to copy the key */
13591 	key_unaligned = qdf_mem_malloc(
13592 		sizeof(u_int8_t)*param->key_len + FIPS_ALIGN);
13593 	data_unaligned = qdf_mem_malloc(
13594 		sizeof(u_int8_t)*param->data_len + FIPS_ALIGN);
13595 
13596 	/* Checking if kmalloc is successful to allocate space */
13597 	if (key_unaligned == NULL)
13598 		return QDF_STATUS_SUCCESS;
13599 	/* Checking if space is aligned */
13600 	if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) {
13601 		/* align to 4 */
13602 		key_aligned =
13603 		(u_int8_t *)FIPS_ALIGNTO(key_unaligned,
13604 			FIPS_ALIGN);
13605 	} else {
13606 		key_aligned = (u_int8_t *)key_unaligned;
13607 	}
13608 
13609 	/* memset and copy content from key to key aligned */
13610 	OS_MEMSET(key_aligned, 0, param->key_len);
13611 	OS_MEMCPY(key_aligned, param->key, param->key_len);
13612 
13613 	/* print a hexdump for host debug */
13614 	print_hex_dump(KERN_DEBUG,
13615 		"\t Aligned and Copied Key:@@@@ ",
13616 		DUMP_PREFIX_NONE,
13617 		16, 1, key_aligned, param->key_len, true);
13618 
13619 	/* Checking if kmalloc is successful to allocate space */
13620 	if (data_unaligned == NULL)
13621 		return QDF_STATUS_SUCCESS;
13622 	/* Checking of space is aligned */
13623 	if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) {
13624 		/* align to 4 */
13625 		data_aligned =
13626 		(u_int8_t *)FIPS_ALIGNTO(data_unaligned,
13627 				FIPS_ALIGN);
13628 	} else {
13629 		data_aligned = (u_int8_t *)data_unaligned;
13630 	}
13631 
13632 	/* memset and copy content from data to data aligned */
13633 	OS_MEMSET(data_aligned, 0, param->data_len);
13634 	OS_MEMCPY(data_aligned, param->data, param->data_len);
13635 
13636 	/* print a hexdump for host debug */
13637 	print_hex_dump(KERN_DEBUG,
13638 		"\t Properly Aligned and Copied Data:@@@@ ",
13639 	DUMP_PREFIX_NONE,
13640 	16, 1, data_aligned, param->data_len, true);
13641 
13642 	/* converting to little Endian both key_aligned and
13643 	* data_aligned*/
13644 	for (c = 0; c < param->key_len/4; c++) {
13645 		*((u_int32_t *)key_aligned+c) =
13646 		qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c));
13647 	}
13648 	for (c = 0; c < param->data_len/4; c++) {
13649 		*((u_int32_t *)data_aligned+c) =
13650 		qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c));
13651 	}
13652 
13653 	/* update endian data to key and data vectors */
13654 	OS_MEMCPY(param->key, key_aligned, param->key_len);
13655 	OS_MEMCPY(param->data, data_aligned, param->data_len);
13656 
13657 	/* clean up allocated spaces */
13658 	qdf_mem_free(key_unaligned);
13659 	key_unaligned = NULL;
13660 	key_aligned = NULL;
13661 
13662 	qdf_mem_free(data_unaligned);
13663 	data_unaligned = NULL;
13664 	data_aligned = NULL;
13665 
13666 	return QDF_STATUS_SUCCESS;
13667 }
13668 #else
13669 /**
13670 * fips_align_data_be() - DUMMY for LE platform
13671 *
13672 * Return: QDF_STATUS - success
13673 */
13674 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle,
13675 		struct fips_params *param)
13676 {
13677 	return QDF_STATUS_SUCCESS;
13678 }
13679 #endif
13680 
13681 
13682 /**
13683  * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw
13684  * @wmi_handle: wmi handle
13685  * @param: pointer to hold pdev fips param
13686  *
13687  * Return: 0 for success or error code
13688  */
13689 static QDF_STATUS
13690 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle,
13691 		struct fips_params *param)
13692 {
13693 	wmi_pdev_fips_cmd_fixed_param *cmd;
13694 	wmi_buf_t buf;
13695 	uint8_t *buf_ptr;
13696 	uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param);
13697 	QDF_STATUS retval = QDF_STATUS_SUCCESS;
13698 
13699 	/* Length TLV placeholder for array of bytes */
13700 	len += WMI_TLV_HDR_SIZE;
13701 	if (param->data_len)
13702 		len += (param->data_len*sizeof(uint8_t));
13703 
13704 	/*
13705 	* Data length must be multiples of 16 bytes - checked against 0xF -
13706 	* and must be less than WMI_SVC_MSG_SIZE - static size of
13707 	* wmi_pdev_fips_cmd structure
13708 	*/
13709 
13710 	/* do sanity on the input */
13711 	if (!(((param->data_len & 0xF) == 0) &&
13712 			((param->data_len > 0) &&
13713 			(param->data_len < (WMI_HOST_MAX_BUFFER_SIZE -
13714 		sizeof(wmi_pdev_fips_cmd_fixed_param)))))) {
13715 		return QDF_STATUS_E_INVAL;
13716 	}
13717 
13718 	buf = wmi_buf_alloc(wmi_handle, len);
13719 	if (!buf) {
13720 		qdf_print("%s:wmi_buf_alloc failed", __func__);
13721 		return QDF_STATUS_E_FAILURE;
13722 	}
13723 
13724 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
13725 	cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr;
13726 	WMITLV_SET_HDR(&cmd->tlv_header,
13727 		WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param,
13728 		WMITLV_GET_STRUCT_TLVLEN
13729 		(wmi_pdev_fips_cmd_fixed_param));
13730 
13731 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13732 								param->pdev_id);
13733 	if (param->key != NULL && param->data != NULL) {
13734 		cmd->key_len = param->key_len;
13735 		cmd->data_len = param->data_len;
13736 		cmd->fips_cmd = !!(param->op);
13737 
13738 		if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS)
13739 			return QDF_STATUS_E_FAILURE;
13740 
13741 		qdf_mem_copy(cmd->key, param->key, param->key_len);
13742 
13743 		if (param->mode == FIPS_ENGINE_AES_CTR ||
13744 			param->mode == FIPS_ENGINE_AES_MIC) {
13745 			cmd->mode = param->mode;
13746 		} else {
13747 			cmd->mode = FIPS_ENGINE_AES_CTR;
13748 		}
13749 		qdf_print("Key len = %d, Data len = %d",
13750 			  cmd->key_len, cmd->data_len);
13751 
13752 		print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1,
13753 				cmd->key, cmd->key_len, true);
13754 		buf_ptr += sizeof(*cmd);
13755 
13756 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len);
13757 
13758 		buf_ptr += WMI_TLV_HDR_SIZE;
13759 		if (param->data_len)
13760 			qdf_mem_copy(buf_ptr,
13761 				(uint8_t *) param->data, param->data_len);
13762 
13763 		print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE,
13764 			16, 1, buf_ptr, cmd->data_len, true);
13765 
13766 		buf_ptr += param->data_len;
13767 
13768 		wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0);
13769 		retval = wmi_unified_cmd_send(wmi_handle, buf, len,
13770 			WMI_PDEV_FIPS_CMDID);
13771 		qdf_print("%s return value %d", __func__, retval);
13772 	} else {
13773 		qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__);
13774 		wmi_buf_free(buf);
13775 		retval = -QDF_STATUS_E_BADMSG;
13776 	}
13777 
13778 	return retval;
13779 }
13780 
13781 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
13782 /**
13783  * send_add_wow_wakeup_event_cmd_tlv() -  Configures wow wakeup events.
13784  * @wmi_handle: wmi handle
13785  * @vdev_id: vdev id
13786  * @bitmap: Event bitmap
13787  * @enable: enable/disable
13788  *
13789  * Return: CDF status
13790  */
13791 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle,
13792 					uint32_t vdev_id,
13793 					uint32_t *bitmap,
13794 					bool enable)
13795 {
13796 	WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd;
13797 	uint16_t len;
13798 	wmi_buf_t buf;
13799 	int ret;
13800 
13801 	len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param);
13802 	buf = wmi_buf_alloc(wmi_handle, len);
13803 	if (!buf) {
13804 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
13805 		return QDF_STATUS_E_NOMEM;
13806 	}
13807 	cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf);
13808 	WMITLV_SET_HDR(&cmd->tlv_header,
13809 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param,
13810 		       WMITLV_GET_STRUCT_TLVLEN
13811 			       (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param));
13812 	cmd->vdev_id = vdev_id;
13813 	cmd->is_add = enable;
13814 	qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) *
13815 		     WMI_WOW_MAX_EVENT_BM_LEN);
13816 
13817 	WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0],
13818 		 cmd->event_bitmaps[1], cmd->event_bitmaps[2],
13819 		 cmd->event_bitmaps[3], enable ? "enabled" : "disabled");
13820 
13821 	wmi_mtrace(WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, cmd->vdev_id, 0);
13822 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
13823 				   WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
13824 	if (ret) {
13825 		WMI_LOGE("Failed to config wow wakeup event");
13826 		wmi_buf_free(buf);
13827 		return QDF_STATUS_E_FAILURE;
13828 	}
13829 
13830 	return QDF_STATUS_SUCCESS;
13831 }
13832 
13833 /**
13834  * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW.
13835  * @wmi_handle: wmi handle
13836  * @vdev_id: vdev id
13837  * @ptrn_id: pattern id
13838  * @ptrn: pattern
13839  * @ptrn_len: pattern length
13840  * @ptrn_offset: pattern offset
13841  * @mask: mask
13842  * @mask_len: mask length
13843  * @user: true for user configured pattern and false for default pattern
13844  * @default_patterns: default patterns
13845  *
13846  * Return: CDF status
13847  */
13848 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle,
13849 				uint8_t vdev_id, uint8_t ptrn_id,
13850 				const uint8_t *ptrn, uint8_t ptrn_len,
13851 				uint8_t ptrn_offset, const uint8_t *mask,
13852 				uint8_t mask_len, bool user,
13853 				uint8_t default_patterns)
13854 {
13855 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
13856 	WOW_BITMAP_PATTERN_T *bitmap_pattern;
13857 	wmi_buf_t buf;
13858 	uint8_t *buf_ptr;
13859 	int32_t len;
13860 	int ret;
13861 
13862 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
13863 		WMI_TLV_HDR_SIZE +
13864 		1 * sizeof(WOW_BITMAP_PATTERN_T) +
13865 		WMI_TLV_HDR_SIZE +
13866 		0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
13867 		WMI_TLV_HDR_SIZE +
13868 		0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
13869 		WMI_TLV_HDR_SIZE +
13870 		0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
13871 		WMI_TLV_HDR_SIZE +
13872 		0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
13873 
13874 	buf = wmi_buf_alloc(wmi_handle, len);
13875 	if (!buf) {
13876 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
13877 		return QDF_STATUS_E_NOMEM;
13878 	}
13879 
13880 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
13881 	buf_ptr = (uint8_t *) cmd;
13882 
13883 	WMITLV_SET_HDR(&cmd->tlv_header,
13884 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
13885 		       WMITLV_GET_STRUCT_TLVLEN
13886 			       (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
13887 	cmd->vdev_id = vdev_id;
13888 	cmd->pattern_id = ptrn_id;
13889 
13890 	cmd->pattern_type = WOW_BITMAP_PATTERN;
13891 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
13892 
13893 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
13894 		       sizeof(WOW_BITMAP_PATTERN_T));
13895 	buf_ptr += WMI_TLV_HDR_SIZE;
13896 	bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr;
13897 
13898 	WMITLV_SET_HDR(&bitmap_pattern->tlv_header,
13899 		       WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T,
13900 		       WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T));
13901 
13902 	qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len);
13903 	qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len);
13904 
13905 	bitmap_pattern->pattern_offset = ptrn_offset;
13906 	bitmap_pattern->pattern_len = ptrn_len;
13907 
13908 	if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE)
13909 		bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE;
13910 
13911 	if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE)
13912 		bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE;
13913 
13914 	bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len;
13915 	bitmap_pattern->pattern_id = ptrn_id;
13916 
13917 	WMI_LOGD("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d",
13918 		 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len,
13919 		 bitmap_pattern->pattern_offset, user);
13920 	WMI_LOGD("Pattern : ");
13921 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
13922 			   &bitmap_pattern->patternbuf[0],
13923 			   bitmap_pattern->pattern_len);
13924 
13925 	WMI_LOGD("Mask : ");
13926 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
13927 			   &bitmap_pattern->bitmaskbuf[0],
13928 			   bitmap_pattern->pattern_len);
13929 
13930 	buf_ptr += sizeof(WOW_BITMAP_PATTERN_T);
13931 
13932 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
13933 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
13934 	buf_ptr += WMI_TLV_HDR_SIZE;
13935 
13936 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
13937 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
13938 	buf_ptr += WMI_TLV_HDR_SIZE;
13939 
13940 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
13941 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
13942 	buf_ptr += WMI_TLV_HDR_SIZE;
13943 
13944 	/* Fill TLV for pattern_info_timeout but no data. */
13945 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
13946 	buf_ptr += WMI_TLV_HDR_SIZE;
13947 
13948 	/* Fill TLV for ratelimit_interval with dummy data as this fix elem */
13949 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t));
13950 	buf_ptr += WMI_TLV_HDR_SIZE;
13951 	*(uint32_t *) buf_ptr = 0;
13952 
13953 	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
13954 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
13955 				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
13956 	if (ret) {
13957 		WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__);
13958 		wmi_buf_free(buf);
13959 		return QDF_STATUS_E_FAILURE;
13960 	}
13961 
13962 	return QDF_STATUS_SUCCESS;
13963 }
13964 
13965 /**
13966  * fill_arp_offload_params_tlv() - Fill ARP offload data
13967  * @wmi_handle: wmi handle
13968  * @offload_req: offload request
13969  * @buf_ptr: buffer pointer
13970  *
13971  * To fill ARP offload data to firmware
13972  * when target goes to wow mode.
13973  *
13974  * Return: None
13975  */
13976 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle,
13977 		struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr)
13978 {
13979 
13980 	int i;
13981 	WMI_ARP_OFFLOAD_TUPLE *arp_tuple;
13982 	bool enable_or_disable = offload_req->enable;
13983 
13984 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
13985 		(WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE)));
13986 	*buf_ptr += WMI_TLV_HDR_SIZE;
13987 	for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) {
13988 		arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr;
13989 		WMITLV_SET_HDR(&arp_tuple->tlv_header,
13990 			WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE,
13991 			WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE));
13992 
13993 		/* Fill data for ARP and NS in the first tupple for LA */
13994 		if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) {
13995 			/* Copy the target ip addr and flags */
13996 			arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID;
13997 			qdf_mem_copy(&arp_tuple->target_ipaddr,
13998 					offload_req->host_ipv4_addr,
13999 					WMI_IPV4_ADDR_LEN);
14000 			WMI_LOGD("ARPOffload IP4 address: %pI4",
14001 					offload_req->host_ipv4_addr);
14002 		}
14003 		*buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE);
14004 	}
14005 }
14006 
14007 #ifdef WLAN_NS_OFFLOAD
14008 /**
14009  * fill_ns_offload_params_tlv() - Fill NS offload data
14010  * @wmi|_handle: wmi handle
14011  * @offload_req: offload request
14012  * @buf_ptr: buffer pointer
14013  *
14014  * To fill NS offload data to firmware
14015  * when target goes to wow mode.
14016  *
14017  * Return: None
14018  */
14019 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle,
14020 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14021 {
14022 
14023 	int i;
14024 	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
14025 
14026 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14027 		(WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE)));
14028 	*buf_ptr += WMI_TLV_HDR_SIZE;
14029 	for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) {
14030 		ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr;
14031 		WMITLV_SET_HDR(&ns_tuple->tlv_header,
14032 			WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
14033 			(sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE));
14034 
14035 		/*
14036 		 * Fill data only for NS offload in the first ARP tuple for LA
14037 		 */
14038 		if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) {
14039 			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
14040 			/* Copy the target/solicitation/remote ip addr */
14041 			if (ns_req->target_ipv6_addr_valid[i])
14042 				qdf_mem_copy(&ns_tuple->target_ipaddr[0],
14043 					&ns_req->target_ipv6_addr[i],
14044 					sizeof(WMI_IPV6_ADDR));
14045 			qdf_mem_copy(&ns_tuple->solicitation_ipaddr,
14046 				&ns_req->self_ipv6_addr[i],
14047 				sizeof(WMI_IPV6_ADDR));
14048 			if (ns_req->target_ipv6_addr_ac_type[i]) {
14049 				ns_tuple->flags |=
14050 					WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST;
14051 			}
14052 			WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6",
14053 				i, &ns_req->self_ipv6_addr[i],
14054 				&ns_req->target_ipv6_addr[i]);
14055 
14056 			/* target MAC is optional, check if it is valid,
14057 			 * if this is not valid, the target will use the known
14058 			 * local MAC address rather than the tuple
14059 			 */
14060 			WMI_CHAR_ARRAY_TO_MAC_ADDR(
14061 				ns_req->self_macaddr.bytes,
14062 				&ns_tuple->target_mac);
14063 			if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
14064 				(ns_tuple->target_mac.mac_addr47to32 != 0)) {
14065 				ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
14066 			}
14067 		}
14068 		*buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
14069 	}
14070 }
14071 
14072 
14073 /**
14074  * fill_nsoffload_ext_tlv() - Fill NS offload ext data
14075  * @wmi: wmi handle
14076  * @offload_req: offload request
14077  * @buf_ptr: buffer pointer
14078  *
14079  * To fill extended NS offload extended data to firmware
14080  * when target goes to wow mode.
14081  *
14082  * Return: None
14083  */
14084 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle,
14085 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14086 {
14087 	int i;
14088 	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
14089 	uint32_t count, num_ns_ext_tuples;
14090 
14091 	count = ns_req->num_ns_offload_count;
14092 	num_ns_ext_tuples = ns_req->num_ns_offload_count -
14093 		WMI_MAX_NS_OFFLOADS;
14094 
14095 	/* Populate extended NS offload tuples */
14096 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14097 		(num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE)));
14098 	*buf_ptr += WMI_TLV_HDR_SIZE;
14099 	for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) {
14100 		ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr;
14101 		WMITLV_SET_HDR(&ns_tuple->tlv_header,
14102 			WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
14103 			(sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE));
14104 
14105 		/*
14106 		 * Fill data only for NS offload in the first ARP tuple for LA
14107 		 */
14108 		if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) {
14109 			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
14110 			/* Copy the target/solicitation/remote ip addr */
14111 			if (ns_req->target_ipv6_addr_valid[i])
14112 				qdf_mem_copy(&ns_tuple->target_ipaddr[0],
14113 					&ns_req->target_ipv6_addr[i],
14114 					sizeof(WMI_IPV6_ADDR));
14115 			qdf_mem_copy(&ns_tuple->solicitation_ipaddr,
14116 				&ns_req->self_ipv6_addr[i],
14117 				sizeof(WMI_IPV6_ADDR));
14118 			if (ns_req->target_ipv6_addr_ac_type[i]) {
14119 				ns_tuple->flags |=
14120 					WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST;
14121 			}
14122 			WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6",
14123 				i, &ns_req->self_ipv6_addr[i],
14124 				&ns_req->target_ipv6_addr[i]);
14125 
14126 			/* target MAC is optional, check if it is valid,
14127 			 * if this is not valid, the target will use the
14128 			 * known local MAC address rather than the tuple
14129 			 */
14130 			 WMI_CHAR_ARRAY_TO_MAC_ADDR(
14131 				ns_req->self_macaddr.bytes,
14132 				&ns_tuple->target_mac);
14133 			if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
14134 				(ns_tuple->target_mac.mac_addr47to32 != 0)) {
14135 				ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
14136 			}
14137 		}
14138 		*buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
14139 	}
14140 }
14141 #else
14142 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle,
14143 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14144 {
14145 }
14146 
14147 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle,
14148 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14149 {
14150 }
14151 #endif
14152 
14153 /**
14154  * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload
14155  * @wma: wmi handle
14156  * @arp_offload_req: arp offload request
14157  * @ns_offload_req: ns offload request
14158  * @arp_only: flag
14159  *
14160  * To configure ARP NS off load data to firmware
14161  * when target goes to wow mode.
14162  *
14163  * Return: QDF Status
14164  */
14165 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle,
14166 			   struct pmo_arp_offload_params *arp_offload_req,
14167 			   struct pmo_ns_offload_params *ns_offload_req,
14168 			   uint8_t vdev_id)
14169 {
14170 	int32_t res;
14171 	WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd;
14172 	uint8_t *buf_ptr;
14173 	wmi_buf_t buf;
14174 	int32_t len;
14175 	uint32_t count = 0, num_ns_ext_tuples = 0;
14176 
14177 	count = ns_offload_req->num_ns_offload_count;
14178 
14179 	/*
14180 	 * TLV place holder size for array of NS tuples
14181 	 * TLV place holder size for array of ARP tuples
14182 	 */
14183 	len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) +
14184 		WMI_TLV_HDR_SIZE +
14185 		WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) +
14186 		WMI_TLV_HDR_SIZE +
14187 		WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE);
14188 
14189 	/*
14190 	 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate
14191 	 * extra length for extended NS offload tuples which follows ARP offload
14192 	 * tuples. Host needs to fill this structure in following format:
14193 	 * 2 NS ofload tuples
14194 	 * 2 ARP offload tuples
14195 	 * N numbers of extended NS offload tuples if HDD has given more than
14196 	 * 2 NS offload addresses
14197 	 */
14198 	if (count > WMI_MAX_NS_OFFLOADS) {
14199 		num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS;
14200 		len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples
14201 			   * sizeof(WMI_NS_OFFLOAD_TUPLE);
14202 	}
14203 
14204 	buf = wmi_buf_alloc(wmi_handle, len);
14205 	if (!buf) {
14206 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
14207 		return QDF_STATUS_E_NOMEM;
14208 	}
14209 
14210 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14211 	cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr;
14212 	WMITLV_SET_HDR(&cmd->tlv_header,
14213 		       WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param,
14214 		       WMITLV_GET_STRUCT_TLVLEN
14215 			       (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param));
14216 	cmd->flags = 0;
14217 	cmd->vdev_id = vdev_id;
14218 	cmd->num_ns_ext_tuples = num_ns_ext_tuples;
14219 
14220 	WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id);
14221 
14222 	buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param);
14223 	fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr);
14224 	fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr);
14225 	if (num_ns_ext_tuples)
14226 		fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr);
14227 
14228 	wmi_mtrace(WMI_SET_ARP_NS_OFFLOAD_CMDID, cmd->vdev_id, 0);
14229 	res = wmi_unified_cmd_send(wmi_handle, buf, len,
14230 				     WMI_SET_ARP_NS_OFFLOAD_CMDID);
14231 	if (res) {
14232 		WMI_LOGE("Failed to enable ARP NDP/NSffload");
14233 		wmi_buf_free(buf);
14234 		return QDF_STATUS_E_FAILURE;
14235 	}
14236 
14237 	return QDF_STATUS_SUCCESS;
14238 }
14239 
14240 /**
14241  * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload
14242  * @wmi_handle: wmi handle
14243  * @vdev_id: vdev id
14244  * @action: true for enable else false
14245  *
14246  * To enable enhance multicast offload to firmware
14247  * when target goes to wow mode.
14248  *
14249  * Return: QDF Status
14250  */
14251 
14252 static
14253 QDF_STATUS send_enable_enhance_multicast_offload_tlv(
14254 		wmi_unified_t wmi_handle,
14255 		uint8_t vdev_id, bool action)
14256 {
14257 	QDF_STATUS status;
14258 	wmi_buf_t buf;
14259 	wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd;
14260 
14261 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
14262 	if (!buf) {
14263 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
14264 		return QDF_STATUS_E_NOMEM;
14265 	}
14266 
14267 	cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *)
14268 							wmi_buf_data(buf);
14269 
14270 	WMITLV_SET_HDR(&cmd->tlv_header,
14271 		WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param,
14272 		WMITLV_GET_STRUCT_TLVLEN(
14273 			wmi_config_enhanced_mcast_filter_cmd_fixed_param));
14274 
14275 	cmd->vdev_id = vdev_id;
14276 	cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED :
14277 			ENHANCED_MCAST_FILTER_ENABLED);
14278 	WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d",
14279 		__func__, action, vdev_id);
14280 	wmi_mtrace(WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID, cmd->vdev_id, 0);
14281 	status = wmi_unified_cmd_send(wmi_handle, buf,
14282 			sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID);
14283 	if (status != QDF_STATUS_SUCCESS) {
14284 		qdf_nbuf_free(buf);
14285 		WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID",
14286 			__func__);
14287 	}
14288 
14289 	return status;
14290 }
14291 
14292 /**
14293  * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event
14294  * @wmi_handle: wmi handle
14295  * @param evt_buf: pointer to event buffer
14296  * @param hdr: Pointer to hold header
14297  * @param bufp: Pointer to hold pointer to rx param buffer
14298  *
14299  * Return: QDF_STATUS_SUCCESS for success or error code
14300  */
14301 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle,
14302 	void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len)
14303 {
14304 	WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param;
14305 	WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf;
14306 
14307 	param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf;
14308 	if (!param_buf) {
14309 		WMI_LOGE("gtk param_buf is NULL");
14310 		return QDF_STATUS_E_INVAL;
14311 	}
14312 
14313 	if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) {
14314 		WMI_LOGE("Invalid length for GTK status");
14315 		return QDF_STATUS_E_INVAL;
14316 	}
14317 
14318 	fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *)
14319 		param_buf->fixed_param;
14320 	gtk_rsp_param->vdev_id = fixed_param->vdev_id;
14321 	gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS;
14322 	gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt;
14323 	qdf_mem_copy(&gtk_rsp_param->replay_counter,
14324 		&fixed_param->replay_counter,
14325 		GTK_REPLAY_COUNTER_BYTES);
14326 
14327 	return QDF_STATUS_SUCCESS;
14328 
14329 }
14330 
14331 #ifdef FEATURE_WLAN_RA_FILTERING
14332 /**
14333  * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw
14334  * @wmi_handle: wmi handle
14335  * @vdev_id: vdev id
14336  *
14337  * Return: CDF status
14338  */
14339 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle,
14340 		   uint8_t vdev_id, uint8_t default_pattern,
14341 		   uint16_t rate_limit_interval)
14342 {
14343 
14344 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
14345 	wmi_buf_t buf;
14346 	uint8_t *buf_ptr;
14347 	int32_t len;
14348 	int ret;
14349 
14350 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
14351 	      WMI_TLV_HDR_SIZE +
14352 	      0 * sizeof(WOW_BITMAP_PATTERN_T) +
14353 	      WMI_TLV_HDR_SIZE +
14354 	      0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
14355 	      WMI_TLV_HDR_SIZE +
14356 	      0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
14357 	      WMI_TLV_HDR_SIZE +
14358 	      0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
14359 	      WMI_TLV_HDR_SIZE +
14360 	      0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
14361 
14362 	buf = wmi_buf_alloc(wmi_handle, len);
14363 	if (!buf) {
14364 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
14365 		return QDF_STATUS_E_NOMEM;
14366 	}
14367 
14368 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
14369 	buf_ptr = (uint8_t *) cmd;
14370 
14371 	WMITLV_SET_HDR(&cmd->tlv_header,
14372 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
14373 		       WMITLV_GET_STRUCT_TLVLEN
14374 			       (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
14375 	cmd->vdev_id = vdev_id;
14376 	cmd->pattern_id = default_pattern,
14377 	cmd->pattern_type = WOW_IPV6_RA_PATTERN;
14378 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
14379 
14380 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
14381 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14382 	buf_ptr += WMI_TLV_HDR_SIZE;
14383 
14384 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
14385 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14386 	buf_ptr += WMI_TLV_HDR_SIZE;
14387 
14388 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
14389 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14390 	buf_ptr += WMI_TLV_HDR_SIZE;
14391 
14392 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
14393 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14394 	buf_ptr += WMI_TLV_HDR_SIZE;
14395 
14396 	/* Fill TLV for pattern_info_timeout but no data. */
14397 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
14398 	buf_ptr += WMI_TLV_HDR_SIZE;
14399 
14400 	/* Fill TLV for ra_ratelimit_interval. */
14401 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
14402 	buf_ptr += WMI_TLV_HDR_SIZE;
14403 
14404 	*((uint32_t *) buf_ptr) = rate_limit_interval;
14405 
14406 	WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__,
14407 		 rate_limit_interval, vdev_id);
14408 
14409 	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
14410 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
14411 				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
14412 	if (ret) {
14413 		WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__);
14414 		wmi_buf_free(buf);
14415 		return QDF_STATUS_E_FAILURE;
14416 	}
14417 
14418 	return QDF_STATUS_SUCCESS;
14419 
14420 }
14421 #endif /* FEATURE_WLAN_RA_FILTERING */
14422 
14423 /**
14424  * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw
14425  * @wmi_handle: wmi handle
14426  * @vdev_id: vdev id
14427  * @multicastAddr: mcast address
14428  * @clearList: clear list flag
14429  *
14430  * Return: QDF_STATUS_SUCCESS for success or error code
14431  */
14432 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle,
14433 				     uint8_t vdev_id,
14434 				     struct qdf_mac_addr multicast_addr,
14435 				     bool clearList)
14436 {
14437 	WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd;
14438 	wmi_buf_t buf;
14439 	int err;
14440 
14441 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
14442 	if (!buf) {
14443 		WMI_LOGE("Failed to allocate buffer to send set_param cmd");
14444 		return QDF_STATUS_E_NOMEM;
14445 	}
14446 
14447 	cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf);
14448 	qdf_mem_zero(cmd, sizeof(*cmd));
14449 
14450 	WMITLV_SET_HDR(&cmd->tlv_header,
14451 	       WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param,
14452 	       WMITLV_GET_STRUCT_TLVLEN
14453 	       (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param));
14454 	cmd->action =
14455 		(clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET);
14456 	cmd->vdev_id = vdev_id;
14457 	WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr);
14458 
14459 	WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM",
14460 		 cmd->action, vdev_id, clearList, multicast_addr.bytes);
14461 
14462 	wmi_mtrace(WMI_SET_MCASTBCAST_FILTER_CMDID, cmd->vdev_id, 0);
14463 	err = wmi_unified_cmd_send(wmi_handle, buf,
14464 				   sizeof(*cmd),
14465 				   WMI_SET_MCASTBCAST_FILTER_CMDID);
14466 	if (err) {
14467 		WMI_LOGE("Failed to send set_param cmd");
14468 		wmi_buf_free(buf);
14469 		return QDF_STATUS_E_FAILURE;
14470 	}
14471 
14472 	return QDF_STATUS_SUCCESS;
14473 }
14474 
14475 /**
14476  * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple  mcast filter
14477  *						   command to fw
14478  * @wmi_handle: wmi handle
14479  * @vdev_id: vdev id
14480  * @mcast_filter_params: mcast filter params
14481  *
14482  * Return: QDF_STATUS_SUCCESS for success or error code
14483  */
14484 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv(
14485 				wmi_unified_t wmi_handle,
14486 				uint8_t vdev_id,
14487 				struct pmo_mcast_filter_params *filter_param)
14488 
14489 {
14490 	WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd;
14491 	uint8_t *buf_ptr;
14492 	wmi_buf_t buf;
14493 	int err;
14494 	int i;
14495 	uint8_t *mac_addr_src_ptr = NULL;
14496 	wmi_mac_addr *mac_addr_dst_ptr;
14497 	uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
14498 		sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt;
14499 
14500 	buf = wmi_buf_alloc(wmi_handle, len);
14501 	if (!buf) {
14502 		WMI_LOGE("Failed to allocate memory");
14503 		return QDF_STATUS_E_NOMEM;
14504 	}
14505 
14506 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14507 	cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *)
14508 		wmi_buf_data(buf);
14509 	qdf_mem_zero(cmd, sizeof(*cmd));
14510 
14511 	WMITLV_SET_HDR(&cmd->tlv_header,
14512 	       WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param,
14513 	       WMITLV_GET_STRUCT_TLVLEN
14514 	       (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param));
14515 	cmd->operation =
14516 		((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE
14517 					: WMI_MULTIPLE_MCAST_FILTER_ADD);
14518 	cmd->vdev_id = vdev_id;
14519 	cmd->num_mcastaddrs = filter_param->multicast_addr_cnt;
14520 
14521 	buf_ptr += sizeof(*cmd);
14522 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
14523 		       sizeof(wmi_mac_addr) *
14524 			       filter_param->multicast_addr_cnt);
14525 
14526 	if (filter_param->multicast_addr_cnt == 0)
14527 		goto send_cmd;
14528 
14529 	mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr;
14530 	mac_addr_dst_ptr = (wmi_mac_addr *)
14531 			(buf_ptr + WMI_TLV_HDR_SIZE);
14532 
14533 	for (i = 0; i < filter_param->multicast_addr_cnt; i++) {
14534 		WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr);
14535 		mac_addr_src_ptr += ATH_MAC_LEN;
14536 		mac_addr_dst_ptr++;
14537 	}
14538 
14539 send_cmd:
14540 	wmi_mtrace(WMI_SET_MULTIPLE_MCAST_FILTER_CMDID, cmd->vdev_id, 0);
14541 	err = wmi_unified_cmd_send(wmi_handle, buf,
14542 				   len,
14543 				   WMI_SET_MULTIPLE_MCAST_FILTER_CMDID);
14544 	if (err) {
14545 		WMI_LOGE("Failed to send set_param cmd");
14546 		wmi_buf_free(buf);
14547 		return QDF_STATUS_E_FAILURE;
14548 	}
14549 
14550 	return QDF_STATUS_SUCCESS;
14551 }
14552 
14553 static void
14554 fill_fils_tlv_params(WMI_GTK_OFFLOAD_CMD_fixed_param *cmd,
14555 			  uint8_t vdev_id,
14556 			  struct pmo_gtk_req *params)
14557 {
14558 	uint8_t *buf_ptr;
14559 	wmi_gtk_offload_fils_tlv_param *ext_param;
14560 
14561 	buf_ptr = (uint8_t *) cmd + sizeof(*cmd);
14562 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14563 		       sizeof(*ext_param));
14564 	buf_ptr += WMI_TLV_HDR_SIZE;
14565 
14566 	ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr;
14567 	WMITLV_SET_HDR(&ext_param->tlv_header,
14568 		       WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param,
14569 		       WMITLV_GET_STRUCT_TLVLEN(
14570 				wmi_gtk_offload_fils_tlv_param));
14571 	ext_param->vdev_id = vdev_id;
14572 	ext_param->flags = cmd->flags;
14573 	ext_param->kek_len = params->kek_len;
14574 	qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len);
14575 	qdf_mem_copy(ext_param->KCK, params->kck,
14576 		     WMI_GTK_OFFLOAD_KCK_BYTES);
14577 	qdf_mem_copy(ext_param->replay_counter, &params->replay_counter,
14578 		     GTK_REPLAY_COUNTER_BYTES);
14579 }
14580 
14581 /**
14582  * send_gtk_offload_cmd_tlv() - send GTK offload command to fw
14583  * @wmi_handle: wmi handle
14584  * @vdev_id: vdev id
14585  * @params: GTK offload parameters
14586  *
14587  * Return: CDF status
14588  */
14589 static
14590 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
14591 					   struct pmo_gtk_req *params,
14592 					   bool enable_offload,
14593 					   uint32_t gtk_offload_opcode)
14594 {
14595 	int len;
14596 	wmi_buf_t buf;
14597 	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
14598 	QDF_STATUS status = QDF_STATUS_SUCCESS;
14599 
14600 	WMI_LOGD("%s Enter", __func__);
14601 
14602 	len = sizeof(*cmd);
14603 
14604 	if (params->is_fils_connection)
14605 		len += WMI_TLV_HDR_SIZE +
14606 		       sizeof(wmi_gtk_offload_fils_tlv_param);
14607 
14608 	/* alloc wmi buffer */
14609 	buf = wmi_buf_alloc(wmi_handle, len);
14610 	if (!buf) {
14611 		WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD");
14612 		status = QDF_STATUS_E_NOMEM;
14613 		goto out;
14614 	}
14615 
14616 	cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
14617 	WMITLV_SET_HDR(&cmd->tlv_header,
14618 		       WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
14619 		       WMITLV_GET_STRUCT_TLVLEN
14620 			       (WMI_GTK_OFFLOAD_CMD_fixed_param));
14621 
14622 	cmd->vdev_id = vdev_id;
14623 
14624 	/* Request target to enable GTK offload */
14625 	if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) {
14626 		cmd->flags = gtk_offload_opcode;
14627 
14628 		/* Copy the keys and replay counter */
14629 		qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN);
14630 		qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY);
14631 		qdf_mem_copy(cmd->replay_counter, &params->replay_counter,
14632 			     GTK_REPLAY_COUNTER_BYTES);
14633 	} else {
14634 		cmd->flags = gtk_offload_opcode;
14635 	}
14636 	if (params->is_fils_connection)
14637 		fill_fils_tlv_params(cmd, vdev_id, params);
14638 
14639 	WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len);
14640 	/* send the wmi command */
14641 	wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0);
14642 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
14643 				 WMI_GTK_OFFLOAD_CMDID)) {
14644 		WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID");
14645 		wmi_buf_free(buf);
14646 		status = QDF_STATUS_E_FAILURE;
14647 	}
14648 
14649 out:
14650 	WMI_LOGD("%s Exit", __func__);
14651 	return status;
14652 }
14653 
14654 /**
14655  * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw
14656  * @wmi_handle: wmi handle
14657  * @params: GTK offload params
14658  *
14659  * Return: CDF status
14660  */
14661 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv(
14662 			wmi_unified_t wmi_handle,
14663 			uint8_t vdev_id,
14664 			uint64_t offload_req_opcode)
14665 {
14666 	int len;
14667 	wmi_buf_t buf;
14668 	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
14669 	QDF_STATUS status = QDF_STATUS_SUCCESS;
14670 
14671 	len = sizeof(*cmd);
14672 
14673 	/* alloc wmi buffer */
14674 	buf = wmi_buf_alloc(wmi_handle, len);
14675 	if (!buf) {
14676 		WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD");
14677 		status = QDF_STATUS_E_NOMEM;
14678 		goto out;
14679 	}
14680 
14681 	cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
14682 	WMITLV_SET_HDR(&cmd->tlv_header,
14683 		       WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
14684 		       WMITLV_GET_STRUCT_TLVLEN
14685 			       (WMI_GTK_OFFLOAD_CMD_fixed_param));
14686 
14687 	/* Request for GTK offload status */
14688 	cmd->flags = offload_req_opcode;
14689 	cmd->vdev_id = vdev_id;
14690 
14691 	/* send the wmi command */
14692 	wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0);
14693 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
14694 				 WMI_GTK_OFFLOAD_CMDID)) {
14695 		WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info");
14696 		wmi_buf_free(buf);
14697 		status = QDF_STATUS_E_FAILURE;
14698 	}
14699 
14700 out:
14701 	return status;
14702 }
14703 
14704 /**
14705  * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params
14706  * @wmi_handle: wmi handler
14707  * @action_params: pointer to action_params
14708  *
14709  * Return: 0 for success, otherwise appropriate error code
14710  */
14711 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle,
14712 		struct pmo_action_wakeup_set_params *action_params)
14713 {
14714 	WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd;
14715 	wmi_buf_t buf;
14716 	int i;
14717 	int32_t err;
14718 	uint32_t len = 0, *cmd_args;
14719 	uint8_t *buf_ptr;
14720 
14721 	len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))
14722 				+ WMI_TLV_HDR_SIZE + sizeof(*cmd);
14723 	buf = wmi_buf_alloc(wmi_handle, len);
14724 	if (!buf) {
14725 		WMI_LOGE("Failed to allocate buffer to send action filter cmd");
14726 		return QDF_STATUS_E_NOMEM;
14727 	}
14728 	cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf);
14729 	buf_ptr = (uint8_t *)cmd;
14730 	WMITLV_SET_HDR(&cmd->tlv_header,
14731 		WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param,
14732 		WMITLV_GET_STRUCT_TLVLEN(
14733 				WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param));
14734 
14735 	cmd->vdev_id = action_params->vdev_id;
14736 	cmd->operation = action_params->operation;
14737 
14738 	for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++)
14739 		cmd->action_category_map[i] =
14740 				action_params->action_category_map[i];
14741 
14742 	buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param);
14743 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
14744 			(PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)));
14745 	buf_ptr += WMI_TLV_HDR_SIZE;
14746 	cmd_args = (uint32_t *) buf_ptr;
14747 	for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++)
14748 		cmd_args[i] = action_params->action_per_category[i];
14749 
14750 	wmi_mtrace(WMI_WOW_SET_ACTION_WAKE_UP_CMDID, cmd->vdev_id, 0);
14751 	err = wmi_unified_cmd_send(wmi_handle, buf,
14752 			len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID);
14753 	if (err) {
14754 		WMI_LOGE("Failed to send ap_ps_egap cmd");
14755 		wmi_buf_free(buf);
14756 		return QDF_STATUS_E_FAILURE;
14757 	}
14758 
14759 	return QDF_STATUS_SUCCESS;
14760 }
14761 
14762 #ifdef FEATURE_WLAN_LPHB
14763 
14764 /**
14765  * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration
14766  * @wmi_handle: wmi handle
14767  * @lphb_conf_req: configuration info
14768  *
14769  * Return: CDF status
14770  */
14771 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle,
14772 				wmi_hb_set_enable_cmd_fixed_param *params)
14773 {
14774 	QDF_STATUS status;
14775 	wmi_buf_t buf = NULL;
14776 	uint8_t *buf_ptr;
14777 	wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp;
14778 	int len = sizeof(wmi_hb_set_enable_cmd_fixed_param);
14779 
14780 
14781 	buf = wmi_buf_alloc(wmi_handle, len);
14782 	if (!buf) {
14783 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14784 		return QDF_STATUS_E_NOMEM;
14785 	}
14786 
14787 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14788 	hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr;
14789 	WMITLV_SET_HDR(&hb_enable_fp->tlv_header,
14790 		       WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param,
14791 		       WMITLV_GET_STRUCT_TLVLEN
14792 			       (wmi_hb_set_enable_cmd_fixed_param));
14793 
14794 	/* fill in values */
14795 	hb_enable_fp->vdev_id = params->session;
14796 	hb_enable_fp->enable = params->enable;
14797 	hb_enable_fp->item = params->item;
14798 	hb_enable_fp->session = params->session;
14799 
14800 	wmi_mtrace(WMI_HB_SET_ENABLE_CMDID, NO_SESSION, 0);
14801 	status = wmi_unified_cmd_send(wmi_handle, buf,
14802 				      len, WMI_HB_SET_ENABLE_CMDID);
14803 	if (QDF_IS_STATUS_ERROR(status)) {
14804 		WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d",
14805 			status);
14806 		wmi_buf_free(buf);
14807 	}
14808 
14809 	return status;
14810 }
14811 
14812 /**
14813  * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration
14814  * @wmi_handle: wmi handle
14815  * @lphb_conf_req: lphb config request
14816  *
14817  * Return: CDF status
14818  */
14819 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle,
14820 	    wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req)
14821 {
14822 	QDF_STATUS status;
14823 	wmi_buf_t buf = NULL;
14824 	uint8_t *buf_ptr;
14825 	wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp;
14826 	int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param);
14827 
14828 	buf = wmi_buf_alloc(wmi_handle, len);
14829 	if (!buf) {
14830 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14831 		return QDF_STATUS_E_NOMEM;
14832 	}
14833 
14834 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14835 	hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr;
14836 	WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header,
14837 		       WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param,
14838 		       WMITLV_GET_STRUCT_TLVLEN
14839 			       (wmi_hb_set_tcp_params_cmd_fixed_param));
14840 
14841 	/* fill in values */
14842 	hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id;
14843 	hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip;
14844 	hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip;
14845 	hb_tcp_params_fp->seq = lphb_conf_req->seq;
14846 	hb_tcp_params_fp->src_port = lphb_conf_req->src_port;
14847 	hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port;
14848 	hb_tcp_params_fp->interval = lphb_conf_req->interval;
14849 	hb_tcp_params_fp->timeout = lphb_conf_req->timeout;
14850 	hb_tcp_params_fp->session = lphb_conf_req->session;
14851 	qdf_mem_copy(&hb_tcp_params_fp->gateway_mac,
14852 				   &lphb_conf_req->gateway_mac,
14853 				   sizeof(hb_tcp_params_fp->gateway_mac));
14854 
14855 	wmi_mtrace(WMI_HB_SET_TCP_PARAMS_CMDID, NO_SESSION, 0);
14856 	status = wmi_unified_cmd_send(wmi_handle, buf,
14857 				      len, WMI_HB_SET_TCP_PARAMS_CMDID);
14858 	if (QDF_IS_STATUS_ERROR(status)) {
14859 		WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d",
14860 			status);
14861 		wmi_buf_free(buf);
14862 	}
14863 
14864 	return status;
14865 }
14866 
14867 /**
14868  * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd
14869  * @wmi_handle: wmi handle
14870  * @lphb_conf_req: lphb config request
14871  *
14872  * Return: CDF status
14873  */
14874 static
14875 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
14876 		wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp)
14877 {
14878 	QDF_STATUS status;
14879 	wmi_buf_t buf = NULL;
14880 	uint8_t *buf_ptr;
14881 	wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp;
14882 	int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param);
14883 
14884 	buf = wmi_buf_alloc(wmi_handle, len);
14885 	if (!buf) {
14886 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14887 		return QDF_STATUS_E_NOMEM;
14888 	}
14889 
14890 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14891 	hb_tcp_filter_fp =
14892 		(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr;
14893 	WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header,
14894 		WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param,
14895 		WMITLV_GET_STRUCT_TLVLEN
14896 		       (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param));
14897 
14898 	/* fill in values */
14899 	hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id;
14900 	hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length;
14901 	hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset;
14902 	hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session;
14903 	memcpy((void *)&hb_tcp_filter_fp->filter,
14904 	       (void *)&g_hb_tcp_filter_fp->filter,
14905 	       WMI_WLAN_HB_MAX_FILTER_SIZE);
14906 
14907 	wmi_mtrace(WMI_HB_SET_TCP_PKT_FILTER_CMDID, NO_SESSION, 0);
14908 	status = wmi_unified_cmd_send(wmi_handle, buf,
14909 				      len, WMI_HB_SET_TCP_PKT_FILTER_CMDID);
14910 	if (QDF_IS_STATUS_ERROR(status)) {
14911 		WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d",
14912 			status);
14913 		wmi_buf_free(buf);
14914 	}
14915 
14916 	return status;
14917 }
14918 
14919 /**
14920  * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB
14921  * @wmi_handle: wmi handle
14922  * @lphb_conf_req: lphb config request
14923  *
14924  * Return: CDF status
14925  */
14926 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle,
14927 		   wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req)
14928 {
14929 	QDF_STATUS status;
14930 	wmi_buf_t buf = NULL;
14931 	uint8_t *buf_ptr;
14932 	wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp;
14933 	int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param);
14934 
14935 	buf = wmi_buf_alloc(wmi_handle, len);
14936 	if (!buf) {
14937 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14938 		return QDF_STATUS_E_NOMEM;
14939 	}
14940 
14941 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14942 	hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr;
14943 	WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header,
14944 		       WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param,
14945 		       WMITLV_GET_STRUCT_TLVLEN
14946 			       (wmi_hb_set_udp_params_cmd_fixed_param));
14947 
14948 	/* fill in values */
14949 	hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id;
14950 	hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip;
14951 	hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip;
14952 	hb_udp_params_fp->src_port = lphb_conf_req->src_port;
14953 	hb_udp_params_fp->dst_port = lphb_conf_req->dst_port;
14954 	hb_udp_params_fp->interval = lphb_conf_req->interval;
14955 	hb_udp_params_fp->timeout = lphb_conf_req->timeout;
14956 	hb_udp_params_fp->session = lphb_conf_req->session;
14957 	qdf_mem_copy(&hb_udp_params_fp->gateway_mac,
14958 				   &lphb_conf_req->gateway_mac,
14959 				   sizeof(lphb_conf_req->gateway_mac));
14960 
14961 	wmi_mtrace(WMI_HB_SET_UDP_PARAMS_CMDID, NO_SESSION, 0);
14962 	status = wmi_unified_cmd_send(wmi_handle, buf,
14963 				      len, WMI_HB_SET_UDP_PARAMS_CMDID);
14964 	if (QDF_IS_STATUS_ERROR(status)) {
14965 		WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d",
14966 			status);
14967 		wmi_buf_free(buf);
14968 	}
14969 
14970 	return status;
14971 }
14972 
14973 /**
14974  * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command
14975  * @wmi_handle: wmi handle
14976  * @lphb_conf_req: lphb config request
14977  *
14978  * Return: CDF status
14979  */
14980 static
14981 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
14982 		wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req)
14983 {
14984 	QDF_STATUS status;
14985 	wmi_buf_t buf = NULL;
14986 	uint8_t *buf_ptr;
14987 	wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp;
14988 	int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param);
14989 
14990 	buf = wmi_buf_alloc(wmi_handle, len);
14991 	if (!buf) {
14992 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
14993 		return QDF_STATUS_E_NOMEM;
14994 	}
14995 
14996 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14997 	hb_udp_filter_fp =
14998 		(wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr;
14999 	WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header,
15000 		WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param,
15001 		WMITLV_GET_STRUCT_TLVLEN
15002 		       (wmi_hb_set_udp_pkt_filter_cmd_fixed_param));
15003 
15004 	/* fill in values */
15005 	hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id;
15006 	hb_udp_filter_fp->length = lphb_conf_req->length;
15007 	hb_udp_filter_fp->offset = lphb_conf_req->offset;
15008 	hb_udp_filter_fp->session = lphb_conf_req->session;
15009 	memcpy((void *)&hb_udp_filter_fp->filter,
15010 	       (void *)&lphb_conf_req->filter,
15011 	       WMI_WLAN_HB_MAX_FILTER_SIZE);
15012 
15013 	wmi_mtrace(WMI_HB_SET_UDP_PKT_FILTER_CMDID, NO_SESSION, 0);
15014 	status = wmi_unified_cmd_send(wmi_handle, buf,
15015 				      len, WMI_HB_SET_UDP_PKT_FILTER_CMDID);
15016 	if (QDF_IS_STATUS_ERROR(status)) {
15017 		WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d",
15018 			status);
15019 		wmi_buf_free(buf);
15020 	}
15021 
15022 	return status;
15023 }
15024 #endif /* FEATURE_WLAN_LPHB */
15025 
15026 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi,
15027 					      struct pmo_hw_filter_params *req)
15028 {
15029 	QDF_STATUS status;
15030 	wmi_hw_data_filter_cmd_fixed_param *cmd;
15031 	wmi_buf_t wmi_buf;
15032 
15033 	if (!req) {
15034 		WMI_LOGE("req is null");
15035 		return QDF_STATUS_E_INVAL;
15036 	}
15037 
15038 	wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd));
15039 	if (!wmi_buf) {
15040 		WMI_LOGE(FL("Out of memory"));
15041 		return QDF_STATUS_E_NOMEM;
15042 	}
15043 
15044 	cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf);
15045 	WMITLV_SET_HDR(&cmd->tlv_header,
15046 		  WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param,
15047 		  WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param));
15048 	cmd->vdev_id = req->vdev_id;
15049 	cmd->enable = req->enable;
15050 	/* Set all modes in case of disable */
15051 	if (!cmd->enable)
15052 		cmd->hw_filter_bitmap = ((uint32_t)~0U);
15053 	else
15054 		cmd->hw_filter_bitmap = req->mode_bitmap;
15055 
15056 	WMI_LOGD("Send %s hw filter mode: 0x%X for vdev id %d",
15057 		 req->enable ? "enable" : "disable", req->mode_bitmap,
15058 		 req->vdev_id);
15059 
15060 	wmi_mtrace(WMI_HW_DATA_FILTER_CMDID, cmd->vdev_id, 0);
15061 	status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd),
15062 				      WMI_HW_DATA_FILTER_CMDID);
15063 	if (QDF_IS_STATUS_ERROR(status)) {
15064 		WMI_LOGE("Failed to configure hw filter");
15065 		wmi_buf_free(wmi_buf);
15066 	}
15067 
15068 	return status;
15069 }
15070 
15071 #ifdef WLAN_FEATURE_PACKET_FILTERING
15072 /**
15073  * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter
15074  * @wmi_handle: wmi handle
15075  * @vdev_id: vdev id
15076  * @enable: Flag to enable/disable packet filter
15077  *
15078  * Return: QDF_STATUS_SUCCESS for success or error code
15079  */
15080 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv(
15081 		wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable)
15082 {
15083 	int32_t len;
15084 	int ret = 0;
15085 	wmi_buf_t buf;
15086 	WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd;
15087 
15088 	len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param);
15089 
15090 	buf = wmi_buf_alloc(wmi_handle, len);
15091 	if (!buf) {
15092 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
15093 		return QDF_STATUS_E_NOMEM;
15094 	}
15095 
15096 	cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf);
15097 	WMITLV_SET_HDR(&cmd->tlv_header,
15098 		WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param,
15099 		WMITLV_GET_STRUCT_TLVLEN(
15100 		WMI_PACKET_FILTER_ENABLE_CMD_fixed_param));
15101 
15102 	cmd->vdev_id = vdev_id;
15103 	if (enable)
15104 		cmd->enable = PACKET_FILTER_SET_ENABLE;
15105 	else
15106 		cmd->enable = PACKET_FILTER_SET_DISABLE;
15107 
15108 	WMI_LOGE("%s: Packet filter enable %d for vdev_id %d",
15109 		__func__, cmd->enable, vdev_id);
15110 
15111 	wmi_mtrace(WMI_PACKET_FILTER_ENABLE_CMDID, cmd->vdev_id, 0);
15112 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
15113 			 WMI_PACKET_FILTER_ENABLE_CMDID);
15114 	if (ret) {
15115 		WMI_LOGE("Failed to send packet filter wmi cmd to fw");
15116 		wmi_buf_free(buf);
15117 	}
15118 
15119 	return ret;
15120 }
15121 
15122 /**
15123  * send_config_packet_filter_cmd_tlv() - configure packet filter in target
15124  * @wmi_handle: wmi handle
15125  * @vdev_id: vdev id
15126  * @rcv_filter_param: Packet filter parameters
15127  * @filter_id: Filter id
15128  * @enable: Flag to add/delete packet filter configuration
15129  *
15130  * Return: QDF_STATUS_SUCCESS for success or error code
15131  */
15132 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle,
15133 		uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param,
15134 		uint8_t filter_id, bool enable)
15135 {
15136 	int len, i;
15137 	int err = 0;
15138 	wmi_buf_t buf;
15139 	WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd;
15140 
15141 
15142 	/* allocate the memory */
15143 	len = sizeof(*cmd);
15144 	buf = wmi_buf_alloc(wmi_handle, len);
15145 	if (!buf) {
15146 		WMI_LOGE("Failed to allocate buffer to send set_param cmd");
15147 		return QDF_STATUS_E_NOMEM;
15148 	}
15149 
15150 	cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf);
15151 	WMITLV_SET_HDR(&cmd->tlv_header,
15152 		WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param,
15153 		WMITLV_GET_STRUCT_TLVLEN
15154 			       (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param));
15155 
15156 	cmd->vdev_id = vdev_id;
15157 	cmd->filter_id = filter_id;
15158 	if (enable)
15159 		cmd->filter_action = PACKET_FILTER_SET_ACTIVE;
15160 	else
15161 		cmd->filter_action = PACKET_FILTER_SET_INACTIVE;
15162 
15163 	if (enable) {
15164 		cmd->num_params = QDF_MIN(
15165 			WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER,
15166 			rcv_filter_param->num_params);
15167 		cmd->filter_type = rcv_filter_param->filter_type;
15168 		cmd->coalesce_time = rcv_filter_param->coalesce_time;
15169 
15170 		for (i = 0; i < cmd->num_params; i++) {
15171 			cmd->paramsData[i].proto_type =
15172 				rcv_filter_param->params_data[i].protocol_layer;
15173 			cmd->paramsData[i].cmp_type =
15174 				rcv_filter_param->params_data[i].compare_flag;
15175 			cmd->paramsData[i].data_length =
15176 				rcv_filter_param->params_data[i].data_length;
15177 			cmd->paramsData[i].data_offset =
15178 				rcv_filter_param->params_data[i].data_offset;
15179 			memcpy(&cmd->paramsData[i].compareData,
15180 				rcv_filter_param->params_data[i].compare_data,
15181 				sizeof(cmd->paramsData[i].compareData));
15182 			memcpy(&cmd->paramsData[i].dataMask,
15183 				rcv_filter_param->params_data[i].data_mask,
15184 				sizeof(cmd->paramsData[i].dataMask));
15185 		}
15186 	}
15187 
15188 	WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d",
15189 		cmd->filter_action, cmd->filter_id, cmd->num_params);
15190 	/* send the command along with data */
15191 	wmi_mtrace(WMI_PACKET_FILTER_CONFIG_CMDID, cmd->vdev_id, 0);
15192 	err = wmi_unified_cmd_send(wmi_handle, buf, len,
15193 				WMI_PACKET_FILTER_CONFIG_CMDID);
15194 	if (err) {
15195 		WMI_LOGE("Failed to send pkt_filter cmd");
15196 		wmi_buf_free(buf);
15197 		return QDF_STATUS_E_FAILURE;
15198 	}
15199 
15200 	return QDF_STATUS_SUCCESS;
15201 }
15202 #endif /* End of WLAN_FEATURE_PACKET_FILTERING */
15203 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */
15204 
15205 /**
15206  * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request
15207  * @wmi_handle: wmi handle
15208  * @request: SSID hotlist set request
15209  *
15210  * Return: QDF_STATUS enumeration
15211  */
15212 static QDF_STATUS
15213 send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle,
15214 		     struct ssid_hotlist_request_params *request)
15215 {
15216 	wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd;
15217 	wmi_buf_t wmi_buf;
15218 	uint32_t len;
15219 	uint32_t array_size;
15220 	uint8_t *buf_ptr;
15221 
15222 	/* length of fixed portion */
15223 	len = sizeof(*cmd);
15224 
15225 	/* length of variable portion */
15226 	array_size =
15227 		request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry);
15228 	len += WMI_TLV_HDR_SIZE + array_size;
15229 
15230 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15231 	if (!wmi_buf) {
15232 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
15233 		return QDF_STATUS_E_NOMEM;
15234 	}
15235 
15236 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
15237 	cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *)
15238 						buf_ptr;
15239 	WMITLV_SET_HDR
15240 		(&cmd->tlv_header,
15241 		 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param,
15242 		 WMITLV_GET_STRUCT_TLVLEN
15243 			(wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param));
15244 
15245 	cmd->request_id = request->request_id;
15246 	cmd->requestor_id = 0;
15247 	cmd->vdev_id = request->session_id;
15248 	cmd->table_id = 0;
15249 	cmd->lost_ap_scan_count = request->lost_ssid_sample_size;
15250 	cmd->total_entries = request->ssid_count;
15251 	cmd->num_entries_in_page = request->ssid_count;
15252 	cmd->first_entry_index = 0;
15253 
15254 	buf_ptr += sizeof(*cmd);
15255 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size);
15256 
15257 	if (request->ssid_count) {
15258 		wmi_extscan_hotlist_ssid_entry *entry;
15259 		int i;
15260 
15261 		buf_ptr += WMI_TLV_HDR_SIZE;
15262 		entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr;
15263 		for (i = 0; i < request->ssid_count; i++) {
15264 			WMITLV_SET_HDR
15265 				(entry,
15266 				 WMITLV_TAG_ARRAY_STRUC,
15267 				 WMITLV_GET_STRUCT_TLVLEN
15268 					(wmi_extscan_hotlist_ssid_entry));
15269 			entry->ssid.ssid_len = request->ssids[i].ssid.length;
15270 			qdf_mem_copy(entry->ssid.ssid,
15271 				     request->ssids[i].ssid.mac_ssid,
15272 				     request->ssids[i].ssid.length);
15273 			entry->band = request->ssids[i].band;
15274 			entry->min_rssi = request->ssids[i].rssi_low;
15275 			entry->max_rssi = request->ssids[i].rssi_high;
15276 			entry++;
15277 		}
15278 		cmd->mode = WMI_EXTSCAN_MODE_START;
15279 	} else {
15280 		cmd->mode = WMI_EXTSCAN_MODE_STOP;
15281 	}
15282 
15283 	wmi_mtrace(WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID,
15284 		   cmd->vdev_id, 0);
15285 	if (wmi_unified_cmd_send
15286 		(wmi_handle, wmi_buf, len,
15287 		 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) {
15288 		WMI_LOGE("%s: failed to send command", __func__);
15289 		wmi_buf_free(wmi_buf);
15290 		return QDF_STATUS_E_FAILURE;
15291 	}
15292 
15293 	return QDF_STATUS_SUCCESS;
15294 }
15295 
15296 /**
15297  * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw.
15298  * @wmi_handle: wmi handle
15299  * @vdev_id: vdev id
15300  *
15301  * This function sends roam synch complete event to fw.
15302  *
15303  * Return: CDF STATUS
15304  */
15305 static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle,
15306 		 uint8_t vdev_id)
15307 {
15308 	wmi_roam_synch_complete_fixed_param *cmd;
15309 	wmi_buf_t wmi_buf;
15310 	uint8_t *buf_ptr;
15311 	uint16_t len;
15312 	len = sizeof(wmi_roam_synch_complete_fixed_param);
15313 
15314 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15315 	if (!wmi_buf) {
15316 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
15317 		return QDF_STATUS_E_NOMEM;
15318 	}
15319 	cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf);
15320 	buf_ptr = (uint8_t *) cmd;
15321 	WMITLV_SET_HDR(&cmd->tlv_header,
15322 		       WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param,
15323 		       WMITLV_GET_STRUCT_TLVLEN
15324 			       (wmi_roam_synch_complete_fixed_param));
15325 	cmd->vdev_id = vdev_id;
15326 	wmi_mtrace(WMI_ROAM_SYNCH_COMPLETE, cmd->vdev_id, 0);
15327 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15328 				 WMI_ROAM_SYNCH_COMPLETE)) {
15329 		WMI_LOGP("%s: failed to send roam synch confirmation",
15330 			 __func__);
15331 		wmi_buf_free(wmi_buf);
15332 		return QDF_STATUS_E_FAILURE;
15333 	}
15334 
15335 	return QDF_STATUS_SUCCESS;
15336 }
15337 
15338 /**
15339  * send_fw_test_cmd_tlv() - send fw test command to fw.
15340  * @wmi_handle: wmi handle
15341  * @wmi_fwtest: fw test command
15342  *
15343  * This function sends fw test command to fw.
15344  *
15345  * Return: CDF STATUS
15346  */
15347 static
15348 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle,
15349 			       struct set_fwtest_params *wmi_fwtest)
15350 {
15351 	wmi_fwtest_set_param_cmd_fixed_param *cmd;
15352 	wmi_buf_t wmi_buf;
15353 	uint16_t len;
15354 
15355 	len = sizeof(*cmd);
15356 
15357 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15358 	if (!wmi_buf) {
15359 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
15360 		return QDF_STATUS_E_NOMEM;
15361 	}
15362 
15363 	cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf);
15364 	WMITLV_SET_HDR(&cmd->tlv_header,
15365 		       WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param,
15366 		       WMITLV_GET_STRUCT_TLVLEN(
15367 		       wmi_fwtest_set_param_cmd_fixed_param));
15368 	cmd->param_id = wmi_fwtest->arg;
15369 	cmd->param_value = wmi_fwtest->value;
15370 
15371 	wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0);
15372 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15373 				 WMI_FWTEST_CMDID)) {
15374 		WMI_LOGP("%s: failed to send fw test command", __func__);
15375 		qdf_nbuf_free(wmi_buf);
15376 		return QDF_STATUS_E_FAILURE;
15377 	}
15378 
15379 	return QDF_STATUS_SUCCESS;
15380 }
15381 
15382 /**
15383  * send_unit_test_cmd_tlv() - send unit test command to fw.
15384  * @wmi_handle: wmi handle
15385  * @wmi_utest: unit test command
15386  *
15387  * This function send unit test command to fw.
15388  *
15389  * Return: CDF STATUS
15390  */
15391 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle,
15392 			       struct wmi_unit_test_cmd *wmi_utest)
15393 {
15394 	wmi_unit_test_cmd_fixed_param *cmd;
15395 	wmi_buf_t wmi_buf;
15396 	uint8_t *buf_ptr;
15397 	int i;
15398 	uint16_t len, args_tlv_len;
15399 	uint32_t *unit_test_cmd_args;
15400 
15401 	args_tlv_len =
15402 		WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t);
15403 	len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len;
15404 
15405 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15406 	if (!wmi_buf) {
15407 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
15408 		return QDF_STATUS_E_NOMEM;
15409 	}
15410 
15411 	cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf);
15412 	buf_ptr = (uint8_t *) cmd;
15413 	WMITLV_SET_HDR(&cmd->tlv_header,
15414 		       WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param,
15415 		       WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param));
15416 	cmd->vdev_id = wmi_utest->vdev_id;
15417 	cmd->module_id = wmi_utest->module_id;
15418 	cmd->num_args = wmi_utest->num_args;
15419 	cmd->diag_token = wmi_utest->diag_token;
15420 	buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param);
15421 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
15422 		       (wmi_utest->num_args * sizeof(uint32_t)));
15423 	unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
15424 	WMI_LOGI("%s: VDEV ID: %d\n", __func__, cmd->vdev_id);
15425 	WMI_LOGI("%s: MODULE ID: %d\n", __func__, cmd->module_id);
15426 	WMI_LOGI("%s: TOKEN: %d\n", __func__, cmd->diag_token);
15427 	WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args);
15428 	for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) {
15429 		unit_test_cmd_args[i] = wmi_utest->args[i];
15430 		WMI_LOGI("%d,", wmi_utest->args[i]);
15431 	}
15432 	wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0);
15433 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15434 				 WMI_UNIT_TEST_CMDID)) {
15435 		WMI_LOGP("%s: failed to send unit test command", __func__);
15436 		wmi_buf_free(wmi_buf);
15437 		return QDF_STATUS_E_FAILURE;
15438 	}
15439 
15440 	return QDF_STATUS_SUCCESS;
15441 }
15442 
15443 /**
15444  * send_roam_invoke_cmd_tlv() - send roam invoke command to fw.
15445  * @wmi_handle: wma handle
15446  * @roaminvoke: roam invoke command
15447  *
15448  * Send roam invoke command to fw for fastreassoc.
15449  *
15450  * Return: CDF STATUS
15451  */
15452 static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle,
15453 		struct wmi_roam_invoke_cmd *roaminvoke,
15454 		uint32_t ch_hz)
15455 {
15456 	wmi_roam_invoke_cmd_fixed_param *cmd;
15457 	wmi_buf_t wmi_buf;
15458 	u_int8_t *buf_ptr;
15459 	u_int16_t len, args_tlv_len;
15460 	uint32_t *channel_list;
15461 	wmi_mac_addr *bssid_list;
15462 	wmi_tlv_buf_len_param *buf_len_tlv;
15463 
15464 	/* Host sends only one channel and one bssid */
15465 	args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) +
15466 			sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) +
15467 			roundup(roaminvoke->frame_len, sizeof(uint32_t));
15468 	len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len;
15469 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15470 	if (!wmi_buf) {
15471 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
15472 		return QDF_STATUS_E_NOMEM;
15473 	}
15474 
15475 	cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf);
15476 	buf_ptr = (u_int8_t *) cmd;
15477 	WMITLV_SET_HDR(&cmd->tlv_header,
15478 	WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param,
15479 	WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param));
15480 	cmd->vdev_id = roaminvoke->vdev_id;
15481 	cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE);
15482 	if (roaminvoke->is_same_bssid)
15483 		cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP);
15484 	WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid);
15485 
15486 	if (roaminvoke->frame_len) {
15487 		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP;
15488 		/* packing 1 beacon/probe_rsp frame with WMI cmd */
15489 		cmd->num_buf = 1;
15490 	} else {
15491 		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH;
15492 		cmd->num_buf = 0;
15493 	}
15494 
15495 	cmd->roam_ap_sel_mode = 0;
15496 	cmd->roam_delay = 0;
15497 	cmd->num_chan = 1;
15498 	cmd->num_bssid = 1;
15499 
15500 	buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param);
15501 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
15502 				(sizeof(u_int32_t)));
15503 	channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
15504 	*channel_list = ch_hz;
15505 	buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE;
15506 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
15507 				(sizeof(wmi_mac_addr)));
15508 	bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
15509 	WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list);
15510 
15511 	/* move to next tlv i.e. bcn_prb_buf_list */
15512 	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr);
15513 
15514 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
15515 			sizeof(wmi_tlv_buf_len_param));
15516 
15517 	buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE);
15518 	buf_len_tlv->buf_len = roaminvoke->frame_len;
15519 
15520 	/* move to next tlv i.e. bcn_prb_frm */
15521 	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param);
15522 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
15523 		roundup(roaminvoke->frame_len, sizeof(uint32_t)));
15524 
15525 	/* copy frame after the header */
15526 	qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
15527 			roaminvoke->frame_buf,
15528 			roaminvoke->frame_len);
15529 
15530 	WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len);
15531 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
15532 			buf_ptr + WMI_TLV_HDR_SIZE,
15533 			roaminvoke->frame_len);
15534 	WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"),
15535 			cmd->flags, cmd->roam_scan_mode,
15536 			cmd->roam_ap_sel_mode, cmd->roam_delay,
15537 			cmd->num_chan, cmd->num_bssid);
15538 	WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz);
15539 
15540 	wmi_mtrace(WMI_ROAM_INVOKE_CMDID, cmd->vdev_id, 0);
15541 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15542 					WMI_ROAM_INVOKE_CMDID)) {
15543 		WMI_LOGP("%s: failed to send roam invoke command", __func__);
15544 		wmi_buf_free(wmi_buf);
15545 		return QDF_STATUS_E_FAILURE;
15546 	}
15547 
15548 	return QDF_STATUS_SUCCESS;
15549 }
15550 
15551 /**
15552  * send_roam_scan_offload_cmd_tlv() - set roam offload command
15553  * @wmi_handle: wmi handle
15554  * @command: command
15555  * @vdev_id: vdev id
15556  *
15557  * This function set roam offload command to fw.
15558  *
15559  * Return: CDF status
15560  */
15561 static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle,
15562 					 uint32_t command, uint32_t vdev_id)
15563 {
15564 	QDF_STATUS status;
15565 	wmi_roam_scan_cmd_fixed_param *cmd_fp;
15566 	wmi_buf_t buf = NULL;
15567 	int len;
15568 	uint8_t *buf_ptr;
15569 
15570 	len = sizeof(wmi_roam_scan_cmd_fixed_param);
15571 	buf = wmi_buf_alloc(wmi_handle, len);
15572 	if (!buf) {
15573 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15574 		return QDF_STATUS_E_NOMEM;
15575 	}
15576 
15577 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15578 
15579 	cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr;
15580 	WMITLV_SET_HDR(&cmd_fp->tlv_header,
15581 		       WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param,
15582 		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param));
15583 	cmd_fp->vdev_id = vdev_id;
15584 	cmd_fp->command_arg = command;
15585 
15586 	wmi_mtrace(WMI_ROAM_SCAN_CMD, NO_SESSION, 0);
15587 	status = wmi_unified_cmd_send(wmi_handle, buf,
15588 				      len, WMI_ROAM_SCAN_CMD);
15589 	if (QDF_IS_STATUS_ERROR(status)) {
15590 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d",
15591 			status);
15592 		goto error;
15593 	}
15594 
15595 	WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__);
15596 	return QDF_STATUS_SUCCESS;
15597 
15598 error:
15599 	wmi_buf_free(buf);
15600 
15601 	return status;
15602 }
15603 
15604 /**
15605  * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw
15606  * @wmi_handle: wmi handle
15607  * @ap_profile_p: ap profile
15608  * @vdev_id: vdev id
15609  *
15610  * Send WMI_ROAM_AP_PROFILE to firmware
15611  *
15612  * Return: CDF status
15613  */
15614 static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
15615 					    struct ap_profile_params *ap_profile)
15616 {
15617 	wmi_buf_t buf = NULL;
15618 	QDF_STATUS status;
15619 	int len;
15620 	uint8_t *buf_ptr;
15621 	wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp;
15622 	wmi_roam_cnd_scoring_param *score_param;
15623 	wmi_ap_profile *profile;
15624 
15625 	len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile);
15626 	len += sizeof(*score_param);
15627 	buf = wmi_buf_alloc(wmi_handle, len);
15628 	if (!buf) {
15629 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15630 		return QDF_STATUS_E_NOMEM;
15631 	}
15632 
15633 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15634 	roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr;
15635 	WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header,
15636 		       WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param,
15637 		       WMITLV_GET_STRUCT_TLVLEN
15638 			       (wmi_roam_ap_profile_fixed_param));
15639 	/* fill in threshold values */
15640 	roam_ap_profile_fp->vdev_id = ap_profile->vdev_id;
15641 	roam_ap_profile_fp->id = 0;
15642 	buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param);
15643 
15644 	profile = (wmi_ap_profile *)buf_ptr;
15645 	WMITLV_SET_HDR(&profile->tlv_header,
15646 		       WMITLV_TAG_STRUC_wmi_ap_profile,
15647 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile));
15648 	profile->flags = ap_profile->profile.flags;
15649 	profile->rssi_threshold = ap_profile->profile.rssi_threshold;
15650 	profile->ssid.ssid_len = ap_profile->profile.ssid.length;
15651 	qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid,
15652 		     profile->ssid.ssid_len);
15653 	profile->rsn_authmode = ap_profile->profile.rsn_authmode;
15654 	profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset;
15655 	profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset;
15656 	profile->rsn_mcastmgmtcipherset =
15657 				ap_profile->profile.rsn_mcastmgmtcipherset;
15658 	profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh;
15659 
15660 	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",
15661 		 profile->flags, profile->rssi_threshold,
15662 		 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid,
15663 		 profile->rsn_authmode, profile->rsn_ucastcipherset,
15664 		 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset,
15665 		 profile->rssi_abs_thresh);
15666 
15667 	buf_ptr += sizeof(wmi_ap_profile);
15668 
15669 	score_param = (wmi_roam_cnd_scoring_param *)buf_ptr;
15670 	WMITLV_SET_HDR(&score_param->tlv_header,
15671 		       WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param,
15672 		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param));
15673 	score_param->disable_bitmap = ap_profile->param.disable_bitmap;
15674 	score_param->rssi_weightage_pcnt =
15675 			ap_profile->param.rssi_weightage;
15676 	score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage;
15677 	score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage;
15678 	score_param->he_weightage_pcnt = ap_profile->param.he_weightage;
15679 	score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage;
15680 	score_param->band_weightage_pcnt = ap_profile->param.band_weightage;
15681 	score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage;
15682 	score_param->esp_qbss_weightage_pcnt =
15683 			ap_profile->param.esp_qbss_weightage;
15684 	score_param->beamforming_weightage_pcnt =
15685 			ap_profile->param.beamforming_weightage;
15686 	score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage;
15687 	score_param->oce_wan_weightage_pcnt =
15688 			ap_profile->param.oce_wan_weightage;
15689 
15690 	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",
15691 		 score_param->disable_bitmap, score_param->rssi_weightage_pcnt,
15692 		 score_param->ht_weightage_pcnt,
15693 		 score_param->vht_weightage_pcnt,
15694 		 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt,
15695 		 score_param->band_weightage_pcnt,
15696 		 score_param->nss_weightage_pcnt,
15697 		 score_param->esp_qbss_weightage_pcnt,
15698 		 score_param->beamforming_weightage_pcnt,
15699 		 score_param->pcl_weightage_pcnt,
15700 		 score_param->oce_wan_weightage_pcnt);
15701 
15702 	score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score;
15703 	score_param->band_scoring.score_pcnt =
15704 			ap_profile->param.band_index_score;
15705 	score_param->nss_scoring.score_pcnt =
15706 			ap_profile->param.nss_index_score;
15707 
15708 	WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x",
15709 		 score_param->bw_scoring.score_pcnt,
15710 		 score_param->band_scoring.score_pcnt,
15711 		 score_param->nss_scoring.score_pcnt);
15712 
15713 	score_param->rssi_scoring.best_rssi_threshold =
15714 		(-1) * ap_profile->param.rssi_scoring.best_rssi_threshold;
15715 	score_param->rssi_scoring.good_rssi_threshold =
15716 		(-1) * ap_profile->param.rssi_scoring.good_rssi_threshold;
15717 	score_param->rssi_scoring.bad_rssi_threshold =
15718 		(-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold;
15719 	score_param->rssi_scoring.good_rssi_pcnt =
15720 		ap_profile->param.rssi_scoring.good_rssi_pcnt;
15721 	score_param->rssi_scoring.bad_rssi_pcnt =
15722 		ap_profile->param.rssi_scoring.bad_rssi_pcnt;
15723 	score_param->rssi_scoring.good_bucket_size =
15724 		ap_profile->param.rssi_scoring.good_bucket_size;
15725 	score_param->rssi_scoring.bad_bucket_size =
15726 		ap_profile->param.rssi_scoring.bad_bucket_size;
15727 	score_param->rssi_scoring.rssi_pref_5g_rssi_thresh =
15728 		(-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh;
15729 
15730 	WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d",
15731 		 score_param->rssi_scoring.best_rssi_threshold,
15732 		 score_param->rssi_scoring.good_rssi_threshold,
15733 		 score_param->rssi_scoring.bad_rssi_threshold,
15734 		 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh);
15735 	WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d",
15736 		 score_param->rssi_scoring.good_rssi_pcnt,
15737 		 score_param->rssi_scoring.bad_rssi_pcnt,
15738 		 score_param->rssi_scoring.good_bucket_size,
15739 		 score_param->rssi_scoring.bad_bucket_size);
15740 
15741 	score_param->esp_qbss_scoring.num_slot =
15742 			ap_profile->param.esp_qbss_scoring.num_slot;
15743 	score_param->esp_qbss_scoring.score_pcnt3_to_0 =
15744 			ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0;
15745 	score_param->esp_qbss_scoring.score_pcnt7_to_4 =
15746 			ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4;
15747 	score_param->esp_qbss_scoring.score_pcnt11_to_8 =
15748 			ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8;
15749 	score_param->esp_qbss_scoring.score_pcnt15_to_12 =
15750 			ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12;
15751 
15752 	WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
15753 		 score_param->esp_qbss_scoring.num_slot,
15754 		 score_param->esp_qbss_scoring.score_pcnt3_to_0,
15755 		 score_param->esp_qbss_scoring.score_pcnt7_to_4,
15756 		 score_param->esp_qbss_scoring.score_pcnt11_to_8,
15757 		 score_param->esp_qbss_scoring.score_pcnt15_to_12);
15758 
15759 	score_param->oce_wan_scoring.num_slot =
15760 			ap_profile->param.oce_wan_scoring.num_slot;
15761 	score_param->oce_wan_scoring.score_pcnt3_to_0 =
15762 			ap_profile->param.oce_wan_scoring.score_pcnt3_to_0;
15763 	score_param->oce_wan_scoring.score_pcnt7_to_4 =
15764 			ap_profile->param.oce_wan_scoring.score_pcnt7_to_4;
15765 	score_param->oce_wan_scoring.score_pcnt11_to_8 =
15766 			ap_profile->param.oce_wan_scoring.score_pcnt11_to_8;
15767 	score_param->oce_wan_scoring.score_pcnt15_to_12 =
15768 			ap_profile->param.oce_wan_scoring.score_pcnt15_to_12;
15769 
15770 	WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
15771 		 score_param->oce_wan_scoring.num_slot,
15772 		 score_param->oce_wan_scoring.score_pcnt3_to_0,
15773 		 score_param->oce_wan_scoring.score_pcnt7_to_4,
15774 		 score_param->oce_wan_scoring.score_pcnt11_to_8,
15775 		 score_param->oce_wan_scoring.score_pcnt15_to_12);
15776 
15777 	wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0);
15778 	status = wmi_unified_cmd_send(wmi_handle, buf,
15779 				      len, WMI_ROAM_AP_PROFILE);
15780 	if (QDF_IS_STATUS_ERROR(status)) {
15781 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d",
15782 			status);
15783 		wmi_buf_free(buf);
15784 	}
15785 
15786 	WMI_LOGD("WMI --> WMI_ROAM_AP_PROFILE and other parameters");
15787 
15788 	return status;
15789 }
15790 
15791 /**
15792  * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period
15793  * @wmi_handle: wmi handle
15794  * @scan_period: scan period
15795  * @scan_age: scan age
15796  * @vdev_id: vdev id
15797  *
15798  * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
15799  *
15800  * Return: CDF status
15801  */
15802 static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle,
15803 					     uint32_t scan_period,
15804 					     uint32_t scan_age,
15805 					     uint32_t vdev_id)
15806 {
15807 	QDF_STATUS status;
15808 	wmi_buf_t buf = NULL;
15809 	int len;
15810 	uint8_t *buf_ptr;
15811 	wmi_roam_scan_period_fixed_param *scan_period_fp;
15812 
15813 	/* Send scan period values */
15814 	len = sizeof(wmi_roam_scan_period_fixed_param);
15815 	buf = wmi_buf_alloc(wmi_handle, len);
15816 	if (!buf) {
15817 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15818 		return QDF_STATUS_E_NOMEM;
15819 	}
15820 
15821 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15822 	scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr;
15823 	WMITLV_SET_HDR(&scan_period_fp->tlv_header,
15824 		       WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param,
15825 		       WMITLV_GET_STRUCT_TLVLEN
15826 			       (wmi_roam_scan_period_fixed_param));
15827 	/* fill in scan period values */
15828 	scan_period_fp->vdev_id = vdev_id;
15829 	scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */
15830 	scan_period_fp->roam_scan_age = scan_age;
15831 
15832 	wmi_mtrace(WMI_ROAM_SCAN_PERIOD, NO_SESSION, 0);
15833 	status = wmi_unified_cmd_send(wmi_handle, buf,
15834 				      len, WMI_ROAM_SCAN_PERIOD);
15835 	if (QDF_IS_STATUS_ERROR(status)) {
15836 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d",
15837 			status);
15838 		goto error;
15839 	}
15840 
15841 	WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d",
15842 		__func__, scan_period, scan_age);
15843 	return QDF_STATUS_SUCCESS;
15844 error:
15845 	wmi_buf_free(buf);
15846 
15847 	return status;
15848 }
15849 
15850 /**
15851  * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list
15852  * @wmi_handle: wmi handle
15853  * @chan_count: channel count
15854  * @chan_list: channel list
15855  * @list_type: list type
15856  * @vdev_id: vdev id
15857  *
15858  * Set roam offload channel list.
15859  *
15860  * Return: CDF status
15861  */
15862 static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
15863 				   uint8_t chan_count,
15864 				   uint32_t *chan_list,
15865 				   uint8_t list_type, uint32_t vdev_id)
15866 {
15867 	wmi_buf_t buf = NULL;
15868 	QDF_STATUS status;
15869 	int len, list_tlv_len;
15870 	int i;
15871 	uint8_t *buf_ptr;
15872 	wmi_roam_chan_list_fixed_param *chan_list_fp;
15873 	uint32_t *roam_chan_list_array;
15874 
15875 	if (chan_count == 0) {
15876 		WMI_LOGD("%s : invalid number of channels %d", __func__,
15877 			 chan_count);
15878 		return QDF_STATUS_E_EMPTY;
15879 	}
15880 	/* Channel list is a table of 2 TLV's */
15881 	list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t);
15882 	len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len;
15883 	buf = wmi_buf_alloc(wmi_handle, len);
15884 	if (!buf) {
15885 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15886 		return QDF_STATUS_E_NOMEM;
15887 	}
15888 
15889 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15890 	chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr;
15891 	WMITLV_SET_HDR(&chan_list_fp->tlv_header,
15892 		       WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param,
15893 		       WMITLV_GET_STRUCT_TLVLEN
15894 			       (wmi_roam_chan_list_fixed_param));
15895 	chan_list_fp->vdev_id = vdev_id;
15896 	chan_list_fp->num_chan = chan_count;
15897 	if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) {
15898 		/* external app is controlling channel list */
15899 		chan_list_fp->chan_list_type =
15900 			WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC;
15901 	} else {
15902 		/* umac supplied occupied channel list in LFR */
15903 		chan_list_fp->chan_list_type =
15904 			WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC;
15905 	}
15906 
15907 	buf_ptr += sizeof(wmi_roam_chan_list_fixed_param);
15908 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
15909 		       (chan_list_fp->num_chan * sizeof(uint32_t)));
15910 	roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
15911 	WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan);
15912 	for (i = 0; ((i < chan_list_fp->num_chan) &&
15913 		     (i < WMI_ROAM_MAX_CHANNELS)); i++) {
15914 		roam_chan_list_array[i] = chan_list[i];
15915 		WMI_LOGD("%d,", roam_chan_list_array[i]);
15916 	}
15917 
15918 	wmi_mtrace(WMI_ROAM_CHAN_LIST, NO_SESSION, 0);
15919 	status = wmi_unified_cmd_send(wmi_handle, buf,
15920 				      len, WMI_ROAM_CHAN_LIST);
15921 	if (QDF_IS_STATUS_ERROR(status)) {
15922 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d",
15923 			status);
15924 		goto error;
15925 	}
15926 
15927 	WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__);
15928 	return QDF_STATUS_SUCCESS;
15929 error:
15930 	wmi_buf_free(buf);
15931 
15932 	return status;
15933 }
15934 
15935 /**
15936  * send_per_roam_config_cmd_tlv() - set per roaming config to FW
15937  * @wmi_handle: wmi handle
15938  * @req_buf: per roam config buffer
15939  *
15940  * Return: QDF status
15941  */
15942 static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle,
15943 		struct wmi_per_roam_config_req *req_buf)
15944 {
15945 	wmi_buf_t buf = NULL;
15946 	QDF_STATUS status;
15947 	int len;
15948 	uint8_t *buf_ptr;
15949 	wmi_roam_per_config_fixed_param *wmi_per_config;
15950 
15951 	len = sizeof(wmi_roam_per_config_fixed_param);
15952 	buf = wmi_buf_alloc(wmi_handle, len);
15953 	if (!buf) {
15954 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15955 		return QDF_STATUS_E_NOMEM;
15956 	}
15957 
15958 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15959 	wmi_per_config =
15960 		(wmi_roam_per_config_fixed_param *) buf_ptr;
15961 	WMITLV_SET_HDR(&wmi_per_config->tlv_header,
15962 			WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param,
15963 			WMITLV_GET_STRUCT_TLVLEN
15964 			(wmi_roam_per_config_fixed_param));
15965 
15966 	/* fill in per roam config values */
15967 	wmi_per_config->vdev_id = req_buf->vdev_id;
15968 
15969 	wmi_per_config->enable = req_buf->per_config.enable;
15970 	wmi_per_config->high_rate_thresh =
15971 		(req_buf->per_config.tx_high_rate_thresh << 16) |
15972 		(req_buf->per_config.rx_high_rate_thresh & 0x0000ffff);
15973 	wmi_per_config->low_rate_thresh =
15974 		(req_buf->per_config.tx_low_rate_thresh << 16) |
15975 		(req_buf->per_config.rx_low_rate_thresh & 0x0000ffff);
15976 	wmi_per_config->pkt_err_rate_thresh_pct =
15977 		(req_buf->per_config.tx_rate_thresh_percnt << 16) |
15978 		(req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff);
15979 	wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time;
15980 	wmi_per_config->pkt_err_rate_mon_time =
15981 			(req_buf->per_config.tx_per_mon_time << 16) |
15982 			(req_buf->per_config.rx_per_mon_time & 0x0000ffff);
15983 	wmi_per_config->min_candidate_rssi =
15984 			req_buf->per_config.min_candidate_rssi;
15985 
15986 	/* Send per roam config parameters */
15987 	wmi_mtrace(WMI_ROAM_PER_CONFIG_CMDID, NO_SESSION, 0);
15988 	status = wmi_unified_cmd_send(wmi_handle, buf,
15989 			len, WMI_ROAM_PER_CONFIG_CMDID);
15990 	if (QDF_IS_STATUS_ERROR(status)) {
15991 		WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d",
15992 			 status);
15993 		wmi_buf_free(buf);
15994 		return status;
15995 	}
15996 	WMI_LOGD(FL("per roam enable=%d, vdev=%d"),
15997 		 req_buf->per_config.enable, req_buf->vdev_id);
15998 
15999 	return QDF_STATUS_SUCCESS;
16000 }
16001 
16002 /**
16003  * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th
16004  * @wmi_handle: wmi handle
16005  * @rssi_change_thresh: RSSI Change threshold
16006  * @bcn_rssi_weight: beacon RSSI weight
16007  * @vdev_id: vdev id
16008  *
16009  * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
16010  *
16011  * Return: CDF status
16012  */
16013 static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle,
16014 	uint32_t vdev_id,
16015 	int32_t rssi_change_thresh,
16016 	uint32_t bcn_rssi_weight,
16017 	uint32_t hirssi_delay_btw_scans)
16018 {
16019 	wmi_buf_t buf = NULL;
16020 	QDF_STATUS status;
16021 	int len;
16022 	uint8_t *buf_ptr;
16023 	wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp;
16024 
16025 	/* Send rssi change parameters */
16026 	len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param);
16027 	buf = wmi_buf_alloc(wmi_handle, len);
16028 	if (!buf) {
16029 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16030 		return QDF_STATUS_E_NOMEM;
16031 	}
16032 
16033 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16034 	rssi_change_fp =
16035 		(wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr;
16036 	WMITLV_SET_HDR(&rssi_change_fp->tlv_header,
16037 		       WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param,
16038 		       WMITLV_GET_STRUCT_TLVLEN
16039 			       (wmi_roam_scan_rssi_change_threshold_fixed_param));
16040 	/* fill in rssi change threshold (hysteresis) values */
16041 	rssi_change_fp->vdev_id = vdev_id;
16042 	rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh;
16043 	rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight;
16044 	rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans;
16045 
16046 	wmi_mtrace(WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, NO_SESSION, 0);
16047 	status = wmi_unified_cmd_send(wmi_handle, buf,
16048 				      len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD);
16049 	if (QDF_IS_STATUS_ERROR(status)) {
16050 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d",
16051 			status);
16052 		goto error;
16053 	}
16054 
16055 	WMI_LOGD(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"),
16056 		 rssi_change_thresh, bcn_rssi_weight);
16057 	WMI_LOGD(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans);
16058 	return QDF_STATUS_SUCCESS;
16059 error:
16060 	wmi_buf_free(buf);
16061 
16062 	return status;
16063 }
16064 
16065 /**
16066  * send_power_dbg_cmd_tlv() - send power debug commands
16067  * @wmi_handle: wmi handle
16068  * @param: wmi power debug parameter
16069  *
16070  * Send WMI_POWER_DEBUG_CMDID parameters to fw.
16071  *
16072  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16073  */
16074 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle,
16075 					 struct wmi_power_dbg_params *param)
16076 {
16077 	wmi_buf_t buf = NULL;
16078 	QDF_STATUS status;
16079 	int len, args_tlv_len;
16080 	uint8_t *buf_ptr;
16081 	uint8_t i;
16082 	wmi_pdev_wal_power_debug_cmd_fixed_param *cmd;
16083 	uint32_t *cmd_args;
16084 
16085 	/* Prepare and send power debug cmd parameters */
16086 	args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t);
16087 	len = sizeof(*cmd) + args_tlv_len;
16088 	buf = wmi_buf_alloc(wmi_handle, len);
16089 	if (!buf) {
16090 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16091 		return QDF_STATUS_E_NOMEM;
16092 	}
16093 
16094 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16095 	cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr;
16096 	WMITLV_SET_HDR(&cmd->tlv_header,
16097 		  WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param,
16098 		  WMITLV_GET_STRUCT_TLVLEN
16099 		  (wmi_pdev_wal_power_debug_cmd_fixed_param));
16100 
16101 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
16102 								param->pdev_id);
16103 	cmd->module_id = param->module_id;
16104 	cmd->num_args = param->num_args;
16105 	buf_ptr += sizeof(*cmd);
16106 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
16107 		       (param->num_args * sizeof(uint32_t)));
16108 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
16109 	WMI_LOGI("%s: %d num of args = ", __func__, param->num_args);
16110 	for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) {
16111 		cmd_args[i] = param->args[i];
16112 		WMI_LOGI("%d,", param->args[i]);
16113 	}
16114 
16115 	wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0);
16116 	status = wmi_unified_cmd_send(wmi_handle, buf,
16117 				      len, WMI_PDEV_WAL_POWER_DEBUG_CMDID);
16118 	if (QDF_IS_STATUS_ERROR(status)) {
16119 		WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d",
16120 			status);
16121 		goto error;
16122 	}
16123 
16124 	return QDF_STATUS_SUCCESS;
16125 error:
16126 	wmi_buf_free(buf);
16127 
16128 	return status;
16129 }
16130 
16131 /**
16132  * send_multiple_vdev_restart_req_cmd_tlv() - send multiple vdev restart req
16133  * @wmi_handle: wmi handle
16134  * @param: wmi multiple vdev restart req param
16135  *
16136  * Send WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID parameters to fw.
16137  *
16138  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16139  */
16140 static QDF_STATUS send_multiple_vdev_restart_req_cmd_tlv(
16141 				wmi_unified_t wmi_handle,
16142 				struct multiple_vdev_restart_params *param)
16143 {
16144 	wmi_buf_t buf;
16145 	QDF_STATUS qdf_status;
16146 	wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *cmd;
16147 	int i;
16148 	uint8_t *buf_ptr;
16149 	uint32_t *vdev_ids;
16150 	wmi_channel *chan_info;
16151 	struct channel_param *tchan_info;
16152 	uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
16153 
16154 	len += sizeof(wmi_channel);
16155 	if (param->num_vdevs)
16156 		len += sizeof(uint32_t) * param->num_vdevs;
16157 
16158 	buf = wmi_buf_alloc(wmi_handle, len);
16159 	if (!buf) {
16160 		WMI_LOGE("Failed to allocate memory\n");
16161 		qdf_status = QDF_STATUS_E_NOMEM;
16162 		goto end;
16163 	}
16164 
16165 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
16166 	cmd = (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *)
16167 	       buf_ptr;
16168 
16169 	WMITLV_SET_HDR(&cmd->tlv_header,
16170 	WMITLV_TAG_STRUC_wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param,
16171 	WMITLV_GET_STRUCT_TLVLEN
16172 		(wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param));
16173 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
16174 								param->pdev_id);
16175 	cmd->requestor_id = param->requestor_id;
16176 	cmd->disable_hw_ack = param->disable_hw_ack;
16177 	cmd->cac_duration_ms = param->cac_duration_ms;
16178 	cmd->num_vdevs = param->num_vdevs;
16179 
16180 	WMI_LOGI("%s:cmd->pdev_id: %d ,cmd->requestor_id: %d ,"
16181 		"cmd->disable_hw_ack: %d , cmd->cac_duration_ms:%d ,"
16182 		" cmd->num_vdevs: %d ",
16183 		__func__, cmd->pdev_id, cmd->requestor_id,
16184 		cmd->disable_hw_ack, cmd->cac_duration_ms, cmd->num_vdevs);
16185 	buf_ptr += sizeof(*cmd);
16186 
16187 	WMITLV_SET_HDR(buf_ptr,
16188 		       WMITLV_TAG_ARRAY_UINT32,
16189 		       sizeof(uint32_t) * param->num_vdevs);
16190 	vdev_ids = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
16191 	for (i = 0; i < param->num_vdevs; i++) {
16192 		vdev_ids[i] = param->vdev_ids[i];
16193 	}
16194 
16195 	buf_ptr += (sizeof(uint32_t) * param->num_vdevs) + WMI_TLV_HDR_SIZE;
16196 
16197 	WMITLV_SET_HDR(buf_ptr,
16198 		       WMITLV_TAG_STRUC_wmi_channel,
16199 		       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
16200 	chan_info = (wmi_channel *)buf_ptr;
16201 	tchan_info = &(param->ch_param);
16202 	chan_info->mhz = tchan_info->mhz;
16203 	chan_info->band_center_freq1 = tchan_info->cfreq1;
16204 	chan_info->band_center_freq2 = tchan_info->cfreq2;
16205 	if (tchan_info->is_chan_passive)
16206 		WMI_SET_CHANNEL_FLAG(chan_info,
16207 				     WMI_CHAN_FLAG_PASSIVE);
16208 	if (tchan_info->dfs_set)
16209 		WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS);
16210 
16211 	if (tchan_info->allow_vht)
16212 		WMI_SET_CHANNEL_FLAG(chan_info,
16213 				     WMI_CHAN_FLAG_ALLOW_VHT);
16214 	else  if (tchan_info->allow_ht)
16215 		WMI_SET_CHANNEL_FLAG(chan_info,
16216 				     WMI_CHAN_FLAG_ALLOW_HT);
16217 	WMI_SET_CHANNEL_MODE(chan_info, tchan_info->phy_mode);
16218 	WMI_SET_CHANNEL_MIN_POWER(chan_info, tchan_info->minpower);
16219 	WMI_SET_CHANNEL_MAX_POWER(chan_info, tchan_info->maxpower);
16220 	WMI_SET_CHANNEL_REG_POWER(chan_info, tchan_info->maxregpower);
16221 	WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, tchan_info->antennamax);
16222 	WMI_SET_CHANNEL_REG_CLASSID(chan_info, tchan_info->reg_class_id);
16223 	WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, tchan_info->maxregpower);
16224 
16225 	WMI_LOGI("%s:tchan_info->is_chan_passive: %d ,"
16226 		"tchan_info->dfs_set : %d ,tchan_info->allow_vht:%d ,"
16227 		"tchan_info->allow_ht: %d ,tchan_info->antennamax: %d ,"
16228 		"tchan_info->phy_mode: %d ,tchan_info->minpower: %d,"
16229 		"tchan_info->maxpower: %d ,tchan_info->maxregpower: %d ,"
16230 		"tchan_info->reg_class_id: %d ,"
16231 		"tchan_info->maxregpower : %d ", __func__,
16232 		tchan_info->is_chan_passive, tchan_info->dfs_set,
16233 		tchan_info->allow_vht, tchan_info->allow_ht,
16234 		tchan_info->antennamax, tchan_info->phy_mode,
16235 		tchan_info->minpower, tchan_info->maxpower,
16236 		tchan_info->maxregpower, tchan_info->reg_class_id,
16237 		tchan_info->maxregpower);
16238 
16239 	wmi_mtrace(WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID, NO_SESSION, 0);
16240 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
16241 				WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID);
16242 
16243 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
16244 		WMI_LOGE("%s: Failed to send\n", __func__);
16245 		wmi_buf_free(buf);
16246 	}
16247 
16248 end:
16249 	return qdf_status;
16250 }
16251 
16252 /**
16253  * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd
16254  * @wmi_handle: wmi handle
16255  * @pdev_id: pdev id
16256  *
16257  * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware.
16258  *
16259  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16260  */
16261 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle,
16262 		uint32_t pdev_id)
16263 {
16264 	wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd;
16265 	wmi_buf_t buf;
16266 	uint16_t len;
16267 	QDF_STATUS ret;
16268 
16269 	len = sizeof(*cmd);
16270 	buf = wmi_buf_alloc(wmi_handle, len);
16271 
16272 	WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id);
16273 
16274 	if (!buf) {
16275 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16276 		return QDF_STATUS_E_NOMEM;
16277 	}
16278 
16279 	cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *)
16280 		wmi_buf_data(buf);
16281 
16282 	WMITLV_SET_HDR(&cmd->tlv_header,
16283 	WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param,
16284 	WMITLV_GET_STRUCT_TLVLEN(
16285 		wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param));
16286 
16287 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
16288 	wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0);
16289 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
16290 			WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID);
16291 	if (QDF_IS_STATUS_ERROR(ret)) {
16292 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d",
16293 			__func__, ret, pdev_id);
16294 		wmi_buf_free(buf);
16295 		return QDF_STATUS_E_FAILURE;
16296 	}
16297 
16298 	return QDF_STATUS_SUCCESS;
16299 }
16300 
16301 /**
16302  * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd
16303  * @wmi_handle: wmi handle
16304  * @pdev_id: pdev id
16305  *
16306  * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware.
16307  *
16308  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16309  */
16310 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle,
16311 		uint32_t pdev_id)
16312 {
16313 	wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd;
16314 	wmi_buf_t buf;
16315 	uint16_t len;
16316 	QDF_STATUS ret;
16317 
16318 	len = sizeof(*cmd);
16319 	buf = wmi_buf_alloc(wmi_handle, len);
16320 
16321 	WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id);
16322 
16323 	if (!buf) {
16324 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16325 		return QDF_STATUS_E_NOMEM;
16326 	}
16327 
16328 	cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *)
16329 		wmi_buf_data(buf);
16330 
16331 	WMITLV_SET_HDR(&cmd->tlv_header,
16332 	WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param,
16333 	WMITLV_GET_STRUCT_TLVLEN(
16334 		wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param));
16335 
16336 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
16337 	wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0);
16338 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
16339 			WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID);
16340 	if (QDF_IS_STATUS_ERROR(ret)) {
16341 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d",
16342 			__func__, ret, pdev_id);
16343 		wmi_buf_free(buf);
16344 		return QDF_STATUS_E_FAILURE;
16345 	}
16346 
16347 	return QDF_STATUS_SUCCESS;
16348 }
16349 
16350 /**
16351  * init_cmd_send_tlv() - send initialization cmd to fw
16352  * @wmi_handle: wmi handle
16353  * @param param: pointer to wmi init param
16354  *
16355  * Return: QDF_STATUS_SUCCESS for success or error code
16356  */
16357 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle,
16358 				struct wmi_init_cmd_param *param)
16359 {
16360 	wmi_buf_t buf;
16361 	wmi_init_cmd_fixed_param *cmd;
16362 	uint8_t *buf_ptr;
16363 	wmi_resource_config *resource_cfg;
16364 	wlan_host_memory_chunk *host_mem_chunks;
16365 	uint32_t mem_chunk_len = 0, hw_mode_len = 0;
16366 	uint16_t idx;
16367 	int len;
16368 	QDF_STATUS ret;
16369 
16370 	len = sizeof(*cmd) + sizeof(wmi_resource_config) +
16371 		WMI_TLV_HDR_SIZE;
16372 	mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS);
16373 
16374 	if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX)
16375 		hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) +
16376 			WMI_TLV_HDR_SIZE +
16377 			(param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac));
16378 
16379 	buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len);
16380 	if (!buf) {
16381 		qdf_print("%s: wmi_buf_alloc failed", __func__);
16382 		return QDF_STATUS_E_FAILURE;
16383 	}
16384 
16385 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16386 	cmd = (wmi_init_cmd_fixed_param *) buf_ptr;
16387 	resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd));
16388 
16389 	host_mem_chunks = (wlan_host_memory_chunk *)
16390 		(buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)
16391 		 + WMI_TLV_HDR_SIZE);
16392 
16393 	WMITLV_SET_HDR(&cmd->tlv_header,
16394 			WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param,
16395 			WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param));
16396 
16397 	wmi_copy_resource_config(resource_cfg, param->res_cfg);
16398 	WMITLV_SET_HDR(&resource_cfg->tlv_header,
16399 			WMITLV_TAG_STRUC_wmi_resource_config,
16400 			WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config));
16401 
16402 	for (idx = 0; idx < param->num_mem_chunks; ++idx) {
16403 		WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header),
16404 				WMITLV_TAG_STRUC_wlan_host_memory_chunk,
16405 				WMITLV_GET_STRUCT_TLVLEN
16406 				(wlan_host_memory_chunk));
16407 		host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr;
16408 		host_mem_chunks[idx].size = param->mem_chunks[idx].len;
16409 		host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id;
16410 		QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG,
16411 				"chunk %d len %d requested ,ptr  0x%x ",
16412 				idx, host_mem_chunks[idx].size,
16413 				host_mem_chunks[idx].ptr);
16414 	}
16415 	cmd->num_host_mem_chunks = param->num_mem_chunks;
16416 	len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk));
16417 
16418 	WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)),
16419 			WMITLV_TAG_ARRAY_STRUC,
16420 			(sizeof(wlan_host_memory_chunk) *
16421 			 param->num_mem_chunks));
16422 
16423 	/* Fill hw mode id config */
16424 	buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param);
16425 
16426 	/* Fill fw_abi_vers */
16427 	copy_fw_abi_version_tlv(wmi_handle, cmd);
16428 
16429 	wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0);
16430 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID);
16431 	if (QDF_IS_STATUS_ERROR(ret)) {
16432 		WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d",
16433 			ret);
16434 		wmi_buf_free(buf);
16435 	}
16436 
16437 	return ret;
16438 
16439 }
16440 
16441 /**
16442  * send_addba_send_cmd_tlv() - send addba send command to fw
16443  * @wmi_handle: wmi handle
16444  * @param: pointer to delba send params
16445  * @macaddr: peer mac address
16446  *
16447  * Send WMI_ADDBA_SEND_CMDID command to firmware
16448  * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error
16449  */
16450 static QDF_STATUS
16451 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle,
16452 				uint8_t macaddr[IEEE80211_ADDR_LEN],
16453 				struct addba_send_params *param)
16454 {
16455 	wmi_addba_send_cmd_fixed_param *cmd;
16456 	wmi_buf_t buf;
16457 	uint16_t len;
16458 	QDF_STATUS ret;
16459 
16460 	len = sizeof(*cmd);
16461 
16462 	buf = wmi_buf_alloc(wmi_handle, len);
16463 	if (!buf) {
16464 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16465 		return QDF_STATUS_E_NOMEM;
16466 	}
16467 
16468 	cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf);
16469 
16470 	WMITLV_SET_HDR(&cmd->tlv_header,
16471 			WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param,
16472 			WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param));
16473 
16474 	cmd->vdev_id = param->vdev_id;
16475 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
16476 	cmd->tid = param->tidno;
16477 	cmd->buffersize = param->buffersize;
16478 
16479 	wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0);
16480 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID);
16481 	if (QDF_IS_STATUS_ERROR(ret)) {
16482 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret);
16483 		wmi_buf_free(buf);
16484 		return QDF_STATUS_E_FAILURE;
16485 	}
16486 
16487 	return QDF_STATUS_SUCCESS;
16488 }
16489 
16490 /**
16491  * send_delba_send_cmd_tlv() - send delba send command to fw
16492  * @wmi_handle: wmi handle
16493  * @param: pointer to delba send params
16494  * @macaddr: peer mac address
16495  *
16496  * Send WMI_DELBA_SEND_CMDID command to firmware
16497  * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error
16498  */
16499 static QDF_STATUS
16500 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle,
16501 				uint8_t macaddr[IEEE80211_ADDR_LEN],
16502 				struct delba_send_params *param)
16503 {
16504 	wmi_delba_send_cmd_fixed_param *cmd;
16505 	wmi_buf_t buf;
16506 	uint16_t len;
16507 	QDF_STATUS ret;
16508 
16509 	len = sizeof(*cmd);
16510 
16511 	buf = wmi_buf_alloc(wmi_handle, len);
16512 	if (!buf) {
16513 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16514 		return QDF_STATUS_E_NOMEM;
16515 	}
16516 
16517 	cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf);
16518 
16519 	WMITLV_SET_HDR(&cmd->tlv_header,
16520 			WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param,
16521 			WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param));
16522 
16523 	cmd->vdev_id = param->vdev_id;
16524 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
16525 	cmd->tid = param->tidno;
16526 	cmd->initiator = param->initiator;
16527 	cmd->reasoncode = param->reasoncode;
16528 
16529 	wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0);
16530 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID);
16531 	if (QDF_IS_STATUS_ERROR(ret)) {
16532 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret);
16533 		wmi_buf_free(buf);
16534 		return QDF_STATUS_E_FAILURE;
16535 	}
16536 
16537 	return QDF_STATUS_SUCCESS;
16538 }
16539 
16540 /**
16541  * send_addba_clearresponse_cmd_tlv() - send addba clear response command
16542  * to fw
16543  * @wmi_handle: wmi handle
16544  * @param: pointer to addba clearresp params
16545  * @macaddr: peer mac address
16546  * Return: 0 for success or error code
16547  */
16548 static QDF_STATUS
16549 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle,
16550 			uint8_t macaddr[IEEE80211_ADDR_LEN],
16551 			struct addba_clearresponse_params *param)
16552 {
16553 	wmi_addba_clear_resp_cmd_fixed_param *cmd;
16554 	wmi_buf_t buf;
16555 	uint16_t len;
16556 	QDF_STATUS ret;
16557 
16558 	len = sizeof(*cmd);
16559 
16560 	buf = wmi_buf_alloc(wmi_handle, len);
16561 	if (!buf) {
16562 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
16563 		return QDF_STATUS_E_FAILURE;
16564 	}
16565 	cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf);
16566 
16567 	WMITLV_SET_HDR(&cmd->tlv_header,
16568 		WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param,
16569 		WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param));
16570 
16571 	cmd->vdev_id = param->vdev_id;
16572 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
16573 
16574 	wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0);
16575 	ret = wmi_unified_cmd_send(wmi_handle,
16576 				buf, len, WMI_ADDBA_CLEAR_RESP_CMDID);
16577 	if (QDF_IS_STATUS_ERROR(ret)) {
16578 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret);
16579 		wmi_buf_free(buf);
16580 		return QDF_STATUS_E_FAILURE;
16581 	}
16582 
16583 	return QDF_STATUS_SUCCESS;
16584 }
16585 
16586 /**
16587  * send_bcn_offload_control_cmd_tlv - send beacon ofload control cmd to fw
16588  * @wmi_handle: wmi handle
16589  * @bcn_ctrl_param: pointer to bcn_offload_control param
16590  *
16591  * Return: QDF_STATUS_SUCCESS for success or error code
16592  */
16593 static
16594 QDF_STATUS send_bcn_offload_control_cmd_tlv(wmi_unified_t wmi_handle,
16595 			struct bcn_offload_control *bcn_ctrl_param)
16596 {
16597 	wmi_buf_t buf;
16598 	wmi_bcn_offload_ctrl_cmd_fixed_param *cmd;
16599 	QDF_STATUS ret;
16600 	uint32_t len;
16601 
16602 	len = sizeof(*cmd);
16603 
16604 	buf = wmi_buf_alloc(wmi_handle, len);
16605 	if (!buf) {
16606 		qdf_print("%s: wmi_buf_alloc failed", __func__);
16607 		return QDF_STATUS_E_FAILURE;
16608 	}
16609 
16610 	cmd = (wmi_bcn_offload_ctrl_cmd_fixed_param *) wmi_buf_data(buf);
16611 	WMITLV_SET_HDR(&cmd->tlv_header,
16612 			WMITLV_TAG_STRUC_wmi_bcn_offload_ctrl_cmd_fixed_param,
16613 			WMITLV_GET_STRUCT_TLVLEN
16614 			(wmi_bcn_offload_ctrl_cmd_fixed_param));
16615 	cmd->vdev_id = bcn_ctrl_param->vdev_id;
16616 	switch (bcn_ctrl_param->bcn_ctrl_op) {
16617 	case BCN_OFFLD_CTRL_TX_DISABLE:
16618 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_DISABLE;
16619 		break;
16620 	case BCN_OFFLD_CTRL_TX_ENABLE:
16621 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_ENABLE;
16622 		break;
16623 	case BCN_OFFLD_CTRL_SWBA_DISABLE:
16624 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_DISABLE;
16625 		break;
16626 	case BCN_OFFLD_CTRL_SWBA_ENABLE:
16627 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_ENABLE;
16628 		break;
16629 	default:
16630 		WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID unknown CTRL Operation %d",
16631 			bcn_ctrl_param->bcn_ctrl_op);
16632 		wmi_buf_free(buf);
16633 		return QDF_STATUS_E_FAILURE;
16634 		break;
16635 	}
16636 	wmi_mtrace(WMI_BCN_OFFLOAD_CTRL_CMDID, cmd->vdev_id, 0);
16637 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
16638 			WMI_BCN_OFFLOAD_CTRL_CMDID);
16639 
16640 	if (QDF_IS_STATUS_ERROR(ret)) {
16641 		WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID send returned Error %d",
16642 				ret);
16643 		wmi_buf_free(buf);
16644 	}
16645 
16646 	return ret;
16647 }
16648 
16649 #ifdef WLAN_FEATURE_NAN_CONVERGENCE
16650 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle,
16651 				struct nan_datapath_initiator_req *ndp_req)
16652 {
16653 	uint16_t len;
16654 	wmi_buf_t buf;
16655 	uint8_t *tlv_ptr;
16656 	QDF_STATUS status;
16657 	wmi_channel *ch_tlv;
16658 	wmi_ndp_initiator_req_fixed_param *cmd;
16659 	uint32_t passphrase_len, service_name_len;
16660 	uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len;
16661 	wmi_ndp_transport_ip_param *tcp_ip_param;
16662 
16663 	/*
16664 	 * WMI command expects 4 byte alligned len:
16665 	 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes
16666 	 */
16667 	ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4);
16668 	ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4);
16669 	pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4);
16670 	passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4);
16671 	service_name_len =
16672 		   qdf_roundup(ndp_req->service_name.service_name_len, 4);
16673 	/* allocated memory for fixed params as well as variable size data */
16674 	len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE)
16675 		+ ndp_cfg_len + ndp_app_info_len + pmk_len
16676 		+ passphrase_len + service_name_len;
16677 
16678 	if (ndp_req->is_ipv6_addr_present)
16679 		len += sizeof(*tcp_ip_param);
16680 
16681 	buf = wmi_buf_alloc(wmi_handle, len);
16682 	if (!buf) {
16683 		WMI_LOGE("wmi_buf_alloc failed");
16684 		return QDF_STATUS_E_NOMEM;
16685 	}
16686 
16687 	cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf);
16688 	WMITLV_SET_HDR(&cmd->tlv_header,
16689 		       WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param,
16690 		       WMITLV_GET_STRUCT_TLVLEN(
16691 				wmi_ndp_initiator_req_fixed_param));
16692 	cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev);
16693 	cmd->transaction_id = ndp_req->transaction_id;
16694 	cmd->service_instance_id = ndp_req->service_instance_id;
16695 	WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes,
16696 				   &cmd->peer_discovery_mac_addr);
16697 
16698 	cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len;
16699 	cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len;
16700 	cmd->ndp_channel_cfg = ndp_req->channel_cfg;
16701 	cmd->nan_pmk_len = ndp_req->pmk.pmk_len;
16702 	cmd->nan_csid = ndp_req->ncs_sk_type;
16703 	cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len;
16704 	cmd->nan_servicename_len = ndp_req->service_name.service_name_len;
16705 
16706 	ch_tlv = (wmi_channel *)&cmd[1];
16707 	WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel,
16708 			WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
16709 	ch_tlv->mhz = ndp_req->channel;
16710 	tlv_ptr = (uint8_t *)&ch_tlv[1];
16711 
16712 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len);
16713 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16714 		     ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len);
16715 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len;
16716 
16717 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len);
16718 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16719 		     ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len);
16720 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len;
16721 
16722 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len);
16723 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk,
16724 		     cmd->nan_pmk_len);
16725 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len;
16726 
16727 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len);
16728 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase,
16729 		     cmd->nan_passphrase_len);
16730 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len;
16731 
16732 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len);
16733 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16734 		     ndp_req->service_name.service_name,
16735 		     cmd->nan_servicename_len);
16736 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len;
16737 
16738 	if (ndp_req->is_ipv6_addr_present) {
16739 		tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr;
16740 		WMITLV_SET_HDR(tcp_ip_param,
16741 			       WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param,
16742 			       WMITLV_GET_STRUCT_TLVLEN(
16743 						wmi_ndp_transport_ip_param));
16744 		tcp_ip_param->ipv6_addr_present = true;
16745 		qdf_mem_copy(tcp_ip_param->ipv6_intf_addr,
16746 			     ndp_req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN);
16747 	}
16748 	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
16749 		 ndp_req->is_ipv6_addr_present, ndp_req->ipv6_addr);
16750 
16751 	WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d",
16752 		 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id,
16753 		 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid);
16754 	WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x",
16755 		 cmd->peer_discovery_mac_addr.mac_addr31to0,
16756 		 cmd->peer_discovery_mac_addr.mac_addr47to32);
16757 
16758 	WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len);
16759 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16760 			   ndp_req->ndp_config.ndp_cfg,
16761 			   ndp_req->ndp_config.ndp_cfg_len);
16762 
16763 	WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len);
16764 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16765 			   ndp_req->ndp_info.ndp_app_info,
16766 			   ndp_req->ndp_info.ndp_app_info_len);
16767 
16768 	WMI_LOGD("pmk len: %d", cmd->nan_pmk_len);
16769 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16770 			   ndp_req->pmk.pmk, cmd->nan_pmk_len);
16771 
16772 	WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len);
16773 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16774 			   ndp_req->passphrase.passphrase,
16775 			   cmd->nan_passphrase_len);
16776 
16777 	WMI_LOGD("service name len: %d", cmd->nan_servicename_len);
16778 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16779 			   ndp_req->service_name.service_name,
16780 			   cmd->nan_servicename_len);
16781 
16782 	WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)",
16783 		 WMI_NDP_INITIATOR_REQ_CMDID);
16784 
16785 	wmi_mtrace(WMI_NDP_INITIATOR_REQ_CMDID, cmd->vdev_id, 0);
16786 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
16787 				      WMI_NDP_INITIATOR_REQ_CMDID);
16788 	if (QDF_IS_STATUS_ERROR(status)) {
16789 		WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status);
16790 		wmi_buf_free(buf);
16791 	}
16792 
16793 	return status;
16794 }
16795 
16796 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle,
16797 					struct nan_datapath_responder_req *req)
16798 {
16799 	uint16_t len;
16800 	wmi_buf_t buf;
16801 	uint8_t *tlv_ptr;
16802 	QDF_STATUS status;
16803 	wmi_ndp_responder_req_fixed_param *cmd;
16804 	wmi_ndp_transport_ip_param *tcp_ip_param;
16805 	uint32_t passphrase_len, service_name_len;
16806 	uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len;
16807 
16808 	vdev_id = wlan_vdev_get_id(req->vdev);
16809 	WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d",
16810 		 vdev_id, req->transaction_id,
16811 		 req->ndp_rsp,
16812 		 req->ndp_instance_id,
16813 		 req->ndp_info.ndp_app_info_len);
16814 
16815 	/*
16816 	 * WMI command expects 4 byte alligned len:
16817 	 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes
16818 	 */
16819 	ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4);
16820 	ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4);
16821 	pmk_len = qdf_roundup(req->pmk.pmk_len, 4);
16822 	passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4);
16823 	service_name_len =
16824 		qdf_roundup(req->service_name.service_name_len, 4);
16825 
16826 	/* allocated memory for fixed params as well as variable size data */
16827 	len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len
16828 		+ pmk_len + passphrase_len + service_name_len;
16829 
16830 	if (req->is_ipv6_addr_present || req->is_port_present ||
16831 	    req->is_protocol_present)
16832 		len += sizeof(*tcp_ip_param);
16833 
16834 	buf = wmi_buf_alloc(wmi_handle, len);
16835 	if (!buf) {
16836 		WMI_LOGE("wmi_buf_alloc failed");
16837 		return QDF_STATUS_E_NOMEM;
16838 	}
16839 	cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf);
16840 	WMITLV_SET_HDR(&cmd->tlv_header,
16841 		       WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param,
16842 		       WMITLV_GET_STRUCT_TLVLEN(
16843 				wmi_ndp_responder_req_fixed_param));
16844 	cmd->vdev_id = vdev_id;
16845 	cmd->transaction_id = req->transaction_id;
16846 	cmd->ndp_instance_id = req->ndp_instance_id;
16847 	cmd->rsp_code = req->ndp_rsp;
16848 	cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len;
16849 	cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len;
16850 	cmd->nan_pmk_len = req->pmk.pmk_len;
16851 	cmd->nan_csid = req->ncs_sk_type;
16852 	cmd->nan_passphrase_len = req->passphrase.passphrase_len;
16853 	cmd->nan_servicename_len = req->service_name.service_name_len;
16854 
16855 	tlv_ptr = (uint8_t *)&cmd[1];
16856 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len);
16857 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16858 		     req->ndp_config.ndp_cfg, cmd->ndp_cfg_len);
16859 
16860 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len;
16861 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len);
16862 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16863 		     req->ndp_info.ndp_app_info,
16864 		     req->ndp_info.ndp_app_info_len);
16865 
16866 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len;
16867 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len);
16868 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk,
16869 		     cmd->nan_pmk_len);
16870 
16871 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len;
16872 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len);
16873 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16874 		     req->passphrase.passphrase,
16875 		     cmd->nan_passphrase_len);
16876 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len;
16877 
16878 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len);
16879 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
16880 		     req->service_name.service_name,
16881 		     cmd->nan_servicename_len);
16882 
16883 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len;
16884 
16885 	if (req->is_ipv6_addr_present || req->is_port_present ||
16886 	    req->is_protocol_present) {
16887 		tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr;
16888 		WMITLV_SET_HDR(tcp_ip_param,
16889 			       WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param,
16890 			       WMITLV_GET_STRUCT_TLVLEN(
16891 						wmi_ndp_transport_ip_param));
16892 		tcp_ip_param->ipv6_addr_present = req->is_ipv6_addr_present;
16893 		qdf_mem_copy(tcp_ip_param->ipv6_intf_addr,
16894 			     req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN);
16895 
16896 		tcp_ip_param->trans_port_present = req->is_port_present;
16897 		tcp_ip_param->transport_port = req->port;
16898 
16899 		tcp_ip_param->trans_proto_present = req->is_protocol_present;
16900 		tcp_ip_param->transport_protocol = req->protocol;
16901 	}
16902 	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
16903 		 req->is_ipv6_addr_present, req->ipv6_addr);
16904 	WMI_LOGD(FL("port: %d present: %d"), req->is_port_present, req->port);
16905 	WMI_LOGD(FL("protocol: %d present: %d"),
16906 		 req->is_protocol_present, req->protocol);
16907 
16908 	WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d",
16909 		 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid);
16910 
16911 	WMI_LOGD("ndp_config len: %d",
16912 		 req->ndp_config.ndp_cfg_len);
16913 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16914 			req->ndp_config.ndp_cfg,
16915 			req->ndp_config.ndp_cfg_len);
16916 
16917 	WMI_LOGD("ndp_app_info len: %d",
16918 		 req->ndp_info.ndp_app_info_len);
16919 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16920 			   req->ndp_info.ndp_app_info,
16921 			   req->ndp_info.ndp_app_info_len);
16922 
16923 	WMI_LOGD("pmk len: %d", cmd->nan_pmk_len);
16924 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16925 			   req->pmk.pmk, cmd->nan_pmk_len);
16926 
16927 	WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len);
16928 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16929 			   req->passphrase.passphrase,
16930 			   cmd->nan_passphrase_len);
16931 
16932 	WMI_LOGD("service name len: %d", cmd->nan_servicename_len);
16933 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
16934 			   req->service_name.service_name,
16935 			   cmd->nan_servicename_len);
16936 
16937 	WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)",
16938 		 WMI_NDP_RESPONDER_REQ_CMDID);
16939 	wmi_mtrace(WMI_NDP_RESPONDER_REQ_CMDID, cmd->vdev_id, 0);
16940 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
16941 				      WMI_NDP_RESPONDER_REQ_CMDID);
16942 	if (QDF_IS_STATUS_ERROR(status)) {
16943 		WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status);
16944 		wmi_buf_free(buf);
16945 	}
16946 	return status;
16947 }
16948 
16949 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle,
16950 				      struct nan_datapath_end_req *req)
16951 {
16952 	uint16_t len;
16953 	wmi_buf_t buf;
16954 	QDF_STATUS status;
16955 	uint32_t ndp_end_req_len, i;
16956 	wmi_ndp_end_req *ndp_end_req_lst;
16957 	wmi_ndp_end_req_fixed_param *cmd;
16958 
16959 	/* len of tlv following fixed param  */
16960 	ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances;
16961 	/* above comes out to 4 byte alligned already, no need of padding */
16962 	len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE;
16963 	buf = wmi_buf_alloc(wmi_handle, len);
16964 	if (!buf) {
16965 		WMI_LOGE("Malloc failed");
16966 		return QDF_STATUS_E_NOMEM;
16967 	}
16968 
16969 	cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf);
16970 	WMITLV_SET_HDR(&cmd->tlv_header,
16971 		       WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param,
16972 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param));
16973 
16974 	cmd->transaction_id = req->transaction_id;
16975 
16976 	/* set tlv pointer to end of fixed param */
16977 	WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC,
16978 			ndp_end_req_len);
16979 
16980 	ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] +
16981 						WMI_TLV_HDR_SIZE);
16982 	for (i = 0; i < req->num_ndp_instances; i++) {
16983 		WMITLV_SET_HDR(&ndp_end_req_lst[i],
16984 				WMITLV_TAG_ARRAY_FIXED_STRUC,
16985 				(sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE));
16986 
16987 		ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i];
16988 	}
16989 
16990 	WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW");
16991 	wmi_mtrace(WMI_NDP_END_REQ_CMDID, NO_SESSION, 0);
16992 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
16993 				   WMI_NDP_END_REQ_CMDID);
16994 	if (QDF_IS_STATUS_ERROR(status)) {
16995 		WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status);
16996 		wmi_buf_free(buf);
16997 	}
16998 
16999 	return status;
17000 }
17001 
17002 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle,
17003 			uint8_t *data, struct nan_datapath_initiator_rsp *rsp)
17004 {
17005 	WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event;
17006 	wmi_ndp_initiator_rsp_event_fixed_param  *fixed_params;
17007 
17008 	event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data;
17009 	fixed_params = event->fixed_param;
17010 
17011 	rsp->vdev =
17012 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17013 						     fixed_params->vdev_id,
17014 						     WLAN_NAN_ID);
17015 	if (!rsp->vdev) {
17016 		WMI_LOGE("vdev is null");
17017 		return QDF_STATUS_E_INVAL;
17018 	}
17019 
17020 	rsp->transaction_id = fixed_params->transaction_id;
17021 	rsp->ndp_instance_id = fixed_params->ndp_instance_id;
17022 	rsp->status = fixed_params->rsp_status;
17023 	rsp->reason = fixed_params->reason_code;
17024 
17025 	return QDF_STATUS_SUCCESS;
17026 }
17027 
17028 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle,
17029 		uint8_t *data, struct nan_datapath_indication_event *rsp)
17030 {
17031 	WMI_NDP_INDICATION_EVENTID_param_tlvs *event;
17032 	wmi_ndp_indication_event_fixed_param *fixed_params;
17033 	size_t total_array_len;
17034 
17035 	event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data;
17036 	fixed_params =
17037 		(wmi_ndp_indication_event_fixed_param *)event->fixed_param;
17038 
17039 	if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) {
17040 		WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d",
17041 			 fixed_params->ndp_cfg_len, event->num_ndp_cfg);
17042 		return QDF_STATUS_E_INVAL;
17043 	}
17044 
17045 	if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) {
17046 		WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d",
17047 			 fixed_params->ndp_app_info_len,
17048 			 event->num_ndp_app_info);
17049 		return QDF_STATUS_E_INVAL;
17050 	}
17051 
17052 	if (fixed_params->ndp_cfg_len >
17053 		(WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) {
17054 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17055 			 __func__, fixed_params->ndp_cfg_len);
17056 		return QDF_STATUS_E_INVAL;
17057 	}
17058 
17059 	total_array_len = fixed_params->ndp_cfg_len +
17060 					sizeof(*fixed_params);
17061 
17062 	if (fixed_params->ndp_app_info_len >
17063 		(WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
17064 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17065 			 __func__, fixed_params->ndp_app_info_len);
17066 		return QDF_STATUS_E_INVAL;
17067 	}
17068 	total_array_len += fixed_params->ndp_app_info_len;
17069 
17070 	if (fixed_params->nan_scid_len >
17071 		(WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
17072 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17073 			 __func__, fixed_params->nan_scid_len);
17074 		return QDF_STATUS_E_INVAL;
17075 	}
17076 
17077 	rsp->vdev =
17078 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17079 						     fixed_params->vdev_id,
17080 						     WLAN_NAN_ID);
17081 	if (!rsp->vdev) {
17082 		WMI_LOGE("vdev is null");
17083 		return QDF_STATUS_E_INVAL;
17084 	}
17085 	rsp->service_instance_id = fixed_params->service_instance_id;
17086 	rsp->ndp_instance_id = fixed_params->ndp_instance_id;
17087 	rsp->role = fixed_params->self_ndp_role;
17088 	rsp->policy = fixed_params->accept_policy;
17089 
17090 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
17091 				rsp->peer_mac_addr.bytes);
17092 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr,
17093 				rsp->peer_discovery_mac_addr.bytes);
17094 
17095 	WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n"
17096 		"service_instance %d, ndp_instance %d, role %d, policy %d,\n"
17097 		"csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM",
17098 		 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id,
17099 		 fixed_params->service_instance_id,
17100 		 fixed_params->ndp_instance_id, fixed_params->self_ndp_role,
17101 		 fixed_params->accept_policy,
17102 		 fixed_params->nan_csid, fixed_params->nan_scid_len,
17103 		 rsp->peer_mac_addr.bytes,
17104 		 rsp->peer_discovery_mac_addr.bytes);
17105 
17106 	WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len);
17107 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17108 			   &event->ndp_cfg, fixed_params->ndp_cfg_len);
17109 
17110 	WMI_LOGD("ndp_app_info - %d bytes",
17111 			fixed_params->ndp_app_info_len);
17112 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17113 			&event->ndp_app_info, fixed_params->ndp_app_info_len);
17114 
17115 	rsp->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len;
17116 	rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len;
17117 	rsp->ncs_sk_type = fixed_params->nan_csid;
17118 	rsp->scid.scid_len = fixed_params->nan_scid_len;
17119 
17120 	if (rsp->ndp_config.ndp_cfg_len > NDP_QOS_INFO_LEN)
17121 		rsp->ndp_config.ndp_cfg_len = NDP_QOS_INFO_LEN;
17122 	qdf_mem_copy(rsp->ndp_config.ndp_cfg, event->ndp_cfg,
17123 		     rsp->ndp_config.ndp_cfg_len);
17124 
17125 	if (rsp->ndp_info.ndp_app_info_len > NDP_APP_INFO_LEN)
17126 		rsp->ndp_info.ndp_app_info_len = NDP_APP_INFO_LEN;
17127 	qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info,
17128 		     rsp->ndp_info.ndp_app_info_len);
17129 
17130 	if (rsp->scid.scid_len > NDP_SCID_BUF_LEN)
17131 		rsp->scid.scid_len = NDP_SCID_BUF_LEN;
17132 	qdf_mem_copy(rsp->scid.scid, event->ndp_scid, rsp->scid.scid_len);
17133 
17134 	if (event->ndp_transport_ip_param &&
17135 	    event->num_ndp_transport_ip_param) {
17136 		if (event->ndp_transport_ip_param->ipv6_addr_present) {
17137 			rsp->is_ipv6_addr_present = true;
17138 			qdf_mem_copy(rsp->ipv6_addr,
17139 				event->ndp_transport_ip_param->ipv6_intf_addr,
17140 				WMI_NDP_IPV6_INTF_ADDR_LEN);
17141 		}
17142 	}
17143 	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
17144 		 rsp->is_ipv6_addr_present, rsp->ipv6_addr);
17145 
17146 	WMI_LOGD("scid hex dump:");
17147 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17148 			   rsp->scid.scid, rsp->scid.scid_len);
17149 
17150 	return QDF_STATUS_SUCCESS;
17151 }
17152 
17153 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle,
17154 			uint8_t *data, struct nan_datapath_confirm_event *rsp)
17155 {
17156 	uint8_t i;
17157 	WMI_HOST_WLAN_PHY_MODE ch_mode;
17158 	WMI_NDP_CONFIRM_EVENTID_param_tlvs *event;
17159 	wmi_ndp_confirm_event_fixed_param *fixed_params;
17160 	size_t total_array_len;
17161 
17162 	event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data;
17163 	fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param;
17164 	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",
17165 		 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id,
17166 		 fixed_params->ndp_instance_id, fixed_params->rsp_code,
17167 		 fixed_params->reason_code,
17168 		 fixed_params->num_active_ndps_on_peer);
17169 	WMI_LOGE("num_ch: %d", fixed_params->num_ndp_channels);
17170 
17171 	if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) {
17172 		WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d",
17173 			 fixed_params->ndp_cfg_len, event->num_ndp_cfg);
17174 		return QDF_STATUS_E_INVAL;
17175 	}
17176 
17177 	WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len);
17178 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17179 		&event->ndp_cfg, fixed_params->ndp_cfg_len);
17180 
17181 	if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) {
17182 		WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d",
17183 			 fixed_params->ndp_app_info_len,
17184 			 event->num_ndp_app_info);
17185 		return QDF_STATUS_E_INVAL;
17186 	}
17187 
17188 	WMI_LOGD("ndp_app_info - %d bytes",
17189 			fixed_params->ndp_app_info_len);
17190 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
17191 		&event->ndp_app_info, fixed_params->ndp_app_info_len);
17192 
17193 	if (fixed_params->ndp_cfg_len >
17194 			(WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) {
17195 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17196 			 __func__, fixed_params->ndp_cfg_len);
17197 		return QDF_STATUS_E_INVAL;
17198 	}
17199 
17200 	total_array_len = fixed_params->ndp_cfg_len +
17201 				sizeof(*fixed_params);
17202 
17203 	if (fixed_params->ndp_app_info_len >
17204 		(WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
17205 		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
17206 			 __func__, fixed_params->ndp_app_info_len);
17207 		return QDF_STATUS_E_INVAL;
17208 	}
17209 
17210 	rsp->vdev =
17211 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17212 						     fixed_params->vdev_id,
17213 						     WLAN_NAN_ID);
17214 	if (!rsp->vdev) {
17215 		WMI_LOGE("vdev is null");
17216 		return QDF_STATUS_E_INVAL;
17217 	}
17218 	rsp->ndp_instance_id = fixed_params->ndp_instance_id;
17219 	rsp->rsp_code = fixed_params->rsp_code;
17220 	rsp->reason_code = fixed_params->reason_code;
17221 	rsp->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer;
17222 	rsp->num_channels = fixed_params->num_ndp_channels;
17223 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
17224 				   rsp->peer_ndi_mac_addr.bytes);
17225 	rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len;
17226 	qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info,
17227 		     rsp->ndp_info.ndp_app_info_len);
17228 
17229 	if (rsp->num_channels > NAN_CH_INFO_MAX_CHANNELS) {
17230 		WMI_LOGE(FL("too many channels"));
17231 		rsp->num_channels = NAN_CH_INFO_MAX_CHANNELS;
17232 	}
17233 
17234 	for (i = 0; i < rsp->num_channels; i++) {
17235 		rsp->ch[i].channel = event->ndp_channel_list[i].mhz;
17236 		rsp->ch[i].nss = event->nss_list[i];
17237 		ch_mode = WMI_GET_CHANNEL_MODE(&event->ndp_channel_list[i]);
17238 		rsp->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle,
17239 								     ch_mode);
17240 		WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"),
17241 			 rsp->ch[i].channel,
17242 			 rsp->ch[i].ch_width,
17243 			 rsp->ch[i].nss);
17244 	}
17245 
17246 	if (event->ndp_transport_ip_param &&
17247 	    event->num_ndp_transport_ip_param) {
17248 		if (event->ndp_transport_ip_param->ipv6_addr_present) {
17249 			rsp->is_ipv6_addr_present = true;
17250 			qdf_mem_copy(rsp->ipv6_addr,
17251 				event->ndp_transport_ip_param->ipv6_intf_addr,
17252 				WMI_NDP_IPV6_INTF_ADDR_LEN);
17253 		}
17254 
17255 		if (event->ndp_transport_ip_param->trans_port_present) {
17256 			rsp->is_port_present = true;
17257 			rsp->port =
17258 			    event->ndp_transport_ip_param->transport_port;
17259 		}
17260 
17261 		if (event->ndp_transport_ip_param->trans_proto_present) {
17262 			rsp->is_protocol_present = true;
17263 			rsp->protocol =
17264 			    event->ndp_transport_ip_param->transport_protocol;
17265 		}
17266 	}
17267 	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
17268 		 rsp->is_ipv6_addr_present, rsp->ipv6_addr);
17269 	WMI_LOGD(FL("port: %d present: %d"), rsp->port, rsp->is_port_present);
17270 	WMI_LOGD(FL("protocol: %d present: %d"),
17271 		 rsp->protocol, rsp->is_protocol_present);
17272 
17273 	return QDF_STATUS_SUCCESS;
17274 }
17275 
17276 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle,
17277 			uint8_t *data, struct nan_datapath_responder_rsp *rsp)
17278 {
17279 	WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event;
17280 	wmi_ndp_responder_rsp_event_fixed_param  *fixed_params;
17281 
17282 	event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data;
17283 	fixed_params = event->fixed_param;
17284 
17285 	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",
17286 		 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id,
17287 		 rsp->peer_mac_addr.bytes, rsp->transaction_id,
17288 		 rsp->status, rsp->reason, rsp->create_peer);
17289 
17290 	rsp->vdev =
17291 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17292 						     fixed_params->vdev_id,
17293 						     WLAN_NAN_ID);
17294 	if (!rsp->vdev) {
17295 		WMI_LOGE("vdev is null");
17296 		return QDF_STATUS_E_INVAL;
17297 	}
17298 	rsp->transaction_id = fixed_params->transaction_id;
17299 	rsp->reason = fixed_params->reason_code;
17300 	rsp->status = fixed_params->rsp_status;
17301 	rsp->create_peer = fixed_params->create_peer;
17302 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
17303 				rsp->peer_mac_addr.bytes);
17304 
17305 	return QDF_STATUS_SUCCESS;
17306 }
17307 
17308 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle,
17309 			uint8_t *data, struct nan_datapath_end_rsp_event *rsp)
17310 {
17311 	WMI_NDP_END_RSP_EVENTID_param_tlvs *event;
17312 	wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL;
17313 
17314 	event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data;
17315 	fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param;
17316 	WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) received. transaction_id: %d, rsp_status: %d, reason_code: %d",
17317 		 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id,
17318 		 fixed_params->rsp_status, fixed_params->reason_code);
17319 
17320 	rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
17321 			wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID);
17322 	if (!rsp->vdev) {
17323 		WMI_LOGE("vdev is null");
17324 		return QDF_STATUS_E_INVAL;
17325 	}
17326 	rsp->transaction_id = fixed_params->transaction_id;
17327 	rsp->reason = fixed_params->reason_code;
17328 	rsp->status = fixed_params->rsp_status;
17329 
17330 	return QDF_STATUS_SUCCESS;
17331 }
17332 
17333 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle,
17334 		uint8_t *data, struct nan_datapath_end_indication_event **rsp)
17335 {
17336 	uint32_t i, buf_size;
17337 	wmi_ndp_end_indication *ind;
17338 	struct qdf_mac_addr peer_addr;
17339 	WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event;
17340 
17341 	event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data;
17342 	ind = event->ndp_end_indication_list;
17343 
17344 	if (event->num_ndp_end_indication_list == 0) {
17345 		WMI_LOGE("Error: Event ignored, 0 ndp instances");
17346 		return QDF_STATUS_E_INVAL;
17347 	}
17348 
17349 	WMI_LOGD("number of ndp instances = %d",
17350 		 event->num_ndp_end_indication_list);
17351 
17352 	if (event->num_ndp_end_indication_list > ((UINT_MAX - sizeof(**rsp))/
17353 						sizeof((*rsp)->ndp_map[0]))) {
17354 		WMI_LOGE("num_ndp_end_ind_list %d too large",
17355 			 event->num_ndp_end_indication_list);
17356 		return QDF_STATUS_E_INVAL;
17357 	}
17358 
17359 	buf_size = sizeof(**rsp) + event->num_ndp_end_indication_list *
17360 			sizeof((*rsp)->ndp_map[0]);
17361 	*rsp = qdf_mem_malloc(buf_size);
17362 	if (!(*rsp)) {
17363 		WMI_LOGE("Failed to allocate memory");
17364 		return QDF_STATUS_E_NOMEM;
17365 	}
17366 
17367 	(*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
17368 			wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID);
17369 	if (!(*rsp)->vdev) {
17370 		WMI_LOGE("vdev is null");
17371 		qdf_mem_free(*rsp);
17372 		*rsp = NULL;
17373 		return QDF_STATUS_E_INVAL;
17374 	}
17375 
17376 	(*rsp)->num_ndp_ids = event->num_ndp_end_indication_list;
17377 	for (i = 0; i < (*rsp)->num_ndp_ids; i++) {
17378 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr,
17379 					   peer_addr.bytes);
17380 		WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ",
17381 			 i, ind[i].type, ind[i].reason_code,
17382 			 ind[i].ndp_instance_id,
17383 			 ind[i].num_active_ndps_on_peer);
17384 		/* Add each instance entry to the list */
17385 		(*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id;
17386 		(*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id;
17387 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr,
17388 			(*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes);
17389 		(*rsp)->ndp_map[i].num_active_ndp_sessions =
17390 			ind[i].num_active_ndps_on_peer;
17391 		(*rsp)->ndp_map[i].type = ind[i].type;
17392 		(*rsp)->ndp_map[i].reason_code = ind[i].reason_code;
17393 	}
17394 
17395 	return QDF_STATUS_SUCCESS;
17396 }
17397 
17398 static QDF_STATUS extract_ndp_sch_update_tlv(wmi_unified_t wmi_handle,
17399 		uint8_t *data, struct nan_datapath_sch_update_event *ind)
17400 {
17401 	uint8_t i;
17402 	WMI_HOST_WLAN_PHY_MODE ch_mode;
17403 	WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *event;
17404 	wmi_ndl_schedule_update_fixed_param *fixed_params;
17405 
17406 	event = (WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *)data;
17407 	fixed_params = event->fixed_param;
17408 
17409 	WMI_LOGD(FL("flags: %d, num_ch: %d, num_ndp_instances: %d"),
17410 		 fixed_params->flags, fixed_params->num_channels,
17411 		 fixed_params->num_ndp_instances);
17412 
17413 	ind->vdev =
17414 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17415 						     fixed_params->vdev_id,
17416 						     WLAN_NAN_ID);
17417 	if (!ind->vdev) {
17418 		WMI_LOGE("vdev is null");
17419 		return QDF_STATUS_E_INVAL;
17420 	}
17421 
17422 	ind->flags = fixed_params->flags;
17423 	ind->num_channels = fixed_params->num_channels;
17424 	ind->num_ndp_instances = fixed_params->num_ndp_instances;
17425 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_macaddr,
17426 				   ind->peer_addr.bytes);
17427 
17428 	if (ind->num_ndp_instances > NDP_NUM_INSTANCE_ID) {
17429 		WMI_LOGE(FL("uint32 overflow"));
17430 		wlan_objmgr_vdev_release_ref(ind->vdev, WLAN_NAN_ID);
17431 		return QDF_STATUS_E_INVAL;
17432 	}
17433 
17434 	qdf_mem_copy(ind->ndp_instances, event->ndp_instance_list,
17435 		     sizeof(uint32_t) * ind->num_ndp_instances);
17436 
17437 	if (ind->num_channels > NAN_CH_INFO_MAX_CHANNELS) {
17438 		WMI_LOGE(FL("too many channels"));
17439 		ind->num_channels = NAN_CH_INFO_MAX_CHANNELS;
17440 	}
17441 	for (i = 0; i < ind->num_channels; i++) {
17442 		ind->ch[i].channel = event->ndl_channel_list[i].mhz;
17443 		ind->ch[i].nss = event->nss_list[i];
17444 		ch_mode = WMI_GET_CHANNEL_MODE(&event->ndl_channel_list[i]);
17445 		ind->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle,
17446 								     ch_mode);
17447 		WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"),
17448 			 ind->ch[i].channel,
17449 			 ind->ch[i].ch_width,
17450 			 ind->ch[i].nss);
17451 	}
17452 
17453 	for (i = 0; i < fixed_params->num_ndp_instances; i++)
17454 		WMI_LOGD(FL("instance_id[%d]: %d"),
17455 			 i, event->ndp_instance_list[i]);
17456 
17457 	return QDF_STATUS_SUCCESS;
17458 }
17459 
17460 #endif
17461 
17462 #ifdef QCA_SUPPORT_CP_STATS
17463 /**
17464  * extract_cca_stats_tlv - api to extract congestion stats from event buffer
17465  * @wmi_handle: wma handle
17466  * @evt_buf: event buffer
17467  * @out_buff: buffer to populated after stats extraction
17468  *
17469  * Return: status of operation
17470  */
17471 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle,
17472 		void *evt_buf, struct wmi_host_congestion_stats *out_buff)
17473 {
17474 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
17475 	wmi_congestion_stats *congestion_stats;
17476 
17477 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf;
17478 	congestion_stats = param_buf->congestion_stats;
17479 	if (!congestion_stats) {
17480 		WMI_LOGD("%s: no cca stats in event buffer", __func__);
17481 		return QDF_STATUS_E_INVAL;
17482 	}
17483 
17484 	out_buff->vdev_id = congestion_stats->vdev_id;
17485 	out_buff->congestion = congestion_stats->congestion;
17486 
17487 	WMI_LOGD("%s: cca stats event processed", __func__);
17488 	return QDF_STATUS_SUCCESS;
17489 }
17490 #endif /* QCA_SUPPORT_CP_STATS */
17491 
17492 /**
17493  * save_service_bitmap_tlv() - save service bitmap
17494  * @wmi_handle: wmi handle
17495  * @param evt_buf: pointer to event buffer
17496  * @param bitmap_buf: bitmap buffer, for converged legacy support
17497  *
17498  * Return: QDF_STATUS
17499  */
17500 static
17501 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
17502 			     void *bitmap_buf)
17503 {
17504 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17505 	struct wmi_soc *soc = wmi_handle->soc;
17506 
17507 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17508 
17509 	/* If it is already allocated, use that buffer. This can happen
17510 	 * during target stop/start scenarios where host allocation is skipped.
17511 	 */
17512 	if (!soc->wmi_service_bitmap) {
17513 		soc->wmi_service_bitmap =
17514 			qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t));
17515 		if (!soc->wmi_service_bitmap) {
17516 			WMI_LOGE("Failed memory allocation for service bitmap");
17517 			return QDF_STATUS_E_NOMEM;
17518 		}
17519 	}
17520 
17521 	qdf_mem_copy(soc->wmi_service_bitmap,
17522 			param_buf->wmi_service_bitmap,
17523 			(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
17524 
17525 	if (bitmap_buf)
17526 		qdf_mem_copy(bitmap_buf,
17527 			     param_buf->wmi_service_bitmap,
17528 			     (WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
17529 
17530 	return QDF_STATUS_SUCCESS;
17531 }
17532 
17533 /**
17534  * save_ext_service_bitmap_tlv() - save extendend service bitmap
17535  * @wmi_handle: wmi handle
17536  * @param evt_buf: pointer to event buffer
17537  * @param bitmap_buf: bitmap buffer, for converged legacy support
17538  *
17539  * Return: QDF_STATUS
17540  */
17541 static
17542 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
17543 			     void *bitmap_buf)
17544 {
17545 	WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf;
17546 	wmi_service_available_event_fixed_param *ev;
17547 	struct wmi_soc *soc = wmi_handle->soc;
17548 
17549 	param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf;
17550 
17551 	ev = param_buf->fixed_param;
17552 
17553 	/* If it is already allocated, use that buffer. This can happen
17554 	 * during target stop/start scenarios where host allocation is skipped.
17555 	 */
17556 	if (!soc->wmi_ext_service_bitmap) {
17557 		soc->wmi_ext_service_bitmap = qdf_mem_malloc(
17558 			WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t));
17559 		if (!soc->wmi_ext_service_bitmap) {
17560 			WMI_LOGE("Failed memory allocation for service bitmap");
17561 			return QDF_STATUS_E_NOMEM;
17562 		}
17563 	}
17564 
17565 	qdf_mem_copy(soc->wmi_ext_service_bitmap,
17566 			ev->wmi_service_segment_bitmap,
17567 			(WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)));
17568 
17569 	WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n",
17570 			soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1],
17571 			soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]);
17572 
17573 	if (bitmap_buf)
17574 		qdf_mem_copy(bitmap_buf,
17575 			soc->wmi_ext_service_bitmap,
17576 			(WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)));
17577 
17578 	return QDF_STATUS_SUCCESS;
17579 }
17580 /**
17581  * is_service_enabled_tlv() - Check if service enabled
17582  * @param wmi_handle: wmi handle
17583  * @param service_id: service identifier
17584  *
17585  * Return: 1 enabled, 0 disabled
17586  */
17587 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle,
17588 		uint32_t service_id)
17589 {
17590 	struct wmi_soc *soc = wmi_handle->soc;
17591 
17592 	if (!soc->wmi_service_bitmap) {
17593 		WMI_LOGE("WMI service bit map is not saved yet\n");
17594 		return false;
17595 	}
17596 
17597 	/* if wmi_service_enabled was received with extended bitmap,
17598 	 * use WMI_SERVICE_EXT_IS_ENABLED to check the services.
17599 	 */
17600 	if (soc->wmi_ext_service_bitmap)
17601 		return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap,
17602 				soc->wmi_ext_service_bitmap,
17603 				service_id);
17604 
17605 	if (service_id >= WMI_MAX_SERVICE) {
17606 		WMI_LOGE("Service id %d but WMI ext service bitmap is NULL",
17607 			 service_id);
17608 		return false;
17609 	}
17610 
17611 	return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap,
17612 				service_id);
17613 }
17614 
17615 static inline void copy_ht_cap_info(uint32_t ev_target_cap,
17616 		struct wlan_psoc_target_capability_info *cap)
17617 {
17618        /* except LDPC all flags are common betwen legacy and here
17619 	*  also IBFEER is not defined for TLV
17620 	*/
17621 	cap->ht_cap_info |= ev_target_cap & (
17622 					WMI_HT_CAP_ENABLED
17623 					| WMI_HT_CAP_HT20_SGI
17624 					| WMI_HT_CAP_DYNAMIC_SMPS
17625 					| WMI_HT_CAP_TX_STBC
17626 					| WMI_HT_CAP_TX_STBC_MASK_SHIFT
17627 					| WMI_HT_CAP_RX_STBC
17628 					| WMI_HT_CAP_RX_STBC_MASK_SHIFT
17629 					| WMI_HT_CAP_LDPC
17630 					| WMI_HT_CAP_L_SIG_TXOP_PROT
17631 					| WMI_HT_CAP_MPDU_DENSITY
17632 					| WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT
17633 					| WMI_HT_CAP_HT40_SGI);
17634 	if (ev_target_cap & WMI_HT_CAP_LDPC)
17635 		cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC |
17636 			WMI_HOST_HT_CAP_TX_LDPC;
17637 }
17638 /**
17639  * extract_service_ready_tlv() - extract service ready event
17640  * @wmi_handle: wmi handle
17641  * @param evt_buf: pointer to received event buffer
17642  * @param cap: pointer to hold target capability information extracted from even
17643  *
17644  * Return: QDF_STATUS_SUCCESS for success or error code
17645  */
17646 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle,
17647 		void *evt_buf, struct wlan_psoc_target_capability_info *cap)
17648 {
17649 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17650 	wmi_service_ready_event_fixed_param *ev;
17651 
17652 
17653 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17654 
17655 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
17656 	if (!ev) {
17657 		qdf_print("%s: wmi_buf_alloc failed", __func__);
17658 		return QDF_STATUS_E_FAILURE;
17659 	}
17660 
17661 	cap->phy_capability = ev->phy_capability;
17662 	cap->max_frag_entry = ev->max_frag_entry;
17663 	cap->num_rf_chains = ev->num_rf_chains;
17664 	copy_ht_cap_info(ev->ht_cap_info, cap);
17665 	cap->vht_cap_info = ev->vht_cap_info;
17666 	cap->vht_supp_mcs = ev->vht_supp_mcs;
17667 	cap->hw_min_tx_power = ev->hw_min_tx_power;
17668 	cap->hw_max_tx_power = ev->hw_max_tx_power;
17669 	cap->sys_cap_info = ev->sys_cap_info;
17670 	cap->min_pkt_size_enable = ev->min_pkt_size_enable;
17671 	cap->max_bcn_ie_size = ev->max_bcn_ie_size;
17672 	cap->max_num_scan_channels = ev->max_num_scan_channels;
17673 	cap->max_supported_macs = ev->max_supported_macs;
17674 	cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps;
17675 	cap->txrx_chainmask = ev->txrx_chainmask;
17676 	cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index;
17677 	cap->num_msdu_desc = ev->num_msdu_desc;
17678 	cap->fw_version = ev->fw_build_vers;
17679 	/* fw_version_1 is not available in TLV. */
17680 	cap->fw_version_1 = 0;
17681 
17682 	return QDF_STATUS_SUCCESS;
17683 }
17684 
17685 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target
17686  *         to host internal WMI_HOST_REGDMN_MODE values.
17687  *         REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the
17688  *         host currently. Add this in the future if required.
17689  *         11AX (Phase II) : 11ax related values are not currently
17690  *         advertised separately by FW. As part of phase II regulatory bring-up,
17691  *         finalize the advertisement mechanism.
17692  * @target_wireless_mode: target wireless mode received in message
17693  *
17694  * Return: returns the host internal wireless mode.
17695  */
17696 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode)
17697 {
17698 
17699 	uint32_t wireless_modes = 0;
17700 
17701 	if (target_wireless_mode & REGDMN_MODE_11A)
17702 		wireless_modes |= WMI_HOST_REGDMN_MODE_11A;
17703 
17704 	if (target_wireless_mode & REGDMN_MODE_TURBO)
17705 		wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO;
17706 
17707 	if (target_wireless_mode & REGDMN_MODE_11B)
17708 		wireless_modes |= WMI_HOST_REGDMN_MODE_11B;
17709 
17710 	if (target_wireless_mode & REGDMN_MODE_PUREG)
17711 		wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG;
17712 
17713 	if (target_wireless_mode & REGDMN_MODE_11G)
17714 		wireless_modes |= WMI_HOST_REGDMN_MODE_11G;
17715 
17716 	if (target_wireless_mode & REGDMN_MODE_108G)
17717 		wireless_modes |= WMI_HOST_REGDMN_MODE_108G;
17718 
17719 	if (target_wireless_mode & REGDMN_MODE_108A)
17720 		wireless_modes |= WMI_HOST_REGDMN_MODE_108A;
17721 
17722 	if (target_wireless_mode & REGDMN_MODE_XR)
17723 		wireless_modes |= WMI_HOST_REGDMN_MODE_XR;
17724 
17725 	if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE)
17726 		wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE;
17727 
17728 	if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE)
17729 		wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE;
17730 
17731 	if (target_wireless_mode & REGDMN_MODE_11NG_HT20)
17732 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20;
17733 
17734 	if (target_wireless_mode & REGDMN_MODE_11NA_HT20)
17735 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20;
17736 
17737 	if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS)
17738 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS;
17739 
17740 	if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS)
17741 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS;
17742 
17743 	if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS)
17744 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS;
17745 
17746 	if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS)
17747 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS;
17748 
17749 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT20)
17750 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20;
17751 
17752 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS)
17753 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS;
17754 
17755 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS)
17756 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS;
17757 
17758 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT80)
17759 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80;
17760 
17761 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT160)
17762 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160;
17763 
17764 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80)
17765 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80;
17766 
17767 	return wireless_modes;
17768 }
17769 
17770 /**
17771  * extract_hal_reg_cap_tlv() - extract HAL registered capabilities
17772  * @wmi_handle: wmi handle
17773  * @param evt_buf: Pointer to event buffer
17774  * @param cap: pointer to hold HAL reg capabilities
17775  *
17776  * Return: QDF_STATUS_SUCCESS for success or error code
17777  */
17778 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle,
17779 	void *evt_buf, struct wlan_psoc_hal_reg_capability *cap)
17780 {
17781 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17782 
17783 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17784 
17785 	qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) +
17786 		sizeof(uint32_t)),
17787 		sizeof(struct wlan_psoc_hal_reg_capability));
17788 
17789 	cap->wireless_modes = convert_wireless_modes_tlv(
17790 			param_buf->hal_reg_capabilities->wireless_modes);
17791 
17792 	return QDF_STATUS_SUCCESS;
17793 }
17794 
17795 /**
17796  * extract_host_mem_req_tlv() - Extract host memory request event
17797  * @wmi_handle: wmi handle
17798  * @param evt_buf: pointer to event buffer
17799  * @param num_entries: pointer to hold number of entries requested
17800  *
17801  * Return: Number of entries requested
17802  */
17803 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle,
17804 		void *evt_buf, uint8_t *num_entries)
17805 {
17806 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17807 	wmi_service_ready_event_fixed_param *ev;
17808 
17809 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17810 
17811 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
17812 	if (!ev) {
17813 		qdf_print("%s: wmi_buf_alloc failed", __func__);
17814 		return NULL;
17815 	}
17816 
17817 	*num_entries = ev->num_mem_reqs;
17818 
17819 	return (host_mem_req *)param_buf->mem_reqs;
17820 }
17821 
17822 /**
17823  * save_fw_version_in_service_ready_tlv() - Save fw version in service
17824  * ready function
17825  * @wmi_handle: wmi handle
17826  * @param evt_buf: pointer to event buffer
17827  *
17828  * Return: QDF_STATUS_SUCCESS for success or error code
17829  */
17830 static QDF_STATUS
17831 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf)
17832 {
17833 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17834 	wmi_service_ready_event_fixed_param *ev;
17835 
17836 
17837 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17838 
17839 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
17840 	if (!ev) {
17841 		qdf_print("%s: wmi_buf_alloc failed", __func__);
17842 		return QDF_STATUS_E_FAILURE;
17843 	}
17844 
17845 	/*Save fw version from service ready message */
17846 	/*This will be used while sending INIT message */
17847 	qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
17848 			sizeof(wmi_handle->fw_abi_version));
17849 
17850 	return QDF_STATUS_SUCCESS;
17851 }
17852 
17853 /**
17854  * ready_extract_init_status_tlv() - Extract init status from ready event
17855  * @wmi_handle: wmi handle
17856  * @param evt_buf: Pointer to event buffer
17857  *
17858  * Return: ready status
17859  */
17860 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle,
17861 	void *evt_buf)
17862 {
17863 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
17864 	wmi_ready_event_fixed_param *ev = NULL;
17865 
17866 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
17867 	ev = param_buf->fixed_param;
17868 
17869 	qdf_print("%s:%d", __func__, ev->status);
17870 
17871 	return ev->status;
17872 }
17873 
17874 /**
17875  * ready_extract_mac_addr_tlv() - extract mac address from ready event
17876  * @wmi_handle: wmi handle
17877  * @param evt_buf: pointer to event buffer
17878  * @param macaddr: Pointer to hold MAC address
17879  *
17880  * Return: QDF_STATUS_SUCCESS for success or error code
17881  */
17882 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle,
17883 	void *evt_buf, uint8_t *macaddr)
17884 {
17885 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
17886 	wmi_ready_event_fixed_param *ev = NULL;
17887 
17888 
17889 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
17890 	ev = param_buf->fixed_param;
17891 
17892 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr);
17893 
17894 	return QDF_STATUS_SUCCESS;
17895 }
17896 
17897 /**
17898  * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event
17899  * @wmi_handle: wmi handle
17900  * @param evt_buf: pointer to event buffer
17901  * @param macaddr: Pointer to hold number of MAC addresses
17902  *
17903  * Return: Pointer to addr list
17904  */
17905 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle,
17906 	void *evt_buf, uint8_t *num_mac)
17907 {
17908 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
17909 	wmi_ready_event_fixed_param *ev = NULL;
17910 
17911 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
17912 	ev = param_buf->fixed_param;
17913 
17914 	*num_mac = ev->num_extra_mac_addr;
17915 
17916 	return (wmi_host_mac_addr *) param_buf->mac_addr_list;
17917 }
17918 
17919 /**
17920  * extract_ready_params_tlv() - Extract data from ready event apart from
17921  *                     status, macaddr and version.
17922  * @wmi_handle: Pointer to WMI handle.
17923  * @evt_buf: Pointer to Ready event buffer.
17924  * @ev_param: Pointer to host defined struct to copy the data from event.
17925  *
17926  * Return: QDF_STATUS_SUCCESS on success.
17927  */
17928 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle,
17929 		void *evt_buf, struct wmi_host_ready_ev_param *ev_param)
17930 {
17931 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
17932 	wmi_ready_event_fixed_param *ev = NULL;
17933 
17934 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
17935 	ev = param_buf->fixed_param;
17936 
17937 	ev_param->status = ev->status;
17938 	ev_param->num_dscp_table = ev->num_dscp_table;
17939 	ev_param->num_extra_mac_addr = ev->num_extra_mac_addr;
17940 	ev_param->num_total_peer = ev->num_total_peers;
17941 	ev_param->num_extra_peer = ev->num_extra_peers;
17942 	/* Agile_cap in ready event is not supported in TLV target */
17943 	ev_param->agile_capability = false;
17944 
17945 	return QDF_STATUS_SUCCESS;
17946 }
17947 
17948 /**
17949  * extract_dbglog_data_len_tlv() - extract debuglog data length
17950  * @wmi_handle: wmi handle
17951  * @param evt_buf: pointer to event buffer
17952  *
17953  * Return: length
17954  */
17955 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle,
17956 	void *evt_buf, uint32_t *len)
17957 {
17958 	 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf;
17959 
17960 	 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf;
17961 
17962 	 *len = param_buf->num_bufp;
17963 
17964 	 return param_buf->bufp;
17965 }
17966 
17967 /**
17968  * extract_vdev_start_resp_tlv() - extract vdev start response
17969  * @wmi_handle: wmi handle
17970  * @param evt_buf: pointer to event buffer
17971  * @param vdev_rsp: Pointer to hold vdev response
17972  *
17973  * Return: QDF_STATUS_SUCCESS for success or error code
17974  */
17975 static QDF_STATUS extract_vdev_start_resp_tlv(wmi_unified_t wmi_handle,
17976 	void *evt_buf, wmi_host_vdev_start_resp *vdev_rsp)
17977 {
17978 	WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf;
17979 	wmi_vdev_start_response_event_fixed_param *ev;
17980 
17981 	param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) evt_buf;
17982 	if (!param_buf) {
17983 		qdf_print("Invalid start response event buffer");
17984 		return QDF_STATUS_E_INVAL;
17985 	}
17986 
17987 	ev = param_buf->fixed_param;
17988 	if (!ev) {
17989 		qdf_print("Invalid start response event buffer");
17990 		return QDF_STATUS_E_INVAL;
17991 	}
17992 
17993 	qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp));
17994 
17995 	vdev_rsp->vdev_id = ev->vdev_id;
17996 	vdev_rsp->requestor_id = ev->requestor_id;
17997 	switch (ev->resp_type) {
17998 	case WMI_VDEV_START_RESP_EVENT:
17999 		vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT;
18000 		break;
18001 	case WMI_VDEV_RESTART_RESP_EVENT:
18002 		vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT;
18003 		break;
18004 	default:
18005 		qdf_print("Invalid start response event buffer");
18006 		break;
18007 	};
18008 	vdev_rsp->status = ev->status;
18009 	vdev_rsp->chain_mask = ev->chain_mask;
18010 	vdev_rsp->smps_mode = ev->smps_mode;
18011 	vdev_rsp->mac_id = ev->mac_id;
18012 	vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams;
18013 	vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams;
18014 
18015 	return QDF_STATUS_SUCCESS;
18016 }
18017 
18018 /**
18019  * extract_vdev_delete_resp_tlv() - extract vdev delete response
18020  * @wmi_handle: wmi handle
18021  * @param evt_buf: pointer to event buffer
18022  * @param delete_rsp: Pointer to hold vdev delete response
18023  *
18024  * Return: QDF_STATUS_SUCCESS for success or error code
18025  */
18026 static QDF_STATUS extract_vdev_delete_resp_tlv(wmi_unified_t wmi_handle,
18027 	void *evt_buf, struct wmi_host_vdev_delete_resp *delete_rsp)
18028 {
18029 	WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf;
18030 	wmi_vdev_delete_resp_event_fixed_param *ev;
18031 
18032 	param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *) evt_buf;
18033 	if (!param_buf) {
18034 		WMI_LOGE("Invalid vdev delete response event buffer\n");
18035 		return QDF_STATUS_E_INVAL;
18036 	}
18037 
18038 	ev = param_buf->fixed_param;
18039 	if (!ev) {
18040 		WMI_LOGE("Invalid vdev delete response event\n");
18041 		return QDF_STATUS_E_INVAL;
18042 	}
18043 
18044 	qdf_mem_zero(delete_rsp, sizeof(*delete_rsp));
18045 	delete_rsp->vdev_id = ev->vdev_id;
18046 
18047 	return QDF_STATUS_SUCCESS;
18048 }
18049 
18050 
18051 /**
18052  * extract_tbttoffset_num_vdevs_tlv() - extract tbtt offset num vdev
18053  * @wmi_handle: wmi handle
18054  * @param evt_buf: pointer to event buffer
18055  * @param num_vdevs: Pointer to hold num vdev
18056  *
18057  * Return: QDF_STATUS_SUCCESS for success or error code
18058  */
18059 static QDF_STATUS extract_tbttoffset_num_vdevs_tlv(void *wmi_hdl,
18060 	void *evt_buf, uint32_t *num_vdevs)
18061 {
18062 	WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
18063 	wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
18064 	uint32_t vdev_map;
18065 
18066 	param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf;
18067 	if (!param_buf) {
18068 		qdf_print("Invalid tbtt update ext event buffer");
18069 		return QDF_STATUS_E_INVAL;
18070 	}
18071 	tbtt_offset_event = param_buf->fixed_param;
18072 	vdev_map = tbtt_offset_event->vdev_map;
18073 	*num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map);
18074 
18075 	return QDF_STATUS_SUCCESS;
18076 }
18077 
18078 /**
18079  * extract_ext_tbttoffset_num_vdevs_tlv() - extract ext tbtt offset num vdev
18080  * @wmi_handle: wmi handle
18081  * @param evt_buf: pointer to event buffer
18082  * @param num_vdevs: Pointer to hold num vdev
18083  *
18084  * Return: QDF_STATUS_SUCCESS for success or error code
18085  */
18086 static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(void *wmi_hdl,
18087 	void *evt_buf, uint32_t *num_vdevs)
18088 {
18089 	WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf;
18090 	wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event;
18091 
18092 	param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf;
18093 	if (!param_buf) {
18094 		qdf_print("Invalid tbtt update ext event buffer");
18095 		return QDF_STATUS_E_INVAL;
18096 	}
18097 	tbtt_offset_ext_event = param_buf->fixed_param;
18098 
18099 	*num_vdevs = tbtt_offset_ext_event->num_vdevs;
18100 
18101 	return QDF_STATUS_SUCCESS;
18102 }
18103 
18104 /**
18105  * extract_tbttoffset_update_params_tlv() - extract tbtt offset param
18106  * @wmi_handle: wmi handle
18107  * @param evt_buf: pointer to event buffer
18108  * @param idx: Index referring to a vdev
18109  * @param tbtt_param: Pointer to tbttoffset event param
18110  *
18111  * Return: QDF_STATUS_SUCCESS for success or error code
18112  */
18113 static QDF_STATUS extract_tbttoffset_update_params_tlv(void *wmi_hdl,
18114 	void *evt_buf, uint8_t idx,
18115 	struct tbttoffset_params *tbtt_param)
18116 {
18117 	WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
18118 	wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
18119 	uint32_t vdev_map;
18120 
18121 	param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) evt_buf;
18122 	if (!param_buf) {
18123 		qdf_print("Invalid tbtt update event buffer");
18124 		return QDF_STATUS_E_INVAL;
18125 	}
18126 
18127 	tbtt_offset_event = param_buf->fixed_param;
18128 	vdev_map = tbtt_offset_event->vdev_map;
18129 	tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx);
18130 	if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID)
18131 		return QDF_STATUS_E_INVAL;
18132 	tbtt_param->tbttoffset =
18133 		param_buf->tbttoffset_list[tbtt_param->vdev_id];
18134 
18135 	return QDF_STATUS_SUCCESS;
18136 }
18137 
18138 /**
18139  * extract_ext_tbttoffset_update_params_tlv() - extract ext tbtt offset param
18140  * @wmi_handle: wmi handle
18141  * @param evt_buf: pointer to event buffer
18142  * @param idx: Index referring to a vdev
18143  * @param tbtt_param: Pointer to tbttoffset event param
18144  *
18145  * Return: QDF_STATUS_SUCCESS for success or error code
18146  */
18147 static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(void *wmi_hdl,
18148 	void *evt_buf, uint8_t idx,
18149 	struct tbttoffset_params *tbtt_param)
18150 {
18151 	WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf;
18152 	wmi_tbtt_offset_info *tbtt_offset_info;
18153 
18154 	param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf;
18155 	if (!param_buf) {
18156 		qdf_print("Invalid tbtt update event buffer");
18157 		return QDF_STATUS_E_INVAL;
18158 	}
18159 	tbtt_offset_info = &param_buf->tbtt_offset_info[idx];
18160 
18161 	tbtt_param->vdev_id = tbtt_offset_info->vdev_id;
18162 	tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset;
18163 
18164 	return QDF_STATUS_SUCCESS;
18165 }
18166 
18167 #ifdef CONFIG_MCL
18168 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \
18169 			((_status) & WMI_RXERR_DECRYPT)
18170 #else
18171 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false
18172 #endif
18173 
18174 /**
18175  * extract_mgmt_rx_params_tlv() - extract management rx params from event
18176  * @wmi_handle: wmi handle
18177  * @param evt_buf: pointer to event buffer
18178  * @param hdr: Pointer to hold header
18179  * @param bufp: Pointer to hold pointer to rx param buffer
18180  *
18181  * Return: QDF_STATUS_SUCCESS for success or error code
18182  */
18183 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle,
18184 	void *evt_buf, struct mgmt_rx_event_params *hdr,
18185 	uint8_t **bufp)
18186 {
18187 	WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL;
18188 	wmi_mgmt_rx_hdr *ev_hdr = NULL;
18189 	int i;
18190 
18191 	param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf;
18192 	if (!param_tlvs) {
18193 		WMI_LOGE("Get NULL point message from FW");
18194 		return QDF_STATUS_E_INVAL;
18195 	}
18196 
18197 	ev_hdr = param_tlvs->hdr;
18198 	if (!hdr) {
18199 		WMI_LOGE("Rx event is NULL");
18200 		return QDF_STATUS_E_INVAL;
18201 	}
18202 
18203 	if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) {
18204 		WMI_LOGE("%s: RX mgmt frame decrypt error, discard it",
18205 			 __func__);
18206 		return QDF_STATUS_E_INVAL;
18207 	}
18208 
18209 	hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18210 							ev_hdr->pdev_id);
18211 
18212 	hdr->channel = ev_hdr->channel;
18213 	hdr->snr = ev_hdr->snr;
18214 	hdr->rate = ev_hdr->rate;
18215 	hdr->phy_mode = ev_hdr->phy_mode;
18216 	hdr->buf_len = ev_hdr->buf_len;
18217 	hdr->status = ev_hdr->status;
18218 	hdr->flags = ev_hdr->flags;
18219 	hdr->rssi = ev_hdr->rssi;
18220 	hdr->tsf_delta = ev_hdr->tsf_delta;
18221 	for (i = 0; i < ATH_MAX_ANTENNA; i++)
18222 		hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i];
18223 
18224 	*bufp = param_tlvs->bufp;
18225 
18226 	return QDF_STATUS_SUCCESS;
18227 }
18228 
18229 /**
18230  * extract_vdev_stopped_param_tlv() - extract vdev stop param from event
18231  * @wmi_handle: wmi handle
18232  * @param evt_buf: pointer to event buffer
18233  * @param vdev_id: Pointer to hold vdev identifier
18234  *
18235  * Return: QDF_STATUS_SUCCESS for success or error code
18236  */
18237 static QDF_STATUS extract_vdev_stopped_param_tlv(wmi_unified_t wmi_handle,
18238 	void *evt_buf, uint32_t *vdev_id)
18239 {
18240 	WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf;
18241 	wmi_vdev_stopped_event_fixed_param *resp_event;
18242 
18243 	param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) evt_buf;
18244 	if (!param_buf) {
18245 		WMI_LOGE("Invalid event buffer");
18246 		return QDF_STATUS_E_INVAL;
18247 	}
18248 	resp_event = param_buf->fixed_param;
18249 	*vdev_id = resp_event->vdev_id;
18250 
18251 	return QDF_STATUS_SUCCESS;
18252 }
18253 
18254 /**
18255  * extract_vdev_roam_param_tlv() - extract vdev roam param from event
18256  * @wmi_handle: wmi handle
18257  * @param evt_buf: pointer to event buffer
18258  * @param param: Pointer to hold roam param
18259  *
18260  * Return: QDF_STATUS_SUCCESS for success or error code
18261  */
18262 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle,
18263 	void *evt_buf, wmi_host_roam_event *param)
18264 {
18265 	WMI_ROAM_EVENTID_param_tlvs *param_buf;
18266 	wmi_roam_event_fixed_param *evt;
18267 
18268 	param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf;
18269 	if (!param_buf) {
18270 		WMI_LOGE("Invalid roam event buffer");
18271 		return QDF_STATUS_E_INVAL;
18272 	}
18273 
18274 	evt = param_buf->fixed_param;
18275 	qdf_mem_zero(param, sizeof(*param));
18276 
18277 	param->vdev_id = evt->vdev_id;
18278 	param->reason = evt->reason;
18279 	param->rssi = evt->rssi;
18280 
18281 	return QDF_STATUS_SUCCESS;
18282 }
18283 
18284 /**
18285  * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event
18286  * @wmi_handle: wmi handle
18287  * @param evt_buf: pointer to event buffer
18288  * @param param: Pointer to hold vdev scan param
18289  *
18290  * Return: QDF_STATUS_SUCCESS for success or error code
18291  */
18292 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle,
18293 	void *evt_buf, struct scan_event *param)
18294 {
18295 	WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL;
18296 	wmi_scan_event_fixed_param *evt = NULL;
18297 
18298 	param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf;
18299 	evt = param_buf->fixed_param;
18300 
18301 	qdf_mem_zero(param, sizeof(*param));
18302 
18303 	switch (evt->event) {
18304 	case WMI_SCAN_EVENT_STARTED:
18305 		param->type = SCAN_EVENT_TYPE_STARTED;
18306 		break;
18307 	case WMI_SCAN_EVENT_COMPLETED:
18308 		param->type = SCAN_EVENT_TYPE_COMPLETED;
18309 		break;
18310 	case WMI_SCAN_EVENT_BSS_CHANNEL:
18311 		param->type = SCAN_EVENT_TYPE_BSS_CHANNEL;
18312 		break;
18313 	case WMI_SCAN_EVENT_FOREIGN_CHANNEL:
18314 		param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL;
18315 		break;
18316 	case WMI_SCAN_EVENT_DEQUEUED:
18317 		param->type = SCAN_EVENT_TYPE_DEQUEUED;
18318 		break;
18319 	case WMI_SCAN_EVENT_PREEMPTED:
18320 		param->type = SCAN_EVENT_TYPE_PREEMPTED;
18321 		break;
18322 	case WMI_SCAN_EVENT_START_FAILED:
18323 		param->type = SCAN_EVENT_TYPE_START_FAILED;
18324 		break;
18325 	case WMI_SCAN_EVENT_RESTARTED:
18326 		param->type = SCAN_EVENT_TYPE_RESTARTED;
18327 		break;
18328 	case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT:
18329 		param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT;
18330 		break;
18331 	case WMI_SCAN_EVENT_MAX:
18332 	default:
18333 		param->type = SCAN_EVENT_TYPE_MAX;
18334 		break;
18335 	};
18336 
18337 	switch (evt->reason) {
18338 	case WMI_SCAN_REASON_NONE:
18339 		param->reason = SCAN_REASON_NONE;
18340 		break;
18341 	case WMI_SCAN_REASON_COMPLETED:
18342 		param->reason = SCAN_REASON_COMPLETED;
18343 		break;
18344 	case WMI_SCAN_REASON_CANCELLED:
18345 		param->reason = SCAN_REASON_CANCELLED;
18346 		break;
18347 	case WMI_SCAN_REASON_PREEMPTED:
18348 		param->reason = SCAN_REASON_PREEMPTED;
18349 		break;
18350 	case WMI_SCAN_REASON_TIMEDOUT:
18351 		param->reason = SCAN_REASON_TIMEDOUT;
18352 		break;
18353 	case WMI_SCAN_REASON_INTERNAL_FAILURE:
18354 		param->reason = SCAN_REASON_INTERNAL_FAILURE;
18355 		break;
18356 	case WMI_SCAN_REASON_SUSPENDED:
18357 		param->reason = SCAN_REASON_SUSPENDED;
18358 		break;
18359 	case WMI_SCAN_REASON_MAX:
18360 		param->reason = SCAN_REASON_MAX;
18361 		break;
18362 	default:
18363 		param->reason = SCAN_REASON_MAX;
18364 		break;
18365 	};
18366 
18367 	param->chan_freq = evt->channel_freq;
18368 	param->requester = evt->requestor;
18369 	param->scan_id = evt->scan_id;
18370 	param->vdev_id = evt->vdev_id;
18371 	param->timestamp = evt->tsf_timestamp;
18372 
18373 	return QDF_STATUS_SUCCESS;
18374 }
18375 
18376 #ifdef CONVERGED_TDLS_ENABLE
18377 /**
18378  * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event
18379  * @wmi_handle: wmi handle
18380  * @param evt_buf: pointer to event buffer
18381  * @param param: Pointer to hold vdev tdls param
18382  *
18383  * Return: QDF_STATUS_SUCCESS for success or error code
18384  */
18385 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle,
18386 	void *evt_buf, struct tdls_event_info *param)
18387 {
18388 	WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf;
18389 	wmi_tdls_peer_event_fixed_param *evt;
18390 
18391 	param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf;
18392 	if (!param_buf) {
18393 		WMI_LOGE("%s: NULL param_buf", __func__);
18394 		return QDF_STATUS_E_NULL_VALUE;
18395 	}
18396 
18397 	evt = param_buf->fixed_param;
18398 
18399 	qdf_mem_zero(param, sizeof(*param));
18400 
18401 	param->vdev_id = evt->vdev_id;
18402 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr,
18403 				   param->peermac.bytes);
18404 	switch (evt->peer_status) {
18405 	case WMI_TDLS_SHOULD_DISCOVER:
18406 		param->message_type = TDLS_SHOULD_DISCOVER;
18407 		break;
18408 	case WMI_TDLS_SHOULD_TEARDOWN:
18409 		param->message_type = TDLS_SHOULD_TEARDOWN;
18410 		break;
18411 	case WMI_TDLS_PEER_DISCONNECTED:
18412 		param->message_type = TDLS_PEER_DISCONNECTED;
18413 		break;
18414 	case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION:
18415 		param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY;
18416 		break;
18417 	default:
18418 		WMI_LOGE("%s: Discarding unknown tdls event %d from target",
18419 			 __func__, evt->peer_status);
18420 		return QDF_STATUS_E_INVAL;
18421 	};
18422 
18423 	switch (evt->peer_reason) {
18424 	case WMI_TDLS_TEARDOWN_REASON_TX:
18425 		param->peer_reason = TDLS_TEARDOWN_TX;
18426 		break;
18427 	case WMI_TDLS_TEARDOWN_REASON_RSSI:
18428 		param->peer_reason = TDLS_TEARDOWN_RSSI;
18429 		break;
18430 	case WMI_TDLS_TEARDOWN_REASON_SCAN:
18431 		param->peer_reason = TDLS_TEARDOWN_SCAN;
18432 		break;
18433 	case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE:
18434 		param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE;
18435 		break;
18436 	case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
18437 		param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT;
18438 		break;
18439 	case WMI_TDLS_TEARDOWN_REASON_BAD_PTR:
18440 		param->peer_reason = TDLS_TEARDOWN_BAD_PTR;
18441 		break;
18442 	case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
18443 		param->peer_reason = TDLS_TEARDOWN_NO_RSP;
18444 		break;
18445 	case WMI_TDLS_ENTER_BUF_STA:
18446 		param->peer_reason = TDLS_PEER_ENTER_BUF_STA;
18447 		break;
18448 	case WMI_TDLS_EXIT_BUF_STA:
18449 		param->peer_reason = TDLS_PEER_EXIT_BUF_STA;
18450 		break;
18451 	case WMI_TDLS_ENTER_BT_BUSY_MODE:
18452 		param->peer_reason = TDLS_ENTER_BT_BUSY;
18453 		break;
18454 	case WMI_TDLS_EXIT_BT_BUSY_MODE:
18455 		param->peer_reason = TDLS_EXIT_BT_BUSY;
18456 		break;
18457 	case WMI_TDLS_SCAN_STARTED_EVENT:
18458 		param->peer_reason = TDLS_SCAN_STARTED;
18459 		break;
18460 	case WMI_TDLS_SCAN_COMPLETED_EVENT:
18461 		param->peer_reason = TDLS_SCAN_COMPLETED;
18462 		break;
18463 
18464 	default:
18465 		WMI_LOGE("%s: unknown reason %d in tdls event %d from target",
18466 			 __func__, evt->peer_reason, evt->peer_status);
18467 		return QDF_STATUS_E_INVAL;
18468 	};
18469 
18470 	WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d",
18471 		 __func__, param->peermac.bytes, param->message_type,
18472 		 param->peer_reason, param->vdev_id);
18473 
18474 	return QDF_STATUS_SUCCESS;
18475 }
18476 #endif
18477 
18478 /**
18479  * extract_mgmt_tx_compl_param_tlv() - extract MGMT tx completion event params
18480  * @wmi_handle: wmi handle
18481  * @param evt_buf: pointer to event buffer
18482  * @param param: Pointer to hold MGMT TX completion params
18483  *
18484  * Return: QDF_STATUS_SUCCESS for success or error code
18485  */
18486 static QDF_STATUS extract_mgmt_tx_compl_param_tlv(wmi_unified_t wmi_handle,
18487 	void *evt_buf, wmi_host_mgmt_tx_compl_event *param)
18488 {
18489 	WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf;
18490 	wmi_mgmt_tx_compl_event_fixed_param *cmpl_params;
18491 
18492 	param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *)
18493 		evt_buf;
18494 	if (!param_buf) {
18495 		WMI_LOGE("%s: Invalid mgmt Tx completion event", __func__);
18496 		return QDF_STATUS_E_INVAL;
18497 	}
18498 	cmpl_params = param_buf->fixed_param;
18499 
18500 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18501 							cmpl_params->pdev_id);
18502 	param->desc_id = cmpl_params->desc_id;
18503 	param->status = cmpl_params->status;
18504 	param->ppdu_id = cmpl_params->ppdu_id;
18505 
18506 	return QDF_STATUS_SUCCESS;
18507 }
18508 
18509 /**
18510  * extract_offchan_data_tx_compl_param_tlv() -
18511  *            extract Offchan data tx completion event params
18512  * @wmi_handle: wmi handle
18513  * @param evt_buf: pointer to event buffer
18514  * @param param: Pointer to hold offchan data TX completion params
18515  *
18516  * Return: QDF_STATUS_SUCCESS for success or error code
18517  */
18518 static QDF_STATUS extract_offchan_data_tx_compl_param_tlv(
18519 		wmi_unified_t wmi_handle, void *evt_buf,
18520 		struct wmi_host_offchan_data_tx_compl_event *param)
18521 {
18522 	WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *param_buf;
18523 	wmi_offchan_data_tx_compl_event_fixed_param *cmpl_params;
18524 
18525 	param_buf = (WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *)
18526 		evt_buf;
18527 	if (!param_buf) {
18528 		WMI_LOGE("%s: Invalid offchan data Tx compl event", __func__);
18529 		return QDF_STATUS_E_INVAL;
18530 	}
18531 	cmpl_params = param_buf->fixed_param;
18532 
18533 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18534 							cmpl_params->pdev_id);
18535 	param->desc_id = cmpl_params->desc_id;
18536 	param->status = cmpl_params->status;
18537 
18538 	return QDF_STATUS_SUCCESS;
18539 }
18540 
18541 /**
18542  * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count
18543  *                                              status tlv
18544  * @wmi_handle: wmi handle
18545  * @param evt_buf: pointer to event buffer
18546  * @param param: Pointer to hold csa switch count status event param
18547  *
18548  * Return: QDF_STATUS_SUCCESS for success or error code
18549  */
18550 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv(
18551 				wmi_unified_t wmi_handle,
18552 				void *evt_buf,
18553 				struct pdev_csa_switch_count_status *param)
18554 {
18555 	WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf;
18556 	wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status;
18557 
18558 	param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *)
18559 		     evt_buf;
18560 	if (!param_buf) {
18561 		WMI_LOGE("%s: Invalid CSA status event\n", __func__);
18562 		return QDF_STATUS_E_INVAL;
18563 	}
18564 
18565 	csa_status = param_buf->fixed_param;
18566 
18567 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18568 							csa_status->pdev_id);
18569 	param->current_switch_count = csa_status->current_switch_count;
18570 	param->num_vdevs = csa_status->num_vdevs;
18571 	param->vdev_ids = param_buf->vdev_ids;
18572 
18573 	return QDF_STATUS_SUCCESS;
18574 }
18575 
18576 /**
18577  * extract_pdev_tpc_config_ev_param_tlv() - extract pdev tpc configuration
18578  * param from event
18579  * @wmi_handle: wmi handle
18580  * @param evt_buf: pointer to event buffer
18581  * @param param: Pointer to hold tpc configuration
18582  *
18583  * Return: 0 for success or error code
18584  */
18585 static QDF_STATUS extract_pdev_tpc_config_ev_param_tlv(wmi_unified_t wmi_handle,
18586 		void *evt_buf,
18587 		wmi_host_pdev_tpc_config_event *param)
18588 {
18589 	wmi_pdev_tpc_config_event_fixed_param *event =
18590 		(wmi_pdev_tpc_config_event_fixed_param *)evt_buf;
18591 
18592 	if (!event) {
18593 		WMI_LOGE("Invalid event buffer");
18594 		return QDF_STATUS_E_INVAL;
18595 	}
18596 
18597 	param->pdev_id = event->pdev_id;
18598 	param->regDomain = event->regDomain;
18599 	param->chanFreq = event->chanFreq;
18600 	param->phyMode = event->phyMode;
18601 	param->twiceAntennaReduction = event->twiceAntennaReduction;
18602 	param->twiceAntennaGain = event->twiceAntennaGain;
18603 	param->twiceMaxRDPower = event->twiceMaxRDPower;
18604 	param->powerLimit = event->powerLimit;
18605 	param->rateMax = event->rateMax;
18606 	param->numTxChain = event->numTxChain;
18607 	param->ctl = event->ctl;
18608 	param->flags = event->flags;
18609 
18610 	qdf_mem_copy(param->maxRegAllowedPower, event->maxRegAllowedPower,
18611 		sizeof(param->maxRegAllowedPower));
18612 	qdf_mem_copy(param->maxRegAllowedPowerAGCDD,
18613 		event->maxRegAllowedPowerAGCDD,
18614 		sizeof(param->maxRegAllowedPowerAGCDD));
18615 	qdf_mem_copy(param->maxRegAllowedPowerAGSTBC,
18616 		event->maxRegAllowedPowerAGSTBC,
18617 		sizeof(param->maxRegAllowedPowerAGSTBC));
18618 	qdf_mem_copy(param->maxRegAllowedPowerAGTXBF,
18619 		event->maxRegAllowedPowerAGTXBF,
18620 		sizeof(param->maxRegAllowedPowerAGTXBF));
18621 	WMI_LOGD("%s:extract success", __func__);
18622 
18623 	return QDF_STATUS_SUCCESS;
18624 }
18625 
18626 /**
18627  * extract_swba_num_vdevs_tlv() - extract swba num vdevs from event
18628  * @wmi_handle: wmi handle
18629  * @param evt_buf: pointer to event buffer
18630  * @param num_vdevs: Pointer to hold num vdevs
18631  *
18632  * Return: QDF_STATUS_SUCCESS for success or error code
18633  */
18634 static QDF_STATUS extract_swba_num_vdevs_tlv(wmi_unified_t wmi_handle,
18635 	void *evt_buf, uint32_t *num_vdevs)
18636 {
18637 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
18638 	wmi_host_swba_event_fixed_param *swba_event;
18639 	uint32_t vdev_map;
18640 
18641 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf;
18642 	if (!param_buf) {
18643 		WMI_LOGE("Invalid swba event buffer");
18644 		return QDF_STATUS_E_INVAL;
18645 	}
18646 
18647 	swba_event = param_buf->fixed_param;
18648 	*num_vdevs = swba_event->num_vdevs;
18649 	if (!(*num_vdevs)) {
18650 		vdev_map = swba_event->vdev_map;
18651 		*num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map);
18652 	}
18653 
18654 	return QDF_STATUS_SUCCESS;
18655 }
18656 
18657 /**
18658  * extract_swba_tim_info_tlv() - extract swba tim info from event
18659  * @wmi_handle: wmi handle
18660  * @param evt_buf: pointer to event buffer
18661  * @param idx: Index to bcn info
18662  * @param tim_info: Pointer to hold tim info
18663  *
18664  * Return: QDF_STATUS_SUCCESS for success or error code
18665  */
18666 static QDF_STATUS extract_swba_tim_info_tlv(wmi_unified_t wmi_handle,
18667 	void *evt_buf, uint32_t idx, wmi_host_tim_info *tim_info)
18668 {
18669 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
18670 	wmi_tim_info *tim_info_ev;
18671 
18672 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf;
18673 	if (!param_buf) {
18674 		WMI_LOGE("Invalid swba event buffer");
18675 		return QDF_STATUS_E_INVAL;
18676 	}
18677 
18678 	tim_info_ev = &param_buf->tim_info[idx];
18679 
18680 	tim_info->tim_len = tim_info_ev->tim_len;
18681 	tim_info->tim_mcast = tim_info_ev->tim_mcast;
18682 	qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap,
18683 			(sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE));
18684 	tim_info->tim_changed = tim_info_ev->tim_changed;
18685 	tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending;
18686 	tim_info->vdev_id = tim_info_ev->vdev_id;
18687 
18688 	return QDF_STATUS_SUCCESS;
18689 }
18690 
18691 /**
18692  * extract_swba_noa_info_tlv() - extract swba NoA information from event
18693  * @wmi_handle: wmi handle
18694  * @param evt_buf: pointer to event buffer
18695  * @param idx: Index to bcn info
18696  * @param p2p_desc: Pointer to hold p2p NoA info
18697  *
18698  * Return: QDF_STATUS_SUCCESS for success or error code
18699  */
18700 static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle,
18701 	void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc)
18702 {
18703 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
18704 	wmi_p2p_noa_info *p2p_noa_info;
18705 	uint8_t i = 0;
18706 
18707 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf;
18708 	if (!param_buf) {
18709 		WMI_LOGE("Invalid swba event buffer");
18710 		return QDF_STATUS_E_INVAL;
18711 	}
18712 
18713 	p2p_noa_info = &param_buf->p2p_noa_info[idx];
18714 
18715 	p2p_desc->modified = false;
18716 	p2p_desc->num_descriptors = 0;
18717 	if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) {
18718 		p2p_desc->modified = true;
18719 		p2p_desc->index =
18720 			(uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info);
18721 		p2p_desc->oppPS =
18722 			(uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info);
18723 		p2p_desc->ctwindow =
18724 			(uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info);
18725 		p2p_desc->num_descriptors =
18726 			(uint8_t) WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET
18727 							(p2p_noa_info);
18728 		for (i = 0; i < p2p_desc->num_descriptors; i++) {
18729 			p2p_desc->noa_descriptors[i].type_count =
18730 				(uint8_t) p2p_noa_info->noa_descriptors[i].
18731 				type_count;
18732 			p2p_desc->noa_descriptors[i].duration =
18733 				p2p_noa_info->noa_descriptors[i].duration;
18734 			p2p_desc->noa_descriptors[i].interval =
18735 				p2p_noa_info->noa_descriptors[i].interval;
18736 			p2p_desc->noa_descriptors[i].start_time =
18737 				p2p_noa_info->noa_descriptors[i].start_time;
18738 		}
18739 		p2p_desc->vdev_id = p2p_noa_info->vdev_id;
18740 	}
18741 
18742 	return QDF_STATUS_SUCCESS;
18743 }
18744 
18745 #ifdef CONVERGED_P2P_ENABLE
18746 /**
18747  * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event
18748  * @wmi_handle: wmi handle
18749  * @param evt_buf: pointer to event buffer
18750  * @param param: Pointer to hold p2p noa info
18751  *
18752  * Return: QDF_STATUS_SUCCESS for success or error code
18753  */
18754 static QDF_STATUS extract_p2p_noa_ev_param_tlv(
18755 	wmi_unified_t wmi_handle, void *evt_buf,
18756 	struct p2p_noa_info *param)
18757 {
18758 	WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs;
18759 	wmi_p2p_noa_event_fixed_param *fixed_param;
18760 	uint8_t i;
18761 	wmi_p2p_noa_info *wmi_noa_info;
18762 	uint8_t *buf_ptr;
18763 	uint32_t descriptors;
18764 
18765 	param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf;
18766 	if (!param_tlvs) {
18767 		WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__);
18768 		return QDF_STATUS_E_INVAL;
18769 	}
18770 
18771 	if (!param) {
18772 		WMI_LOGE("noa information param is null");
18773 		return QDF_STATUS_E_INVAL;
18774 	}
18775 
18776 	fixed_param = param_tlvs->fixed_param;
18777 	buf_ptr = (uint8_t *) fixed_param;
18778 	buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param);
18779 	wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr);
18780 
18781 	if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) {
18782 		WMI_LOGE("%s: noa attr is not modified", __func__);
18783 		return QDF_STATUS_E_INVAL;
18784 	}
18785 
18786 	param->vdev_id = fixed_param->vdev_id;
18787 	param->index =
18788 		(uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info);
18789 	param->opps_ps =
18790 		(uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info);
18791 	param->ct_window =
18792 		(uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info);
18793 	descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info);
18794 	param->num_desc = (uint8_t) descriptors;
18795 	if (param->num_desc > WMI_P2P_MAX_NOA_DESCRIPTORS) {
18796 		WMI_LOGE("%s: invalid num desc:%d", __func__,
18797 			 param->num_desc);
18798 		return QDF_STATUS_E_INVAL;
18799 	}
18800 
18801 	WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__,
18802 		param->index, param->opps_ps, param->ct_window,
18803 		param->num_desc);
18804 	for (i = 0; i < param->num_desc; i++) {
18805 		param->noa_desc[i].type_count =
18806 			(uint8_t) wmi_noa_info->noa_descriptors[i].
18807 			type_count;
18808 		param->noa_desc[i].duration =
18809 			wmi_noa_info->noa_descriptors[i].duration;
18810 		param->noa_desc[i].interval =
18811 			wmi_noa_info->noa_descriptors[i].interval;
18812 		param->noa_desc[i].start_time =
18813 			wmi_noa_info->noa_descriptors[i].start_time;
18814 		WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u",
18815 			__func__, i, param->noa_desc[i].type_count,
18816 			param->noa_desc[i].duration,
18817 			param->noa_desc[i].interval,
18818 			param->noa_desc[i].start_time);
18819 	}
18820 
18821 	return QDF_STATUS_SUCCESS;
18822 }
18823 
18824 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
18825 /**
18826  * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop
18827  * information from event
18828  * @wmi_handle: wmi handle
18829  * @param evt_buf: pointer to event buffer
18830  * @param param: Pointer to hold p2p lo stop event information
18831  *
18832  * Return: QDF_STATUS_SUCCESS for success or error code
18833  */
18834 static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv(
18835 	wmi_unified_t wmi_handle, void *evt_buf,
18836 	struct p2p_lo_event *param)
18837 {
18838 	WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs;
18839 	wmi_p2p_lo_stopped_event_fixed_param *lo_param;
18840 
18841 	param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *)
18842 					evt_buf;
18843 	if (!param_tlvs) {
18844 		WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__);
18845 		return QDF_STATUS_E_INVAL;
18846 	}
18847 
18848 	if (!param) {
18849 		WMI_LOGE("lo stop event param is null");
18850 		return QDF_STATUS_E_INVAL;
18851 	}
18852 
18853 	lo_param = param_tlvs->fixed_param;
18854 	param->vdev_id = lo_param->vdev_id;
18855 	param->reason_code = lo_param->reason;
18856 	WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__,
18857 		param->vdev_id, param->reason_code);
18858 
18859 	return QDF_STATUS_SUCCESS;
18860 }
18861 #endif
18862 #endif /* End of CONVERGED_P2P_ENABLE */
18863 
18864 /**
18865  * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event
18866  * @wmi_handle: wmi handle
18867  * @param evt_buf: pointer to event buffer
18868  * @param ev: Pointer to hold peer param
18869  *
18870  * Return: QDF_STATUS_SUCCESS for success or error code
18871  */
18872 static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle,
18873 	void *evt_buf, wmi_host_peer_sta_kickout_event *ev)
18874 {
18875 	WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL;
18876 	wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL;
18877 
18878 	param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) evt_buf;
18879 	kickout_event = param_buf->fixed_param;
18880 
18881 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr,
18882 							ev->peer_macaddr);
18883 
18884 	ev->reason = kickout_event->reason;
18885 	ev->rssi = kickout_event->rssi;
18886 
18887 	return QDF_STATUS_SUCCESS;
18888 }
18889 
18890 /**
18891  * extract_all_stats_counts_tlv() - extract all stats count from event
18892  * @wmi_handle: wmi handle
18893  * @param evt_buf: pointer to event buffer
18894  * @param stats_param: Pointer to hold stats count
18895  *
18896  * Return: QDF_STATUS_SUCCESS for success or error code
18897  */
18898 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle,
18899 	void *evt_buf, wmi_host_stats_event *stats_param)
18900 {
18901 	wmi_stats_event_fixed_param *ev;
18902 	wmi_per_chain_rssi_stats *rssi_event;
18903 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
18904 
18905 	qdf_mem_zero(stats_param, sizeof(*stats_param));
18906 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
18907 	ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
18908 	rssi_event = param_buf->chain_stats;
18909 	if (!ev) {
18910 		WMI_LOGE("%s: event fixed param NULL\n", __func__);
18911 		return QDF_STATUS_E_FAILURE;
18912 	}
18913 
18914 	switch (ev->stats_id) {
18915 	case WMI_REQUEST_PEER_STAT:
18916 		stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT;
18917 		break;
18918 
18919 	case WMI_REQUEST_AP_STAT:
18920 		stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT;
18921 		break;
18922 
18923 	case WMI_REQUEST_PDEV_STAT:
18924 		stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT;
18925 		break;
18926 
18927 	case WMI_REQUEST_VDEV_STAT:
18928 		stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT;
18929 		break;
18930 
18931 	case WMI_REQUEST_BCNFLT_STAT:
18932 		stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT;
18933 		break;
18934 
18935 	case WMI_REQUEST_VDEV_RATE_STAT:
18936 		stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT;
18937 		break;
18938 
18939 	case WMI_REQUEST_BCN_STAT:
18940 		stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT;
18941 		break;
18942 
18943 	default:
18944 		stats_param->stats_id = 0;
18945 		break;
18946 
18947 	}
18948 
18949 	stats_param->num_pdev_stats = ev->num_pdev_stats;
18950 	stats_param->num_pdev_ext_stats = 0;
18951 	stats_param->num_vdev_stats = ev->num_vdev_stats;
18952 	stats_param->num_peer_stats = ev->num_peer_stats;
18953 	stats_param->num_bcnflt_stats = ev->num_bcnflt_stats;
18954 	stats_param->num_chan_stats = ev->num_chan_stats;
18955 	stats_param->num_bcn_stats = ev->num_bcn_stats;
18956 	stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18957 							ev->pdev_id);
18958 
18959 	/* if chain_stats is not populated */
18960 	if (!param_buf->chain_stats || !param_buf->num_chain_stats)
18961 		return QDF_STATUS_SUCCESS;
18962 
18963 	if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats !=
18964 	    WMITLV_GET_TLVTAG(rssi_event->tlv_header))
18965 		return QDF_STATUS_SUCCESS;
18966 
18967 	if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) !=
18968 	    WMITLV_GET_TLVLEN(rssi_event->tlv_header))
18969 		return QDF_STATUS_SUCCESS;
18970 
18971 	stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats;
18972 
18973 	return QDF_STATUS_SUCCESS;
18974 }
18975 
18976 /**
18977  * extract_pdev_tx_stats() - extract pdev tx stats from event
18978  */
18979 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, struct wlan_dbg_tx_stats *tx_stats)
18980 {
18981 	/* Tx Stats */
18982 	tx->comp_queued = tx_stats->comp_queued;
18983 	tx->comp_delivered = tx_stats->comp_delivered;
18984 	tx->msdu_enqued = tx_stats->msdu_enqued;
18985 	tx->mpdu_enqued = tx_stats->mpdu_enqued;
18986 	tx->wmm_drop = tx_stats->wmm_drop;
18987 	tx->local_enqued = tx_stats->local_enqued;
18988 	tx->local_freed = tx_stats->local_freed;
18989 	tx->hw_queued = tx_stats->hw_queued;
18990 	tx->hw_reaped = tx_stats->hw_reaped;
18991 	tx->underrun = tx_stats->underrun;
18992 	tx->tx_abort = tx_stats->tx_abort;
18993 	tx->mpdus_requed = tx_stats->mpdus_requed;
18994 	tx->data_rc = tx_stats->data_rc;
18995 	tx->self_triggers = tx_stats->self_triggers;
18996 	tx->sw_retry_failure = tx_stats->sw_retry_failure;
18997 	tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err;
18998 	tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry;
18999 	tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout;
19000 	tx->pdev_resets = tx_stats->pdev_resets;
19001 	tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure;
19002 	tx->phy_underrun = tx_stats->phy_underrun;
19003 	tx->txop_ovf = tx_stats->txop_ovf;
19004 
19005 	return;
19006 }
19007 
19008 
19009 /**
19010  * extract_pdev_rx_stats() - extract pdev rx stats from event
19011  */
19012 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, struct wlan_dbg_rx_stats *rx_stats)
19013 {
19014 	/* Rx Stats */
19015 	rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change;
19016 	rx->status_rcvd = rx_stats->status_rcvd;
19017 	rx->r0_frags = rx_stats->r0_frags;
19018 	rx->r1_frags = rx_stats->r1_frags;
19019 	rx->r2_frags = rx_stats->r2_frags;
19020 	/* Only TLV */
19021 	rx->r3_frags = 0;
19022 	rx->htt_msdus = rx_stats->htt_msdus;
19023 	rx->htt_mpdus = rx_stats->htt_mpdus;
19024 	rx->loc_msdus = rx_stats->loc_msdus;
19025 	rx->loc_mpdus = rx_stats->loc_mpdus;
19026 	rx->oversize_amsdu = rx_stats->oversize_amsdu;
19027 	rx->phy_errs = rx_stats->phy_errs;
19028 	rx->phy_err_drop = rx_stats->phy_err_drop;
19029 	rx->mpdu_errs = rx_stats->mpdu_errs;
19030 
19031 	return;
19032 }
19033 
19034 /**
19035  * extract_pdev_stats_tlv() - extract pdev stats from event
19036  * @wmi_handle: wmi handle
19037  * @param evt_buf: pointer to event buffer
19038  * @param index: Index into pdev stats
19039  * @param pdev_stats: Pointer to hold pdev stats
19040  *
19041  * Return: QDF_STATUS_SUCCESS for success or error code
19042  */
19043 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle,
19044 	void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats)
19045 {
19046 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19047 	wmi_stats_event_fixed_param *ev_param;
19048 	uint8_t *data;
19049 
19050 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19051 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19052 
19053 	data = param_buf->data;
19054 
19055 	if (index < ev_param->num_pdev_stats) {
19056 		wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) +
19057 				(index * sizeof(wmi_pdev_stats)));
19058 
19059 		pdev_stats->chan_nf = ev->chan_nf;
19060 		pdev_stats->tx_frame_count = ev->tx_frame_count;
19061 		pdev_stats->rx_frame_count = ev->rx_frame_count;
19062 		pdev_stats->rx_clear_count = ev->rx_clear_count;
19063 		pdev_stats->cycle_count = ev->cycle_count;
19064 		pdev_stats->phy_err_count = ev->phy_err_count;
19065 		pdev_stats->chan_tx_pwr = ev->chan_tx_pwr;
19066 
19067 		extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx),
19068 			&(ev->pdev_stats.tx));
19069 		extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx),
19070 			&(ev->pdev_stats.rx));
19071 	}
19072 
19073 	return QDF_STATUS_SUCCESS;
19074 }
19075 
19076 /**
19077  * extract_unit_test_tlv() - extract unit test data
19078  * @wmi_handle: wmi handle
19079  * @param evt_buf: pointer to event buffer
19080  * @param unit_test: pointer to hold unit test data
19081  * @param maxspace: Amount of space in evt_buf
19082  *
19083  * Return: QDF_STATUS_SUCCESS for success or error code
19084  */
19085 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle,
19086 	void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace)
19087 {
19088 	WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf;
19089 	wmi_unit_test_event_fixed_param *ev_param;
19090 	uint32_t num_bufp;
19091 	uint32_t copy_size;
19092 	uint8_t *bufp;
19093 
19094 	param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf;
19095 	ev_param = param_buf->fixed_param;
19096 	bufp = param_buf->bufp;
19097 	num_bufp = param_buf->num_bufp;
19098 	unit_test->vdev_id = ev_param->vdev_id;
19099 	unit_test->module_id = ev_param->module_id;
19100 	unit_test->diag_token = ev_param->diag_token;
19101 	unit_test->flag = ev_param->flag;
19102 	unit_test->payload_len = ev_param->payload_len;
19103 	WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d\n", __func__,
19104 			ev_param->vdev_id,
19105 			ev_param->module_id,
19106 			ev_param->diag_token,
19107 			ev_param->flag);
19108 	WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp);
19109 	qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
19110 			bufp, num_bufp);
19111 	copy_size = (num_bufp < maxspace) ? num_bufp : maxspace;
19112 	qdf_mem_copy(unit_test->buffer, bufp, copy_size);
19113 	unit_test->buffer_len = copy_size;
19114 
19115 	return QDF_STATUS_SUCCESS;
19116 }
19117 
19118 /**
19119  * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event
19120  * @wmi_handle: wmi handle
19121  * @param evt_buf: pointer to event buffer
19122  * @param index: Index into extended pdev stats
19123  * @param pdev_ext_stats: Pointer to hold extended pdev stats
19124  *
19125  * Return: QDF_STATUS_SUCCESS for success or error code
19126  */
19127 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle,
19128 	void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats)
19129 {
19130 	return QDF_STATUS_SUCCESS;
19131 }
19132 
19133 /**
19134  * extract_vdev_stats_tlv() - extract vdev stats from event
19135  * @wmi_handle: wmi handle
19136  * @param evt_buf: pointer to event buffer
19137  * @param index: Index into vdev stats
19138  * @param vdev_stats: Pointer to hold vdev stats
19139  *
19140  * Return: QDF_STATUS_SUCCESS for success or error code
19141  */
19142 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle,
19143 	void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats)
19144 {
19145 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19146 	wmi_stats_event_fixed_param *ev_param;
19147 	uint8_t *data;
19148 
19149 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19150 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19151 	data = (uint8_t *) param_buf->data;
19152 
19153 	if (index < ev_param->num_vdev_stats) {
19154 		wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) +
19155 				((ev_param->num_pdev_stats) *
19156 				sizeof(wmi_pdev_stats)) +
19157 				(index * sizeof(wmi_vdev_stats)));
19158 
19159 		vdev_stats->vdev_id = ev->vdev_id;
19160 		vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr;
19161 		vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr;
19162 
19163 		OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt,
19164 			sizeof(ev->tx_frm_cnt));
19165 		vdev_stats->rx_frm_cnt = ev->rx_frm_cnt;
19166 		OS_MEMCPY(vdev_stats->multiple_retry_cnt,
19167 				ev->multiple_retry_cnt,
19168 				sizeof(ev->multiple_retry_cnt));
19169 		OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt,
19170 				sizeof(ev->fail_cnt));
19171 		vdev_stats->rts_fail_cnt = ev->rts_fail_cnt;
19172 		vdev_stats->rts_succ_cnt = ev->rts_succ_cnt;
19173 		vdev_stats->rx_err_cnt = ev->rx_err_cnt;
19174 		vdev_stats->rx_discard_cnt = ev->rx_discard_cnt;
19175 		vdev_stats->ack_fail_cnt = ev->ack_fail_cnt;
19176 		OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history,
19177 			sizeof(ev->tx_rate_history));
19178 		OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history,
19179 			sizeof(ev->bcn_rssi_history));
19180 
19181 	}
19182 
19183 	return QDF_STATUS_SUCCESS;
19184 }
19185 
19186 /**
19187  * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event
19188  * buffer
19189  * @wmi_handle: wmi handle
19190  * @evt_buf: pointer to event buffer
19191  * @index: Index into vdev stats
19192  * @rssi_stats: Pointer to hold rssi stats
19193  *
19194  * Return: QDF_STATUS_SUCCESS for success or error code
19195  */
19196 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle,
19197 			void *evt_buf, uint32_t index,
19198 			struct wmi_host_per_chain_rssi_stats *rssi_stats)
19199 {
19200 	uint8_t *data;
19201 	wmi_rssi_stats *fw_rssi_stats;
19202 	wmi_per_chain_rssi_stats *rssi_event;
19203 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19204 
19205 	if (!evt_buf) {
19206 		WMI_LOGE("evt_buf is null");
19207 		return QDF_STATUS_E_NULL_VALUE;
19208 	}
19209 
19210 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19211 	rssi_event = param_buf->chain_stats;
19212 
19213 	if (index >= rssi_event->num_per_chain_rssi_stats) {
19214 		WMI_LOGE("invalid index");
19215 		return QDF_STATUS_E_INVAL;
19216 	}
19217 
19218 	data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE;
19219 	fw_rssi_stats = &((wmi_rssi_stats *)data)[index];
19220 
19221 	rssi_stats->vdev_id = fw_rssi_stats->vdev_id;
19222 	qdf_mem_copy(rssi_stats->rssi_avg_beacon,
19223 		     fw_rssi_stats->rssi_avg_beacon,
19224 		     sizeof(fw_rssi_stats->rssi_avg_beacon));
19225 	qdf_mem_copy(rssi_stats->rssi_avg_data,
19226 		     fw_rssi_stats->rssi_avg_data,
19227 		     sizeof(fw_rssi_stats->rssi_avg_data));
19228 	qdf_mem_copy(&rssi_stats->peer_macaddr,
19229 		     &fw_rssi_stats->peer_macaddr,
19230 		     sizeof(fw_rssi_stats->peer_macaddr));
19231 
19232 	return QDF_STATUS_SUCCESS;
19233 }
19234 
19235 
19236 
19237 /**
19238  * extract_bcn_stats_tlv() - extract bcn stats from event
19239  * @wmi_handle: wmi handle
19240  * @param evt_buf: pointer to event buffer
19241  * @param index: Index into vdev stats
19242  * @param bcn_stats: Pointer to hold bcn stats
19243  *
19244  * Return: QDF_STATUS_SUCCESS for success or error code
19245  */
19246 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle,
19247 	void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats)
19248 {
19249 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19250 	wmi_stats_event_fixed_param *ev_param;
19251 	uint8_t *data;
19252 
19253 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19254 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19255 	data = (uint8_t *) param_buf->data;
19256 
19257 	if (index < ev_param->num_bcn_stats) {
19258 		wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) +
19259 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19260 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19261 			((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) +
19262 			((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) +
19263 			((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) +
19264 			(index * sizeof(wmi_bcn_stats)));
19265 
19266 		bcn_stats->vdev_id = ev->vdev_id;
19267 		bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt;
19268 		bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt;
19269 	}
19270 
19271 	return QDF_STATUS_SUCCESS;
19272 }
19273 
19274 /**
19275  * extract_peer_stats_tlv() - extract peer stats from event
19276  * @wmi_handle: wmi handle
19277  * @param evt_buf: pointer to event buffer
19278  * @param index: Index into peer stats
19279  * @param peer_stats: Pointer to hold peer stats
19280  *
19281  * Return: QDF_STATUS_SUCCESS for success or error code
19282  */
19283 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle,
19284 	void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats)
19285 {
19286 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19287 	wmi_stats_event_fixed_param *ev_param;
19288 	uint8_t *data;
19289 
19290 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19291 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19292 	data = (uint8_t *) param_buf->data;
19293 
19294 	if (index < ev_param->num_peer_stats) {
19295 		wmi_peer_stats *ev = (wmi_peer_stats *) ((data) +
19296 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19297 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19298 			(index * sizeof(wmi_peer_stats)));
19299 
19300 		OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats));
19301 
19302 		OS_MEMCPY(&(peer_stats->peer_macaddr),
19303 			&(ev->peer_macaddr), sizeof(wmi_mac_addr));
19304 
19305 		peer_stats->peer_rssi = ev->peer_rssi;
19306 		peer_stats->peer_tx_rate = ev->peer_tx_rate;
19307 		peer_stats->peer_rx_rate = ev->peer_rx_rate;
19308 	}
19309 
19310 	return QDF_STATUS_SUCCESS;
19311 }
19312 
19313 /**
19314  * extract_bcnflt_stats_tlv() - extract bcn fault stats from event
19315  * @wmi_handle: wmi handle
19316  * @param evt_buf: pointer to event buffer
19317  * @param index: Index into bcn fault stats
19318  * @param bcnflt_stats: Pointer to hold bcn fault stats
19319  *
19320  * Return: QDF_STATUS_SUCCESS for success or error code
19321  */
19322 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle,
19323 	void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats)
19324 {
19325 	return QDF_STATUS_SUCCESS;
19326 }
19327 
19328 /**
19329  * extract_peer_extd_stats_tlv() - extract extended peer stats from event
19330  * @wmi_handle: wmi handle
19331  * @param evt_buf: pointer to event buffer
19332  * @param index: Index into extended peer stats
19333  * @param peer_extd_stats: Pointer to hold extended peer stats
19334  *
19335  * Return: QDF_STATUS_SUCCESS for success or error code
19336  */
19337 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle,
19338 		void *evt_buf, uint32_t index,
19339 		wmi_host_peer_extd_stats *peer_extd_stats)
19340 {
19341 	return QDF_STATUS_SUCCESS;
19342 }
19343 
19344 /**
19345  * extract_chan_stats_tlv() - extract chan stats from event
19346  * @wmi_handle: wmi handle
19347  * @param evt_buf: pointer to event buffer
19348  * @param index: Index into chan stats
19349  * @param vdev_extd_stats: Pointer to hold chan stats
19350  *
19351  * Return: QDF_STATUS_SUCCESS for success or error code
19352  */
19353 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle,
19354 	void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats)
19355 {
19356 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19357 	wmi_stats_event_fixed_param *ev_param;
19358 	uint8_t *data;
19359 
19360 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19361 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19362 	data = (uint8_t *) param_buf->data;
19363 
19364 	if (index < ev_param->num_chan_stats) {
19365 		wmi_chan_stats *ev = (wmi_chan_stats *) ((data) +
19366 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19367 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19368 			((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) +
19369 			(index * sizeof(wmi_chan_stats)));
19370 
19371 
19372 		/* Non-TLV doesn't have num_chan_stats */
19373 		chan_stats->chan_mhz = ev->chan_mhz;
19374 		chan_stats->sampling_period_us = ev->sampling_period_us;
19375 		chan_stats->rx_clear_count = ev->rx_clear_count;
19376 		chan_stats->tx_duration_us = ev->tx_duration_us;
19377 		chan_stats->rx_duration_us = ev->rx_duration_us;
19378 	}
19379 
19380 	return QDF_STATUS_SUCCESS;
19381 }
19382 
19383 /**
19384  * extract_profile_ctx_tlv() - extract profile context from event
19385  * @wmi_handle: wmi handle
19386  * @param evt_buf: pointer to event buffer
19387  * @idx: profile stats index to extract
19388  * @param profile_ctx: Pointer to hold profile context
19389  *
19390  * Return: QDF_STATUS_SUCCESS for success or error code
19391  */
19392 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle,
19393 	void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx)
19394 {
19395 	return QDF_STATUS_SUCCESS;
19396 }
19397 
19398 /**
19399  * extract_profile_data_tlv() - extract profile data from event
19400  * @wmi_handle: wmi handle
19401  * @param evt_buf: pointer to event buffer
19402  * @param profile_data: Pointer to hold profile data
19403  *
19404  * Return: QDF_STATUS_SUCCESS for success or error code
19405  */
19406 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle,
19407 	void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data)
19408 {
19409 
19410 	return QDF_STATUS_SUCCESS;
19411 }
19412 
19413 /**
19414  * extract_chan_info_event_tlv() - extract chan information from event
19415  * @wmi_handle: wmi handle
19416  * @param evt_buf: pointer to event buffer
19417  * @param chan_info: Pointer to hold chan information
19418  *
19419  * Return: QDF_STATUS_SUCCESS for success or error code
19420  */
19421 static QDF_STATUS extract_chan_info_event_tlv(wmi_unified_t wmi_handle,
19422 	void *evt_buf, wmi_host_chan_info_event *chan_info)
19423 {
19424 	WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf;
19425 	wmi_chan_info_event_fixed_param *ev;
19426 
19427 	param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) evt_buf;
19428 
19429 	ev = (wmi_chan_info_event_fixed_param *) param_buf->fixed_param;
19430 	if (!ev) {
19431 		WMI_LOGE("%s: Failed to allocmemory\n", __func__);
19432 		return QDF_STATUS_E_FAILURE;
19433 	}
19434 
19435 	chan_info->err_code = ev->err_code;
19436 	chan_info->freq = ev->freq;
19437 	chan_info->cmd_flags = ev->cmd_flags;
19438 	chan_info->noise_floor = ev->noise_floor;
19439 	chan_info->rx_clear_count = ev->rx_clear_count;
19440 	chan_info->cycle_count = ev->cycle_count;
19441 	chan_info->tx_frame_cnt = ev->tx_frame_cnt;
19442 	chan_info->mac_clk_mhz = ev->mac_clk_mhz;
19443 	chan_info->pdev_id = wlan_get_pdev_id_from_vdev_id(
19444 			(struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc,
19445 			ev->vdev_id, WLAN_SCAN_ID);
19446 	chan_info->chan_tx_pwr_range = ev->chan_tx_pwr_range;
19447 	chan_info->chan_tx_pwr_tp = ev->chan_tx_pwr_tp;
19448 	chan_info->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count;
19449 	chan_info->rx_11b_mode_data_duration = ev->rx_11b_mode_data_duration;
19450 	chan_info->tx_frame_cnt = ev->tx_frame_cnt;
19451 	chan_info->rx_frame_count = ev->rx_frame_count;
19452 	chan_info->mac_clk_mhz = ev->mac_clk_mhz;
19453 	chan_info->vdev_id = ev->vdev_id;
19454 
19455 	return QDF_STATUS_SUCCESS;
19456 }
19457 
19458 /**
19459  * extract_pdev_utf_event_tlv() - extract UTF data info from event
19460  * @wmi_handle: WMI handle
19461  * @param evt_buf: Pointer to event buffer
19462  * @param param: Pointer to hold data
19463  *
19464  * Return : QDF_STATUS_SUCCESS for success or error code
19465  */
19466 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle,
19467 			     uint8_t *evt_buf,
19468 			     struct wmi_host_pdev_utf_event *event)
19469 {
19470 	WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf;
19471 	struct wmi_host_utf_seg_header_info *seg_hdr;
19472 
19473 	param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf;
19474 	event->data = param_buf->data;
19475 	event->datalen = param_buf->num_data;
19476 
19477 	if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) {
19478 		WMI_LOGE("%s: Invalid datalen: %d ", __func__, event->datalen);
19479 		return QDF_STATUS_E_INVAL;
19480 	}
19481 	seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data;
19482 	/* Set pdev_id=1 until FW adds support to include pdev_id */
19483 	event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19484 							seg_hdr->pdev_id);
19485 
19486 	return QDF_STATUS_SUCCESS;
19487 }
19488 
19489 /**
19490  * extract_chainmask_tables_tlv() - extract chain mask tables from event
19491  * @wmi_handle: wmi handle
19492  * @param evt_buf: pointer to event buffer
19493  * @param param: Pointer to hold evt buf
19494  *
19495  * Return: QDF_STATUS_SUCCESS for success or error code
19496  */
19497 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle,
19498 		uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table)
19499 {
19500 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19501 	WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps;
19502 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19503 	uint8_t i = 0, j = 0;
19504 
19505 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19506 	if (!param_buf)
19507 		return QDF_STATUS_E_INVAL;
19508 
19509 	hw_caps = param_buf->soc_hw_mode_caps;
19510 	if (!hw_caps)
19511 		return QDF_STATUS_E_INVAL;
19512 
19513 	if (!hw_caps->num_chainmask_tables)
19514 		return QDF_STATUS_E_INVAL;
19515 
19516 	chainmask_caps = param_buf->mac_phy_chainmask_caps;
19517 
19518 	if (chainmask_caps == NULL)
19519 		return QDF_STATUS_E_INVAL;
19520 
19521 	for (i = 0; i < hw_caps->num_chainmask_tables; i++) {
19522 
19523 		qdf_print("Dumping chain mask combo data for table : %d", i);
19524 		for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) {
19525 
19526 			chainmask_table[i].cap_list[j].chainmask =
19527 				chainmask_caps->chainmask;
19528 
19529 			chainmask_table[i].cap_list[j].supports_chan_width_20 =
19530 				WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags);
19531 
19532 			chainmask_table[i].cap_list[j].supports_chan_width_40 =
19533 				WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags);
19534 
19535 			chainmask_table[i].cap_list[j].supports_chan_width_80 =
19536 				WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags);
19537 
19538 			chainmask_table[i].cap_list[j].supports_chan_width_160 =
19539 				WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags);
19540 
19541 			chainmask_table[i].cap_list[j].supports_chan_width_80P80 =
19542 				WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags);
19543 
19544 			chainmask_table[i].cap_list[j].chain_mask_2G =
19545 				WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags);
19546 
19547 			chainmask_table[i].cap_list[j].chain_mask_5G =
19548 				WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags);
19549 
19550 			chainmask_table[i].cap_list[j].chain_mask_tx =
19551 				WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags);
19552 
19553 			chainmask_table[i].cap_list[j].chain_mask_rx =
19554 				WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags);
19555 
19556 			chainmask_table[i].cap_list[j].supports_aDFS =
19557 				WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags);
19558 
19559 			qdf_print("supported_flags: 0x%08x  chainmasks: 0x%08x",
19560 				  chainmask_caps->supported_flags,
19561 				  chainmask_caps->chainmask
19562 				 );
19563 			chainmask_caps++;
19564 		}
19565 	}
19566 
19567 	return QDF_STATUS_SUCCESS;
19568 }
19569 
19570 /**
19571  * extract_service_ready_ext_tlv() - extract basic extended service ready params
19572  * from event
19573  * @wmi_handle: wmi handle
19574  * @param evt_buf: pointer to event buffer
19575  * @param param: Pointer to hold evt buf
19576  *
19577  * Return: QDF_STATUS_SUCCESS for success or error code
19578  */
19579 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle,
19580 		uint8_t *event, struct wlan_psoc_host_service_ext_param *param)
19581 {
19582 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19583 	wmi_service_ready_ext_event_fixed_param *ev;
19584 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19585 	WMI_SOC_HAL_REG_CAPABILITIES *reg_caps;
19586 	WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo;
19587 	uint8_t i = 0;
19588 
19589 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19590 	if (!param_buf)
19591 		return QDF_STATUS_E_INVAL;
19592 
19593 	ev = param_buf->fixed_param;
19594 	if (!ev)
19595 		return QDF_STATUS_E_INVAL;
19596 
19597 	/* Move this to host based bitmap */
19598 	param->default_conc_scan_config_bits =
19599 				ev->default_conc_scan_config_bits;
19600 	param->default_fw_config_bits = ev->default_fw_config_bits;
19601 	param->he_cap_info = ev->he_cap_info;
19602 	param->mpdu_density = ev->mpdu_density;
19603 	param->max_bssid_rx_filters = ev->max_bssid_rx_filters;
19604 	param->fw_build_vers_ext = ev->fw_build_vers_ext;
19605 	param->num_dbr_ring_caps = param_buf->num_dma_ring_caps;
19606 	param->max_bssid_indicator = ev->max_bssid_indicator;
19607 	qdf_mem_copy(&param->ppet, &ev->ppet, sizeof(param->ppet));
19608 
19609 	hw_caps = param_buf->soc_hw_mode_caps;
19610 	if (hw_caps)
19611 		param->num_hw_modes = hw_caps->num_hw_modes;
19612 	else
19613 		param->num_hw_modes = 0;
19614 
19615 	reg_caps = param_buf->soc_hal_reg_caps;
19616 	if (reg_caps)
19617 		param->num_phy = reg_caps->num_phy;
19618 	else
19619 		param->num_phy = 0;
19620 
19621 	if (hw_caps) {
19622 		param->num_chainmask_tables = hw_caps->num_chainmask_tables;
19623 		qdf_print("Num chain mask tables: %d", hw_caps->num_chainmask_tables);
19624 	} else
19625 		param->num_chainmask_tables = 0;
19626 
19627 	chain_mask_combo = param_buf->mac_phy_chainmask_combo;
19628 
19629 	if (chain_mask_combo == NULL)
19630 		return QDF_STATUS_SUCCESS;
19631 
19632 	qdf_print("Dumping chain mask combo data");
19633 
19634 	for (i = 0; i < param->num_chainmask_tables; i++) {
19635 
19636 		qdf_print("table_id : %d Num valid chainmasks: %d",
19637 			  chain_mask_combo->chainmask_table_id,
19638 			  chain_mask_combo->num_valid_chainmask
19639 			 );
19640 
19641 		param->chainmask_table[i].table_id =
19642 			chain_mask_combo->chainmask_table_id;
19643 		param->chainmask_table[i].num_valid_chainmasks =
19644 			chain_mask_combo->num_valid_chainmask;
19645 		chain_mask_combo++;
19646 	}
19647 	qdf_print("chain mask combo end");
19648 
19649 	return QDF_STATUS_SUCCESS;
19650 }
19651 
19652 /**
19653  * extract_sar_cap_service_ready_ext_tlv() -
19654  *       extract SAR cap from service ready event
19655  * @wmi_handle: wmi handle
19656  * @event: pointer to event buffer
19657  * @ext_param: extended target info
19658  *
19659  * Return: QDF_STATUS_SUCCESS for success or error code
19660  */
19661 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv(
19662 			wmi_unified_t wmi_handle,
19663 			uint8_t *event,
19664 			struct wlan_psoc_host_service_ext_param *ext_param)
19665 {
19666 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19667 	WMI_SAR_CAPABILITIES *sar_caps;
19668 
19669 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event;
19670 
19671 	if (!param_buf)
19672 		return QDF_STATUS_E_INVAL;
19673 
19674 	sar_caps = param_buf->sar_caps;
19675 	if (sar_caps)
19676 		ext_param->sar_version = sar_caps->active_version;
19677 	else
19678 		ext_param->sar_version = 0;
19679 
19680 	return QDF_STATUS_SUCCESS;
19681 }
19682 
19683 /**
19684  * extract_hw_mode_cap_service_ready_ext_tlv() -
19685  *       extract HW mode cap from service ready event
19686  * @wmi_handle: wmi handle
19687  * @param evt_buf: pointer to event buffer
19688  * @param param: Pointer to hold evt buf
19689  * @param hw_mode_idx: hw mode idx should be less than num_mode
19690  *
19691  * Return: QDF_STATUS_SUCCESS for success or error code
19692  */
19693 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv(
19694 			wmi_unified_t wmi_handle,
19695 			uint8_t *event, uint8_t hw_mode_idx,
19696 			struct wlan_psoc_host_hw_mode_caps *param)
19697 {
19698 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19699 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19700 
19701 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19702 	if (!param_buf)
19703 		return QDF_STATUS_E_INVAL;
19704 
19705 	hw_caps = param_buf->soc_hw_mode_caps;
19706 	if (!hw_caps)
19707 		return QDF_STATUS_E_INVAL;
19708 
19709 	if (hw_mode_idx >= hw_caps->num_hw_modes)
19710 		return QDF_STATUS_E_INVAL;
19711 
19712 	param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id;
19713 	param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map;
19714 
19715 	param->hw_mode_config_type =
19716 		param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type;
19717 
19718 	return QDF_STATUS_SUCCESS;
19719 }
19720 
19721 /**
19722  * extract_mac_phy_cap_service_ready_ext_tlv() -
19723  *       extract MAC phy cap from service ready event
19724  * @wmi_handle: wmi handle
19725  * @param evt_buf: pointer to event buffer
19726  * @param param: Pointer to hold evt buf
19727  * @param hw_mode_idx: hw mode idx should be less than num_mode
19728  * @param phy_id: phy id within hw_mode
19729  *
19730  * Return: QDF_STATUS_SUCCESS for success or error code
19731  */
19732 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv(
19733 			wmi_unified_t wmi_handle,
19734 			uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id,
19735 			struct wlan_psoc_host_mac_phy_caps *param)
19736 {
19737 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19738 	WMI_MAC_PHY_CAPABILITIES *mac_phy_caps;
19739 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19740 	uint32_t phy_map;
19741 	uint8_t hw_idx, phy_idx = 0;
19742 
19743 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19744 	if (!param_buf)
19745 		return QDF_STATUS_E_INVAL;
19746 
19747 	hw_caps = param_buf->soc_hw_mode_caps;
19748 	if (!hw_caps)
19749 		return QDF_STATUS_E_INVAL;
19750 
19751 	for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) {
19752 		if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id)
19753 			break;
19754 
19755 		phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map;
19756 		while (phy_map) {
19757 			phy_map >>= 1;
19758 			phy_idx++;
19759 		}
19760 	}
19761 
19762 	if (hw_idx == hw_caps->num_hw_modes)
19763 		return QDF_STATUS_E_INVAL;
19764 
19765 	phy_idx += phy_id;
19766 	if (phy_idx >= param_buf->num_mac_phy_caps)
19767 		return QDF_STATUS_E_INVAL;
19768 
19769 	mac_phy_caps = &param_buf->mac_phy_caps[phy_idx];
19770 
19771 	param->hw_mode_id = mac_phy_caps->hw_mode_id;
19772 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19773 							mac_phy_caps->pdev_id);
19774 	param->phy_id = mac_phy_caps->phy_id;
19775 	param->supports_11b =
19776 			WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags);
19777 	param->supports_11g =
19778 			WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags);
19779 	param->supports_11a =
19780 			WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags);
19781 	param->supports_11n =
19782 			WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags);
19783 	param->supports_11ac =
19784 			WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags);
19785 	param->supports_11ax =
19786 			WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags);
19787 
19788 	param->supported_bands = mac_phy_caps->supported_bands;
19789 	param->ampdu_density = mac_phy_caps->ampdu_density;
19790 	param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G;
19791 	param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G;
19792 	param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G;
19793 	param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G;
19794 	param->he_cap_info_2G = mac_phy_caps->he_cap_info_2G;
19795 	param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G;
19796 	param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G;
19797 	param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G;
19798 	param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G;
19799 	param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G;
19800 	param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G;
19801 	param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G;
19802 	param->he_cap_info_5G = mac_phy_caps->he_cap_info_5G;
19803 	param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G;
19804 	param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G;
19805 	param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G;
19806 	qdf_mem_copy(&param->he_cap_phy_info_2G,
19807 			&mac_phy_caps->he_cap_phy_info_2G,
19808 			sizeof(param->he_cap_phy_info_2G));
19809 	qdf_mem_copy(&param->he_cap_phy_info_5G,
19810 			&mac_phy_caps->he_cap_phy_info_5G,
19811 			sizeof(param->he_cap_phy_info_5G));
19812 	qdf_mem_copy(&param->he_ppet2G, &mac_phy_caps->he_ppet2G,
19813 				 sizeof(param->he_ppet2G));
19814 	qdf_mem_copy(&param->he_ppet5G, &mac_phy_caps->he_ppet5G,
19815 				sizeof(param->he_ppet5G));
19816 	param->chainmask_table_id = mac_phy_caps->chainmask_table_id;
19817 
19818 	return QDF_STATUS_SUCCESS;
19819 }
19820 
19821 /**
19822  * extract_reg_cap_service_ready_ext_tlv() -
19823  *       extract REG cap from service ready event
19824  * @wmi_handle: wmi handle
19825  * @param evt_buf: pointer to event buffer
19826  * @param param: Pointer to hold evt buf
19827  * @param phy_idx: phy idx should be less than num_mode
19828  *
19829  * Return: QDF_STATUS_SUCCESS for success or error code
19830  */
19831 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv(
19832 			wmi_unified_t wmi_handle,
19833 			uint8_t *event, uint8_t phy_idx,
19834 			struct wlan_psoc_host_hal_reg_capabilities_ext *param)
19835 {
19836 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19837 	WMI_SOC_HAL_REG_CAPABILITIES *reg_caps;
19838 	WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap;
19839 
19840 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19841 	if (!param_buf)
19842 		return QDF_STATUS_E_INVAL;
19843 
19844 	reg_caps = param_buf->soc_hal_reg_caps;
19845 	if (!reg_caps)
19846 		return QDF_STATUS_E_INVAL;
19847 
19848 	if (phy_idx >= reg_caps->num_phy)
19849 		return QDF_STATUS_E_INVAL;
19850 
19851 	ext_reg_cap = &param_buf->hal_reg_caps[phy_idx];
19852 
19853 	param->phy_id = ext_reg_cap->phy_id;
19854 	param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain;
19855 	param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext;
19856 	param->regcap1 = ext_reg_cap->regcap1;
19857 	param->regcap2 = ext_reg_cap->regcap2;
19858 	param->wireless_modes = convert_wireless_modes_tlv(
19859 						ext_reg_cap->wireless_modes);
19860 	param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan;
19861 	param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan;
19862 	param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan;
19863 	param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan;
19864 
19865 	return QDF_STATUS_SUCCESS;
19866 }
19867 
19868 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv(
19869 			wmi_unified_t wmi_handle,
19870 			uint8_t *event, uint8_t idx,
19871 			struct wlan_psoc_host_dbr_ring_caps *param)
19872 {
19873 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19874 	WMI_DMA_RING_CAPABILITIES *dbr_ring_caps;
19875 
19876 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event;
19877 	if (!param_buf)
19878 		return QDF_STATUS_E_INVAL;
19879 
19880 	dbr_ring_caps = &param_buf->dma_ring_caps[idx];
19881 
19882 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19883 				dbr_ring_caps->pdev_id);
19884 	param->mod_id = dbr_ring_caps->mod_id;
19885 	param->ring_elems_min = dbr_ring_caps->ring_elems_min;
19886 	param->min_buf_size = dbr_ring_caps->min_buf_size;
19887 	param->min_buf_align = dbr_ring_caps->min_buf_align;
19888 
19889 	return QDF_STATUS_SUCCESS;
19890 }
19891 
19892 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle,
19893 		uint8_t *event, struct direct_buf_rx_rsp *param)
19894 {
19895 	WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
19896 	wmi_dma_buf_release_fixed_param *ev;
19897 
19898 	param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
19899 	if (!param_buf)
19900 		return QDF_STATUS_E_INVAL;
19901 
19902 	ev = param_buf->fixed_param;
19903 	if (!ev)
19904 		return QDF_STATUS_E_INVAL;
19905 
19906 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19907 								ev->pdev_id);
19908 	param->mod_id = ev->mod_id;
19909 	param->num_buf_release_entry = ev->num_buf_release_entry;
19910 	param->num_meta_data_entry = ev->num_meta_data_entry;
19911 	WMI_LOGD("%s:pdev id %d mod id %d num buf release entry %d\n", __func__,
19912 		 param->pdev_id, param->mod_id, param->num_buf_release_entry);
19913 
19914 	return QDF_STATUS_SUCCESS;
19915 }
19916 
19917 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle,
19918 		uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param)
19919 {
19920 	WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
19921 	wmi_dma_buf_release_entry *entry;
19922 
19923 	param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
19924 	if (!param_buf)
19925 		return QDF_STATUS_E_INVAL;
19926 
19927 	entry = &param_buf->entries[idx];
19928 
19929 	if (!entry) {
19930 		WMI_LOGE("%s: Entry is NULL\n", __func__);
19931 		return QDF_STATUS_E_FAILURE;
19932 	}
19933 
19934 	WMI_LOGD("%s: paddr_lo[%d] = %x\n", __func__, idx, entry->paddr_lo);
19935 
19936 	param->paddr_lo = entry->paddr_lo;
19937 	param->paddr_hi = entry->paddr_hi;
19938 
19939 	return QDF_STATUS_SUCCESS;
19940 }
19941 
19942 static QDF_STATUS extract_dbr_buf_metadata_tlv(
19943 		wmi_unified_t wmi_handle, uint8_t *event,
19944 		uint8_t idx, struct direct_buf_rx_metadata *param)
19945 {
19946 	WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
19947 	wmi_dma_buf_release_spectral_meta_data *entry;
19948 
19949 	param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
19950 	if (!param_buf)
19951 		return QDF_STATUS_E_INVAL;
19952 
19953 	entry = &param_buf->meta_data[idx];
19954 
19955 	if (!entry) {
19956 		WMI_LOGE("%s: Entry is NULL\n", __func__);
19957 		return QDF_STATUS_E_FAILURE;
19958 	}
19959 
19960 	qdf_mem_copy(param->noisefloor, entry->noise_floor,
19961 		     sizeof(entry->noise_floor));
19962 	return QDF_STATUS_SUCCESS;
19963 }
19964 
19965 /**
19966  * extract_dcs_interference_type_tlv() - extract dcs interference type
19967  * from event
19968  * @wmi_handle: wmi handle
19969  * @param evt_buf: pointer to event buffer
19970  * @param param: Pointer to hold dcs interference param
19971  *
19972  * Return: 0 for success or error code
19973  */
19974 static QDF_STATUS extract_dcs_interference_type_tlv(
19975 		wmi_unified_t wmi_handle,
19976 		void *evt_buf, struct wmi_host_dcs_interference_param *param)
19977 {
19978 	WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf;
19979 
19980 	param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf;
19981 	if (!param_buf)
19982 		return QDF_STATUS_E_INVAL;
19983 
19984 	param->interference_type = param_buf->fixed_param->interference_type;
19985 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19986 					param_buf->fixed_param->pdev_id);
19987 
19988 	return QDF_STATUS_SUCCESS;
19989 }
19990 
19991 /*
19992  * extract_dcs_cw_int_tlv() - extract dcs cw interference from event
19993  * @wmi_handle: wmi handle
19994  * @param evt_buf: pointer to event buffer
19995  * @param cw_int: Pointer to hold cw interference
19996  *
19997  * Return: 0 for success or error code
19998  */
19999 static QDF_STATUS extract_dcs_cw_int_tlv(wmi_unified_t wmi_handle,
20000 		void *evt_buf,
20001 		wmi_host_ath_dcs_cw_int *cw_int)
20002 {
20003 	WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf;
20004 	wlan_dcs_cw_int *ev;
20005 
20006 	param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf;
20007 	if (!param_buf)
20008 		return QDF_STATUS_E_INVAL;
20009 
20010 	ev = param_buf->cw_int;
20011 
20012 	cw_int->channel = ev->channel;
20013 
20014 	return QDF_STATUS_SUCCESS;
20015 }
20016 
20017 /**
20018  * extract_dcs_im_tgt_stats_tlv() - extract dcs im target stats from event
20019  * @wmi_handle: wmi handle
20020  * @param evt_buf: pointer to event buffer
20021  * @param wlan_stat: Pointer to hold wlan stats
20022  *
20023  * Return: 0 for success or error code
20024  */
20025 static QDF_STATUS extract_dcs_im_tgt_stats_tlv(wmi_unified_t wmi_handle,
20026 		void *evt_buf,
20027 		wmi_host_dcs_im_tgt_stats_t *wlan_stat)
20028 {
20029 	WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf;
20030 	wlan_dcs_im_tgt_stats_t *ev;
20031 
20032 	param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf;
20033 	if (!param_buf)
20034 		return QDF_STATUS_E_INVAL;
20035 
20036 	ev = param_buf->wlan_stat;
20037 	wlan_stat->reg_tsf32 = ev->reg_tsf32;
20038 	wlan_stat->last_ack_rssi = ev->last_ack_rssi;
20039 	wlan_stat->tx_waste_time = ev->tx_waste_time;
20040 	wlan_stat->rx_time = ev->rx_time;
20041 	wlan_stat->phyerr_cnt = ev->phyerr_cnt;
20042 	wlan_stat->mib_stats.listen_time = ev->listen_time;
20043 	wlan_stat->mib_stats.reg_tx_frame_cnt = ev->reg_tx_frame_cnt;
20044 	wlan_stat->mib_stats.reg_rx_frame_cnt = ev->reg_rx_frame_cnt;
20045 	wlan_stat->mib_stats.reg_rxclr_cnt = ev->reg_rxclr_cnt;
20046 	wlan_stat->mib_stats.reg_cycle_cnt = ev->reg_cycle_cnt;
20047 	wlan_stat->mib_stats.reg_rxclr_ext_cnt = ev->reg_rxclr_ext_cnt;
20048 	wlan_stat->mib_stats.reg_ofdm_phyerr_cnt = ev->reg_ofdm_phyerr_cnt;
20049 	wlan_stat->mib_stats.reg_cck_phyerr_cnt = ev->reg_cck_phyerr_cnt;
20050 	wlan_stat->chan_nf = ev->chan_nf;
20051 	wlan_stat->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count;
20052 
20053 	return QDF_STATUS_SUCCESS;
20054 }
20055 
20056 /**
20057  * extract_thermal_stats_tlv() - extract thermal stats from event
20058  * @wmi_handle: wmi handle
20059  * @param evt_buf: Pointer to event buffer
20060  * @param temp: Pointer to hold extracted temperature
20061  * @param level: Pointer to hold extracted level
20062  *
20063  * Return: 0 for success or error code
20064  */
20065 static QDF_STATUS
20066 extract_thermal_stats_tlv(wmi_unified_t wmi_handle,
20067 		void *evt_buf, uint32_t *temp,
20068 		uint32_t *level, uint32_t *pdev_id)
20069 {
20070 	WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf;
20071 	wmi_therm_throt_stats_event_fixed_param *tt_stats_event;
20072 
20073 	param_buf =
20074 		(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf;
20075 	if (!param_buf)
20076 		return QDF_STATUS_E_INVAL;
20077 
20078 	tt_stats_event = param_buf->fixed_param;
20079 
20080 	*pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20081 						tt_stats_event->pdev_id);
20082 	*temp = tt_stats_event->temp;
20083 	*level = tt_stats_event->level;
20084 
20085 	return QDF_STATUS_SUCCESS;
20086 }
20087 
20088 /**
20089  * extract_thermal_level_stats_tlv() - extract thermal level stats from event
20090  * @wmi_handle: wmi handle
20091  * @param evt_buf: pointer to event buffer
20092  * @param idx: Index to level stats
20093  * @param levelcount: Pointer to hold levelcount
20094  * @param dccount: Pointer to hold dccount
20095  *
20096  * Return: 0 for success or error code
20097  */
20098 static QDF_STATUS
20099 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle,
20100 		void *evt_buf, uint8_t idx, uint32_t *levelcount,
20101 		uint32_t *dccount)
20102 {
20103 	WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf;
20104 	wmi_therm_throt_level_stats_info *tt_level_info;
20105 
20106 	param_buf =
20107 		(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf;
20108 	if (!param_buf)
20109 		return QDF_STATUS_E_INVAL;
20110 
20111 	tt_level_info = param_buf->therm_throt_level_stats_info;
20112 
20113 	if (idx < THERMAL_LEVELS) {
20114 		*levelcount = tt_level_info[idx].level_count;
20115 		*dccount = tt_level_info[idx].dc_count;
20116 		return QDF_STATUS_SUCCESS;
20117 	}
20118 
20119 	return QDF_STATUS_E_FAILURE;
20120 }
20121 #ifdef BIG_ENDIAN_HOST
20122 /**
20123  * fips_conv_data_be() - LE to BE conversion of FIPS ev data
20124  * @param data_len - data length
20125  * @param data - pointer to data
20126  *
20127  * Return: QDF_STATUS - success or error status
20128  */
20129 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data)
20130 {
20131 	uint8_t *data_aligned = NULL;
20132 	int c;
20133 	unsigned char *data_unaligned;
20134 
20135 	data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) +
20136 					FIPS_ALIGN));
20137 	/* Assigning unaligned space to copy the data */
20138 	/* Checking if kmalloc does successful allocation */
20139 	if (data_unaligned == NULL)
20140 		return QDF_STATUS_E_FAILURE;
20141 
20142 	/* Checking if space is alligned */
20143 	if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) {
20144 		/* align the data space */
20145 		data_aligned =
20146 			(uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN);
20147 	} else {
20148 		data_aligned = (u_int8_t *)data_unaligned;
20149 	}
20150 
20151 	/* memset and copy content from data to data aligned */
20152 	OS_MEMSET(data_aligned, 0, data_len);
20153 	OS_MEMCPY(data_aligned, data, data_len);
20154 	/* Endianness to LE */
20155 	for (c = 0; c < data_len/4; c++) {
20156 		*((u_int32_t *)data_aligned + c) =
20157 			qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c));
20158 	}
20159 
20160 	/* Copy content to event->data */
20161 	OS_MEMCPY(data, data_aligned, data_len);
20162 
20163 	/* clean up allocated space */
20164 	qdf_mem_free(data_unaligned);
20165 	data_aligned = NULL;
20166 	data_unaligned = NULL;
20167 
20168 	/*************************************************************/
20169 
20170 	return QDF_STATUS_SUCCESS;
20171 }
20172 #else
20173 /**
20174  * fips_conv_data_be() - DUMMY for LE platform
20175  *
20176  * Return: QDF_STATUS - success
20177  */
20178 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data)
20179 {
20180 	return QDF_STATUS_SUCCESS;
20181 }
20182 #endif
20183 
20184 /**
20185  * extract_fips_event_data_tlv() - extract fips event data
20186  * @wmi_handle: wmi handle
20187  * @param evt_buf: pointer to event buffer
20188  * @param param: pointer FIPS event params
20189  *
20190  * Return: 0 for success or error code
20191  */
20192 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle,
20193 		void *evt_buf, struct wmi_host_fips_event_param *param)
20194 {
20195 	WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf;
20196 	wmi_pdev_fips_event_fixed_param *event;
20197 
20198 	param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf;
20199 	event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param;
20200 
20201 	if (fips_conv_data_be(event->data_len, param_buf->data) !=
20202 							QDF_STATUS_SUCCESS)
20203 		return QDF_STATUS_E_FAILURE;
20204 
20205 	param->data = (uint32_t *)param_buf->data;
20206 	param->data_len = event->data_len;
20207 	param->error_status = event->error_status;
20208 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20209 								event->pdev_id);
20210 
20211 	return QDF_STATUS_SUCCESS;
20212 }
20213 
20214 /*
20215  * extract_peer_delete_response_event_tlv() - extract peer delete response event
20216  * @wmi_handle: wmi handle
20217  * @param evt_buf: pointer to event buffer
20218  * @param vdev_id: Pointer to hold vdev_id
20219  * @param mac_addr: Pointer to hold peer mac address
20220  *
20221  * Return: QDF_STATUS_SUCCESS for success or error code
20222  */
20223 static QDF_STATUS extract_peer_delete_response_event_tlv(wmi_unified_t wmi_hdl,
20224 	void *evt_buf, struct wmi_host_peer_delete_response_event *param)
20225 {
20226 	WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf;
20227 	wmi_peer_delete_resp_event_fixed_param *ev;
20228 
20229 	param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)evt_buf;
20230 
20231 	ev = (wmi_peer_delete_resp_event_fixed_param *) param_buf->fixed_param;
20232 	if (!ev) {
20233 		WMI_LOGE("%s: Invalid peer_delete response\n", __func__);
20234 		return QDF_STATUS_E_FAILURE;
20235 	}
20236 
20237 	param->vdev_id = ev->vdev_id;
20238 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr,
20239 			&param->mac_address.bytes[0]);
20240 
20241 	return QDF_STATUS_SUCCESS;
20242 }
20243 
20244 static bool is_management_record_tlv(uint32_t cmd_id)
20245 {
20246 	if ((cmd_id == WMI_MGMT_TX_COMPLETION_EVENTID) ||
20247 			(cmd_id == WMI_MGMT_TX_SEND_CMDID) ||
20248 			(cmd_id == WMI_OFFCHAN_DATA_TX_SEND_CMDID)) {
20249 		return true;
20250 	}
20251 
20252 	return false;
20253 }
20254 
20255 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf)
20256 {
20257 	wmi_vdev_set_param_cmd_fixed_param *set_cmd;
20258 
20259 	set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf);
20260 
20261 	switch (set_cmd->param_id) {
20262 	case WMI_VDEV_PARAM_LISTEN_INTERVAL:
20263 	case WMI_VDEV_PARAM_DTIM_POLICY:
20264 		return HTC_TX_PACKET_TAG_AUTO_PM;
20265 	default:
20266 		break;
20267 	}
20268 
20269 	return 0;
20270 }
20271 
20272 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf)
20273 {
20274 	wmi_sta_powersave_param_cmd_fixed_param *ps_cmd;
20275 
20276 	ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf);
20277 
20278 	switch (ps_cmd->param) {
20279 	case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD:
20280 	case WMI_STA_PS_PARAM_INACTIVITY_TIME:
20281 	case WMI_STA_PS_ENABLE_QPOWER:
20282 		return HTC_TX_PACKET_TAG_AUTO_PM;
20283 	default:
20284 		break;
20285 	}
20286 
20287 	return 0;
20288 }
20289 
20290 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf,
20291 				   uint32_t cmd_id)
20292 {
20293 	if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended))
20294 		return 0;
20295 
20296 	switch (cmd_id) {
20297 	case WMI_VDEV_SET_PARAM_CMDID:
20298 		return wmi_tag_vdev_set_cmd(wmi_hdl, buf);
20299 	case WMI_STA_POWERSAVE_PARAM_CMDID:
20300 		return wmi_tag_sta_powersave_cmd(wmi_hdl, buf);
20301 	default:
20302 		break;
20303 	}
20304 
20305 	return 0;
20306 }
20307 
20308 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle)
20309 {
20310 	uint16_t tag = 0;
20311 
20312 	if (qdf_atomic_read(&wmi_handle->is_target_suspended)) {
20313 		pr_err("%s: Target is already suspended, Ignore FW Hang Command\n",
20314 			__func__);
20315 		return tag;
20316 	}
20317 
20318 	if (wmi_handle->tag_crash_inject)
20319 		tag = HTC_TX_PACKET_TAG_AUTO_PM;
20320 
20321 	wmi_handle->tag_crash_inject = false;
20322 	return tag;
20323 }
20324 
20325 /**
20326  * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands
20327  * @wmi_handle: WMI handle
20328  * @buf:	WMI buffer
20329  * @cmd_id:	WMI command Id
20330  *
20331  * Return htc_tx_tag
20332  */
20333 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle,
20334 				wmi_buf_t buf,
20335 				uint32_t cmd_id)
20336 {
20337 	uint16_t htc_tx_tag = 0;
20338 
20339 	switch (cmd_id) {
20340 	case WMI_WOW_ENABLE_CMDID:
20341 	case WMI_PDEV_SUSPEND_CMDID:
20342 	case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID:
20343 	case WMI_WOW_ADD_WAKE_PATTERN_CMDID:
20344 	case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID:
20345 	case WMI_PDEV_RESUME_CMDID:
20346 	case WMI_WOW_DEL_WAKE_PATTERN_CMDID:
20347 	case WMI_WOW_SET_ACTION_WAKE_UP_CMDID:
20348 #ifdef FEATURE_WLAN_D0WOW
20349 	case WMI_D0_WOW_ENABLE_DISABLE_CMDID:
20350 #endif
20351 		htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM;
20352 		break;
20353 	case WMI_FORCE_FW_HANG_CMDID:
20354 		htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle);
20355 		break;
20356 	case WMI_VDEV_SET_PARAM_CMDID:
20357 	case WMI_STA_POWERSAVE_PARAM_CMDID:
20358 		htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id);
20359 	default:
20360 		break;
20361 	}
20362 
20363 	return htc_tx_tag;
20364 }
20365 
20366 /**
20367  * extract_channel_hopping_event_tlv() - extract channel hopping param
20368  * from event
20369  * @wmi_handle: wmi handle
20370  * @param evt_buf: pointer to event buffer
20371  * @param ch_hopping: Pointer to hold channel hopping param
20372  *
20373  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20374  */
20375 static QDF_STATUS extract_channel_hopping_event_tlv(
20376 	wmi_unified_t wmi_handle, void *evt_buf,
20377 	wmi_host_pdev_channel_hopping_event *ch_hopping)
20378 {
20379 	WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *param_buf;
20380 	wmi_pdev_channel_hopping_event_fixed_param *event;
20381 
20382 	param_buf = (WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *)evt_buf;
20383 	event = (wmi_pdev_channel_hopping_event_fixed_param *)
20384 						param_buf->fixed_param;
20385 
20386 	ch_hopping->noise_floor_report_iter = event->noise_floor_report_iter;
20387 	ch_hopping->noise_floor_total_iter = event->noise_floor_total_iter;
20388 	ch_hopping->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20389 								event->pdev_id);
20390 
20391 	return QDF_STATUS_SUCCESS;
20392 }
20393 
20394 /**
20395  * extract_pdev_tpc_ev_param_tlv() - extract tpc param from event
20396  * @wmi_handle: wmi handle
20397  * @param evt_buf: pointer to event buffer
20398  * @param param: Pointer to hold tpc param
20399  *
20400  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20401  */
20402 static QDF_STATUS extract_pdev_tpc_ev_param_tlv(wmi_unified_t wmi_handle,
20403 		void *evt_buf,
20404 		wmi_host_pdev_tpc_event *param)
20405 {
20406 	WMI_PDEV_TPC_EVENTID_param_tlvs *param_buf;
20407 	wmi_pdev_tpc_event_fixed_param *event;
20408 
20409 	param_buf = (WMI_PDEV_TPC_EVENTID_param_tlvs *)evt_buf;
20410 	event = (wmi_pdev_tpc_event_fixed_param *)param_buf->fixed_param;
20411 
20412 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20413 								event->pdev_id);
20414 	qdf_mem_copy(param->tpc, param_buf->tpc, sizeof(param->tpc));
20415 
20416 	return QDF_STATUS_SUCCESS;
20417 }
20418 
20419 /**
20420  * extract_nfcal_power_ev_param_tlv() - extract noise floor calibration
20421  * power param from event
20422  * @wmi_handle: wmi handle
20423  * @param evt_buf: pointer to event buffer
20424  * @param param: Pointer to hold nf cal power param
20425  *
20426  * Return: 0 for success or error code
20427  */
20428 static QDF_STATUS
20429 extract_nfcal_power_ev_param_tlv(wmi_unified_t wmi_handle,
20430 				 void *evt_buf,
20431 				 wmi_host_pdev_nfcal_power_all_channels_event *param)
20432 {
20433 	WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *param_buf;
20434 	wmi_pdev_nfcal_power_all_channels_event_fixed_param *event;
20435 	wmi_pdev_nfcal_power_all_channels_nfdBr *ch_nfdbr;
20436 	wmi_pdev_nfcal_power_all_channels_nfdBm *ch_nfdbm;
20437 	wmi_pdev_nfcal_power_all_channels_freqNum *ch_freqnum;
20438 	uint32_t i;
20439 
20440 	param_buf =
20441 		(WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *)evt_buf;
20442 	event = param_buf->fixed_param;
20443 	ch_nfdbr = param_buf->nfdbr;
20444 	ch_nfdbm = param_buf->nfdbm;
20445 	ch_freqnum = param_buf->freqnum;
20446 
20447 	WMI_LOGD("pdev_id[%x], num_nfdbr[%d], num_nfdbm[%d] num_freqnum[%d]\n",
20448 		 event->pdev_id, param_buf->num_nfdbr,
20449 		 param_buf->num_nfdbm, param_buf->num_freqnum);
20450 
20451 	if (param_buf->num_nfdbr >
20452 	    WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) {
20453 		WMI_LOGE("invalid number of nfdBr");
20454 		return QDF_STATUS_E_FAILURE;
20455 	}
20456 
20457 	if (param_buf->num_nfdbm >
20458 	    WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) {
20459 		WMI_LOGE("invalid number of nfdBm");
20460 		return QDF_STATUS_E_FAILURE;
20461 	}
20462 
20463 	if (param_buf->num_freqnum > WMI_HOST_RXG_CAL_CHAN_MAX) {
20464 		WMI_LOGE("invalid number of freqNum");
20465 		return QDF_STATUS_E_FAILURE;
20466 	}
20467 
20468 	for (i = 0; i < param_buf->num_nfdbr; i++) {
20469 		param->nfdbr[i] = (int8_t)ch_nfdbr->nfdBr;
20470 		param->nfdbm[i] = (int8_t)ch_nfdbm->nfdBm;
20471 		ch_nfdbr++;
20472 		ch_nfdbm++;
20473 	}
20474 
20475 	for (i = 0; i < param_buf->num_freqnum; i++) {
20476 		param->freqnum[i] = ch_freqnum->freqNum;
20477 		ch_freqnum++;
20478 	}
20479 
20480 	param->pdev_id = wmi_handle->ops->
20481 		convert_pdev_id_target_to_host(event->pdev_id);
20482 
20483 	return QDF_STATUS_SUCCESS;
20484 }
20485 
20486 
20487 #ifdef BIG_ENDIAN_HOST
20488 /**
20489  * wds_addr_ev_conv_data_be() - LE to BE conversion of wds addr event
20490  * @param data_len - data length
20491  * @param data - pointer to data
20492  *
20493  * Return: QDF_STATUS - success or error status
20494  */
20495 static QDF_STATUS wds_addr_ev_conv_data_be(uint16_t data_len, uint8_t *ev)
20496 {
20497 	uint8_t *datap = (uint8_t *)ev;
20498 	int i;
20499 	/* Skip swapping the first word */
20500 	datap += sizeof(uint32_t);
20501 	for (i = 0; i < ((data_len / sizeof(uint32_t))-1);
20502 			i++, datap += sizeof(uint32_t)) {
20503 		*(uint32_t *)datap = qdf_le32_to_cpu(*(uint32_t *)datap);
20504 	}
20505 
20506 	return QDF_STATUS_SUCCESS;
20507 }
20508 #else
20509 /**
20510  * wds_addr_ev_conv_data_be() - Dummy operation for LE platforms
20511  * @param data_len - data length
20512  * @param data - pointer to data
20513  *
20514  * Return: QDF_STATUS - success or error status
20515  */
20516 static QDF_STATUS wds_addr_ev_conv_data_be(uint32_t data_len, uint8_t *ev)
20517 {
20518 	return QDF_STATUS_SUCCESS;
20519 }
20520 #endif
20521 
20522 /**
20523  * extract_wds_addr_event_tlv() - extract wds address from event
20524  * @wmi_handle: wmi handle
20525  * @param evt_buf: pointer to event buffer
20526  * @param wds_ev: Pointer to hold wds address
20527  *
20528  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20529  */
20530 static QDF_STATUS extract_wds_addr_event_tlv(wmi_unified_t wmi_handle,
20531 		void *evt_buf,
20532 		uint16_t len, wds_addr_event_t *wds_ev)
20533 {
20534 	WMI_WDS_PEER_EVENTID_param_tlvs *param_buf;
20535 	wmi_wds_addr_event_fixed_param *ev;
20536 	int i;
20537 
20538 	param_buf = (WMI_WDS_PEER_EVENTID_param_tlvs *)evt_buf;
20539 	ev = (wmi_wds_addr_event_fixed_param *)param_buf->fixed_param;
20540 
20541 	if (wds_addr_ev_conv_data_be(len, (uint8_t *)ev) != QDF_STATUS_SUCCESS)
20542 		return QDF_STATUS_E_FAILURE;
20543 
20544 	qdf_mem_copy(wds_ev->event_type, ev->event_type,
20545 		     sizeof(wds_ev->event_type));
20546 	for (i = 0; i < 4; i++) {
20547 		wds_ev->peer_mac[i] =
20548 			((u_int8_t *)&(ev->peer_mac.mac_addr31to0))[i];
20549 		wds_ev->dest_mac[i] =
20550 			((u_int8_t *)&(ev->dest_mac.mac_addr31to0))[i];
20551 	}
20552 	for (i = 0; i < 2; i++) {
20553 		wds_ev->peer_mac[4+i] =
20554 			((u_int8_t *)&(ev->peer_mac.mac_addr47to32))[i];
20555 		wds_ev->dest_mac[4+i] =
20556 			((u_int8_t *)&(ev->dest_mac.mac_addr47to32))[i];
20557 	}
20558 	return QDF_STATUS_SUCCESS;
20559 }
20560 
20561 /**
20562  * extract_peer_sta_ps_statechange_ev_tlv() - extract peer sta ps state
20563  * from event
20564  * @wmi_handle: wmi handle
20565  * @param evt_buf: pointer to event buffer
20566  * @param ev: Pointer to hold peer param and ps state
20567  *
20568  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20569  */
20570 static QDF_STATUS extract_peer_sta_ps_statechange_ev_tlv(wmi_unified_t wmi_handle,
20571 		void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev)
20572 {
20573 	WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf;
20574 	wmi_peer_sta_ps_statechange_event_fixed_param *event;
20575 
20576 	param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)evt_buf;
20577 	event = (wmi_peer_sta_ps_statechange_event_fixed_param *)
20578 						param_buf->fixed_param;
20579 
20580 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, ev->peer_macaddr);
20581 	ev->peer_ps_state = event->peer_ps_state;
20582 
20583 	return QDF_STATUS_SUCCESS;
20584 }
20585 
20586 /**
20587  * extract_inst_rssi_stats_event_tlv() - extract inst rssi stats from event
20588  * @wmi_handle: wmi handle
20589  * @param evt_buf: pointer to event buffer
20590  * @param inst_rssi_resp: Pointer to hold inst rssi response
20591  *
20592  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20593  */
20594 static QDF_STATUS extract_inst_rssi_stats_event_tlv(
20595 	wmi_unified_t wmi_handle, void *evt_buf,
20596 	wmi_host_inst_stats_resp *inst_rssi_resp)
20597 {
20598 	WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf;
20599 	wmi_inst_rssi_stats_resp_fixed_param *event;
20600 
20601 	param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf;
20602 	event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param;
20603 
20604 	qdf_mem_copy(&(inst_rssi_resp->peer_macaddr),
20605 		     &(event->peer_macaddr), sizeof(wmi_mac_addr));
20606 	inst_rssi_resp->iRSSI = event->iRSSI;
20607 
20608 	return QDF_STATUS_SUCCESS;
20609 }
20610 
20611 static struct cur_reg_rule
20612 *create_reg_rules_from_wmi(uint32_t num_reg_rules,
20613 		wmi_regulatory_rule_struct *wmi_reg_rule)
20614 {
20615 	struct cur_reg_rule *reg_rule_ptr;
20616 	uint32_t count;
20617 
20618 	reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr));
20619 
20620 	if (NULL == reg_rule_ptr) {
20621 		WMI_LOGE("memory allocation failure");
20622 		return NULL;
20623 	}
20624 
20625 	for (count = 0; count < num_reg_rules; count++) {
20626 		reg_rule_ptr[count].start_freq =
20627 			WMI_REG_RULE_START_FREQ_GET(
20628 					wmi_reg_rule[count].freq_info);
20629 		reg_rule_ptr[count].end_freq =
20630 			WMI_REG_RULE_END_FREQ_GET(
20631 					wmi_reg_rule[count].freq_info);
20632 		reg_rule_ptr[count].max_bw =
20633 			WMI_REG_RULE_MAX_BW_GET(
20634 					wmi_reg_rule[count].bw_pwr_info);
20635 		reg_rule_ptr[count].reg_power =
20636 			WMI_REG_RULE_REG_POWER_GET(
20637 					wmi_reg_rule[count].bw_pwr_info);
20638 		reg_rule_ptr[count].ant_gain =
20639 			WMI_REG_RULE_ANTENNA_GAIN_GET(
20640 					wmi_reg_rule[count].bw_pwr_info);
20641 		reg_rule_ptr[count].flags =
20642 			WMI_REG_RULE_FLAGS_GET(
20643 					wmi_reg_rule[count].flag_info);
20644 	}
20645 
20646 	return reg_rule_ptr;
20647 }
20648 
20649 static QDF_STATUS extract_reg_chan_list_update_event_tlv(
20650 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
20651 	struct cur_regulatory_info *reg_info, uint32_t len)
20652 {
20653 	WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf;
20654 	wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr;
20655 	wmi_regulatory_rule_struct *wmi_reg_rule;
20656 	uint32_t num_2g_reg_rules, num_5g_reg_rules;
20657 
20658 	WMI_LOGD("processing regulatory channel list");
20659 
20660 	param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf;
20661 	if (!param_buf) {
20662 		WMI_LOGE("invalid channel list event buf");
20663 		return QDF_STATUS_E_FAILURE;
20664 	}
20665 
20666 	chan_list_event_hdr = param_buf->fixed_param;
20667 
20668 	reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules;
20669 	reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules;
20670 	qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2),
20671 		     REG_ALPHA2_LEN);
20672 	reg_info->dfs_region = chan_list_event_hdr->dfs_region;
20673 	reg_info->phybitmap = chan_list_event_hdr->phybitmap;
20674 	reg_info->offload_enabled = true;
20675 	reg_info->num_phy = chan_list_event_hdr->num_phy;
20676 	reg_info->phy_id = chan_list_event_hdr->phy_id;
20677 	reg_info->ctry_code = chan_list_event_hdr->country_id;
20678 	reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code;
20679 	if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS)
20680 		reg_info->status_code = REG_SET_CC_STATUS_PASS;
20681 	else if (chan_list_event_hdr->status_code ==
20682 		 WMI_REG_CURRENT_ALPHA2_NOT_FOUND)
20683 		reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND;
20684 	else if (chan_list_event_hdr->status_code ==
20685 		 WMI_REG_INIT_ALPHA2_NOT_FOUND)
20686 		reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND;
20687 	else if (chan_list_event_hdr->status_code ==
20688 		 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED)
20689 		reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED;
20690 	else if (chan_list_event_hdr->status_code ==
20691 		 WMI_REG_SET_CC_STATUS_NO_MEMORY)
20692 		reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY;
20693 	else if (chan_list_event_hdr->status_code ==
20694 		 WMI_REG_SET_CC_STATUS_FAIL)
20695 		reg_info->status_code = REG_SET_CC_STATUS_FAIL;
20696 
20697 	reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g;
20698 	reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g;
20699 	reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g;
20700 	reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g;
20701 
20702 	num_2g_reg_rules = reg_info->num_2g_reg_rules;
20703 	num_5g_reg_rules = reg_info->num_5g_reg_rules;
20704 
20705 	WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d",
20706 			__func__, reg_info->alpha2, reg_info->dfs_region,
20707 			reg_info->min_bw_2g, reg_info->max_bw_2g,
20708 			reg_info->min_bw_5g, reg_info->max_bw_5g);
20709 
20710 	WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__,
20711 			num_2g_reg_rules, num_5g_reg_rules);
20712 	wmi_reg_rule =
20713 		(wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr
20714 			+ sizeof(wmi_reg_chan_list_cc_event_fixed_param)
20715 			+ WMI_TLV_HDR_SIZE);
20716 	reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules,
20717 			wmi_reg_rule);
20718 	wmi_reg_rule += num_2g_reg_rules;
20719 
20720 	reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules,
20721 			wmi_reg_rule);
20722 
20723 	WMI_LOGD("processed regulatory channel list");
20724 
20725 	return QDF_STATUS_SUCCESS;
20726 }
20727 
20728 static QDF_STATUS extract_reg_11d_new_country_event_tlv(
20729 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
20730 	struct reg_11d_new_country *reg_11d_country, uint32_t len)
20731 {
20732 	wmi_11d_new_country_event_fixed_param *reg_11d_country_event;
20733 	WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf;
20734 
20735 	param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf;
20736 	if (!param_buf) {
20737 		WMI_LOGE("invalid 11d country event buf");
20738 		return QDF_STATUS_E_FAILURE;
20739 	}
20740 
20741 	reg_11d_country_event = param_buf->fixed_param;
20742 
20743 	qdf_mem_copy(reg_11d_country->alpha2,
20744 			&reg_11d_country_event->new_alpha2, REG_ALPHA2_LEN);
20745 
20746 	WMI_LOGD("processed 11d country event, new cc %s",
20747 			reg_11d_country->alpha2);
20748 
20749 	return QDF_STATUS_SUCCESS;
20750 }
20751 
20752 static QDF_STATUS extract_reg_ch_avoid_event_tlv(
20753 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
20754 	struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len)
20755 {
20756 	wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param;
20757 	wmi_avoid_freq_range_desc *afr_desc;
20758 	uint32_t num_freq_ranges, freq_range_idx;
20759 	WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf =
20760 		(WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf;
20761 
20762 	if (!param_buf) {
20763 		WMI_LOGE("Invalid channel avoid event buffer");
20764 		return QDF_STATUS_E_INVAL;
20765 	}
20766 
20767 	afr_fixed_param = param_buf->fixed_param;
20768 	if (!afr_fixed_param) {
20769 		WMI_LOGE("Invalid channel avoid event fixed param buffer");
20770 		return QDF_STATUS_E_INVAL;
20771 	}
20772 
20773 	if (!ch_avoid_ind) {
20774 		WMI_LOGE("Invalid channel avoid indication buffer");
20775 		return QDF_STATUS_E_INVAL;
20776 	}
20777 	num_freq_ranges = (afr_fixed_param->num_freq_ranges >
20778 			CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE :
20779 			afr_fixed_param->num_freq_ranges;
20780 
20781 	WMI_LOGD("Channel avoid event received with %d ranges",
20782 		 num_freq_ranges);
20783 
20784 	ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges;
20785 	afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range);
20786 	for (freq_range_idx = 0; freq_range_idx < num_freq_ranges;
20787 	     freq_range_idx++) {
20788 		ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq =
20789 			afr_desc->start_freq;
20790 		ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq =
20791 			afr_desc->end_freq;
20792 		WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u",
20793 				freq_range_idx, afr_desc->tlv_header,
20794 				afr_desc->start_freq, afr_desc->end_freq);
20795 		afr_desc++;
20796 	}
20797 
20798 	return QDF_STATUS_SUCCESS;
20799 }
20800 #ifdef DFS_COMPONENT_ENABLE
20801 /**
20802  * extract_dfs_cac_complete_event_tlv() - extract cac complete event
20803  * @wmi_handle: wma handle
20804  * @evt_buf: event buffer
20805  * @vdev_id: vdev id
20806  * @len: length of buffer
20807  *
20808  * Return: 0 for success or error code
20809  */
20810 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle,
20811 		uint8_t *evt_buf,
20812 		uint32_t *vdev_id,
20813 		uint32_t len)
20814 {
20815 	WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs;
20816 	wmi_vdev_dfs_cac_complete_event_fixed_param  *cac_event;
20817 
20818 	param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf;
20819 	if (!param_tlvs) {
20820 		WMI_LOGE("invalid cac complete event buf");
20821 		return QDF_STATUS_E_FAILURE;
20822 	}
20823 
20824 	cac_event = param_tlvs->fixed_param;
20825 	*vdev_id = cac_event->vdev_id;
20826 	WMI_LOGD("processed cac complete event vdev %d", *vdev_id);
20827 
20828 	return QDF_STATUS_SUCCESS;
20829 }
20830 
20831 /**
20832  * extract_dfs_radar_detection_event_tlv() - extract radar found event
20833  * @wmi_handle: wma handle
20834  * @evt_buf: event buffer
20835  * @radar_found: radar found event info
20836  * @len: length of buffer
20837  *
20838  * Return: 0 for success or error code
20839  */
20840 static QDF_STATUS extract_dfs_radar_detection_event_tlv(
20841 		wmi_unified_t wmi_handle,
20842 		uint8_t *evt_buf,
20843 		struct radar_found_info *radar_found,
20844 		uint32_t len)
20845 {
20846 	WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv;
20847 	wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event;
20848 
20849 	param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf;
20850 	if (!param_tlv) {
20851 		WMI_LOGE("invalid radar detection event buf");
20852 		return QDF_STATUS_E_FAILURE;
20853 	}
20854 
20855 	radar_event = param_tlv->fixed_param;
20856 	radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id(
20857 			radar_event->pdev_id);
20858 	radar_found->detection_mode = radar_event->detection_mode;
20859 	radar_found->chan_freq = radar_event->chan_freq;
20860 	radar_found->chan_width = radar_event->chan_width;
20861 	radar_found->detector_id = radar_event->detector_id;
20862 	radar_found->segment_id = radar_event->segment_id;
20863 	radar_found->timestamp = radar_event->timestamp;
20864 	radar_found->is_chirp = radar_event->is_chirp;
20865 	radar_found->freq_offset = radar_event->freq_offset;
20866 	radar_found->sidx = radar_event->sidx;
20867 
20868 	WMI_LOGI("processed radar found event pdev %d,"
20869 		"Radar Event Info:pdev_id %d,timestamp %d,chan_freq  (dur) %d,"
20870 		"chan_width (RSSI) %d,detector_id (false_radar) %d,"
20871 		"freq_offset (radar_check) %d,segment_id %d,sidx %d,"
20872 		"is_chirp %d,detection mode %d\n",
20873 		radar_event->pdev_id, radar_found->pdev_id,
20874 		radar_event->timestamp, radar_event->chan_freq,
20875 		radar_event->chan_width, radar_event->detector_id,
20876 		radar_event->freq_offset, radar_event->segment_id,
20877 		radar_event->sidx, radar_event->is_chirp,
20878 		radar_event->detection_mode);
20879 
20880 	return QDF_STATUS_SUCCESS;
20881 }
20882 
20883 #ifdef QCA_MCL_DFS_SUPPORT
20884 /**
20885  * extract_wlan_radar_event_info_tlv() - extract radar pulse event
20886  * @wmi_handle: wma handle
20887  * @evt_buf: event buffer
20888  * @wlan_radar_event: Pointer to struct radar_event_info
20889  * @len: length of buffer
20890  *
20891  * Return: QDF_STATUS
20892  */
20893 static QDF_STATUS extract_wlan_radar_event_info_tlv(
20894 		wmi_unified_t wmi_handle,
20895 		uint8_t *evt_buf,
20896 		struct radar_event_info *wlan_radar_event,
20897 		uint32_t len)
20898 {
20899 	WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv;
20900 	wmi_dfs_radar_event_fixed_param *radar_event;
20901 
20902 	param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf;
20903 	if (!param_tlv) {
20904 		WMI_LOGE("invalid wlan radar event buf");
20905 		return QDF_STATUS_E_FAILURE;
20906 	}
20907 
20908 	radar_event = param_tlv->fixed_param;
20909 	wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp;
20910 	wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq;
20911 	wlan_radar_event->pulse_duration = radar_event->pulse_duration;
20912 	wlan_radar_event->rssi = radar_event->rssi;
20913 	wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts;
20914 	wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high;
20915 	wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low;
20916 	wlan_radar_event->peak_sidx = radar_event->peak_sidx;
20917 	wlan_radar_event->delta_peak = radar_event->pulse_delta_peak;
20918 	wlan_radar_event->delta_diff = radar_event->pulse_delta_diff;
20919 	if (radar_event->pulse_flags &
20920 			WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) {
20921 		wlan_radar_event->is_psidx_diff_valid = true;
20922 		wlan_radar_event->psidx_diff = radar_event->psidx_diff;
20923 	} else {
20924 		wlan_radar_event->is_psidx_diff_valid = false;
20925 	}
20926 
20927 	wlan_radar_event->pdev_id = radar_event->pdev_id;
20928 
20929 	return QDF_STATUS_SUCCESS;
20930 }
20931 #else
20932 static QDF_STATUS extract_wlan_radar_event_info_tlv(
20933 		wmi_unified_t wmi_handle,
20934 		uint8_t *evt_buf,
20935 		struct radar_event_info *wlan_radar_event,
20936 		uint32_t len)
20937 {
20938 	return QDF_STATUS_SUCCESS;
20939 }
20940 #endif
20941 #endif
20942 
20943 /**
20944  * send_get_rcpi_cmd_tlv() - send request for rcpi value
20945  * @wmi_handle: wmi handle
20946  * @get_rcpi_param: rcpi params
20947  *
20948  * Return: QDF status
20949  */
20950 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle,
20951 					struct rcpi_req  *get_rcpi_param)
20952 {
20953 	wmi_buf_t buf;
20954 	wmi_request_rcpi_cmd_fixed_param *cmd;
20955 	uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param);
20956 
20957 	buf = wmi_buf_alloc(wmi_handle, len);
20958 	if (!buf) {
20959 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
20960 		return QDF_STATUS_E_NOMEM;
20961 	}
20962 
20963 	cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf);
20964 	WMITLV_SET_HDR(&cmd->tlv_header,
20965 		       WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param,
20966 		       WMITLV_GET_STRUCT_TLVLEN
20967 		       (wmi_request_rcpi_cmd_fixed_param));
20968 
20969 	cmd->vdev_id = get_rcpi_param->vdev_id;
20970 	WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr,
20971 				   &cmd->peer_macaddr);
20972 
20973 	switch (get_rcpi_param->measurement_type) {
20974 
20975 	case RCPI_MEASUREMENT_TYPE_AVG_MGMT:
20976 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT;
20977 		break;
20978 
20979 	case RCPI_MEASUREMENT_TYPE_AVG_DATA:
20980 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA;
20981 		break;
20982 
20983 	case RCPI_MEASUREMENT_TYPE_LAST_MGMT:
20984 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT;
20985 		break;
20986 
20987 	case RCPI_MEASUREMENT_TYPE_LAST_DATA:
20988 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA;
20989 		break;
20990 
20991 	default:
20992 		/*
20993 		 * invalid rcpi measurement type, fall back to
20994 		 * RCPI_MEASUREMENT_TYPE_AVG_MGMT
20995 		 */
20996 		cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT;
20997 		break;
20998 	}
20999 	WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id);
21000 	wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0);
21001 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21002 				 WMI_REQUEST_RCPI_CMDID)) {
21003 
21004 		WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID",
21005 			 __func__);
21006 		wmi_buf_free(buf);
21007 		return QDF_STATUS_E_FAILURE;
21008 	}
21009 
21010 	return QDF_STATUS_SUCCESS;
21011 }
21012 
21013 /**
21014  * extract_rcpi_response_event_tlv() - Extract RCPI event params
21015  * @wmi_handle: wmi handle
21016  * @evt_buf: pointer to event buffer
21017  * @res: pointer to hold rcpi response from firmware
21018  *
21019  * Return: QDF_STATUS_SUCCESS for successful event parse
21020  *         else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE
21021  */
21022 static QDF_STATUS
21023 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle,
21024 				void *evt_buf, struct rcpi_res *res)
21025 {
21026 	WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf;
21027 	wmi_update_rcpi_event_fixed_param *event;
21028 
21029 	param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf;
21030 	if (!param_buf) {
21031 		WMI_LOGE(FL("Invalid rcpi event"));
21032 		return QDF_STATUS_E_INVAL;
21033 	}
21034 
21035 	event = param_buf->fixed_param;
21036 	res->vdev_id = event->vdev_id;
21037 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr);
21038 
21039 	switch (event->measurement_type) {
21040 
21041 	case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT:
21042 		res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT;
21043 		break;
21044 
21045 	case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA:
21046 		res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA;
21047 		break;
21048 
21049 	case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT:
21050 		res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT;
21051 		break;
21052 
21053 	case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA:
21054 		res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA;
21055 		break;
21056 
21057 	default:
21058 		WMI_LOGE(FL("Invalid rcpi measurement type from firmware"));
21059 		res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID;
21060 		return QDF_STATUS_E_FAILURE;
21061 	}
21062 
21063 	if (event->status)
21064 		return QDF_STATUS_E_FAILURE;
21065 	else
21066 		return QDF_STATUS_SUCCESS;
21067 }
21068 
21069 /**
21070  * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from
21071  *           host to target defines. For legacy there is not conversion
21072  *           required. Just return pdev_id as it is.
21073  * @param pdev_id: host pdev_id to be converted.
21074  * Return: target pdev_id after conversion.
21075  */
21076 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy(
21077 							uint32_t pdev_id)
21078 {
21079 	if (pdev_id == WMI_HOST_PDEV_ID_SOC)
21080 		return WMI_PDEV_ID_SOC;
21081 
21082 	/*No conversion required*/
21083 	return pdev_id;
21084 }
21085 
21086 /**
21087  * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from
21088  *           target to host defines. For legacy there is not conversion
21089  *           required. Just return pdev_id as it is.
21090  * @param pdev_id: target pdev_id to be converted.
21091  * Return: host pdev_id after conversion.
21092  */
21093 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy(
21094 							uint32_t pdev_id)
21095 {
21096 	/*No conversion required*/
21097 	return pdev_id;
21098 }
21099 
21100 /**
21101  *  send_set_country_cmd_tlv() - WMI scan channel list function
21102  *  @param wmi_handle      : handle to WMI.
21103  *  @param param    : pointer to hold scan channel list parameter
21104  *
21105  *  Return: 0  on success and -ve on failure.
21106  */
21107 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle,
21108 				struct set_country *params)
21109 {
21110 	wmi_buf_t buf;
21111 	QDF_STATUS qdf_status;
21112 	wmi_set_current_country_cmd_fixed_param *cmd;
21113 	uint16_t len = sizeof(*cmd);
21114 
21115 	buf = wmi_buf_alloc(wmi_handle, len);
21116 	if (!buf) {
21117 		WMI_LOGE("Failed to allocate memory");
21118 		qdf_status = QDF_STATUS_E_NOMEM;
21119 		goto end;
21120 	}
21121 
21122 	cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf);
21123 	WMITLV_SET_HDR(&cmd->tlv_header,
21124 		       WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param,
21125 		       WMITLV_GET_STRUCT_TLVLEN
21126 			       (wmi_set_current_country_cmd_fixed_param));
21127 
21128 	WMI_LOGD("setting cuurnet country to  %s", params->country);
21129 
21130 	qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3);
21131 
21132 	cmd->pdev_id = params->pdev_id;
21133 
21134 	wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0);
21135 	qdf_status = wmi_unified_cmd_send(wmi_handle,
21136 			buf, len, WMI_SET_CURRENT_COUNTRY_CMDID);
21137 
21138 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
21139 		WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID");
21140 		wmi_buf_free(buf);
21141 	}
21142 
21143 end:
21144 	return qdf_status;
21145 }
21146 
21147 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2)          do { \
21148 	    WMI_SET_BITS(alpha, 0, 8, val0); \
21149 	    WMI_SET_BITS(alpha, 8, 8, val1); \
21150 	    WMI_SET_BITS(alpha, 16, 8, val2); \
21151 	    } while (0)
21152 
21153 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle,
21154 		uint8_t pdev_id, struct cc_regdmn_s *rd)
21155 {
21156 	wmi_set_init_country_cmd_fixed_param *cmd;
21157 	uint16_t len;
21158 	wmi_buf_t buf;
21159 	int ret;
21160 
21161 	len = sizeof(wmi_set_init_country_cmd_fixed_param);
21162 	buf = wmi_buf_alloc(wmi_handle, len);
21163 	if (!buf) {
21164 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
21165 		return QDF_STATUS_E_NOMEM;
21166 	}
21167 	cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf);
21168 	WMITLV_SET_HDR(&cmd->tlv_header,
21169 			WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param,
21170 			WMITLV_GET_STRUCT_TLVLEN
21171 			(wmi_set_init_country_cmd_fixed_param));
21172 
21173 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
21174 
21175 	if (rd->flags == CC_IS_SET) {
21176 		cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID;
21177 		cmd->country_code.country_id = rd->cc.country_code;
21178 	} else if (rd->flags == ALPHA_IS_SET) {
21179 		cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2;
21180 		WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2,
21181 				rd->cc.alpha[0],
21182 				rd->cc.alpha[1],
21183 				rd->cc.alpha[2]);
21184 	} else if (rd->flags == REGDMN_IS_SET) {
21185 		cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE;
21186 		cmd->country_code.domain_code = rd->cc.regdmn_id;
21187 	}
21188 
21189 	wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0);
21190 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
21191 			WMI_SET_INIT_COUNTRY_CMDID);
21192 	if (ret) {
21193 		WMI_LOGE("Failed to config wow wakeup event");
21194 		wmi_buf_free(buf);
21195 		return QDF_STATUS_E_FAILURE;
21196 	}
21197 
21198 	return QDF_STATUS_SUCCESS;
21199 }
21200 
21201 /**
21202  * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan
21203  * configuration params
21204  * @wmi_handle: wmi handler
21205  * @limit_off_chan_param: pointer to wmi_off_chan_param
21206  *
21207  * Return: 0 for success and non zero for failure
21208  */
21209 static
21210 QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle,
21211 		struct wmi_limit_off_chan_param *limit_off_chan_param)
21212 {
21213 	wmi_vdev_limit_offchan_cmd_fixed_param *cmd;
21214 	wmi_buf_t buf;
21215 	uint32_t len = sizeof(*cmd);
21216 	int err;
21217 
21218 	buf = wmi_buf_alloc(wmi_handle, len);
21219 	if (!buf) {
21220 		WMI_LOGP("%s: failed to allocate memory for limit off chan cmd",
21221 				__func__);
21222 		return QDF_STATUS_E_NOMEM;
21223 	}
21224 
21225 	cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf);
21226 
21227 	WMITLV_SET_HDR(&cmd->tlv_header,
21228 			WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param,
21229 			WMITLV_GET_STRUCT_TLVLEN(
21230 				wmi_vdev_limit_offchan_cmd_fixed_param));
21231 
21232 	cmd->vdev_id = limit_off_chan_param->vdev_id;
21233 
21234 	cmd->flags &= 0;
21235 	if (limit_off_chan_param->status)
21236 		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE;
21237 	if (limit_off_chan_param->skip_dfs_chans)
21238 		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS;
21239 
21240 	cmd->max_offchan_time = limit_off_chan_param->max_offchan_time;
21241 	cmd->rest_time = limit_off_chan_param->rest_time;
21242 
21243 	WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d",
21244 			__func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time,
21245 			cmd->rest_time);
21246 
21247 	wmi_mtrace(WMI_VDEV_LIMIT_OFFCHAN_CMDID, cmd->vdev_id, 0);
21248 	err = wmi_unified_cmd_send(wmi_handle, buf,
21249 			len, WMI_VDEV_LIMIT_OFFCHAN_CMDID);
21250 	if (QDF_IS_STATUS_ERROR(err)) {
21251 		WMI_LOGE("Failed to send limit off chan cmd err=%d", err);
21252 		wmi_buf_free(buf);
21253 		return QDF_STATUS_E_FAILURE;
21254 	}
21255 
21256 	return QDF_STATUS_SUCCESS;
21257 }
21258 
21259 /**
21260  * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request
21261  * @wmi_handle: wmi handler
21262  * @req_buf: set arp stats request buffer
21263  *
21264  * Return: 0 for success and non zero for failure
21265  */
21266 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
21267 					  struct set_arp_stats *req_buf)
21268 {
21269 	wmi_buf_t buf = NULL;
21270 	QDF_STATUS status;
21271 	int len;
21272 	uint8_t *buf_ptr;
21273 	wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp;
21274 
21275 	len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
21276 	if (req_buf->pkt_type_bitmap) {
21277 		len += WMI_TLV_HDR_SIZE;
21278 		len += sizeof(wmi_vdev_set_connectivity_check_stats);
21279 	}
21280 	buf = wmi_buf_alloc(wmi_handle, len);
21281 	if (!buf) {
21282 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
21283 		return QDF_STATUS_E_NOMEM;
21284 	}
21285 
21286 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21287 	wmi_set_arp =
21288 		(wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr;
21289 	WMITLV_SET_HDR(&wmi_set_arp->tlv_header,
21290 		       WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param,
21291 		       WMITLV_GET_STRUCT_TLVLEN
21292 		       (wmi_vdev_set_arp_stats_cmd_fixed_param));
21293 
21294 	/* fill in per roam config values */
21295 	wmi_set_arp->vdev_id = req_buf->vdev_id;
21296 
21297 	wmi_set_arp->set_clr = req_buf->flag;
21298 	wmi_set_arp->pkt_type = req_buf->pkt_type;
21299 	wmi_set_arp->ipv4 = req_buf->ip_addr;
21300 
21301 	WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u",
21302 			 wmi_set_arp->vdev_id, wmi_set_arp->set_clr,
21303 			 wmi_set_arp->pkt_type, wmi_set_arp->ipv4);
21304 
21305 	/*
21306 	 * pkt_type_bitmap should be non-zero to ensure
21307 	 * presence of additional stats.
21308 	 */
21309 	if (req_buf->pkt_type_bitmap) {
21310 		wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats;
21311 
21312 		buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
21313 		WMITLV_SET_HDR(buf_ptr,
21314 			   WMITLV_TAG_ARRAY_STRUC,
21315 			   sizeof(wmi_vdev_set_connectivity_check_stats));
21316 		buf_ptr += WMI_TLV_HDR_SIZE;
21317 		wmi_set_connect_stats =
21318 			(wmi_vdev_set_connectivity_check_stats *)buf_ptr;
21319 		WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header,
21320 			WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats,
21321 			WMITLV_GET_STRUCT_TLVLEN(
21322 					wmi_vdev_set_connectivity_check_stats));
21323 		wmi_set_connect_stats->pkt_type_bitmap =
21324 						req_buf->pkt_type_bitmap;
21325 		wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port;
21326 		wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port;
21327 		wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4;
21328 
21329 		WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u",
21330 			 wmi_set_connect_stats->pkt_type_bitmap,
21331 			 wmi_set_connect_stats->tcp_src_port,
21332 			 wmi_set_connect_stats->tcp_dst_port,
21333 			 wmi_set_connect_stats->icmp_ipv4);
21334 	}
21335 
21336 	/* Send per roam config parameters */
21337 	wmi_mtrace(WMI_VDEV_SET_ARP_STAT_CMDID, NO_SESSION, 0);
21338 	status = wmi_unified_cmd_send(wmi_handle, buf,
21339 				      len, WMI_VDEV_SET_ARP_STAT_CMDID);
21340 	if (QDF_IS_STATUS_ERROR(status)) {
21341 		WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d",
21342 			 status);
21343 		goto error;
21344 	}
21345 
21346 	WMI_LOGD(FL("set arp stats flag=%d, vdev=%d"),
21347 		 req_buf->flag, req_buf->vdev_id);
21348 	return QDF_STATUS_SUCCESS;
21349 error:
21350 	wmi_buf_free(buf);
21351 
21352 	return status;
21353 }
21354 
21355 /**
21356  * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request
21357  * @wmi_handle: wmi handler
21358  * @req_buf: get arp stats request buffer
21359  *
21360  * Return: 0 for success and non zero for failure
21361  */
21362 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
21363 					  struct get_arp_stats *req_buf)
21364 {
21365 	wmi_buf_t buf = NULL;
21366 	QDF_STATUS status;
21367 	int len;
21368 	uint8_t *buf_ptr;
21369 	wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats;
21370 
21371 	len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param);
21372 	buf = wmi_buf_alloc(wmi_handle, len);
21373 	if (!buf) {
21374 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
21375 		return QDF_STATUS_E_NOMEM;
21376 	}
21377 
21378 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21379 	get_arp_stats =
21380 		(wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr;
21381 	WMITLV_SET_HDR(&get_arp_stats->tlv_header,
21382 		       WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param,
21383 		       WMITLV_GET_STRUCT_TLVLEN
21384 		       (wmi_vdev_get_arp_stats_cmd_fixed_param));
21385 
21386 	/* fill in arp stats req cmd values */
21387 	get_arp_stats->vdev_id = req_buf->vdev_id;
21388 
21389 	WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id);
21390 	/* Send per roam config parameters */
21391 	wmi_mtrace(WMI_VDEV_GET_ARP_STAT_CMDID, NO_SESSION, 0);
21392 	status = wmi_unified_cmd_send(wmi_handle, buf,
21393 				      len, WMI_VDEV_GET_ARP_STAT_CMDID);
21394 	if (QDF_IS_STATUS_ERROR(status)) {
21395 		WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d",
21396 			 status);
21397 		goto error;
21398 	}
21399 
21400 	return QDF_STATUS_SUCCESS;
21401 error:
21402 	wmi_buf_free(buf);
21403 
21404 	return status;
21405 }
21406 
21407 /**
21408  * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid
21409  * @wmi_handle: wmi handler
21410  * @pmk_info: pointer to PMK cache entry
21411  * @vdev_id: vdev id
21412  *
21413  * Return: 0 for success and non zero for failure
21414  */
21415 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle,
21416 				struct wmi_unified_pmk_cache *pmk_info)
21417 {
21418 	wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd;
21419 	wmi_buf_t buf;
21420 	QDF_STATUS status;
21421 	uint8_t *buf_ptr;
21422 	wmi_pmk_cache *pmksa;
21423 	uint32_t len = sizeof(*cmd);
21424 
21425 	if (pmk_info->pmk_len)
21426 		len += WMI_TLV_HDR_SIZE + sizeof(*pmksa);
21427 
21428 	buf = wmi_buf_alloc(wmi_handle, len);
21429 	if (!buf) {
21430 		WMI_LOGP("%s: failed to allocate memory for set del pmkid cache",
21431 			 __func__);
21432 		return QDF_STATUS_E_NOMEM;
21433 	}
21434 
21435 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21436 	cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr;
21437 
21438 	WMITLV_SET_HDR(&cmd->tlv_header,
21439 		 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param,
21440 		 WMITLV_GET_STRUCT_TLVLEN(
21441 			wmi_pdev_update_pmk_cache_cmd_fixed_param));
21442 
21443 	cmd->vdev_id = pmk_info->session_id;
21444 
21445 	/* If pmk_info->pmk_len is 0, this is a flush request */
21446 	if (!pmk_info->pmk_len) {
21447 		cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL;
21448 		cmd->num_cache = 0;
21449 		goto send_cmd;
21450 	}
21451 
21452 	cmd->num_cache = 1;
21453 	buf_ptr += sizeof(*cmd);
21454 
21455 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
21456 			sizeof(*pmksa));
21457 	buf_ptr += WMI_TLV_HDR_SIZE;
21458 
21459 	pmksa = (wmi_pmk_cache *)buf_ptr;
21460 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache,
21461 			WMITLV_GET_STRUCT_TLVLEN
21462 				(wmi_pmk_cache));
21463 	pmksa->pmk_len = pmk_info->pmk_len;
21464 	qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len);
21465 	pmksa->pmkid_len = pmk_info->pmkid_len;
21466 	qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len);
21467 	qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr));
21468 	pmksa->ssid.ssid_len = pmk_info->ssid.length;
21469 	qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid),
21470 			pmksa->ssid.ssid_len);
21471 	pmksa->cache_id = pmk_info->cache_id;
21472 	pmksa->cat_flag = pmk_info->cat_flag;
21473 	pmksa->action_flag = pmk_info->action_flag;
21474 
21475 send_cmd:
21476 	wmi_mtrace(WMI_PDEV_UPDATE_PMK_CACHE_CMDID, cmd->vdev_id, 0);
21477 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
21478 			WMI_PDEV_UPDATE_PMK_CACHE_CMDID);
21479 	if (status != QDF_STATUS_SUCCESS) {
21480 		WMI_LOGE("%s: failed to send set del pmkid cache command %d",
21481 			 __func__, status);
21482 		wmi_buf_free(buf);
21483 	}
21484 
21485 	return status;
21486 }
21487 
21488 /**
21489  * send_pdev_caldata_version_check_cmd_tlv() - send caldata check cmd to fw
21490  * @wmi_handle: wmi handle
21491  * @param:	reserved param
21492  *
21493  * Return: 0 for success or error code
21494  */
21495 static QDF_STATUS
21496 send_pdev_caldata_version_check_cmd_tlv(wmi_unified_t wmi_handle,
21497 						uint32_t param)
21498 {
21499 	wmi_pdev_check_cal_version_cmd_fixed_param *cmd;
21500 	wmi_buf_t buf;
21501 	int32_t len = sizeof(wmi_pdev_check_cal_version_cmd_fixed_param);
21502 
21503 	buf = wmi_buf_alloc(wmi_handle, len);
21504 	if (!buf) {
21505 		qdf_print("%s:wmi_buf_alloc failed", __func__);
21506 		return QDF_STATUS_E_FAILURE;
21507 	}
21508 	cmd = (wmi_pdev_check_cal_version_cmd_fixed_param *)wmi_buf_data(buf);
21509 	WMITLV_SET_HDR(&cmd->tlv_header,
21510 			WMITLV_TAG_STRUC_wmi_pdev_check_cal_version_cmd_fixed_param,
21511 			WMITLV_GET_STRUCT_TLVLEN
21512 			(wmi_pdev_check_cal_version_cmd_fixed_param));
21513 	cmd->pdev_id = param; /* set to 0x0 as expected from FW */
21514 	wmi_mtrace(WMI_PDEV_CHECK_CAL_VERSION_CMDID, NO_SESSION, 0);
21515 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21516 			WMI_PDEV_CHECK_CAL_VERSION_CMDID)) {
21517 		wmi_buf_free(buf);
21518 		return QDF_STATUS_E_FAILURE;
21519 	}
21520 
21521 	return QDF_STATUS_SUCCESS;
21522 }
21523 
21524 /**
21525  * extract_pdev_caldata_version_check_ev_param_tlv() - extract caldata from event
21526  * @wmi_handle: wmi handle
21527  * @param evt_buf: pointer to event buffer
21528  * @param param: Pointer to hold peer caldata version data
21529  *
21530  * Return: 0 for success or error code
21531  */
21532 static QDF_STATUS extract_pdev_caldata_version_check_ev_param_tlv(
21533 			wmi_unified_t wmi_handle,
21534 			void *evt_buf,
21535 			wmi_host_pdev_check_cal_version_event *param)
21536 {
21537 	WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *param_tlvs;
21538 	wmi_pdev_check_cal_version_event_fixed_param *event;
21539 
21540 	param_tlvs = (WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *) evt_buf;
21541 	if (!param_tlvs) {
21542 		WMI_LOGE("invalid cal version event buf");
21543 		return QDF_STATUS_E_FAILURE;
21544 	}
21545 	event =  param_tlvs->fixed_param;
21546 	if (event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] != '\0')
21547 		event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] = '\0';
21548 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(param->board_mcn_detail,
21549 			event->board_mcn_detail, WMI_BOARD_MCN_STRING_BUF_SIZE);
21550 
21551 	param->software_cal_version = event->software_cal_version;
21552 	param->board_cal_version = event->board_cal_version;
21553 	param->cal_ok  = event->cal_status;
21554 
21555 	return QDF_STATUS_SUCCESS;
21556 }
21557 
21558 /*
21559  * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config
21560  * @wmi_handle: wmi handle
21561  * @params: pointer to wmi_btm_config
21562  *
21563  * Return: QDF_STATUS
21564  */
21565 static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle,
21566 					  struct wmi_btm_config *params)
21567 {
21568 
21569 	wmi_btm_config_fixed_param *cmd;
21570 	wmi_buf_t buf;
21571 	uint32_t len;
21572 
21573 	len = sizeof(*cmd);
21574 	buf = wmi_buf_alloc(wmi_handle, len);
21575 	if (!buf) {
21576 		qdf_print("%s:wmi_buf_alloc failed", __func__);
21577 		return QDF_STATUS_E_NOMEM;
21578 	}
21579 
21580 	cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf);
21581 	WMITLV_SET_HDR(&cmd->tlv_header,
21582 		       WMITLV_TAG_STRUC_wmi_btm_config_fixed_param,
21583 		       WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param));
21584 	cmd->vdev_id = params->vdev_id;
21585 	cmd->flags = params->btm_offload_config;
21586 	cmd->max_attempt_cnt = params->btm_max_attempt_cnt;
21587 	cmd->solicited_timeout_ms = params->btm_solicited_timeout;
21588 	cmd->stick_time_seconds = params->btm_sticky_time;
21589 
21590 	wmi_mtrace(WMI_ROAM_BTM_CONFIG_CMDID, cmd->vdev_id, 0);
21591 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21592 	    WMI_ROAM_BTM_CONFIG_CMDID)) {
21593 		WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID",
21594 			 __func__);
21595 		wmi_buf_free(buf);
21596 		return QDF_STATUS_E_FAILURE;
21597 	}
21598 
21599 	return QDF_STATUS_SUCCESS;
21600 }
21601 
21602 /**
21603  * send_obss_detection_cfg_cmd_tlv() - send obss detection
21604  *   configurations to firmware.
21605  * @wmi_handle: wmi handle
21606  * @obss_cfg_param: obss detection configurations
21607  *
21608  * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw.
21609  *
21610  * Return: QDF_STATUS
21611  */
21612 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle,
21613 		struct wmi_obss_detection_cfg_param *obss_cfg_param)
21614 {
21615 	wmi_buf_t buf;
21616 	wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd;
21617 	uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param);
21618 
21619 	buf = wmi_buf_alloc(wmi_handle, len);
21620 	if (!buf) {
21621 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
21622 		return QDF_STATUS_E_NOMEM;
21623 	}
21624 
21625 	cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf);
21626 	WMITLV_SET_HDR(&cmd->tlv_header,
21627 		WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param,
21628 		       WMITLV_GET_STRUCT_TLVLEN
21629 		       (wmi_sap_obss_detection_cfg_cmd_fixed_param));
21630 
21631 	cmd->vdev_id = obss_cfg_param->vdev_id;
21632 	cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms;
21633 	cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode;
21634 	cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode;
21635 	cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode;
21636 	cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode;
21637 	cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode;
21638 	cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode;
21639 	cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode;
21640 
21641 	wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0);
21642 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21643 				 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) {
21644 		WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID");
21645 		wmi_buf_free(buf);
21646 		return QDF_STATUS_E_FAILURE;
21647 	}
21648 
21649 	return QDF_STATUS_SUCCESS;
21650 }
21651 
21652 /**
21653  * extract_obss_detection_info_tlv() - Extract obss detection info
21654  *   received from firmware.
21655  * @evt_buf: pointer to event buffer
21656  * @obss_detection: Pointer to hold obss detection info
21657  *
21658  * Return: QDF_STATUS
21659  */
21660 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf,
21661 						  struct wmi_obss_detect_info
21662 						  *obss_detection)
21663 {
21664 	WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf;
21665 	wmi_sap_obss_detection_info_evt_fixed_param *fix_param;
21666 
21667 	if (!obss_detection) {
21668 		WMI_LOGE("%s: Invalid obss_detection event buffer", __func__);
21669 		return QDF_STATUS_E_INVAL;
21670 	}
21671 
21672 	param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf;
21673 	if (!param_buf) {
21674 		WMI_LOGE("%s: Invalid evt_buf", __func__);
21675 		return QDF_STATUS_E_INVAL;
21676 	}
21677 
21678 	fix_param = param_buf->fixed_param;
21679 	obss_detection->vdev_id = fix_param->vdev_id;
21680 	obss_detection->matched_detection_masks =
21681 		fix_param->matched_detection_masks;
21682 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr,
21683 				   &obss_detection->matched_bssid_addr[0]);
21684 	switch (fix_param->reason) {
21685 	case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT:
21686 		obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED;
21687 		break;
21688 	case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY:
21689 		obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT;
21690 		break;
21691 	case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT:
21692 		obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT;
21693 		break;
21694 	default:
21695 		WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason);
21696 		return QDF_STATUS_E_INVAL;
21697 	}
21698 
21699 	return QDF_STATUS_SUCCESS;
21700 }
21701 
21702 /**
21703  * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw
21704  * @wmi_handle: wmi handle
21705  * @params: pointer to request structure
21706  *
21707  * Return: QDF_STATUS
21708  */
21709 static QDF_STATUS
21710 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle,
21711 			     struct wmi_roam_scan_stats_req *params)
21712 {
21713 	wmi_buf_t buf;
21714 	wmi_request_roam_scan_stats_cmd_fixed_param *cmd;
21715 	WMITLV_TAG_ID tag;
21716 	uint32_t size;
21717 	uint32_t len = sizeof(*cmd);
21718 
21719 	buf = wmi_buf_alloc(wmi_handle, len);
21720 	if (!buf) {
21721 		WMI_LOGE(FL("Failed to allocate wmi buffer"));
21722 		return QDF_STATUS_E_FAILURE;
21723 	}
21724 
21725 	cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf);
21726 
21727 	tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param;
21728 	size = WMITLV_GET_STRUCT_TLVLEN(
21729 			wmi_request_roam_scan_stats_cmd_fixed_param);
21730 	WMITLV_SET_HDR(&cmd->tlv_header, tag, size);
21731 
21732 	cmd->vdev_id = params->vdev_id;
21733 
21734 	WMI_LOGD(FL("Roam Scan Stats Req vdev_id: %u"), cmd->vdev_id);
21735 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21736 				 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) {
21737 		WMI_LOGE("%s: Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID",
21738 			 __func__);
21739 		wmi_buf_free(buf);
21740 		return QDF_STATUS_E_FAILURE;
21741 	}
21742 
21743 	return QDF_STATUS_SUCCESS;
21744 }
21745 
21746 /**
21747  * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event
21748  * @wmi_handle: wmi handle
21749  * @evt_buf: pointer to event buffer
21750  * @vdev_id: output pointer to hold vdev id
21751  * @res_param: output pointer to hold the allocated response
21752  *
21753  * Return: QDF_STATUS
21754  */
21755 static QDF_STATUS
21756 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf,
21757 				    uint32_t *vdev_id,
21758 				    struct wmi_roam_scan_stats_res **res_param)
21759 {
21760 	WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf;
21761 	wmi_roam_scan_stats_event_fixed_param *fixed_param;
21762 	uint32_t *client_id = NULL;
21763 	wmi_roaming_timestamp *timestamp = NULL;
21764 	uint32_t *num_channels = NULL;
21765 	uint32_t *chan_info = NULL;
21766 	wmi_mac_addr *old_bssid = NULL;
21767 	uint32_t *is_roaming_success = NULL;
21768 	wmi_mac_addr *new_bssid = NULL;
21769 	uint32_t *num_roam_candidates = NULL;
21770 	wmi_roam_scan_trigger_reason *roam_reason = NULL;
21771 	wmi_mac_addr *bssid = NULL;
21772 	uint32_t *score = NULL;
21773 	uint32_t *channel = NULL;
21774 	uint32_t *rssi = NULL;
21775 	int chan_idx = 0, cand_idx = 0;
21776 	uint32_t total_len;
21777 	struct wmi_roam_scan_stats_res *res;
21778 	uint32_t i, j;
21779 	uint32_t num_scans;
21780 
21781 	*res_param = NULL;
21782 	*vdev_id = 0xFF; /* Initialize to invalid vdev id */
21783 	param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf;
21784 	if (!param_buf) {
21785 		WMI_LOGE(FL("Invalid roam scan stats event"));
21786 		return QDF_STATUS_E_INVAL;
21787 	}
21788 
21789 	fixed_param = param_buf->fixed_param;
21790 	total_len = sizeof(*res) + fixed_param->num_roam_scans *
21791 		    sizeof(struct wmi_roam_scan_stats_params);
21792 
21793 	*vdev_id = fixed_param->vdev_id;
21794 	num_scans = fixed_param->num_roam_scans;
21795 
21796 	res = qdf_mem_malloc(total_len);
21797 	if (!res) {
21798 		WMI_LOGE("Failed to allocate roam scan stats response memory");
21799 		return QDF_STATUS_E_NOMEM;
21800 	}
21801 
21802 	if (!num_scans) {
21803 		*res_param = res;
21804 		return QDF_STATUS_SUCCESS;
21805 	}
21806 
21807 	if (param_buf->client_id &&
21808 	    param_buf->num_client_id == num_scans)
21809 		client_id = param_buf->client_id;
21810 
21811 	if (param_buf->timestamp &&
21812 	    param_buf->num_timestamp == num_scans)
21813 		timestamp = param_buf->timestamp;
21814 
21815 	if (param_buf->old_bssid &&
21816 	    param_buf->num_old_bssid == num_scans)
21817 		old_bssid = param_buf->old_bssid;
21818 
21819 	if (param_buf->new_bssid &&
21820 	    param_buf->num_new_bssid == num_scans)
21821 		new_bssid = param_buf->new_bssid;
21822 
21823 	if (param_buf->is_roaming_success &&
21824 	    param_buf->num_is_roaming_success == num_scans)
21825 		is_roaming_success = param_buf->is_roaming_success;
21826 
21827 	if (param_buf->roam_reason &&
21828 	    param_buf->num_roam_reason == num_scans)
21829 		roam_reason = param_buf->roam_reason;
21830 
21831 	if (param_buf->num_channels &&
21832 	    param_buf->num_num_channels == num_scans) {
21833 		uint32_t count, chan_info_sum = 0;
21834 
21835 		num_channels = param_buf->num_channels;
21836 		for (count = 0; count < param_buf->num_num_channels; count++)
21837 			chan_info_sum += param_buf->num_channels[count];
21838 
21839 		if (param_buf->chan_info &&
21840 		    param_buf->num_chan_info == chan_info_sum)
21841 			chan_info = param_buf->chan_info;
21842 	}
21843 
21844 	if (param_buf->num_roam_candidates &&
21845 	    param_buf->num_num_roam_candidates == num_scans) {
21846 		uint32_t count, roam_cand_sum = 0;
21847 
21848 		num_roam_candidates = param_buf->num_roam_candidates;
21849 		for (count = 0; count < param_buf->num_num_roam_candidates;
21850 		     count++)
21851 			roam_cand_sum += param_buf->num_roam_candidates[count];
21852 
21853 		if (param_buf->bssid &&
21854 		    param_buf->num_bssid == roam_cand_sum)
21855 			bssid = param_buf->bssid;
21856 
21857 		if (param_buf->score &&
21858 		    param_buf->num_score == roam_cand_sum)
21859 			score = param_buf->score;
21860 
21861 		if (param_buf->channel &&
21862 		    param_buf->num_channel == roam_cand_sum)
21863 			channel = param_buf->channel;
21864 
21865 		if (param_buf->rssi &&
21866 		    param_buf->num_rssi == roam_cand_sum)
21867 			rssi = param_buf->rssi;
21868 	}
21869 
21870 	res->num_roam_scans = num_scans;
21871 	for (i = 0; i < num_scans; i++) {
21872 		struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i];
21873 
21874 		if (timestamp)
21875 			roam->time_stamp = timestamp[i].lower32bit |
21876 						(timestamp[i].upper32bit << 31);
21877 
21878 		if (client_id)
21879 			roam->client_id = client_id[i];
21880 
21881 		if (num_channels) {
21882 			roam->num_scan_chans = num_channels[i];
21883 			if (chan_info) {
21884 				for (j = 0; j < num_channels[i]; j++)
21885 					roam->scan_freqs[j] =
21886 							chan_info[chan_idx++];
21887 			}
21888 		}
21889 
21890 		if (is_roaming_success)
21891 			roam->is_roam_successful = is_roaming_success[i];
21892 
21893 		if (roam_reason) {
21894 			roam->trigger_id = roam_reason[i].trigger_id;
21895 			roam->trigger_value = roam_reason[i].trigger_value;
21896 		}
21897 
21898 		if (num_roam_candidates) {
21899 			roam->num_roam_candidates = num_roam_candidates[i];
21900 
21901 			for (j = 0; j < num_roam_candidates[i]; j++) {
21902 				if (score)
21903 					roam->cand[j].score = score[cand_idx];
21904 				if (rssi)
21905 					roam->cand[j].rssi = rssi[cand_idx];
21906 				if (channel)
21907 					roam->cand[j].freq =
21908 						channel[cand_idx];
21909 
21910 				if (bssid)
21911 					WMI_MAC_ADDR_TO_CHAR_ARRAY(
21912 							&bssid[cand_idx],
21913 							roam->cand[j].bssid);
21914 
21915 				cand_idx++;
21916 			}
21917 		}
21918 
21919 		if (old_bssid)
21920 			WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i],
21921 						   roam->old_bssid);
21922 
21923 		if (new_bssid)
21924 			WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i],
21925 						   roam->new_bssid);
21926 	}
21927 
21928 	*res_param = res;
21929 
21930 	return QDF_STATUS_SUCCESS;
21931 }
21932 
21933 /**
21934  * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params
21935  * @wmi_handle: wmi handler
21936  * @params: pointer to 11k offload params
21937  *
21938  * Return: 0 for success and non zero for failure
21939  */
21940 static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle,
21941 				struct wmi_11k_offload_params *params)
21942 {
21943 	wmi_11k_offload_report_fixed_param *cmd;
21944 	wmi_buf_t buf;
21945 	QDF_STATUS status;
21946 	uint8_t *buf_ptr;
21947 	wmi_neighbor_report_11k_offload_tlv_param
21948 					*neighbor_report_offload_params;
21949 	wmi_neighbor_report_offload *neighbor_report_offload;
21950 
21951 	uint32_t len = sizeof(*cmd);
21952 
21953 	if (params->offload_11k_bitmask &
21954 	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ)
21955 		len += WMI_TLV_HDR_SIZE +
21956 			sizeof(wmi_neighbor_report_11k_offload_tlv_param);
21957 
21958 	buf = wmi_buf_alloc(wmi_handle, len);
21959 	if (!buf) {
21960 		WMI_LOGP("%s: failed to allocate memory for 11k offload params",
21961 			 __func__);
21962 		return QDF_STATUS_E_NOMEM;
21963 	}
21964 
21965 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21966 	cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr;
21967 
21968 	WMITLV_SET_HDR(&cmd->tlv_header,
21969 		 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param,
21970 		 WMITLV_GET_STRUCT_TLVLEN(
21971 			wmi_11k_offload_report_fixed_param));
21972 
21973 	cmd->vdev_id = params->vdev_id;
21974 	cmd->offload_11k = params->offload_11k_bitmask;
21975 
21976 	if (params->offload_11k_bitmask &
21977 	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) {
21978 		buf_ptr += sizeof(wmi_11k_offload_report_fixed_param);
21979 
21980 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
21981 			sizeof(wmi_neighbor_report_11k_offload_tlv_param));
21982 		buf_ptr += WMI_TLV_HDR_SIZE;
21983 
21984 		neighbor_report_offload_params =
21985 			(wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr;
21986 		WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header,
21987 			WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param,
21988 			WMITLV_GET_STRUCT_TLVLEN(
21989 			wmi_neighbor_report_11k_offload_tlv_param));
21990 
21991 		neighbor_report_offload = &neighbor_report_offload_params->
21992 			neighbor_rep_ofld_params;
21993 
21994 		neighbor_report_offload->time_offset =
21995 			params->neighbor_report_params.time_offset;
21996 		neighbor_report_offload->low_rssi_offset =
21997 			params->neighbor_report_params.low_rssi_offset;
21998 		neighbor_report_offload->bmiss_count_trigger =
21999 			params->neighbor_report_params.bmiss_count_trigger;
22000 		neighbor_report_offload->per_threshold_offset =
22001 			params->neighbor_report_params.per_threshold_offset;
22002 		neighbor_report_offload->neighbor_report_cache_timeout =
22003 			params->neighbor_report_params.
22004 			neighbor_report_cache_timeout;
22005 		neighbor_report_offload->max_neighbor_report_req_cap =
22006 			params->neighbor_report_params.
22007 			max_neighbor_report_req_cap;
22008 		neighbor_report_offload->ssid.ssid_len =
22009 			params->neighbor_report_params.ssid.length;
22010 		qdf_mem_copy(neighbor_report_offload->ssid.ssid,
22011 			&params->neighbor_report_params.ssid.mac_ssid,
22012 			neighbor_report_offload->ssid.ssid_len);
22013 	}
22014 
22015 	wmi_mtrace(WMI_11K_OFFLOAD_REPORT_CMDID, cmd->vdev_id, 0);
22016 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
22017 			WMI_11K_OFFLOAD_REPORT_CMDID);
22018 	if (status != QDF_STATUS_SUCCESS) {
22019 		WMI_LOGE("%s: failed to send 11k offload command %d",
22020 			 __func__, status);
22021 		wmi_buf_free(buf);
22022 	}
22023 
22024 	return status;
22025 }
22026 
22027 /**
22028  * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report
22029  * command
22030  * @wmi_handle: wmi handler
22031  * @params: pointer to neighbor report invoke params
22032  *
22033  * Return: 0 for success and non zero for failure
22034  */
22035 static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle,
22036 			struct wmi_invoke_neighbor_report_params *params)
22037 {
22038 	wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd;
22039 	wmi_buf_t buf;
22040 	QDF_STATUS status;
22041 	uint8_t *buf_ptr;
22042 	uint32_t len = sizeof(*cmd);
22043 
22044 	buf = wmi_buf_alloc(wmi_handle, len);
22045 	if (!buf) {
22046 		WMI_LOGP("%s:failed to allocate memory for neighbor invoke cmd",
22047 			 __func__);
22048 		return QDF_STATUS_E_NOMEM;
22049 	}
22050 
22051 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
22052 	cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr;
22053 
22054 	WMITLV_SET_HDR(&cmd->tlv_header,
22055 		 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param,
22056 		 WMITLV_GET_STRUCT_TLVLEN(
22057 			wmi_11k_offload_invoke_neighbor_report_fixed_param));
22058 
22059 	cmd->vdev_id = params->vdev_id;
22060 	cmd->flags = params->send_resp_to_host;
22061 
22062 	cmd->ssid.ssid_len = params->ssid.length;
22063 	qdf_mem_copy(cmd->ssid.ssid,
22064 		     &params->ssid.mac_ssid,
22065 		     cmd->ssid.ssid_len);
22066 
22067 	wmi_mtrace(WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID, cmd->vdev_id, 0);
22068 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
22069 			WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID);
22070 	if (status != QDF_STATUS_SUCCESS) {
22071 		WMI_LOGE("%s: failed to send invoke neighbor report command %d",
22072 			 __func__, status);
22073 		wmi_buf_free(buf);
22074 	}
22075 
22076 	return status;
22077 }
22078 
22079 #ifdef WLAN_SUPPORT_GREEN_AP
22080 static QDF_STATUS extract_green_ap_egap_status_info_tlv(
22081 		uint8_t *evt_buf,
22082 		struct wlan_green_ap_egap_status_info *egap_status_info_params)
22083 {
22084 	WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf;
22085 	wmi_ap_ps_egap_info_event_fixed_param  *egap_info_event;
22086 	wmi_ap_ps_egap_info_chainmask_list *chainmask_event;
22087 
22088 	param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf;
22089 	if (!param_buf) {
22090 		WMI_LOGE("Invalid EGAP Info status event buffer");
22091 		return QDF_STATUS_E_INVAL;
22092 	}
22093 
22094 	egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *)
22095 				param_buf->fixed_param;
22096 	chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *)
22097 				param_buf->chainmask_list;
22098 
22099 	egap_status_info_params->status = egap_info_event->status;
22100 	egap_status_info_params->mac_id = chainmask_event->mac_id;
22101 	egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask;
22102 	egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask;
22103 
22104 	return QDF_STATUS_SUCCESS;
22105 }
22106 #endif
22107 
22108 /*
22109  * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of
22110  * updating bss color change within firmware when AP announces bss color change.
22111  * @wmi_handle: wmi handle
22112  * @vdev_id: vdev ID
22113  * @enable: enable bss color change within firmware
22114  *
22115  * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw.
22116  *
22117  * Return: QDF_STATUS
22118  */
22119 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle,
22120 						       uint32_t vdev_id,
22121 						       bool enable)
22122 {
22123 	wmi_buf_t buf;
22124 	wmi_bss_color_change_enable_fixed_param *cmd;
22125 	uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param);
22126 
22127 	buf = wmi_buf_alloc(wmi_handle, len);
22128 	if (!buf) {
22129 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
22130 		return QDF_STATUS_E_NOMEM;
22131 	}
22132 
22133 	cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf);
22134 	WMITLV_SET_HDR(&cmd->tlv_header,
22135 		WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param,
22136 		       WMITLV_GET_STRUCT_TLVLEN
22137 		       (wmi_bss_color_change_enable_fixed_param));
22138 	cmd->vdev_id = vdev_id;
22139 	cmd->enable = enable;
22140 	wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0);
22141 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
22142 				 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) {
22143 		WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID");
22144 		wmi_buf_free(buf);
22145 		return QDF_STATUS_E_FAILURE;
22146 	}
22147 
22148 	return QDF_STATUS_SUCCESS;
22149 }
22150 
22151 /**
22152  * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection
22153  *   configurations to firmware.
22154  * @wmi_handle: wmi handle
22155  * @cfg_param: obss detection configurations
22156  *
22157  * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw.
22158  *
22159  * Return: QDF_STATUS
22160  */
22161 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv(
22162 		wmi_unified_t wmi_handle,
22163 		struct wmi_obss_color_collision_cfg_param *cfg_param)
22164 {
22165 	wmi_buf_t buf;
22166 	wmi_obss_color_collision_det_config_fixed_param *cmd;
22167 	uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param);
22168 
22169 	buf = wmi_buf_alloc(wmi_handle, len);
22170 	if (!buf) {
22171 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
22172 		return QDF_STATUS_E_NOMEM;
22173 	}
22174 
22175 	cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data(
22176 			buf);
22177 	WMITLV_SET_HDR(&cmd->tlv_header,
22178 	WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param,
22179 		       WMITLV_GET_STRUCT_TLVLEN
22180 		       (wmi_obss_color_collision_det_config_fixed_param));
22181 	cmd->vdev_id = cfg_param->vdev_id;
22182 	cmd->flags = cfg_param->flags;
22183 	cmd->current_bss_color = cfg_param->current_bss_color;
22184 	cmd->detection_period_ms = cfg_param->detection_period_ms;
22185 	cmd->scan_period_ms = cfg_param->scan_period_ms;
22186 	cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms;
22187 
22188 	switch (cfg_param->evt_type) {
22189 	case OBSS_COLOR_COLLISION_DETECTION_DISABLE:
22190 		cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE;
22191 		break;
22192 	case OBSS_COLOR_COLLISION_DETECTION:
22193 		cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION;
22194 		break;
22195 	case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY:
22196 		cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY;
22197 		break;
22198 	case OBSS_COLOR_FREE_SLOT_AVAILABLE:
22199 		cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE;
22200 		break;
22201 	default:
22202 		WMI_LOGE("%s: invalid event type: %d",
22203 			 __func__, cfg_param->evt_type);
22204 		wmi_buf_free(buf);
22205 		return QDF_STATUS_E_FAILURE;
22206 	}
22207 
22208 	wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0);
22209 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
22210 				 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) {
22211 		WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d",
22212 			 __func__, cfg_param->vdev_id);
22213 		wmi_buf_free(buf);
22214 		return QDF_STATUS_E_FAILURE;
22215 	}
22216 
22217 	return QDF_STATUS_SUCCESS;
22218 }
22219 
22220 /**
22221  * extract_obss_color_collision_info_tlv() - Extract bss color collision info
22222  *   received from firmware.
22223  * @evt_buf: pointer to event buffer
22224  * @info: Pointer to hold bss collision  info
22225  *
22226  * Return: QDF_STATUS
22227  */
22228 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf,
22229 		struct wmi_obss_color_collision_info *info)
22230 {
22231 	WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf;
22232 	wmi_obss_color_collision_evt_fixed_param *fix_param;
22233 
22234 	if (!info) {
22235 		WMI_LOGE("%s: Invalid obss color buffer", __func__);
22236 		return QDF_STATUS_E_INVAL;
22237 	}
22238 
22239 	param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *)
22240 		    evt_buf;
22241 	if (!param_buf) {
22242 		WMI_LOGE("%s: Invalid evt_buf", __func__);
22243 		return QDF_STATUS_E_INVAL;
22244 	}
22245 
22246 	fix_param = param_buf->fixed_param;
22247 	info->vdev_id = fix_param->vdev_id;
22248 	info->obss_color_bitmap_bit0to31 = fix_param->bss_color_bitmap_bit0to31;
22249 	info->obss_color_bitmap_bit32to63 =
22250 		fix_param->bss_color_bitmap_bit32to63;
22251 
22252 	switch (fix_param->evt_type) {
22253 	case WMI_BSS_COLOR_COLLISION_DISABLE:
22254 		info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE;
22255 		break;
22256 	case WMI_BSS_COLOR_COLLISION_DETECTION:
22257 		info->evt_type = OBSS_COLOR_COLLISION_DETECTION;
22258 		break;
22259 	case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY:
22260 		info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY;
22261 		break;
22262 	case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE:
22263 		info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE;
22264 		break;
22265 	default:
22266 		WMI_LOGE("%s: invalid event type: %d, vdev_id: %d",
22267 			 __func__, fix_param->evt_type, fix_param->vdev_id);
22268 		return QDF_STATUS_E_FAILURE;
22269 	}
22270 
22271 	return QDF_STATUS_SUCCESS;
22272 }
22273 
22274 /*
22275  * extract_comb_phyerr_tlv() - extract comb phy error from event
22276  * @wmi_handle: wmi handle
22277  * @evt_buf: pointer to event buffer
22278  * @datalen: data length of event buffer
22279  * @buf_offset: Pointer to hold value of current event buffer offset
22280  * post extraction
22281  * @phyerr: Pointer to hold phyerr
22282  *
22283  * Return: QDF_STATUS
22284  */
22285 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle,
22286 					  void *evt_buf,
22287 					  uint16_t datalen,
22288 					  uint16_t *buf_offset,
22289 					  wmi_host_phyerr_t *phyerr)
22290 {
22291 	WMI_PHYERR_EVENTID_param_tlvs *param_tlvs;
22292 	wmi_comb_phyerr_rx_hdr *pe_hdr;
22293 
22294 	param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf;
22295 	if (!param_tlvs) {
22296 		WMI_LOGD("%s: Received null data from FW", __func__);
22297 		return QDF_STATUS_E_FAILURE;
22298 	}
22299 
22300 	pe_hdr = param_tlvs->hdr;
22301 	if (!pe_hdr) {
22302 		WMI_LOGD("%s: Received Data PE Header is NULL", __func__);
22303 		return QDF_STATUS_E_FAILURE;
22304 	}
22305 
22306 	/* Ensure it's at least the size of the header */
22307 	if (datalen < sizeof(*pe_hdr)) {
22308 		WMI_LOGD("%s: Expected minimum size %zu, received %d",
22309 			 __func__, sizeof(*pe_hdr), datalen);
22310 		return QDF_STATUS_E_FAILURE;
22311 	}
22312 
22313 	phyerr->pdev_id = wmi_handle->ops->
22314 		convert_pdev_id_target_to_host(pe_hdr->pdev_id);
22315 	phyerr->tsf64 = pe_hdr->tsf_l32;
22316 	phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32);
22317 	phyerr->bufp = param_tlvs->bufp;
22318 	phyerr->buf_len = pe_hdr->buf_len;
22319 	phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0;
22320 	phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1;
22321 	*buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t);
22322 
22323 	return QDF_STATUS_SUCCESS;
22324 }
22325 
22326 /**
22327  * extract_single_phyerr_tlv() - extract single phy error from event
22328  * @wmi_handle: wmi handle
22329  * @evt_buf: pointer to event buffer
22330  * @datalen: data length of event buffer
22331  * @buf_offset: Pointer to hold value of current event buffer offset
22332  * post extraction
22333  * @phyerr: Pointer to hold phyerr
22334  *
22335  * Return: QDF_STATUS
22336  */
22337 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle,
22338 					    void *evt_buf,
22339 					    uint16_t datalen,
22340 					    uint16_t *buf_offset,
22341 					    wmi_host_phyerr_t *phyerr)
22342 {
22343 	wmi_single_phyerr_rx_event *ev;
22344 	uint16_t n = *buf_offset;
22345 	uint8_t *data = (uint8_t *)evt_buf;
22346 
22347 	if (n < datalen) {
22348 		if ((datalen - n) < sizeof(ev->hdr)) {
22349 			WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu",
22350 				 __func__, datalen, n, sizeof(ev->hdr));
22351 			return QDF_STATUS_E_FAILURE;
22352 		}
22353 
22354 		/*
22355 		 * Obtain a pointer to the beginning of the current event.
22356 		 * data[0] is the beginning of the WMI payload.
22357 		 */
22358 		ev = (wmi_single_phyerr_rx_event *)&data[n];
22359 
22360 		/*
22361 		 * Sanity check the buffer length of the event against
22362 		 * what we currently have.
22363 		 *
22364 		 * Since buf_len is 32 bits, we check if it overflows
22365 		 * a large 32 bit value.  It's not 0x7fffffff because
22366 		 * we increase n by (buf_len + sizeof(hdr)), which would
22367 		 * in itself cause n to overflow.
22368 		 *
22369 		 * If "int" is 64 bits then this becomes a moot point.
22370 		 */
22371 		if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) {
22372 			WMI_LOGD("%s: buf_len is garbage 0x%x",
22373 				 __func__, ev->hdr.buf_len);
22374 			return QDF_STATUS_E_FAILURE;
22375 		}
22376 
22377 		if ((n + ev->hdr.buf_len) > datalen) {
22378 			WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d",
22379 				 __func__, n, ev->hdr.buf_len, datalen);
22380 			return QDF_STATUS_E_FAILURE;
22381 		}
22382 
22383 		phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr);
22384 		phyerr->tsf_timestamp = ev->hdr.tsf_timestamp;
22385 		phyerr->bufp = &ev->bufp[0];
22386 		phyerr->buf_len = ev->hdr.buf_len;
22387 		phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr);
22388 
22389 		/*
22390 		 * Advance the buffer pointer to the next PHY error.
22391 		 * buflen is the length of this payload, so we need to
22392 		 * advance past the current header _AND_ the payload.
22393 		 */
22394 		n += sizeof(*ev) + ev->hdr.buf_len;
22395 	}
22396 	*buf_offset = n;
22397 
22398 	return QDF_STATUS_SUCCESS;
22399 }
22400 
22401 /**
22402  * extract_esp_estimation_ev_param_tlv() - extract air time from event
22403  * @wmi_handle: wmi handle
22404  * @evt_buf: pointer to event buffer
22405  * @param: Pointer to hold esp event
22406  *
22407  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure
22408  */
22409 static QDF_STATUS
22410 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle,
22411 				    void *evt_buf,
22412 				    struct esp_estimation_event *param)
22413 {
22414 	WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf;
22415 	wmi_esp_estimate_event_fixed_param *esp_event;
22416 
22417 	param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf;
22418 	if (!param_buf) {
22419 		WMI_LOGE("Invalid ESP Estimate Event buffer");
22420 		return QDF_STATUS_E_INVAL;
22421 	}
22422 	esp_event = param_buf->fixed_param;
22423 	param->ac_airtime_percentage = esp_event->ac_airtime_percentage;
22424 	param->pdev_id = convert_target_pdev_id_to_host_pdev_id(
22425 				esp_event->pdev_id);
22426 
22427 	return QDF_STATUS_SUCCESS;
22428 }
22429 
22430 struct wmi_ops tlv_ops =  {
22431 	.send_vdev_create_cmd = send_vdev_create_cmd_tlv,
22432 	.send_vdev_delete_cmd = send_vdev_delete_cmd_tlv,
22433 	.send_vdev_down_cmd = send_vdev_down_cmd_tlv,
22434 	.send_vdev_start_cmd = send_vdev_start_cmd_tlv,
22435 	.send_hidden_ssid_vdev_restart_cmd =
22436 		send_hidden_ssid_vdev_restart_cmd_tlv,
22437 	.send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv,
22438 	.send_peer_param_cmd = send_peer_param_cmd_tlv,
22439 	.send_vdev_up_cmd = send_vdev_up_cmd_tlv,
22440 	.send_vdev_stop_cmd = send_vdev_stop_cmd_tlv,
22441 	.send_peer_create_cmd = send_peer_create_cmd_tlv,
22442 	.send_peer_delete_cmd = send_peer_delete_cmd_tlv,
22443 	.send_peer_rx_reorder_queue_setup_cmd =
22444 		send_peer_rx_reorder_queue_setup_cmd_tlv,
22445 	.send_peer_rx_reorder_queue_remove_cmd =
22446 		send_peer_rx_reorder_queue_remove_cmd_tlv,
22447 	.send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv,
22448 	.send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv,
22449 	.send_peer_update_wds_entry_cmd = send_peer_update_wds_entry_cmd_tlv,
22450 	.send_pdev_utf_cmd = send_pdev_utf_cmd_tlv,
22451 	.send_pdev_param_cmd = send_pdev_param_cmd_tlv,
22452 	.send_pdev_get_tpc_config_cmd = send_pdev_get_tpc_config_cmd_tlv,
22453 	.send_suspend_cmd = send_suspend_cmd_tlv,
22454 	.send_resume_cmd = send_resume_cmd_tlv,
22455 #ifdef FEATURE_WLAN_D0WOW
22456 	.send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv,
22457 	.send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv,
22458 #endif
22459 	.send_wow_enable_cmd = send_wow_enable_cmd_tlv,
22460 	.send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv,
22461 	.send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv,
22462 	.send_crash_inject_cmd = send_crash_inject_cmd_tlv,
22463 #ifdef FEATURE_FW_LOG_PARSING
22464 	.send_dbglog_cmd = send_dbglog_cmd_tlv,
22465 #endif
22466 	.send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv,
22467 	.send_stats_request_cmd = send_stats_request_cmd_tlv,
22468 	.send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv,
22469 	.send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv,
22470 	.send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv,
22471 	.send_beacon_send_cmd = send_beacon_send_cmd_tlv,
22472 	.send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv,
22473 	.send_peer_assoc_cmd = send_peer_assoc_cmd_tlv,
22474 	.send_scan_start_cmd = send_scan_start_cmd_tlv,
22475 	.send_scan_stop_cmd = send_scan_stop_cmd_tlv,
22476 	.send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv,
22477 	.send_mgmt_cmd = send_mgmt_cmd_tlv,
22478 	.send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv,
22479 	.send_modem_power_state_cmd = send_modem_power_state_cmd_tlv,
22480 	.send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv,
22481 	.send_set_sta_uapsd_auto_trig_cmd =
22482 		send_set_sta_uapsd_auto_trig_cmd_tlv,
22483 	.send_get_temperature_cmd = send_get_temperature_cmd_tlv,
22484 	.send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv,
22485 	.send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv,
22486 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
22487 	.send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv,
22488 	.send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv,
22489 #endif
22490 	.send_set_smps_params_cmd = send_set_smps_params_cmd_tlv,
22491 	.send_set_mimops_cmd = send_set_mimops_cmd_tlv,
22492 #ifdef WLAN_FEATURE_DSRC
22493 	.send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv,
22494 	.send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv,
22495 	.send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv,
22496 	.send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv,
22497 	.send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv,
22498 	.send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv,
22499 	.send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv,
22500 	.send_ocb_start_timing_advert_cmd =
22501 		send_ocb_start_timing_advert_cmd_tlv,
22502 	.extract_ocb_chan_config_resp = extract_ocb_channel_config_resp_tlv,
22503 	.extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv,
22504 	.extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv,
22505 	.extract_dcc_stats = extract_ocb_dcc_stats_tlv,
22506 #endif
22507 	.send_set_enable_disable_mcc_adaptive_scheduler_cmd =
22508 		 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv,
22509 	.send_set_mcc_channel_time_latency_cmd =
22510 			 send_set_mcc_channel_time_latency_cmd_tlv,
22511 	.send_set_mcc_channel_time_quota_cmd =
22512 			 send_set_mcc_channel_time_quota_cmd_tlv,
22513 	.send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv,
22514 	.send_lro_config_cmd = send_lro_config_cmd_tlv,
22515 	.send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv,
22516 	.send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv,
22517 	.send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv,
22518 	.send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv,
22519 	.send_probe_rsp_tmpl_send_cmd =
22520 				send_probe_rsp_tmpl_send_cmd_tlv,
22521 	.send_p2p_go_set_beacon_ie_cmd =
22522 				send_p2p_go_set_beacon_ie_cmd_tlv,
22523 	.send_setup_install_key_cmd =
22524 				send_setup_install_key_cmd_tlv,
22525 	.send_set_gateway_params_cmd =
22526 				send_set_gateway_params_cmd_tlv,
22527 	.send_set_rssi_monitoring_cmd =
22528 			 send_set_rssi_monitoring_cmd_tlv,
22529 	.send_scan_probe_setoui_cmd =
22530 				send_scan_probe_setoui_cmd_tlv,
22531 	.send_roam_scan_offload_rssi_thresh_cmd =
22532 			send_roam_scan_offload_rssi_thresh_cmd_tlv,
22533 	.send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv,
22534 	.send_roam_scan_filter_cmd =
22535 			send_roam_scan_filter_cmd_tlv,
22536 #ifdef IPA_OFFLOAD
22537 	.send_ipa_offload_control_cmd =
22538 			 send_ipa_offload_control_cmd_tlv,
22539 #endif
22540 	.send_plm_stop_cmd = send_plm_stop_cmd_tlv,
22541 	.send_plm_start_cmd = send_plm_start_cmd_tlv,
22542 	.send_pno_stop_cmd = send_pno_stop_cmd_tlv,
22543 	.send_pno_start_cmd = send_pno_start_cmd_tlv,
22544 	.send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv,
22545 	.send_set_ric_req_cmd = send_set_ric_req_cmd_tlv,
22546 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
22547 	.send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv,
22548 	.send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv,
22549 	.send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv,
22550 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/
22551 	.send_congestion_cmd = send_congestion_cmd_tlv,
22552 	.send_snr_request_cmd = send_snr_request_cmd_tlv,
22553 	.send_snr_cmd = send_snr_cmd_tlv,
22554 	.send_link_status_req_cmd = send_link_status_req_cmd_tlv,
22555 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
22556 	.send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv,
22557 	.send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv,
22558 	.send_enable_arp_ns_offload_cmd = send_enable_arp_ns_offload_cmd_tlv,
22559 	.send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv,
22560 	.send_multiple_add_clear_mcbc_filter_cmd =
22561 		send_multiple_add_clear_mcbc_filter_cmd_tlv,
22562 	.send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv,
22563 	.send_gtk_offload_cmd = send_gtk_offload_cmd_tlv,
22564 	.send_process_gtk_offload_getinfo_cmd =
22565 		send_process_gtk_offload_getinfo_cmd_tlv,
22566 	.send_enable_enhance_multicast_offload_cmd =
22567 		send_enable_enhance_multicast_offload_tlv,
22568 	.extract_gtk_rsp_event = extract_gtk_rsp_event_tlv,
22569 #ifdef FEATURE_WLAN_RA_FILTERING
22570 	.send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv,
22571 #endif
22572 	.send_action_frame_patterns_cmd = send_action_frame_patterns_cmd_tlv,
22573 	.send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv,
22574 	.send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv,
22575 	.send_lphb_config_tcp_pkt_filter_cmd =
22576 		send_lphb_config_tcp_pkt_filter_cmd_tlv,
22577 	.send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv,
22578 	.send_lphb_config_udp_pkt_filter_cmd =
22579 		send_lphb_config_udp_pkt_filter_cmd_tlv,
22580 #ifdef WLAN_FEATURE_PACKET_FILTERING
22581 	.send_enable_disable_packet_filter_cmd =
22582 		send_enable_disable_packet_filter_cmd_tlv,
22583 	.send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv,
22584 #endif
22585 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */
22586 #ifdef CONFIG_MCL
22587 	.send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv,
22588 	.send_get_link_speed_cmd = send_get_link_speed_cmd_tlv,
22589 	.send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv,
22590 	.send_roam_scan_offload_mode_cmd =
22591 			send_roam_scan_offload_mode_cmd_tlv,
22592 #ifndef REMOVE_PKT_LOG
22593 	.send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv,
22594 #endif
22595 	.send_roam_scan_offload_ap_profile_cmd =
22596 			send_roam_scan_offload_ap_profile_cmd_tlv,
22597 #endif
22598 #ifdef WLAN_SUPPORT_GREEN_AP
22599 	.send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv,
22600 	.send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv,
22601 	.extract_green_ap_egap_status_info =
22602 			extract_green_ap_egap_status_info_tlv,
22603 #endif
22604 	.send_fw_profiling_cmd = send_fw_profiling_cmd_tlv,
22605 	.send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv,
22606 	.send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv,
22607 	.send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv,
22608 	.send_start_oem_data_cmd = send_start_oem_data_cmd_tlv,
22609 #ifdef WLAN_FEATURE_CIF_CFR
22610 	.send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv,
22611 #endif
22612 	.send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv,
22613 	.send_dfs_phyerr_filter_offload_en_cmd =
22614 		 send_dfs_phyerr_filter_offload_en_cmd_tlv,
22615 	.send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv,
22616 	.send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv,
22617 	.send_del_ts_cmd = send_del_ts_cmd_tlv,
22618 	.send_aggr_qos_cmd = send_aggr_qos_cmd_tlv,
22619 	.send_add_ts_cmd = send_add_ts_cmd_tlv,
22620 	.send_process_add_periodic_tx_ptrn_cmd =
22621 		send_process_add_periodic_tx_ptrn_cmd_tlv,
22622 	.send_process_del_periodic_tx_ptrn_cmd =
22623 		send_process_del_periodic_tx_ptrn_cmd_tlv,
22624 	.send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv,
22625 	.send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv,
22626 	.send_set_app_type2_params_in_fw_cmd =
22627 		send_set_app_type2_params_in_fw_cmd_tlv,
22628 	.send_set_auto_shutdown_timer_cmd =
22629 		send_set_auto_shutdown_timer_cmd_tlv,
22630 	.send_nan_req_cmd = send_nan_req_cmd_tlv,
22631 	.send_process_dhcpserver_offload_cmd =
22632 		send_process_dhcpserver_offload_cmd_tlv,
22633 	.send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv,
22634 	.send_process_ch_avoid_update_cmd =
22635 		send_process_ch_avoid_update_cmd_tlv,
22636 	.send_pdev_set_regdomain_cmd =
22637 				send_pdev_set_regdomain_cmd_tlv,
22638 	.send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv,
22639 	.send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv,
22640 	.send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv,
22641 	.send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv,
22642 	.send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv,
22643 	.save_fw_version_cmd = save_fw_version_cmd_tlv,
22644 	.check_and_update_fw_version =
22645 		 check_and_update_fw_version_cmd_tlv,
22646 	.send_set_base_macaddr_indicate_cmd =
22647 		 send_set_base_macaddr_indicate_cmd_tlv,
22648 	.send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv,
22649 	.send_enable_specific_fw_logs_cmd =
22650 		 send_enable_specific_fw_logs_cmd_tlv,
22651 	.send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv,
22652 	.send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv,
22653 	.send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv,
22654 #ifdef WLAN_POLICY_MGR_ENABLE
22655 	.send_pdev_set_dual_mac_config_cmd =
22656 		 send_pdev_set_dual_mac_config_cmd_tlv,
22657 #endif
22658 	.send_app_type1_params_in_fw_cmd =
22659 		 send_app_type1_params_in_fw_cmd_tlv,
22660 	.send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv,
22661 	.send_process_roam_synch_complete_cmd =
22662 		 send_process_roam_synch_complete_cmd_tlv,
22663 	.send_unit_test_cmd = send_unit_test_cmd_tlv,
22664 	.send_roam_invoke_cmd = send_roam_invoke_cmd_tlv,
22665 	.send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv,
22666 	.send_roam_scan_offload_scan_period_cmd =
22667 		 send_roam_scan_offload_scan_period_cmd_tlv,
22668 	.send_roam_scan_offload_chan_list_cmd =
22669 		 send_roam_scan_offload_chan_list_cmd_tlv,
22670 	.send_roam_scan_offload_rssi_change_cmd =
22671 		 send_roam_scan_offload_rssi_change_cmd_tlv,
22672 #ifdef FEATURE_WLAN_APF
22673 	.send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv,
22674 	.send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv,
22675 	.send_apf_write_work_memory_cmd =
22676 				wmi_send_apf_write_work_memory_cmd_tlv,
22677 	.send_apf_read_work_memory_cmd =
22678 				wmi_send_apf_read_work_memory_cmd_tlv,
22679 	.extract_apf_read_memory_resp_event =
22680 				wmi_extract_apf_read_memory_resp_event_tlv,
22681 #endif /* FEATURE_WLAN_APF */
22682 	.send_adapt_dwelltime_params_cmd =
22683 		send_adapt_dwelltime_params_cmd_tlv,
22684 	.send_dbs_scan_sel_params_cmd =
22685 		send_dbs_scan_sel_params_cmd_tlv,
22686 	.init_cmd_send = init_cmd_send_tlv,
22687 	.send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv,
22688 	.send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv,
22689 	.send_set_ctl_table_cmd = send_set_ctl_table_cmd_tlv,
22690 	.send_set_mimogain_table_cmd = send_set_mimogain_table_cmd_tlv,
22691 	.send_packet_power_info_get_cmd = send_packet_power_info_get_cmd_tlv,
22692 	.send_vdev_config_ratemask_cmd = send_vdev_config_ratemask_cmd_tlv,
22693 	.send_vdev_set_custom_aggr_size_cmd =
22694 		send_vdev_set_custom_aggr_size_cmd_tlv,
22695 	.send_vdev_set_qdepth_thresh_cmd =
22696 		send_vdev_set_qdepth_thresh_cmd_tlv,
22697 	.send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv,
22698 	.send_vdev_set_neighbour_rx_cmd = send_vdev_set_neighbour_rx_cmd_tlv,
22699 	.send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_tlv,
22700 	.send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_tlv,
22701 	.send_smart_ant_set_training_info_cmd =
22702 		send_smart_ant_set_training_info_cmd_tlv,
22703 	.send_smart_ant_set_node_config_cmd =
22704 		send_smart_ant_set_node_config_cmd_tlv,
22705 #ifdef WLAN_ATF_ENABLE
22706 	.send_set_atf_cmd = send_set_atf_cmd_tlv,
22707 #endif
22708 	.send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv,
22709 	.send_set_qboost_param_cmd = send_set_qboost_param_cmd_tlv,
22710 	.send_gpio_config_cmd = send_gpio_config_cmd_tlv,
22711 	.send_gpio_output_cmd = send_gpio_output_cmd_tlv,
22712 	.send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv,
22713 	.send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv,
22714 	.send_periodic_chan_stats_config_cmd =
22715 		send_periodic_chan_stats_config_cmd_tlv,
22716 	.send_nf_dbr_dbm_info_get_cmd = send_nf_dbr_dbm_info_get_cmd_tlv,
22717 	.send_set_ht_ie_cmd = send_set_ht_ie_cmd_tlv,
22718 	.send_set_vht_ie_cmd = send_set_vht_ie_cmd_tlv,
22719 	.send_set_quiet_mode_cmd = send_set_quiet_mode_cmd_tlv,
22720 	.send_set_bwf_cmd = send_set_bwf_cmd_tlv,
22721 	.send_mcast_group_update_cmd = send_mcast_group_update_cmd_tlv,
22722 	.send_vdev_spectral_configure_cmd =
22723 				send_vdev_spectral_configure_cmd_tlv,
22724 	.send_vdev_spectral_enable_cmd =
22725 				send_vdev_spectral_enable_cmd_tlv,
22726 	.send_thermal_mitigation_param_cmd =
22727 		send_thermal_mitigation_param_cmd_tlv,
22728 	.send_pdev_qvit_cmd = send_pdev_qvit_cmd_tlv,
22729 	.send_wmm_update_cmd = send_wmm_update_cmd_tlv,
22730 	.send_process_update_edca_param_cmd =
22731 				 send_process_update_edca_param_cmd_tlv,
22732 	.send_coex_config_cmd = send_coex_config_cmd_tlv,
22733 	.send_set_country_cmd = send_set_country_cmd_tlv,
22734 	.send_bcn_offload_control_cmd = send_bcn_offload_control_cmd_tlv,
22735 	.send_addba_send_cmd = send_addba_send_cmd_tlv,
22736 	.send_delba_send_cmd = send_delba_send_cmd_tlv,
22737 	.send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv,
22738 	.get_target_cap_from_service_ready = extract_service_ready_tlv,
22739 	.extract_hal_reg_cap = extract_hal_reg_cap_tlv,
22740 	.extract_host_mem_req = extract_host_mem_req_tlv,
22741 	.save_service_bitmap = save_service_bitmap_tlv,
22742 	.save_ext_service_bitmap = save_ext_service_bitmap_tlv,
22743 	.is_service_enabled = is_service_enabled_tlv,
22744 	.save_fw_version = save_fw_version_in_service_ready_tlv,
22745 	.ready_extract_init_status = ready_extract_init_status_tlv,
22746 	.ready_extract_mac_addr = ready_extract_mac_addr_tlv,
22747 	.ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv,
22748 	.extract_ready_event_params = extract_ready_event_params_tlv,
22749 	.extract_dbglog_data_len = extract_dbglog_data_len_tlv,
22750 	.extract_vdev_start_resp = extract_vdev_start_resp_tlv,
22751 	.extract_vdev_delete_resp = extract_vdev_delete_resp_tlv,
22752 	.extract_tbttoffset_update_params =
22753 				extract_tbttoffset_update_params_tlv,
22754 	.extract_ext_tbttoffset_update_params =
22755 				extract_ext_tbttoffset_update_params_tlv,
22756 	.extract_tbttoffset_num_vdevs =
22757 				extract_tbttoffset_num_vdevs_tlv,
22758 	.extract_ext_tbttoffset_num_vdevs =
22759 				extract_ext_tbttoffset_num_vdevs_tlv,
22760 	.extract_mgmt_rx_params = extract_mgmt_rx_params_tlv,
22761 	.extract_vdev_stopped_param = extract_vdev_stopped_param_tlv,
22762 	.extract_vdev_roam_param = extract_vdev_roam_param_tlv,
22763 	.extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv,
22764 #ifdef CONVERGED_TDLS_ENABLE
22765 	.extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv,
22766 #endif
22767 	.extract_mgmt_tx_compl_param = extract_mgmt_tx_compl_param_tlv,
22768 	.extract_swba_num_vdevs = extract_swba_num_vdevs_tlv,
22769 	.extract_swba_tim_info = extract_swba_tim_info_tlv,
22770 	.extract_swba_noa_info = extract_swba_noa_info_tlv,
22771 #ifdef CONVERGED_P2P_ENABLE
22772 	.extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv,
22773 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
22774 	.extract_p2p_lo_stop_ev_param =
22775 				extract_p2p_lo_stop_ev_param_tlv,
22776 #endif
22777 #endif
22778 	.extract_offchan_data_tx_compl_param =
22779 				extract_offchan_data_tx_compl_param_tlv,
22780 	.extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv,
22781 	.extract_all_stats_count = extract_all_stats_counts_tlv,
22782 	.extract_pdev_stats = extract_pdev_stats_tlv,
22783 	.extract_unit_test = extract_unit_test_tlv,
22784 	.extract_pdev_ext_stats = extract_pdev_ext_stats_tlv,
22785 	.extract_vdev_stats = extract_vdev_stats_tlv,
22786 	.extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv,
22787 	.extract_peer_stats = extract_peer_stats_tlv,
22788 	.extract_bcn_stats = extract_bcn_stats_tlv,
22789 	.extract_bcnflt_stats = extract_bcnflt_stats_tlv,
22790 	.extract_peer_extd_stats = extract_peer_extd_stats_tlv,
22791 	.extract_chan_stats = extract_chan_stats_tlv,
22792 	.extract_profile_ctx = extract_profile_ctx_tlv,
22793 	.extract_profile_data = extract_profile_data_tlv,
22794 	.extract_chan_info_event = extract_chan_info_event_tlv,
22795 	.extract_channel_hopping_event = extract_channel_hopping_event_tlv,
22796 	.send_fw_test_cmd = send_fw_test_cmd_tlv,
22797 #ifdef WLAN_FEATURE_DISA
22798 	.send_encrypt_decrypt_send_cmd =
22799 				send_encrypt_decrypt_send_cmd_tlv,
22800 	.extract_encrypt_decrypt_resp_event =
22801 				extract_encrypt_decrypt_resp_event_tlv,
22802 #endif
22803 	.send_sar_limit_cmd = send_sar_limit_cmd_tlv,
22804 	.get_sar_limit_cmd = get_sar_limit_cmd_tlv,
22805 	.extract_sar_limit_event = extract_sar_limit_event_tlv,
22806 	.extract_sar2_result_event = extract_sar2_result_event_tlv,
22807 	.send_power_dbg_cmd = send_power_dbg_cmd_tlv,
22808 	.send_multiple_vdev_restart_req_cmd =
22809 				send_multiple_vdev_restart_req_cmd_tlv,
22810 	.extract_service_ready_ext = extract_service_ready_ext_tlv,
22811 	.extract_hw_mode_cap_service_ready_ext =
22812 				extract_hw_mode_cap_service_ready_ext_tlv,
22813 	.extract_mac_phy_cap_service_ready_ext =
22814 				extract_mac_phy_cap_service_ready_ext_tlv,
22815 	.extract_reg_cap_service_ready_ext =
22816 				extract_reg_cap_service_ready_ext_tlv,
22817 	.extract_dbr_ring_cap_service_ready_ext =
22818 				extract_dbr_ring_cap_service_ready_ext_tlv,
22819 	.extract_sar_cap_service_ready_ext =
22820 				extract_sar_cap_service_ready_ext_tlv,
22821 	.extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv,
22822 	.extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv,
22823 	.extract_dbr_buf_metadata = extract_dbr_buf_metadata_tlv,
22824 	.extract_pdev_utf_event = extract_pdev_utf_event_tlv,
22825 	.wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv,
22826 	.extract_dcs_interference_type = extract_dcs_interference_type_tlv,
22827 	.extract_dcs_cw_int = extract_dcs_cw_int_tlv,
22828 	.extract_dcs_im_tgt_stats = extract_dcs_im_tgt_stats_tlv,
22829 	.extract_fips_event_data = extract_fips_event_data_tlv,
22830 	.send_pdev_fips_cmd = send_pdev_fips_cmd_tlv,
22831 	.extract_peer_delete_response_event =
22832 				extract_peer_delete_response_event_tlv,
22833 	.is_management_record = is_management_record_tlv,
22834 	.extract_pdev_csa_switch_count_status =
22835 				extract_pdev_csa_switch_count_status_tlv,
22836 	.extract_pdev_tpc_ev_param = extract_pdev_tpc_ev_param_tlv,
22837 	.extract_pdev_tpc_config_ev_param =
22838 			extract_pdev_tpc_config_ev_param_tlv,
22839 	.extract_nfcal_power_ev_param = extract_nfcal_power_ev_param_tlv,
22840 	.extract_wds_addr_event = extract_wds_addr_event_tlv,
22841 	.extract_peer_sta_ps_statechange_ev =
22842 		extract_peer_sta_ps_statechange_ev_tlv,
22843 	.extract_inst_rssi_stats_event = extract_inst_rssi_stats_event_tlv,
22844 	.send_per_roam_config_cmd = send_per_roam_config_cmd_tlv,
22845 #ifdef WLAN_FEATURE_ACTION_OUI
22846 	.send_action_oui_cmd = send_action_oui_cmd_tlv,
22847 #endif
22848 	.send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv,
22849 	.send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv,
22850 	.extract_reg_chan_list_update_event =
22851 		extract_reg_chan_list_update_event_tlv,
22852 	.extract_chainmask_tables =
22853 		extract_chainmask_tables_tlv,
22854 	.extract_thermal_stats = extract_thermal_stats_tlv,
22855 	.extract_thermal_level_stats = extract_thermal_level_stats_tlv,
22856 	.send_get_rcpi_cmd = send_get_rcpi_cmd_tlv,
22857 	.extract_rcpi_response_event = extract_rcpi_response_event_tlv,
22858 #ifdef DFS_COMPONENT_ENABLE
22859 	.extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv,
22860 	.extract_dfs_radar_detection_event =
22861 		extract_dfs_radar_detection_event_tlv,
22862 	.extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv,
22863 #endif
22864 	.convert_pdev_id_host_to_target =
22865 		convert_host_pdev_id_to_target_pdev_id_legacy,
22866 	.convert_pdev_id_target_to_host =
22867 		convert_target_pdev_id_to_host_pdev_id_legacy,
22868 
22869 	.send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv,
22870 	.send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv,
22871 	.extract_reg_11d_new_country_event =
22872 		extract_reg_11d_new_country_event_tlv,
22873 	.send_user_country_code_cmd = send_user_country_code_cmd_tlv,
22874 	.send_limit_off_chan_cmd =
22875 		send_limit_off_chan_cmd_tlv,
22876 	.extract_reg_ch_avoid_event =
22877 		extract_reg_ch_avoid_event_tlv,
22878 	.send_pdev_caldata_version_check_cmd =
22879 			send_pdev_caldata_version_check_cmd_tlv,
22880 	.extract_pdev_caldata_version_check_ev_param =
22881 			extract_pdev_caldata_version_check_ev_param_tlv,
22882 	.send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv,
22883 	.send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv,
22884 	.send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv,
22885 #if defined(WLAN_FEATURE_FILS_SK)
22886 	.send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv,
22887 #endif
22888 	.send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv,
22889 #ifdef WLAN_FEATURE_NAN_CONVERGENCE
22890 	.send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv,
22891 	.send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv,
22892 	.send_ndp_end_req_cmd = nan_ndp_end_req_tlv,
22893 	.extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv,
22894 	.extract_ndp_ind = extract_ndp_ind_tlv,
22895 	.extract_ndp_confirm = extract_ndp_confirm_tlv,
22896 	.extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv,
22897 	.extract_ndp_end_rsp = extract_ndp_end_rsp_tlv,
22898 	.extract_ndp_end_ind = extract_ndp_end_ind_tlv,
22899 	.extract_ndp_sch_update = extract_ndp_sch_update_tlv,
22900 #endif
22901 	.send_btm_config = send_btm_config_cmd_tlv,
22902 	.send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv,
22903 	.extract_obss_detection_info = extract_obss_detection_info_tlv,
22904 #ifdef WLAN_SUPPORT_FILS
22905 	.send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_tlv,
22906 	.extract_swfda_vdev_id = extract_swfda_vdev_id_tlv,
22907 	.send_fils_discovery_send_cmd = send_fils_discovery_send_cmd_tlv,
22908 #endif /* WLAN_SUPPORT_FILS */
22909 	.send_offload_11k_cmd = send_offload_11k_cmd_tlv,
22910 	.send_invoke_neighbor_report_cmd = send_invoke_neighbor_report_cmd_tlv,
22911 	.wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable,
22912 	.wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs,
22913 	.wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs,
22914 	.wmi_check_command_params = wmitlv_check_command_tlv_params,
22915 	.send_bss_color_change_enable_cmd =
22916 		send_bss_color_change_enable_cmd_tlv,
22917 	.send_obss_color_collision_cfg_cmd =
22918 		send_obss_color_collision_cfg_cmd_tlv,
22919 	.extract_obss_color_collision_info =
22920 		extract_obss_color_collision_info_tlv,
22921 	.extract_comb_phyerr = extract_comb_phyerr_tlv,
22922 	.extract_single_phyerr = extract_single_phyerr_tlv,
22923 #ifdef QCA_SUPPORT_CP_STATS
22924 	.extract_cca_stats = extract_cca_stats_tlv,
22925 #endif
22926 	.extract_esp_estimation_ev_param =
22927 				extract_esp_estimation_ev_param_tlv,
22928 	.send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv,
22929 	.extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv,
22930 };
22931 
22932 /**
22933  * populate_tlv_event_id() - populates wmi event ids
22934  *
22935  * @param event_ids: Pointer to hold event ids
22936  * Return: None
22937  */
22938 static void populate_tlv_events_id(uint32_t *event_ids)
22939 {
22940 	event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID;
22941 	event_ids[wmi_ready_event_id] = WMI_READY_EVENTID;
22942 	event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID;
22943 	event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID;
22944 	event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID;
22945 	event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID;
22946 	event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID;
22947 	event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID;
22948 	event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID;
22949 	event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID;
22950 	event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID;
22951 	event_ids[wmi_service_ready_ext_event_id] =
22952 						WMI_SERVICE_READY_EXT_EVENTID;
22953 	event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID;
22954 	event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID;
22955 	event_ids[wmi_vdev_install_key_complete_event_id] =
22956 				WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID;
22957 	event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] =
22958 				WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID;
22959 
22960 	event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID;
22961 	event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID;
22962 	event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID;
22963 	event_ids[wmi_peer_tx_fail_cnt_thr_event_id] =
22964 				WMI_PEER_TX_FAIL_CNT_THR_EVENTID;
22965 	event_ids[wmi_peer_estimated_linkspeed_event_id] =
22966 				WMI_PEER_ESTIMATED_LINKSPEED_EVENTID;
22967 	event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID;
22968 	event_ids[wmi_peer_delete_response_event_id] =
22969 					WMI_PEER_DELETE_RESP_EVENTID;
22970 	event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID;
22971 	event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID;
22972 	event_ids[wmi_tbttoffset_update_event_id] =
22973 					WMI_TBTTOFFSET_UPDATE_EVENTID;
22974 	event_ids[wmi_ext_tbttoffset_update_event_id] =
22975 					WMI_TBTTOFFSET_EXT_UPDATE_EVENTID;
22976 	event_ids[wmi_offload_bcn_tx_status_event_id] =
22977 				WMI_OFFLOAD_BCN_TX_STATUS_EVENTID;
22978 	event_ids[wmi_offload_prob_resp_tx_status_event_id] =
22979 				WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID;
22980 	event_ids[wmi_mgmt_tx_completion_event_id] =
22981 				WMI_MGMT_TX_COMPLETION_EVENTID;
22982 	event_ids[wmi_pdev_nfcal_power_all_channels_event_id] =
22983 				WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID;
22984 	event_ids[wmi_tx_delba_complete_event_id] =
22985 					WMI_TX_DELBA_COMPLETE_EVENTID;
22986 	event_ids[wmi_tx_addba_complete_event_id] =
22987 					WMI_TX_ADDBA_COMPLETE_EVENTID;
22988 	event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID;
22989 
22990 	event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID;
22991 
22992 	event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID;
22993 	event_ids[wmi_profile_match] = WMI_PROFILE_MATCH;
22994 
22995 	event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID;
22996 	event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID;
22997 
22998 	event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID;
22999 
23000 	event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID;
23001 	event_ids[wmi_p2p_lo_stop_event_id] =
23002 				WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID;
23003 	event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID;
23004 	event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID;
23005 	event_ids[wmi_d0_wow_disable_ack_event_id] =
23006 				WMI_D0_WOW_DISABLE_ACK_EVENTID;
23007 	event_ids[wmi_wow_initial_wakeup_event_id] =
23008 				WMI_WOW_INITIAL_WAKEUP_EVENTID;
23009 
23010 	event_ids[wmi_rtt_meas_report_event_id] =
23011 				WMI_RTT_MEASUREMENT_REPORT_EVENTID;
23012 	event_ids[wmi_tsf_meas_report_event_id] =
23013 				WMI_TSF_MEASUREMENT_REPORT_EVENTID;
23014 	event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID;
23015 	event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID;
23016 	event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID;
23017 	event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID;
23018 	event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID;
23019 	event_ids[wmi_diag_event_id_log_supported_event_id] =
23020 				WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID;
23021 	event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID;
23022 	event_ids[wmi_nlo_scan_complete_event_id] =
23023 					WMI_NLO_SCAN_COMPLETE_EVENTID;
23024 	event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID;
23025 	event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID;
23026 
23027 	event_ids[wmi_gtk_offload_status_event_id] =
23028 				WMI_GTK_OFFLOAD_STATUS_EVENTID;
23029 	event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID;
23030 	event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID;
23031 	event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID;
23032 
23033 	event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID;
23034 
23035 	event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID;
23036 
23037 	event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID;
23038 	event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID;
23039 	event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID;
23040 	event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID;
23041 	event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID;
23042 	event_ids[wmi_wlan_profile_data_event_id] =
23043 						WMI_WLAN_PROFILE_DATA_EVENTID;
23044 	event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID;
23045 	event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID;
23046 	event_ids[wmi_vdev_get_keepalive_event_id] =
23047 				WMI_VDEV_GET_KEEPALIVE_EVENTID;
23048 	event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID;
23049 
23050 	event_ids[wmi_diag_container_event_id] =
23051 						WMI_DIAG_DATA_CONTAINER_EVENTID;
23052 
23053 	event_ids[wmi_host_auto_shutdown_event_id] =
23054 				WMI_HOST_AUTO_SHUTDOWN_EVENTID;
23055 
23056 	event_ids[wmi_update_whal_mib_stats_event_id] =
23057 				WMI_UPDATE_WHAL_MIB_STATS_EVENTID;
23058 
23059 	/*update ht/vht info based on vdev (rx and tx NSS and preamble) */
23060 	event_ids[wmi_update_vdev_rate_stats_event_id] =
23061 				WMI_UPDATE_VDEV_RATE_STATS_EVENTID;
23062 
23063 	event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID;
23064 	event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID;
23065 
23066 	/** Set OCB Sched Response, deprecated */
23067 	event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID;
23068 
23069 	event_ids[wmi_dbg_mesg_flush_complete_event_id] =
23070 				WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID;
23071 	event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID;
23072 
23073 	/* GPIO Event */
23074 	event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID;
23075 	event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID;
23076 
23077 	event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID;
23078 	event_ids[wmi_rfkill_state_change_event_id] =
23079 				WMI_RFKILL_STATE_CHANGE_EVENTID;
23080 
23081 	/* TDLS Event */
23082 	event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID;
23083 
23084 	event_ids[wmi_batch_scan_enabled_event_id] =
23085 				WMI_BATCH_SCAN_ENABLED_EVENTID;
23086 	event_ids[wmi_batch_scan_result_event_id] =
23087 				WMI_BATCH_SCAN_RESULT_EVENTID;
23088 	/* OEM Event */
23089 	event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID;
23090 	event_ids[wmi_oem_meas_report_event_id] =
23091 				WMI_OEM_MEASUREMENT_REPORT_EVENTID;
23092 	event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID;
23093 
23094 	/* NAN Event */
23095 	event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID;
23096 
23097 	/* LPI Event */
23098 	event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID;
23099 	event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID;
23100 	event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID;
23101 
23102 	/* ExtScan events */
23103 	event_ids[wmi_extscan_start_stop_event_id] =
23104 				WMI_EXTSCAN_START_STOP_EVENTID;
23105 	event_ids[wmi_extscan_operation_event_id] =
23106 				WMI_EXTSCAN_OPERATION_EVENTID;
23107 	event_ids[wmi_extscan_table_usage_event_id] =
23108 				WMI_EXTSCAN_TABLE_USAGE_EVENTID;
23109 	event_ids[wmi_extscan_cached_results_event_id] =
23110 				WMI_EXTSCAN_CACHED_RESULTS_EVENTID;
23111 	event_ids[wmi_extscan_wlan_change_results_event_id] =
23112 				WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID;
23113 	event_ids[wmi_extscan_hotlist_match_event_id] =
23114 				WMI_EXTSCAN_HOTLIST_MATCH_EVENTID;
23115 	event_ids[wmi_extscan_capabilities_event_id] =
23116 				WMI_EXTSCAN_CAPABILITIES_EVENTID;
23117 	event_ids[wmi_extscan_hotlist_ssid_match_event_id] =
23118 				WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID;
23119 
23120 	/* mDNS offload events */
23121 	event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID;
23122 
23123 	/* SAP Authentication offload events */
23124 	event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID;
23125 	event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID;
23126 
23127 	/** Out-of-context-of-bss (OCB) events */
23128 	event_ids[wmi_ocb_set_config_resp_event_id] =
23129 				WMI_OCB_SET_CONFIG_RESP_EVENTID;
23130 	event_ids[wmi_ocb_get_tsf_timer_resp_event_id] =
23131 				WMI_OCB_GET_TSF_TIMER_RESP_EVENTID;
23132 	event_ids[wmi_dcc_get_stats_resp_event_id] =
23133 				WMI_DCC_GET_STATS_RESP_EVENTID;
23134 	event_ids[wmi_dcc_update_ndl_resp_event_id] =
23135 				WMI_DCC_UPDATE_NDL_RESP_EVENTID;
23136 	event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID;
23137 	/* System-On-Chip events */
23138 	event_ids[wmi_soc_set_hw_mode_resp_event_id] =
23139 				WMI_SOC_SET_HW_MODE_RESP_EVENTID;
23140 	event_ids[wmi_soc_hw_mode_transition_event_id] =
23141 				WMI_SOC_HW_MODE_TRANSITION_EVENTID;
23142 	event_ids[wmi_soc_set_dual_mac_config_resp_event_id] =
23143 				WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID;
23144 	event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID;
23145 	event_ids[wmi_pdev_csa_switch_count_status_event_id] =
23146 				WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID;
23147 	event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID;
23148 	event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID;
23149 	event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID;
23150 	event_ids[wmi_peer_sta_ps_statechg_event_id] =
23151 					WMI_PEER_STA_PS_STATECHG_EVENTID;
23152 	event_ids[wmi_pdev_channel_hopping_event_id] =
23153 					WMI_PDEV_CHANNEL_HOPPING_EVENTID;
23154 	event_ids[wmi_offchan_data_tx_completion_event] =
23155 				WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID;
23156 	event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID;
23157 	event_ids[wmi_dfs_radar_detection_event_id] =
23158 		WMI_PDEV_DFS_RADAR_DETECTION_EVENTID;
23159 	event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID;
23160 	event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID;
23161 	event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID;
23162 	event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID;
23163 	event_ids[wmi_service_available_event_id] =
23164 						WMI_SERVICE_AVAILABLE_EVENTID;
23165 	event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID;
23166 	event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID;
23167 	/* NDP events */
23168 	event_ids[wmi_ndp_initiator_rsp_event_id] =
23169 		WMI_NDP_INITIATOR_RSP_EVENTID;
23170 	event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID;
23171 	event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID;
23172 	event_ids[wmi_ndp_responder_rsp_event_id] =
23173 		WMI_NDP_RESPONDER_RSP_EVENTID;
23174 	event_ids[wmi_ndp_end_indication_event_id] =
23175 		WMI_NDP_END_INDICATION_EVENTID;
23176 	event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID;
23177 	event_ids[wmi_ndl_schedule_update_event_id] =
23178 					WMI_NDL_SCHEDULE_UPDATE_EVENTID;
23179 
23180 	event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID;
23181 	event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID;
23182 	event_ids[wmi_pdev_chip_power_stats_event_id] =
23183 		WMI_PDEV_CHIP_POWER_STATS_EVENTID;
23184 	event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID;
23185 	event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID;
23186 	event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID;
23187 	event_ids[wmi_apf_capability_info_event_id] =
23188 		WMI_BPF_CAPABILIY_INFO_EVENTID;
23189 	event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] =
23190 		WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID;
23191 	event_ids[wmi_report_rx_aggr_failure_event_id] =
23192 		WMI_REPORT_RX_AGGR_FAILURE_EVENTID;
23193 	event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] =
23194 		WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID;
23195 	event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID;
23196 	event_ids[wmi_pdev_set_hw_mode_rsp_event_id] =
23197 		WMI_PDEV_SET_HW_MODE_RESP_EVENTID;
23198 	event_ids[wmi_pdev_hw_mode_transition_event_id] =
23199 		WMI_PDEV_HW_MODE_TRANSITION_EVENTID;
23200 	event_ids[wmi_pdev_set_mac_config_resp_event_id] =
23201 		WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID;
23202 	event_ids[wmi_coex_bt_activity_event_id] =
23203 		WMI_WLAN_COEX_BT_ACTIVITY_EVENTID;
23204 	event_ids[wmi_mgmt_tx_bundle_completion_event_id] =
23205 		WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID;
23206 	event_ids[wmi_radio_tx_power_level_stats_event_id] =
23207 		WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID;
23208 	event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID;
23209 	event_ids[wmi_dma_buf_release_event_id] =
23210 					WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID;
23211 	event_ids[wmi_sap_obss_detection_report_event_id] =
23212 		WMI_SAP_OBSS_DETECTION_REPORT_EVENTID;
23213 	event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID;
23214 	event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID;
23215 	event_ids[wmi_obss_color_collision_report_event_id] =
23216 		WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID;
23217 	event_ids[wmi_pdev_div_rssi_antid_event_id] =
23218 		WMI_PDEV_DIV_RSSI_ANTID_EVENTID;
23219 	event_ids[wmi_twt_enable_complete_event_id] =
23220 		WMI_TWT_ENABLE_COMPLETE_EVENTID;
23221 	event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] =
23222 		WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID;
23223 	event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID;
23224 	event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID;
23225 	event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID;
23226 }
23227 
23228 /**
23229  * populate_tlv_service() - populates wmi services
23230  *
23231  * @param wmi_service: Pointer to hold wmi_service
23232  * Return: None
23233  */
23234 static void populate_tlv_service(uint32_t *wmi_service)
23235 {
23236 	wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD;
23237 	wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT;
23238 	wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD;
23239 	wmi_service[wmi_service_roam_scan_offload] =
23240 					WMI_SERVICE_ROAM_SCAN_OFFLOAD;
23241 	wmi_service[wmi_service_bcn_miss_offload] =
23242 					WMI_SERVICE_BCN_MISS_OFFLOAD;
23243 	wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE;
23244 	wmi_service[wmi_service_sta_advanced_pwrsave] =
23245 				WMI_SERVICE_STA_ADVANCED_PWRSAVE;
23246 	wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD;
23247 	wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS;
23248 	wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC;
23249 	wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK;
23250 	wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR;
23251 	wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER;
23252 	wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT;
23253 	wmi_service[wmi_service_wow] = WMI_SERVICE_WOW;
23254 	wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE;
23255 	wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS;
23256 	wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD;
23257 	wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO;
23258 	wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD;
23259 	wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH;
23260 	wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD;
23261 	wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER;
23262 	wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID;
23263 	wmi_service[wmi_service_packet_power_save] =
23264 					WMI_SERVICE_PACKET_POWER_SAVE;
23265 	wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG;
23266 	wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO;
23267 	wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] =
23268 				WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM;
23269 	wmi_service[wmi_sta_uapsd_basic_auto_trig] =
23270 					WMI_STA_UAPSD_BASIC_AUTO_TRIG;
23271 	wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG;
23272 	wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE;
23273 	wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP;
23274 	wmi_service[wmi_service_ap_ps_detect_out_of_sync] =
23275 				WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC;
23276 	wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX;
23277 	wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS;
23278 	wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST;
23279 	wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC;
23280 	wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS;
23281 	wmi_service[wmi_service_burst] = WMI_SERVICE_BURST;
23282 	wmi_service[wmi_service_mcc_bcn_interval_change] =
23283 				WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE;
23284 	wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS;
23285 	wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT;
23286 	wmi_service[wmi_service_filter_ipsec_natkeepalive] =
23287 				WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE;
23288 	wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB;
23289 	wmi_service[wmi_service_lte_ant_share_support] =
23290 				WMI_SERVICE_LTE_ANT_SHARE_SUPPORT;
23291 	wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN;
23292 	wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER;
23293 	wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ;
23294 	wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT;
23295 	wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC;
23296 	wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD;
23297 	wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR;
23298 	wmi_service[wmi_service_bcn_txrate_override] =
23299 				WMI_SERVICE_BCN_TXRATE_OVERRIDE;
23300 	wmi_service[wmi_service_nan] = WMI_SERVICE_NAN;
23301 	wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT;
23302 	wmi_service[wmi_service_estimate_linkspeed] =
23303 				WMI_SERVICE_ESTIMATE_LINKSPEED;
23304 	wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN;
23305 	wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN;
23306 	wmi_service[wmi_service_tdls_uapsd_buffer_sta] =
23307 				WMI_SERVICE_TDLS_UAPSD_BUFFER_STA;
23308 	wmi_service[wmi_service_tdls_uapsd_sleep_sta] =
23309 				WMI_SERVICE_TDLS_UAPSD_SLEEP_STA;
23310 	wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE;
23311 	wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS;
23312 	wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN;
23313 	wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW;
23314 	wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD;
23315 	wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD;
23316 	wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER;
23317 	wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD;
23318 	wmi_service[wmi_service_sta_rx_ipa_offload_support] =
23319 				WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT;
23320 	wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD;
23321 	wmi_service[wmi_service_sap_auth_offload] =
23322 					WMI_SERVICE_SAP_AUTH_OFFLOAD;
23323 	wmi_service[wmi_service_dual_band_simultaneous_support] =
23324 				WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT;
23325 	wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB;
23326 	wmi_service[wmi_service_ap_arpns_offload] =
23327 					WMI_SERVICE_AP_ARPNS_OFFLOAD;
23328 	wmi_service[wmi_service_per_band_chainmask_support] =
23329 				WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT;
23330 	wmi_service[wmi_service_packet_filter_offload] =
23331 				WMI_SERVICE_PACKET_FILTER_OFFLOAD;
23332 	wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT;
23333 	wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI;
23334 	wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG;
23335 	wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC;
23336 	wmi_service[wmi_service_multiple_vdev_restart] =
23337 			WMI_SERVICE_MULTIPLE_VDEV_RESTART;
23338 
23339 	wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE;
23340 	wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE;
23341 	wmi_service[wmi_service_smart_antenna_sw_support] =
23342 				WMI_SERVICE_UNAVAILABLE;
23343 	wmi_service[wmi_service_smart_antenna_hw_support] =
23344 				WMI_SERVICE_UNAVAILABLE;
23345 	wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE;
23346 	wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT;
23347 	wmi_service[wmi_service_atf] = WMI_SERVICE_ATF;
23348 	wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE;
23349 	wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE;
23350 	wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE;
23351 	wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE;
23352 	wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE;
23353 	wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE;
23354 	wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE;
23355 	wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE;
23356 	wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE;
23357 	wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE;
23358 	wmi_service[wmi_service_periodic_chan_stat_support] =
23359 			WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT;
23360 	wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE;
23361 	wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE;
23362 	wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE;
23363 	wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE;
23364 	wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE;
23365 	wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH;
23366 	wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF;
23367 	wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP;
23368 	wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD;
23369 	wmi_service[wmi_service_unified_wow_capability] =
23370 				WMI_SERVICE_UNIFIED_WOW_CAPABILITY;
23371 	wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH;
23372 	wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD;
23373 	wmi_service[wmi_service_sync_delete_cmds] =
23374 				WMI_SERVICE_SYNC_DELETE_CMDS;
23375 	wmi_service[wmi_service_ratectrl_limit_max_min_rates] =
23376 				WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES;
23377 	wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA;
23378 	wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT;
23379 	wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX;
23380 	wmi_service[wmi_service_deprecated_replace] =
23381 				WMI_SERVICE_DEPRECATED_REPLACE;
23382 	wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] =
23383 				WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE;
23384 	wmi_service[wmi_service_enhanced_mcast_filter] =
23385 				WMI_SERVICE_ENHANCED_MCAST_FILTER;
23386 	wmi_service[wmi_service_half_rate_quarter_rate_support] =
23387 				WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT;
23388 	wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER;
23389 	wmi_service[wmi_service_p2p_listen_offload_support] =
23390 				WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT;
23391 	wmi_service[wmi_service_mark_first_wakeup_packet] =
23392 				WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET;
23393 	wmi_service[wmi_service_multiple_mcast_filter_set] =
23394 				WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET;
23395 	wmi_service[wmi_service_host_managed_rx_reorder] =
23396 				WMI_SERVICE_HOST_MANAGED_RX_REORDER;
23397 	wmi_service[wmi_service_flash_rdwr_support] =
23398 				WMI_SERVICE_FLASH_RDWR_SUPPORT;
23399 	wmi_service[wmi_service_wlan_stats_report] =
23400 				WMI_SERVICE_WLAN_STATS_REPORT;
23401 	wmi_service[wmi_service_tx_msdu_id_new_partition_support] =
23402 				WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT;
23403 	wmi_service[wmi_service_dfs_phyerr_offload] =
23404 				WMI_SERVICE_DFS_PHYERR_OFFLOAD;
23405 	wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT;
23406 	wmi_service[wmi_service_fw_mem_dump_support] =
23407 				WMI_SERVICE_FW_MEM_DUMP_SUPPORT;
23408 	wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO;
23409 	wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB;
23410 	wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD;
23411 	wmi_service[wmi_service_hw_data_filtering] =
23412 				WMI_SERVICE_HW_DATA_FILTERING;
23413 	wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING;
23414 	wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI;
23415 	wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO;
23416 	wmi_service[wmi_service_extended_nss_support] =
23417 				WMI_SERVICE_EXTENDED_NSS_SUPPORT;
23418 	wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT;
23419 	wmi_service[wmi_service_bcn_offload_start_stop_support] =
23420 				WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT;
23421 	wmi_service[wmi_service_offchan_data_tid_support] =
23422 				WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT;
23423 	wmi_service[wmi_service_support_dma] =
23424 				WMI_SERVICE_SUPPORT_DIRECT_DMA;
23425 	wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE;
23426 	wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT;
23427 	wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT;
23428 	wmi_service[wmi_service_wow_wakeup_by_timer_pattern] =
23429 				WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN;
23430 	wmi_service[wmi_service_11k_neighbour_report_support] =
23431 				WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT;
23432 	wmi_service[wmi_service_ap_obss_detection_offload] =
23433 				WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD;
23434 	wmi_service[wmi_service_bss_color_offload] =
23435 				WMI_SERVICE_BSS_COLOR_OFFLOAD;
23436 	wmi_service[wmi_service_gmac_offload_support] =
23437 				WMI_SERVICE_GMAC_OFFLOAD_SUPPORT;
23438 	wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] =
23439 			WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT;
23440 	wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] =
23441 			WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT;
23442 	wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT;
23443 	wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT;
23444 	wmi_service[wmi_service_listen_interval_offload_support] =
23445 			WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT;
23446 
23447 }
23448 
23449 #ifndef CONFIG_MCL
23450 
23451 /**
23452  * populate_pdev_param_tlv() - populates pdev params
23453  *
23454  * @param pdev_param: Pointer to hold pdev params
23455  * Return: None
23456  */
23457 static void populate_pdev_param_tlv(uint32_t *pdev_param)
23458 {
23459 	pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK;
23460 	pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK;
23461 	pdev_param[wmi_pdev_param_txpower_limit2g] =
23462 				WMI_PDEV_PARAM_TXPOWER_LIMIT2G;
23463 	pdev_param[wmi_pdev_param_txpower_limit5g] =
23464 				WMI_PDEV_PARAM_TXPOWER_LIMIT5G;
23465 	pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE;
23466 	pdev_param[wmi_pdev_param_beacon_gen_mode] =
23467 				WMI_PDEV_PARAM_BEACON_GEN_MODE;
23468 	pdev_param[wmi_pdev_param_beacon_tx_mode] =
23469 				WMI_PDEV_PARAM_BEACON_TX_MODE;
23470 	pdev_param[wmi_pdev_param_resmgr_offchan_mode] =
23471 				WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE;
23472 	pdev_param[wmi_pdev_param_protection_mode] =
23473 				WMI_PDEV_PARAM_PROTECTION_MODE;
23474 	pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW;
23475 	pdev_param[wmi_pdev_param_non_agg_sw_retry_th] =
23476 				WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH;
23477 	pdev_param[wmi_pdev_param_agg_sw_retry_th] =
23478 				WMI_PDEV_PARAM_AGG_SW_RETRY_TH;
23479 	pdev_param[wmi_pdev_param_sta_kickout_th] =
23480 				WMI_PDEV_PARAM_STA_KICKOUT_TH;
23481 	pdev_param[wmi_pdev_param_ac_aggrsize_scaling] =
23482 				WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING;
23483 	pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE;
23484 	pdev_param[wmi_pdev_param_ltr_ac_latency_be] =
23485 				WMI_PDEV_PARAM_LTR_AC_LATENCY_BE;
23486 	pdev_param[wmi_pdev_param_ltr_ac_latency_bk] =
23487 				WMI_PDEV_PARAM_LTR_AC_LATENCY_BK;
23488 	pdev_param[wmi_pdev_param_ltr_ac_latency_vi] =
23489 				WMI_PDEV_PARAM_LTR_AC_LATENCY_VI;
23490 	pdev_param[wmi_pdev_param_ltr_ac_latency_vo] =
23491 				WMI_PDEV_PARAM_LTR_AC_LATENCY_VO;
23492 	pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] =
23493 				WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT;
23494 	pdev_param[wmi_pdev_param_ltr_sleep_override] =
23495 				WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE;
23496 	pdev_param[wmi_pdev_param_ltr_rx_override] =
23497 				WMI_PDEV_PARAM_LTR_RX_OVERRIDE;
23498 	pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] =
23499 				WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT;
23500 	pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE;
23501 	pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE;
23502 	pdev_param[wmi_pdev_param_pcielp_txbuf_flush] =
23503 				WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH;
23504 	pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] =
23505 				WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK;
23506 	pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] =
23507 				WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN;
23508 	pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] =
23509 				WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE;
23510 	pdev_param[wmi_pdev_param_pdev_stats_update_period] =
23511 				WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD;
23512 	pdev_param[wmi_pdev_param_vdev_stats_update_period] =
23513 				WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD;
23514 	pdev_param[wmi_pdev_param_peer_stats_update_period] =
23515 				WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD;
23516 	pdev_param[wmi_pdev_param_bcnflt_stats_update_period] =
23517 				WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD;
23518 	pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS;
23519 	pdev_param[wmi_pdev_param_arp_ac_override] =
23520 				WMI_PDEV_PARAM_ARP_AC_OVERRIDE;
23521 	pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS;
23522 	pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE;
23523 	pdev_param[wmi_pdev_param_ani_poll_period] =
23524 				WMI_PDEV_PARAM_ANI_POLL_PERIOD;
23525 	pdev_param[wmi_pdev_param_ani_listen_period] =
23526 				WMI_PDEV_PARAM_ANI_LISTEN_PERIOD;
23527 	pdev_param[wmi_pdev_param_ani_ofdm_level] =
23528 				WMI_PDEV_PARAM_ANI_OFDM_LEVEL;
23529 	pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL;
23530 	pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN;
23531 	pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA;
23532 	pdev_param[wmi_pdev_param_idle_ps_config] =
23533 				WMI_PDEV_PARAM_IDLE_PS_CONFIG;
23534 	pdev_param[wmi_pdev_param_power_gating_sleep] =
23535 				WMI_PDEV_PARAM_POWER_GATING_SLEEP;
23536 	pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE;
23537 	pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR;
23538 	pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE;
23539 	pdev_param[wmi_pdev_param_hw_rfkill_config] =
23540 				WMI_PDEV_PARAM_HW_RFKILL_CONFIG;
23541 	pdev_param[wmi_pdev_param_low_power_rf_enable] =
23542 				WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE;
23543 	pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK;
23544 	pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN;
23545 	pdev_param[wmi_pdev_param_power_collapse_enable] =
23546 				WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE;
23547 	pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE;
23548 	pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE;
23549 	pdev_param[wmi_pdev_param_audio_over_wlan_latency] =
23550 				WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY;
23551 	pdev_param[wmi_pdev_param_audio_over_wlan_enable] =
23552 				WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE;
23553 	pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] =
23554 				WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE;
23555 	pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] =
23556 				WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD;
23557 	pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW;
23558 	pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG;
23559 	pdev_param[wmi_pdev_param_adaptive_early_rx_enable] =
23560 				WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE;
23561 	pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] =
23562 				WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP;
23563 	pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] =
23564 				WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP;
23565 	pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] =
23566 				WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP;
23567 	pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] =
23568 				WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE;
23569 	pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] =
23570 				WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT;
23571 	pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] =
23572 				WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP;
23573 	pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] =
23574 				WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT;
23575 	pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] =
23576 				WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE;
23577 	pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] =
23578 				WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE;
23579 	pdev_param[wmi_pdev_param_tx_chain_mask_2g] =
23580 				WMI_PDEV_PARAM_TX_CHAIN_MASK_2G;
23581 	pdev_param[wmi_pdev_param_rx_chain_mask_2g] =
23582 				WMI_PDEV_PARAM_RX_CHAIN_MASK_2G;
23583 	pdev_param[wmi_pdev_param_tx_chain_mask_5g] =
23584 				WMI_PDEV_PARAM_TX_CHAIN_MASK_5G;
23585 	pdev_param[wmi_pdev_param_rx_chain_mask_5g] =
23586 				WMI_PDEV_PARAM_RX_CHAIN_MASK_5G;
23587 	pdev_param[wmi_pdev_param_tx_chain_mask_cck] =
23588 				WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK;
23589 	pdev_param[wmi_pdev_param_tx_chain_mask_1ss] =
23590 				WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS;
23591 	pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER;
23592 	pdev_param[wmi_pdev_set_mcast_to_ucast_tid] =
23593 				WMI_PDEV_SET_MCAST_TO_UCAST_TID;
23594 	pdev_param[wmi_pdev_param_mgmt_retry_limit] =
23595 					WMI_PDEV_PARAM_MGMT_RETRY_LIMIT;
23596 	pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST;
23597 	pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] =
23598 					WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE;
23599 	pdev_param[wmi_pdev_param_proxy_sta_mode] =
23600 				WMI_PDEV_PARAM_PROXY_STA_MODE;
23601 	pdev_param[wmi_pdev_param_mu_group_policy] =
23602 				WMI_PDEV_PARAM_MU_GROUP_POLICY;
23603 	pdev_param[wmi_pdev_param_noise_detection] =
23604 				WMI_PDEV_PARAM_NOISE_DETECTION;
23605 	pdev_param[wmi_pdev_param_noise_threshold] =
23606 				WMI_PDEV_PARAM_NOISE_THRESHOLD;
23607 	pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE;
23608 	pdev_param[wmi_pdev_param_set_mcast_bcast_echo] =
23609 				WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO;
23610 	pdev_param[wmi_pdev_param_atf_strict_sch] =
23611 		WMI_PDEV_PARAM_ATF_STRICT_SCH;
23612 	pdev_param[wmi_pdev_param_atf_sched_duration] =
23613 		WMI_PDEV_PARAM_ATF_SCHED_DURATION;
23614 	pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN;
23615 	pdev_param[wmi_pdev_param_sensitivity_level] =
23616 				WMI_PDEV_PARAM_SENSITIVITY_LEVEL;
23617 	pdev_param[wmi_pdev_param_signed_txpower_2g] =
23618 				WMI_PDEV_PARAM_SIGNED_TXPOWER_2G;
23619 	pdev_param[wmi_pdev_param_signed_txpower_5g] =
23620 				WMI_PDEV_PARAM_SIGNED_TXPOWER_5G;
23621 	pdev_param[wmi_pdev_param_enable_per_tid_amsdu] =
23622 		WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU;
23623 	pdev_param[wmi_pdev_param_enable_per_tid_ampdu] =
23624 		WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU;
23625 	pdev_param[wmi_pdev_param_cca_threshold] =
23626 				WMI_PDEV_PARAM_CCA_THRESHOLD;
23627 	pdev_param[wmi_pdev_param_rts_fixed_rate] =
23628 				WMI_PDEV_PARAM_RTS_FIXED_RATE;
23629 	pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM;
23630 	pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET;
23631 	pdev_param[wmi_pdev_param_wapi_mbssid_offset] =
23632 				WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET;
23633 	pdev_param[wmi_pdev_param_arp_srcaddr] =
23634 				WMI_PDEV_PARAM_ARP_DBG_SRCADDR;
23635 	pdev_param[wmi_pdev_param_arp_dstaddr] =
23636 				WMI_PDEV_PARAM_ARP_DBG_DSTADDR;
23637 	pdev_param[wmi_pdev_param_txpower_decr_db] =
23638 				WMI_PDEV_PARAM_TXPOWER_DECR_DB;
23639 	pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM;
23640 	pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM;
23641 	pdev_param[wmi_pdev_param_atf_obss_noise_sch] =
23642 		WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH;
23643 	pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] =
23644 		WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR;
23645 	pdev_param[wmi_pdev_param_cust_txpower_scale] =
23646 				WMI_PDEV_PARAM_CUST_TXPOWER_SCALE;
23647 	pdev_param[wmi_pdev_param_atf_dynamic_enable] =
23648 		WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE;
23649 	pdev_param[wmi_pdev_param_atf_ssid_group_policy] =
23650 						WMI_UNAVAILABLE_PARAM;
23651 	pdev_param[wmi_pdev_param_igmpmld_override] =
23652 					WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE;
23653 	pdev_param[wmi_pdev_param_igmpmld_tid] =
23654 					WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE;
23655 	pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN;
23656 	pdev_param[wmi_pdev_param_block_interbss] =
23657 				WMI_PDEV_PARAM_BLOCK_INTERBSS;
23658 	pdev_param[wmi_pdev_param_set_disable_reset_cmdid] =
23659 				WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID;
23660 	pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] =
23661 				WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID;
23662 	pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] =
23663 				WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID;
23664 	pdev_param[wmi_pdev_param_set_burst_mode_cmdid] =
23665 					WMI_PDEV_PARAM_SET_BURST_MODE_CMDID;
23666 	pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS;
23667 	pdev_param[wmi_pdev_param_mesh_mcast_enable] =
23668 					WMI_PDEV_PARAM_MESH_MCAST_ENABLE;
23669 	pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] =
23670 					WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID;
23671 	pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] =
23672 					WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID;
23673 	pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] =
23674 				WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER;
23675 	pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] =
23676 				WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER;
23677 	pdev_param[wmi_pdev_param_set_mcast2ucast_mode] =
23678 				WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE;
23679 	pdev_param[wmi_pdev_param_smart_antenna_default_antenna] =
23680 				WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA;
23681 	pdev_param[wmi_pdev_param_fast_channel_reset] =
23682 				WMI_PDEV_PARAM_FAST_CHANNEL_RESET;
23683 	pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE;
23684 	pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT;
23685 	pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE;
23686 	pdev_param[wmi_pdev_param_antenna_gain_half_db] =
23687 		WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB;
23688 	pdev_param[wmi_pdev_param_esp_indication_period] =
23689 				WMI_PDEV_PARAM_ESP_INDICATION_PERIOD;
23690 #ifdef WLAN_RU26_SUPPORT
23691 	pdev_param[wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_RU26_ALLOWED;
23692 #endif
23693 }
23694 
23695 /**
23696  * populate_vdev_param_tlv() - populates vdev params
23697  *
23698  * @param vdev_param: Pointer to hold vdev params
23699  * Return: None
23700  */
23701 static void populate_vdev_param_tlv(uint32_t *vdev_param)
23702 {
23703 	vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD;
23704 	vdev_param[wmi_vdev_param_fragmentation_threshold] =
23705 				WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD;
23706 	vdev_param[wmi_vdev_param_beacon_interval] =
23707 				WMI_VDEV_PARAM_BEACON_INTERVAL;
23708 	vdev_param[wmi_vdev_param_listen_interval] =
23709 				WMI_VDEV_PARAM_LISTEN_INTERVAL;
23710 	vdev_param[wmi_vdev_param_multicast_rate] =
23711 				WMI_VDEV_PARAM_MULTICAST_RATE;
23712 	vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE;
23713 	vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME;
23714 	vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE;
23715 	vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME;
23716 	vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD;
23717 	vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME;
23718 	vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL;
23719 	vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD;
23720 	vdev_param[wmi_vdev_oc_scheduler_air_time_limit] =
23721 				WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT;
23722 	vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS;
23723 	vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW;
23724 	vdev_param[wmi_vdev_param_bmiss_count_max] =
23725 				WMI_VDEV_PARAM_BMISS_COUNT_MAX;
23726 	vdev_param[wmi_vdev_param_bmiss_first_bcnt] =
23727 				WMI_VDEV_PARAM_BMISS_FIRST_BCNT;
23728 	vdev_param[wmi_vdev_param_bmiss_final_bcnt] =
23729 				WMI_VDEV_PARAM_BMISS_FINAL_BCNT;
23730 	vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM;
23731 	vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH;
23732 	vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET;
23733 	vdev_param[wmi_vdev_param_disable_htprotection] =
23734 				WMI_VDEV_PARAM_DISABLE_HTPROTECTION;
23735 	vdev_param[wmi_vdev_param_sta_quickkickout] =
23736 				WMI_VDEV_PARAM_STA_QUICKKICKOUT;
23737 	vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE;
23738 	vdev_param[wmi_vdev_param_protection_mode] =
23739 				WMI_VDEV_PARAM_PROTECTION_MODE;
23740 	vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE;
23741 	vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI;
23742 	vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC;
23743 	vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC;
23744 	vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC;
23745 	vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD;
23746 	vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID;
23747 	vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS;
23748 	vdev_param[wmi_vdev_param_bcast_data_rate] =
23749 				WMI_VDEV_PARAM_BCAST_DATA_RATE;
23750 	vdev_param[wmi_vdev_param_mcast_data_rate] =
23751 				WMI_VDEV_PARAM_MCAST_DATA_RATE;
23752 	vdev_param[wmi_vdev_param_mcast_indicate] =
23753 				WMI_VDEV_PARAM_MCAST_INDICATE;
23754 	vdev_param[wmi_vdev_param_dhcp_indicate] =
23755 				WMI_VDEV_PARAM_DHCP_INDICATE;
23756 	vdev_param[wmi_vdev_param_unknown_dest_indicate] =
23757 				WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE;
23758 	vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] =
23759 		WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS;
23760 	vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] =
23761 		WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS;
23762 	vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] =
23763 		WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS;
23764 	vdev_param[wmi_vdev_param_ap_enable_nawds] =
23765 				WMI_VDEV_PARAM_AP_ENABLE_NAWDS;
23766 	vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS;
23767 	vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF;
23768 	vdev_param[wmi_vdev_param_packet_powersave] =
23769 				WMI_VDEV_PARAM_PACKET_POWERSAVE;
23770 	vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY;
23771 	vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
23772 	vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] =
23773 		WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS;
23774 	vdev_param[wmi_vdev_param_early_rx_adjust_enable] =
23775 				WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE;
23776 	vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] =
23777 				WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM;
23778 	vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] =
23779 				WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE;
23780 	vdev_param[wmi_vdev_param_early_rx_slop_step] =
23781 				WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP;
23782 	vdev_param[wmi_vdev_param_early_rx_init_slop] =
23783 				WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP;
23784 	vdev_param[wmi_vdev_param_early_rx_adjust_pause] =
23785 				WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE;
23786 	vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT;
23787 	vdev_param[wmi_vdev_param_snr_num_for_cal] =
23788 				WMI_VDEV_PARAM_SNR_NUM_FOR_CAL;
23789 	vdev_param[wmi_vdev_param_roam_fw_offload] =
23790 				WMI_VDEV_PARAM_ROAM_FW_OFFLOAD;
23791 	vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC;
23792 	vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] =
23793 				WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS;
23794 	vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE;
23795 	vdev_param[wmi_vdev_param_early_rx_drift_sample] =
23796 				WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE;
23797 	vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] =
23798 				WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR;
23799 	vdev_param[wmi_vdev_param_ebt_resync_timeout] =
23800 				WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT;
23801 	vdev_param[wmi_vdev_param_aggr_trig_event_enable] =
23802 				WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE;
23803 	vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] =
23804 				WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED;
23805 	vdev_param[wmi_vdev_param_is_power_collapse_allowed] =
23806 				WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED;
23807 	vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] =
23808 				WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED;
23809 	vdev_param[wmi_vdev_param_inactivity_cnt] =
23810 		WMI_VDEV_PARAM_INACTIVITY_CNT;
23811 	vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] =
23812 				WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS;
23813 	vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY;
23814 	vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] =
23815 				WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS;
23816 	vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] =
23817 			WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE;
23818 	vdev_param[wmi_vdev_param_rx_leak_window] =
23819 			WMI_VDEV_PARAM_RX_LEAK_WINDOW;
23820 	vdev_param[wmi_vdev_param_stats_avg_factor] =
23821 				WMI_VDEV_PARAM_STATS_AVG_FACTOR;
23822 	vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH;
23823 	vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE;
23824 	vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] =
23825 				WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE;
23826 	vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] =
23827 				WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE;
23828 	vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER;
23829 	vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE;
23830 	vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE;
23831 	vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM;
23832 	vdev_param[wmi_vdev_param_he_range_ext_enable] =
23833 				 WMI_VDEV_PARAM_HE_RANGE_EXT;
23834 	vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR;
23835 	vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE;
23836 	vdev_param[wmi_vdev_param_set_he_sounding_mode]
23837 					= WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE;
23838 	vdev_param[wmi_vdev_param_set_heop]      = WMI_VDEV_PARAM_HEOPS_0_31;
23839 	vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP;
23840 	vdev_param[wmi_vdev_param_dtim_enable_cts] =
23841 					WMI_VDEV_PARAM_DTIM_ENABLE_CTS;
23842 	vdev_param[wmi_vdev_param_atf_ssid_sched_policy] =
23843 					WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY;
23844 	vdev_param[wmi_vdev_param_disable_dyn_bw_rts] =
23845 					WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS;
23846 	vdev_param[wmi_vdev_param_mcast2ucast_set] =
23847 					WMI_VDEV_PARAM_MCAST2UCAST_SET;
23848 	vdev_param[wmi_vdev_param_rc_num_retries] =
23849 					WMI_VDEV_PARAM_RC_NUM_RETRIES;
23850 	vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR;
23851 	vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET;
23852 	vdev_param[wmi_vdev_param_rts_fixed_rate] =
23853 					WMI_VDEV_PARAM_RTS_FIXED_RATE;
23854 	vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK;
23855 	vdev_param[wmi_vdev_param_vht80_ratemask] =
23856 					WMI_VDEV_PARAM_VHT80_RATEMASK;
23857 	vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA;
23858 	vdev_param[wmi_vdev_param_bw_nss_ratemask] =
23859 					WMI_VDEV_PARAM_BW_NSS_RATEMASK;
23860 	vdev_param[wmi_vdev_param_set_he_ltf] =
23861 					WMI_VDEV_PARAM_HE_LTF;
23862 	vdev_param[wmi_vdev_param_disable_cabq] =
23863 					WMI_VDEV_PARAM_DISABLE_CABQ;
23864 	vdev_param[wmi_vdev_param_rate_dropdown_bmap] =
23865 					WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP;
23866 	vdev_param[wmi_vdev_param_set_ba_mode] =
23867 					WMI_VDEV_PARAM_BA_MODE;
23868 	vdev_param[wmi_vdev_param_capabilities] =
23869 					WMI_VDEV_PARAM_CAPABILITIES;
23870 	vdev_param[wmi_vdev_param_autorate_misc_cfg] =
23871 					WMI_VDEV_PARAM_AUTORATE_MISC_CFG;
23872 }
23873 #endif
23874 
23875 /**
23876  * populate_target_defines_tlv() - Populate target defines and params
23877  * @wmi_handle: pointer to wmi handle
23878  *
23879  * Return: None
23880  */
23881 #ifndef CONFIG_MCL
23882 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle)
23883 {
23884 	populate_pdev_param_tlv(wmi_handle->pdev_param);
23885 	populate_vdev_param_tlv(wmi_handle->vdev_param);
23886 }
23887 #else
23888 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle)
23889 { }
23890 #endif
23891 
23892 /**
23893  * wmi_ocb_ut_attach() - Attach OCB test framework
23894  * @wmi_handle: wmi handle
23895  *
23896  * Return: None
23897  */
23898 #ifdef WLAN_OCB_UT
23899 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle);
23900 #else
23901 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle)
23902 {
23903 	return;
23904 }
23905 #endif
23906 
23907 /**
23908  * wmi_tlv_attach() - Attach TLV APIs
23909  *
23910  * Return: None
23911  */
23912 void wmi_tlv_attach(wmi_unified_t wmi_handle)
23913 {
23914 	wmi_handle->ops = &tlv_ops;
23915 	wmi_ocb_ut_attach(wmi_handle);
23916 	wmi_handle->soc->svc_ids = &multi_svc_ids[0];
23917 #ifdef WMI_INTERFACE_EVENT_LOGGING
23918 	/* Skip saving WMI_CMD_HDR and TLV HDR */
23919 	wmi_handle->log_info.buf_offset_command = 8;
23920 	/* WMI_CMD_HDR is already stripped, skip saving TLV HDR */
23921 	wmi_handle->log_info.buf_offset_event = 4;
23922 #endif
23923 	populate_tlv_events_id(wmi_handle->wmi_events);
23924 	populate_tlv_service(wmi_handle->services);
23925 	populate_target_defines_tlv(wmi_handle);
23926 	wmi_twt_attach_tlv(wmi_handle);
23927 	wmi_extscan_attach_tlv(wmi_handle);
23928 }
23929 qdf_export_symbol(wmi_tlv_attach);
23930 
23931 /**
23932  * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine
23933  *
23934  * Return: None
23935  */
23936 void wmi_tlv_init(void)
23937 {
23938 	wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach);
23939 }
23940