xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_tlv.c (revision 3149adf58a329e17232a4c0e58d460d025edd55a)
1 /*
2  * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
3  *
4  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5  *
6  *
7  * Permission to use, copy, modify, and/or distribute this software for
8  * any purpose with or without fee is hereby granted, provided that the
9  * above copyright notice and this permission notice appear in all
10  * copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19  * PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 /*
23  * This file was originally distributed by Qualcomm Atheros, Inc.
24  * under proprietary terms before Copyright ownership was assigned
25  * to the Linux Foundation.
26  */
27 
28 #include "wmi_unified_api.h"
29 #include "wmi.h"
30 #include "wmi_version.h"
31 #include "wmi_unified_priv.h"
32 #include "wmi_version_whitelist.h"
33 #include <wlan_defs.h>
34 #include <htc_services.h>
35 
36 #ifdef CONVERGED_P2P_ENABLE
37 #include "wlan_p2p_public_struct.h"
38 #endif
39 #ifdef WLAN_PMO_ENABLE
40 #include "wlan_pmo_hw_filter_public_struct.h"
41 #endif
42 #include <wlan_utility.h>
43 #ifdef WLAN_SUPPORT_GREEN_AP
44 #include "wlan_green_ap_api.h"
45 #endif
46 
47 #ifdef WLAN_FEATURE_NAN_CONVERGENCE
48 #include "nan_public_structs.h"
49 #endif
50 
51 /* HTC service ids for WMI for multi-radio */
52 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC,
53 				WMI_CONTROL_SVC_WMAC1,
54 				WMI_CONTROL_SVC_WMAC2};
55 
56 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command
57  *                              buffer.
58  * @wmi_handle: pointer to wmi_handle
59  * @cmd: pointer target vdev create command buffer
60  * @param: pointer host params for vdev create
61  *
62  * Return: None
63  */
64 #ifdef CONFIG_MCL
65 static inline void copy_vdev_create_pdev_id(
66 		struct wmi_unified *wmi_handle,
67 		wmi_vdev_create_cmd_fixed_param * cmd,
68 		struct vdev_create_params *param)
69 {
70 	cmd->pdev_id = WMI_PDEV_ID_SOC;
71 }
72 #else
73 static inline void copy_vdev_create_pdev_id(
74 		struct wmi_unified *wmi_handle,
75 		wmi_vdev_create_cmd_fixed_param * cmd,
76 		struct vdev_create_params *param)
77 {
78 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
79 							param->pdev_id);
80 }
81 #endif
82 
83 /**
84  * send_vdev_create_cmd_tlv() - send VDEV create command to fw
85  * @wmi_handle: wmi handle
86  * @param: pointer to hold vdev create parameter
87  * @macaddr: vdev mac address
88  *
89  * Return: QDF_STATUS_SUCCESS for success or error code
90  */
91 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle,
92 				 uint8_t macaddr[IEEE80211_ADDR_LEN],
93 				 struct vdev_create_params *param)
94 {
95 	wmi_vdev_create_cmd_fixed_param *cmd;
96 	wmi_buf_t buf;
97 	int32_t len = sizeof(*cmd);
98 	QDF_STATUS ret;
99 	int num_bands = 2;
100 	uint8_t *buf_ptr;
101 	wmi_vdev_txrx_streams *txrx_streams;
102 
103 	len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE);
104 	buf = wmi_buf_alloc(wmi_handle, len);
105 	if (!buf) {
106 		WMI_LOGP("%s:wmi_buf_alloc failed", __func__);
107 		return QDF_STATUS_E_NOMEM;
108 	}
109 	cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf);
110 	WMITLV_SET_HDR(&cmd->tlv_header,
111 		       WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param,
112 		       WMITLV_GET_STRUCT_TLVLEN
113 			       (wmi_vdev_create_cmd_fixed_param));
114 	cmd->vdev_id = param->if_id;
115 	cmd->vdev_type = param->type;
116 	cmd->vdev_subtype = param->subtype;
117 	cmd->num_cfg_txrx_streams = num_bands;
118 	copy_vdev_create_pdev_id(wmi_handle, cmd, param);
119 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr);
120 	WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x",
121 		 __func__, param->if_id, cmd->pdev_id,
122 		 macaddr[0], macaddr[1], macaddr[2],
123 		 macaddr[3], macaddr[4], macaddr[5]);
124 	buf_ptr = (uint8_t *)cmd + sizeof(*cmd);
125 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
126 			(num_bands * sizeof(wmi_vdev_txrx_streams)));
127 	buf_ptr += WMI_TLV_HDR_SIZE;
128 
129 	WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__,
130 			param->type, param->subtype,
131 			param->nss_2g, param->nss_5g);
132 	txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr;
133 	txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G;
134 	txrx_streams->supported_tx_streams = param->nss_2g;
135 	txrx_streams->supported_rx_streams = param->nss_2g;
136 	WMITLV_SET_HDR(&txrx_streams->tlv_header,
137 		       WMITLV_TAG_STRUC_wmi_vdev_txrx_streams,
138 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams));
139 
140 	txrx_streams++;
141 	txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G;
142 	txrx_streams->supported_tx_streams = param->nss_5g;
143 	txrx_streams->supported_rx_streams = param->nss_5g;
144 	WMITLV_SET_HDR(&txrx_streams->tlv_header,
145 		       WMITLV_TAG_STRUC_wmi_vdev_txrx_streams,
146 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams));
147 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID);
148 	if (QDF_IS_STATUS_ERROR(ret)) {
149 		WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID");
150 		wmi_buf_free(buf);
151 	}
152 
153 	return ret;
154 }
155 
156 /**
157  * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw
158  * @wmi_handle: wmi handle
159  * @if_id: vdev id
160  *
161  * Return: QDF_STATUS_SUCCESS for success or error code
162  */
163 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle,
164 					  uint8_t if_id)
165 {
166 	wmi_vdev_delete_cmd_fixed_param *cmd;
167 	wmi_buf_t buf;
168 	QDF_STATUS ret;
169 
170 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
171 	if (!buf) {
172 		WMI_LOGP("%s:wmi_buf_alloc failed", __func__);
173 		return QDF_STATUS_E_NOMEM;
174 	}
175 
176 	cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf);
177 	WMITLV_SET_HDR(&cmd->tlv_header,
178 		       WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param,
179 		       WMITLV_GET_STRUCT_TLVLEN
180 			       (wmi_vdev_delete_cmd_fixed_param));
181 	cmd->vdev_id = if_id;
182 	ret = wmi_unified_cmd_send(wmi_handle, buf,
183 				   sizeof(wmi_vdev_delete_cmd_fixed_param),
184 				   WMI_VDEV_DELETE_CMDID);
185 	if (QDF_IS_STATUS_ERROR(ret)) {
186 		WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID");
187 		wmi_buf_free(buf);
188 	}
189 	WMI_LOGD("%s:vdev id = %d", __func__, if_id);
190 
191 	return ret;
192 }
193 
194 /**
195  * send_vdev_stop_cmd_tlv() - send vdev stop command to fw
196  * @wmi: wmi handle
197  * @vdev_id: vdev id
198  *
199  * Return: QDF_STATUS_SUCCESS for success or erro code
200  */
201 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi,
202 					uint8_t vdev_id)
203 {
204 	wmi_vdev_stop_cmd_fixed_param *cmd;
205 	wmi_buf_t buf;
206 	int32_t len = sizeof(*cmd);
207 
208 	buf = wmi_buf_alloc(wmi, len);
209 	if (!buf) {
210 		WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
211 		return QDF_STATUS_E_NOMEM;
212 	}
213 	cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf);
214 	WMITLV_SET_HDR(&cmd->tlv_header,
215 		       WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param,
216 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param));
217 	cmd->vdev_id = vdev_id;
218 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) {
219 		WMI_LOGP("%s: Failed to send vdev stop command", __func__);
220 		wmi_buf_free(buf);
221 		return QDF_STATUS_E_FAILURE;
222 	}
223 	WMI_LOGD("%s:vdev id = %d", __func__, vdev_id);
224 
225 	return 0;
226 }
227 
228 /**
229  * send_vdev_down_cmd_tlv() - send vdev down command to fw
230  * @wmi: wmi handle
231  * @vdev_id: vdev id
232  *
233  * Return: QDF_STATUS_SUCCESS for success or error code
234  */
235 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id)
236 {
237 	wmi_vdev_down_cmd_fixed_param *cmd;
238 	wmi_buf_t buf;
239 	int32_t len = sizeof(*cmd);
240 
241 	buf = wmi_buf_alloc(wmi, len);
242 	if (!buf) {
243 		WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
244 		return QDF_STATUS_E_NOMEM;
245 	}
246 	cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf);
247 	WMITLV_SET_HDR(&cmd->tlv_header,
248 		       WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param,
249 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param));
250 	cmd->vdev_id = vdev_id;
251 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) {
252 		WMI_LOGP("%s: Failed to send vdev down", __func__);
253 		wmi_buf_free(buf);
254 		return QDF_STATUS_E_FAILURE;
255 	}
256 	WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
257 
258 	return 0;
259 }
260 
261 #ifdef CONFIG_MCL
262 static inline void copy_channel_info(
263 		wmi_vdev_start_request_cmd_fixed_param * cmd,
264 		wmi_channel *chan,
265 		struct vdev_start_params *req)
266 {
267 	chan->mhz = req->chan_freq;
268 
269 	WMI_SET_CHANNEL_MODE(chan, req->chan_mode);
270 
271 	chan->band_center_freq1 = req->band_center_freq1;
272 	chan->band_center_freq2 = req->band_center_freq2;
273 
274 	if (req->is_half_rate)
275 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
276 	else if (req->is_quarter_rate)
277 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
278 
279 	if (req->is_dfs && req->flag_dfs) {
280 		WMI_SET_CHANNEL_FLAG(chan, req->flag_dfs);
281 		cmd->disable_hw_ack = req->dis_hw_ack;
282 	}
283 
284 	WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow);
285 	WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->max_txpow);
286 
287 }
288 #else
289 static inline void copy_channel_info(
290 		wmi_vdev_start_request_cmd_fixed_param * cmd,
291 		wmi_channel *chan,
292 		struct vdev_start_params *req)
293 {
294 	chan->mhz = req->channel.mhz;
295 
296 	WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode);
297 
298 	chan->band_center_freq1 = req->channel.cfreq1;
299 	chan->band_center_freq2 = req->channel.cfreq2;
300 	WMI_LOGI("%s: req->channel.phy_mode: %d ", req->channel.phy_mode);
301 
302 	if (req->channel.half_rate)
303 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
304 	else if (req->channel.quarter_rate)
305 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
306 
307 	WMI_LOGI("%s: req->channel.dfs_set: %d ", req->channel.dfs_set);
308 
309 	if (req->channel.dfs_set) {
310 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS);
311 		cmd->disable_hw_ack = req->disable_hw_ack;
312 	}
313 
314 	if (req->channel.dfs_set_cfreq2)
315 		WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2);
316 
317 	/* According to firmware both reg power and max tx power
318 	 * on set channel power is used and set it to max reg
319 	 * power from regulatory.
320 	 */
321 	WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower);
322 	WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower);
323 	WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower);
324 	WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax);
325 	WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id);
326 	WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower);
327 
328 }
329 #endif
330 /**
331  * send_vdev_start_cmd_tlv() - send vdev start request to fw
332  * @wmi_handle: wmi handle
333  * @req: vdev start params
334  *
335  * Return: QDF status
336  */
337 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle,
338 			  struct vdev_start_params *req)
339 {
340 	wmi_vdev_start_request_cmd_fixed_param *cmd;
341 	wmi_buf_t buf;
342 	wmi_channel *chan;
343 	int32_t len, ret;
344 	uint8_t *buf_ptr;
345 
346 	len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE;
347 	buf = wmi_buf_alloc(wmi_handle, len);
348 	if (!buf) {
349 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
350 		return QDF_STATUS_E_NOMEM;
351 	}
352 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
353 	cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr;
354 	chan = (wmi_channel *) (buf_ptr + sizeof(*cmd));
355 	WMITLV_SET_HDR(&cmd->tlv_header,
356 		       WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param,
357 		       WMITLV_GET_STRUCT_TLVLEN
358 			       (wmi_vdev_start_request_cmd_fixed_param));
359 	WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel,
360 		       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
361 	cmd->vdev_id = req->vdev_id;
362 
363 	/* Fill channel info */
364 	copy_channel_info(cmd, chan, req);
365 
366 	cmd->beacon_interval = req->beacon_intval;
367 	cmd->dtim_period = req->dtim_period;
368 
369 	cmd->bcn_tx_rate = req->bcn_tx_rate_code;
370 	if (req->bcn_tx_rate_code)
371 		cmd->flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT;
372 
373 	if (!req->is_restart) {
374 		cmd->beacon_interval = req->beacon_intval;
375 		cmd->dtim_period = req->dtim_period;
376 
377 		/* Copy the SSID */
378 		if (req->ssid.length) {
379 			if (req->ssid.length < sizeof(cmd->ssid.ssid))
380 				cmd->ssid.ssid_len = req->ssid.length;
381 			else
382 				cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid);
383 			qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid,
384 				     cmd->ssid.ssid_len);
385 		}
386 
387 		if (req->hidden_ssid)
388 			cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
389 
390 		if (req->pmf_enabled)
391 			cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED;
392 	}
393 
394 	cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED;
395 	cmd->num_noa_descriptors = req->num_noa_descriptors;
396 	cmd->preferred_rx_streams = req->preferred_rx_streams;
397 	cmd->preferred_tx_streams = req->preferred_tx_streams;
398 	cmd->cac_duration_ms = req->cac_duration_ms;
399 	cmd->regdomain = req->regdomain;
400 	cmd->he_ops = req->he_ops;
401 
402 	buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) +
403 			       sizeof(wmi_channel));
404 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
405 		       cmd->num_noa_descriptors *
406 		       sizeof(wmi_p2p_noa_descriptor));
407 	WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d "
408 		"beacon interval %d dtim %d center_chan %d center_freq2 %d "
409 		"reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x "
410 		"Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d"
411 		"req->dis_hw_ack: %d ", __func__, req->vdev_id,
412 		chan->mhz, req->chan_mode, chan->info,
413 		req->is_dfs, req->beacon_intval, cmd->dtim_period,
414 		chan->band_center_freq1, chan->band_center_freq2,
415 		chan->reg_info_1, chan->reg_info_2, req->max_txpow,
416 		req->preferred_tx_streams, req->preferred_rx_streams,
417 		req->ldpc_rx_enabled, req->cac_duration_ms,
418 		req->regdomain, req->he_ops,
419 		req->dis_hw_ack);
420 
421 	if (req->is_restart)
422 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
423 					   WMI_VDEV_RESTART_REQUEST_CMDID);
424 	else
425 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
426 					   WMI_VDEV_START_REQUEST_CMDID);
427 	 if (ret) {
428 		WMI_LOGP("%s: Failed to send vdev start command", __func__);
429 		wmi_buf_free(buf);
430 		return QDF_STATUS_E_FAILURE;
431 	 }
432 
433 	return QDF_STATUS_SUCCESS;
434 }
435 
436 /**
437  * send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid
438  * @wmi_handle: wmi handle
439  * @restart_params: vdev restart params
440  *
441  * Return: QDF_STATUS_SUCCESS for success or error code
442  */
443 static QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle,
444 			struct hidden_ssid_vdev_restart_params *restart_params)
445 {
446 	wmi_vdev_start_request_cmd_fixed_param *cmd;
447 	wmi_buf_t buf;
448 	wmi_channel *chan;
449 	int32_t len;
450 	uint8_t *buf_ptr;
451 	QDF_STATUS ret = 0;
452 
453 	len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE;
454 	buf = wmi_buf_alloc(wmi_handle, len);
455 	if (!buf) {
456 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
457 		return QDF_STATUS_E_NOMEM;
458 	}
459 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
460 	cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr;
461 	chan = (wmi_channel *) (buf_ptr + sizeof(*cmd));
462 
463 	WMITLV_SET_HDR(&cmd->tlv_header,
464 		       WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param,
465 		       WMITLV_GET_STRUCT_TLVLEN
466 			       (wmi_vdev_start_request_cmd_fixed_param));
467 
468 	WMITLV_SET_HDR(&chan->tlv_header,
469 		       WMITLV_TAG_STRUC_wmi_channel,
470 		       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
471 
472 	cmd->vdev_id = restart_params->session_id;
473 	cmd->ssid.ssid_len = restart_params->ssid_len;
474 	qdf_mem_copy(cmd->ssid.ssid,
475 		     restart_params->ssid,
476 		     cmd->ssid.ssid_len);
477 	cmd->flags = restart_params->flags;
478 	cmd->requestor_id = restart_params->requestor_id;
479 	cmd->disable_hw_ack = restart_params->disable_hw_ack;
480 
481 	chan->mhz = restart_params->mhz;
482 	chan->band_center_freq1 =
483 			restart_params->band_center_freq1;
484 	chan->band_center_freq2 =
485 			restart_params->band_center_freq2;
486 	chan->info = restart_params->info;
487 	chan->reg_info_1 = restart_params->reg_info_1;
488 	chan->reg_info_2 = restart_params->reg_info_2;
489 
490 	cmd->num_noa_descriptors = 0;
491 	buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) +
492 			       sizeof(wmi_channel));
493 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
494 		       cmd->num_noa_descriptors *
495 		       sizeof(wmi_p2p_noa_descriptor));
496 
497 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
498 				   WMI_VDEV_RESTART_REQUEST_CMDID);
499 	if (QDF_IS_STATUS_ERROR(ret)) {
500 		wmi_buf_free(buf);
501 		return QDF_STATUS_E_FAILURE;
502 	}
503 	return QDF_STATUS_SUCCESS;
504 }
505 
506 
507 /**
508  * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw
509  * @wmi: wmi handle
510  * @peer_addr: peer mac address
511  * @param: pointer to hold peer flush tid parameter
512  *
513  * Return: 0 for sucess or error code
514  */
515 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi,
516 					 uint8_t peer_addr[IEEE80211_ADDR_LEN],
517 					 struct peer_flush_params *param)
518 {
519 	wmi_peer_flush_tids_cmd_fixed_param *cmd;
520 	wmi_buf_t buf;
521 	int32_t len = sizeof(*cmd);
522 
523 	buf = wmi_buf_alloc(wmi, len);
524 	if (!buf) {
525 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
526 		return QDF_STATUS_E_NOMEM;
527 	}
528 	cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf);
529 	WMITLV_SET_HDR(&cmd->tlv_header,
530 		       WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param,
531 		       WMITLV_GET_STRUCT_TLVLEN
532 			       (wmi_peer_flush_tids_cmd_fixed_param));
533 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
534 	cmd->peer_tid_bitmap = param->peer_tid_bitmap;
535 	cmd->vdev_id = param->vdev_id;
536 	WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__,
537 				peer_addr, param->vdev_id,
538 				param->peer_tid_bitmap);
539 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) {
540 		WMI_LOGP("%s: Failed to send flush tid command", __func__);
541 		wmi_buf_free(buf);
542 		return QDF_STATUS_E_FAILURE;
543 	}
544 
545 	return 0;
546 }
547 
548 /**
549  * send_peer_delete_cmd_tlv() - send PEER delete command to fw
550  * @wmi: wmi handle
551  * @peer_addr: peer mac addr
552  * @vdev_id: vdev id
553  *
554  * Return: QDF_STATUS_SUCCESS for success or error code
555  */
556 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi,
557 				 uint8_t peer_addr[IEEE80211_ADDR_LEN],
558 				 uint8_t vdev_id)
559 {
560 	wmi_peer_delete_cmd_fixed_param *cmd;
561 	wmi_buf_t buf;
562 	int32_t len = sizeof(*cmd);
563 	buf = wmi_buf_alloc(wmi, len);
564 	if (!buf) {
565 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
566 		return QDF_STATUS_E_NOMEM;
567 	}
568 	cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf);
569 	WMITLV_SET_HDR(&cmd->tlv_header,
570 		       WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param,
571 		       WMITLV_GET_STRUCT_TLVLEN
572 			       (wmi_peer_delete_cmd_fixed_param));
573 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
574 	cmd->vdev_id = vdev_id;
575 
576 	WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id);
577 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) {
578 		WMI_LOGP("%s: Failed to send peer delete command", __func__);
579 		wmi_buf_free(buf);
580 		return QDF_STATUS_E_FAILURE;
581 	}
582 
583 	return 0;
584 }
585 
586 /**
587  * convert_host_peer_id_to_target_id_tlv - convert host peer param_id
588  * to target id.
589  * @targ_paramid: Target parameter id to hold the result.
590  * @peer_param_id: host param id.
591  *
592  * Return: QDF_STATUS_SUCCESS for success
593  *         QDF_STATUS_E_NOSUPPORT when the param_id in not supported in tareget
594  */
595 #ifdef CONFIG_MCL
596 static QDF_STATUS convert_host_peer_id_to_target_id_tlv(
597 		uint32_t *targ_paramid,
598 		uint32_t peer_param_id)
599 {
600 	*targ_paramid = peer_param_id;
601 	return QDF_STATUS_SUCCESS;
602 }
603 #else
604 static QDF_STATUS convert_host_peer_id_to_target_id_tlv(
605 		uint32_t *targ_paramid,
606 		uint32_t peer_param_id)
607 {
608 	switch (peer_param_id) {
609 	case WMI_HOST_PEER_MIMO_PS_STATE:
610 		*targ_paramid = WMI_PEER_MIMO_PS_STATE;
611 		break;
612 	case WMI_HOST_PEER_AMPDU:
613 		*targ_paramid = WMI_PEER_AMPDU;
614 		break;
615 	case WMI_HOST_PEER_AUTHORIZE:
616 		*targ_paramid = WMI_PEER_AUTHORIZE;
617 		break;
618 	case WMI_HOST_PEER_CHWIDTH:
619 		*targ_paramid = WMI_PEER_CHWIDTH;
620 		break;
621 	case WMI_HOST_PEER_NSS:
622 		*targ_paramid = WMI_PEER_NSS;
623 		break;
624 	case WMI_HOST_PEER_USE_4ADDR:
625 		*targ_paramid = WMI_PEER_USE_4ADDR;
626 		break;
627 	case WMI_HOST_PEER_MEMBERSHIP:
628 		*targ_paramid = WMI_PEER_MEMBERSHIP;
629 		break;
630 	case WMI_HOST_PEER_USERPOS:
631 		*targ_paramid = WMI_PEER_USERPOS;
632 		break;
633 	case WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED:
634 		*targ_paramid = WMI_PEER_CRIT_PROTO_HINT_ENABLED;
635 		break;
636 	case WMI_HOST_PEER_TX_FAIL_CNT_THR:
637 		*targ_paramid = WMI_PEER_TX_FAIL_CNT_THR;
638 		break;
639 	case WMI_HOST_PEER_SET_HW_RETRY_CTS2S:
640 		*targ_paramid = WMI_PEER_SET_HW_RETRY_CTS2S;
641 		break;
642 	case WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH:
643 		*targ_paramid = WMI_PEER_IBSS_ATIM_WINDOW_LENGTH;
644 		break;
645 	case WMI_HOST_PEER_PHYMODE:
646 		*targ_paramid = WMI_PEER_PHYMODE;
647 		break;
648 	case WMI_HOST_PEER_USE_FIXED_PWR:
649 		*targ_paramid = WMI_PEER_USE_FIXED_PWR;
650 		break;
651 	case WMI_HOST_PEER_PARAM_FIXED_RATE:
652 		*targ_paramid = WMI_PEER_PARAM_FIXED_RATE;
653 		break;
654 	case WMI_HOST_PEER_SET_MU_WHITELIST:
655 		*targ_paramid = WMI_PEER_SET_MU_WHITELIST;
656 		break;
657 	case WMI_HOST_PEER_SET_MAC_TX_RATE:
658 		*targ_paramid = WMI_PEER_SET_MAX_TX_RATE;
659 		break;
660 	case WMI_HOST_PEER_SET_MIN_TX_RATE:
661 		*targ_paramid = WMI_PEER_SET_MIN_TX_RATE;
662 		break;
663 	case WMI_HOST_PEER_SET_DEFAULT_ROUTING:
664 		*targ_paramid = WMI_PEER_SET_DEFAULT_ROUTING;
665 		break;
666 	case WMI_HOST_PEER_NSS_VHT160:
667 		*targ_paramid = WMI_PEER_NSS_VHT160;
668 		break;
669 	case WMI_HOST_PEER_NSS_VHT80_80:
670 		*targ_paramid = WMI_PEER_NSS_VHT80_80;
671 		break;
672 	case WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL:
673 		*targ_paramid = WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL;
674 		break;
675 	case WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL:
676 		*targ_paramid = WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL;
677 		break;
678 	case WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE:
679 		*targ_paramid = WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE;
680 		break;
681 	case WMI_HOST_PEER_PARAM_MU_ENABLE:
682 		*targ_paramid = WMI_PEER_PARAM_MU_ENABLE;
683 		break;
684 	case WMI_HOST_PEER_PARAM_OFDMA_ENABLE:
685 		*targ_paramid = WMI_PEER_PARAM_OFDMA_ENABLE;
686 		break;
687 	default:
688 		return QDF_STATUS_E_NOSUPPORT;
689 	}
690 
691 	return QDF_STATUS_SUCCESS;
692 }
693 #endif
694 /**
695  * send_peer_param_cmd_tlv() - set peer parameter in fw
696  * @wmi: wmi handle
697  * @peer_addr: peer mac address
698  * @param    : pointer to hold peer set parameter
699  *
700  * Return: QDF_STATUS_SUCCESS for success or error code
701  */
702 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi,
703 				uint8_t peer_addr[IEEE80211_ADDR_LEN],
704 				struct peer_set_params *param)
705 {
706 	wmi_peer_set_param_cmd_fixed_param *cmd;
707 	wmi_buf_t buf;
708 	int32_t err;
709 	uint32_t param_id;
710 
711 	if (convert_host_peer_id_to_target_id_tlv(&param_id,
712 				param->param_id) != QDF_STATUS_SUCCESS)
713 		return QDF_STATUS_E_NOSUPPORT;
714 
715 	buf = wmi_buf_alloc(wmi, sizeof(*cmd));
716 	if (!buf) {
717 		WMI_LOGE("Failed to allocate buffer to send set_param cmd");
718 		return QDF_STATUS_E_NOMEM;
719 	}
720 	cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf);
721 	WMITLV_SET_HDR(&cmd->tlv_header,
722 		       WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
723 		       WMITLV_GET_STRUCT_TLVLEN
724 				(wmi_peer_set_param_cmd_fixed_param));
725 	cmd->vdev_id = param->vdev_id;
726 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
727 	cmd->param_id = param_id;
728 	cmd->param_value = param->param_value;
729 	err = wmi_unified_cmd_send(wmi, buf,
730 				   sizeof(wmi_peer_set_param_cmd_fixed_param),
731 				   WMI_PEER_SET_PARAM_CMDID);
732 	if (err) {
733 		WMI_LOGE("Failed to send set_param cmd");
734 		wmi_buf_free(buf);
735 		return QDF_STATUS_E_FAILURE;
736 	}
737 
738 	return 0;
739 }
740 
741 /**
742  * send_vdev_up_cmd_tlv() - send vdev up command in fw
743  * @wmi: wmi handle
744  * @bssid: bssid
745  * @vdev_up_params: pointer to hold vdev up parameter
746  *
747  * Return: QDF_STATUS_SUCCESS for success or error code
748  */
749 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi,
750 			     uint8_t bssid[IEEE80211_ADDR_LEN],
751 				 struct vdev_up_params *params)
752 {
753 	wmi_vdev_up_cmd_fixed_param *cmd;
754 	wmi_buf_t buf;
755 	int32_t len = sizeof(*cmd);
756 
757 	WMI_LOGD("%s: VDEV_UP", __func__);
758 	WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__,
759 		 params->vdev_id, params->assoc_id, bssid);
760 	buf = wmi_buf_alloc(wmi, len);
761 	if (!buf) {
762 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
763 		return QDF_STATUS_E_NOMEM;
764 	}
765 	cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf);
766 	WMITLV_SET_HDR(&cmd->tlv_header,
767 		       WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param,
768 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param));
769 	cmd->vdev_id = params->vdev_id;
770 	cmd->vdev_assoc_id = params->assoc_id;
771 	WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid);
772 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) {
773 		WMI_LOGP("%s: Failed to send vdev up command", __func__);
774 		wmi_buf_free(buf);
775 		return QDF_STATUS_E_FAILURE;
776 	}
777 
778 	return 0;
779 }
780 
781 /**
782  * send_peer_create_cmd_tlv() - send peer create command to fw
783  * @wmi: wmi handle
784  * @peer_addr: peer mac address
785  * @peer_type: peer type
786  * @vdev_id: vdev id
787  *
788  * Return: QDF_STATUS_SUCCESS for success or error code
789  */
790 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi,
791 					struct peer_create_params *param)
792 {
793 	wmi_peer_create_cmd_fixed_param *cmd;
794 	wmi_buf_t buf;
795 	int32_t len = sizeof(*cmd);
796 
797 	buf = wmi_buf_alloc(wmi, len);
798 	if (!buf) {
799 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
800 		return QDF_STATUS_E_NOMEM;
801 	}
802 	cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf);
803 	WMITLV_SET_HDR(&cmd->tlv_header,
804 		       WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param,
805 		       WMITLV_GET_STRUCT_TLVLEN
806 			       (wmi_peer_create_cmd_fixed_param));
807 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
808 	cmd->peer_type = param->peer_type;
809 	cmd->vdev_id = param->vdev_id;
810 
811 	if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) {
812 		WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__);
813 		wmi_buf_free(buf);
814 		return QDF_STATUS_E_FAILURE;
815 	}
816 	WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr,
817 			param->vdev_id);
818 
819 	return 0;
820 }
821 
822 /**
823  * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup
824  * 	command to fw
825  * @wmi: wmi handle
826  * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters
827  *
828  * Return: 0 for success or error code
829  */
830 static
831 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi,
832 		struct rx_reorder_queue_setup_params *param)
833 {
834 	wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd;
835 	wmi_buf_t buf;
836 	int32_t len = sizeof(*cmd);
837 
838 	buf = wmi_buf_alloc(wmi, len);
839 	if (!buf) {
840 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
841 		return QDF_STATUS_E_NOMEM;
842 	}
843 	cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf);
844 	WMITLV_SET_HDR(&cmd->tlv_header,
845 		WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param,
846 		WMITLV_GET_STRUCT_TLVLEN
847 			(wmi_peer_reorder_queue_setup_cmd_fixed_param));
848 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr);
849 	cmd->vdev_id = param->vdev_id;
850 	cmd->tid = param->tid;
851 	cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo;
852 	cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi;
853 	cmd->queue_no = param->queue_no;
854 
855 	if (wmi_unified_cmd_send(wmi, buf, len,
856 			WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) {
857 		WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID",
858 			__func__);
859 		qdf_nbuf_free(buf);
860 		return QDF_STATUS_E_FAILURE;
861 	}
862 	WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d\n", __func__,
863 		param->peer_macaddr, param->vdev_id, param->tid);
864 
865 	return QDF_STATUS_SUCCESS;
866 }
867 
868 /**
869  * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove
870  * 	command to fw
871  * @wmi: wmi handle
872  * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters
873  *
874  * Return: 0 for success or error code
875  */
876 static
877 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi,
878 		struct rx_reorder_queue_remove_params *param)
879 {
880 	wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd;
881 	wmi_buf_t buf;
882 	int32_t len = sizeof(*cmd);
883 
884 	buf = wmi_buf_alloc(wmi, len);
885 	if (!buf) {
886 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
887 		return QDF_STATUS_E_NOMEM;
888 	}
889 	cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *)
890 			wmi_buf_data(buf);
891 	WMITLV_SET_HDR(&cmd->tlv_header,
892 		WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param,
893 		WMITLV_GET_STRUCT_TLVLEN
894 			(wmi_peer_reorder_queue_remove_cmd_fixed_param));
895 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr);
896 	cmd->vdev_id = param->vdev_id;
897 	cmd->tid_mask = param->peer_tid_bitmap;
898 
899 	if (wmi_unified_cmd_send(wmi, buf, len,
900 			WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) {
901 		WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID",
902 			__func__);
903 		qdf_nbuf_free(buf);
904 		return QDF_STATUS_E_FAILURE;
905 	}
906 	WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__,
907 		param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap);
908 
909 	return QDF_STATUS_SUCCESS;
910 }
911 
912 /**
913  * send_peer_add_wds_entry_cmd_tlv() - send peer add command to fw
914  * @wmi_handle: wmi handle
915  * @param: pointer holding peer details
916  *
917  * Return: 0 for success or error code
918  */
919 static QDF_STATUS send_peer_add_wds_entry_cmd_tlv(wmi_unified_t wmi_handle,
920 					struct peer_add_wds_entry_params *param)
921 {
922 	wmi_peer_add_wds_entry_cmd_fixed_param *cmd;
923 	wmi_buf_t buf;
924 	int len = sizeof(*cmd);
925 
926 	buf = wmi_buf_alloc(wmi_handle, len);
927 	if (!buf) {
928 		qdf_print("%s: wmi_buf_alloc failed\n", __func__);
929 		return QDF_STATUS_E_FAILURE;
930 	}
931 	cmd = (wmi_peer_add_wds_entry_cmd_fixed_param *) wmi_buf_data(buf);
932 	WMITLV_SET_HDR(&cmd->tlv_header,
933 			WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param,
934 			WMITLV_GET_STRUCT_TLVLEN
935 				(wmi_peer_add_wds_entry_cmd_fixed_param));
936 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr);
937 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
938 	cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0;
939 	cmd->vdev_id = param->vdev_id;
940 
941 	return wmi_unified_cmd_send(wmi_handle, buf, len,
942 			WMI_PEER_ADD_WDS_ENTRY_CMDID);
943 }
944 
945 /**
946  * send_peer_del_wds_entry_cmd_tlv() - send peer delete command to fw
947  * @wmi_handle: wmi handle
948  * @param: pointer holding peer details
949  *
950  * Return: 0 for success or error code
951  */
952 static QDF_STATUS send_peer_del_wds_entry_cmd_tlv(wmi_unified_t wmi_handle,
953 					struct peer_del_wds_entry_params *param)
954 {
955 	wmi_peer_remove_wds_entry_cmd_fixed_param *cmd;
956 	wmi_buf_t buf;
957 	int len = sizeof(*cmd);
958 
959 	buf = wmi_buf_alloc(wmi_handle, len);
960 	if (!buf) {
961 		qdf_print("%s: wmi_buf_alloc failed\n", __func__);
962 		return QDF_STATUS_E_NOMEM;
963 	}
964 	cmd = (wmi_peer_remove_wds_entry_cmd_fixed_param *)wmi_buf_data(buf);
965 	WMITLV_SET_HDR(&cmd->tlv_header,
966 			WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param,
967 			WMITLV_GET_STRUCT_TLVLEN
968 				(wmi_peer_remove_wds_entry_cmd_fixed_param));
969 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr);
970 	cmd->vdev_id = param->vdev_id;
971 	return wmi_unified_cmd_send(wmi_handle, buf, len,
972 			WMI_PEER_REMOVE_WDS_ENTRY_CMDID);
973 }
974 
975 /**
976  * send_peer_update_wds_entry_cmd_non_tlv() - send peer update command to fw
977  * @wmi_handle: wmi handle
978  * @param: pointer holding peer details
979  *
980  * Return: 0 for success or error code
981  */
982 static QDF_STATUS send_peer_update_wds_entry_cmd_tlv(wmi_unified_t wmi_handle,
983 				struct peer_update_wds_entry_params *param)
984 {
985 	wmi_peer_update_wds_entry_cmd_fixed_param *cmd;
986 	wmi_buf_t buf;
987 	int len = sizeof(*cmd);
988 
989 	buf = wmi_buf_alloc(wmi_handle, len);
990 	if (!buf) {
991 		qdf_print("%s: wmi_buf_alloc failed\n", __func__);
992 		return QDF_STATUS_E_NOMEM;
993 	}
994 
995 	/* wmi_buf_alloc returns zeroed command buffer */
996 	cmd = (wmi_peer_update_wds_entry_cmd_fixed_param *)wmi_buf_data(buf);
997 	WMITLV_SET_HDR(&cmd->tlv_header,
998 			WMITLV_TAG_STRUC_wmi_peer_update_wds_entry_cmd_fixed_param,
999 			WMITLV_GET_STRUCT_TLVLEN
1000 				(wmi_peer_update_wds_entry_cmd_fixed_param));
1001 	cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0;
1002 	cmd->vdev_id = param->vdev_id;
1003 	if (param->wds_macaddr)
1004 		WMI_CHAR_ARRAY_TO_MAC_ADDR(param->wds_macaddr,
1005 				&cmd->wds_macaddr);
1006 	if (param->peer_macaddr)
1007 		WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr,
1008 				&cmd->peer_macaddr);
1009 	return wmi_unified_cmd_send(wmi_handle, buf, len,
1010 			WMI_PEER_UPDATE_WDS_ENTRY_CMDID);
1011 }
1012 
1013 /**
1014  * send_pdev_get_tpc_config_cmd_tlv() - send get tpc config command to fw
1015  * @wmi_handle: wmi handle
1016  * @param: pointer to get tpc config params
1017  *
1018  * Return: 0 for success or error code
1019  */
1020 static QDF_STATUS
1021 send_pdev_get_tpc_config_cmd_tlv(wmi_unified_t wmi_handle,
1022 				uint32_t param)
1023 {
1024 	wmi_pdev_get_tpc_config_cmd_fixed_param *cmd;
1025 	wmi_buf_t buf;
1026 	int32_t len = sizeof(wmi_pdev_get_tpc_config_cmd_fixed_param);
1027 
1028 	buf = wmi_buf_alloc(wmi_handle, len);
1029 	if (!buf) {
1030 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
1031 		return QDF_STATUS_E_NOMEM;
1032 	}
1033 	cmd = (wmi_pdev_get_tpc_config_cmd_fixed_param *)wmi_buf_data(buf);
1034 	WMITLV_SET_HDR(&cmd->tlv_header,
1035 		WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param,
1036 		WMITLV_GET_STRUCT_TLVLEN
1037 		(wmi_pdev_get_tpc_config_cmd_fixed_param));
1038 
1039 	cmd->param = param;
1040 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1041 				 WMI_PDEV_GET_TPC_CONFIG_CMDID)) {
1042 		WMI_LOGE("Send pdev get tpc config cmd failed");
1043 		wmi_buf_free(buf);
1044 		return QDF_STATUS_E_FAILURE;
1045 
1046 	}
1047 	WMI_LOGD("%s:send success", __func__);
1048 
1049 	return QDF_STATUS_SUCCESS;
1050 }
1051 
1052 #ifdef WLAN_SUPPORT_GREEN_AP
1053 /**
1054  * send_green_ap_ps_cmd_tlv() - enable green ap powersave command
1055  * @wmi_handle: wmi handle
1056  * @value: value
1057  * @pdev_id: pdev id to have radio context
1058  *
1059  * Return: QDF_STATUS_SUCCESS for success or error code
1060  */
1061 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle,
1062 						uint32_t value, uint8_t pdev_id)
1063 {
1064 	wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd;
1065 	wmi_buf_t buf;
1066 	int32_t len = sizeof(*cmd);
1067 
1068 	WMI_LOGD("Set Green AP PS val %d", value);
1069 
1070 	buf = wmi_buf_alloc(wmi_handle, len);
1071 	if (!buf) {
1072 		WMI_LOGP("%s: Green AP PS Mem Alloc Failed", __func__);
1073 		return QDF_STATUS_E_NOMEM;
1074 	}
1075 
1076 	cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf);
1077 	WMITLV_SET_HDR(&cmd->tlv_header,
1078 		   WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param,
1079 		   WMITLV_GET_STRUCT_TLVLEN
1080 			       (wmi_pdev_green_ap_ps_enable_cmd_fixed_param));
1081 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
1082 	cmd->enable = value;
1083 
1084 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1085 				 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) {
1086 		WMI_LOGE("Set Green AP PS param Failed val %d", value);
1087 		wmi_buf_free(buf);
1088 		return QDF_STATUS_E_FAILURE;
1089 	}
1090 
1091 	return 0;
1092 }
1093 #endif
1094 
1095 /**
1096  * send_pdev_utf_cmd_tlv() - send utf command to fw
1097  * @wmi_handle: wmi handle
1098  * @param: pointer to pdev_utf_params
1099  * @mac_id: mac id to have radio context
1100  *
1101  * Return: QDF_STATUS_SUCCESS for success or error code
1102  */
1103 static QDF_STATUS
1104 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle,
1105 				struct pdev_utf_params *param,
1106 				uint8_t mac_id)
1107 {
1108 	wmi_buf_t buf;
1109 	uint8_t *cmd;
1110 	/* if param->len is 0 no data is sent, return error */
1111 	QDF_STATUS ret = QDF_STATUS_E_INVAL;
1112 	static uint8_t msgref = 1;
1113 	uint8_t segNumber = 0, segInfo, numSegments;
1114 	uint16_t chunk_len, total_bytes;
1115 	uint8_t *bufpos;
1116 	struct seg_hdr_info segHdrInfo;
1117 
1118 	bufpos = param->utf_payload;
1119 	total_bytes = param->len;
1120 	ASSERT(total_bytes / MAX_WMI_UTF_LEN ==
1121 	       (uint8_t) (total_bytes / MAX_WMI_UTF_LEN));
1122 	numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN);
1123 
1124 	if (param->len - (numSegments * MAX_WMI_UTF_LEN))
1125 		numSegments++;
1126 
1127 	while (param->len) {
1128 		if (param->len > MAX_WMI_UTF_LEN)
1129 			chunk_len = MAX_WMI_UTF_LEN;    /* MAX messsage */
1130 		else
1131 			chunk_len = param->len;
1132 
1133 		buf = wmi_buf_alloc(wmi_handle,
1134 				    (chunk_len + sizeof(segHdrInfo) +
1135 				     WMI_TLV_HDR_SIZE));
1136 		if (!buf) {
1137 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
1138 			return QDF_STATUS_E_NOMEM;
1139 		}
1140 
1141 		cmd = (uint8_t *) wmi_buf_data(buf);
1142 
1143 		segHdrInfo.len = total_bytes;
1144 		segHdrInfo.msgref = msgref;
1145 		segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF);
1146 		segHdrInfo.segmentInfo = segInfo;
1147 		segHdrInfo.pad = 0;
1148 
1149 		WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d,"
1150 			 " segHdrInfo.segmentInfo = %d",
1151 			 __func__, segHdrInfo.len, segHdrInfo.msgref,
1152 			 segHdrInfo.segmentInfo);
1153 
1154 		WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d"
1155 			 "chunk len %d", __func__, total_bytes, segNumber,
1156 			 numSegments, chunk_len);
1157 
1158 		segNumber++;
1159 
1160 		WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE,
1161 			       (chunk_len + sizeof(segHdrInfo)));
1162 		cmd += WMI_TLV_HDR_SIZE;
1163 		memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo));   /* 4 bytes */
1164 		memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len);
1165 
1166 		ret = wmi_unified_cmd_send(wmi_handle, buf,
1167 					   (chunk_len + sizeof(segHdrInfo) +
1168 					    WMI_TLV_HDR_SIZE),
1169 					   WMI_PDEV_UTF_CMDID);
1170 
1171 		if (QDF_IS_STATUS_ERROR(ret)) {
1172 			WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command");
1173 			wmi_buf_free(buf);
1174 			break;
1175 		}
1176 
1177 		param->len -= chunk_len;
1178 		bufpos += chunk_len;
1179 	}
1180 
1181 	msgref++;
1182 
1183 	return ret;
1184 }
1185 #ifdef CONFIG_MCL
1186 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle,
1187 				uint32_t host_param)
1188 {
1189 	return host_param;
1190 }
1191 #else
1192 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle,
1193 				uint32_t host_param)
1194 {
1195 	if (host_param < wmi_pdev_param_max)
1196 		return wmi_handle->pdev_param[host_param];
1197 
1198 	return WMI_UNAVAILABLE_PARAM;
1199 }
1200 #endif
1201 /**
1202  * send_pdev_param_cmd_tlv() - set pdev parameters
1203  * @wmi_handle: wmi handle
1204  * @param: pointer to pdev parameter
1205  * @mac_id: radio context
1206  *
1207  * Return: 0 on success, errno on failure
1208  */
1209 static QDF_STATUS
1210 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle,
1211 			   struct pdev_params *param,
1212 				uint8_t mac_id)
1213 {
1214 	QDF_STATUS ret;
1215 	wmi_pdev_set_param_cmd_fixed_param *cmd;
1216 	wmi_buf_t buf;
1217 	uint16_t len = sizeof(*cmd);
1218 	uint32_t pdev_param;
1219 
1220 	pdev_param = convert_host_pdev_param_tlv(wmi_handle, param->param_id);
1221 	if (pdev_param == WMI_UNAVAILABLE_PARAM) {
1222 		WMI_LOGW("%s: Unavailable param %d\n",
1223 				__func__, param->param_id);
1224 		return QDF_STATUS_E_INVAL;
1225 	}
1226 
1227 	buf = wmi_buf_alloc(wmi_handle, len);
1228 	if (!buf) {
1229 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
1230 		return QDF_STATUS_E_NOMEM;
1231 	}
1232 	cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
1233 	WMITLV_SET_HDR(&cmd->tlv_header,
1234 		       WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param,
1235 		       WMITLV_GET_STRUCT_TLVLEN
1236 			       (wmi_pdev_set_param_cmd_fixed_param));
1237 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
1238 	cmd->param_id = pdev_param;
1239 	cmd->param_value = param->param_value;
1240 	WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id,
1241 				param->param_value);
1242 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1243 				   WMI_PDEV_SET_PARAM_CMDID);
1244 	if (QDF_IS_STATUS_ERROR(ret)) {
1245 		WMI_LOGE("Failed to send set param command ret = %d", ret);
1246 		wmi_buf_free(buf);
1247 	}
1248 	return ret;
1249 }
1250 
1251 /**
1252  * send_suspend_cmd_tlv() - WMI suspend function
1253  * @param wmi_handle      : handle to WMI.
1254  * @param param    : pointer to hold suspend parameter
1255  * @mac_id: radio context
1256  *
1257  * Return 0  on success and -ve on failure.
1258  */
1259 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle,
1260 				struct suspend_params *param,
1261 				uint8_t mac_id)
1262 {
1263 	wmi_pdev_suspend_cmd_fixed_param *cmd;
1264 	wmi_buf_t wmibuf;
1265 	uint32_t len = sizeof(*cmd);
1266 	int32_t ret;
1267 
1268 	/*
1269 	 * send the comand to Target to ignore the
1270 	 * PCIE reset so as to ensure that Host and target
1271 	 * states are in sync
1272 	 */
1273 	wmibuf = wmi_buf_alloc(wmi_handle, len);
1274 	if (wmibuf == NULL)
1275 		return QDF_STATUS_E_NOMEM;
1276 
1277 	cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf);
1278 	WMITLV_SET_HDR(&cmd->tlv_header,
1279 		       WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param,
1280 		       WMITLV_GET_STRUCT_TLVLEN
1281 			       (wmi_pdev_suspend_cmd_fixed_param));
1282 	if (param->disable_target_intr)
1283 		cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR;
1284 	else
1285 		cmd->suspend_opt = WMI_PDEV_SUSPEND;
1286 
1287 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
1288 
1289 	ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len,
1290 				 WMI_PDEV_SUSPEND_CMDID);
1291 	if (ret) {
1292 		wmi_buf_free(wmibuf);
1293 		WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command");
1294 	}
1295 
1296 	return ret;
1297 }
1298 
1299 /**
1300  * send_resume_cmd_tlv() - WMI resume function
1301  * @param wmi_handle      : handle to WMI.
1302  * @mac_id: radio context
1303  *
1304  * Return: 0  on success and -ve on failure.
1305  */
1306 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle,
1307 				uint8_t mac_id)
1308 {
1309 	wmi_buf_t wmibuf;
1310 	wmi_pdev_resume_cmd_fixed_param *cmd;
1311 	QDF_STATUS ret;
1312 
1313 	wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
1314 	if (wmibuf == NULL)
1315 		return QDF_STATUS_E_NOMEM;
1316 	cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf);
1317 	WMITLV_SET_HDR(&cmd->tlv_header,
1318 		       WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param,
1319 		       WMITLV_GET_STRUCT_TLVLEN
1320 			       (wmi_pdev_resume_cmd_fixed_param));
1321 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
1322 	ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd),
1323 				   WMI_PDEV_RESUME_CMDID);
1324 	if (QDF_IS_STATUS_ERROR(ret)) {
1325 		WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command");
1326 		wmi_buf_free(wmibuf);
1327 	}
1328 
1329 	return ret;
1330 }
1331 
1332 #ifdef FEATURE_WLAN_D0WOW
1333 /**
1334  *  send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function
1335  *  @param wmi_handle: handle to WMI.
1336  *  @mac_id: radio context
1337  *
1338  *  Return: 0  on success  and  error code on failure.
1339  */
1340 static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle,
1341 				uint8_t mac_id)
1342 {
1343 	wmi_d0_wow_enable_disable_cmd_fixed_param *cmd;
1344 	wmi_buf_t buf;
1345 	int32_t len;
1346 	QDF_STATUS status;
1347 
1348 	len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param);
1349 
1350 	buf = wmi_buf_alloc(wmi_handle, len);
1351 	if (!buf) {
1352 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
1353 		return QDF_STATUS_E_NOMEM;
1354 	}
1355 	cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf);
1356 	WMITLV_SET_HDR(&cmd->tlv_header,
1357 		WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param,
1358 		WMITLV_GET_STRUCT_TLVLEN
1359 		(wmi_d0_wow_enable_disable_cmd_fixed_param));
1360 
1361 	cmd->enable = true;
1362 
1363 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
1364 			WMI_D0_WOW_ENABLE_DISABLE_CMDID);
1365 	if (QDF_IS_STATUS_ERROR(status))
1366 		wmi_buf_free(buf);
1367 
1368 	return status;
1369 }
1370 
1371 /**
1372  *  send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function
1373  *  @param wmi_handle: handle to WMI.
1374  *  @mac_id: radio context
1375  *
1376  *  Return: 0  on success  and  error code on failure.
1377  */
1378 static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle,
1379 				uint8_t mac_id)
1380 {
1381 	wmi_d0_wow_enable_disable_cmd_fixed_param *cmd;
1382 	wmi_buf_t buf;
1383 	int32_t len;
1384 	QDF_STATUS status;
1385 
1386 	len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param);
1387 
1388 	buf = wmi_buf_alloc(wmi_handle, len);
1389 	if (!buf) {
1390 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
1391 		return QDF_STATUS_E_NOMEM;
1392 	}
1393 	cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf);
1394 	WMITLV_SET_HDR(&cmd->tlv_header,
1395 		WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param,
1396 		WMITLV_GET_STRUCT_TLVLEN
1397 		(wmi_d0_wow_enable_disable_cmd_fixed_param));
1398 
1399 	cmd->enable = false;
1400 
1401 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
1402 			WMI_D0_WOW_ENABLE_DISABLE_CMDID);
1403 	if (QDF_IS_STATUS_ERROR(status))
1404 		wmi_buf_free(buf);
1405 
1406 	return status;
1407 }
1408 #endif
1409 
1410 /**
1411  *  send_wow_enable_cmd_tlv() - WMI wow enable function
1412  *  @param wmi_handle      : handle to WMI.
1413  *  @param param    : pointer to hold wow enable parameter
1414  *  @mac_id: radio context
1415  *
1416  *  Return: 0  on success and -ve on failure.
1417  */
1418 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle,
1419 				struct wow_cmd_params *param,
1420 				uint8_t mac_id)
1421 {
1422 	wmi_wow_enable_cmd_fixed_param *cmd;
1423 	wmi_buf_t buf;
1424 	int32_t len;
1425 	int32_t ret;
1426 
1427 	len = sizeof(wmi_wow_enable_cmd_fixed_param);
1428 
1429 	buf = wmi_buf_alloc(wmi_handle, len);
1430 	if (!buf) {
1431 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
1432 		return QDF_STATUS_E_NOMEM;
1433 	}
1434 	cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf);
1435 	WMITLV_SET_HDR(&cmd->tlv_header,
1436 		       WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param,
1437 		       WMITLV_GET_STRUCT_TLVLEN
1438 			       (wmi_wow_enable_cmd_fixed_param));
1439 	cmd->enable = param->enable;
1440 	if (param->can_suspend_link)
1441 		cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED;
1442 	else
1443 		cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED;
1444 	cmd->flags = param->flags;
1445 
1446 	WMI_LOGI("suspend type: %s",
1447 		cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ?
1448 		"WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED");
1449 
1450 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1451 				   WMI_WOW_ENABLE_CMDID);
1452 	if (ret)
1453 		wmi_buf_free(buf);
1454 
1455 	return ret;
1456 }
1457 
1458 /**
1459  * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters
1460  * @wmi_handle: wmi handle
1461  * @peer_addr: peer mac address
1462  * @param: pointer to ap_ps parameter structure
1463  *
1464  * Return: QDF_STATUS_SUCCESS for success or error code
1465  */
1466 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle,
1467 					   uint8_t *peer_addr,
1468 					   struct ap_ps_params *param)
1469 {
1470 	wmi_ap_ps_peer_cmd_fixed_param *cmd;
1471 	wmi_buf_t buf;
1472 	int32_t err;
1473 
1474 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
1475 	if (!buf) {
1476 		WMI_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd");
1477 		return QDF_STATUS_E_NOMEM;
1478 	}
1479 	cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf);
1480 	WMITLV_SET_HDR(&cmd->tlv_header,
1481 		       WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param,
1482 		       WMITLV_GET_STRUCT_TLVLEN
1483 			       (wmi_ap_ps_peer_cmd_fixed_param));
1484 	cmd->vdev_id = param->vdev_id;
1485 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
1486 	cmd->param = param->param;
1487 	cmd->value = param->value;
1488 	err = wmi_unified_cmd_send(wmi_handle, buf,
1489 				   sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID);
1490 	if (err) {
1491 		WMI_LOGE("Failed to send set_ap_ps_param cmd");
1492 		wmi_buf_free(buf);
1493 		return QDF_STATUS_E_FAILURE;
1494 	}
1495 
1496 	return 0;
1497 }
1498 
1499 /**
1500  * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters
1501  * @wmi_handle: wmi handle
1502  * @peer_addr: peer mac address
1503  * @param: pointer to sta_ps parameter structure
1504  *
1505  * Return: QDF_STATUS_SUCCESS for success or error code
1506  */
1507 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle,
1508 					   struct sta_ps_params *param)
1509 {
1510 	wmi_sta_powersave_param_cmd_fixed_param *cmd;
1511 	wmi_buf_t buf;
1512 	int32_t len = sizeof(*cmd);
1513 
1514 	buf = wmi_buf_alloc(wmi_handle, len);
1515 	if (!buf) {
1516 		WMI_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__);
1517 		return QDF_STATUS_E_NOMEM;
1518 	}
1519 
1520 	cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf);
1521 	WMITLV_SET_HDR(&cmd->tlv_header,
1522 		       WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param,
1523 		       WMITLV_GET_STRUCT_TLVLEN
1524 			       (wmi_sta_powersave_param_cmd_fixed_param));
1525 	cmd->vdev_id = param->vdev_id;
1526 	cmd->param = param->param;
1527 	cmd->value = param->value;
1528 
1529 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1530 				 WMI_STA_POWERSAVE_PARAM_CMDID)) {
1531 		WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d",
1532 			 param->vdev_id, param->param, param->value);
1533 		wmi_buf_free(buf);
1534 		return QDF_STATUS_E_FAILURE;
1535 	}
1536 
1537 	return 0;
1538 }
1539 
1540 /**
1541  * send_crash_inject_cmd_tlv() - inject fw crash
1542  * @wmi_handle: wmi handle
1543  * @param: ponirt to crash inject paramter structure
1544  *
1545  * Return: QDF_STATUS_SUCCESS for success or return error
1546  */
1547 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle,
1548 			 struct crash_inject *param)
1549 {
1550 	int32_t ret = 0;
1551 	WMI_FORCE_FW_HANG_CMD_fixed_param *cmd;
1552 	uint16_t len = sizeof(*cmd);
1553 	wmi_buf_t buf;
1554 
1555 	buf = wmi_buf_alloc(wmi_handle, len);
1556 	if (!buf) {
1557 		WMI_LOGE("%s: wmi_buf_alloc failed!", __func__);
1558 		return QDF_STATUS_E_NOMEM;
1559 	}
1560 
1561 	cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf);
1562 	WMITLV_SET_HDR(&cmd->tlv_header,
1563 		       WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param,
1564 		       WMITLV_GET_STRUCT_TLVLEN
1565 			       (WMI_FORCE_FW_HANG_CMD_fixed_param));
1566 	cmd->type = param->type;
1567 	cmd->delay_time_ms = param->delay_time_ms;
1568 
1569 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1570 		WMI_FORCE_FW_HANG_CMDID);
1571 	if (ret) {
1572 		WMI_LOGE("%s: Failed to send set param command, ret = %d",
1573 			 __func__, ret);
1574 		wmi_buf_free(buf);
1575 	}
1576 
1577 	return ret;
1578 }
1579 
1580 /**
1581  *  send_dbglog_cmd_tlv() - set debug log level
1582  *  @param wmi_handle      : handle to WMI.
1583  *  @param param    : pointer to hold dbglog level parameter
1584  *
1585  *  Return: 0  on success and -ve on failure.
1586  */
1587  static QDF_STATUS
1588 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle,
1589 				struct dbglog_params *dbglog_param)
1590 {
1591 	wmi_buf_t buf;
1592 	wmi_debug_log_config_cmd_fixed_param *configmsg;
1593 	QDF_STATUS status;
1594 	int32_t i;
1595 	int32_t len;
1596 	int8_t *buf_ptr;
1597 	int32_t *module_id_bitmap_array;     /* Used to fomr the second tlv */
1598 
1599 	ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS);
1600 
1601 	/* Allocate size for 2 tlvs - including tlv hdr space for second tlv */
1602 	len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE +
1603 	      (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS);
1604 	buf = wmi_buf_alloc(wmi_handle, len);
1605 	if (buf == NULL)
1606 		return QDF_STATUS_E_NOMEM;
1607 
1608 	configmsg =
1609 		(wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf));
1610 	buf_ptr = (int8_t *) configmsg;
1611 	WMITLV_SET_HDR(&configmsg->tlv_header,
1612 		       WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param,
1613 		       WMITLV_GET_STRUCT_TLVLEN
1614 			       (wmi_debug_log_config_cmd_fixed_param));
1615 	configmsg->dbg_log_param = dbglog_param->param;
1616 	configmsg->value = dbglog_param->val;
1617 	/* Filling in the data part of second tlv -- should
1618 	 * follow first tlv _ WMI_TLV_HDR_SIZE */
1619 	module_id_bitmap_array = (A_UINT32 *) (buf_ptr +
1620 				       sizeof
1621 				       (wmi_debug_log_config_cmd_fixed_param)
1622 				       + WMI_TLV_HDR_SIZE);
1623 	WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param),
1624 		       WMITLV_TAG_ARRAY_UINT32,
1625 		       sizeof(A_UINT32) * MAX_MODULE_ID_BITMAP_WORDS);
1626 	if (dbglog_param->module_id_bitmap) {
1627 		for (i = 0; i < dbglog_param->bitmap_len; ++i) {
1628 			module_id_bitmap_array[i] =
1629 					dbglog_param->module_id_bitmap[i];
1630 		}
1631 	}
1632 
1633 	status = wmi_unified_cmd_send(wmi_handle, buf,
1634 				      len, WMI_DBGLOG_CFG_CMDID);
1635 
1636 	if (status != QDF_STATUS_SUCCESS)
1637 		wmi_buf_free(buf);
1638 
1639 	return status;
1640 }
1641 
1642 #ifdef CONFIG_MCL
1643 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle,
1644 				uint32_t host_param)
1645 {
1646 	return host_param;
1647 }
1648 #else
1649 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle,
1650 				uint32_t host_param)
1651 {
1652 	if (host_param < wmi_vdev_param_max)
1653 		return wmi_handle->vdev_param[host_param];
1654 
1655 	return WMI_UNAVAILABLE_PARAM;
1656 }
1657 #endif
1658 /**
1659  *  send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function
1660  *  @param wmi_handle      : handle to WMI.
1661  *  @param macaddr        : MAC address
1662  *  @param param    : pointer to hold vdev set parameter
1663  *
1664  *  Return: 0  on success and -ve on failure.
1665  */
1666 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle,
1667 				struct vdev_set_params *param)
1668 {
1669 	QDF_STATUS ret;
1670 	wmi_vdev_set_param_cmd_fixed_param *cmd;
1671 	wmi_buf_t buf;
1672 	uint16_t len = sizeof(*cmd);
1673 	uint32_t vdev_param;
1674 
1675 	vdev_param = convert_host_vdev_param_tlv(wmi_handle, param->param_id);
1676 	if (vdev_param == WMI_UNAVAILABLE_PARAM) {
1677 		WMI_LOGW("%s:Vdev param %d not available", __func__,
1678 				param->param_id);
1679 		return QDF_STATUS_E_INVAL;
1680 
1681 	}
1682 
1683 	buf = wmi_buf_alloc(wmi_handle, len);
1684 	if (!buf) {
1685 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
1686 		return QDF_STATUS_E_NOMEM;
1687 	}
1688 	cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
1689 	WMITLV_SET_HDR(&cmd->tlv_header,
1690 		       WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param,
1691 		       WMITLV_GET_STRUCT_TLVLEN
1692 			       (wmi_vdev_set_param_cmd_fixed_param));
1693 	cmd->vdev_id = param->if_id;
1694 	cmd->param_id = vdev_param;
1695 	cmd->param_value = param->param_value;
1696 	WMI_LOGD("Setting vdev %d param = %x, value = %u",
1697 		 param->if_id, param->param_id, param->param_value);
1698 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1699 				   WMI_VDEV_SET_PARAM_CMDID);
1700 	if (QDF_IS_STATUS_ERROR(ret)) {
1701 		WMI_LOGE("Failed to send set param command ret = %d", ret);
1702 		wmi_buf_free(buf);
1703 	}
1704 
1705 	return ret;
1706 }
1707 
1708 /**
1709  *  send_stats_request_cmd_tlv() - WMI request stats function
1710  *  @param wmi_handle      : handle to WMI.
1711  *  @param macaddr        : MAC address
1712  *  @param param    : pointer to hold stats request parameter
1713  *
1714  *  Return: 0  on success and -ve on failure.
1715  */
1716 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle,
1717 				uint8_t macaddr[IEEE80211_ADDR_LEN],
1718 				struct stats_request_params *param)
1719 {
1720 	int32_t ret;
1721 	wmi_request_stats_cmd_fixed_param *cmd;
1722 	wmi_buf_t buf;
1723 	uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param);
1724 
1725 	buf = wmi_buf_alloc(wmi_handle, len);
1726 	if (!buf) {
1727 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
1728 		return -QDF_STATUS_E_NOMEM;
1729 	}
1730 
1731 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
1732 	WMITLV_SET_HDR(&cmd->tlv_header,
1733 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
1734 		       WMITLV_GET_STRUCT_TLVLEN
1735 			       (wmi_request_stats_cmd_fixed_param));
1736 	cmd->stats_id = param->stats_id;
1737 	cmd->vdev_id = param->vdev_id;
1738 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
1739 							param->pdev_id);
1740 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
1741 
1742 	WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->",
1743 				cmd->stats_id, cmd->vdev_id, cmd->pdev_id);
1744 
1745 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1746 					 WMI_REQUEST_STATS_CMDID);
1747 
1748 	if (ret) {
1749 		WMI_LOGE("Failed to send status request to fw =%d", ret);
1750 		wmi_buf_free(buf);
1751 	}
1752 
1753 	return ret;
1754 }
1755 
1756 #ifdef CONFIG_WIN
1757 /**
1758  *  send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log
1759  *  @param wmi_handle      : handle to WMI.
1760  *  @param PKTLOG_EVENT	: packet log event
1761  *  @mac_id: mac id to have radio context
1762  *
1763  *  Return: 0  on success and -ve on failure.
1764  */
1765 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle,
1766 			WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id)
1767 {
1768 	int32_t ret;
1769 	wmi_pdev_pktlog_enable_cmd_fixed_param *cmd;
1770 	wmi_buf_t buf;
1771 	uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param);
1772 
1773 	buf = wmi_buf_alloc(wmi_handle, len);
1774 	if (!buf) {
1775 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
1776 		return -QDF_STATUS_E_NOMEM;
1777 	}
1778 
1779 	cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf);
1780 	WMITLV_SET_HDR(&cmd->tlv_header,
1781 		       WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param,
1782 		       WMITLV_GET_STRUCT_TLVLEN
1783 			       (wmi_pdev_pktlog_enable_cmd_fixed_param));
1784 	cmd->evlist = PKTLOG_EVENT;
1785 	cmd->pdev_id = mac_id;
1786 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1787 					 WMI_PDEV_PKTLOG_ENABLE_CMDID);
1788 	if (ret) {
1789 		WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret);
1790 		wmi_buf_free(buf);
1791 	}
1792 
1793 	return ret;
1794 }
1795 
1796 /**
1797  *  send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log
1798  *  @param wmi_handle      : handle to WMI.
1799  *  @mac_id: mac id to have radio context
1800  *
1801  *  Return: 0  on success and -ve on failure.
1802  */
1803 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle,
1804 			uint8_t mac_id)
1805 {
1806 	int32_t ret;
1807 	wmi_pdev_pktlog_disable_cmd_fixed_param *cmd;
1808 	wmi_buf_t buf;
1809 	uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param);
1810 
1811 	buf = wmi_buf_alloc(wmi_handle, len);
1812 	if (!buf) {
1813 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
1814 		return -QDF_STATUS_E_NOMEM;
1815 	}
1816 
1817 	cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf);
1818 	WMITLV_SET_HDR(&cmd->tlv_header,
1819 		       WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param,
1820 		       WMITLV_GET_STRUCT_TLVLEN
1821 			       (wmi_pdev_pktlog_disable_cmd_fixed_param));
1822 	cmd->pdev_id = mac_id;
1823 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1824 					 WMI_PDEV_PKTLOG_DISABLE_CMDID);
1825 	if (ret) {
1826 		WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret);
1827 		wmi_buf_free(buf);
1828 	}
1829 
1830 	return ret;
1831 }
1832 #else
1833 /**
1834  *  send_packet_log_enable_cmd_tlv() - Send WMI command to enable
1835  *  packet-log
1836  *  @param wmi_handle      : handle to WMI.
1837  *  @param macaddr        : MAC address
1838  *  @param param    : pointer to hold stats request parameter
1839  *
1840  *  Return: 0  on success and -ve on failure.
1841  */
1842 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle,
1843 				uint8_t macaddr[IEEE80211_ADDR_LEN],
1844 				struct packet_enable_params *param)
1845 {
1846 	return 0;
1847 }
1848 /**
1849  *  send_packet_log_disable_cmd_tlv() - Send WMI command to disable
1850  *  packet-log
1851  *  @param wmi_handle      : handle to WMI.
1852  *  @mac_id: mac id to have radio context
1853  *
1854  *  Return: 0  on success and -ve on failure.
1855  */
1856 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle,
1857 				uint8_t mac_id)
1858 {
1859 	return 0;
1860 }
1861 #endif
1862 
1863 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff
1864 /**
1865  *  send_time_stamp_sync_cmd_tlv() - Send WMI command to
1866  *  sync time between bwtween host and firmware
1867  *  @param wmi_handle      : handle to WMI.
1868  *
1869  *  Return: None
1870  */
1871 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle)
1872 {
1873 	wmi_buf_t buf;
1874 	A_STATUS status = A_OK;
1875 	WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp;
1876 	int32_t len;
1877 	qdf_time_t time_ms;
1878 
1879 	len = sizeof(*time_stamp);
1880 	buf = wmi_buf_alloc(wmi_handle, len);
1881 
1882 	if (!buf) {
1883 		WMI_LOGP(FL("wmi_buf_alloc failed"));
1884 		return;
1885 	}
1886 	time_stamp =
1887 		(WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *)
1888 			(wmi_buf_data(buf));
1889 	WMITLV_SET_HDR(&time_stamp->tlv_header,
1890 		WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param,
1891 		WMITLV_GET_STRUCT_TLVLEN(
1892 		WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param));
1893 
1894 	time_ms = qdf_get_time_of_the_day_ms();
1895 	time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS;
1896 	time_stamp->time_stamp_low = time_ms &
1897 		WMI_FW_TIME_STAMP_LOW_MASK;
1898 	/*
1899 	 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms
1900 	 * wont exceed 27 bit
1901 	 */
1902 	time_stamp->time_stamp_high = 0;
1903 	WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"),
1904 		time_stamp->mode, time_stamp->time_stamp_low,
1905 		time_stamp->time_stamp_high);
1906 
1907 	status = wmi_unified_cmd_send(wmi_handle, buf,
1908 				      len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID);
1909 	if (status) {
1910 		WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command");
1911 		wmi_buf_free(buf);
1912 	}
1913 
1914 }
1915 
1916 #ifdef WLAN_SUPPORT_FILS
1917 /**
1918  * extract_swfda_vdev_id_tlv() - extract swfda vdev id from event
1919  * @wmi_handle: wmi handle
1920  * @evt_buf: pointer to event buffer
1921  * @vdev_id: pointer to hold vdev id
1922  *
1923  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure
1924  */
1925 static QDF_STATUS
1926 extract_swfda_vdev_id_tlv(wmi_unified_t wmi_handle,
1927 			  void *evt_buf, uint32_t *vdev_id)
1928 {
1929 	WMI_HOST_SWFDA_EVENTID_param_tlvs *param_buf;
1930 	wmi_host_swfda_event_fixed_param *swfda_event;
1931 
1932 	param_buf = (WMI_HOST_SWFDA_EVENTID_param_tlvs *)evt_buf;
1933 	if (!param_buf) {
1934 		WMI_LOGE("Invalid swfda event buffer");
1935 		return QDF_STATUS_E_INVAL;
1936 	}
1937 	swfda_event = param_buf->fixed_param;
1938 	*vdev_id = swfda_event->vdev_id;
1939 
1940 	return QDF_STATUS_SUCCESS;
1941 }
1942 
1943 /**
1944  * send_vdev_fils_enable_cmd_tlv() - enable/Disable FD Frame command to fw
1945  * @wmi_handle: wmi handle
1946  * @param: pointer to hold FILS discovery enable param
1947  *
1948  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE on failure
1949  */
1950 static QDF_STATUS
1951 send_vdev_fils_enable_cmd_tlv(wmi_unified_t wmi_handle,
1952 			      struct config_fils_params *param)
1953 {
1954 	wmi_enable_fils_cmd_fixed_param *cmd;
1955 	wmi_buf_t buf;
1956 	QDF_STATUS status;
1957 	uint32_t len = sizeof(wmi_enable_fils_cmd_fixed_param);
1958 
1959 	buf = wmi_buf_alloc(wmi_handle, len);
1960 	if (!buf) {
1961 		WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__);
1962 		return QDF_STATUS_E_NOMEM;
1963 	}
1964 	cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data(buf);
1965 	WMITLV_SET_HDR(&cmd->tlv_header,
1966 		       WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param,
1967 		       WMITLV_GET_STRUCT_TLVLEN(
1968 		       wmi_enable_fils_cmd_fixed_param));
1969 	cmd->vdev_id = param->vdev_id;
1970 	cmd->fd_period = param->fd_period;
1971 	WMI_LOGI("Setting FD period to %d vdev id : %d\n",
1972 		 param->fd_period, param->vdev_id);
1973 
1974 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
1975 				      WMI_ENABLE_FILS_CMDID);
1976 	if (status != QDF_STATUS_SUCCESS) {
1977 		wmi_buf_free(buf);
1978 		return QDF_STATUS_E_FAILURE;
1979 	}
1980 
1981 	return QDF_STATUS_SUCCESS;
1982 }
1983 
1984 /**
1985  * send_fils_discovery_send_cmd_tlv() - WMI FILS Discovery send function
1986  * @wmi_handle: wmi handle
1987  * @param: pointer to hold FD send cmd parameter
1988  *
1989  * Return : QDF_STATUS_SUCCESS on success and QDF_STATUS_E_NOMEM on failure.
1990  */
1991 static QDF_STATUS
1992 send_fils_discovery_send_cmd_tlv(wmi_unified_t wmi_handle,
1993 				 struct fd_params *param)
1994 {
1995 	QDF_STATUS ret;
1996 	wmi_fd_send_from_host_cmd_fixed_param *cmd;
1997 	wmi_buf_t wmi_buf;
1998 	qdf_dma_addr_t dma_addr;
1999 
2000 	wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
2001 	if (!wmi_buf) {
2002 		WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__);
2003 		return QDF_STATUS_E_NOMEM;
2004 	}
2005 	cmd = (wmi_fd_send_from_host_cmd_fixed_param *)wmi_buf_data(wmi_buf);
2006 	WMITLV_SET_HDR(&cmd->tlv_header,
2007 		       WMITLV_TAG_STRUC_wmi_fd_send_from_host_cmd_fixed_param,
2008 		       WMITLV_GET_STRUCT_TLVLEN(
2009 		       wmi_fd_send_from_host_cmd_fixed_param));
2010 	cmd->vdev_id = param->vdev_id;
2011 	cmd->data_len = qdf_nbuf_len(param->wbuf);
2012 	dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0);
2013 	qdf_dmaaddr_to_32s(dma_addr, &cmd->frag_ptr_lo, &cmd->frag_ptr_hi);
2014 	cmd->frame_ctrl = param->frame_ctrl;
2015 
2016 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd),
2017 				   WMI_PDEV_SEND_FD_CMDID);
2018 	if (ret != QDF_STATUS_SUCCESS) {
2019 		WMI_LOGE("%s: Failed to send fils discovery frame: %d",
2020 			 __func__, ret);
2021 		wmi_buf_free(wmi_buf);
2022 	}
2023 
2024 	return ret;
2025 }
2026 #endif /* WLAN_SUPPORT_FILS */
2027 
2028 static QDF_STATUS send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle,
2029 				struct beacon_params *param)
2030 {
2031 	QDF_STATUS ret;
2032 	wmi_bcn_send_from_host_cmd_fixed_param *cmd;
2033 	wmi_buf_t wmi_buf;
2034 	qdf_dma_addr_t dma_addr;
2035 	uint32_t dtim_flag = 0;
2036 
2037 	wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
2038 	if (!wmi_buf) {
2039 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
2040 		return QDF_STATUS_E_NOMEM;
2041 	}
2042 	if (param->is_dtim_count_zero) {
2043 		dtim_flag |= WMI_BCN_SEND_DTIM_ZERO;
2044 		if (param->is_bitctl_reqd) {
2045 			/* deliver CAB traffic in next DTIM beacon */
2046 			dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET;
2047 		}
2048 	}
2049 	cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf);
2050 	WMITLV_SET_HDR(&cmd->tlv_header,
2051 		WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param,
2052 		WMITLV_GET_STRUCT_TLVLEN
2053 				(wmi_bcn_send_from_host_cmd_fixed_param));
2054 	cmd->vdev_id = param->vdev_id;
2055 	cmd->data_len = qdf_nbuf_len(param->wbuf);
2056 	cmd->frame_ctrl = param->frame_ctrl;
2057 	cmd->dtim_flag = dtim_flag;
2058 	dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0);
2059 	cmd->frag_ptr_lo = qdf_get_lower_32_bits(dma_addr);
2060 #if defined(HTT_PADDR64)
2061 	cmd->frag_ptr_hi = qdf_get_upper_32_bits(dma_addr) & 0x1F;
2062 #endif
2063 	cmd->bcn_antenna = param->bcn_txant;
2064 
2065 	ret = wmi_unified_cmd_send(wmi_handle,
2066 			wmi_buf, sizeof(*cmd), WMI_PDEV_SEND_BCN_CMDID);
2067 	if (ret != QDF_STATUS_SUCCESS) {
2068 		WMI_LOGE("%s: Failed to send bcn: %d", __func__, ret);
2069 		wmi_buf_free(wmi_buf);
2070 	}
2071 
2072 	return ret;
2073 }
2074 
2075 /**
2076  *  send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function
2077  *  @param wmi_handle      : handle to WMI.
2078  *  @param param    : pointer to hold beacon send cmd parameter
2079  *
2080  *  Return: 0  on success and -ve on failure.
2081  */
2082 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle,
2083 				struct beacon_tmpl_params *param)
2084 {
2085 	int32_t ret;
2086 	wmi_bcn_tmpl_cmd_fixed_param *cmd;
2087 	wmi_bcn_prb_info *bcn_prb_info;
2088 	wmi_buf_t wmi_buf;
2089 	uint8_t *buf_ptr;
2090 	uint32_t wmi_buf_len;
2091 
2092 	wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) +
2093 		      sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE +
2094 		      param->tmpl_len_aligned;
2095 	wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
2096 	if (!wmi_buf) {
2097 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
2098 		return QDF_STATUS_E_NOMEM;
2099 	}
2100 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
2101 	cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr;
2102 	WMITLV_SET_HDR(&cmd->tlv_header,
2103 		       WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param,
2104 		       WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param));
2105 	cmd->vdev_id = param->vdev_id;
2106 	cmd->tim_ie_offset = param->tim_ie_offset;
2107 	cmd->csa_switch_count_offset = param->csa_switch_count_offset;
2108 	cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset;
2109 	cmd->buf_len = param->tmpl_len;
2110 	buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param);
2111 
2112 	bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr;
2113 	WMITLV_SET_HDR(&bcn_prb_info->tlv_header,
2114 		       WMITLV_TAG_STRUC_wmi_bcn_prb_info,
2115 		       WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info));
2116 	bcn_prb_info->caps = 0;
2117 	bcn_prb_info->erp = 0;
2118 	buf_ptr += sizeof(wmi_bcn_prb_info);
2119 
2120 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned);
2121 	buf_ptr += WMI_TLV_HDR_SIZE;
2122 	qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len);
2123 
2124 	ret = wmi_unified_cmd_send(wmi_handle,
2125 				   wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID);
2126 	if (ret) {
2127 		WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret);
2128 		wmi_buf_free(wmi_buf);
2129 	}
2130 
2131 	return 0;
2132 }
2133 
2134 #ifdef CONFIG_MCL
2135 static inline void copy_peer_flags_tlv(
2136 			wmi_peer_assoc_complete_cmd_fixed_param * cmd,
2137 			struct peer_assoc_params *param)
2138 {
2139 	cmd->peer_flags = param->peer_flags;
2140 }
2141 #else
2142 static inline void copy_peer_flags_tlv(
2143 			wmi_peer_assoc_complete_cmd_fixed_param * cmd,
2144 			struct peer_assoc_params *param)
2145 {
2146 	/*
2147 	 * The target only needs a subset of the flags maintained in the host.
2148 	 * Just populate those flags and send it down
2149 	 */
2150 	cmd->peer_flags = 0;
2151 
2152 	/*
2153 	 * Do not enable HT/VHT if WMM/wme is disabled for vap.
2154 	 */
2155 	if (param->is_wme_set) {
2156 
2157 		if (param->qos_flag)
2158 			cmd->peer_flags |= WMI_PEER_QOS;
2159 		if (param->apsd_flag)
2160 			cmd->peer_flags |= WMI_PEER_APSD;
2161 		if (param->ht_flag)
2162 			cmd->peer_flags |= WMI_PEER_HT;
2163 		if (param->bw_40)
2164 			cmd->peer_flags |= WMI_PEER_40MHZ;
2165 		if (param->bw_80)
2166 			cmd->peer_flags |= WMI_PEER_80MHZ;
2167 		if (param->bw_160)
2168 			cmd->peer_flags |= WMI_PEER_160MHZ;
2169 
2170 		/* Typically if STBC is enabled for VHT it should be enabled
2171 		 * for HT as well
2172 		 **/
2173 		if (param->stbc_flag)
2174 			cmd->peer_flags |= WMI_PEER_STBC;
2175 
2176 		/* Typically if LDPC is enabled for VHT it should be enabled
2177 		 * for HT as well
2178 		 **/
2179 		if (param->ldpc_flag)
2180 			cmd->peer_flags |= WMI_PEER_LDPC;
2181 
2182 		if (param->static_mimops_flag)
2183 			cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS;
2184 		if (param->dynamic_mimops_flag)
2185 			cmd->peer_flags |= WMI_PEER_DYN_MIMOPS;
2186 		if (param->spatial_mux_flag)
2187 			cmd->peer_flags |= WMI_PEER_SPATIAL_MUX;
2188 		if (param->vht_flag)
2189 			cmd->peer_flags |= WMI_PEER_VHT;
2190 		if (param->he_flag)
2191 			cmd->peer_flags |= WMI_PEER_HE;
2192 	}
2193 
2194 	if (param->is_pmf_enabled)
2195 		cmd->peer_flags |= WMI_PEER_PMF;
2196 	/*
2197 	 * Suppress authorization for all AUTH modes that need 4-way handshake
2198 	 * (during re-association).
2199 	 * Authorization will be done for these modes on key installation.
2200 	 */
2201 	if (param->auth_flag)
2202 		cmd->peer_flags |= WMI_PEER_AUTH;
2203 	if (param->need_ptk_4_way)
2204 		cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
2205 	else
2206 		cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY;
2207 	if (param->need_gtk_2_way)
2208 		cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
2209 	/* safe mode bypass the 4-way handshake */
2210 	if (param->safe_mode_enabled)
2211 		cmd->peer_flags &=
2212 		    ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY);
2213 	/* Disable AMSDU for station transmit, if user configures it */
2214 	/* Disable AMSDU for AP transmit to 11n Stations, if user configures
2215 	 * it
2216 	 * if (param->amsdu_disable) Add after FW support
2217 	 **/
2218 
2219 	/* Target asserts if node is marked HT and all MCS is set to 0.
2220 	 * Mark the node as non-HT if all the mcs rates are disabled through
2221 	 * iwpriv
2222 	 **/
2223 	if (param->peer_ht_rates.num_rates == 0)
2224 		cmd->peer_flags &= ~WMI_PEER_HT;
2225 }
2226 #endif
2227 
2228 #ifdef CONFIG_MCL
2229 static inline void copy_peer_mac_addr_tlv(
2230 		wmi_peer_assoc_complete_cmd_fixed_param * cmd,
2231 		struct peer_assoc_params *param)
2232 {
2233 	qdf_mem_copy(&cmd->peer_macaddr, &param->peer_macaddr,
2234 			sizeof(param->peer_macaddr));
2235 }
2236 #else
2237 static inline void copy_peer_mac_addr_tlv(
2238 		wmi_peer_assoc_complete_cmd_fixed_param * cmd,
2239 		struct peer_assoc_params *param)
2240 {
2241 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr);
2242 }
2243 #endif
2244 
2245 /**
2246  *  send_peer_assoc_cmd_tlv() - WMI peer assoc function
2247  *  @param wmi_handle      : handle to WMI.
2248  *  @param param    : pointer to peer assoc parameter
2249  *
2250  *  Return: 0  on success and -ve on failure.
2251  */
2252 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle,
2253 				struct peer_assoc_params *param)
2254 {
2255 	wmi_peer_assoc_complete_cmd_fixed_param *cmd;
2256 	wmi_vht_rate_set *mcs;
2257 	wmi_he_rate_set *he_mcs;
2258 	wmi_buf_t buf;
2259 	int32_t len;
2260 	uint8_t *buf_ptr;
2261 	QDF_STATUS ret;
2262 	uint32_t peer_legacy_rates_align;
2263 	uint32_t peer_ht_rates_align;
2264 	int32_t i;
2265 
2266 
2267 	peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates);
2268 	peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates);
2269 
2270 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
2271 		(peer_legacy_rates_align * sizeof(uint8_t)) +
2272 		WMI_TLV_HDR_SIZE +
2273 		(peer_ht_rates_align * sizeof(uint8_t)) +
2274 		sizeof(wmi_vht_rate_set) +
2275 		(sizeof(wmi_he_rate_set) * param->peer_he_mcs_count
2276 		+ WMI_TLV_HDR_SIZE);
2277 
2278 	buf = wmi_buf_alloc(wmi_handle, len);
2279 	if (!buf) {
2280 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
2281 		return QDF_STATUS_E_NOMEM;
2282 	}
2283 
2284 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
2285 	cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr;
2286 	WMITLV_SET_HDR(&cmd->tlv_header,
2287 		       WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param,
2288 		       WMITLV_GET_STRUCT_TLVLEN
2289 			       (wmi_peer_assoc_complete_cmd_fixed_param));
2290 
2291 	cmd->vdev_id = param->vdev_id;
2292 
2293 	cmd->peer_new_assoc = param->peer_new_assoc;
2294 	cmd->peer_associd = param->peer_associd;
2295 
2296 	copy_peer_flags_tlv(cmd, param);
2297 	copy_peer_mac_addr_tlv(cmd, param);
2298 
2299 	cmd->peer_rate_caps = param->peer_rate_caps;
2300 	cmd->peer_caps = param->peer_caps;
2301 	cmd->peer_listen_intval = param->peer_listen_intval;
2302 	cmd->peer_ht_caps = param->peer_ht_caps;
2303 	cmd->peer_max_mpdu = param->peer_max_mpdu;
2304 	cmd->peer_mpdu_density = param->peer_mpdu_density;
2305 	cmd->peer_vht_caps = param->peer_vht_caps;
2306 	cmd->peer_phymode = param->peer_phymode;
2307 
2308 	/* Update 11ax capabilities */
2309 	cmd->peer_he_cap_info = param->peer_he_cap_macinfo;
2310 	cmd->peer_he_ops = param->peer_he_ops;
2311 	qdf_mem_copy(&cmd->peer_he_cap_phy, &param->peer_he_cap_phyinfo,
2312 				sizeof(param->peer_he_cap_phyinfo));
2313 	qdf_mem_copy(&cmd->peer_ppet, &param->peer_ppet,
2314 				sizeof(param->peer_ppet));
2315 
2316 	/* Update peer legacy rate information */
2317 	buf_ptr += sizeof(*cmd);
2318 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
2319 				peer_legacy_rates_align);
2320 	buf_ptr += WMI_TLV_HDR_SIZE;
2321 	cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates;
2322 	qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates,
2323 		     param->peer_legacy_rates.num_rates);
2324 
2325 	/* Update peer HT rate information */
2326 	buf_ptr += peer_legacy_rates_align;
2327 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
2328 			  peer_ht_rates_align);
2329 	buf_ptr += WMI_TLV_HDR_SIZE;
2330 	cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates;
2331 	qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates,
2332 				 param->peer_ht_rates.num_rates);
2333 
2334 	/* VHT Rates */
2335 	buf_ptr += peer_ht_rates_align;
2336 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set,
2337 		       WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set));
2338 
2339 	cmd->peer_nss = param->peer_nss;
2340 
2341 	/* Update bandwidth-NSS mapping */
2342 	cmd->peer_bw_rxnss_override = 0;
2343 	cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override;
2344 
2345 	mcs = (wmi_vht_rate_set *) buf_ptr;
2346 	if (param->vht_capable) {
2347 		mcs->rx_max_rate = param->rx_max_rate;
2348 		mcs->rx_mcs_set = param->rx_mcs_set;
2349 		mcs->tx_max_rate = param->tx_max_rate;
2350 		mcs->tx_mcs_set = param->tx_mcs_set;
2351 	}
2352 
2353 	/* HE Rates */
2354 	cmd->peer_he_mcs = param->peer_he_mcs_count;
2355 	buf_ptr += sizeof(wmi_vht_rate_set);
2356 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2357 		(param->peer_he_mcs_count * sizeof(wmi_he_rate_set)));
2358 	buf_ptr += WMI_TLV_HDR_SIZE;
2359 
2360 	/* Loop through the HE rate set */
2361 	for (i = 0; i < param->peer_he_mcs_count; i++) {
2362 		he_mcs = (wmi_he_rate_set *) buf_ptr;
2363 		WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set,
2364 			WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set));
2365 
2366 		he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i];
2367 		he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i];
2368 		WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__,
2369 			i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set);
2370 		buf_ptr += sizeof(wmi_he_rate_set);
2371 	}
2372 
2373 
2374 	WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x "
2375 		 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d "
2376 		 "nss %d phymode %d peer_mpdu_density %d "
2377 		 "cmd->peer_vht_caps %x "
2378 		 "HE cap_info %x ops %x "
2379 		 "HE phy %x  %x  %x  "
2380 		 "peer_bw_rxnss_override %x", __func__,
2381 		 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags,
2382 		 cmd->peer_rate_caps, cmd->peer_caps,
2383 		 cmd->peer_listen_intval, cmd->peer_ht_caps,
2384 		 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode,
2385 		 cmd->peer_mpdu_density,
2386 		 cmd->peer_vht_caps, cmd->peer_he_cap_info,
2387 		 cmd->peer_he_ops, cmd->peer_he_cap_phy[0],
2388 		 cmd->peer_he_cap_phy[1], cmd->peer_he_cap_phy[2],
2389 		 cmd->peer_bw_rxnss_override);
2390 
2391 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2392 				   WMI_PEER_ASSOC_CMDID);
2393 	if (QDF_IS_STATUS_ERROR(ret)) {
2394 		WMI_LOGP("%s: Failed to send peer assoc command ret = %d",
2395 			 __func__, ret);
2396 		wmi_buf_free(buf);
2397 	}
2398 
2399 	return ret;
2400 }
2401 
2402 /* copy_scan_notify_events() - Helper routine to copy scan notify events
2403  */
2404 static inline void copy_scan_event_cntrl_flags(
2405 		wmi_start_scan_cmd_fixed_param * cmd,
2406 		struct scan_req_params *param)
2407 {
2408 
2409 	/* Scan events subscription */
2410 	if (param->scan_ev_started)
2411 		cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED;
2412 	if (param->scan_ev_completed)
2413 		cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED;
2414 	if (param->scan_ev_bss_chan)
2415 		cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL;
2416 	if (param->scan_ev_foreign_chan)
2417 		cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL;
2418 	if (param->scan_ev_dequeued)
2419 		cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED;
2420 	if (param->scan_ev_preempted)
2421 		cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED;
2422 	if (param->scan_ev_start_failed)
2423 		cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED;
2424 	if (param->scan_ev_restarted)
2425 		cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED;
2426 	if (param->scan_ev_foreign_chn_exit)
2427 		cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT;
2428 	if (param->scan_ev_suspended)
2429 		cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED;
2430 	if (param->scan_ev_resumed)
2431 		cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED;
2432 
2433 	/** Set scan control flags */
2434 	cmd->scan_ctrl_flags = 0;
2435 	if (param->scan_f_passive)
2436 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
2437 	if (param->scan_f_strict_passive_pch)
2438 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN;
2439 	if (param->scan_f_promisc_mode)
2440 		cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS;
2441 	if (param->scan_f_capture_phy_err)
2442 		cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR;
2443 	if (param->scan_f_half_rate)
2444 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT;
2445 	if (param->scan_f_quarter_rate)
2446 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT;
2447 	if (param->scan_f_cck_rates)
2448 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES;
2449 	if (param->scan_f_ofdm_rates)
2450 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES;
2451 	if (param->scan_f_chan_stat_evnt)
2452 		cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT;
2453 	if (param->scan_f_filter_prb_req)
2454 		cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
2455 	if (param->scan_f_bcast_probe)
2456 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ;
2457 	if (param->scan_f_offchan_mgmt_tx)
2458 		cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX;
2459 	if (param->scan_f_offchan_data_tx)
2460 		cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX;
2461 	if (param->scan_f_force_active_dfs_chn)
2462 		cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS;
2463 	if (param->scan_f_add_tpc_ie_in_probe)
2464 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ;
2465 	if (param->scan_f_add_ds_ie_in_probe)
2466 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
2467 	if (param->scan_f_add_spoofed_mac_in_probe)
2468 		cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ;
2469 	if (param->scan_f_add_rand_seq_in_probe)
2470 		cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ;
2471 	if (param->scan_f_en_ie_whitelist_in_probe)
2472 		cmd->scan_ctrl_flags |=
2473 			WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ;
2474 
2475 	/* for adaptive scan mode using 3 bits (21 - 23 bits) */
2476 	WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags,
2477 		param->adaptive_dwell_time_mode);
2478 }
2479 
2480 /* scan_copy_ie_buffer() - Copy scan ie_data */
2481 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr,
2482 				struct scan_req_params *params)
2483 {
2484 	qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len);
2485 }
2486 
2487 /*
2488  * get_pdev_wmi_handle() - Helper func to derive pdev wmi handle from vdev_id
2489  * @param wmi_handle : Handle to WMI
2490  * @param vdev_id : vdev identifier
2491  *
2492  * Return : void *
2493  */
2494 static inline void *get_pdev_wmi_handle(wmi_unified_t wmi_handle, uint8_t vdev_id)
2495 {
2496 	struct wlan_objmgr_vdev *vdev = NULL;
2497 	struct wlan_objmgr_pdev *pdev = NULL;
2498 	uint8_t pdev_id = 0;
2499 
2500 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
2501 			(struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc,
2502 			vdev_id, WLAN_SCAN_ID);
2503 	if (vdev) {
2504 		wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID);
2505 		pdev = wlan_vdev_get_pdev(vdev);
2506 		if (pdev)
2507 			pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
2508 		else {
2509 			qdf_print("%s : Invalid PDEV, forcing pdev_id to 0\n", __func__);
2510 		}
2511 	} else {
2512 		qdf_print("%s : Invalid VDEV, forcing pdev_id to 0\n", __func__);
2513 	}
2514 
2515 	return wmi_unified_get_pdev_handle(wmi_handle->soc, pdev_id);
2516 }
2517 
2518 /**
2519  * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer
2520  * @mac: random mac addr
2521  * @mask: random mac mask
2522  * @mac_addr: wmi random mac
2523  * @mac_mask: wmi random mac mask
2524  *
2525  * Return None.
2526  */
2527 static inline
2528 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask,
2529 			      wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask)
2530 {
2531 	WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr);
2532 	WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask);
2533 }
2534 
2535 /*
2536  * wmi_fill_vendor_oui() - fill vendor OUIs
2537  * @buf_ptr: pointer to wmi tlv buffer
2538  * @num_vendor_oui: number of vendor OUIs to be filled
2539  * @param_voui: pointer to OUI buffer
2540  *
2541  * This function populates the wmi tlv buffer when vendor specific OUIs are
2542  * present.
2543  *
2544  * Return: None
2545  */
2546 static inline
2547 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui,
2548 			 uint32_t *pvoui)
2549 {
2550 	wmi_vendor_oui *voui = NULL;
2551 	uint32_t i;
2552 
2553 	voui = (wmi_vendor_oui *)buf_ptr;
2554 
2555 	for (i = 0; i < num_vendor_oui; i++) {
2556 		WMITLV_SET_HDR(&voui[i].tlv_header,
2557 			       WMITLV_TAG_STRUC_wmi_vendor_oui,
2558 			       WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui));
2559 		voui[i].oui_type_subtype = pvoui[i];
2560 	}
2561 }
2562 
2563 /*
2564  * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs
2565  * @ie_bitmap: output pointer to ie bit map in cmd
2566  * @num_vendor_oui: output pointer to num vendor OUIs
2567  * @ie_whitelist: input parameter
2568  *
2569  * This function populates the IE whitelist attrs of scan, pno and
2570  * scan oui commands for ie_whitelist parameter.
2571  *
2572  * Return: None
2573  */
2574 static inline
2575 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap,
2576 				 uint32_t *num_vendor_oui,
2577 				 struct probe_req_whitelist_attr *ie_whitelist)
2578 {
2579 	uint32_t i = 0;
2580 
2581 	for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++)
2582 		ie_bitmap[i] = ie_whitelist->ie_bitmap[i];
2583 
2584 	*num_vendor_oui = ie_whitelist->num_vendor_oui;
2585 }
2586 
2587 /**
2588  *  send_scan_start_cmd_tlv() - WMI scan start function
2589  *  @param wmi_handle      : handle to WMI.
2590  *  @param param    : pointer to hold scan start cmd parameter
2591  *
2592  *  Return: 0  on success and -ve on failure.
2593  */
2594 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle,
2595 				struct scan_req_params *params)
2596 {
2597 	int32_t ret = 0;
2598 	int32_t i;
2599 	wmi_buf_t wmi_buf;
2600 	wmi_start_scan_cmd_fixed_param *cmd;
2601 	uint8_t *buf_ptr;
2602 	uint32_t *tmp_ptr;
2603 	wmi_ssid *ssid = NULL;
2604 	wmi_mac_addr *bssid;
2605 	int len = sizeof(*cmd);
2606 	uint8_t extraie_len_with_pad = 0;
2607 	uint8_t phymode_roundup = 0;
2608 	struct probe_req_whitelist_attr *ie_whitelist = &params->ie_whitelist;
2609 	wmi_unified_t pdev_wmi_handle;
2610 
2611 	/* Length TLV placeholder for array of uint32_t */
2612 	len += WMI_TLV_HDR_SIZE;
2613 	/* calculate the length of buffer required */
2614 	if (params->chan_list.num_chan)
2615 		len += params->chan_list.num_chan * sizeof(uint32_t);
2616 
2617 	/* Length TLV placeholder for array of wmi_ssid structures */
2618 	len += WMI_TLV_HDR_SIZE;
2619 	if (params->num_ssids)
2620 		len += params->num_ssids * sizeof(wmi_ssid);
2621 
2622 	/* Length TLV placeholder for array of wmi_mac_addr structures */
2623 	len += WMI_TLV_HDR_SIZE;
2624 	if (params->num_bssid)
2625 		len += sizeof(wmi_mac_addr) * params->num_bssid;
2626 
2627 	/* Length TLV placeholder for array of bytes */
2628 	len += WMI_TLV_HDR_SIZE;
2629 	if (params->extraie.len)
2630 		extraie_len_with_pad =
2631 		roundup(params->extraie.len, sizeof(uint32_t));
2632 	len += extraie_len_with_pad;
2633 
2634 	len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */
2635 	if (ie_whitelist->num_vendor_oui)
2636 		len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui);
2637 
2638 	len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */
2639 	if (params->scan_f_wide_band)
2640 		phymode_roundup =
2641 			qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t),
2642 					sizeof(uint32_t));
2643 	len += phymode_roundup;
2644 
2645 	/* Allocate the memory */
2646 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
2647 	if (!wmi_buf) {
2648 		WMI_LOGP("%s: failed to allocate memory for start scan cmd",
2649 			 __func__);
2650 		return QDF_STATUS_E_FAILURE;
2651 	}
2652 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
2653 	cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr;
2654 	WMITLV_SET_HDR(&cmd->tlv_header,
2655 		       WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
2656 		       WMITLV_GET_STRUCT_TLVLEN
2657 			       (wmi_start_scan_cmd_fixed_param));
2658 
2659 	cmd->scan_id = params->scan_id;
2660 	cmd->scan_req_id = params->scan_req_id;
2661 	cmd->vdev_id = params->vdev_id;
2662 	cmd->scan_priority = params->scan_priority;
2663 
2664 	copy_scan_event_cntrl_flags(cmd, params);
2665 
2666 	cmd->dwell_time_active = params->dwell_time_active;
2667 	cmd->dwell_time_passive = params->dwell_time_passive;
2668 	cmd->min_rest_time = params->min_rest_time;
2669 	cmd->max_rest_time = params->max_rest_time;
2670 	cmd->repeat_probe_time = params->repeat_probe_time;
2671 	cmd->probe_spacing_time = params->probe_spacing_time;
2672 	cmd->idle_time = params->idle_time;
2673 	cmd->max_scan_time = params->max_scan_time;
2674 	cmd->probe_delay = params->probe_delay;
2675 	cmd->burst_duration = params->burst_duration;
2676 	cmd->num_chan = params->chan_list.num_chan;
2677 	cmd->num_bssid = params->num_bssid;
2678 	cmd->num_ssids = params->num_ssids;
2679 	cmd->ie_len = params->extraie.len;
2680 	cmd->n_probes = params->n_probes;
2681 	cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext;
2682 
2683 	WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext);
2684 
2685 	if (params->scan_random.randomize)
2686 		wmi_copy_scan_random_mac(params->scan_random.mac_addr,
2687 					 params->scan_random.mac_mask,
2688 					 &cmd->mac_addr,
2689 					 &cmd->mac_mask);
2690 
2691 	if (ie_whitelist->white_list)
2692 		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
2693 					    &cmd->num_vendor_oui,
2694 					    ie_whitelist);
2695 
2696 	buf_ptr += sizeof(*cmd);
2697 	tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
2698 	for (i = 0; i < params->chan_list.num_chan; ++i)
2699 		tmp_ptr[i] = params->chan_list.chan[i].freq;
2700 
2701 	WMITLV_SET_HDR(buf_ptr,
2702 		       WMITLV_TAG_ARRAY_UINT32,
2703 		       (params->chan_list.num_chan * sizeof(uint32_t)));
2704 	buf_ptr += WMI_TLV_HDR_SIZE +
2705 			(params->chan_list.num_chan * sizeof(uint32_t));
2706 
2707 	if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) {
2708 		WMI_LOGE("Invalid value for numSsid");
2709 		goto error;
2710 	}
2711 
2712 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
2713 	       (params->num_ssids * sizeof(wmi_ssid)));
2714 
2715 	if (params->num_ssids) {
2716 		ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE);
2717 		for (i = 0; i < params->num_ssids; ++i) {
2718 			ssid->ssid_len = params->ssid[i].length;
2719 			qdf_mem_copy(ssid->ssid, params->ssid[i].ssid,
2720 				     params->ssid[i].length);
2721 			ssid++;
2722 		}
2723 	}
2724 	buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid));
2725 
2726 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
2727 		       (params->num_bssid * sizeof(wmi_mac_addr)));
2728 	bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE);
2729 
2730 	if (params->num_bssid) {
2731 		for (i = 0; i < params->num_bssid; ++i) {
2732 			WMI_CHAR_ARRAY_TO_MAC_ADDR(
2733 				&params->bssid_list[i].bytes[0], bssid);
2734 			bssid++;
2735 		}
2736 	}
2737 
2738 	buf_ptr += WMI_TLV_HDR_SIZE +
2739 		(params->num_bssid * sizeof(wmi_mac_addr));
2740 
2741 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad);
2742 	if (params->extraie.len)
2743 		scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE,
2744 			     params);
2745 
2746 	buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad;
2747 
2748 	/* probe req ie whitelisting */
2749 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2750 		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
2751 
2752 	buf_ptr += WMI_TLV_HDR_SIZE;
2753 
2754 	if (cmd->num_vendor_oui) {
2755 		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
2756 				    ie_whitelist->voui);
2757 		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
2758 	}
2759 
2760 	/* Add phy mode TLV if it's a wide band scan */
2761 	if (params->scan_f_wide_band) {
2762 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup);
2763 		buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
2764 		for (i = 0; i < params->chan_list.num_chan; ++i)
2765 			buf_ptr[i] =
2766 				WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode);
2767 		buf_ptr += phymode_roundup;
2768 	} else {
2769 		/* Add ZERO legth phy mode TLV */
2770 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0);
2771 	}
2772 
2773 	pdev_wmi_handle = get_pdev_wmi_handle(wmi_handle, cmd->vdev_id);
2774 	if (pdev_wmi_handle == NULL) {
2775 		WMI_LOGE("%s: Invalid PDEV WMI handle", __func__);
2776 		goto error;
2777 	}
2778 
2779 	ret = wmi_unified_cmd_send(pdev_wmi_handle, wmi_buf,
2780 				   len, WMI_START_SCAN_CMDID);
2781 	if (ret) {
2782 		WMI_LOGE("%s: Failed to start scan: %d", __func__, ret);
2783 		wmi_buf_free(wmi_buf);
2784 	}
2785 	return ret;
2786 error:
2787 	wmi_buf_free(wmi_buf);
2788 	return QDF_STATUS_E_FAILURE;
2789 }
2790 
2791 /**
2792  *  send_scan_stop_cmd_tlv() - WMI scan start function
2793  *  @param wmi_handle      : handle to WMI.
2794  *  @param param    : pointer to hold scan cancel cmd parameter
2795  *
2796  *  Return: 0  on success and -ve on failure.
2797  */
2798 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle,
2799 				struct scan_cancel_param *param)
2800 {
2801 	wmi_stop_scan_cmd_fixed_param *cmd;
2802 	int ret;
2803 	int len = sizeof(*cmd);
2804 	wmi_buf_t wmi_buf;
2805 	wmi_unified_t pdev_wmi_handle;
2806 
2807 	/* Allocate the memory */
2808 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
2809 	if (!wmi_buf) {
2810 		WMI_LOGP("%s: failed to allocate memory for stop scan cmd",
2811 			 __func__);
2812 		ret = QDF_STATUS_E_NOMEM;
2813 		goto error;
2814 	}
2815 
2816 	cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf);
2817 	WMITLV_SET_HDR(&cmd->tlv_header,
2818 		       WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param,
2819 		       WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param));
2820 	cmd->vdev_id = param->vdev_id;
2821 	cmd->requestor = param->requester;
2822 	cmd->scan_id = param->scan_id;
2823 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
2824 								param->pdev_id);
2825 	/* stop the scan with the corresponding scan_id */
2826 	if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) {
2827 		/* Cancelling all scans */
2828 		cmd->req_type = WMI_SCAN_STOP_ALL;
2829 	} else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) {
2830 		/* Cancelling VAP scans */
2831 		cmd->req_type = WMI_SCN_STOP_VAP_ALL;
2832 	} else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) {
2833 		/* Cancelling specific scan */
2834 		cmd->req_type = WMI_SCAN_STOP_ONE;
2835 	} else {
2836 		WMI_LOGE("%s: Invalid Command : ", __func__);
2837 		wmi_buf_free(wmi_buf);
2838 		return QDF_STATUS_E_INVAL;
2839 	}
2840 
2841 	pdev_wmi_handle = get_pdev_wmi_handle(wmi_handle, cmd->vdev_id);
2842 	if (pdev_wmi_handle == NULL) {
2843 		WMI_LOGE("%s: Invalid PDEV WMI handle", __func__);
2844 		wmi_buf_free(wmi_buf);
2845 		return QDF_STATUS_E_NULL_VALUE;
2846 	}
2847 
2848 	ret = wmi_unified_cmd_send(pdev_wmi_handle, wmi_buf,
2849 				   len, WMI_STOP_SCAN_CMDID);
2850 	if (ret) {
2851 		WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret);
2852 		wmi_buf_free(wmi_buf);
2853 	}
2854 
2855 error:
2856 	return ret;
2857 }
2858 
2859 #ifdef CONFIG_MCL
2860 /**
2861  *  send_scan_chan_list_cmd_tlv() - WMI scan channel list function
2862  *  @param wmi_handle      : handle to WMI.
2863  *  @param param    : pointer to hold scan channel list parameter
2864  *
2865  *  Return: 0  on success and -ve on failure.
2866  */
2867 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
2868 				struct scan_chan_list_params *chan_list)
2869 {
2870 	wmi_buf_t buf;
2871 	QDF_STATUS qdf_status;
2872 	wmi_scan_chan_list_cmd_fixed_param *cmd;
2873 	int i;
2874 	uint8_t *buf_ptr;
2875 	wmi_channel_param *chan_info, *tchan_info;
2876 	uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
2877 
2878 	len += sizeof(wmi_channel) * chan_list->num_scan_chans;
2879 	buf = wmi_buf_alloc(wmi_handle, len);
2880 	if (!buf) {
2881 		WMI_LOGE("Failed to allocate memory");
2882 		qdf_status = QDF_STATUS_E_NOMEM;
2883 		goto end;
2884 	}
2885 
2886 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
2887 	cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr;
2888 	WMITLV_SET_HDR(&cmd->tlv_header,
2889 		       WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param,
2890 		       WMITLV_GET_STRUCT_TLVLEN
2891 			       (wmi_scan_chan_list_cmd_fixed_param));
2892 
2893 	WMI_LOGD("no of channels = %d, len = %d", chan_list->num_scan_chans, len);
2894 
2895 	cmd->num_scan_chans = chan_list->num_scan_chans;
2896 	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)),
2897 		       WMITLV_TAG_ARRAY_STRUC,
2898 		       sizeof(wmi_channel) * chan_list->num_scan_chans);
2899 	chan_info = (wmi_channel_param *)
2900 			(buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE);
2901 	tchan_info = chan_list->chan_info;
2902 
2903 	for (i = 0; i < chan_list->num_scan_chans; ++i) {
2904 		WMITLV_SET_HDR(&chan_info->tlv_header,
2905 			       WMITLV_TAG_STRUC_wmi_channel,
2906 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
2907 		chan_info->mhz = tchan_info->mhz;
2908 		chan_info->band_center_freq1 =
2909 				 tchan_info->band_center_freq1;
2910 		chan_info->band_center_freq2 =
2911 				tchan_info->band_center_freq2;
2912 		chan_info->info = tchan_info->info;
2913 		chan_info->reg_info_1 = tchan_info->reg_info_1;
2914 		chan_info->reg_info_2 = tchan_info->reg_info_2;
2915 		WMI_LOGD("chan[%d] = %u", i, chan_info->mhz);
2916 
2917 		/*TODO: Set WMI_SET_CHANNEL_MIN_POWER */
2918 		/*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */
2919 		/*TODO: WMI_SET_CHANNEL_REG_CLASSID */
2920 		tchan_info++;
2921 		chan_info++;
2922 	}
2923 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
2924 							chan_list->pdev_id);
2925 
2926 	qdf_status = wmi_unified_cmd_send(wmi_handle,
2927 			buf, len, WMI_SCAN_CHAN_LIST_CMDID);
2928 
2929 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
2930 		WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
2931 		wmi_buf_free(buf);
2932 	}
2933 
2934 end:
2935 	return qdf_status;
2936 }
2937 #else
2938 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
2939 				struct scan_chan_list_params *chan_list)
2940 {
2941 	wmi_buf_t buf;
2942 	QDF_STATUS qdf_status;
2943 	wmi_scan_chan_list_cmd_fixed_param *cmd;
2944 	int i;
2945 	uint8_t *buf_ptr;
2946 	wmi_channel *chan_info;
2947 	struct channel_param *tchan_info;
2948 	uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
2949 
2950 	len += sizeof(wmi_channel) * chan_list->nallchans;
2951 	buf = wmi_buf_alloc(wmi_handle, len);
2952 	if (!buf) {
2953 		WMI_LOGE("Failed to allocate memory");
2954 		qdf_status = QDF_STATUS_E_NOMEM;
2955 		goto end;
2956 	}
2957 
2958 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
2959 	cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr;
2960 	WMITLV_SET_HDR(&cmd->tlv_header,
2961 		       WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param,
2962 		       WMITLV_GET_STRUCT_TLVLEN
2963 			       (wmi_scan_chan_list_cmd_fixed_param));
2964 
2965 	WMI_LOGD("no of channels = %d, len = %d", chan_list->nallchans, len);
2966 
2967 	if (chan_list->append)
2968 		cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST;
2969 
2970 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
2971 							chan_list->pdev_id);
2972 	cmd->num_scan_chans = chan_list->nallchans;
2973 	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)),
2974 		       WMITLV_TAG_ARRAY_STRUC,
2975 		       sizeof(wmi_channel) * chan_list->nallchans);
2976 	chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE);
2977 	tchan_info = &(chan_list->ch_param[0]);
2978 
2979 	for (i = 0; i < chan_list->nallchans; ++i) {
2980 		WMITLV_SET_HDR(&chan_info->tlv_header,
2981 			       WMITLV_TAG_STRUC_wmi_channel,
2982 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
2983 		chan_info->mhz = tchan_info->mhz;
2984 		chan_info->band_center_freq1 =
2985 				 tchan_info->cfreq1;
2986 		chan_info->band_center_freq2 =
2987 				tchan_info->cfreq2;
2988 
2989 		if (tchan_info->is_chan_passive)
2990 			WMI_SET_CHANNEL_FLAG(chan_info,
2991 					WMI_CHAN_FLAG_PASSIVE);
2992 
2993 		if (tchan_info->allow_vht)
2994 			WMI_SET_CHANNEL_FLAG(chan_info,
2995 					WMI_CHAN_FLAG_ALLOW_VHT);
2996 		else  if (tchan_info->allow_ht)
2997 			WMI_SET_CHANNEL_FLAG(chan_info,
2998 					WMI_CHAN_FLAG_ALLOW_HT);
2999 		WMI_SET_CHANNEL_MODE(chan_info,
3000 				tchan_info->phy_mode);
3001 
3002 		/* Add tchan_info->half_rate and tchan_info->quarter_rate later
3003 		 * after FW support
3004 		 */
3005 
3006 		/* also fill in power information */
3007 		WMI_SET_CHANNEL_MIN_POWER(chan_info,
3008 				tchan_info->minpower);
3009 		WMI_SET_CHANNEL_MAX_POWER(chan_info,
3010 				tchan_info->maxpower);
3011 		WMI_SET_CHANNEL_REG_POWER(chan_info,
3012 				tchan_info->maxregpower);
3013 		WMI_SET_CHANNEL_ANTENNA_MAX(chan_info,
3014 				tchan_info->antennamax);
3015 		WMI_SET_CHANNEL_REG_CLASSID(chan_info,
3016 				tchan_info->reg_class_id);
3017 		WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
3018 				tchan_info->maxregpower);
3019 
3020 		WMI_LOGD("chan[%d] = %u", i, chan_info->mhz);
3021 
3022 		tchan_info++;
3023 		chan_info++;
3024 	}
3025 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
3026 							chan_list->pdev_id);
3027 
3028 	qdf_status = wmi_unified_cmd_send(
3029 			wmi_handle,
3030 			buf, len, WMI_SCAN_CHAN_LIST_CMDID);
3031 
3032 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
3033 		WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
3034 		wmi_buf_free(buf);
3035 	}
3036 
3037 end:
3038 	return qdf_status;
3039 }
3040 #endif
3041 
3042 /**
3043  * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx
3044  *
3045  * @bufp: Pointer to buffer
3046  * @param: Pointer to tx param
3047  *
3048  * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure
3049  */
3050 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp,
3051 					 struct tx_send_params param)
3052 {
3053 	wmi_tx_send_params *tx_param;
3054 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3055 
3056 	if (!bufp) {
3057 		status = QDF_STATUS_E_FAILURE;
3058 		return status;
3059 	}
3060 	tx_param = (wmi_tx_send_params *)bufp;
3061 	WMITLV_SET_HDR(&tx_param->tlv_header,
3062 		       WMITLV_TAG_STRUC_wmi_tx_send_params,
3063 		       WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params));
3064 	WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr);
3065 	WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0,
3066 				       param.mcs_mask);
3067 	WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0,
3068 				       param.nss_mask);
3069 	WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0,
3070 					  param.retry_limit);
3071 	WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1,
3072 					 param.chain_mask);
3073 	WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1,
3074 				      param.bw_mask);
3075 	WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1,
3076 				       param.preamble_type);
3077 	WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1,
3078 					 param.frame_type);
3079 
3080 	return status;
3081 }
3082 
3083 /**
3084  *  send_mgmt_cmd_tlv() - WMI scan start function
3085  *  @wmi_handle      : handle to WMI.
3086  *  @param    : pointer to hold mgmt cmd parameter
3087  *
3088  *  Return: 0  on success and -ve on failure.
3089  */
3090 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
3091 				struct wmi_mgmt_params *param)
3092 {
3093 	wmi_buf_t buf;
3094 	wmi_mgmt_tx_send_cmd_fixed_param *cmd;
3095 	int32_t cmd_len;
3096 	uint64_t dma_addr;
3097 	void *qdf_ctx = param->qdf_ctx;
3098 	uint8_t *bufp;
3099 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3100 	int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len :
3101 		mgmt_tx_dl_frm_len;
3102 
3103 	cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) +
3104 		  WMI_TLV_HDR_SIZE +
3105 		  roundup(bufp_len, sizeof(uint32_t));
3106 
3107 	buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len);
3108 	if (!buf) {
3109 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3110 		return QDF_STATUS_E_NOMEM;
3111 	}
3112 
3113 	cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf);
3114 	bufp = (uint8_t *) cmd;
3115 	WMITLV_SET_HDR(&cmd->tlv_header,
3116 		WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param,
3117 		WMITLV_GET_STRUCT_TLVLEN
3118 		(wmi_mgmt_tx_send_cmd_fixed_param));
3119 
3120 	cmd->vdev_id = param->vdev_id;
3121 
3122 	cmd->desc_id = param->desc_id;
3123 	cmd->chanfreq = param->chanfreq;
3124 	bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param);
3125 	WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
3126 							    sizeof(uint32_t)));
3127 	bufp += WMI_TLV_HDR_SIZE;
3128 	qdf_mem_copy(bufp, param->pdata, bufp_len);
3129 
3130 	status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame,
3131 				     QDF_DMA_TO_DEVICE);
3132 	if (status != QDF_STATUS_SUCCESS) {
3133 		WMI_LOGE("%s: wmi buf map failed", __func__);
3134 		goto free_buf;
3135 	}
3136 
3137 	dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0);
3138 	cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff);
3139 #if defined(HTT_PADDR64)
3140 	cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F);
3141 #endif
3142 	cmd->frame_len = param->frm_len;
3143 	cmd->buf_len = bufp_len;
3144 	cmd->tx_params_valid = param->tx_params_valid;
3145 
3146 	wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID,
3147 			bufp, cmd->vdev_id, cmd->chanfreq);
3148 
3149 	bufp += roundup(bufp_len, sizeof(uint32_t));
3150 	if (param->tx_params_valid) {
3151 		status = populate_tx_send_params(bufp, param->tx_param);
3152 		if (status != QDF_STATUS_SUCCESS) {
3153 			WMI_LOGE("%s: Populate TX send params failed",
3154 				 __func__);
3155 			goto unmap_tx_frame;
3156 		}
3157 		cmd_len += sizeof(wmi_tx_send_params);
3158 	}
3159 
3160 	if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
3161 				      WMI_MGMT_TX_SEND_CMDID)) {
3162 		WMI_LOGE("%s: Failed to send mgmt Tx", __func__);
3163 		goto unmap_tx_frame;
3164 	}
3165 	return QDF_STATUS_SUCCESS;
3166 
3167 unmap_tx_frame:
3168 	qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame,
3169 				     QDF_DMA_TO_DEVICE);
3170 free_buf:
3171 	wmi_buf_free(buf);
3172 	return QDF_STATUS_E_FAILURE;
3173 }
3174 
3175 /**
3176  *  send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data
3177  *  @wmi_handle      : handle to WMI.
3178  *  @param    : pointer to offchan data tx cmd parameter
3179  *
3180  *  Return: QDF_STATUS_SUCCESS  on success and error on failure.
3181  */
3182 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle,
3183 				struct wmi_offchan_data_tx_params *param)
3184 {
3185 	wmi_buf_t buf;
3186 	wmi_offchan_data_tx_send_cmd_fixed_param *cmd;
3187 	int32_t cmd_len;
3188 	uint64_t dma_addr;
3189 	void *qdf_ctx = param->qdf_ctx;
3190 	uint8_t *bufp;
3191 	int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ?
3192 					param->frm_len : mgmt_tx_dl_frm_len;
3193 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3194 
3195 	cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) +
3196 		  WMI_TLV_HDR_SIZE +
3197 		  roundup(bufp_len, sizeof(uint32_t));
3198 
3199 	buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len);
3200 	if (!buf) {
3201 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3202 		return QDF_STATUS_E_NOMEM;
3203 	}
3204 
3205 	cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf);
3206 	bufp = (uint8_t *) cmd;
3207 	WMITLV_SET_HDR(&cmd->tlv_header,
3208 		WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param,
3209 		WMITLV_GET_STRUCT_TLVLEN
3210 		(wmi_offchan_data_tx_send_cmd_fixed_param));
3211 
3212 	cmd->vdev_id = param->vdev_id;
3213 
3214 	cmd->desc_id = param->desc_id;
3215 	cmd->chanfreq = param->chanfreq;
3216 	bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param);
3217 	WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
3218 							    sizeof(uint32_t)));
3219 	bufp += WMI_TLV_HDR_SIZE;
3220 	qdf_mem_copy(bufp, param->pdata, bufp_len);
3221 	qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE);
3222 	dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0);
3223 	cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff);
3224 #if defined(HTT_PADDR64)
3225 	cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F);
3226 #endif
3227 	cmd->frame_len = param->frm_len;
3228 	cmd->buf_len = bufp_len;
3229 	cmd->tx_params_valid = param->tx_params_valid;
3230 
3231 	wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID,
3232 			bufp, cmd->vdev_id, cmd->chanfreq);
3233 
3234 	bufp += roundup(bufp_len, sizeof(uint32_t));
3235 	if (param->tx_params_valid) {
3236 		status = populate_tx_send_params(bufp, param->tx_param);
3237 		if (status != QDF_STATUS_SUCCESS) {
3238 			WMI_LOGE("%s: Populate TX send params failed",
3239 				 __func__);
3240 			goto err1;
3241 		}
3242 		cmd_len += sizeof(wmi_tx_send_params);
3243 	}
3244 
3245 	if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
3246 				WMI_OFFCHAN_DATA_TX_SEND_CMDID)) {
3247 		WMI_LOGE("%s: Failed to offchan data Tx", __func__);
3248 		goto err1;
3249 	}
3250 
3251 	return QDF_STATUS_SUCCESS;
3252 
3253 err1:
3254 	wmi_buf_free(buf);
3255 	return QDF_STATUS_E_FAILURE;
3256 }
3257 
3258 /**
3259  * send_modem_power_state_cmd_tlv() - set modem power state to fw
3260  * @wmi_handle: wmi handle
3261  * @param_value: parameter value
3262  *
3263  * Return: QDF_STATUS_SUCCESS for success or error code
3264  */
3265 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle,
3266 		uint32_t param_value)
3267 {
3268 	QDF_STATUS ret;
3269 	wmi_modem_power_state_cmd_param *cmd;
3270 	wmi_buf_t buf;
3271 	uint16_t len = sizeof(*cmd);
3272 
3273 	buf = wmi_buf_alloc(wmi_handle, len);
3274 	if (!buf) {
3275 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3276 		return QDF_STATUS_E_NOMEM;
3277 	}
3278 	cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf);
3279 	WMITLV_SET_HDR(&cmd->tlv_header,
3280 		       WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param,
3281 		       WMITLV_GET_STRUCT_TLVLEN
3282 			       (wmi_modem_power_state_cmd_param));
3283 	cmd->modem_power_state = param_value;
3284 	WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__,
3285 		 param_value);
3286 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3287 				     WMI_MODEM_POWER_STATE_CMDID);
3288 	if (QDF_IS_STATUS_ERROR(ret)) {
3289 		WMI_LOGE("Failed to send notify cmd ret = %d", ret);
3290 		wmi_buf_free(buf);
3291 	}
3292 
3293 	return ret;
3294 }
3295 
3296 /**
3297  * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw
3298  * @wmi_handle: wmi handle
3299  * @vdev_id: vdev id
3300  * @val: value
3301  *
3302  * Return: QDF_STATUS_SUCCESS for success or error code.
3303  */
3304 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle,
3305 			       uint32_t vdev_id, uint8_t val)
3306 {
3307 	wmi_sta_powersave_mode_cmd_fixed_param *cmd;
3308 	wmi_buf_t buf;
3309 	int32_t len = sizeof(*cmd);
3310 
3311 	WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val);
3312 
3313 	buf = wmi_buf_alloc(wmi_handle, len);
3314 	if (!buf) {
3315 		WMI_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__);
3316 		return QDF_STATUS_E_NOMEM;
3317 	}
3318 	cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf);
3319 	WMITLV_SET_HDR(&cmd->tlv_header,
3320 		       WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param,
3321 		       WMITLV_GET_STRUCT_TLVLEN
3322 			       (wmi_sta_powersave_mode_cmd_fixed_param));
3323 	cmd->vdev_id = vdev_id;
3324 	if (val)
3325 		cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED;
3326 	else
3327 		cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED;
3328 
3329 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
3330 				 WMI_STA_POWERSAVE_MODE_CMDID)) {
3331 		WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d",
3332 			 vdev_id, val);
3333 		wmi_buf_free(buf);
3334 		return QDF_STATUS_E_FAILURE;
3335 	}
3336 	return 0;
3337 }
3338 
3339 /**
3340  * send_set_mimops_cmd_tlv() - set MIMO powersave
3341  * @wmi_handle: wmi handle
3342  * @vdev_id: vdev id
3343  * @value: value
3344  *
3345  * Return: QDF_STATUS_SUCCESS for success or error code.
3346  */
3347 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle,
3348 			uint8_t vdev_id, int value)
3349 {
3350 	QDF_STATUS ret;
3351 	wmi_sta_smps_force_mode_cmd_fixed_param *cmd;
3352 	wmi_buf_t buf;
3353 	uint16_t len = sizeof(*cmd);
3354 
3355 	buf = wmi_buf_alloc(wmi_handle, len);
3356 	if (!buf) {
3357 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3358 		return QDF_STATUS_E_NOMEM;
3359 	}
3360 	cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf);
3361 	WMITLV_SET_HDR(&cmd->tlv_header,
3362 		       WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param,
3363 		       WMITLV_GET_STRUCT_TLVLEN
3364 			       (wmi_sta_smps_force_mode_cmd_fixed_param));
3365 
3366 	cmd->vdev_id = vdev_id;
3367 
3368 	/* WMI_SMPS_FORCED_MODE values do not directly map
3369 	 * to SM power save values defined in the specification.
3370 	 * Make sure to send the right mapping.
3371 	 */
3372 	switch (value) {
3373 	case 0:
3374 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE;
3375 		break;
3376 	case 1:
3377 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED;
3378 		break;
3379 	case 2:
3380 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC;
3381 		break;
3382 	case 3:
3383 		cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC;
3384 		break;
3385 	default:
3386 		WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__);
3387 		return QDF_STATUS_E_FAILURE;
3388 	}
3389 
3390 	WMI_LOGD("Setting vdev %d value = %u", vdev_id, value);
3391 
3392 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3393 				   WMI_STA_SMPS_FORCE_MODE_CMDID);
3394 	if (QDF_IS_STATUS_ERROR(ret)) {
3395 		WMI_LOGE("Failed to send set Mimo PS ret = %d", ret);
3396 		wmi_buf_free(buf);
3397 	}
3398 
3399 	return ret;
3400 }
3401 
3402 /**
3403  * send_set_smps_params_cmd_tlv() - set smps params
3404  * @wmi_handle: wmi handle
3405  * @vdev_id: vdev id
3406  * @value: value
3407  *
3408  * Return: QDF_STATUS_SUCCESS for success or error code.
3409  */
3410 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
3411 			       int value)
3412 {
3413 	QDF_STATUS ret;
3414 	wmi_sta_smps_param_cmd_fixed_param *cmd;
3415 	wmi_buf_t buf;
3416 	uint16_t len = sizeof(*cmd);
3417 
3418 	buf = wmi_buf_alloc(wmi_handle, len);
3419 	if (!buf) {
3420 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3421 		return QDF_STATUS_E_NOMEM;
3422 	}
3423 	cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf);
3424 	WMITLV_SET_HDR(&cmd->tlv_header,
3425 		       WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param,
3426 		       WMITLV_GET_STRUCT_TLVLEN
3427 			       (wmi_sta_smps_param_cmd_fixed_param));
3428 
3429 	cmd->vdev_id = vdev_id;
3430 	cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS;
3431 	cmd->param =
3432 		(value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS;
3433 
3434 	WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value,
3435 		 cmd->param);
3436 
3437 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3438 				   WMI_STA_SMPS_PARAM_CMDID);
3439 	if (QDF_IS_STATUS_ERROR(ret)) {
3440 		WMI_LOGE("Failed to send set Mimo PS ret = %d", ret);
3441 		wmi_buf_free(buf);
3442 	}
3443 
3444 	return ret;
3445 }
3446 
3447 /**
3448  * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw
3449  * @wmi_handle: wmi handle
3450  * @noa: p2p power save parameters
3451  *
3452  * Return: CDF status
3453  */
3454 static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle,
3455 			struct p2p_ps_params *noa)
3456 {
3457 	wmi_p2p_set_noa_cmd_fixed_param *cmd;
3458 	wmi_p2p_noa_descriptor *noa_discriptor;
3459 	wmi_buf_t buf;
3460 	uint8_t *buf_ptr;
3461 	uint16_t len;
3462 	QDF_STATUS status;
3463 	uint32_t duration;
3464 
3465 	WMI_LOGD("%s: Enter", __func__);
3466 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor);
3467 	buf = wmi_buf_alloc(wmi_handle, len);
3468 	if (!buf) {
3469 		WMI_LOGE("Failed to allocate memory");
3470 		status = QDF_STATUS_E_FAILURE;
3471 		goto end;
3472 	}
3473 
3474 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3475 	cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr;
3476 	WMITLV_SET_HDR(&cmd->tlv_header,
3477 		       WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param,
3478 		       WMITLV_GET_STRUCT_TLVLEN
3479 			       (wmi_p2p_set_noa_cmd_fixed_param));
3480 	duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration;
3481 	cmd->vdev_id = noa->session_id;
3482 	cmd->enable = (duration) ? true : false;
3483 	cmd->num_noa = 1;
3484 
3485 	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)),
3486 		       WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor));
3487 	noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr +
3488 						     sizeof
3489 						     (wmi_p2p_set_noa_cmd_fixed_param)
3490 						     + WMI_TLV_HDR_SIZE);
3491 	WMITLV_SET_HDR(&noa_discriptor->tlv_header,
3492 		       WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor,
3493 		       WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor));
3494 	noa_discriptor->type_count = noa->count;
3495 	noa_discriptor->duration = duration;
3496 	noa_discriptor->interval = noa->interval;
3497 	noa_discriptor->start_time = 0;
3498 
3499 	WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d",
3500 		 cmd->vdev_id, noa->count, noa_discriptor->duration,
3501 		 noa->interval);
3502 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
3503 				      WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID);
3504 	if (QDF_IS_STATUS_ERROR(status)) {
3505 		WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID");
3506 		wmi_buf_free(buf);
3507 	}
3508 
3509 end:
3510 	WMI_LOGD("%s: Exit", __func__);
3511 	return status;
3512 }
3513 
3514 
3515 /**
3516  * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw
3517  * @wmi_handle: wmi handle
3518  * @noa: p2p opp power save parameters
3519  *
3520  * Return: CDF status
3521  */
3522 static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle,
3523 		struct p2p_ps_params *oppps)
3524 {
3525 	wmi_p2p_set_oppps_cmd_fixed_param *cmd;
3526 	wmi_buf_t buf;
3527 	QDF_STATUS status;
3528 
3529 	WMI_LOGD("%s: Enter", __func__);
3530 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
3531 	if (!buf) {
3532 		WMI_LOGE("Failed to allocate memory");
3533 		status = QDF_STATUS_E_FAILURE;
3534 		goto end;
3535 	}
3536 
3537 	cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf);
3538 	WMITLV_SET_HDR(&cmd->tlv_header,
3539 		       WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param,
3540 		       WMITLV_GET_STRUCT_TLVLEN
3541 			       (wmi_p2p_set_oppps_cmd_fixed_param));
3542 	cmd->vdev_id = oppps->session_id;
3543 	if (oppps->ctwindow)
3544 		WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd);
3545 
3546 	WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow);
3547 	WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d",
3548 		 cmd->vdev_id, oppps->ctwindow);
3549 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
3550 				      WMI_P2P_SET_OPPPS_PARAM_CMDID);
3551 	if (QDF_IS_STATUS_ERROR(status)) {
3552 		WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID");
3553 		wmi_buf_free(buf);
3554 	}
3555 
3556 end:
3557 	WMI_LOGD("%s: Exit", __func__);
3558 	return status;
3559 }
3560 
3561 #ifdef CONVERGED_P2P_ENABLE
3562 /**
3563  * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw
3564  * @wmi_handle: wmi handle
3565  * @param: p2p listen offload start parameters
3566  *
3567  * Return: QDF status
3568  */
3569 static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle,
3570 	struct p2p_lo_start *param)
3571 {
3572 	wmi_buf_t buf;
3573 	wmi_p2p_lo_start_cmd_fixed_param *cmd;
3574 	int32_t len = sizeof(*cmd);
3575 	uint8_t *buf_ptr;
3576 	QDF_STATUS status;
3577 	int device_types_len_aligned;
3578 	int probe_resp_len_aligned;
3579 
3580 	if (!param) {
3581 		WMI_LOGE("lo start param is null");
3582 		return QDF_STATUS_E_INVAL;
3583 	}
3584 
3585 	WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id);
3586 
3587 	device_types_len_aligned =
3588 		qdf_roundup(param->dev_types_len,
3589 			sizeof(A_UINT32));
3590 	probe_resp_len_aligned =
3591 		qdf_roundup(param->probe_resp_len,
3592 			sizeof(A_UINT32));
3593 
3594 	len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned +
3595 			probe_resp_len_aligned;
3596 
3597 	buf = wmi_buf_alloc(wmi_handle, len);
3598 	if (!buf) {
3599 		WMI_LOGE("%s: Failed to allocate memory for p2p lo start",
3600 			__func__);
3601 		return QDF_STATUS_E_NOMEM;
3602 	}
3603 
3604 	cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf);
3605 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3606 
3607 	WMITLV_SET_HDR(&cmd->tlv_header,
3608 		 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param,
3609 		 WMITLV_GET_STRUCT_TLVLEN(
3610 			wmi_p2p_lo_start_cmd_fixed_param));
3611 
3612 	cmd->vdev_id = param->vdev_id;
3613 	cmd->ctl_flags = param->ctl_flags;
3614 	cmd->channel = param->freq;
3615 	cmd->period = param->period;
3616 	cmd->interval = param->interval;
3617 	cmd->count = param->count;
3618 	cmd->device_types_len = param->dev_types_len;
3619 	cmd->prob_resp_len = param->probe_resp_len;
3620 
3621 	buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param);
3622 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
3623 				device_types_len_aligned);
3624 	buf_ptr += WMI_TLV_HDR_SIZE;
3625 	qdf_mem_copy(buf_ptr, param->device_types,
3626 			param->dev_types_len);
3627 
3628 	buf_ptr += device_types_len_aligned;
3629 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
3630 			probe_resp_len_aligned);
3631 	buf_ptr += WMI_TLV_HDR_SIZE;
3632 	qdf_mem_copy(buf_ptr, param->probe_resp_tmplt,
3633 			param->probe_resp_len);
3634 
3635 	WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__,
3636 	cmd->channel, cmd->period, cmd->interval, cmd->count);
3637 
3638 	status = wmi_unified_cmd_send(wmi_handle,
3639 				buf, len,
3640 				WMI_P2P_LISTEN_OFFLOAD_START_CMDID);
3641 	if (status != QDF_STATUS_SUCCESS) {
3642 		WMI_LOGE("%s: Failed to send p2p lo start: %d",
3643 			__func__, status);
3644 		wmi_buf_free(buf);
3645 		return status;
3646 	}
3647 
3648 	WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__);
3649 
3650 	return QDF_STATUS_SUCCESS;
3651 }
3652 
3653 /**
3654  * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw
3655  * @wmi_handle: wmi handle
3656  * @param: p2p listen offload stop parameters
3657  *
3658  * Return: QDF status
3659  */
3660 static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle,
3661 	uint8_t vdev_id)
3662 {
3663 	wmi_buf_t buf;
3664 	wmi_p2p_lo_stop_cmd_fixed_param *cmd;
3665 	int32_t len;
3666 	QDF_STATUS status;
3667 
3668 	WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id);
3669 
3670 	len = sizeof(*cmd);
3671 	buf = wmi_buf_alloc(wmi_handle, len);
3672 	if (!buf) {
3673 		qdf_print("%s: Failed to allocate memory for p2p lo stop",
3674 			__func__);
3675 		return QDF_STATUS_E_NOMEM;
3676 	}
3677 	cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf);
3678 
3679 	WMITLV_SET_HDR(&cmd->tlv_header,
3680 		WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param,
3681 		WMITLV_GET_STRUCT_TLVLEN(
3682 			wmi_p2p_lo_stop_cmd_fixed_param));
3683 
3684 	cmd->vdev_id = vdev_id;
3685 
3686 	WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__);
3687 
3688 	status = wmi_unified_cmd_send(wmi_handle,
3689 				buf, len,
3690 				WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID);
3691 	if (status != QDF_STATUS_SUCCESS) {
3692 		WMI_LOGE("%s: Failed to send p2p lo stop: %d",
3693 			__func__, status);
3694 		wmi_buf_free(buf);
3695 		return status;
3696 	}
3697 
3698 	WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__);
3699 
3700 	return QDF_STATUS_SUCCESS;
3701 }
3702 #endif /* End of CONVERGED_P2P_ENABLE */
3703 
3704 /**
3705  * send_get_temperature_cmd_tlv() - get pdev temperature req
3706  * @wmi_handle: wmi handle
3707  *
3708  * Return: QDF_STATUS_SUCCESS for success or error code.
3709  */
3710 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle)
3711 {
3712 	wmi_pdev_get_temperature_cmd_fixed_param *cmd;
3713 	wmi_buf_t wmi_buf;
3714 	uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param);
3715 	uint8_t *buf_ptr;
3716 
3717 	if (!wmi_handle) {
3718 		WMI_LOGE(FL("WMI is closed, can not issue cmd"));
3719 		return QDF_STATUS_E_INVAL;
3720 	}
3721 
3722 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
3723 	if (!wmi_buf) {
3724 		WMI_LOGE(FL("wmi_buf_alloc failed"));
3725 		return QDF_STATUS_E_NOMEM;
3726 	}
3727 
3728 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
3729 
3730 	cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr;
3731 	WMITLV_SET_HDR(&cmd->tlv_header,
3732 		       WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param,
3733 		       WMITLV_GET_STRUCT_TLVLEN
3734 			       (wmi_pdev_get_temperature_cmd_fixed_param));
3735 
3736 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
3737 				 WMI_PDEV_GET_TEMPERATURE_CMDID)) {
3738 		WMI_LOGE(FL("failed to send get temperature command"));
3739 		wmi_buf_free(wmi_buf);
3740 		return QDF_STATUS_E_FAILURE;
3741 	}
3742 
3743 	return QDF_STATUS_SUCCESS;
3744 }
3745 
3746 /**
3747  * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command
3748  * @wmi_handle: wmi handle
3749  * @vdevid: vdev id
3750  * @peer_addr: peer mac address
3751  * @auto_triggerparam: auto trigger parameters
3752  * @num_ac: number of access category
3753  *
3754  * This function sets the trigger
3755  * uapsd params such as service interval, delay interval
3756  * and suspend interval which will be used by the firmware
3757  * to send trigger frames periodically when there is no
3758  * traffic on the transmit side.
3759  *
3760  * Return: QDF_STATUS_SUCCESS for success or error code.
3761  */
3762 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle,
3763 				struct sta_uapsd_trig_params *param)
3764 {
3765 	wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd;
3766 	QDF_STATUS ret;
3767 	uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param);
3768 	uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE;
3769 	uint32_t i;
3770 	wmi_buf_t buf;
3771 	uint8_t *buf_ptr;
3772 	struct sta_uapsd_params *uapsd_param;
3773 	wmi_sta_uapsd_auto_trig_param *trig_param;
3774 
3775 	buf = wmi_buf_alloc(wmi_handle, cmd_len);
3776 	if (!buf) {
3777 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
3778 		return QDF_STATUS_E_NOMEM;
3779 	}
3780 
3781 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
3782 	cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr;
3783 	WMITLV_SET_HDR(&cmd->tlv_header,
3784 		       WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param,
3785 		       WMITLV_GET_STRUCT_TLVLEN
3786 			       (wmi_sta_uapsd_auto_trig_cmd_fixed_param));
3787 	cmd->vdev_id = param->vdevid;
3788 	cmd->num_ac = param->num_ac;
3789 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
3790 
3791 	/* TLV indicating array of structures to follow */
3792 	buf_ptr += sizeof(*cmd);
3793 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len);
3794 
3795 	buf_ptr += WMI_TLV_HDR_SIZE;
3796 
3797 	/*
3798 	 * Update tag and length for uapsd auto trigger params (this will take
3799 	 * care of updating tag and length if it is not pre-filled by caller).
3800 	 */
3801 	uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam;
3802 	trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr;
3803 	for (i = 0; i < param->num_ac; i++) {
3804 		WMITLV_SET_HDR((buf_ptr +
3805 				(i * sizeof(wmi_sta_uapsd_auto_trig_param))),
3806 			       WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param,
3807 			       WMITLV_GET_STRUCT_TLVLEN
3808 				       (wmi_sta_uapsd_auto_trig_param));
3809 		trig_param->wmm_ac = uapsd_param->wmm_ac;
3810 		trig_param->user_priority = uapsd_param->user_priority;
3811 		trig_param->service_interval = uapsd_param->service_interval;
3812 		trig_param->suspend_interval = uapsd_param->suspend_interval;
3813 		trig_param->delay_interval = uapsd_param->delay_interval;
3814 		trig_param++;
3815 		uapsd_param++;
3816 	}
3817 
3818 	ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
3819 				   WMI_STA_UAPSD_AUTO_TRIG_CMDID);
3820 	if (QDF_IS_STATUS_ERROR(ret)) {
3821 		WMI_LOGE("Failed to send set uapsd param ret = %d", ret);
3822 		wmi_buf_free(buf);
3823 	}
3824 
3825 	return ret;
3826 }
3827 
3828 #ifdef WLAN_FEATURE_DSRC
3829 /**
3830  * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware
3831  * @wmi_handle: pointer to the wmi handle
3832  * @utc: pointer to the UTC time struct
3833  *
3834  * Return: 0 on succes
3835  */
3836 static QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle,
3837 				struct ocb_utc_param *utc)
3838 {
3839 	QDF_STATUS ret;
3840 	wmi_ocb_set_utc_time_cmd_fixed_param *cmd;
3841 	uint8_t *buf_ptr;
3842 	uint32_t len, i;
3843 	wmi_buf_t buf;
3844 
3845 	len = sizeof(*cmd);
3846 	buf = wmi_buf_alloc(wmi_handle, len);
3847 	if (!buf) {
3848 		WMI_LOGE(FL("wmi_buf_alloc failed"));
3849 		return QDF_STATUS_E_NOMEM;
3850 	}
3851 
3852 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
3853 	cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr;
3854 	WMITLV_SET_HDR(&cmd->tlv_header,
3855 		WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param,
3856 		WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param));
3857 	cmd->vdev_id = utc->vdev_id;
3858 
3859 	for (i = 0; i < SIZE_UTC_TIME; i++)
3860 		WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]);
3861 
3862 	for (i = 0; i < SIZE_UTC_TIME_ERROR; i++)
3863 		WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]);
3864 
3865 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3866 				   WMI_OCB_SET_UTC_TIME_CMDID);
3867 	if (QDF_IS_STATUS_ERROR(ret)) {
3868 		WMI_LOGE(FL("Failed to set OCB UTC time"));
3869 		wmi_buf_free(buf);
3870 	}
3871 
3872 	return ret;
3873 }
3874 
3875 /**
3876  * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement
3877  *				   frames on a channel
3878  * @wmi_handle: pointer to the wmi handle
3879  * @timing_advert: pointer to the timing advertisement struct
3880  *
3881  * Return: 0 on succes
3882  */
3883 static QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
3884 	struct ocb_timing_advert_param *timing_advert)
3885 {
3886 	QDF_STATUS ret;
3887 	wmi_ocb_start_timing_advert_cmd_fixed_param *cmd;
3888 	uint8_t *buf_ptr;
3889 	uint32_t len, len_template;
3890 	wmi_buf_t buf;
3891 
3892 	len = sizeof(*cmd) +
3893 		     WMI_TLV_HDR_SIZE;
3894 
3895 	len_template = timing_advert->template_length;
3896 	/* Add padding to the template if needed */
3897 	if (len_template % 4 != 0)
3898 		len_template += 4 - (len_template % 4);
3899 	len += len_template;
3900 
3901 	buf = wmi_buf_alloc(wmi_handle, len);
3902 	if (!buf) {
3903 		WMI_LOGE(FL("wmi_buf_alloc failed"));
3904 		return QDF_STATUS_E_NOMEM;
3905 	}
3906 
3907 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
3908 	cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr;
3909 	WMITLV_SET_HDR(&cmd->tlv_header,
3910 		WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param,
3911 		WMITLV_GET_STRUCT_TLVLEN(
3912 			wmi_ocb_start_timing_advert_cmd_fixed_param));
3913 	cmd->vdev_id = timing_advert->vdev_id;
3914 	cmd->repeat_rate = timing_advert->repeat_rate;
3915 	cmd->channel_freq = timing_advert->chan_freq;
3916 	cmd->timestamp_offset = timing_advert->timestamp_offset;
3917 	cmd->time_value_offset = timing_advert->time_value_offset;
3918 	cmd->timing_advert_template_length = timing_advert->template_length;
3919 	buf_ptr += sizeof(*cmd);
3920 
3921 	/* Add the timing advert template */
3922 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
3923 		       len_template);
3924 	qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
3925 		     (uint8_t *)timing_advert->template_value,
3926 		     timing_advert->template_length);
3927 
3928 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3929 				   WMI_OCB_START_TIMING_ADVERT_CMDID);
3930 	if (QDF_IS_STATUS_ERROR(ret)) {
3931 		WMI_LOGE(FL("Failed to start OCB timing advert"));
3932 		wmi_buf_free(buf);
3933 	}
3934 
3935 	return ret;
3936 }
3937 
3938 /**
3939  * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames
3940  *				  on a channel
3941  * @wmi_handle: pointer to the wmi handle
3942  * @timing_advert: pointer to the timing advertisement struct
3943  *
3944  * Return: 0 on succes
3945  */
3946 static QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
3947 	struct ocb_timing_advert_param *timing_advert)
3948 {
3949 	QDF_STATUS ret;
3950 	wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd;
3951 	uint8_t *buf_ptr;
3952 	uint32_t len;
3953 	wmi_buf_t buf;
3954 
3955 	len = sizeof(*cmd);
3956 	buf = wmi_buf_alloc(wmi_handle, len);
3957 	if (!buf) {
3958 		WMI_LOGE(FL("wmi_buf_alloc failed"));
3959 		return QDF_STATUS_E_NOMEM;
3960 	}
3961 
3962 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
3963 	cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr;
3964 	WMITLV_SET_HDR(&cmd->tlv_header,
3965 		WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param,
3966 		WMITLV_GET_STRUCT_TLVLEN(
3967 			wmi_ocb_stop_timing_advert_cmd_fixed_param));
3968 	cmd->vdev_id = timing_advert->vdev_id;
3969 	cmd->channel_freq = timing_advert->chan_freq;
3970 
3971 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3972 				   WMI_OCB_STOP_TIMING_ADVERT_CMDID);
3973 	if (QDF_IS_STATUS_ERROR(ret)) {
3974 		WMI_LOGE(FL("Failed to stop OCB timing advert"));
3975 		wmi_buf_free(buf);
3976 	}
3977 
3978 	return ret;
3979 }
3980 
3981 /**
3982  * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val
3983  * @wmi_handle: pointer to the wmi handle
3984  * @request: pointer to the request
3985  *
3986  * Return: 0 on succes
3987  */
3988 static QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle,
3989 			  uint8_t vdev_id)
3990 {
3991 	QDF_STATUS ret;
3992 	wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd;
3993 	uint8_t *buf_ptr;
3994 	wmi_buf_t buf;
3995 	int32_t len;
3996 
3997 	len = sizeof(*cmd);
3998 	buf = wmi_buf_alloc(wmi_handle, len);
3999 	if (!buf) {
4000 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4001 		return QDF_STATUS_E_NOMEM;
4002 	}
4003 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4004 
4005 	cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr;
4006 	qdf_mem_zero(cmd, len);
4007 	WMITLV_SET_HDR(&cmd->tlv_header,
4008 		WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param,
4009 		WMITLV_GET_STRUCT_TLVLEN(
4010 			wmi_ocb_get_tsf_timer_cmd_fixed_param));
4011 	cmd->vdev_id = vdev_id;
4012 
4013 	/* Send the WMI command */
4014 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4015 				   WMI_OCB_GET_TSF_TIMER_CMDID);
4016 	/* If there is an error, set the completion event */
4017 	if (QDF_IS_STATUS_ERROR(ret)) {
4018 		WMI_LOGE(FL("Failed to send WMI message: %d"), ret);
4019 		wmi_buf_free(buf);
4020 	}
4021 
4022 	return ret;
4023 }
4024 
4025 /**
4026  * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats
4027  * @wmi_handle: pointer to the wmi handle
4028  * @get_stats_param: pointer to the dcc stats
4029  *
4030  * Return: 0 on succes
4031  */
4032 static QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle,
4033 		     struct ocb_dcc_get_stats_param *get_stats_param)
4034 {
4035 	QDF_STATUS ret;
4036 	wmi_dcc_get_stats_cmd_fixed_param *cmd;
4037 	wmi_dcc_channel_stats_request *channel_stats_array;
4038 	wmi_buf_t buf;
4039 	uint8_t *buf_ptr;
4040 	uint32_t len;
4041 	uint32_t i;
4042 
4043 	/* Validate the input */
4044 	if (get_stats_param->request_array_len !=
4045 	    get_stats_param->channel_count * sizeof(*channel_stats_array)) {
4046 		WMI_LOGE(FL("Invalid parameter"));
4047 		return QDF_STATUS_E_INVAL;
4048 	}
4049 
4050 	/* Allocate memory for the WMI command */
4051 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
4052 		get_stats_param->request_array_len;
4053 
4054 	buf = wmi_buf_alloc(wmi_handle, len);
4055 	if (!buf) {
4056 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4057 		return QDF_STATUS_E_NOMEM;
4058 	}
4059 
4060 	buf_ptr = wmi_buf_data(buf);
4061 	qdf_mem_zero(buf_ptr, len);
4062 
4063 	/* Populate the WMI command */
4064 	cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr;
4065 	buf_ptr += sizeof(*cmd);
4066 
4067 	WMITLV_SET_HDR(&cmd->tlv_header,
4068 		       WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param,
4069 		       WMITLV_GET_STRUCT_TLVLEN(
4070 			   wmi_dcc_get_stats_cmd_fixed_param));
4071 	cmd->vdev_id = get_stats_param->vdev_id;
4072 	cmd->num_channels = get_stats_param->channel_count;
4073 
4074 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4075 		       get_stats_param->request_array_len);
4076 	buf_ptr += WMI_TLV_HDR_SIZE;
4077 
4078 	channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr;
4079 	qdf_mem_copy(channel_stats_array, get_stats_param->request_array,
4080 		     get_stats_param->request_array_len);
4081 	for (i = 0; i < cmd->num_channels; i++)
4082 		WMITLV_SET_HDR(&channel_stats_array[i].tlv_header,
4083 			WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request,
4084 			WMITLV_GET_STRUCT_TLVLEN(
4085 			    wmi_dcc_channel_stats_request));
4086 
4087 	/* Send the WMI command */
4088 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4089 				   WMI_DCC_GET_STATS_CMDID);
4090 
4091 	if (QDF_IS_STATUS_ERROR(ret)) {
4092 		WMI_LOGE(FL("Failed to send WMI message: %d"), ret);
4093 		wmi_buf_free(buf);
4094 	}
4095 
4096 	return ret;
4097 }
4098 
4099 /**
4100  * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats
4101  * @wmi_handle: pointer to the wmi handle
4102  * @vdev_id: vdev id
4103  * @dcc_stats_bitmap: dcc status bitmap
4104  *
4105  * Return: 0 on succes
4106  */
4107 static QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle,
4108 				uint32_t vdev_id, uint32_t dcc_stats_bitmap)
4109 {
4110 	QDF_STATUS ret;
4111 	wmi_dcc_clear_stats_cmd_fixed_param *cmd;
4112 	wmi_buf_t buf;
4113 	uint8_t *buf_ptr;
4114 	uint32_t len;
4115 
4116 	/* Allocate memory for the WMI command */
4117 	len = sizeof(*cmd);
4118 
4119 	buf = wmi_buf_alloc(wmi_handle, len);
4120 	if (!buf) {
4121 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4122 		return QDF_STATUS_E_NOMEM;
4123 	}
4124 
4125 	buf_ptr = wmi_buf_data(buf);
4126 	qdf_mem_zero(buf_ptr, len);
4127 
4128 	/* Populate the WMI command */
4129 	cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr;
4130 
4131 	WMITLV_SET_HDR(&cmd->tlv_header,
4132 		       WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param,
4133 		       WMITLV_GET_STRUCT_TLVLEN(
4134 			   wmi_dcc_clear_stats_cmd_fixed_param));
4135 	cmd->vdev_id = vdev_id;
4136 	cmd->dcc_stats_bitmap = dcc_stats_bitmap;
4137 
4138 	/* Send the WMI command */
4139 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4140 				   WMI_DCC_CLEAR_STATS_CMDID);
4141 	if (QDF_IS_STATUS_ERROR(ret)) {
4142 		WMI_LOGE(FL("Failed to send the WMI command"));
4143 		wmi_buf_free(buf);
4144 	}
4145 
4146 	return ret;
4147 }
4148 
4149 /**
4150  * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data
4151  * @wmi_handle: pointer to the wmi handle
4152  * @update_ndl_param: pointer to the request parameters
4153  *
4154  * Return: 0 on success
4155  */
4156 static QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle,
4157 		       struct ocb_dcc_update_ndl_param *update_ndl_param)
4158 {
4159 	QDF_STATUS qdf_status;
4160 	wmi_dcc_update_ndl_cmd_fixed_param *cmd;
4161 	wmi_dcc_ndl_chan *ndl_chan_array;
4162 	wmi_dcc_ndl_active_state_config *ndl_active_state_array;
4163 	uint32_t active_state_count;
4164 	wmi_buf_t buf;
4165 	uint8_t *buf_ptr;
4166 	uint32_t len;
4167 	uint32_t i;
4168 
4169 	/* validate the input */
4170 	if (update_ndl_param->dcc_ndl_chan_list_len !=
4171 	    update_ndl_param->channel_count * sizeof(*ndl_chan_array)) {
4172 		WMI_LOGE(FL("Invalid parameter"));
4173 		return QDF_STATUS_E_INVAL;
4174 	}
4175 	active_state_count = 0;
4176 	ndl_chan_array = update_ndl_param->dcc_ndl_chan_list;
4177 	for (i = 0; i < update_ndl_param->channel_count; i++)
4178 		active_state_count +=
4179 			WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]);
4180 	if (update_ndl_param->dcc_ndl_active_state_list_len !=
4181 	    active_state_count * sizeof(*ndl_active_state_array)) {
4182 		WMI_LOGE(FL("Invalid parameter"));
4183 		return QDF_STATUS_E_INVAL;
4184 	}
4185 
4186 	/* Allocate memory for the WMI command */
4187 	len = sizeof(*cmd) +
4188 		WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len +
4189 		WMI_TLV_HDR_SIZE +
4190 		update_ndl_param->dcc_ndl_active_state_list_len;
4191 
4192 	buf = wmi_buf_alloc(wmi_handle, len);
4193 	if (!buf) {
4194 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4195 		return QDF_STATUS_E_NOMEM;
4196 	}
4197 
4198 	buf_ptr = wmi_buf_data(buf);
4199 	qdf_mem_zero(buf_ptr, len);
4200 
4201 	/* Populate the WMI command */
4202 	cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr;
4203 	buf_ptr += sizeof(*cmd);
4204 
4205 	WMITLV_SET_HDR(&cmd->tlv_header,
4206 		       WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param,
4207 		       WMITLV_GET_STRUCT_TLVLEN(
4208 			   wmi_dcc_update_ndl_cmd_fixed_param));
4209 	cmd->vdev_id = update_ndl_param->vdev_id;
4210 	cmd->num_channel = update_ndl_param->channel_count;
4211 
4212 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4213 		       update_ndl_param->dcc_ndl_chan_list_len);
4214 	buf_ptr += WMI_TLV_HDR_SIZE;
4215 
4216 	ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr;
4217 	qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list,
4218 		     update_ndl_param->dcc_ndl_chan_list_len);
4219 	for (i = 0; i < cmd->num_channel; i++)
4220 		WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header,
4221 			WMITLV_TAG_STRUC_wmi_dcc_ndl_chan,
4222 			WMITLV_GET_STRUCT_TLVLEN(
4223 			    wmi_dcc_ndl_chan));
4224 	buf_ptr += update_ndl_param->dcc_ndl_chan_list_len;
4225 
4226 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4227 		       update_ndl_param->dcc_ndl_active_state_list_len);
4228 	buf_ptr += WMI_TLV_HDR_SIZE;
4229 
4230 	ndl_active_state_array = (wmi_dcc_ndl_active_state_config *) buf_ptr;
4231 	qdf_mem_copy(ndl_active_state_array,
4232 		     update_ndl_param->dcc_ndl_active_state_list,
4233 		     update_ndl_param->dcc_ndl_active_state_list_len);
4234 	for (i = 0; i < active_state_count; i++) {
4235 		WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header,
4236 			WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config,
4237 			WMITLV_GET_STRUCT_TLVLEN(
4238 			    wmi_dcc_ndl_active_state_config));
4239 	}
4240 	buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len;
4241 
4242 	/* Send the WMI command */
4243 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
4244 				   WMI_DCC_UPDATE_NDL_CMDID);
4245 	/* If there is an error, set the completion event */
4246 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4247 		WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status);
4248 		wmi_buf_free(buf);
4249 	}
4250 
4251 	return qdf_status;
4252 }
4253 
4254 /**
4255  * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW
4256  * @wmi_handle: pointer to the wmi handle
4257  * @config: the OCB configuration
4258  *
4259  * Return: 0 on success
4260  */
4261 static QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle,
4262 				struct ocb_config *config)
4263 {
4264 	QDF_STATUS ret;
4265 	wmi_ocb_set_config_cmd_fixed_param *cmd;
4266 	wmi_channel *chan;
4267 	wmi_ocb_channel *ocb_chan;
4268 	wmi_qos_parameter *qos_param;
4269 	wmi_dcc_ndl_chan *ndl_chan;
4270 	wmi_dcc_ndl_active_state_config *ndl_active_config;
4271 	wmi_ocb_schedule_element *sched_elem;
4272 	uint8_t *buf_ptr;
4273 	wmi_buf_t buf;
4274 	int32_t len;
4275 	int32_t i, j, active_state_count;
4276 
4277 	/*
4278 	 * Validate the dcc_ndl_chan_list_len and count the number of active
4279 	 * states. Validate dcc_ndl_active_state_list_len.
4280 	 */
4281 	active_state_count = 0;
4282 	if (config->dcc_ndl_chan_list_len) {
4283 		if (!config->dcc_ndl_chan_list ||
4284 			config->dcc_ndl_chan_list_len !=
4285 			config->channel_count * sizeof(wmi_dcc_ndl_chan)) {
4286 			WMI_LOGE(FL("NDL channel is invalid. List len: %d"),
4287 				 config->dcc_ndl_chan_list_len);
4288 			return QDF_STATUS_E_INVAL;
4289 		}
4290 
4291 		for (i = 0, ndl_chan = config->dcc_ndl_chan_list;
4292 				i < config->channel_count; ++i, ++ndl_chan)
4293 			active_state_count +=
4294 				WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan);
4295 
4296 		if (active_state_count) {
4297 			if (!config->dcc_ndl_active_state_list ||
4298 				config->dcc_ndl_active_state_list_len !=
4299 				active_state_count *
4300 				sizeof(wmi_dcc_ndl_active_state_config)) {
4301 				WMI_LOGE(FL("NDL active state is invalid."));
4302 				return QDF_STATUS_E_INVAL;
4303 			}
4304 		}
4305 	}
4306 
4307 	len = sizeof(*cmd) +
4308 		WMI_TLV_HDR_SIZE + config->channel_count *
4309 			sizeof(wmi_channel) +
4310 		WMI_TLV_HDR_SIZE + config->channel_count *
4311 			sizeof(wmi_ocb_channel) +
4312 		WMI_TLV_HDR_SIZE + config->channel_count *
4313 			sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC +
4314 		WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len +
4315 		WMI_TLV_HDR_SIZE + active_state_count *
4316 			sizeof(wmi_dcc_ndl_active_state_config) +
4317 		WMI_TLV_HDR_SIZE + config->schedule_size *
4318 			sizeof(wmi_ocb_schedule_element);
4319 	buf = wmi_buf_alloc(wmi_handle, len);
4320 	if (!buf) {
4321 		WMI_LOGE(FL("wmi_buf_alloc failed"));
4322 		return QDF_STATUS_E_NOMEM;
4323 	}
4324 
4325 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4326 	cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr;
4327 	WMITLV_SET_HDR(&cmd->tlv_header,
4328 		WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param,
4329 		WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param));
4330 	cmd->vdev_id = config->vdev_id;
4331 	cmd->channel_count = config->channel_count;
4332 	cmd->schedule_size = config->schedule_size;
4333 	cmd->flags = config->flags;
4334 	buf_ptr += sizeof(*cmd);
4335 
4336 	/* Add the wmi_channel info */
4337 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4338 		       config->channel_count*sizeof(wmi_channel));
4339 	buf_ptr += WMI_TLV_HDR_SIZE;
4340 	for (i = 0; i < config->channel_count; i++) {
4341 		chan = (wmi_channel *)buf_ptr;
4342 		WMITLV_SET_HDR(&chan->tlv_header,
4343 				WMITLV_TAG_STRUC_wmi_channel,
4344 				WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
4345 		chan->mhz = config->channels[i].chan_freq;
4346 		chan->band_center_freq1 = config->channels[i].chan_freq;
4347 		chan->band_center_freq2 = 0;
4348 		chan->info = 0;
4349 
4350 		WMI_SET_CHANNEL_MODE(chan, config->channels[i].ch_mode);
4351 		WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr);
4352 		WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr);
4353 		WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr);
4354 		WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr);
4355 		WMI_SET_CHANNEL_ANTENNA_MAX(chan,
4356 					    config->channels[i].antenna_max);
4357 
4358 		if (config->channels[i].bandwidth < 10)
4359 			WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
4360 		else if (config->channels[i].bandwidth < 20)
4361 			WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
4362 		buf_ptr += sizeof(*chan);
4363 	}
4364 
4365 	/* Add the wmi_ocb_channel info */
4366 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4367 		       config->channel_count*sizeof(wmi_ocb_channel));
4368 	buf_ptr += WMI_TLV_HDR_SIZE;
4369 	for (i = 0; i < config->channel_count; i++) {
4370 		ocb_chan = (wmi_ocb_channel *)buf_ptr;
4371 		WMITLV_SET_HDR(&ocb_chan->tlv_header,
4372 			       WMITLV_TAG_STRUC_wmi_ocb_channel,
4373 			       WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel));
4374 		ocb_chan->bandwidth = config->channels[i].bandwidth;
4375 		WMI_CHAR_ARRAY_TO_MAC_ADDR(
4376 					config->channels[i].mac_address.bytes,
4377 					&ocb_chan->mac_address);
4378 		buf_ptr += sizeof(*ocb_chan);
4379 	}
4380 
4381 	/* Add the wmi_qos_parameter info */
4382 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4383 		config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC);
4384 	buf_ptr += WMI_TLV_HDR_SIZE;
4385 	/* WMI_MAX_NUM_AC parameters for each channel */
4386 	for (i = 0; i < config->channel_count; i++) {
4387 		for (j = 0; j < WMI_MAX_NUM_AC; j++) {
4388 			qos_param = (wmi_qos_parameter *)buf_ptr;
4389 			WMITLV_SET_HDR(&qos_param->tlv_header,
4390 				WMITLV_TAG_STRUC_wmi_qos_parameter,
4391 				WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter));
4392 			qos_param->aifsn =
4393 				config->channels[i].qos_params[j].aifsn;
4394 			qos_param->cwmin =
4395 				config->channels[i].qos_params[j].cwmin;
4396 			qos_param->cwmax =
4397 				config->channels[i].qos_params[j].cwmax;
4398 			buf_ptr += sizeof(*qos_param);
4399 		}
4400 	}
4401 
4402 	/* Add the wmi_dcc_ndl_chan (per channel) */
4403 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4404 		       config->dcc_ndl_chan_list_len);
4405 	buf_ptr += WMI_TLV_HDR_SIZE;
4406 	if (config->dcc_ndl_chan_list_len) {
4407 		ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr;
4408 		qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list,
4409 			     config->dcc_ndl_chan_list_len);
4410 		for (i = 0; i < config->channel_count; i++)
4411 			WMITLV_SET_HDR(&(ndl_chan[i].tlv_header),
4412 				WMITLV_TAG_STRUC_wmi_dcc_ndl_chan,
4413 				WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan));
4414 		buf_ptr += config->dcc_ndl_chan_list_len;
4415 	}
4416 
4417 	/* Add the wmi_dcc_ndl_active_state_config */
4418 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count *
4419 		       sizeof(wmi_dcc_ndl_active_state_config));
4420 	buf_ptr += WMI_TLV_HDR_SIZE;
4421 	if (active_state_count) {
4422 		ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr;
4423 		qdf_mem_copy(ndl_active_config,
4424 			config->dcc_ndl_active_state_list,
4425 			active_state_count * sizeof(*ndl_active_config));
4426 		for (i = 0; i < active_state_count; ++i)
4427 			WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header),
4428 			  WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config,
4429 			  WMITLV_GET_STRUCT_TLVLEN(
4430 				wmi_dcc_ndl_active_state_config));
4431 		buf_ptr += active_state_count *
4432 			sizeof(*ndl_active_config);
4433 	}
4434 
4435 	/* Add the wmi_ocb_schedule_element info */
4436 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4437 		config->schedule_size * sizeof(wmi_ocb_schedule_element));
4438 	buf_ptr += WMI_TLV_HDR_SIZE;
4439 	for (i = 0; i < config->schedule_size; i++) {
4440 		sched_elem = (wmi_ocb_schedule_element *)buf_ptr;
4441 		WMITLV_SET_HDR(&sched_elem->tlv_header,
4442 			WMITLV_TAG_STRUC_wmi_ocb_schedule_element,
4443 			WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element));
4444 		sched_elem->channel_freq = config->schedule[i].chan_freq;
4445 		sched_elem->total_duration = config->schedule[i].total_duration;
4446 		sched_elem->guard_interval = config->schedule[i].guard_interval;
4447 		buf_ptr += sizeof(*sched_elem);
4448 	}
4449 
4450 
4451 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4452 				   WMI_OCB_SET_CONFIG_CMDID);
4453 	if (QDF_IS_STATUS_ERROR(ret)) {
4454 		WMI_LOGE("Failed to set OCB config");
4455 		wmi_buf_free(buf);
4456 	}
4457 
4458 	return ret;
4459 }
4460 
4461 /**
4462  * extract_ocb_channel_config_resp_tlv() - extract ocb channel config resp
4463  * @wmi_handle: wmi handle
4464  * @evt_buf: wmi event buffer
4465  * @status: status buffer
4466  *
4467  * Return: QDF_STATUS_SUCCESS on success
4468  */
4469 static QDF_STATUS extract_ocb_channel_config_resp_tlv(wmi_unified_t wmi_handle,
4470 						      void *evt_buf,
4471 						      uint32_t *status)
4472 {
4473 	WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs;
4474 	wmi_ocb_set_config_resp_event_fixed_param *fix_param;
4475 
4476 	param_tlvs = evt_buf;
4477 	fix_param = param_tlvs->fixed_param;
4478 
4479 	*status = fix_param->status;
4480 	return QDF_STATUS_SUCCESS;
4481 }
4482 
4483 /**
4484  * extract_ocb_tsf_timer_tlv() - extract TSF timer from event buffer
4485  * @wmi_handle: wmi handle
4486  * @evt_buf: wmi event buffer
4487  * @resp: response buffer
4488  *
4489  * Return: QDF_STATUS_SUCCESS on success
4490  */
4491 static QDF_STATUS extract_ocb_tsf_timer_tlv(wmi_unified_t wmi_handle,
4492 			void *evt_buf, struct ocb_get_tsf_timer_response *resp)
4493 {
4494 	WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs;
4495 	wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param;
4496 
4497 	param_tlvs = evt_buf;
4498 	fix_param = param_tlvs->fixed_param;
4499 	resp->vdev_id = fix_param->vdev_id;
4500 	resp->timer_high = fix_param->tsf_timer_high;
4501 	resp->timer_low = fix_param->tsf_timer_low;
4502 
4503 	return QDF_STATUS_SUCCESS;
4504 }
4505 
4506 /**
4507  * extract_ocb_ndl_resp_tlv() - extract TSF timer from event buffer
4508  * @wmi_handle: wmi handle
4509  * @evt_buf: wmi event buffer
4510  * @resp: response buffer
4511  *
4512  * Return: QDF_STATUS_SUCCESS on success
4513  */
4514 static QDF_STATUS extract_ocb_ndl_resp_tlv(wmi_unified_t wmi_handle,
4515 		void *evt_buf, struct ocb_dcc_update_ndl_response *resp)
4516 {
4517 	WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs;
4518 	wmi_dcc_update_ndl_resp_event_fixed_param *fix_param;
4519 
4520 	param_tlvs = evt_buf;
4521 	fix_param = param_tlvs->fixed_param;
4522 	resp->vdev_id = fix_param->vdev_id;
4523 	resp->status = fix_param->status;
4524 	return QDF_STATUS_SUCCESS;
4525 }
4526 
4527 /**
4528  * extract_ocb_dcc_stats_tlv() - extract DCC stats from event buffer
4529  * @wmi_handle: wmi handle
4530  * @evt_buf: wmi event buffer
4531  * @resp: response buffer
4532  *
4533  * Since length of stats is variable, buffer for DCC stats will be allocated
4534  * in this function. The caller must free the buffer.
4535  *
4536  * Return: QDF_STATUS_SUCCESS on success
4537  */
4538 static QDF_STATUS extract_ocb_dcc_stats_tlv(wmi_unified_t wmi_handle,
4539 		void *evt_buf, struct ocb_dcc_get_stats_response **resp)
4540 {
4541 	struct ocb_dcc_get_stats_response *response;
4542 	WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs;
4543 	wmi_dcc_get_stats_resp_event_fixed_param *fix_param;
4544 
4545 	param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)evt_buf;
4546 	fix_param = param_tlvs->fixed_param;
4547 
4548 	/* Allocate and populate the response */
4549 	if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE -
4550 	    sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) {
4551 		WMI_LOGE("%s: too many channels:%d", __func__,
4552 			 fix_param->num_channels);
4553 		QDF_ASSERT(0);
4554 		*resp = NULL;
4555 		return QDF_STATUS_E_INVAL;
4556 	}
4557 	response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels *
4558 		sizeof(wmi_dcc_ndl_stats_per_channel));
4559 	*resp = response;
4560 	if (!response)
4561 		return  QDF_STATUS_E_NOMEM;
4562 
4563 	response->vdev_id = fix_param->vdev_id;
4564 	response->num_channels = fix_param->num_channels;
4565 	response->channel_stats_array_len =
4566 		fix_param->num_channels *
4567 		sizeof(wmi_dcc_ndl_stats_per_channel);
4568 	response->channel_stats_array = ((uint8_t *)response) +
4569 					sizeof(*response);
4570 	qdf_mem_copy(response->channel_stats_array,
4571 		     param_tlvs->stats_per_channel_list,
4572 		     response->channel_stats_array_len);
4573 
4574 	return QDF_STATUS_SUCCESS;
4575 }
4576 #endif
4577 
4578 /**
4579  * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable mcc scheduler
4580  * @wmi_handle: wmi handle
4581  * @mcc_adaptive_scheduler: enable/disable
4582  *
4583  * This function enable/disable mcc adaptive scheduler in fw.
4584  *
4585  * Return: QDF_STATUS_SUCCESS for sucess or error code
4586  */
4587 static QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv(
4588 		wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler,
4589 		uint32_t pdev_id)
4590 {
4591 	QDF_STATUS ret;
4592 	wmi_buf_t buf = 0;
4593 	wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL;
4594 	uint16_t len =
4595 		sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param);
4596 
4597 	buf = wmi_buf_alloc(wmi_handle, len);
4598 	if (!buf) {
4599 		WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
4600 		return QDF_STATUS_E_NOMEM;
4601 	}
4602 	cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *)
4603 		wmi_buf_data(buf);
4604 
4605 	WMITLV_SET_HDR(&cmd->tlv_header,
4606 		       WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param,
4607 		       WMITLV_GET_STRUCT_TLVLEN
4608 			       (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param));
4609 	cmd->enable = mcc_adaptive_scheduler;
4610 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
4611 
4612 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4613 				   WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID);
4614 	if (QDF_IS_STATUS_ERROR(ret)) {
4615 		WMI_LOGP("%s: Failed to send enable/disable MCC"
4616 			 " adaptive scheduler command", __func__);
4617 		wmi_buf_free(buf);
4618 	}
4619 
4620 	return ret;
4621 }
4622 
4623 /**
4624  * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency
4625  * @wmi: wmi handle
4626  * @mcc_channel: mcc channel
4627  * @mcc_channel_time_latency: MCC channel time latency.
4628  *
4629  * Currently used to set time latency for an MCC vdev/adapter using operating
4630  * channel of it and channel number. The info is provided run time using
4631  * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>.
4632  *
4633  * Return: CDF status
4634  */
4635 static QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(wmi_unified_t wmi_handle,
4636 	uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency)
4637 {
4638 	QDF_STATUS ret;
4639 	wmi_buf_t buf = 0;
4640 	wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL;
4641 	uint16_t len = 0;
4642 	uint8_t *buf_ptr = NULL;
4643 	wmi_resmgr_chan_latency chan_latency;
4644 	/* Note: we only support MCC time latency for a single channel */
4645 	uint32_t num_channels = 1;
4646 	uint32_t chan1_freq = mcc_channel_freq;
4647 	uint32_t latency_chan1 = mcc_channel_time_latency;
4648 
4649 
4650 	/* If 0ms latency is provided, then FW will set to a default.
4651 	 * Otherwise, latency must be at least 30ms.
4652 	 */
4653 	if ((latency_chan1 > 0) &&
4654 	    (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) {
4655 		WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms "
4656 			 "Minimum is 30ms (or 0 to use default value by "
4657 			 "firmware)", __func__, latency_chan1);
4658 		return QDF_STATUS_E_INVAL;
4659 	}
4660 
4661 	/*   Set WMI CMD for channel time latency here */
4662 	len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) +
4663 	      WMI_TLV_HDR_SIZE +  /*Place holder for chan_time_latency array */
4664 	      num_channels * sizeof(wmi_resmgr_chan_latency);
4665 	buf = wmi_buf_alloc(wmi_handle, len);
4666 	if (!buf) {
4667 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
4668 		return QDF_STATUS_E_NOMEM;
4669 	}
4670 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
4671 	cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *)
4672 		wmi_buf_data(buf);
4673 	WMITLV_SET_HDR(&cmdTL->tlv_header,
4674 		WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param,
4675 		       WMITLV_GET_STRUCT_TLVLEN
4676 		       (wmi_resmgr_set_chan_latency_cmd_fixed_param));
4677 	cmdTL->num_chans = num_channels;
4678 	/* Update channel time latency information for home channel(s) */
4679 	buf_ptr += sizeof(*cmdTL);
4680 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
4681 		       num_channels * sizeof(wmi_resmgr_chan_latency));
4682 	buf_ptr += WMI_TLV_HDR_SIZE;
4683 	chan_latency.chan_mhz = chan1_freq;
4684 	chan_latency.latency = latency_chan1;
4685 	qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency));
4686 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4687 				   WMI_RESMGR_SET_CHAN_LATENCY_CMDID);
4688 	if (QDF_IS_STATUS_ERROR(ret)) {
4689 		WMI_LOGE("%s: Failed to send MCC Channel Time Latency command",
4690 			 __func__);
4691 		wmi_buf_free(buf);
4692 		QDF_ASSERT(0);
4693 	}
4694 
4695 	return ret;
4696 }
4697 
4698 /**
4699  * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota
4700  * @wmi: wmi handle
4701  * @adapter_1_chan_number: adapter 1 channel number
4702  * @adapter_1_quota: adapter 1 quota
4703  * @adapter_2_chan_number: adapter 2 channel number
4704  *
4705  * Return: CDF status
4706  */
4707 static QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(wmi_unified_t wmi_handle,
4708 	uint32_t adapter_1_chan_freq,
4709 	uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq)
4710 {
4711 	QDF_STATUS ret;
4712 	wmi_buf_t buf = 0;
4713 	uint16_t len = 0;
4714 	uint8_t *buf_ptr = NULL;
4715 	wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL;
4716 	wmi_resmgr_chan_time_quota chan_quota;
4717 	uint32_t quota_chan1 = adapter_1_quota;
4718 	/* Knowing quota of 1st chan., derive quota for 2nd chan. */
4719 	uint32_t quota_chan2 = 100 - quota_chan1;
4720 	/* Note: setting time quota for MCC requires info for 2 channels */
4721 	uint32_t num_channels = 2;
4722 	uint32_t chan1_freq = adapter_1_chan_freq;
4723 	uint32_t chan2_freq = adapter_2_chan_freq;
4724 
4725 	WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, "
4726 		 "freq2:%dMHz, Quota2:%dms", __func__,
4727 		 chan1_freq, quota_chan1, chan2_freq,
4728 		 quota_chan2);
4729 
4730 	/*
4731 	 * Perform sanity check on time quota values provided.
4732 	 */
4733 	if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA ||
4734 	    quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) {
4735 		WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum "
4736 			 "is 20ms & maximum is 80ms", __func__, quota_chan1);
4737 		return QDF_STATUS_E_INVAL;
4738 	}
4739 	/* Set WMI CMD for channel time quota here */
4740 	len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) +
4741 	      WMI_TLV_HDR_SIZE +       /* Place holder for chan_time_quota array */
4742 	      num_channels * sizeof(wmi_resmgr_chan_time_quota);
4743 	buf = wmi_buf_alloc(wmi_handle, len);
4744 	if (!buf) {
4745 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
4746 		QDF_ASSERT(0);
4747 		return QDF_STATUS_E_NOMEM;
4748 	}
4749 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
4750 	cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *)
4751 		wmi_buf_data(buf);
4752 	WMITLV_SET_HDR(&cmdTQ->tlv_header,
4753 		       WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param,
4754 		       WMITLV_GET_STRUCT_TLVLEN
4755 			       (wmi_resmgr_set_chan_time_quota_cmd_fixed_param));
4756 	cmdTQ->num_chans = num_channels;
4757 
4758 	/* Update channel time quota information for home channel(s) */
4759 	buf_ptr += sizeof(*cmdTQ);
4760 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
4761 		       num_channels * sizeof(wmi_resmgr_chan_time_quota));
4762 	buf_ptr += WMI_TLV_HDR_SIZE;
4763 	chan_quota.chan_mhz = chan1_freq;
4764 	chan_quota.channel_time_quota = quota_chan1;
4765 	qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
4766 	/* Construct channel and quota record for the 2nd MCC mode. */
4767 	buf_ptr += sizeof(chan_quota);
4768 	chan_quota.chan_mhz = chan2_freq;
4769 	chan_quota.channel_time_quota = quota_chan2;
4770 	qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
4771 
4772 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4773 				   WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID);
4774 	if (QDF_IS_STATUS_ERROR(ret)) {
4775 		WMI_LOGE("Failed to send MCC Channel Time Quota command");
4776 		wmi_buf_free(buf);
4777 		QDF_ASSERT(0);
4778 	}
4779 
4780 	return ret;
4781 }
4782 
4783 /**
4784  * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw
4785  * @wmi_handle: Pointer to wmi handle
4786  * @thermal_info: Thermal command information
4787  *
4788  * This function sends the thermal management command
4789  * to the firmware
4790  *
4791  * Return: QDF_STATUS_SUCCESS for success otherwise failure
4792  */
4793 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
4794 				struct thermal_cmd_params *thermal_info)
4795 {
4796 	wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL;
4797 	wmi_buf_t buf = NULL;
4798 	QDF_STATUS status;
4799 	uint32_t len = 0;
4800 
4801 	len = sizeof(*cmd);
4802 
4803 	buf = wmi_buf_alloc(wmi_handle, len);
4804 	if (!buf) {
4805 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
4806 		return QDF_STATUS_E_FAILURE;
4807 	}
4808 
4809 	cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf);
4810 
4811 	WMITLV_SET_HDR(&cmd->tlv_header,
4812 		       WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param,
4813 		       WMITLV_GET_STRUCT_TLVLEN
4814 			       (wmi_thermal_mgmt_cmd_fixed_param));
4815 
4816 	cmd->lower_thresh_degreeC = thermal_info->min_temp;
4817 	cmd->upper_thresh_degreeC = thermal_info->max_temp;
4818 	cmd->enable = thermal_info->thermal_enable;
4819 
4820 	WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d",
4821 		cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable);
4822 
4823 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
4824 				      WMI_THERMAL_MGMT_CMDID);
4825 	if (QDF_IS_STATUS_ERROR(status)) {
4826 		wmi_buf_free(buf);
4827 		WMI_LOGE("%s:Failed to send thermal mgmt command", __func__);
4828 	}
4829 
4830 	return status;
4831 }
4832 
4833 
4834 /**
4835  * send_lro_config_cmd_tlv() - process the LRO config command
4836  * @wmi_handle: Pointer to WMI handle
4837  * @wmi_lro_cmd: Pointer to LRO configuration parameters
4838  *
4839  * This function sends down the LRO configuration parameters to
4840  * the firmware to enable LRO, sets the TCP flags and sets the
4841  * seed values for the toeplitz hash generation
4842  *
4843  * Return: QDF_STATUS_SUCCESS for success otherwise failure
4844  */
4845 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle,
4846 	 struct wmi_lro_config_cmd_t *wmi_lro_cmd)
4847 {
4848 	wmi_lro_info_cmd_fixed_param *cmd;
4849 	wmi_buf_t buf;
4850 	QDF_STATUS status;
4851 
4852 
4853 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
4854 	if (!buf) {
4855 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
4856 		return QDF_STATUS_E_FAILURE;
4857 	}
4858 
4859 	cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf);
4860 
4861 	WMITLV_SET_HDR(&cmd->tlv_header,
4862 		 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param,
4863 		 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param));
4864 
4865 	cmd->lro_enable = wmi_lro_cmd->lro_enable;
4866 	WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32,
4867 		 wmi_lro_cmd->tcp_flag);
4868 	WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32,
4869 		 wmi_lro_cmd->tcp_flag_mask);
4870 	cmd->toeplitz_hash_ipv4_0_3 =
4871 		 wmi_lro_cmd->toeplitz_hash_ipv4[0];
4872 	cmd->toeplitz_hash_ipv4_4_7 =
4873 		 wmi_lro_cmd->toeplitz_hash_ipv4[1];
4874 	cmd->toeplitz_hash_ipv4_8_11 =
4875 		 wmi_lro_cmd->toeplitz_hash_ipv4[2];
4876 	cmd->toeplitz_hash_ipv4_12_15 =
4877 		 wmi_lro_cmd->toeplitz_hash_ipv4[3];
4878 	cmd->toeplitz_hash_ipv4_16 =
4879 		 wmi_lro_cmd->toeplitz_hash_ipv4[4];
4880 
4881 	cmd->toeplitz_hash_ipv6_0_3 =
4882 		 wmi_lro_cmd->toeplitz_hash_ipv6[0];
4883 	cmd->toeplitz_hash_ipv6_4_7 =
4884 		 wmi_lro_cmd->toeplitz_hash_ipv6[1];
4885 	cmd->toeplitz_hash_ipv6_8_11 =
4886 		 wmi_lro_cmd->toeplitz_hash_ipv6[2];
4887 	cmd->toeplitz_hash_ipv6_12_15 =
4888 		 wmi_lro_cmd->toeplitz_hash_ipv6[3];
4889 	cmd->toeplitz_hash_ipv6_16_19 =
4890 		 wmi_lro_cmd->toeplitz_hash_ipv6[4];
4891 	cmd->toeplitz_hash_ipv6_20_23 =
4892 		 wmi_lro_cmd->toeplitz_hash_ipv6[5];
4893 	cmd->toeplitz_hash_ipv6_24_27 =
4894 		 wmi_lro_cmd->toeplitz_hash_ipv6[6];
4895 	cmd->toeplitz_hash_ipv6_28_31 =
4896 		 wmi_lro_cmd->toeplitz_hash_ipv6[7];
4897 	cmd->toeplitz_hash_ipv6_32_35 =
4898 		 wmi_lro_cmd->toeplitz_hash_ipv6[8];
4899 	cmd->toeplitz_hash_ipv6_36_39 =
4900 		 wmi_lro_cmd->toeplitz_hash_ipv6[9];
4901 	cmd->toeplitz_hash_ipv6_40 =
4902 		 wmi_lro_cmd->toeplitz_hash_ipv6[10];
4903 
4904 	WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x",
4905 		cmd->lro_enable, cmd->tcp_flag_u32);
4906 
4907 	status = wmi_unified_cmd_send(wmi_handle, buf,
4908 		 sizeof(*cmd), WMI_LRO_CONFIG_CMDID);
4909 	if (QDF_IS_STATUS_ERROR(status)) {
4910 		wmi_buf_free(buf);
4911 		WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__);
4912 	}
4913 
4914 	return status;
4915 }
4916 
4917 /**
4918  * send_peer_rate_report_cmd_tlv() - process the peer rate report command
4919  * @wmi_handle: Pointer to wmi handle
4920  * @rate_report_params: Pointer to peer rate report parameters
4921  *
4922  *
4923  * Return: QDF_STATUS_SUCCESS for success otherwise failure
4924  */
4925 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle,
4926 	 struct wmi_peer_rate_report_params *rate_report_params)
4927 {
4928 	wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL;
4929 	wmi_buf_t buf = NULL;
4930 	QDF_STATUS status = 0;
4931 	uint32_t len = 0;
4932 	uint32_t i, j;
4933 
4934 	len = sizeof(*cmd);
4935 
4936 	buf = wmi_buf_alloc(wmi_handle, len);
4937 	if (!buf) {
4938 		WMI_LOGE("Failed to alloc buf to peer_set_condition cmd\n");
4939 		return QDF_STATUS_E_FAILURE;
4940 	}
4941 
4942 	cmd = (wmi_peer_set_rate_report_condition_fixed_param *)
4943 		wmi_buf_data(buf);
4944 
4945 	WMITLV_SET_HDR(
4946 	&cmd->tlv_header,
4947 	WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param,
4948 	WMITLV_GET_STRUCT_TLVLEN(
4949 		wmi_peer_set_rate_report_condition_fixed_param));
4950 
4951 	cmd->enable_rate_report  = rate_report_params->rate_report_enable;
4952 	cmd->report_backoff_time = rate_report_params->backoff_time;
4953 	cmd->report_timer_period = rate_report_params->timer_period;
4954 	for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) {
4955 		cmd->cond_per_phy[i].val_cond_flags        =
4956 			rate_report_params->report_per_phy[i].cond_flags;
4957 		cmd->cond_per_phy[i].rate_delta.min_delta  =
4958 			rate_report_params->report_per_phy[i].delta.delta_min;
4959 		cmd->cond_per_phy[i].rate_delta.percentage =
4960 			rate_report_params->report_per_phy[i].delta.percent;
4961 		for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) {
4962 			cmd->cond_per_phy[i].rate_threshold[j] =
4963 			rate_report_params->report_per_phy[i].
4964 						report_rate_threshold[j];
4965 		}
4966 	}
4967 
4968 	WMI_LOGE("%s enable %d backoff_time %d period %d\n", __func__,
4969 		 cmd->enable_rate_report,
4970 		 cmd->report_backoff_time, cmd->report_timer_period);
4971 
4972 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
4973 			WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID);
4974 	if (QDF_IS_STATUS_ERROR(status)) {
4975 		wmi_buf_free(buf);
4976 		WMI_LOGE("%s:Failed to send peer_set_report_cond command",
4977 			 __func__);
4978 	}
4979 	return status;
4980 }
4981 
4982 /**
4983  * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL
4984  * @wmi_handle: wmi handle
4985  * @param: bcn ll cmd parameter
4986  *
4987  * Return: QDF_STATUS_SUCCESS for success otherwise failure
4988  */
4989 static QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle,
4990 			wmi_bcn_send_from_host_cmd_fixed_param *param)
4991 {
4992 	wmi_bcn_send_from_host_cmd_fixed_param *cmd;
4993 	wmi_buf_t wmi_buf;
4994 	QDF_STATUS ret;
4995 
4996 	wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
4997 	if (!wmi_buf) {
4998 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
4999 		return QDF_STATUS_E_FAILURE;
5000 	}
5001 
5002 	cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf);
5003 	WMITLV_SET_HDR(&cmd->tlv_header,
5004 		       WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param,
5005 		       WMITLV_GET_STRUCT_TLVLEN
5006 			       (wmi_bcn_send_from_host_cmd_fixed_param));
5007 	cmd->vdev_id = param->vdev_id;
5008 	cmd->data_len = param->data_len;
5009 	cmd->frame_ctrl = param->frame_ctrl;
5010 	cmd->frag_ptr = param->frag_ptr;
5011 	cmd->dtim_flag = param->dtim_flag;
5012 
5013 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd),
5014 				      WMI_PDEV_SEND_BCN_CMDID);
5015 
5016 	if (QDF_IS_STATUS_ERROR(ret)) {
5017 		WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command");
5018 		wmi_buf_free(wmi_buf);
5019 	}
5020 
5021 	return ret;
5022 }
5023 
5024 /**
5025  * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters
5026  * @wmi_handle: wmi handle
5027  * @vdev_id: vdev id
5028  * @max_retries: max retries
5029  * @retry_interval: retry interval
5030  * This function sets sta query related parameters in fw.
5031  *
5032  * Return: QDF_STATUS_SUCCESS for success otherwise failure
5033  */
5034 
5035 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle,
5036 				       uint8_t vdev_id, uint32_t max_retries,
5037 					   uint32_t retry_interval)
5038 {
5039 	wmi_buf_t buf;
5040 	WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd;
5041 	int len;
5042 
5043 	len = sizeof(*cmd);
5044 	buf = wmi_buf_alloc(wmi_handle, len);
5045 	if (!buf) {
5046 		WMI_LOGE(FL("wmi_buf_alloc failed"));
5047 		return QDF_STATUS_E_FAILURE;
5048 	}
5049 
5050 	cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf);
5051 	WMITLV_SET_HDR(&cmd->tlv_header,
5052 		WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param,
5053 		WMITLV_GET_STRUCT_TLVLEN
5054 		(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param));
5055 
5056 
5057 	cmd->vdev_id = vdev_id;
5058 	cmd->sa_query_max_retry_count = max_retries;
5059 	cmd->sa_query_retry_interval = retry_interval;
5060 
5061 	WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"),
5062 		 vdev_id, retry_interval, max_retries);
5063 
5064 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
5065 				 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) {
5066 		WMI_LOGE(FL("Failed to offload STA SA Query"));
5067 		wmi_buf_free(buf);
5068 		return QDF_STATUS_E_FAILURE;
5069 	}
5070 
5071 	WMI_LOGD(FL("Exit :"));
5072 	return 0;
5073 }
5074 
5075 /**
5076  * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters
5077  * @wmi_handle: wmi handle
5078  * @params: sta keep alive parameter
5079  *
5080  * This function sets keep alive related parameters in fw.
5081  *
5082  * Return: CDF status
5083  */
5084 static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle,
5085 				struct sta_params *params)
5086 {
5087 	wmi_buf_t buf;
5088 	WMI_STA_KEEPALIVE_CMD_fixed_param *cmd;
5089 	WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp;
5090 	uint8_t *buf_ptr;
5091 	int len;
5092 	QDF_STATUS ret;
5093 
5094 	WMI_LOGD("%s: Enter", __func__);
5095 
5096 	len = sizeof(*cmd) + sizeof(*arp_rsp);
5097 	buf = wmi_buf_alloc(wmi_handle, len);
5098 	if (!buf) {
5099 		WMI_LOGE("wmi_buf_alloc failed");
5100 		return QDF_STATUS_E_FAILURE;
5101 	}
5102 
5103 	cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf);
5104 	buf_ptr = (uint8_t *) cmd;
5105 	WMITLV_SET_HDR(&cmd->tlv_header,
5106 		       WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param,
5107 		       WMITLV_GET_STRUCT_TLVLEN
5108 			       (WMI_STA_KEEPALIVE_CMD_fixed_param));
5109 	cmd->interval = params->timeperiod;
5110 	cmd->enable = (params->timeperiod) ? 1 : 0;
5111 	cmd->vdev_id = params->vdev_id;
5112 	WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id,
5113 		 params->timeperiod, params->method);
5114 	arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd));
5115 	WMITLV_SET_HDR(&arp_rsp->tlv_header,
5116 		       WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE,
5117 		       WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE));
5118 
5119 	if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) ||
5120 	    (params->method ==
5121 	     WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) {
5122 		if ((NULL == params->hostv4addr) ||
5123 			(NULL == params->destv4addr) ||
5124 			(NULL == params->destmac)) {
5125 			WMI_LOGE("%s: received null pointer, hostv4addr:%pK "
5126 			   "destv4addr:%pK destmac:%pK ", __func__,
5127 			   params->hostv4addr, params->destv4addr, params->destmac);
5128 			wmi_buf_free(buf);
5129 			return QDF_STATUS_E_FAILURE;
5130 		}
5131 		cmd->method = params->method;
5132 		qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr,
5133 			     WMI_IPV4_ADDR_LEN);
5134 		qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr,
5135 			     WMI_IPV4_ADDR_LEN);
5136 		WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr);
5137 	} else {
5138 		cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
5139 	}
5140 
5141 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5142 				 WMI_STA_KEEPALIVE_CMDID);
5143 	if (QDF_IS_STATUS_ERROR(ret)) {
5144 		WMI_LOGE("Failed to set KeepAlive");
5145 		wmi_buf_free(buf);
5146 	}
5147 
5148 	WMI_LOGD("%s: Exit", __func__);
5149 	return ret;
5150 }
5151 
5152 /**
5153  * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params
5154  * @wmi_handle: wmi handle
5155  * @if_id: vdev id
5156  * @gtx_info: GTX config params
5157  *
5158  * This function set GTX related params in firmware.
5159  *
5160  * Return: QDF_STATUS_SUCCESS for success or error code
5161  */
5162 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id,
5163 				  struct wmi_gtx_config *gtx_info)
5164 {
5165 	wmi_vdev_set_gtx_params_cmd_fixed_param *cmd;
5166 	wmi_buf_t buf;
5167 	QDF_STATUS ret;
5168 	int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param);
5169 
5170 	buf = wmi_buf_alloc(wmi_handle, len);
5171 	if (!buf) {
5172 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
5173 		return QDF_STATUS_E_NOMEM;
5174 	}
5175 	cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf);
5176 	WMITLV_SET_HDR(&cmd->tlv_header,
5177 		       WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param,
5178 		       WMITLV_GET_STRUCT_TLVLEN
5179 			       (wmi_vdev_set_gtx_params_cmd_fixed_param));
5180 	cmd->vdev_id = if_id;
5181 
5182 	cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0];
5183 	cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1];
5184 	cmd->userGtxMask = gtx_info->gtx_usrcfg;
5185 	cmd->gtxPERThreshold = gtx_info->gtx_threshold;
5186 	cmd->gtxPERMargin = gtx_info->gtx_margin;
5187 	cmd->gtxTPCstep = gtx_info->gtx_tpcstep;
5188 	cmd->gtxTPCMin = gtx_info->gtx_tpcmin;
5189 	cmd->gtxBWMask = gtx_info->gtx_bwmask;
5190 
5191 	WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \
5192 		gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \
5193 		gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1],
5194 		 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin,
5195 		 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask);
5196 
5197 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5198 				    WMI_VDEV_SET_GTX_PARAMS_CMDID);
5199 	if (QDF_IS_STATUS_ERROR(ret)) {
5200 		WMI_LOGE("Failed to set GTX PARAMS");
5201 		wmi_buf_free(buf);
5202 	}
5203 	return ret;
5204 }
5205 
5206 /**
5207  * send_process_update_edca_param_cmd_tlv() - update EDCA params
5208  * @wmi_handle: wmi handle
5209  * @vdev_id: vdev id.
5210  * @wmm_vparams: edca parameters
5211  *
5212  * This function updates EDCA parameters to the target
5213  *
5214  * Return: CDF Status
5215  */
5216 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle,
5217 				    uint8_t vdev_id,
5218 				    struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC])
5219 {
5220 	uint8_t *buf_ptr;
5221 	wmi_buf_t buf;
5222 	wmi_vdev_set_wmm_params_cmd_fixed_param *cmd;
5223 	wmi_wmm_vparams *wmm_param;
5224 	struct wmi_host_wme_vparams *twmm_param;
5225 	int len = sizeof(*cmd);
5226 	int ac;
5227 
5228 	buf = wmi_buf_alloc(wmi_handle, len);
5229 
5230 	if (!buf) {
5231 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
5232 		return QDF_STATUS_E_NOMEM;
5233 	}
5234 
5235 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
5236 	cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr;
5237 	WMITLV_SET_HDR(&cmd->tlv_header,
5238 		       WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param,
5239 		       WMITLV_GET_STRUCT_TLVLEN
5240 			       (wmi_vdev_set_wmm_params_cmd_fixed_param));
5241 	cmd->vdev_id = vdev_id;
5242 
5243 	for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) {
5244 		wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]);
5245 		twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]);
5246 		WMITLV_SET_HDR(&wmm_param->tlv_header,
5247 			       WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param,
5248 			       WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams));
5249 		wmm_param->cwmin = twmm_param->cwmin;
5250 		wmm_param->cwmax = twmm_param->cwmax;
5251 		wmm_param->aifs = twmm_param->aifs;
5252 		wmm_param->txoplimit = twmm_param->txoplimit;
5253 		wmm_param->acm = twmm_param->acm;
5254 		wmm_param->no_ack = twmm_param->noackpolicy;
5255 	}
5256 
5257 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
5258 				 WMI_VDEV_SET_WMM_PARAMS_CMDID))
5259 		goto fail;
5260 
5261 	return QDF_STATUS_SUCCESS;
5262 
5263 fail:
5264 	wmi_buf_free(buf);
5265 	WMI_LOGE("%s: Failed to set WMM Paremeters", __func__);
5266 	return QDF_STATUS_E_FAILURE;
5267 }
5268 
5269 /**
5270  * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw
5271  * @wmi_handle: wmi handle
5272  * @vdev_id: vdev id
5273  * @probe_rsp_info: probe response info
5274  *
5275  * Return: QDF_STATUS_SUCCESS for success or error code
5276  */
5277 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle,
5278 				   uint8_t vdev_id,
5279 				   struct wmi_probe_resp_params *probe_rsp_info)
5280 {
5281 	wmi_prb_tmpl_cmd_fixed_param *cmd;
5282 	wmi_bcn_prb_info *bcn_prb_info;
5283 	wmi_buf_t wmi_buf;
5284 	uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len;
5285 	uint8_t *buf_ptr;
5286 	QDF_STATUS ret;
5287 
5288 	WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id);
5289 
5290 	tmpl_len = probe_rsp_info->prb_rsp_template_len;
5291 	tmpl_len_aligned = roundup(tmpl_len, sizeof(A_UINT32));
5292 
5293 	wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) +
5294 			sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE +
5295 			tmpl_len_aligned;
5296 
5297 	if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) {
5298 		WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"),
5299 		wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE);
5300 		return QDF_STATUS_E_INVAL;
5301 	}
5302 
5303 	wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
5304 	if (!wmi_buf) {
5305 		WMI_LOGE(FL("wmi_buf_alloc failed"));
5306 		return QDF_STATUS_E_NOMEM;
5307 	}
5308 
5309 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
5310 
5311 	cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr;
5312 	WMITLV_SET_HDR(&cmd->tlv_header,
5313 		       WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param,
5314 		       WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param));
5315 	cmd->vdev_id = vdev_id;
5316 	cmd->buf_len = tmpl_len;
5317 	buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param);
5318 
5319 	bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr;
5320 	WMITLV_SET_HDR(&bcn_prb_info->tlv_header,
5321 		       WMITLV_TAG_STRUC_wmi_bcn_prb_info,
5322 		       WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info));
5323 	bcn_prb_info->caps = 0;
5324 	bcn_prb_info->erp = 0;
5325 	buf_ptr += sizeof(wmi_bcn_prb_info);
5326 
5327 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned);
5328 	buf_ptr += WMI_TLV_HDR_SIZE;
5329 	qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len);
5330 
5331 	ret = wmi_unified_cmd_send(wmi_handle,
5332 				   wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID);
5333 	if (QDF_IS_STATUS_ERROR(ret)) {
5334 		WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret);
5335 		wmi_buf_free(wmi_buf);
5336 	}
5337 
5338 	return ret;
5339 }
5340 
5341 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI)
5342 #define WPI_IV_LEN 16
5343 
5344 /**
5345  * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters
5346  *
5347  * @dest_tx: destination address of tsc key counter
5348  * @src_tx: source address of tsc key counter
5349  * @dest_rx: destination address of rsc key counter
5350  * @src_rx: source address of rsc key counter
5351  *
5352  * This function copies WAPI tsc and rsc key counters in the wmi buffer.
5353  *
5354  * Return: None
5355  *
5356  */
5357 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx,
5358 					uint8_t *dest_rx, uint8_t *src_rx)
5359 {
5360 	qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN);
5361 	qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN);
5362 }
5363 #else
5364 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx,
5365 					uint8_t *dest_rx, uint8_t *src_rx)
5366 {
5367 	return;
5368 }
5369 #endif
5370 
5371 /**
5372  * send_setup_install_key_cmd_tlv() - set key parameters
5373  * @wmi_handle: wmi handle
5374  * @key_params: key parameters
5375  *
5376  * This function fills structure from information
5377  * passed in key_params.
5378  *
5379  * Return: QDF_STATUS_SUCCESS - success
5380  *         QDF_STATUS_E_FAILURE - failure
5381  *         QDF_STATUS_E_NOMEM - not able to allocate buffer
5382  */
5383 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle,
5384 					   struct set_key_params *key_params)
5385 {
5386 	wmi_vdev_install_key_cmd_fixed_param *cmd;
5387 	wmi_buf_t buf;
5388 	uint8_t *buf_ptr;
5389 	uint32_t len;
5390 	uint8_t *key_data;
5391 	QDF_STATUS status;
5392 
5393 	len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) +
5394 	       WMI_TLV_HDR_SIZE;
5395 
5396 	buf = wmi_buf_alloc(wmi_handle, len);
5397 	if (!buf) {
5398 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
5399 		return QDF_STATUS_E_NOMEM;
5400 	}
5401 
5402 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
5403 	cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr;
5404 	WMITLV_SET_HDR(&cmd->tlv_header,
5405 		       WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param,
5406 		       WMITLV_GET_STRUCT_TLVLEN
5407 			       (wmi_vdev_install_key_cmd_fixed_param));
5408 	cmd->vdev_id = key_params->vdev_id;
5409 	cmd->key_ix = key_params->key_idx;
5410 
5411 
5412 	WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr);
5413 	cmd->key_flags |= key_params->key_flags;
5414 	cmd->key_cipher = key_params->key_cipher;
5415 	if ((key_params->key_txmic_len) &&
5416 			(key_params->key_rxmic_len)) {
5417 		cmd->key_txmic_len = key_params->key_txmic_len;
5418 		cmd->key_rxmic_len = key_params->key_rxmic_len;
5419 	}
5420 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI)
5421 	wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter,
5422 				   key_params->tx_iv,
5423 				   cmd->wpi_key_rsc_counter,
5424 				   key_params->rx_iv);
5425 #endif
5426 	buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param);
5427 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5428 		       roundup(key_params->key_len, sizeof(uint32_t)));
5429 	key_data = (A_UINT8 *) (buf_ptr + WMI_TLV_HDR_SIZE);
5430 	qdf_mem_copy((void *)key_data,
5431 		     (const void *)key_params->key_data, key_params->key_len);
5432 	if (key_params->key_rsc_counter)
5433 	    qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter,
5434 			 sizeof(wmi_key_seq_counter));
5435 	cmd->key_len = key_params->key_len;
5436 
5437 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
5438 					      WMI_VDEV_INSTALL_KEY_CMDID);
5439 	if (QDF_IS_STATUS_ERROR(status))
5440 		wmi_buf_free(buf);
5441 
5442 	return status;
5443 }
5444 
5445 /**
5446  * send_sar_limit_cmd_tlv() - send sar limit cmd to fw
5447  * @wmi_handle: wmi handle
5448  * @params: sar limit params
5449  *
5450  * Return: QDF_STATUS_SUCCESS for success or error code
5451  */
5452 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle,
5453 		struct sar_limit_cmd_params *sar_limit_params)
5454 {
5455 	wmi_buf_t buf;
5456 	QDF_STATUS qdf_status;
5457 	wmi_sar_limits_cmd_fixed_param *cmd;
5458 	int i;
5459 	uint8_t *buf_ptr;
5460 	wmi_sar_limit_cmd_row *wmi_sar_rows_list;
5461 	struct sar_limit_cmd_row *sar_rows_list;
5462 	uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
5463 
5464 	len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows;
5465 	buf = wmi_buf_alloc(wmi_handle, len);
5466 	if (!buf) {
5467 		WMI_LOGE("Failed to allocate memory");
5468 		qdf_status = QDF_STATUS_E_NOMEM;
5469 		goto end;
5470 	}
5471 
5472 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
5473 	cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr;
5474 	WMITLV_SET_HDR(&cmd->tlv_header,
5475 		       WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param,
5476 		       WMITLV_GET_STRUCT_TLVLEN
5477 		       (wmi_sar_limits_cmd_fixed_param));
5478 	cmd->sar_enable = sar_limit_params->sar_enable;
5479 	cmd->commit_limits = sar_limit_params->commit_limits;
5480 	cmd->num_limit_rows = sar_limit_params->num_limit_rows;
5481 
5482 	WMI_LOGD("no of sar rows = %d, len = %d",
5483 		 sar_limit_params->num_limit_rows, len);
5484 	buf_ptr += sizeof(*cmd);
5485 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5486 		       sizeof(wmi_sar_limit_cmd_row) *
5487 			       sar_limit_params->num_limit_rows);
5488 	if (cmd->num_limit_rows == 0)
5489 		goto send_sar_limits;
5490 
5491 	wmi_sar_rows_list = (wmi_sar_limit_cmd_row *)
5492 			(buf_ptr + WMI_TLV_HDR_SIZE);
5493 	sar_rows_list = sar_limit_params->sar_limit_row_list;
5494 
5495 	for (i = 0; i < sar_limit_params->num_limit_rows; i++) {
5496 		WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header,
5497 			       WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row,
5498 			       WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row));
5499 		wmi_sar_rows_list->band_id = sar_rows_list->band_id;
5500 		wmi_sar_rows_list->chain_id = sar_rows_list->chain_id;
5501 		wmi_sar_rows_list->mod_id = sar_rows_list->mod_id;
5502 		wmi_sar_rows_list->limit_value = sar_rows_list->limit_value;
5503 		wmi_sar_rows_list->validity_bitmap =
5504 						sar_rows_list->validity_bitmap;
5505 		WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d",
5506 			 i, wmi_sar_rows_list->band_id,
5507 			 wmi_sar_rows_list->chain_id,
5508 			 wmi_sar_rows_list->mod_id,
5509 			 wmi_sar_rows_list->limit_value,
5510 			 wmi_sar_rows_list->validity_bitmap);
5511 		sar_rows_list++;
5512 		wmi_sar_rows_list++;
5513 	}
5514 send_sar_limits:
5515 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
5516 				      WMI_SAR_LIMITS_CMDID);
5517 
5518 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
5519 		WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID");
5520 		wmi_buf_free(buf);
5521 	}
5522 
5523 end:
5524 	return qdf_status;
5525 }
5526 
5527 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle)
5528 {
5529 	wmi_sar_get_limits_cmd_fixed_param *cmd;
5530 	wmi_buf_t wmi_buf;
5531 	uint32_t len;
5532 	QDF_STATUS status;
5533 
5534 	WMI_LOGD(FL("Enter"));
5535 
5536 	len = sizeof(*cmd);
5537 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
5538 	if (!wmi_buf) {
5539 		WMI_LOGP(FL("failed to allocate memory for msg"));
5540 		return QDF_STATUS_E_NOMEM;
5541 	}
5542 
5543 	cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf);
5544 
5545 	WMITLV_SET_HDR(&cmd->tlv_header,
5546 		       WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param,
5547 		       WMITLV_GET_STRUCT_TLVLEN
5548 				(wmi_sar_get_limits_cmd_fixed_param));
5549 
5550 	cmd->reserved = 0;
5551 
5552 	status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
5553 				      WMI_SAR_GET_LIMITS_CMDID);
5554 	if (QDF_IS_STATUS_ERROR(status)) {
5555 		WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status);
5556 		wmi_buf_free(wmi_buf);
5557 	}
5558 
5559 	WMI_LOGD(FL("Exit"));
5560 
5561 	return status;
5562 }
5563 
5564 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle,
5565 					      uint8_t *evt_buf,
5566 					      struct sar_limit_event *event)
5567 {
5568 	wmi_sar_get_limits_event_fixed_param *fixed_param;
5569 	WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf;
5570 	wmi_sar_get_limit_event_row *row_in;
5571 	struct sar_limit_event_row *row_out;
5572 	uint32_t row;
5573 
5574 	if (!evt_buf) {
5575 		WMI_LOGE(FL("input event is NULL"));
5576 		return QDF_STATUS_E_INVAL;
5577 	}
5578 	if (!event) {
5579 		WMI_LOGE(FL("output event is NULL"));
5580 		return QDF_STATUS_E_INVAL;
5581 	}
5582 
5583 	param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf;
5584 
5585 	fixed_param = param_buf->fixed_param;
5586 	if (!fixed_param) {
5587 		WMI_LOGE(FL("Invalid fixed param"));
5588 		return QDF_STATUS_E_INVAL;
5589 	}
5590 
5591 	event->sar_enable = fixed_param->sar_enable;
5592 	event->num_limit_rows = fixed_param->num_limit_rows;
5593 
5594 	if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) {
5595 		QDF_ASSERT(0);
5596 		WMI_LOGE(FL("Num rows %d exceeds max of %d"),
5597 			 event->num_limit_rows,
5598 			 MAX_SAR_LIMIT_ROWS_SUPPORTED);
5599 		event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED;
5600 	}
5601 
5602 	row_in = param_buf->sar_get_limits;
5603 	row_out = &event->sar_limit_row[0];
5604 	for (row = 0; row < event->num_limit_rows; row++) {
5605 		row_out->band_id = row_in->band_id;
5606 		row_out->chain_id = row_in->chain_id;
5607 		row_out->mod_id = row_in->mod_id;
5608 		row_out->limit_value = row_in->limit_value;
5609 		row_out++;
5610 		row_in++;
5611 	}
5612 
5613 	return QDF_STATUS_SUCCESS;
5614 }
5615 
5616 #ifdef WLAN_FEATURE_DISA
5617 /**
5618  * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw
5619  * @wmi_handle: wmi handle
5620  * @params: encrypt/decrypt params
5621  *
5622  * Return: QDF_STATUS_SUCCESS for success or error code
5623  */
5624 static
5625 QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle,
5626 		struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params)
5627 {
5628 	wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd;
5629 	wmi_buf_t wmi_buf;
5630 	uint8_t *buf_ptr;
5631 	QDF_STATUS ret;
5632 	uint32_t len;
5633 
5634 	WMI_LOGD(FL("Send encrypt decrypt cmd"));
5635 
5636 	len = sizeof(*cmd) +
5637 		roundup(encrypt_decrypt_params->data_len, sizeof(A_UINT32)) +
5638 		WMI_TLV_HDR_SIZE;
5639 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
5640 	if (!wmi_buf) {
5641 		WMI_LOGP("%s: failed to allocate memory for encrypt/decrypt msg",
5642 			 __func__);
5643 		return QDF_STATUS_E_NOMEM;
5644 	}
5645 
5646 	buf_ptr = wmi_buf_data(wmi_buf);
5647 	cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr;
5648 
5649 	WMITLV_SET_HDR(&cmd->tlv_header,
5650 		WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param,
5651 		WMITLV_GET_STRUCT_TLVLEN(
5652 			wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param));
5653 
5654 	cmd->vdev_id = encrypt_decrypt_params->vdev_id;
5655 	cmd->key_flag = encrypt_decrypt_params->key_flag;
5656 	cmd->key_idx = encrypt_decrypt_params->key_idx;
5657 	cmd->key_cipher = encrypt_decrypt_params->key_cipher;
5658 	cmd->key_len = encrypt_decrypt_params->key_len;
5659 	cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len;
5660 	cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len;
5661 
5662 	qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data,
5663 				encrypt_decrypt_params->key_len);
5664 
5665 	qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header,
5666 				MAX_MAC_HEADER_LEN);
5667 
5668 	cmd->data_len = encrypt_decrypt_params->data_len;
5669 
5670 	if (cmd->data_len) {
5671 		buf_ptr += sizeof(*cmd);
5672 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5673 				roundup(encrypt_decrypt_params->data_len,
5674 					sizeof(A_UINT32)));
5675 		buf_ptr += WMI_TLV_HDR_SIZE;
5676 		qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data,
5677 					encrypt_decrypt_params->data_len);
5678 	}
5679 
5680 	/* This conversion is to facilitate data to FW in little endian */
5681 	cmd->pn[5] = encrypt_decrypt_params->pn[0];
5682 	cmd->pn[4] = encrypt_decrypt_params->pn[1];
5683 	cmd->pn[3] = encrypt_decrypt_params->pn[2];
5684 	cmd->pn[2] = encrypt_decrypt_params->pn[3];
5685 	cmd->pn[1] = encrypt_decrypt_params->pn[4];
5686 	cmd->pn[0] = encrypt_decrypt_params->pn[5];
5687 
5688 	ret = wmi_unified_cmd_send(wmi_handle,
5689 				   wmi_buf, len,
5690 				   WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID);
5691 	if (QDF_IS_STATUS_ERROR(ret)) {
5692 		WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret);
5693 		wmi_buf_free(wmi_buf);
5694 	}
5695 
5696 	return ret;
5697 }
5698 
5699 /**
5700  * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp
5701  *	params from event
5702  * @wmi_handle: wmi handle
5703  * @evt_buf: pointer to event buffer
5704  * @resp: Pointer to hold resp parameters
5705  *
5706  * Return: QDF_STATUS_SUCCESS for success or error code
5707  */
5708 static
5709 QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle,
5710 	void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp)
5711 {
5712 	WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf;
5713 	wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event;
5714 
5715 	param_buf = evt_buf;
5716 	if (!param_buf) {
5717 		WMI_LOGE("encrypt decrypt resp evt_buf is NULL");
5718 		return QDF_STATUS_E_INVAL;
5719 	}
5720 
5721 	data_event = param_buf->fixed_param;
5722 
5723 	resp->vdev_id = data_event->vdev_id;
5724 	resp->status = data_event->status;
5725 
5726 	if (data_event->data_length > param_buf->num_enc80211_frame) {
5727 		WMI_LOGE("FW msg data_len %d more than TLV hdr %d",
5728 			 data_event->data_length,
5729 			 param_buf->num_enc80211_frame);
5730 		return QDF_STATUS_E_INVAL;
5731 	}
5732 
5733 	resp->data_len = data_event->data_length;
5734 
5735 	if (resp->data_len)
5736 		resp->data = (uint8_t *)param_buf->enc80211_frame;
5737 
5738 	return QDF_STATUS_SUCCESS;
5739 }
5740 #endif
5741 
5742 /**
5743  * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go
5744  * @wmi_handle: wmi handle
5745  * @vdev_id: vdev id
5746  * @p2p_ie: p2p IE
5747  *
5748  * Return: QDF_STATUS_SUCCESS for success or error code
5749  */
5750 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle,
5751 				    A_UINT32 vdev_id, uint8_t *p2p_ie)
5752 {
5753 	QDF_STATUS ret;
5754 	wmi_p2p_go_set_beacon_ie_fixed_param *cmd;
5755 	wmi_buf_t wmi_buf;
5756 	uint32_t ie_len, ie_len_aligned, wmi_buf_len;
5757 	uint8_t *buf_ptr;
5758 
5759 	ie_len = (uint32_t) (p2p_ie[1] + 2);
5760 
5761 	/* More than one P2P IE may be included in a single frame.
5762 	   If multiple P2P IEs are present, the complete P2P attribute
5763 	   data consists of the concatenation of the P2P Attribute
5764 	   fields of the P2P IEs. The P2P Attributes field of each
5765 	   P2P IE may be any length up to the maximum (251 octets).
5766 	   In this case host sends one P2P IE to firmware so the length
5767 	   should not exceed more than 251 bytes
5768 	 */
5769 	if (ie_len > 251) {
5770 		WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len);
5771 		return QDF_STATUS_E_INVAL;
5772 	}
5773 
5774 	ie_len_aligned = roundup(ie_len, sizeof(A_UINT32));
5775 
5776 	wmi_buf_len =
5777 		sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned +
5778 		WMI_TLV_HDR_SIZE;
5779 
5780 	wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
5781 	if (!wmi_buf) {
5782 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
5783 		return QDF_STATUS_E_NOMEM;
5784 	}
5785 
5786 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
5787 
5788 	cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr;
5789 	WMITLV_SET_HDR(&cmd->tlv_header,
5790 		       WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param,
5791 		       WMITLV_GET_STRUCT_TLVLEN
5792 			       (wmi_p2p_go_set_beacon_ie_fixed_param));
5793 	cmd->vdev_id = vdev_id;
5794 	cmd->ie_buf_len = ie_len;
5795 
5796 	buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param);
5797 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
5798 	buf_ptr += WMI_TLV_HDR_SIZE;
5799 	qdf_mem_copy(buf_ptr, p2p_ie, ie_len);
5800 
5801 	WMI_LOGI("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__);
5802 
5803 	ret = wmi_unified_cmd_send(wmi_handle,
5804 				   wmi_buf, wmi_buf_len,
5805 				   WMI_P2P_GO_SET_BEACON_IE);
5806 	if (QDF_IS_STATUS_ERROR(ret)) {
5807 		WMI_LOGE("Failed to send bcn tmpl: %d", ret);
5808 		wmi_buf_free(wmi_buf);
5809 	}
5810 
5811 	WMI_LOGI("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__);
5812 	return ret;
5813 }
5814 
5815 /**
5816  * send_set_gateway_params_cmd_tlv() - set gateway parameters
5817  * @wmi_handle: wmi handle
5818  * @req: gateway parameter update request structure
5819  *
5820  * This function reads the incoming @req and fill in the destination
5821  * WMI structure and sends down the gateway configs down to the firmware
5822  *
5823  * Return: QDF_STATUS
5824  */
5825 static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle,
5826 				struct gateway_update_req_param *req)
5827 {
5828 	wmi_roam_subnet_change_config_fixed_param *cmd;
5829 	wmi_buf_t buf;
5830 	QDF_STATUS ret;
5831 	int len = sizeof(*cmd);
5832 
5833 	buf = wmi_buf_alloc(wmi_handle, len);
5834 	if (!buf) {
5835 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
5836 		return QDF_STATUS_E_NOMEM;
5837 	}
5838 
5839 	cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf);
5840 	WMITLV_SET_HDR(&cmd->tlv_header,
5841 		WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param,
5842 		WMITLV_GET_STRUCT_TLVLEN(
5843 			wmi_roam_subnet_change_config_fixed_param));
5844 
5845 	cmd->vdev_id = req->session_id;
5846 	qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr,
5847 		QDF_IPV4_ADDR_SIZE);
5848 	qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr,
5849 		QDF_IPV6_ADDR_SIZE);
5850 	WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes,
5851 		&cmd->inet_gw_mac_addr);
5852 	cmd->max_retries = req->max_retries;
5853 	cmd->timeout = req->timeout;
5854 	cmd->num_skip_subnet_change_detection_bssid_list = 0;
5855 	cmd->flag = 0;
5856 	if (req->ipv4_addr_type)
5857 		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag);
5858 
5859 	if (req->ipv6_addr_type)
5860 		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag);
5861 
5862 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5863 				WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID);
5864 	if (QDF_IS_STATUS_ERROR(ret)) {
5865 		WMI_LOGE("Failed to send gw config parameter to fw, ret: %d",
5866 			ret);
5867 		wmi_buf_free(buf);
5868 	}
5869 
5870 	return ret;
5871 }
5872 
5873 /**
5874  * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring
5875  * @wmi_handle: wmi handle
5876  * @req: rssi monitoring request structure
5877  *
5878  * This function reads the incoming @req and fill in the destination
5879  * WMI structure and send down the rssi monitoring configs down to the firmware
5880  *
5881  * Return: 0 on success; error number otherwise
5882  */
5883 static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle,
5884 					struct rssi_monitor_param *req)
5885 {
5886 	wmi_rssi_breach_monitor_config_fixed_param *cmd;
5887 	wmi_buf_t buf;
5888 	QDF_STATUS ret;
5889 	uint32_t len = sizeof(*cmd);
5890 
5891 	buf = wmi_buf_alloc(wmi_handle, len);
5892 	if (!buf) {
5893 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
5894 		return QDF_STATUS_E_NOMEM;
5895 	}
5896 
5897 	cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf);
5898 	WMITLV_SET_HDR(&cmd->tlv_header,
5899 		WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param,
5900 		WMITLV_GET_STRUCT_TLVLEN(
5901 			wmi_rssi_breach_monitor_config_fixed_param));
5902 
5903 	cmd->vdev_id = req->session_id;
5904 	cmd->request_id = req->request_id;
5905 	cmd->lo_rssi_reenable_hysteresis = 0;
5906 	cmd->hi_rssi_reenable_histeresis = 0;
5907 	cmd->min_report_interval = 0;
5908 	cmd->max_num_report = 1;
5909 	if (req->control) {
5910 		/* enable one threshold for each min/max */
5911 		cmd->enabled_bitmap = 0x09;
5912 		cmd->low_rssi_breach_threshold[0] = req->min_rssi;
5913 		cmd->hi_rssi_breach_threshold[0] = req->max_rssi;
5914 	} else {
5915 		cmd->enabled_bitmap = 0;
5916 		cmd->low_rssi_breach_threshold[0] = 0;
5917 		cmd->hi_rssi_breach_threshold[0] = 0;
5918 	}
5919 
5920 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5921 				   WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID);
5922 	if (QDF_IS_STATUS_ERROR(ret)) {
5923 		WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID");
5924 		wmi_buf_free(buf);
5925 	}
5926 
5927 	WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW");
5928 
5929 	return ret;
5930 }
5931 
5932 /**
5933  * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI
5934  * @wmi_handle: wmi handle
5935  * @psetoui: OUI parameters
5936  *
5937  * set scan probe OUI parameters in firmware
5938  *
5939  * Return: CDF status
5940  */
5941 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle,
5942 			  struct scan_mac_oui *psetoui)
5943 {
5944 	wmi_scan_prob_req_oui_cmd_fixed_param *cmd;
5945 	wmi_buf_t wmi_buf;
5946 	uint32_t len;
5947 	uint8_t *buf_ptr;
5948 	uint32_t *oui_buf;
5949 	struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist;
5950 
5951 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
5952 		ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui);
5953 
5954 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
5955 	if (!wmi_buf) {
5956 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
5957 		return QDF_STATUS_E_NOMEM;
5958 	}
5959 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
5960 	cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr;
5961 	WMITLV_SET_HDR(&cmd->tlv_header,
5962 		       WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param,
5963 		       WMITLV_GET_STRUCT_TLVLEN
5964 			       (wmi_scan_prob_req_oui_cmd_fixed_param));
5965 
5966 	oui_buf = &cmd->prob_req_oui;
5967 	qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui));
5968 	*oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8
5969 		   | psetoui->oui[2];
5970 	WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__,
5971 		 cmd->prob_req_oui);
5972 
5973 	cmd->vdev_id = psetoui->vdev_id;
5974 	cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ;
5975 	if (psetoui->enb_probe_req_sno_randomization)
5976 		cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ;
5977 
5978 	if (ie_whitelist->white_list) {
5979 		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
5980 					    &cmd->num_vendor_oui,
5981 					    ie_whitelist);
5982 		cmd->flags |=
5983 			WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ;
5984 	}
5985 
5986 	buf_ptr += sizeof(*cmd);
5987 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5988 		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
5989 	buf_ptr += WMI_TLV_HDR_SIZE;
5990 
5991 	if (cmd->num_vendor_oui != 0) {
5992 		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
5993 				    ie_whitelist->voui);
5994 		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
5995 	}
5996 
5997 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
5998 				 WMI_SCAN_PROB_REQ_OUI_CMDID)) {
5999 		WMI_LOGE("%s: failed to send command", __func__);
6000 		wmi_buf_free(wmi_buf);
6001 		return QDF_STATUS_E_FAILURE;
6002 	}
6003 	return QDF_STATUS_SUCCESS;
6004 }
6005 
6006 /**
6007  * send_reset_passpoint_network_list_cmd_tlv() - reset passpoint network list
6008  * @wmi_handle: wmi handle
6009  * @req: passpoint network request structure
6010  *
6011  * This function sends down WMI command with network id set to wildcard id.
6012  * firmware shall clear all the config entries
6013  *
6014  * Return: QDF_STATUS enumeration
6015  */
6016 static QDF_STATUS send_reset_passpoint_network_list_cmd_tlv(wmi_unified_t wmi_handle,
6017 					struct wifi_passpoint_req_param *req)
6018 {
6019 	wmi_passpoint_config_cmd_fixed_param *cmd;
6020 	wmi_buf_t buf;
6021 	uint32_t len;
6022 	int ret;
6023 
6024 	len = sizeof(*cmd);
6025 	buf = wmi_buf_alloc(wmi_handle, len);
6026 	if (!buf) {
6027 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
6028 		return QDF_STATUS_E_NOMEM;
6029 	}
6030 
6031 	cmd = (wmi_passpoint_config_cmd_fixed_param *) wmi_buf_data(buf);
6032 
6033 	WMITLV_SET_HDR(&cmd->tlv_header,
6034 			WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param,
6035 			WMITLV_GET_STRUCT_TLVLEN(
6036 			wmi_passpoint_config_cmd_fixed_param));
6037 	cmd->id = WMI_PASSPOINT_NETWORK_ID_WILDCARD;
6038 
6039 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6040 				   WMI_PASSPOINT_LIST_CONFIG_CMDID);
6041 	if (ret) {
6042 		WMI_LOGE("%s: Failed to send reset passpoint network list wmi cmd",
6043 			 __func__);
6044 		wmi_buf_free(buf);
6045 		return QDF_STATUS_E_FAILURE;
6046 	}
6047 
6048 	return QDF_STATUS_SUCCESS;
6049 }
6050 
6051 /**
6052  * send_set_passpoint_network_list_cmd_tlv() - set passpoint network list
6053  * @wmi_handle: wmi handle
6054  * @req: passpoint network request structure
6055  *
6056  * This function reads the incoming @req and fill in the destination
6057  * WMI structure and send down the passpoint configs down to the firmware
6058  *
6059  * Return: QDF_STATUS enumeration
6060  */
6061 static QDF_STATUS send_set_passpoint_network_list_cmd_tlv(wmi_unified_t wmi_handle,
6062 					struct wifi_passpoint_req_param *req)
6063 {
6064 	wmi_passpoint_config_cmd_fixed_param *cmd;
6065 	u_int8_t i, j, *bytes;
6066 	wmi_buf_t buf;
6067 	uint32_t len;
6068 	int ret;
6069 
6070 	len = sizeof(*cmd);
6071 	for (i = 0; i < req->num_networks; i++) {
6072 		buf = wmi_buf_alloc(wmi_handle, len);
6073 		if (!buf) {
6074 			WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
6075 			return QDF_STATUS_E_NOMEM;
6076 		}
6077 
6078 		cmd = (wmi_passpoint_config_cmd_fixed_param *)
6079 				wmi_buf_data(buf);
6080 
6081 		WMITLV_SET_HDR(&cmd->tlv_header,
6082 			WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param,
6083 			WMITLV_GET_STRUCT_TLVLEN(
6084 			wmi_passpoint_config_cmd_fixed_param));
6085 		cmd->id = req->networks[i].id;
6086 		WMI_LOGD("%s: network id: %u", __func__, cmd->id);
6087 		qdf_mem_copy(cmd->realm, req->networks[i].realm,
6088 			strlen(req->networks[i].realm) + 1);
6089 		WMI_LOGD("%s: realm: %s", __func__, cmd->realm);
6090 		for (j = 0; j < PASSPOINT_ROAMING_CONSORTIUM_ID_NUM; j++) {
6091 			bytes = (uint8_t *) &req->networks[i].roaming_consortium_ids[j];
6092 			WMI_LOGD("index: %d rcids: %02x %02x %02x %02x %02x %02x %02x %02x",
6093 				j, bytes[0], bytes[1], bytes[2], bytes[3],
6094 				bytes[4], bytes[5], bytes[6], bytes[7]);
6095 
6096 			qdf_mem_copy(&cmd->roaming_consortium_ids[j],
6097 				&req->networks[i].roaming_consortium_ids[j],
6098 				PASSPOINT_ROAMING_CONSORTIUM_ID_LEN);
6099 		}
6100 		qdf_mem_copy(cmd->plmn, req->networks[i].plmn,
6101 				PASSPOINT_PLMN_ID_LEN);
6102 		WMI_LOGD("%s: plmn: %02x:%02x:%02x", __func__,
6103 			cmd->plmn[0], cmd->plmn[1], cmd->plmn[2]);
6104 
6105 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6106 					   WMI_PASSPOINT_LIST_CONFIG_CMDID);
6107 		if (ret) {
6108 			WMI_LOGE("%s: Failed to send set passpoint network list wmi cmd",
6109 				 __func__);
6110 			wmi_buf_free(buf);
6111 			return QDF_STATUS_E_FAILURE;
6112 		}
6113 	}
6114 
6115 	return QDF_STATUS_SUCCESS;
6116 }
6117 
6118 #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
6119 /**
6120  * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command
6121  * @wmi_handle: wmi handle
6122  * @roam_req: Roam scan offload params
6123  * @buf_ptr: command buffer to send
6124  * @fils_tlv_len: fils tlv length
6125  *
6126  * Return: Updated buffer pointer
6127  */
6128 static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
6129 			     struct roam_offload_scan_params *roam_req,
6130 			     uint8_t *buf_ptr, uint32_t fils_tlv_len)
6131 {
6132 	wmi_roam_fils_offload_tlv_param *fils_tlv;
6133 	wmi_erp_info *erp_info;
6134 	struct roam_fils_params *roam_fils_params;
6135 
6136 	if (!roam_req->add_fils_tlv)
6137 		return buf_ptr;
6138 
6139 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6140 			sizeof(*fils_tlv));
6141 	buf_ptr += WMI_TLV_HDR_SIZE;
6142 
6143 	fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr;
6144 	WMITLV_SET_HDR(&fils_tlv->tlv_header,
6145 			WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param,
6146 			WMITLV_GET_STRUCT_TLVLEN
6147 				(wmi_roam_fils_offload_tlv_param));
6148 
6149 	roam_fils_params = &roam_req->roam_fils_params;
6150 	erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info);
6151 
6152 	erp_info->username_length = roam_fils_params->username_length;
6153 	qdf_mem_copy(erp_info->username, roam_fils_params->username,
6154 				erp_info->username_length);
6155 
6156 	erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num;
6157 
6158 	erp_info->rRk_length = roam_fils_params->rrk_length;
6159 	qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk,
6160 				erp_info->rRk_length);
6161 
6162 	erp_info->rIk_length = roam_fils_params->rik_length;
6163 	qdf_mem_copy(erp_info->rIk, roam_fils_params->rik,
6164 				erp_info->rIk_length);
6165 
6166 	erp_info->realm_len = roam_fils_params->realm_len;
6167 	qdf_mem_copy(erp_info->realm, roam_fils_params->realm,
6168 				erp_info->realm_len);
6169 
6170 	buf_ptr += sizeof(*fils_tlv);
6171 	return buf_ptr;
6172 }
6173 #else
6174 static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
6175 				struct roam_offload_scan_params *roam_req,
6176 				uint8_t *buf_ptr, uint32_t fils_tlv_len)
6177 {
6178 	return buf_ptr;
6179 }
6180 #endif
6181 /**
6182  * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw
6183  * @wmi_handle: wmi handle
6184  * @scan_cmd_fp: start scan command ptr
6185  * @roam_req: roam request param
6186  *
6187  * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
6188  * of WMI_ROAM_SCAN_MODE.
6189  *
6190  * Return: QDF status
6191  */
6192 static QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle,
6193 				      wmi_start_scan_cmd_fixed_param *
6194 				      scan_cmd_fp,
6195 				      struct roam_offload_scan_params *roam_req)
6196 {
6197 	wmi_buf_t buf = NULL;
6198 	QDF_STATUS status;
6199 	int len;
6200 	uint8_t *buf_ptr;
6201 	wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp;
6202 
6203 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6204 	int auth_mode = roam_req->auth_mode;
6205 	wmi_roam_offload_tlv_param *roam_offload_params;
6206 	wmi_roam_11i_offload_tlv_param *roam_offload_11i;
6207 	wmi_roam_11r_offload_tlv_param *roam_offload_11r;
6208 	wmi_roam_ese_offload_tlv_param *roam_offload_ese;
6209 	wmi_tlv_buf_len_param *assoc_ies;
6210 	uint32_t fils_tlv_len = 0;
6211 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6212 	/* Need to create a buf with roam_scan command at
6213 	 * front and piggyback with scan command */
6214 	len = sizeof(wmi_roam_scan_mode_fixed_param) +
6215 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6216 	      (2 * WMI_TLV_HDR_SIZE) +
6217 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6218 	      sizeof(wmi_start_scan_cmd_fixed_param);
6219 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6220 	WMI_LOGD("auth_mode = %d", auth_mode);
6221 		if (roam_req->is_roam_req_valid &&
6222 				roam_req->roam_offload_enabled) {
6223 			len += sizeof(wmi_roam_offload_tlv_param);
6224 			len += WMI_TLV_HDR_SIZE;
6225 			if ((auth_mode != WMI_AUTH_NONE) &&
6226 				((auth_mode != WMI_AUTH_OPEN) ||
6227 				 (auth_mode == WMI_AUTH_OPEN &&
6228 				  roam_req->mdid.mdie_present) ||
6229 				  roam_req->is_ese_assoc)) {
6230 				len += WMI_TLV_HDR_SIZE;
6231 				if (roam_req->is_ese_assoc)
6232 					len +=
6233 					sizeof(wmi_roam_ese_offload_tlv_param);
6234 				else if (auth_mode == WMI_AUTH_FT_RSNA ||
6235 					 auth_mode == WMI_AUTH_FT_RSNA_PSK ||
6236 					 (auth_mode == WMI_AUTH_OPEN &&
6237 					  roam_req->mdid.mdie_present))
6238 					len +=
6239 					sizeof(wmi_roam_11r_offload_tlv_param);
6240 				else
6241 					len +=
6242 					sizeof(wmi_roam_11i_offload_tlv_param);
6243 			} else {
6244 				len += WMI_TLV_HDR_SIZE;
6245 			}
6246 
6247 			len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE)
6248 					+ roundup(roam_req->assoc_ie_length,
6249 					sizeof(uint32_t)));
6250 
6251 			if (roam_req->add_fils_tlv) {
6252 				fils_tlv_len = sizeof(
6253 					wmi_roam_fils_offload_tlv_param);
6254 				len += WMI_TLV_HDR_SIZE + fils_tlv_len;
6255 			}
6256 		} else {
6257 			if (roam_req->is_roam_req_valid)
6258 				WMI_LOGD("%s : roam offload = %d",
6259 				     __func__, roam_req->roam_offload_enabled);
6260 			else
6261 				WMI_LOGD("%s : roam_req is NULL", __func__);
6262 			len += (4 * WMI_TLV_HDR_SIZE);
6263 		}
6264 		if (roam_req->is_roam_req_valid &&
6265 				roam_req->roam_offload_enabled) {
6266 			roam_req->mode = roam_req->mode |
6267 				WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
6268 		}
6269 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6270 
6271 	if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE
6272 				|WMI_ROAM_SCAN_MODE_ROAMOFFLOAD))
6273 		len = sizeof(wmi_roam_scan_mode_fixed_param);
6274 
6275 	buf = wmi_buf_alloc(wmi_handle, len);
6276 	if (!buf) {
6277 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6278 		return QDF_STATUS_E_NOMEM;
6279 	}
6280 
6281 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6282 	roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr;
6283 	WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header,
6284 		       WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param,
6285 		       WMITLV_GET_STRUCT_TLVLEN
6286 			       (wmi_roam_scan_mode_fixed_param));
6287 
6288 	roam_scan_mode_fp->roam_scan_mode = roam_req->mode;
6289 	roam_scan_mode_fp->vdev_id = roam_req->vdev_id;
6290 	if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE |
6291 			WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) {
6292 		roam_scan_mode_fp->flags |=
6293 			WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS;
6294 		goto send_roam_scan_mode_cmd;
6295 	}
6296 
6297 	/* Fill in scan parameters suitable for roaming scan */
6298 	buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param);
6299 
6300 	qdf_mem_copy(buf_ptr, scan_cmd_fp,
6301 		     sizeof(wmi_start_scan_cmd_fixed_param));
6302 	/* Ensure there is no additional IEs */
6303 	scan_cmd_fp->ie_len = 0;
6304 	WMITLV_SET_HDR(buf_ptr,
6305 		       WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
6306 		       WMITLV_GET_STRUCT_TLVLEN
6307 			       (wmi_start_scan_cmd_fixed_param));
6308 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6309 	buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param);
6310 	if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) {
6311 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6312 			       sizeof(wmi_roam_offload_tlv_param));
6313 		buf_ptr += WMI_TLV_HDR_SIZE;
6314 		roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr;
6315 		WMITLV_SET_HDR(buf_ptr,
6316 			       WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param,
6317 			       WMITLV_GET_STRUCT_TLVLEN
6318 				       (wmi_roam_offload_tlv_param));
6319 		roam_offload_params->prefer_5g = roam_req->prefer_5ghz;
6320 		roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap;
6321 		roam_offload_params->select_5g_margin =
6322 			roam_req->select_5ghz_margin;
6323 		roam_offload_params->reassoc_failure_timeout =
6324 			roam_req->reassoc_failure_timeout;
6325 
6326 		/* Fill the capabilities */
6327 		roam_offload_params->capability =
6328 				roam_req->roam_offload_params.capability;
6329 		roam_offload_params->ht_caps_info =
6330 				roam_req->roam_offload_params.ht_caps_info;
6331 		roam_offload_params->ampdu_param =
6332 				roam_req->roam_offload_params.ampdu_param;
6333 		roam_offload_params->ht_ext_cap =
6334 				roam_req->roam_offload_params.ht_ext_cap;
6335 		roam_offload_params->ht_txbf =
6336 				roam_req->roam_offload_params.ht_txbf;
6337 		roam_offload_params->asel_cap =
6338 				roam_req->roam_offload_params.asel_cap;
6339 		roam_offload_params->qos_caps =
6340 				roam_req->roam_offload_params.qos_caps;
6341 		roam_offload_params->qos_enabled =
6342 				roam_req->roam_offload_params.qos_enabled;
6343 		roam_offload_params->wmm_caps =
6344 				roam_req->roam_offload_params.wmm_caps;
6345 		qdf_mem_copy((uint8_t *)roam_offload_params->mcsset,
6346 				(uint8_t *)roam_req->roam_offload_params.mcsset,
6347 				ROAM_OFFLOAD_NUM_MCS_SET);
6348 
6349 		buf_ptr += sizeof(wmi_roam_offload_tlv_param);
6350 		/* The TLV's are in the order of 11i, 11R, ESE. Hence,
6351 		 * they are filled in the same order.Depending on the
6352 		 * authentication type, the other mode TLV's are nullified
6353 		 * and only headers are filled.*/
6354 		if ((auth_mode != WMI_AUTH_NONE) &&
6355 		    ((auth_mode != WMI_AUTH_OPEN) ||
6356 		     (auth_mode == WMI_AUTH_OPEN
6357 		      && roam_req->mdid.mdie_present) ||
6358 			roam_req->is_ese_assoc)) {
6359 			if (roam_req->is_ese_assoc) {
6360 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6361 					       WMITLV_GET_STRUCT_TLVLEN(0));
6362 				buf_ptr += WMI_TLV_HDR_SIZE;
6363 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6364 					       WMITLV_GET_STRUCT_TLVLEN(0));
6365 				buf_ptr += WMI_TLV_HDR_SIZE;
6366 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6367 					sizeof(wmi_roam_ese_offload_tlv_param));
6368 				buf_ptr += WMI_TLV_HDR_SIZE;
6369 				roam_offload_ese =
6370 				    (wmi_roam_ese_offload_tlv_param *) buf_ptr;
6371 				qdf_mem_copy(roam_offload_ese->krk,
6372 					     roam_req->krk,
6373 					     sizeof(roam_req->krk));
6374 				qdf_mem_copy(roam_offload_ese->btk,
6375 					     roam_req->btk,
6376 					     sizeof(roam_req->btk));
6377 				WMITLV_SET_HDR(&roam_offload_ese->tlv_header,
6378 				WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param,
6379 				WMITLV_GET_STRUCT_TLVLEN
6380 				(wmi_roam_ese_offload_tlv_param));
6381 				buf_ptr +=
6382 					sizeof(wmi_roam_ese_offload_tlv_param);
6383 			} else if (auth_mode == WMI_AUTH_FT_RSNA
6384 				   || auth_mode == WMI_AUTH_FT_RSNA_PSK
6385 				   || (auth_mode == WMI_AUTH_OPEN
6386 				       && roam_req->mdid.mdie_present)) {
6387 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6388 					       0);
6389 				buf_ptr += WMI_TLV_HDR_SIZE;
6390 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6391 					sizeof(wmi_roam_11r_offload_tlv_param));
6392 				buf_ptr += WMI_TLV_HDR_SIZE;
6393 				roam_offload_11r =
6394 				    (wmi_roam_11r_offload_tlv_param *) buf_ptr;
6395 				roam_offload_11r->r0kh_id_len =
6396 					roam_req->rokh_id_length;
6397 				qdf_mem_copy(roam_offload_11r->r0kh_id,
6398 					     roam_req->rokh_id,
6399 					     roam_offload_11r->r0kh_id_len);
6400 				qdf_mem_copy(roam_offload_11r->psk_msk,
6401 					     roam_req->psk_pmk,
6402 					     sizeof(roam_req->psk_pmk));
6403 				roam_offload_11r->psk_msk_len =
6404 					roam_req->pmk_len;
6405 				roam_offload_11r->mdie_present =
6406 					roam_req->mdid.mdie_present;
6407 				roam_offload_11r->mdid =
6408 					roam_req->mdid.mobility_domain;
6409 				if (auth_mode == WMI_AUTH_OPEN) {
6410 					/* If FT-Open ensure pmk length
6411 					   and r0khid len are zero */
6412 					roam_offload_11r->r0kh_id_len = 0;
6413 					roam_offload_11r->psk_msk_len = 0;
6414 				}
6415 				WMITLV_SET_HDR(&roam_offload_11r->tlv_header,
6416 				WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param,
6417 				WMITLV_GET_STRUCT_TLVLEN
6418 				(wmi_roam_11r_offload_tlv_param));
6419 				buf_ptr +=
6420 					sizeof(wmi_roam_11r_offload_tlv_param);
6421 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6422 					       WMITLV_GET_STRUCT_TLVLEN(0));
6423 				buf_ptr += WMI_TLV_HDR_SIZE;
6424 				WMI_LOGD("psk_msk_len = %d",
6425 					roam_offload_11r->psk_msk_len);
6426 				if (roam_offload_11r->psk_msk_len)
6427 					QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
6428 						QDF_TRACE_LEVEL_DEBUG,
6429 						roam_offload_11r->psk_msk,
6430 						roam_offload_11r->psk_msk_len);
6431 			} else {
6432 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6433 					sizeof(wmi_roam_11i_offload_tlv_param));
6434 				buf_ptr += WMI_TLV_HDR_SIZE;
6435 				roam_offload_11i =
6436 				     (wmi_roam_11i_offload_tlv_param *) buf_ptr;
6437 
6438 				if (roam_req->roam_key_mgmt_offload_enabled &&
6439 				    roam_req->fw_okc) {
6440 					WMI_SET_ROAM_OFFLOAD_OKC_ENABLED
6441 						(roam_offload_11i->flags);
6442 					WMI_LOGI("LFR3:OKC enabled");
6443 				} else {
6444 					WMI_SET_ROAM_OFFLOAD_OKC_DISABLED
6445 						(roam_offload_11i->flags);
6446 					WMI_LOGI("LFR3:OKC disabled");
6447 				}
6448 				if (roam_req->roam_key_mgmt_offload_enabled &&
6449 				    roam_req->fw_pmksa_cache) {
6450 					WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED
6451 						(roam_offload_11i->flags);
6452 					WMI_LOGI("LFR3:PMKSA caching enabled");
6453 				} else {
6454 					WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED
6455 						(roam_offload_11i->flags);
6456 					WMI_LOGI("LFR3:PMKSA caching disabled");
6457 				}
6458 
6459 				qdf_mem_copy(roam_offload_11i->pmk,
6460 					     roam_req->psk_pmk,
6461 					     sizeof(roam_req->psk_pmk));
6462 				roam_offload_11i->pmk_len = roam_req->pmk_len;
6463 				WMITLV_SET_HDR(&roam_offload_11i->tlv_header,
6464 				WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param,
6465 				WMITLV_GET_STRUCT_TLVLEN
6466 				(wmi_roam_11i_offload_tlv_param));
6467 				buf_ptr +=
6468 					sizeof(wmi_roam_11i_offload_tlv_param);
6469 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6470 					       0);
6471 				buf_ptr += WMI_TLV_HDR_SIZE;
6472 				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6473 					       0);
6474 				buf_ptr += WMI_TLV_HDR_SIZE;
6475 				WMI_LOGD("pmk_len = %d",
6476 					roam_offload_11i->pmk_len);
6477 				if (roam_offload_11i->pmk_len)
6478 					QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
6479 						QDF_TRACE_LEVEL_DEBUG,
6480 						roam_offload_11i->pmk,
6481 						roam_offload_11i->pmk_len);
6482 			}
6483 		} else {
6484 			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6485 				       WMITLV_GET_STRUCT_TLVLEN(0));
6486 			buf_ptr += WMI_TLV_HDR_SIZE;
6487 			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6488 				       WMITLV_GET_STRUCT_TLVLEN(0));
6489 			buf_ptr += WMI_TLV_HDR_SIZE;
6490 			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6491 				       WMITLV_GET_STRUCT_TLVLEN(0));
6492 			buf_ptr += WMI_TLV_HDR_SIZE;
6493 		}
6494 
6495 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6496 					sizeof(*assoc_ies));
6497 		buf_ptr += WMI_TLV_HDR_SIZE;
6498 
6499 		assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr;
6500 		WMITLV_SET_HDR(&assoc_ies->tlv_header,
6501 			WMITLV_TAG_STRUC_wmi_tlv_buf_len_param,
6502 			WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param));
6503 		assoc_ies->buf_len = roam_req->assoc_ie_length;
6504 
6505 		buf_ptr += sizeof(*assoc_ies);
6506 
6507 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
6508 				roundup(assoc_ies->buf_len, sizeof(uint32_t)));
6509 		buf_ptr += WMI_TLV_HDR_SIZE;
6510 
6511 		if (assoc_ies->buf_len != 0) {
6512 			qdf_mem_copy(buf_ptr, roam_req->assoc_ie,
6513 					assoc_ies->buf_len);
6514 		}
6515 		buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t));
6516 		buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req,
6517 						buf_ptr, fils_tlv_len);
6518 	} else {
6519 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6520 			       WMITLV_GET_STRUCT_TLVLEN(0));
6521 		buf_ptr += WMI_TLV_HDR_SIZE;
6522 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6523 			       WMITLV_GET_STRUCT_TLVLEN(0));
6524 		buf_ptr += WMI_TLV_HDR_SIZE;
6525 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6526 			       WMITLV_GET_STRUCT_TLVLEN(0));
6527 		buf_ptr += WMI_TLV_HDR_SIZE;
6528 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6529 			       WMITLV_GET_STRUCT_TLVLEN(0));
6530 		buf_ptr += WMI_TLV_HDR_SIZE;
6531 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6532 				WMITLV_GET_STRUCT_TLVLEN(0));
6533 		buf_ptr += WMI_TLV_HDR_SIZE;
6534 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
6535 				WMITLV_GET_STRUCT_TLVLEN(0));
6536 	}
6537 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
6538 
6539 send_roam_scan_mode_cmd:
6540 	status = wmi_unified_cmd_send(wmi_handle, buf,
6541 				      len, WMI_ROAM_SCAN_MODE);
6542 	if (QDF_IS_STATUS_ERROR(status)) {
6543 		WMI_LOGE(
6544 		    "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d",
6545 			status);
6546 		wmi_buf_free(buf);
6547 	}
6548 
6549 	return status;
6550 }
6551 
6552 static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle,
6553 		struct wmi_mawc_roam_params *params)
6554 {
6555 	wmi_buf_t buf = NULL;
6556 	QDF_STATUS status;
6557 	int len;
6558 	uint8_t *buf_ptr;
6559 	wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params;
6560 
6561 	len = sizeof(*wmi_roam_mawc_params);
6562 	buf = wmi_buf_alloc(wmi_handle, len);
6563 	if (!buf) {
6564 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6565 		return QDF_STATUS_E_NOMEM;
6566 	}
6567 
6568 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6569 	wmi_roam_mawc_params =
6570 		(wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr;
6571 	WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header,
6572 		       WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param,
6573 		       WMITLV_GET_STRUCT_TLVLEN
6574 			       (wmi_roam_configure_mawc_cmd_fixed_param));
6575 	wmi_roam_mawc_params->vdev_id = params->vdev_id;
6576 	if (params->enable)
6577 		wmi_roam_mawc_params->enable = 1;
6578 	else
6579 		wmi_roam_mawc_params->enable = 0;
6580 	wmi_roam_mawc_params->traffic_load_threshold =
6581 		params->traffic_load_threshold;
6582 	wmi_roam_mawc_params->best_ap_rssi_threshold =
6583 		params->best_ap_rssi_threshold;
6584 	wmi_roam_mawc_params->rssi_stationary_high_adjust =
6585 		params->rssi_stationary_high_adjust;
6586 	wmi_roam_mawc_params->rssi_stationary_low_adjust =
6587 		params->rssi_stationary_low_adjust;
6588 	WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"),
6589 		wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id,
6590 		wmi_roam_mawc_params->traffic_load_threshold,
6591 		wmi_roam_mawc_params->best_ap_rssi_threshold,
6592 		wmi_roam_mawc_params->rssi_stationary_high_adjust,
6593 		wmi_roam_mawc_params->rssi_stationary_low_adjust);
6594 
6595 	status = wmi_unified_cmd_send(wmi_handle, buf,
6596 				      len, WMI_ROAM_CONFIGURE_MAWC_CMDID);
6597 	if (QDF_IS_STATUS_ERROR(status)) {
6598 		WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d",
6599 			status);
6600 		wmi_buf_free(buf);
6601 		return status;
6602 	}
6603 
6604 	return QDF_STATUS_SUCCESS;
6605 }
6606 
6607 /**
6608  * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload
6609  *                                                rssi threashold
6610  * @wmi_handle: wmi handle
6611  * @roam_req:   Roaming request buffer
6612  *
6613  * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
6614  *
6615  * Return: QDF status
6616  */
6617 static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle,
6618 				struct roam_offload_scan_rssi_params *roam_req)
6619 {
6620 	wmi_buf_t buf = NULL;
6621 	QDF_STATUS status;
6622 	int len;
6623 	uint8_t *buf_ptr;
6624 	wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp;
6625 	wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL;
6626 	wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL;
6627 	wmi_roam_dense_thres_param *dense_thresholds = NULL;
6628 	wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL;
6629 
6630 	len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
6631 	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
6632 	len += sizeof(wmi_roam_scan_extended_threshold_param);
6633 	len += WMI_TLV_HDR_SIZE;
6634 	len += sizeof(wmi_roam_earlystop_rssi_thres_param);
6635 	len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/
6636 	len += sizeof(wmi_roam_dense_thres_param);
6637 	len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/
6638 	len += sizeof(wmi_roam_bg_scan_roaming_param);
6639 	buf = wmi_buf_alloc(wmi_handle, len);
6640 	if (!buf) {
6641 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6642 		return QDF_STATUS_E_NOMEM;
6643 	}
6644 
6645 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6646 	rssi_threshold_fp =
6647 		(wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr;
6648 	WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header,
6649 		      WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param,
6650 		      WMITLV_GET_STRUCT_TLVLEN
6651 			       (wmi_roam_scan_rssi_threshold_fixed_param));
6652 	/* fill in threshold values */
6653 	rssi_threshold_fp->vdev_id = roam_req->session_id;
6654 	rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh;
6655 	rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff;
6656 	rssi_threshold_fp->hirssi_scan_max_count =
6657 			roam_req->hi_rssi_scan_max_count;
6658 	rssi_threshold_fp->hirssi_scan_delta =
6659 			roam_req->hi_rssi_scan_rssi_delta;
6660 	rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub;
6661 	rssi_threshold_fp->rssi_thresh_offset_5g =
6662 		roam_req->rssi_thresh_offset_5g;
6663 
6664 	buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
6665 	WMITLV_SET_HDR(buf_ptr,
6666 			WMITLV_TAG_ARRAY_STRUC,
6667 			sizeof(wmi_roam_scan_extended_threshold_param));
6668 	buf_ptr += WMI_TLV_HDR_SIZE;
6669 	ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr;
6670 
6671 	ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g;
6672 	if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT)
6673 		ext_thresholds->boost_threshold_5g =
6674 					roam_req->boost_threshold_5g;
6675 
6676 	ext_thresholds->boost_algorithm_5g =
6677 		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
6678 	ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g;
6679 	ext_thresholds->penalty_algorithm_5g =
6680 		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
6681 	ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g;
6682 	ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g;
6683 	ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g;
6684 	ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold;
6685 
6686 	WMITLV_SET_HDR(&ext_thresholds->tlv_header,
6687 		WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param,
6688 		WMITLV_GET_STRUCT_TLVLEN
6689 		(wmi_roam_scan_extended_threshold_param));
6690 	buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param);
6691 	WMITLV_SET_HDR(buf_ptr,
6692 			WMITLV_TAG_ARRAY_STRUC,
6693 			sizeof(wmi_roam_earlystop_rssi_thres_param));
6694 	buf_ptr += WMI_TLV_HDR_SIZE;
6695 	early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr;
6696 	early_stop_thresholds->roam_earlystop_thres_min =
6697 		roam_req->roam_earlystop_thres_min;
6698 	early_stop_thresholds->roam_earlystop_thres_max =
6699 		roam_req->roam_earlystop_thres_max;
6700 	WMITLV_SET_HDR(&early_stop_thresholds->tlv_header,
6701 		WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param,
6702 		WMITLV_GET_STRUCT_TLVLEN
6703 		(wmi_roam_earlystop_rssi_thres_param));
6704 
6705 	buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param);
6706 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6707 			 sizeof(wmi_roam_dense_thres_param));
6708 	buf_ptr += WMI_TLV_HDR_SIZE;
6709 	dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr;
6710 	dense_thresholds->roam_dense_rssi_thres_offset =
6711 			roam_req->dense_rssi_thresh_offset;
6712 	dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt;
6713 	dense_thresholds->roam_dense_traffic_thres =
6714 			roam_req->traffic_threshold;
6715 	dense_thresholds->roam_dense_status = roam_req->initial_dense_status;
6716 	WMITLV_SET_HDR(&dense_thresholds->tlv_header,
6717 			WMITLV_TAG_STRUC_wmi_roam_dense_thres_param,
6718 			WMITLV_GET_STRUCT_TLVLEN
6719 			(wmi_roam_dense_thres_param));
6720 
6721 	buf_ptr += sizeof(wmi_roam_dense_thres_param);
6722 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6723 			 sizeof(wmi_roam_bg_scan_roaming_param));
6724 	buf_ptr += WMI_TLV_HDR_SIZE;
6725 	bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr;
6726 	bg_scan_params->roam_bg_scan_bad_rssi_thresh =
6727 		roam_req->bg_scan_bad_rssi_thresh;
6728 	bg_scan_params->roam_bg_scan_client_bitmap =
6729 		roam_req->bg_scan_client_bitmap;
6730 	bg_scan_params->bad_rssi_thresh_offset_2g =
6731 		roam_req->roam_bad_rssi_thresh_offset_2g;
6732 	bg_scan_params->flags = roam_req->flags;
6733 	WMITLV_SET_HDR(&bg_scan_params->tlv_header,
6734 			WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param,
6735 			WMITLV_GET_STRUCT_TLVLEN
6736 			(wmi_roam_bg_scan_roaming_param));
6737 
6738 	status = wmi_unified_cmd_send(wmi_handle, buf,
6739 				      len, WMI_ROAM_SCAN_RSSI_THRESHOLD);
6740 	if (QDF_IS_STATUS_ERROR(status)) {
6741 		WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d",
6742 					status);
6743 		wmi_buf_free(buf);
6744 	}
6745 
6746 	return status;
6747 }
6748 
6749 /**
6750  * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime
6751  * configuration params
6752  * @wma_handle:  wma handler
6753  * @dwelltime_params: pointer to dwelltime_params
6754  *
6755  * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
6756  */
6757 static
6758 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle,
6759 		struct wmi_adaptive_dwelltime_params *dwelltime_params)
6760 {
6761 	wmi_scan_adaptive_dwell_config_fixed_param *dwell_param;
6762 	wmi_scan_adaptive_dwell_parameters_tlv *cmd;
6763 	wmi_buf_t buf;
6764 	uint8_t *buf_ptr;
6765 	int32_t err;
6766 	int len;
6767 
6768 	len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
6769 	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
6770 	len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv);
6771 	buf = wmi_buf_alloc(wmi_handle, len);
6772 	if (!buf) {
6773 		WMI_LOGE("%s :Failed to allocate buffer to send cmd",
6774 				__func__);
6775 		return QDF_STATUS_E_NOMEM;
6776 	}
6777 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6778 	dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr;
6779 	WMITLV_SET_HDR(&dwell_param->tlv_header,
6780 		WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param,
6781 		WMITLV_GET_STRUCT_TLVLEN
6782 		(wmi_scan_adaptive_dwell_config_fixed_param));
6783 
6784 	dwell_param->enable = dwelltime_params->is_enabled;
6785 	buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
6786 	WMITLV_SET_HDR(buf_ptr,
6787 			WMITLV_TAG_ARRAY_STRUC,
6788 			sizeof(wmi_scan_adaptive_dwell_parameters_tlv));
6789 	buf_ptr += WMI_TLV_HDR_SIZE;
6790 
6791 	cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr;
6792 	WMITLV_SET_HDR(&cmd->tlv_header,
6793 			WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv,
6794 			WMITLV_GET_STRUCT_TLVLEN(
6795 				wmi_scan_adaptive_dwell_parameters_tlv));
6796 
6797 	cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode;
6798 	cmd->adapative_lpf_weight = dwelltime_params->lpf_weight;
6799 	cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval;
6800 	cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold;
6801 	err = wmi_unified_cmd_send(wmi_handle, buf,
6802 			len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID);
6803 	if (err) {
6804 		WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err);
6805 		wmi_buf_free(buf);
6806 		return QDF_STATUS_E_FAILURE;
6807 	}
6808 
6809 	return QDF_STATUS_SUCCESS;
6810 }
6811 
6812 /**
6813  * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection
6814  * configuration params
6815  * @wmi_handle: wmi handler
6816  * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params
6817  *
6818  * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
6819  */
6820 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle,
6821 			struct wmi_dbs_scan_sel_params *dbs_scan_params)
6822 {
6823 	wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param;
6824 	wmi_scan_dbs_duty_cycle_tlv_param *cmd;
6825 	wmi_buf_t buf;
6826 	uint8_t *buf_ptr;
6827 	QDF_STATUS err;
6828 	uint32_t i;
6829 	int len;
6830 
6831 	len = sizeof(*dbs_scan_param);
6832 	len += WMI_TLV_HDR_SIZE;
6833 	len += dbs_scan_params->num_clients * sizeof(*cmd);
6834 
6835 	buf = wmi_buf_alloc(wmi_handle, len);
6836 	if (!buf) {
6837 		WMI_LOGE("%s:Failed to allocate buffer to send cmd", __func__);
6838 		return QDF_STATUS_E_NOMEM;
6839 	}
6840 
6841 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
6842 	dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr;
6843 	WMITLV_SET_HDR(&dbs_scan_param->tlv_header,
6844 		       WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param,
6845 		       WMITLV_GET_STRUCT_TLVLEN
6846 		       (wmi_scan_dbs_duty_cycle_fixed_param));
6847 
6848 	dbs_scan_param->num_clients = dbs_scan_params->num_clients;
6849 	dbs_scan_param->pdev_id = dbs_scan_params->pdev_id;
6850 	buf_ptr += sizeof(*dbs_scan_param);
6851 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6852 		       (sizeof(*cmd) * dbs_scan_params->num_clients));
6853 	buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE;
6854 
6855 	for (i = 0; i < dbs_scan_params->num_clients; i++) {
6856 		cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr;
6857 		WMITLV_SET_HDR(&cmd->tlv_header,
6858 			WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv,
6859 			WMITLV_GET_STRUCT_TLVLEN(
6860 					wmi_scan_dbs_duty_cycle_tlv_param));
6861 		cmd->module_id = dbs_scan_params->module_id[i];
6862 		cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i];
6863 		cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i];
6864 		buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd);
6865 	}
6866 
6867 	err = wmi_unified_cmd_send(wmi_handle, buf,
6868 				   len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID);
6869 	if (QDF_IS_STATUS_ERROR(err)) {
6870 		WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err);
6871 		wmi_buf_free(buf);
6872 		return QDF_STATUS_E_FAILURE;
6873 	}
6874 
6875 	return QDF_STATUS_SUCCESS;
6876 }
6877 
6878 /**
6879  * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming
6880  * @wmi_handle:     wmi handle
6881  * @roam_req:       Request which contains the filters
6882  *
6883  * There are filters such as whitelist, blacklist and preferred
6884  * list that need to be applied to the scan results to form the
6885  * probable candidates for roaming.
6886  *
6887  * Return: Return success upon succesfully passing the
6888  *         parameters to the firmware, otherwise failure.
6889  */
6890 static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle,
6891 				struct roam_scan_filter_params *roam_req)
6892 {
6893 	wmi_buf_t buf = NULL;
6894 	QDF_STATUS status;
6895 	uint32_t i;
6896 	uint32_t len, blist_len = 0;
6897 	uint8_t *buf_ptr;
6898 	wmi_roam_filter_fixed_param *roam_filter;
6899 	uint8_t *bssid_src_ptr = NULL;
6900 	wmi_mac_addr *bssid_dst_ptr = NULL;
6901 	wmi_ssid *ssid_ptr = NULL;
6902 	uint32_t *bssid_preferred_factor_ptr = NULL;
6903 	wmi_roam_lca_disallow_config_tlv_param *blist_param;
6904 	wmi_roam_rssi_rejection_oce_config_param *rssi_rej;
6905 
6906 	len = sizeof(wmi_roam_filter_fixed_param);
6907 
6908 	len += WMI_TLV_HDR_SIZE;
6909 	if (roam_req->num_bssid_black_list)
6910 		len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr);
6911 	len += WMI_TLV_HDR_SIZE;
6912 	if (roam_req->num_ssid_white_list)
6913 		len += roam_req->num_ssid_white_list * sizeof(wmi_ssid);
6914 	len += 2 * WMI_TLV_HDR_SIZE;
6915 	if (roam_req->num_bssid_preferred_list) {
6916 		len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr);
6917 		len += roam_req->num_bssid_preferred_list * sizeof(A_UINT32);
6918 	}
6919 	len += WMI_TLV_HDR_SIZE;
6920 	if (roam_req->lca_disallow_config_present) {
6921 		len += sizeof(*blist_param);
6922 		blist_len = sizeof(*blist_param);
6923 	}
6924 
6925 	len += WMI_TLV_HDR_SIZE;
6926 	if (roam_req->num_rssi_rejection_ap)
6927 		len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej);
6928 
6929 	buf = wmi_buf_alloc(wmi_handle, len);
6930 	if (!buf) {
6931 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6932 		return QDF_STATUS_E_NOMEM;
6933 	}
6934 
6935 	buf_ptr = (u_int8_t *) wmi_buf_data(buf);
6936 	roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr;
6937 	WMITLV_SET_HDR(&roam_filter->tlv_header,
6938 		WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param,
6939 		WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param));
6940 	/* fill in fixed values */
6941 	roam_filter->vdev_id = roam_req->session_id;
6942 	roam_filter->flags = 0;
6943 	roam_filter->op_bitmap = roam_req->op_bitmap;
6944 	roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list;
6945 	roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list;
6946 	roam_filter->num_bssid_preferred_list =
6947 			roam_req->num_bssid_preferred_list;
6948 	roam_filter->num_rssi_rejection_ap =
6949 			roam_req->num_rssi_rejection_ap;
6950 	buf_ptr += sizeof(wmi_roam_filter_fixed_param);
6951 
6952 	WMITLV_SET_HDR((buf_ptr),
6953 		WMITLV_TAG_ARRAY_FIXED_STRUC,
6954 		(roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)));
6955 	bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list;
6956 	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
6957 	for (i = 0; i < roam_req->num_bssid_black_list; i++) {
6958 		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr);
6959 		bssid_src_ptr += ATH_MAC_LEN;
6960 		bssid_dst_ptr++;
6961 	}
6962 	buf_ptr += WMI_TLV_HDR_SIZE +
6963 		(roam_req->num_bssid_black_list * sizeof(wmi_mac_addr));
6964 	WMITLV_SET_HDR((buf_ptr),
6965 		WMITLV_TAG_ARRAY_FIXED_STRUC,
6966 		(roam_req->num_ssid_white_list * sizeof(wmi_ssid)));
6967 	ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE);
6968 	for (i = 0; i < roam_req->num_ssid_white_list; i++) {
6969 		qdf_mem_copy(&ssid_ptr->ssid,
6970 			&roam_req->ssid_allowed_list[i].mac_ssid,
6971 			roam_req->ssid_allowed_list[i].length);
6972 		ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length;
6973 		ssid_ptr++;
6974 	}
6975 	buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list *
6976 							sizeof(wmi_ssid));
6977 	WMITLV_SET_HDR((buf_ptr),
6978 		WMITLV_TAG_ARRAY_FIXED_STRUC,
6979 		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)));
6980 	bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored;
6981 	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
6982 	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
6983 		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr,
6984 				(wmi_mac_addr *)bssid_dst_ptr);
6985 		bssid_src_ptr += ATH_MAC_LEN;
6986 		bssid_dst_ptr++;
6987 	}
6988 	buf_ptr += WMI_TLV_HDR_SIZE +
6989 		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr));
6990 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
6991 		(roam_req->num_bssid_preferred_list * sizeof(uint32_t)));
6992 	bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
6993 	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
6994 		*bssid_preferred_factor_ptr =
6995 			roam_req->bssid_favored_factor[i];
6996 		bssid_preferred_factor_ptr++;
6997 	}
6998 	buf_ptr += WMI_TLV_HDR_SIZE +
6999 		(roam_req->num_bssid_preferred_list * sizeof(uint32_t));
7000 
7001 	WMITLV_SET_HDR(buf_ptr,
7002 			WMITLV_TAG_ARRAY_STRUC, blist_len);
7003 	buf_ptr += WMI_TLV_HDR_SIZE;
7004 	if (roam_req->lca_disallow_config_present) {
7005 		blist_param =
7006 			(wmi_roam_lca_disallow_config_tlv_param *) buf_ptr;
7007 		WMITLV_SET_HDR(&blist_param->tlv_header,
7008 			WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param,
7009 			WMITLV_GET_STRUCT_TLVLEN(
7010 				wmi_roam_lca_disallow_config_tlv_param));
7011 
7012 		blist_param->disallow_duration = roam_req->disallow_duration;
7013 		blist_param->rssi_channel_penalization =
7014 				roam_req->rssi_channel_penalization;
7015 		blist_param->num_disallowed_aps = roam_req->num_disallowed_aps;
7016 		blist_param->disallow_lca_enable_source_bitmap =
7017 			(WMI_ROAM_LCA_DISALLOW_SOURCE_PER |
7018 			WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND);
7019 		buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param));
7020 	}
7021 
7022 	WMITLV_SET_HDR(buf_ptr,
7023 			WMITLV_TAG_ARRAY_STRUC,
7024 			(roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej)));
7025 	buf_ptr += WMI_TLV_HDR_SIZE;
7026 	for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) {
7027 		rssi_rej =
7028 		(wmi_roam_rssi_rejection_oce_config_param *) buf_ptr;
7029 		WMITLV_SET_HDR(&rssi_rej->tlv_header,
7030 			WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param,
7031 			WMITLV_GET_STRUCT_TLVLEN(
7032 			wmi_roam_rssi_rejection_oce_config_param));
7033 		WMI_CHAR_ARRAY_TO_MAC_ADDR(
7034 			roam_req->rssi_rejection_ap[i].bssid.bytes,
7035 			&rssi_rej->bssid);
7036 		rssi_rej->remaining_disallow_duration =
7037 			roam_req->rssi_rejection_ap[i].remaining_duration;
7038 		rssi_rej->requested_rssi =
7039 			(A_INT32)roam_req->rssi_rejection_ap[i].expected_rssi;
7040 		buf_ptr +=
7041 			(sizeof(wmi_roam_rssi_rejection_oce_config_param));
7042 	}
7043 
7044 	status = wmi_unified_cmd_send(wmi_handle, buf,
7045 		len, WMI_ROAM_FILTER_CMDID);
7046 	if (QDF_IS_STATUS_ERROR(status)) {
7047 		WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d",
7048 				status);
7049 		wmi_buf_free(buf);
7050 	}
7051 
7052 	return status;
7053 }
7054 
7055 #if defined(WLAN_FEATURE_FILS_SK)
7056 static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle,
7057 						  struct hlp_params *params)
7058 {
7059 	uint32_t len;
7060 	uint8_t *buf_ptr;
7061 	wmi_buf_t buf = NULL;
7062 	wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params;
7063 
7064 	len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param);
7065 	len += WMI_TLV_HDR_SIZE;
7066 	len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t));
7067 
7068 	buf = wmi_buf_alloc(wmi_handle, len);
7069 	if (!buf) {
7070 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
7071 		return QDF_STATUS_E_NOMEM;
7072 	}
7073 
7074 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
7075 	hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr;
7076 	WMITLV_SET_HDR(&hlp_params->tlv_header,
7077 		WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param,
7078 		WMITLV_GET_STRUCT_TLVLEN(
7079 			wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param));
7080 
7081 	hlp_params->vdev_id = params->vdev_id;
7082 	hlp_params->size = params->hlp_ie_len;
7083 	hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER;
7084 
7085 	buf_ptr += sizeof(*hlp_params);
7086 
7087 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
7088 				round_up(params->hlp_ie_len,
7089 				sizeof(uint32_t)));
7090 	buf_ptr += WMI_TLV_HDR_SIZE;
7091 	qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len);
7092 
7093 	WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"),
7094 			hlp_params->vdev_id, hlp_params->size);
7095 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
7096 				WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) {
7097 		WMI_LOGE(FL("Failed to send FILS HLP pkt cmd"));
7098 		wmi_buf_free(buf);
7099 		return QDF_STATUS_E_FAILURE;
7100 	}
7101 
7102 	return QDF_STATUS_SUCCESS;
7103 }
7104 #endif
7105 
7106 /** send_set_epno_network_list_cmd_tlv() - set epno network list
7107  * @wmi_handle: wmi handle
7108  * @req: epno config params request structure
7109  *
7110  * This function reads the incoming epno config request structure
7111  * and constructs the WMI message to the firmware.
7112  *
7113  * Returns: 0 on success, error number otherwise
7114  */
7115 static QDF_STATUS send_set_epno_network_list_cmd_tlv(wmi_unified_t wmi_handle,
7116 		struct wifi_enhanched_pno_params *req)
7117 {
7118 	wmi_nlo_config_cmd_fixed_param *cmd;
7119 	nlo_configured_parameters *nlo_list;
7120 	enlo_candidate_score_params *cand_score_params;
7121 	u_int8_t i, *buf_ptr;
7122 	wmi_buf_t buf;
7123 	uint32_t len;
7124 	QDF_STATUS ret;
7125 
7126 	/* Fixed Params */
7127 	len = sizeof(*cmd);
7128 	if (req->num_networks) {
7129 		/* TLV place holder for array of structures
7130 		 * then each nlo_configured_parameters(nlo_list) TLV.
7131 		 */
7132 		len += WMI_TLV_HDR_SIZE;
7133 		len += (sizeof(nlo_configured_parameters)
7134 			    * QDF_MIN(req->num_networks, WMI_NLO_MAX_SSIDS));
7135 		/* TLV for array of uint32 channel_list */
7136 		len += WMI_TLV_HDR_SIZE;
7137 		/* TLV for nlo_channel_prediction_cfg */
7138 		len += WMI_TLV_HDR_SIZE;
7139 		/* TLV for candidate score params */
7140 		len += sizeof(enlo_candidate_score_params);
7141 	}
7142 
7143 	buf = wmi_buf_alloc(wmi_handle, len);
7144 	if (!buf) {
7145 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7146 		return QDF_STATUS_E_NOMEM;
7147 	}
7148 
7149 	cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf);
7150 
7151 	buf_ptr = (u_int8_t *) cmd;
7152 	WMITLV_SET_HDR(&cmd->tlv_header,
7153 		       WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param,
7154 		       WMITLV_GET_STRUCT_TLVLEN(
7155 			       wmi_nlo_config_cmd_fixed_param));
7156 	cmd->vdev_id = req->session_id;
7157 
7158 	/* set flag to reset if num of networks are 0 */
7159 	cmd->flags = (req->num_networks == 0 ?
7160 		WMI_NLO_CONFIG_ENLO_RESET : WMI_NLO_CONFIG_ENLO);
7161 
7162 	buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param);
7163 
7164 	cmd->no_of_ssids = QDF_MIN(req->num_networks, WMI_NLO_MAX_SSIDS);
7165 	WMI_LOGD("SSID count: %d flags: %d",
7166 		cmd->no_of_ssids, cmd->flags);
7167 
7168 	/* Fill nlo_config only when num_networks are non zero */
7169 	if (cmd->no_of_ssids) {
7170 		/* Fill networks */
7171 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
7172 			cmd->no_of_ssids * sizeof(nlo_configured_parameters));
7173 		buf_ptr += WMI_TLV_HDR_SIZE;
7174 
7175 		nlo_list = (nlo_configured_parameters *) buf_ptr;
7176 		for (i = 0; i < cmd->no_of_ssids; i++) {
7177 			WMITLV_SET_HDR(&nlo_list[i].tlv_header,
7178 				WMITLV_TAG_ARRAY_BYTE,
7179 				WMITLV_GET_STRUCT_TLVLEN(
7180 				nlo_configured_parameters));
7181 			/* Copy ssid and it's length */
7182 			nlo_list[i].ssid.valid = true;
7183 			nlo_list[i].ssid.ssid.ssid_len =
7184 				req->networks[i].ssid.length;
7185 			qdf_mem_copy(nlo_list[i].ssid.ssid.ssid,
7186 				     req->networks[i].ssid.mac_ssid,
7187 				     nlo_list[i].ssid.ssid.ssid_len);
7188 			WMI_LOGD("index: %d ssid: %.*s len: %d", i,
7189 				 nlo_list[i].ssid.ssid.ssid_len,
7190 				 (char *) nlo_list[i].ssid.ssid.ssid,
7191 				 nlo_list[i].ssid.ssid.ssid_len);
7192 
7193 			/* Copy pno flags */
7194 			nlo_list[i].bcast_nw_type.valid = true;
7195 			nlo_list[i].bcast_nw_type.bcast_nw_type =
7196 					req->networks[i].flags;
7197 			WMI_LOGD("PNO flags (%u)",
7198 				nlo_list[i].bcast_nw_type.bcast_nw_type);
7199 
7200 			/* Copy auth bit field */
7201 			nlo_list[i].auth_type.valid = true;
7202 			nlo_list[i].auth_type.auth_type =
7203 					req->networks[i].auth_bit_field;
7204 			WMI_LOGD("Auth bit field (%u)",
7205 					nlo_list[i].auth_type.auth_type);
7206 		}
7207 
7208 		buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters);
7209 		/* Fill the channel list */
7210 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
7211 		buf_ptr += WMI_TLV_HDR_SIZE;
7212 
7213 		/* Fill prediction_param */
7214 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
7215 		buf_ptr += WMI_TLV_HDR_SIZE;
7216 
7217 		/* Fill epno candidate score params */
7218 		cand_score_params = (enlo_candidate_score_params *) buf_ptr;
7219 		WMITLV_SET_HDR(buf_ptr,
7220 			WMITLV_TAG_STRUC_enlo_candidate_score_param,
7221 			WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params));
7222 		cand_score_params->min5GHz_rssi =
7223 			req->min_5ghz_rssi;
7224 		cand_score_params->min24GHz_rssi =
7225 			req->min_24ghz_rssi;
7226 		cand_score_params->initial_score_max =
7227 			req->initial_score_max;
7228 		cand_score_params->current_connection_bonus =
7229 			req->current_connection_bonus;
7230 		cand_score_params->same_network_bonus =
7231 			req->same_network_bonus;
7232 		cand_score_params->secure_bonus =
7233 			req->secure_bonus;
7234 		cand_score_params->band5GHz_bonus =
7235 			req->band_5ghz_bonus;
7236 		buf_ptr += sizeof(enlo_candidate_score_params);
7237 	}
7238 
7239 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7240 			WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
7241 	if (QDF_IS_STATUS_ERROR(ret)) {
7242 		WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__);
7243 		wmi_buf_free(buf);
7244 		return QDF_STATUS_E_INVAL;
7245 	}
7246 
7247 	WMI_LOGD("set ePNO list request sent successfully for vdev %d",
7248 		 req->session_id);
7249 
7250 	return ret;
7251 }
7252 
7253 
7254 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter
7255  * @wmi_handle: wmi handle
7256  * @ipa_offload: ipa offload control parameter
7257  *
7258  * Returns: 0 on success, error number otherwise
7259  */
7260 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle,
7261 		struct ipa_offload_control_params *ipa_offload)
7262 {
7263 	wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd;
7264 	wmi_buf_t wmi_buf;
7265 	uint32_t len;
7266 	u_int8_t *buf_ptr;
7267 
7268 	len  = sizeof(*cmd);
7269 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
7270 	if (!wmi_buf) {
7271 		WMI_LOGE("%s: wmi_buf_alloc failed (len=%d)", __func__, len);
7272 		return QDF_STATUS_E_NOMEM;
7273 	}
7274 
7275 	WMI_LOGD("%s: offload_type=%d, enable=%d", __func__,
7276 		ipa_offload->offload_type, ipa_offload->enable);
7277 
7278 	buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf);
7279 
7280 	cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr;
7281 	WMITLV_SET_HDR(&cmd->tlv_header,
7282 		WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param,
7283 		WMITLV_GET_STRUCT_TLVLEN(
7284 		wmi_ipa_offload_enable_disable_cmd_fixed_param));
7285 
7286 	cmd->offload_type = ipa_offload->offload_type;
7287 	cmd->vdev_id = ipa_offload->vdev_id;
7288 	cmd->enable = ipa_offload->enable;
7289 
7290 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
7291 		WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) {
7292 		WMI_LOGE("%s: failed to command", __func__);
7293 		wmi_buf_free(wmi_buf);
7294 		return QDF_STATUS_E_FAILURE;
7295 	}
7296 
7297 	return QDF_STATUS_SUCCESS;
7298 }
7299 
7300 /**
7301  * send_extscan_get_capabilities_cmd_tlv() - extscan get capabilities
7302  * @wmi_handle: wmi handle
7303  * @pgetcapab: get capabilities params
7304  *
7305  * This function send request to fw to get extscan capabilities.
7306  *
7307  * Return: CDF status
7308  */
7309 static QDF_STATUS send_extscan_get_capabilities_cmd_tlv(wmi_unified_t wmi_handle,
7310 		    struct extscan_capabilities_params *pgetcapab)
7311 {
7312 	wmi_extscan_get_capabilities_cmd_fixed_param *cmd;
7313 	wmi_buf_t wmi_buf;
7314 	uint32_t len;
7315 	uint8_t *buf_ptr;
7316 
7317 	len = sizeof(*cmd);
7318 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
7319 	if (!wmi_buf) {
7320 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
7321 		return QDF_STATUS_E_NOMEM;
7322 	}
7323 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
7324 
7325 	cmd = (wmi_extscan_get_capabilities_cmd_fixed_param *) buf_ptr;
7326 	WMITLV_SET_HDR(&cmd->tlv_header,
7327 	       WMITLV_TAG_STRUC_wmi_extscan_get_capabilities_cmd_fixed_param,
7328 	       WMITLV_GET_STRUCT_TLVLEN
7329 	       (wmi_extscan_get_capabilities_cmd_fixed_param));
7330 
7331 	cmd->request_id = pgetcapab->request_id;
7332 
7333 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
7334 				 WMI_EXTSCAN_GET_CAPABILITIES_CMDID)) {
7335 		WMI_LOGE("%s: failed to  command", __func__);
7336 		wmi_buf_free(wmi_buf);
7337 		return QDF_STATUS_E_FAILURE;
7338 	}
7339 	return QDF_STATUS_SUCCESS;
7340 }
7341 
7342 /**
7343  * send_extscan_get_cached_results_cmd_tlv() - extscan get cached results
7344  * @wmi_handle: wmi handle
7345  * @pcached_results: cached results parameters
7346  *
7347  * This function send request to fw to get cached results.
7348  *
7349  * Return: CDF status
7350  */
7351 static QDF_STATUS send_extscan_get_cached_results_cmd_tlv(wmi_unified_t wmi_handle,
7352 		  struct extscan_cached_result_params *pcached_results)
7353 {
7354 	wmi_extscan_get_cached_results_cmd_fixed_param *cmd;
7355 	wmi_buf_t wmi_buf;
7356 	uint32_t len;
7357 	uint8_t *buf_ptr;
7358 
7359 	len = sizeof(*cmd);
7360 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
7361 	if (!wmi_buf) {
7362 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
7363 		return QDF_STATUS_E_NOMEM;
7364 	}
7365 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
7366 
7367 	cmd = (wmi_extscan_get_cached_results_cmd_fixed_param *) buf_ptr;
7368 	WMITLV_SET_HDR(&cmd->tlv_header,
7369 		WMITLV_TAG_STRUC_wmi_extscan_get_cached_results_cmd_fixed_param,
7370 		WMITLV_GET_STRUCT_TLVLEN
7371 		(wmi_extscan_get_cached_results_cmd_fixed_param));
7372 
7373 	cmd->request_id = pcached_results->request_id;
7374 	cmd->vdev_id = pcached_results->session_id;
7375 	cmd->control_flags = pcached_results->flush;
7376 
7377 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
7378 				 WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID)) {
7379 		WMI_LOGE("%s: failed to  command", __func__);
7380 		wmi_buf_free(wmi_buf);
7381 		return QDF_STATUS_E_FAILURE;
7382 	}
7383 	return QDF_STATUS_SUCCESS;
7384 }
7385 
7386 /**
7387  * send_extscan_stop_change_monitor_cmd_tlv() - send stop change monitor cmd
7388  * @wmi_handle: wmi handle
7389  * @reset_req: Reset change request params
7390  *
7391  * This function sends stop change monitor request to fw.
7392  *
7393  * Return: CDF status
7394  */
7395 static QDF_STATUS send_extscan_stop_change_monitor_cmd_tlv(wmi_unified_t wmi_handle,
7396 			struct extscan_capabilities_reset_params *reset_req)
7397 {
7398 	wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd;
7399 	wmi_buf_t wmi_buf;
7400 	uint32_t len;
7401 	uint8_t *buf_ptr;
7402 	int change_list = 0;
7403 
7404 	len = sizeof(*cmd);
7405 
7406 	/* reset significant change tlv is set to 0 */
7407 	len += WMI_TLV_HDR_SIZE;
7408 	len += change_list * sizeof(wmi_extscan_wlan_change_bssid_param);
7409 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
7410 	if (!wmi_buf) {
7411 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
7412 		return QDF_STATUS_E_NOMEM;
7413 	}
7414 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
7415 
7416 	cmd = (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *)
7417 		buf_ptr;
7418 	WMITLV_SET_HDR(&cmd->tlv_header,
7419 	WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param,
7420 		WMITLV_GET_STRUCT_TLVLEN
7421 		(wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param));
7422 
7423 	cmd->request_id = reset_req->request_id;
7424 	cmd->vdev_id = reset_req->session_id;
7425 	cmd->mode = 0;
7426 
7427 	buf_ptr += sizeof(*cmd);
7428 	WMITLV_SET_HDR(buf_ptr,
7429 		       WMITLV_TAG_ARRAY_STRUC,
7430 		       change_list *
7431 		       sizeof(wmi_extscan_wlan_change_bssid_param));
7432 	buf_ptr += WMI_TLV_HDR_SIZE + (change_list *
7433 				       sizeof
7434 				       (wmi_extscan_wlan_change_bssid_param));
7435 
7436 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
7437 			 WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) {
7438 		WMI_LOGE("%s: failed to  command", __func__);
7439 		wmi_buf_free(wmi_buf);
7440 		return QDF_STATUS_E_FAILURE;
7441 	}
7442 	return QDF_STATUS_SUCCESS;
7443 }
7444 
7445 /**
7446  * wmi_get_buf_extscan_change_monitor_cmd() - fill change monitor request
7447  * @wmi_handle: wmi handle
7448  * @psigchange: change monitor request params
7449  * @buf: wmi buffer
7450  * @buf_len: buffer length
7451  *
7452  * This function fills elements of change monitor request buffer.
7453  *
7454  * Return: CDF status
7455  */
7456 static QDF_STATUS wmi_get_buf_extscan_change_monitor_cmd(wmi_unified_t wmi_handle,
7457 			struct extscan_set_sig_changereq_params
7458 			*psigchange, wmi_buf_t *buf, int *buf_len)
7459 {
7460 	wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd;
7461 	wmi_extscan_wlan_change_bssid_param *dest_chglist;
7462 	uint8_t *buf_ptr;
7463 	int j;
7464 	int len = sizeof(*cmd);
7465 	uint32_t numap = psigchange->num_ap;
7466 	struct ap_threshold_params *src_ap = psigchange->ap;
7467 
7468 	if (!numap || (numap > WMI_WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS)) {
7469 		WMI_LOGE("%s: Invalid number of bssid's", __func__);
7470 		return QDF_STATUS_E_INVAL;
7471 	}
7472 	len += WMI_TLV_HDR_SIZE;
7473 	len += numap * sizeof(wmi_extscan_wlan_change_bssid_param);
7474 
7475 	*buf = wmi_buf_alloc(wmi_handle, len);
7476 	if (!*buf) {
7477 		WMI_LOGP("%s: failed to allocate memory for change monitor cmd",
7478 			 __func__);
7479 		return QDF_STATUS_E_FAILURE;
7480 	}
7481 	buf_ptr = (uint8_t *) wmi_buf_data(*buf);
7482 	cmd =
7483 		(wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *)
7484 		buf_ptr;
7485 	WMITLV_SET_HDR(&cmd->tlv_header,
7486 	WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param,
7487 	       WMITLV_GET_STRUCT_TLVLEN
7488 	       (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param));
7489 
7490 	cmd->request_id = psigchange->request_id;
7491 	cmd->vdev_id = psigchange->session_id;
7492 	cmd->total_entries = numap;
7493 	cmd->mode = 1;
7494 	cmd->num_entries_in_page = numap;
7495 	cmd->lost_ap_scan_count = psigchange->lostap_sample_size;
7496 	cmd->max_rssi_samples = psigchange->rssi_sample_size;
7497 	cmd->rssi_averaging_samples = psigchange->rssi_sample_size;
7498 	cmd->max_out_of_range_count = psigchange->min_breaching;
7499 
7500 	buf_ptr += sizeof(*cmd);
7501 	WMITLV_SET_HDR(buf_ptr,
7502 		       WMITLV_TAG_ARRAY_STRUC,
7503 		       numap * sizeof(wmi_extscan_wlan_change_bssid_param));
7504 	dest_chglist = (wmi_extscan_wlan_change_bssid_param *)
7505 		       (buf_ptr + WMI_TLV_HDR_SIZE);
7506 
7507 	for (j = 0; j < numap; j++) {
7508 		WMITLV_SET_HDR(dest_chglist,
7509 		       WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param,
7510 		       WMITLV_GET_STRUCT_TLVLEN
7511 		       (wmi_extscan_wlan_change_bssid_param));
7512 
7513 		dest_chglist->lower_rssi_limit = src_ap->low;
7514 		dest_chglist->upper_rssi_limit = src_ap->high;
7515 		WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes,
7516 					   &dest_chglist->bssid);
7517 
7518 		WMI_LOGD("%s: min_rssi %d", __func__,
7519 			 dest_chglist->lower_rssi_limit);
7520 		dest_chglist++;
7521 		src_ap++;
7522 	}
7523 	buf_ptr += WMI_TLV_HDR_SIZE +
7524 		   (numap * sizeof(wmi_extscan_wlan_change_bssid_param));
7525 	*buf_len = len;
7526 	return QDF_STATUS_SUCCESS;
7527 }
7528 
7529 /**
7530  * send_extscan_start_change_monitor_cmd_tlv() - send start change monitor cmd
7531  * @wmi_handle: wmi handle
7532  * @psigchange: change monitor request params
7533  *
7534  * This function sends start change monitor request to fw.
7535  *
7536  * Return: CDF status
7537  */
7538 static QDF_STATUS send_extscan_start_change_monitor_cmd_tlv(wmi_unified_t wmi_handle,
7539 			   struct extscan_set_sig_changereq_params *
7540 			   psigchange)
7541 {
7542 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
7543 	wmi_buf_t buf;
7544 	int len;
7545 
7546 
7547 	qdf_status = wmi_get_buf_extscan_change_monitor_cmd(wmi_handle,
7548 			     psigchange, &buf,
7549 			     &len);
7550 	if (qdf_status != QDF_STATUS_SUCCESS) {
7551 		WMI_LOGE("%s: Failed to get buffer for change monitor cmd",
7552 			 __func__);
7553 		return QDF_STATUS_E_FAILURE;
7554 	}
7555 	if (!buf) {
7556 		WMI_LOGE("%s: Failed to get buffer", __func__);
7557 		return QDF_STATUS_E_FAILURE;
7558 	}
7559 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
7560 		 WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) {
7561 		WMI_LOGE("%s: failed to send command", __func__);
7562 		wmi_buf_free(buf);
7563 		return QDF_STATUS_E_FAILURE;
7564 	}
7565 	return QDF_STATUS_SUCCESS;
7566 }
7567 
7568 /**
7569  * send_extscan_stop_hotlist_monitor_cmd_tlv() - stop hotlist monitor
7570  * @wmi_handle: wmi handle
7571  * @photlist_reset: hotlist reset params
7572  *
7573  * This function configures hotlist monitor to stop in fw.
7574  *
7575  * Return: CDF status
7576  */
7577 static QDF_STATUS send_extscan_stop_hotlist_monitor_cmd_tlv(wmi_unified_t wmi_handle,
7578 		  struct extscan_bssid_hotlist_reset_params *photlist_reset)
7579 {
7580 	wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd;
7581 	wmi_buf_t wmi_buf;
7582 	uint32_t len;
7583 	uint8_t *buf_ptr;
7584 	int hotlist_entries = 0;
7585 
7586 	len = sizeof(*cmd);
7587 
7588 	/* reset bssid hotlist with tlv set to 0 */
7589 	len += WMI_TLV_HDR_SIZE;
7590 	len += hotlist_entries * sizeof(wmi_extscan_hotlist_entry);
7591 
7592 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
7593 	if (!wmi_buf) {
7594 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
7595 		return QDF_STATUS_E_NOMEM;
7596 	}
7597 
7598 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
7599 	cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *)
7600 	      buf_ptr;
7601 	WMITLV_SET_HDR(&cmd->tlv_header,
7602 	WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param,
7603 	WMITLV_GET_STRUCT_TLVLEN
7604 	(wmi_extscan_configure_hotlist_monitor_cmd_fixed_param));
7605 
7606 	cmd->request_id = photlist_reset->request_id;
7607 	cmd->vdev_id = photlist_reset->session_id;
7608 	cmd->mode = 0;
7609 
7610 	buf_ptr += sizeof(*cmd);
7611 	WMITLV_SET_HDR(buf_ptr,
7612 		       WMITLV_TAG_ARRAY_STRUC,
7613 		       hotlist_entries * sizeof(wmi_extscan_hotlist_entry));
7614 	buf_ptr += WMI_TLV_HDR_SIZE +
7615 		   (hotlist_entries * sizeof(wmi_extscan_hotlist_entry));
7616 
7617 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
7618 				 WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) {
7619 		WMI_LOGE("%s: failed to  command", __func__);
7620 		wmi_buf_free(wmi_buf);
7621 		return QDF_STATUS_E_FAILURE;
7622 	}
7623 	return QDF_STATUS_SUCCESS;
7624 }
7625 
7626 /**
7627  * send_stop_extscan_cmd_tlv() - stop extscan command to fw.
7628  * @wmi_handle: wmi handle
7629  * @pstopcmd: stop scan command request params
7630  *
7631  * This function sends stop extscan request to fw.
7632  *
7633  * Return: CDF Status.
7634  */
7635 static QDF_STATUS send_stop_extscan_cmd_tlv(wmi_unified_t wmi_handle,
7636 			  struct extscan_stop_req_params *pstopcmd)
7637 {
7638 	wmi_extscan_stop_cmd_fixed_param *cmd;
7639 	wmi_buf_t wmi_buf;
7640 	uint32_t len;
7641 	uint8_t *buf_ptr;
7642 
7643 	len = sizeof(*cmd);
7644 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
7645 	if (!wmi_buf) {
7646 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
7647 		return QDF_STATUS_E_NOMEM;
7648 	}
7649 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
7650 	cmd = (wmi_extscan_stop_cmd_fixed_param *) buf_ptr;
7651 	WMITLV_SET_HDR(&cmd->tlv_header,
7652 		       WMITLV_TAG_STRUC_wmi_extscan_stop_cmd_fixed_param,
7653 		       WMITLV_GET_STRUCT_TLVLEN
7654 			       (wmi_extscan_stop_cmd_fixed_param));
7655 
7656 	cmd->request_id = pstopcmd->request_id;
7657 	cmd->vdev_id = pstopcmd->session_id;
7658 
7659 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
7660 				 WMI_EXTSCAN_STOP_CMDID)) {
7661 		WMI_LOGE("%s: failed to  command", __func__);
7662 		wmi_buf_free(wmi_buf);
7663 		return QDF_STATUS_E_FAILURE;
7664 	}
7665 
7666 	return QDF_STATUS_SUCCESS;
7667 }
7668 
7669 /**
7670  * wmi_get_buf_extscan_start_cmd() - Fill extscan start request
7671  * @wmi_handle: wmi handle
7672  * @pstart: scan command request params
7673  * @buf: event buffer
7674  * @buf_len: length of buffer
7675  *
7676  * This function fills individual elements of extscan request and
7677  * TLV for buckets, channel list.
7678  *
7679  * Return: CDF Status.
7680  */
7681 static
7682 QDF_STATUS wmi_get_buf_extscan_start_cmd(wmi_unified_t wmi_handle,
7683 			 struct wifi_scan_cmd_req_params *pstart,
7684 			 wmi_buf_t *buf, int *buf_len)
7685 {
7686 	wmi_extscan_start_cmd_fixed_param *cmd;
7687 	wmi_extscan_bucket *dest_blist;
7688 	wmi_extscan_bucket_channel *dest_clist;
7689 	struct wifi_scan_bucket_params *src_bucket = pstart->buckets;
7690 	struct wifi_scan_channelspec_params *src_channel = src_bucket->channels;
7691 	struct wifi_scan_channelspec_params save_channel[WMI_WLAN_EXTSCAN_MAX_CHANNELS];
7692 
7693 	uint8_t *buf_ptr;
7694 	int i, k, count = 0;
7695 	int len = sizeof(*cmd);
7696 	int nbuckets = pstart->numBuckets;
7697 	int nchannels = 0;
7698 
7699 	/* These TLV's are are NULL by default */
7700 	uint32_t ie_len_with_pad = 0;
7701 	int num_ssid = 0;
7702 	int num_bssid = 0;
7703 	int ie_len = 0;
7704 
7705 	uint32_t base_period = pstart->basePeriod;
7706 
7707 	/* TLV placeholder for ssid_list (NULL) */
7708 	len += WMI_TLV_HDR_SIZE;
7709 	len += num_ssid * sizeof(wmi_ssid);
7710 
7711 	/* TLV placeholder for bssid_list (NULL) */
7712 	len += WMI_TLV_HDR_SIZE;
7713 	len += num_bssid * sizeof(wmi_mac_addr);
7714 
7715 	/* TLV placeholder for ie_data (NULL) */
7716 	len += WMI_TLV_HDR_SIZE;
7717 	len += ie_len * sizeof(uint32_t);
7718 
7719 	/* TLV placeholder for bucket */
7720 	len += WMI_TLV_HDR_SIZE;
7721 	len += nbuckets * sizeof(wmi_extscan_bucket);
7722 
7723 	/* TLV channel placeholder */
7724 	len += WMI_TLV_HDR_SIZE;
7725 	for (i = 0; i < nbuckets; i++) {
7726 		nchannels += src_bucket->numChannels;
7727 		src_bucket++;
7728 	}
7729 
7730 	WMI_LOGD("%s: Total buckets: %d total #of channels is %d",
7731 		__func__, nbuckets, nchannels);
7732 	len += nchannels * sizeof(wmi_extscan_bucket_channel);
7733 	/* Allocate the memory */
7734 	*buf = wmi_buf_alloc(wmi_handle, len);
7735 	if (!*buf) {
7736 		WMI_LOGP("%s: failed to allocate memory"
7737 			 " for start extscan cmd", __func__);
7738 		return QDF_STATUS_E_NOMEM;
7739 	}
7740 	buf_ptr = (uint8_t *) wmi_buf_data(*buf);
7741 	cmd = (wmi_extscan_start_cmd_fixed_param *) buf_ptr;
7742 	WMITLV_SET_HDR(&cmd->tlv_header,
7743 		       WMITLV_TAG_STRUC_wmi_extscan_start_cmd_fixed_param,
7744 		       WMITLV_GET_STRUCT_TLVLEN
7745 			       (wmi_extscan_start_cmd_fixed_param));
7746 
7747 	cmd->request_id = pstart->requestId;
7748 	cmd->vdev_id = pstart->sessionId;
7749 	cmd->base_period = pstart->basePeriod;
7750 	cmd->num_buckets = nbuckets;
7751 	cmd->configuration_flags = 0;
7752 	if (pstart->configuration_flags & WMI_EXTSCAN_LP_EXTENDED_BATCHING)
7753 		cmd->configuration_flags |= WMI_EXTSCAN_EXTENDED_BATCHING_EN;
7754 	WMI_LOGI("%s: configuration_flags: 0x%x", __func__,
7755 			cmd->configuration_flags);
7756 #ifdef FEATURE_WLAN_EXTSCAN
7757 	cmd->min_rest_time = WMI_EXTSCAN_REST_TIME;
7758 	cmd->max_rest_time = WMI_EXTSCAN_REST_TIME;
7759 	cmd->max_scan_time = WMI_EXTSCAN_MAX_SCAN_TIME;
7760 	cmd->burst_duration = WMI_EXTSCAN_BURST_DURATION;
7761 #endif
7762 	cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan;
7763 
7764 	/* The max dwell time is retrieved from the first channel
7765 	 * of the first bucket and kept common for all channels.
7766 	 */
7767 	cmd->min_dwell_time_active = pstart->min_dwell_time_active;
7768 	cmd->max_dwell_time_active = pstart->max_dwell_time_active;
7769 	cmd->min_dwell_time_passive = pstart->min_dwell_time_passive;
7770 	cmd->max_dwell_time_passive = pstart->max_dwell_time_passive;
7771 	cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan;
7772 	cmd->max_table_usage = pstart->report_threshold_percent;
7773 	cmd->report_threshold_num_scans = pstart->report_threshold_num_scans;
7774 
7775 	cmd->repeat_probe_time = cmd->max_dwell_time_active /
7776 					WMI_SCAN_NPROBES_DEFAULT;
7777 	cmd->probe_delay = 0;
7778 	cmd->probe_spacing_time = 0;
7779 	cmd->idle_time = 0;
7780 	cmd->scan_ctrl_flags = WMI_SCAN_ADD_BCAST_PROBE_REQ |
7781 			       WMI_SCAN_ADD_CCK_RATES |
7782 			       WMI_SCAN_ADD_OFDM_RATES |
7783 			       WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ |
7784 			       WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
7785 	WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags,
7786 			pstart->extscan_adaptive_dwell_mode);
7787 	cmd->scan_priority = WMI_SCAN_PRIORITY_VERY_LOW;
7788 	cmd->num_ssids = 0;
7789 	cmd->num_bssid = 0;
7790 	cmd->ie_len = 0;
7791 	cmd->n_probes = (cmd->repeat_probe_time > 0) ?
7792 			cmd->max_dwell_time_active / cmd->repeat_probe_time : 0;
7793 
7794 	buf_ptr += sizeof(*cmd);
7795 	WMITLV_SET_HDR(buf_ptr,
7796 		       WMITLV_TAG_ARRAY_FIXED_STRUC,
7797 		       num_ssid * sizeof(wmi_ssid));
7798 	buf_ptr += WMI_TLV_HDR_SIZE + (num_ssid * sizeof(wmi_ssid));
7799 
7800 	WMITLV_SET_HDR(buf_ptr,
7801 		       WMITLV_TAG_ARRAY_FIXED_STRUC,
7802 		       num_bssid * sizeof(wmi_mac_addr));
7803 	buf_ptr += WMI_TLV_HDR_SIZE + (num_bssid * sizeof(wmi_mac_addr));
7804 
7805 	ie_len_with_pad = 0;
7806 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
7807 			  ie_len_with_pad);
7808 	buf_ptr += WMI_TLV_HDR_SIZE + ie_len_with_pad;
7809 
7810 	WMITLV_SET_HDR(buf_ptr,
7811 		       WMITLV_TAG_ARRAY_STRUC,
7812 		       nbuckets * sizeof(wmi_extscan_bucket));
7813 	dest_blist = (wmi_extscan_bucket *)
7814 		     (buf_ptr + WMI_TLV_HDR_SIZE);
7815 	src_bucket = pstart->buckets;
7816 
7817 	/* Retrieve scanning information from each bucket and
7818 	 * channels and send it to the target
7819 	 */
7820 	for (i = 0; i < nbuckets; i++) {
7821 		WMITLV_SET_HDR(dest_blist,
7822 		      WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param,
7823 		      WMITLV_GET_STRUCT_TLVLEN(wmi_extscan_bucket));
7824 
7825 		dest_blist->bucket_id = src_bucket->bucket;
7826 		dest_blist->base_period_multiplier =
7827 			src_bucket->period / base_period;
7828 		dest_blist->min_period = src_bucket->period;
7829 		dest_blist->max_period = src_bucket->max_period;
7830 		dest_blist->exp_backoff = src_bucket->exponent;
7831 		dest_blist->exp_max_step_count = src_bucket->step_count;
7832 		dest_blist->channel_band = src_bucket->band;
7833 		dest_blist->num_channels = src_bucket->numChannels;
7834 		dest_blist->notify_extscan_events = 0;
7835 
7836 		if (src_bucket->reportEvents & WMI_EXTSCAN_REPORT_EVENTS_EACH_SCAN)
7837 			dest_blist->notify_extscan_events =
7838 					WMI_EXTSCAN_CYCLE_COMPLETED_EVENT |
7839 					WMI_EXTSCAN_CYCLE_STARTED_EVENT;
7840 
7841 		if (src_bucket->reportEvents &
7842 				WMI_EXTSCAN_REPORT_EVENTS_FULL_RESULTS) {
7843 			dest_blist->forwarding_flags =
7844 				WMI_EXTSCAN_FORWARD_FRAME_TO_HOST;
7845 			dest_blist->notify_extscan_events |=
7846 				WMI_EXTSCAN_BUCKET_COMPLETED_EVENT |
7847 				WMI_EXTSCAN_CYCLE_STARTED_EVENT |
7848 				WMI_EXTSCAN_CYCLE_COMPLETED_EVENT;
7849 		} else {
7850 			dest_blist->forwarding_flags =
7851 				WMI_EXTSCAN_NO_FORWARDING;
7852 		}
7853 
7854 		if (src_bucket->reportEvents & WMI_EXTSCAN_REPORT_EVENTS_NO_BATCH)
7855 			dest_blist->configuration_flags = 0;
7856 		else
7857 			dest_blist->configuration_flags =
7858 				WMI_EXTSCAN_BUCKET_CACHE_RESULTS;
7859 
7860 		WMI_LOGI("%s: ntfy_extscan_events:%u cfg_flags:%u fwd_flags:%u",
7861 			__func__, dest_blist->notify_extscan_events,
7862 			dest_blist->configuration_flags,
7863 			dest_blist->forwarding_flags);
7864 
7865 		dest_blist->min_dwell_time_active =
7866 				   src_bucket->min_dwell_time_active;
7867 		dest_blist->max_dwell_time_active =
7868 				   src_bucket->max_dwell_time_active;
7869 		dest_blist->min_dwell_time_passive =
7870 				   src_bucket->min_dwell_time_passive;
7871 		dest_blist->max_dwell_time_passive =
7872 				   src_bucket->max_dwell_time_passive;
7873 		src_channel = src_bucket->channels;
7874 
7875 		/* save the channel info to later populate
7876 		 * the  channel TLV
7877 		 */
7878 		for (k = 0; k < src_bucket->numChannels; k++) {
7879 			save_channel[count++].channel = src_channel->channel;
7880 			src_channel++;
7881 		}
7882 		dest_blist++;
7883 		src_bucket++;
7884 	}
7885 	buf_ptr += WMI_TLV_HDR_SIZE + (nbuckets * sizeof(wmi_extscan_bucket));
7886 	WMITLV_SET_HDR(buf_ptr,
7887 		       WMITLV_TAG_ARRAY_STRUC,
7888 		       nchannels * sizeof(wmi_extscan_bucket_channel));
7889 	dest_clist = (wmi_extscan_bucket_channel *)
7890 		     (buf_ptr + WMI_TLV_HDR_SIZE);
7891 
7892 	/* Active or passive scan is based on the bucket dwell time
7893 	 * and channel specific active,passive scans are not
7894 	 * supported yet
7895 	 */
7896 	for (i = 0; i < nchannels; i++) {
7897 		WMITLV_SET_HDR(dest_clist,
7898 		WMITLV_TAG_STRUC_wmi_extscan_bucket_channel_event_fixed_param,
7899 			   WMITLV_GET_STRUCT_TLVLEN
7900 			   (wmi_extscan_bucket_channel));
7901 		dest_clist->channel = save_channel[i].channel;
7902 		dest_clist++;
7903 	}
7904 	buf_ptr += WMI_TLV_HDR_SIZE +
7905 		   (nchannels * sizeof(wmi_extscan_bucket_channel));
7906 	*buf_len = len;
7907 	return QDF_STATUS_SUCCESS;
7908 }
7909 
7910 /**
7911  * send_start_extscan_cmd_tlv() - start extscan command to fw.
7912  * @wmi_handle: wmi handle
7913  * @pstart: scan command request params
7914  *
7915  * This function sends start extscan request to fw.
7916  *
7917  * Return: CDF Status.
7918  */
7919 static QDF_STATUS send_start_extscan_cmd_tlv(wmi_unified_t wmi_handle,
7920 			  struct wifi_scan_cmd_req_params *pstart)
7921 {
7922 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
7923 	wmi_buf_t buf;
7924 	int len;
7925 
7926 	/* Fill individual elements of extscan request and
7927 	 * TLV for buckets, channel list.
7928 	 */
7929 	qdf_status = wmi_get_buf_extscan_start_cmd(wmi_handle,
7930 			     pstart, &buf, &len);
7931 	if (qdf_status != QDF_STATUS_SUCCESS) {
7932 		WMI_LOGE("%s: Failed to get buffer for ext scan cmd", __func__);
7933 		return QDF_STATUS_E_FAILURE;
7934 	}
7935 	if (!buf) {
7936 		WMI_LOGE("%s:Failed to get buffer"
7937 			 "for current extscan info", __func__);
7938 		return QDF_STATUS_E_FAILURE;
7939 	}
7940 	if (wmi_unified_cmd_send(wmi_handle, buf,
7941 				 len, WMI_EXTSCAN_START_CMDID)) {
7942 		WMI_LOGE("%s: failed to send command", __func__);
7943 		wmi_buf_free(buf);
7944 		return QDF_STATUS_E_FAILURE;
7945 	}
7946 
7947 	return QDF_STATUS_SUCCESS;
7948 }
7949 
7950 /**
7951  * send_plm_stop_cmd_tlv() - plm stop request
7952  * @wmi_handle: wmi handle
7953  * @plm: plm request parameters
7954  *
7955  * This function request FW to stop PLM.
7956  *
7957  * Return: CDF status
7958  */
7959 static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle,
7960 			  const struct plm_req_params *plm)
7961 {
7962 	wmi_vdev_plmreq_stop_cmd_fixed_param *cmd;
7963 	int32_t len;
7964 	wmi_buf_t buf;
7965 	uint8_t *buf_ptr;
7966 	int ret;
7967 
7968 	len = sizeof(*cmd);
7969 	buf = wmi_buf_alloc(wmi_handle, len);
7970 	if (!buf) {
7971 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7972 		return QDF_STATUS_E_NOMEM;
7973 	}
7974 
7975 	cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf);
7976 
7977 	buf_ptr = (uint8_t *) cmd;
7978 
7979 	WMITLV_SET_HDR(&cmd->tlv_header,
7980 		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param,
7981 		       WMITLV_GET_STRUCT_TLVLEN
7982 		       (wmi_vdev_plmreq_stop_cmd_fixed_param));
7983 
7984 	cmd->vdev_id = plm->session_id;
7985 
7986 	cmd->meas_token = plm->meas_token;
7987 	WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token);
7988 
7989 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7990 				   WMI_VDEV_PLMREQ_STOP_CMDID);
7991 	if (ret) {
7992 		WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__);
7993 		wmi_buf_free(buf);
7994 		return QDF_STATUS_E_FAILURE;
7995 	}
7996 
7997 	return QDF_STATUS_SUCCESS;
7998 }
7999 
8000 /**
8001  * send_plm_start_cmd_tlv() - plm start request
8002  * @wmi_handle: wmi handle
8003  * @plm: plm request parameters
8004  *
8005  * This function request FW to start PLM.
8006  *
8007  * Return: CDF status
8008  */
8009 static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle,
8010 			  const struct plm_req_params *plm,
8011 			  uint32_t *gchannel_list)
8012 {
8013 	wmi_vdev_plmreq_start_cmd_fixed_param *cmd;
8014 	uint32_t *channel_list;
8015 	int32_t len;
8016 	wmi_buf_t buf;
8017 	uint8_t *buf_ptr;
8018 	uint8_t count;
8019 	int ret;
8020 
8021 	/* TLV place holder for channel_list */
8022 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
8023 	len += sizeof(uint32_t) * plm->plm_num_ch;
8024 
8025 	buf = wmi_buf_alloc(wmi_handle, len);
8026 	if (!buf) {
8027 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8028 		return QDF_STATUS_E_NOMEM;
8029 	}
8030 	cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf);
8031 
8032 	buf_ptr = (uint8_t *) cmd;
8033 
8034 	WMITLV_SET_HDR(&cmd->tlv_header,
8035 		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param,
8036 		       WMITLV_GET_STRUCT_TLVLEN
8037 			       (wmi_vdev_plmreq_start_cmd_fixed_param));
8038 
8039 	cmd->vdev_id = plm->session_id;
8040 
8041 	cmd->meas_token = plm->meas_token;
8042 	cmd->dialog_token = plm->diag_token;
8043 	cmd->number_bursts = plm->num_bursts;
8044 	cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int);
8045 	cmd->off_duration = plm->meas_duration;
8046 	cmd->burst_cycle = plm->burst_len;
8047 	cmd->tx_power = plm->desired_tx_pwr;
8048 	WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac);
8049 	cmd->num_chans = plm->plm_num_ch;
8050 
8051 	buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param);
8052 
8053 	WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token);
8054 	WMI_LOGD("dialog_token: %d", cmd->dialog_token);
8055 	WMI_LOGD("number_bursts: %d", cmd->number_bursts);
8056 	WMI_LOGD("burst_interval: %d", cmd->burst_interval);
8057 	WMI_LOGD("off_duration: %d", cmd->off_duration);
8058 	WMI_LOGD("burst_cycle: %d", cmd->burst_cycle);
8059 	WMI_LOGD("tx_power: %d", cmd->tx_power);
8060 	WMI_LOGD("Number of channels : %d", cmd->num_chans);
8061 
8062 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
8063 		       (cmd->num_chans * sizeof(uint32_t)));
8064 
8065 	buf_ptr += WMI_TLV_HDR_SIZE;
8066 	if (cmd->num_chans) {
8067 		channel_list = (uint32_t *) buf_ptr;
8068 		for (count = 0; count < cmd->num_chans; count++) {
8069 			channel_list[count] = plm->plm_ch_list[count];
8070 			if (channel_list[count] < WMI_NLO_FREQ_THRESH)
8071 				channel_list[count] =
8072 					gchannel_list[count];
8073 			WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]);
8074 		}
8075 		buf_ptr += cmd->num_chans * sizeof(uint32_t);
8076 	}
8077 
8078 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8079 				   WMI_VDEV_PLMREQ_START_CMDID);
8080 	if (ret) {
8081 		WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__);
8082 		wmi_buf_free(buf);
8083 		return QDF_STATUS_E_FAILURE;
8084 	}
8085 
8086 	return QDF_STATUS_SUCCESS;
8087 }
8088 
8089 /**
8090  * send_pno_stop_cmd_tlv() - PNO stop request
8091  * @wmi_handle: wmi handle
8092  * @vdev_id: vdev id
8093  *
8094  * This function request FW to stop ongoing PNO operation.
8095  *
8096  * Return: CDF status
8097  */
8098 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
8099 {
8100 	wmi_nlo_config_cmd_fixed_param *cmd;
8101 	int32_t len = sizeof(*cmd);
8102 	wmi_buf_t buf;
8103 	uint8_t *buf_ptr;
8104 	int ret;
8105 
8106 	/*
8107 	 * TLV place holder for array of structures nlo_configured_parameters
8108 	 * TLV place holder for array of uint32_t channel_list
8109 	 * TLV place holder for chnl prediction cfg
8110 	 */
8111 	len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE;
8112 	buf = wmi_buf_alloc(wmi_handle, len);
8113 	if (!buf) {
8114 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8115 		return QDF_STATUS_E_NOMEM;
8116 	}
8117 
8118 	cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf);
8119 	buf_ptr = (uint8_t *) cmd;
8120 
8121 	WMITLV_SET_HDR(&cmd->tlv_header,
8122 		       WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param,
8123 		       WMITLV_GET_STRUCT_TLVLEN
8124 			       (wmi_nlo_config_cmd_fixed_param));
8125 
8126 	cmd->vdev_id = vdev_id;
8127 	cmd->flags = WMI_NLO_CONFIG_STOP;
8128 	buf_ptr += sizeof(*cmd);
8129 
8130 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
8131 	buf_ptr += WMI_TLV_HDR_SIZE;
8132 
8133 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
8134 	buf_ptr += WMI_TLV_HDR_SIZE;
8135 
8136 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
8137 	buf_ptr += WMI_TLV_HDR_SIZE;
8138 
8139 
8140 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8141 				   WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
8142 	if (ret) {
8143 		WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__);
8144 		wmi_buf_free(buf);
8145 		return QDF_STATUS_E_FAILURE;
8146 	}
8147 
8148 	return QDF_STATUS_SUCCESS;
8149 }
8150 
8151 /**
8152  * wmi_set_pno_channel_prediction() - Set PNO channel prediction
8153  * @buf_ptr:      Buffer passed by upper layers
8154  * @pno:          Buffer to be sent to the firmware
8155  *
8156  * Copy the PNO Channel prediction configuration parameters
8157  * passed by the upper layers to a WMI format TLV and send it
8158  * down to the firmware.
8159  *
8160  * Return: None
8161  */
8162 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr,
8163 		struct pno_scan_req_params *pno)
8164 {
8165 	nlo_channel_prediction_cfg *channel_prediction_cfg =
8166 		(nlo_channel_prediction_cfg *) buf_ptr;
8167 	WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header,
8168 			WMITLV_TAG_ARRAY_BYTE,
8169 			WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg));
8170 #ifdef FEATURE_WLAN_SCAN_PNO
8171 	channel_prediction_cfg->enable = pno->pno_channel_prediction;
8172 	channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels;
8173 	channel_prediction_cfg->stationary_threshold = pno->stationary_thresh;
8174 	channel_prediction_cfg->full_scan_period_ms =
8175 		pno->channel_prediction_full_scan;
8176 #endif
8177 	buf_ptr += sizeof(nlo_channel_prediction_cfg);
8178 	WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d",
8179 			channel_prediction_cfg->enable,
8180 			channel_prediction_cfg->top_k_num,
8181 			channel_prediction_cfg->stationary_threshold,
8182 			channel_prediction_cfg->full_scan_period_ms);
8183 }
8184 
8185 /**
8186  * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration
8187  * @wmi_handle: wmi handle
8188  * @params: configuration parameters
8189  *
8190  * Return: QDF_STATUS
8191  */
8192 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle,
8193 		struct nlo_mawc_params *params)
8194 {
8195 	wmi_buf_t buf = NULL;
8196 	QDF_STATUS status;
8197 	int len;
8198 	uint8_t *buf_ptr;
8199 	wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params;
8200 
8201 	len = sizeof(*wmi_nlo_mawc_params);
8202 	buf = wmi_buf_alloc(wmi_handle, len);
8203 	if (!buf) {
8204 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
8205 		return QDF_STATUS_E_NOMEM;
8206 	}
8207 
8208 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8209 	wmi_nlo_mawc_params =
8210 		(wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr;
8211 	WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header,
8212 		       WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param,
8213 		       WMITLV_GET_STRUCT_TLVLEN
8214 			       (wmi_nlo_configure_mawc_cmd_fixed_param));
8215 	wmi_nlo_mawc_params->vdev_id = params->vdev_id;
8216 	if (params->enable)
8217 		wmi_nlo_mawc_params->enable = 1;
8218 	else
8219 		wmi_nlo_mawc_params->enable = 0;
8220 	wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio;
8221 	wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval;
8222 	wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval;
8223 	WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"),
8224 		wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id,
8225 		wmi_nlo_mawc_params->exp_backoff_ratio,
8226 		wmi_nlo_mawc_params->init_scan_interval,
8227 		wmi_nlo_mawc_params->max_scan_interval);
8228 
8229 	status = wmi_unified_cmd_send(wmi_handle, buf,
8230 				      len, WMI_NLO_CONFIGURE_MAWC_CMDID);
8231 	if (QDF_IS_STATUS_ERROR(status)) {
8232 		WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d",
8233 			status);
8234 		wmi_buf_free(buf);
8235 		return QDF_STATUS_E_FAILURE;
8236 	}
8237 
8238 	return QDF_STATUS_SUCCESS;
8239 }
8240 
8241 /**
8242  * send_pno_start_cmd_tlv() - PNO start request
8243  * @wmi_handle: wmi handle
8244  * @pno: PNO request
8245  *
8246  * This function request FW to start PNO request.
8247  * Request: CDF status
8248  */
8249 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle,
8250 		   struct pno_scan_req_params *pno)
8251 {
8252 	wmi_nlo_config_cmd_fixed_param *cmd;
8253 	nlo_configured_parameters *nlo_list;
8254 	uint32_t *channel_list;
8255 	int32_t len;
8256 	wmi_buf_t buf;
8257 	uint8_t *buf_ptr;
8258 	uint8_t i;
8259 	int ret;
8260 	struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist;
8261 	connected_nlo_rssi_params *nlo_relative_rssi;
8262 	connected_nlo_bss_band_rssi_pref *nlo_band_rssi;
8263 
8264 	/*
8265 	 * TLV place holder for array nlo_configured_parameters(nlo_list)
8266 	 * TLV place holder for array of uint32_t channel_list
8267 	 * TLV place holder for chnnl prediction cfg
8268 	 * TLV place holder for array of wmi_vendor_oui
8269 	 * TLV place holder for array of connected_nlo_bss_band_rssi_pref
8270 	 */
8271 	len = sizeof(*cmd) +
8272 		WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE +
8273 		WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE;
8274 
8275 	len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt,
8276 					  WMI_NLO_MAX_CHAN);
8277 	len += sizeof(nlo_configured_parameters) *
8278 	       QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS);
8279 	len += sizeof(nlo_channel_prediction_cfg);
8280 	len += sizeof(enlo_candidate_score_params);
8281 	len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui;
8282 	len += sizeof(connected_nlo_rssi_params);
8283 	len += sizeof(connected_nlo_bss_band_rssi_pref);
8284 
8285 	buf = wmi_buf_alloc(wmi_handle, len);
8286 	if (!buf) {
8287 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8288 		return QDF_STATUS_E_NOMEM;
8289 	}
8290 
8291 	cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf);
8292 
8293 	buf_ptr = (uint8_t *) cmd;
8294 	WMITLV_SET_HDR(&cmd->tlv_header,
8295 		       WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param,
8296 		       WMITLV_GET_STRUCT_TLVLEN
8297 			       (wmi_nlo_config_cmd_fixed_param));
8298 	cmd->vdev_id = pno->vdev_id;
8299 	cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN;
8300 
8301 #ifdef FEATURE_WLAN_SCAN_PNO
8302 	WMI_SCAN_SET_DWELL_MODE(cmd->flags,
8303 			pno->adaptive_dwell_mode);
8304 #endif
8305 	/* Current FW does not support min-max range for dwell time */
8306 	cmd->active_dwell_time = pno->active_dwell_time;
8307 	cmd->passive_dwell_time = pno->passive_dwell_time;
8308 
8309 	if (pno->do_passive_scan)
8310 		cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE;
8311 	/* Copy scan interval */
8312 	cmd->fast_scan_period = pno->fast_scan_period;
8313 	cmd->slow_scan_period = pno->slow_scan_period;
8314 	cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time);
8315 	cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles;
8316 	cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier;
8317 	WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec",
8318 			cmd->fast_scan_period, cmd->slow_scan_period);
8319 	WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles);
8320 
8321 	/* mac randomization attributes */
8322 	if (pno->scan_random.randomize) {
8323 		cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ |
8324 				WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ;
8325 		wmi_copy_scan_random_mac(pno->scan_random.mac_addr,
8326 					 pno->scan_random.mac_mask,
8327 					 &cmd->mac_addr,
8328 					 &cmd->mac_mask);
8329 	}
8330 
8331 	buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param);
8332 
8333 	cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS);
8334 	WMI_LOGD("SSID count : %d", cmd->no_of_ssids);
8335 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
8336 		       cmd->no_of_ssids * sizeof(nlo_configured_parameters));
8337 	buf_ptr += WMI_TLV_HDR_SIZE;
8338 
8339 	nlo_list = (nlo_configured_parameters *) buf_ptr;
8340 	for (i = 0; i < cmd->no_of_ssids; i++) {
8341 		WMITLV_SET_HDR(&nlo_list[i].tlv_header,
8342 			       WMITLV_TAG_ARRAY_BYTE,
8343 			       WMITLV_GET_STRUCT_TLVLEN
8344 				       (nlo_configured_parameters));
8345 		/* Copy ssid and it's length */
8346 		nlo_list[i].ssid.valid = true;
8347 		nlo_list[i].ssid.ssid.ssid_len =
8348 			pno->networks_list[i].ssid.length;
8349 		qdf_mem_copy(nlo_list[i].ssid.ssid.ssid,
8350 			     pno->networks_list[i].ssid.ssid,
8351 			     nlo_list[i].ssid.ssid.ssid_len);
8352 		WMI_LOGD("index: %d ssid: %.*s len: %d", i,
8353 			 nlo_list[i].ssid.ssid.ssid_len,
8354 			 (char *)nlo_list[i].ssid.ssid.ssid,
8355 			 nlo_list[i].ssid.ssid.ssid_len);
8356 
8357 		/* Copy rssi threshold */
8358 		if (pno->networks_list[i].rssi_thresh &&
8359 		    pno->networks_list[i].rssi_thresh >
8360 		    WMI_RSSI_THOLD_DEFAULT) {
8361 			nlo_list[i].rssi_cond.valid = true;
8362 			nlo_list[i].rssi_cond.rssi =
8363 				pno->networks_list[i].rssi_thresh;
8364 			WMI_LOGD("RSSI threshold : %d dBm",
8365 				 nlo_list[i].rssi_cond.rssi);
8366 		}
8367 		nlo_list[i].bcast_nw_type.valid = true;
8368 		nlo_list[i].bcast_nw_type.bcast_nw_type =
8369 			pno->networks_list[i].bc_new_type;
8370 		WMI_LOGD("Broadcast NW type (%u)",
8371 			 nlo_list[i].bcast_nw_type.bcast_nw_type);
8372 	}
8373 	buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters);
8374 
8375 	/* Copy channel info */
8376 	cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt,
8377 				       WMI_NLO_MAX_CHAN);
8378 	WMI_LOGD("Channel count: %d", cmd->num_of_channels);
8379 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
8380 		       (cmd->num_of_channels * sizeof(uint32_t)));
8381 	buf_ptr += WMI_TLV_HDR_SIZE;
8382 
8383 	channel_list = (uint32_t *) buf_ptr;
8384 	for (i = 0; i < cmd->num_of_channels; i++) {
8385 		channel_list[i] = pno->networks_list[0].channels[i];
8386 
8387 		if (channel_list[i] < WMI_NLO_FREQ_THRESH)
8388 			channel_list[i] =
8389 				wlan_chan_to_freq(pno->
8390 					networks_list[0].channels[i]);
8391 
8392 		WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]);
8393 	}
8394 	buf_ptr += cmd->num_of_channels * sizeof(uint32_t);
8395 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
8396 			sizeof(nlo_channel_prediction_cfg));
8397 	buf_ptr += WMI_TLV_HDR_SIZE;
8398 	wmi_set_pno_channel_prediction(buf_ptr, pno);
8399 	buf_ptr += sizeof(nlo_channel_prediction_cfg);
8400 	/** TODO: Discrete firmware doesn't have command/option to configure
8401 	 * App IE which comes from wpa_supplicant as of part PNO start request.
8402 	 */
8403 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param,
8404 		       WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params));
8405 	buf_ptr += sizeof(enlo_candidate_score_params);
8406 
8407 	if (ie_whitelist->white_list) {
8408 		cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ;
8409 		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
8410 					    &cmd->num_vendor_oui,
8411 					    ie_whitelist);
8412 	}
8413 
8414 	/* ie white list */
8415 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
8416 		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
8417 	buf_ptr += WMI_TLV_HDR_SIZE;
8418 	if (cmd->num_vendor_oui != 0) {
8419 		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
8420 				    ie_whitelist->voui);
8421 		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
8422 	}
8423 
8424 	if (pno->relative_rssi_set)
8425 		cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG;
8426 
8427 	/*
8428 	 * Firmware calculation using connected PNO params:
8429 	 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref)
8430 	 * deduction of rssi_pref for chosen band_pref and
8431 	 * addition of rssi_pref for remaining bands (other than chosen band).
8432 	 */
8433 	nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr;
8434 	WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header,
8435 		WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params,
8436 		WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params));
8437 	nlo_relative_rssi->relative_rssi = pno->relative_rssi;
8438 	WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi);
8439 	buf_ptr += sizeof(*nlo_relative_rssi);
8440 
8441 	/*
8442 	 * As of now Kernel and Host supports one band and rssi preference.
8443 	 * Firmware supports array of band and rssi preferences
8444 	 */
8445 	cmd->num_cnlo_band_pref = 1;
8446 	WMITLV_SET_HDR(buf_ptr,
8447 		WMITLV_TAG_ARRAY_STRUC,
8448 		cmd->num_cnlo_band_pref *
8449 		sizeof(connected_nlo_bss_band_rssi_pref));
8450 	buf_ptr += WMI_TLV_HDR_SIZE;
8451 
8452 	nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr;
8453 	for (i = 0; i < cmd->num_cnlo_band_pref; i++) {
8454 		WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header,
8455 			WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref,
8456 			WMITLV_GET_STRUCT_TLVLEN(
8457 				connected_nlo_bss_band_rssi_pref));
8458 		nlo_band_rssi[i].band = pno->band_rssi_pref.band;
8459 		nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi;
8460 		WMI_LOGI("band_pref %d, rssi_pref %d",
8461 			nlo_band_rssi[i].band,
8462 			nlo_band_rssi[i].rssi_pref);
8463 	}
8464 	buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi);
8465 
8466 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8467 				   WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
8468 	if (ret) {
8469 		WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__);
8470 		wmi_buf_free(buf);
8471 		return QDF_STATUS_E_FAILURE;
8472 	}
8473 
8474 	return QDF_STATUS_SUCCESS;
8475 }
8476 
8477 /* send_set_ric_req_cmd_tlv() - set ric request element
8478  * @wmi_handle: wmi handle
8479  * @msg: message
8480  * @is_add_ts: is addts required
8481  *
8482  * This function sets ric request element for 11r roaming.
8483  *
8484  * Return: CDF status
8485  */
8486 static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle,
8487 			void *msg, uint8_t is_add_ts)
8488 {
8489 	wmi_ric_request_fixed_param *cmd;
8490 	wmi_ric_tspec *tspec_param;
8491 	wmi_buf_t buf;
8492 	uint8_t *buf_ptr;
8493 	struct mac_tspec_ie *ptspecIE = NULL;
8494 	int32_t len = sizeof(wmi_ric_request_fixed_param) +
8495 		      WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec);
8496 
8497 	buf = wmi_buf_alloc(wmi_handle, len);
8498 	if (!buf) {
8499 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
8500 		return QDF_STATUS_E_NOMEM;
8501 	}
8502 
8503 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8504 
8505 	cmd = (wmi_ric_request_fixed_param *) buf_ptr;
8506 	WMITLV_SET_HDR(&cmd->tlv_header,
8507 		   WMITLV_TAG_STRUC_wmi_ric_request_fixed_param,
8508 		   WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param));
8509 	if (is_add_ts)
8510 		cmd->vdev_id = ((struct add_ts_param *) msg)->sme_session_id;
8511 	else
8512 		cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId;
8513 	cmd->num_ric_request = 1;
8514 	cmd->is_add_ric = is_add_ts;
8515 
8516 	buf_ptr += sizeof(wmi_ric_request_fixed_param);
8517 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec));
8518 
8519 	buf_ptr += WMI_TLV_HDR_SIZE;
8520 	tspec_param = (wmi_ric_tspec *) buf_ptr;
8521 	WMITLV_SET_HDR(&tspec_param->tlv_header,
8522 		       WMITLV_TAG_STRUC_wmi_ric_tspec,
8523 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec));
8524 
8525 	if (is_add_ts)
8526 		ptspecIE = &(((struct add_ts_param *) msg)->tspec);
8527 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
8528 	else
8529 		ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec);
8530 #endif
8531 	if (ptspecIE) {
8532 		/* Fill the tsinfo in the format expected by firmware */
8533 #ifndef ANI_LITTLE_BIT_ENDIAN
8534 		qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1,
8535 			     ((uint8_t *) &ptspecIE->tsinfo) + 1, 2);
8536 #else
8537 		qdf_mem_copy(((uint8_t *) &tspec_param->ts_info),
8538 			     ((uint8_t *) &ptspecIE->tsinfo) + 1, 2);
8539 #endif /* ANI_LITTLE_BIT_ENDIAN */
8540 
8541 		tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz;
8542 		tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz;
8543 		tspec_param->min_service_interval = ptspecIE->minSvcInterval;
8544 		tspec_param->max_service_interval = ptspecIE->maxSvcInterval;
8545 		tspec_param->inactivity_interval = ptspecIE->inactInterval;
8546 		tspec_param->suspension_interval = ptspecIE->suspendInterval;
8547 		tspec_param->svc_start_time = ptspecIE->svcStartTime;
8548 		tspec_param->min_data_rate = ptspecIE->minDataRate;
8549 		tspec_param->mean_data_rate = ptspecIE->meanDataRate;
8550 		tspec_param->peak_data_rate = ptspecIE->peakDataRate;
8551 		tspec_param->max_burst_size = ptspecIE->maxBurstSz;
8552 		tspec_param->delay_bound = ptspecIE->delayBound;
8553 		tspec_param->min_phy_rate = ptspecIE->minPhyRate;
8554 		tspec_param->surplus_bw_allowance = ptspecIE->surplusBw;
8555 		tspec_param->medium_time = 0;
8556 	}
8557 	WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts);
8558 
8559 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8560 				 WMI_ROAM_SET_RIC_REQUEST_CMDID)) {
8561 		WMI_LOGP("%s: Failed to send vdev Set RIC Req command",
8562 			 __func__);
8563 		if (is_add_ts)
8564 			((struct add_ts_param *) msg)->status =
8565 					    QDF_STATUS_E_FAILURE;
8566 		wmi_buf_free(buf);
8567 		return QDF_STATUS_E_FAILURE;
8568 	}
8569 
8570 	return QDF_STATUS_SUCCESS;
8571 }
8572 
8573 /**
8574  * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats
8575  * @wmi_handle: wmi handle
8576  * @clear_req: ll stats clear request command params
8577  *
8578  * Return: QDF_STATUS_SUCCESS for success or error code
8579  */
8580 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle,
8581 		const struct ll_stats_clear_params *clear_req,
8582 		uint8_t addr[IEEE80211_ADDR_LEN])
8583 {
8584 	wmi_clear_link_stats_cmd_fixed_param *cmd;
8585 	int32_t len;
8586 	wmi_buf_t buf;
8587 	uint8_t *buf_ptr;
8588 	int ret;
8589 
8590 	len = sizeof(*cmd);
8591 	buf = wmi_buf_alloc(wmi_handle, len);
8592 
8593 	if (!buf) {
8594 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8595 		return QDF_STATUS_E_NOMEM;
8596 	}
8597 
8598 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8599 	qdf_mem_zero(buf_ptr, len);
8600 	cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr;
8601 
8602 	WMITLV_SET_HDR(&cmd->tlv_header,
8603 		       WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param,
8604 		       WMITLV_GET_STRUCT_TLVLEN
8605 			       (wmi_clear_link_stats_cmd_fixed_param));
8606 
8607 	cmd->stop_stats_collection_req = clear_req->stop_req;
8608 	cmd->vdev_id = clear_req->sta_id;
8609 	cmd->stats_clear_req_mask = clear_req->stats_clear_mask;
8610 
8611 	WMI_CHAR_ARRAY_TO_MAC_ADDR(addr,
8612 				   &cmd->peer_macaddr);
8613 
8614 	WMI_LOGD("LINK_LAYER_STATS - Clear Request Params");
8615 	WMI_LOGD("StopReq         : %d", cmd->stop_stats_collection_req);
8616 	WMI_LOGD("Vdev Id         : %d", cmd->vdev_id);
8617 	WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask);
8618 	/* WMI_LOGD("Peer MAC Addr   : %pM",
8619 		 cmd->peer_macaddr); */
8620 
8621 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8622 				   WMI_CLEAR_LINK_STATS_CMDID);
8623 	if (ret) {
8624 		WMI_LOGE("%s: Failed to send clear link stats req", __func__);
8625 		wmi_buf_free(buf);
8626 		return QDF_STATUS_E_FAILURE;
8627 	}
8628 
8629 	WMI_LOGD("Clear Link Layer Stats request sent successfully");
8630 	return QDF_STATUS_SUCCESS;
8631 }
8632 
8633 /**
8634  * send_process_ll_stats_set_cmd_tlv() - link layer stats set request
8635  * @wmi_handle:       wmi handle
8636  * @setReq:  ll stats set request command params
8637  *
8638  * Return: QDF_STATUS_SUCCESS for success or error code
8639  */
8640 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle,
8641 		const struct ll_stats_set_params *set_req)
8642 {
8643 	wmi_start_link_stats_cmd_fixed_param *cmd;
8644 	int32_t len;
8645 	wmi_buf_t buf;
8646 	uint8_t *buf_ptr;
8647 	int ret;
8648 
8649 	len = sizeof(*cmd);
8650 	buf = wmi_buf_alloc(wmi_handle, len);
8651 
8652 	if (!buf) {
8653 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
8654 		return QDF_STATUS_E_NOMEM;
8655 	}
8656 
8657 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8658 	qdf_mem_zero(buf_ptr, len);
8659 	cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr;
8660 
8661 	WMITLV_SET_HDR(&cmd->tlv_header,
8662 		       WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param,
8663 		       WMITLV_GET_STRUCT_TLVLEN
8664 			       (wmi_start_link_stats_cmd_fixed_param));
8665 
8666 	cmd->mpdu_size_threshold = set_req->mpdu_size_threshold;
8667 	cmd->aggressive_statistics_gathering =
8668 		set_req->aggressive_statistics_gathering;
8669 
8670 	WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params");
8671 	WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold);
8672 	WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering);
8673 
8674 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8675 				   WMI_START_LINK_STATS_CMDID);
8676 	if (ret) {
8677 		WMI_LOGE("%s: Failed to send set link stats request", __func__);
8678 		wmi_buf_free(buf);
8679 		return QDF_STATUS_E_FAILURE;
8680 	}
8681 
8682 	return QDF_STATUS_SUCCESS;
8683 }
8684 
8685 /**
8686  * send_process_ll_stats_get_cmd_tlv() - link layer stats get request
8687  * @wmi_handle:wmi handle
8688  * @get_req:ll stats get request command params
8689  * @addr: mac address
8690  *
8691  * Return: QDF_STATUS_SUCCESS for success or error code
8692  */
8693 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle,
8694 		 const struct ll_stats_get_params  *get_req,
8695 		 uint8_t addr[IEEE80211_ADDR_LEN])
8696 {
8697 	wmi_request_link_stats_cmd_fixed_param *cmd;
8698 	int32_t len;
8699 	wmi_buf_t buf;
8700 	uint8_t *buf_ptr;
8701 	int ret;
8702 
8703 	len = sizeof(*cmd);
8704 	buf = wmi_buf_alloc(wmi_handle, len);
8705 
8706 	if (!buf) {
8707 		WMI_LOGE("%s: buf allocation failed", __func__);
8708 		return QDF_STATUS_E_NOMEM;
8709 	}
8710 
8711 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8712 	qdf_mem_zero(buf_ptr, len);
8713 	cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr;
8714 
8715 	WMITLV_SET_HDR(&cmd->tlv_header,
8716 		       WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param,
8717 		       WMITLV_GET_STRUCT_TLVLEN
8718 			       (wmi_request_link_stats_cmd_fixed_param));
8719 
8720 	cmd->request_id = get_req->req_id;
8721 	cmd->stats_type = get_req->param_id_mask;
8722 	cmd->vdev_id = get_req->sta_id;
8723 
8724 	WMI_CHAR_ARRAY_TO_MAC_ADDR(addr,
8725 				   &cmd->peer_macaddr);
8726 
8727 	WMI_LOGD("LINK_LAYER_STATS - Get Request Params");
8728 	WMI_LOGD("Request ID      : %u", cmd->request_id);
8729 	WMI_LOGD("Stats Type      : %0x", cmd->stats_type);
8730 	WMI_LOGD("Vdev ID         : %d", cmd->vdev_id);
8731 	WMI_LOGD("Peer MAC Addr   : %pM", addr);
8732 
8733 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8734 				   WMI_REQUEST_LINK_STATS_CMDID);
8735 	if (ret) {
8736 		WMI_LOGE("%s: Failed to send get link stats request", __func__);
8737 		wmi_buf_free(buf);
8738 		return QDF_STATUS_E_FAILURE;
8739 	}
8740 
8741 	return QDF_STATUS_SUCCESS;
8742 }
8743 
8744 
8745 /**
8746  * send_congestion_cmd_tlv() - send request to fw to get CCA
8747  * @wmi_handle: wmi handle
8748  * @vdev_id: vdev id
8749  *
8750  * Return: CDF status
8751  */
8752 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle,
8753 			A_UINT8 vdev_id)
8754 {
8755 	wmi_buf_t buf;
8756 	wmi_request_stats_cmd_fixed_param *cmd;
8757 	uint8_t len;
8758 	uint8_t *buf_ptr;
8759 
8760 	len = sizeof(*cmd);
8761 	buf = wmi_buf_alloc(wmi_handle, len);
8762 	if (!buf) {
8763 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
8764 		return QDF_STATUS_E_FAILURE;
8765 	}
8766 
8767 	buf_ptr = wmi_buf_data(buf);
8768 	cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr;
8769 	WMITLV_SET_HDR(&cmd->tlv_header,
8770 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8771 		       WMITLV_GET_STRUCT_TLVLEN
8772 			       (wmi_request_stats_cmd_fixed_param));
8773 
8774 	cmd->stats_id = WMI_REQUEST_CONGESTION_STAT;
8775 	cmd->vdev_id = vdev_id;
8776 	WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->",
8777 			cmd->vdev_id, cmd->stats_id);
8778 
8779 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8780 				 WMI_REQUEST_STATS_CMDID)) {
8781 		WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID",
8782 			 __func__);
8783 		wmi_buf_free(buf);
8784 		return QDF_STATUS_E_FAILURE;
8785 	}
8786 
8787 	return QDF_STATUS_SUCCESS;
8788 }
8789 
8790 /**
8791  * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats
8792  * @wmi_handle: wmi handle
8793  * @rssi_req: get RSSI request
8794  *
8795  * Return: CDF status
8796  */
8797 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle)
8798 {
8799 	wmi_buf_t buf;
8800 	wmi_request_stats_cmd_fixed_param *cmd;
8801 	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
8802 
8803 	buf = wmi_buf_alloc(wmi_handle, len);
8804 	if (!buf) {
8805 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8806 		return QDF_STATUS_E_FAILURE;
8807 	}
8808 
8809 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
8810 	WMITLV_SET_HDR(&cmd->tlv_header,
8811 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8812 		       WMITLV_GET_STRUCT_TLVLEN
8813 			       (wmi_request_stats_cmd_fixed_param));
8814 	cmd->stats_id = WMI_REQUEST_VDEV_STAT;
8815 	if (wmi_unified_cmd_send
8816 		    (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) {
8817 		WMI_LOGE("Failed to send host stats request to fw");
8818 		wmi_buf_free(buf);
8819 		return QDF_STATUS_E_FAILURE;
8820 	}
8821 
8822 	return QDF_STATUS_SUCCESS;
8823 }
8824 
8825 /**
8826  * send_snr_cmd_tlv() - get RSSI from fw
8827  * @wmi_handle: wmi handle
8828  * @vdev_id: vdev id
8829  *
8830  * Return: CDF status
8831  */
8832 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
8833 {
8834 	wmi_buf_t buf;
8835 	wmi_request_stats_cmd_fixed_param *cmd;
8836 	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
8837 
8838 	buf = wmi_buf_alloc(wmi_handle, len);
8839 	if (!buf) {
8840 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8841 		return QDF_STATUS_E_FAILURE;
8842 	}
8843 
8844 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
8845 	cmd->vdev_id = vdev_id;
8846 
8847 	WMITLV_SET_HDR(&cmd->tlv_header,
8848 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8849 		       WMITLV_GET_STRUCT_TLVLEN
8850 			       (wmi_request_stats_cmd_fixed_param));
8851 	cmd->stats_id = WMI_REQUEST_VDEV_STAT;
8852 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8853 				 WMI_REQUEST_STATS_CMDID)) {
8854 		WMI_LOGE("Failed to send host stats request to fw");
8855 		wmi_buf_free(buf);
8856 		return QDF_STATUS_E_FAILURE;
8857 	}
8858 
8859 	return QDF_STATUS_SUCCESS;
8860 }
8861 
8862 /**
8863  * send_link_status_req_cmd_tlv() - process link status request from UMAC
8864  * @wmi_handle: wmi handle
8865  * @link_status: get link params
8866  *
8867  * Return: CDF status
8868  */
8869 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle,
8870 				 struct link_status_params *link_status)
8871 {
8872 	wmi_buf_t buf;
8873 	wmi_request_stats_cmd_fixed_param *cmd;
8874 	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
8875 
8876 	buf = wmi_buf_alloc(wmi_handle, len);
8877 	if (!buf) {
8878 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8879 		return QDF_STATUS_E_FAILURE;
8880 	}
8881 
8882 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
8883 	WMITLV_SET_HDR(&cmd->tlv_header,
8884 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
8885 		       WMITLV_GET_STRUCT_TLVLEN
8886 			       (wmi_request_stats_cmd_fixed_param));
8887 	cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT;
8888 	cmd->vdev_id = link_status->session_id;
8889 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
8890 				 WMI_REQUEST_STATS_CMDID)) {
8891 		WMI_LOGE("Failed to send WMI link  status request to fw");
8892 		wmi_buf_free(buf);
8893 		return QDF_STATUS_E_FAILURE;
8894 	}
8895 
8896 	return QDF_STATUS_SUCCESS;
8897 }
8898 
8899 /**
8900  * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME
8901  * @wmi_handle: wmi handle
8902  * @ta_dhcp_ind: DHCP indication parameter
8903  *
8904  * Return: CDF Status
8905  */
8906 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle,
8907 				wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind)
8908 {
8909 	QDF_STATUS status;
8910 	wmi_buf_t buf = NULL;
8911 	uint8_t *buf_ptr;
8912 	wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp;
8913 	int len = sizeof(wmi_peer_set_param_cmd_fixed_param);
8914 
8915 
8916 	buf = wmi_buf_alloc(wmi_handle, len);
8917 	if (!buf) {
8918 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
8919 		return QDF_STATUS_E_NOMEM;
8920 	}
8921 
8922 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
8923 	peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr;
8924 	WMITLV_SET_HDR(&peer_set_param_fp->tlv_header,
8925 		       WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
8926 		       WMITLV_GET_STRUCT_TLVLEN
8927 			       (wmi_peer_set_param_cmd_fixed_param));
8928 
8929 	/* fill in values */
8930 	peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id;
8931 	peer_set_param_fp->param_id = ta_dhcp_ind->param_id;
8932 	peer_set_param_fp->param_value = ta_dhcp_ind->param_value;
8933 	qdf_mem_copy(&peer_set_param_fp->peer_macaddr,
8934 				   &ta_dhcp_ind->peer_macaddr,
8935 				   sizeof(ta_dhcp_ind->peer_macaddr));
8936 
8937 	status = wmi_unified_cmd_send(wmi_handle, buf,
8938 				      len, WMI_PEER_SET_PARAM_CMDID);
8939 	if (QDF_IS_STATUS_ERROR(status)) {
8940 		WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
8941 			 " returned Error %d", __func__, status);
8942 		wmi_buf_free(buf);
8943 	}
8944 
8945 	return status;
8946 }
8947 
8948 /**
8949  * send_get_link_speed_cmd_tlv() -send command to get linkspeed
8950  * @wmi_handle: wmi handle
8951  * @pLinkSpeed: link speed info
8952  *
8953  * Return: CDF status
8954  */
8955 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle,
8956 		wmi_mac_addr peer_macaddr)
8957 {
8958 	wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd;
8959 	wmi_buf_t wmi_buf;
8960 	uint32_t len;
8961 	uint8_t *buf_ptr;
8962 
8963 	len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param);
8964 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
8965 	if (!wmi_buf) {
8966 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8967 		return QDF_STATUS_E_NOMEM;
8968 	}
8969 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
8970 
8971 	cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr;
8972 	WMITLV_SET_HDR(&cmd->tlv_header,
8973 	       WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param,
8974 	       WMITLV_GET_STRUCT_TLVLEN
8975 	       (wmi_peer_get_estimated_linkspeed_cmd_fixed_param));
8976 
8977 	/* Copy the peer macaddress to the wma buffer */
8978 	qdf_mem_copy(&cmd->peer_macaddr,
8979 				   &peer_macaddr,
8980 				   sizeof(peer_macaddr));
8981 
8982 
8983 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
8984 				 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) {
8985 		WMI_LOGE("%s: failed to send link speed command", __func__);
8986 		wmi_buf_free(wmi_buf);
8987 		return QDF_STATUS_E_FAILURE;
8988 	}
8989 	return QDF_STATUS_SUCCESS;
8990 }
8991 
8992 #ifdef WLAN_SUPPORT_GREEN_AP
8993 /**
8994  * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params
8995  * @wmi_handle:	 wmi handler
8996  * @egap_params: pointer to egap_params
8997  *
8998  * Return:	 0 for success, otherwise appropriate error code
8999  */
9000 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle,
9001 		     struct wlan_green_ap_egap_params *egap_params)
9002 {
9003 	wmi_ap_ps_egap_param_cmd_fixed_param *cmd;
9004 	wmi_buf_t buf;
9005 	int32_t err;
9006 
9007 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
9008 	if (!buf) {
9009 		WMI_LOGE("Failed to allocate buffer to send ap_ps_egap cmd");
9010 		return QDF_STATUS_E_NOMEM;
9011 	}
9012 	cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf);
9013 	WMITLV_SET_HDR(&cmd->tlv_header,
9014 		       WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param,
9015 		       WMITLV_GET_STRUCT_TLVLEN(
9016 			       wmi_ap_ps_egap_param_cmd_fixed_param));
9017 
9018 	cmd->enable = egap_params->host_enable_egap;
9019 	cmd->inactivity_time = egap_params->egap_inactivity_time;
9020 	cmd->wait_time = egap_params->egap_wait_time;
9021 	cmd->flags = egap_params->egap_feature_flags;
9022 	err = wmi_unified_cmd_send(wmi_handle, buf,
9023 				   sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID);
9024 	if (err) {
9025 		WMI_LOGE("Failed to send ap_ps_egap cmd");
9026 		wmi_buf_free(buf);
9027 		return QDF_STATUS_E_FAILURE;
9028 	}
9029 
9030 	return QDF_STATUS_SUCCESS;
9031 }
9032 #endif
9033 
9034 /**
9035  * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW
9036  * @wmi_handl: wmi handle
9037  * @cmd: Profiling command index
9038  * @value1: parameter1 value
9039  * @value2: parameter2 value
9040  *
9041  * Return: QDF_STATUS_SUCCESS for success else error code
9042  */
9043 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle,
9044 			uint32_t cmd, uint32_t value1, uint32_t value2)
9045 {
9046 	wmi_buf_t buf;
9047 	int32_t len = 0;
9048 	int ret;
9049 	wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd;
9050 	wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd;
9051 	wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd;
9052 	wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd;
9053 
9054 	switch (cmd) {
9055 	case WMI_WLAN_PROFILE_TRIGGER_CMDID:
9056 		len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param);
9057 		buf = wmi_buf_alloc(wmi_handle, len);
9058 		if (!buf) {
9059 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
9060 			return QDF_STATUS_E_NOMEM;
9061 		}
9062 		prof_trig_cmd =
9063 			(wmi_wlan_profile_trigger_cmd_fixed_param *)
9064 				wmi_buf_data(buf);
9065 		WMITLV_SET_HDR(&prof_trig_cmd->tlv_header,
9066 		     WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param,
9067 		     WMITLV_GET_STRUCT_TLVLEN
9068 		    (wmi_wlan_profile_trigger_cmd_fixed_param));
9069 		prof_trig_cmd->enable = value1;
9070 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9071 				WMI_WLAN_PROFILE_TRIGGER_CMDID);
9072 		if (ret) {
9073 			WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d",
9074 					value1);
9075 			wmi_buf_free(buf);
9076 			return ret;
9077 		}
9078 		break;
9079 
9080 	case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
9081 		len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param);
9082 		buf = wmi_buf_alloc(wmi_handle, len);
9083 		if (!buf) {
9084 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
9085 			return QDF_STATUS_E_NOMEM;
9086 		}
9087 		profile_getdata_cmd =
9088 			(wmi_wlan_profile_get_prof_data_cmd_fixed_param *)
9089 				wmi_buf_data(buf);
9090 		WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header,
9091 		      WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param,
9092 		      WMITLV_GET_STRUCT_TLVLEN
9093 		      (wmi_wlan_profile_get_prof_data_cmd_fixed_param));
9094 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9095 				WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID);
9096 		if (ret) {
9097 			WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d",
9098 					value1, value2);
9099 			wmi_buf_free(buf);
9100 			return ret;
9101 		}
9102 		break;
9103 
9104 	case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
9105 		len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param);
9106 		buf = wmi_buf_alloc(wmi_handle, len);
9107 		if (!buf) {
9108 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
9109 			return QDF_STATUS_E_NOMEM;
9110 		}
9111 		hist_intvl_cmd =
9112 			(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *)
9113 				wmi_buf_data(buf);
9114 		WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header,
9115 		      WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param,
9116 		      WMITLV_GET_STRUCT_TLVLEN
9117 		      (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param));
9118 		hist_intvl_cmd->profile_id = value1;
9119 		hist_intvl_cmd->value = value2;
9120 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9121 				WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID);
9122 		if (ret) {
9123 			WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d",
9124 					value1, value2);
9125 			wmi_buf_free(buf);
9126 			return ret;
9127 		}
9128 		break;
9129 
9130 	case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
9131 		len =
9132 		sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param);
9133 		buf = wmi_buf_alloc(wmi_handle, len);
9134 		if (!buf) {
9135 			WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
9136 			return QDF_STATUS_E_NOMEM;
9137 		}
9138 		profile_enable_cmd =
9139 			(wmi_wlan_profile_enable_profile_id_cmd_fixed_param *)
9140 				wmi_buf_data(buf);
9141 		WMITLV_SET_HDR(&profile_enable_cmd->tlv_header,
9142 		      WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param,
9143 		      WMITLV_GET_STRUCT_TLVLEN
9144 		      (wmi_wlan_profile_enable_profile_id_cmd_fixed_param));
9145 		profile_enable_cmd->profile_id = value1;
9146 		profile_enable_cmd->enable = value2;
9147 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9148 				WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID);
9149 		if (ret) {
9150 			WMI_LOGE("enable cmd Failed for id %d value %d",
9151 					value1, value2);
9152 			wmi_buf_free(buf);
9153 			return ret;
9154 		}
9155 		break;
9156 
9157 	default:
9158 		WMI_LOGD("%s: invalid profiling command", __func__);
9159 		break;
9160 	}
9161 
9162 	return 0;
9163 }
9164 
9165 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle,
9166 				struct wlm_latency_level_param *params)
9167 {
9168 	wmi_wlm_config_cmd_fixed_param *cmd;
9169 	wmi_buf_t buf;
9170 	uint32_t len = sizeof(*cmd);
9171 	static uint32_t ll[4] = {100, 60, 40, 20};
9172 
9173 	buf = wmi_buf_alloc(wmi_handle, len);
9174 	if (!buf) {
9175 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9176 		return QDF_STATUS_E_NOMEM;
9177 	}
9178 	cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf);
9179 	WMITLV_SET_HDR(&cmd->tlv_header,
9180 		       WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param,
9181 		       WMITLV_GET_STRUCT_TLVLEN
9182 		       (wmi_wlm_config_cmd_fixed_param));
9183 	cmd->vdev_id = params->vdev_id;
9184 	cmd->latency_level = params->wlm_latency_level;
9185 	cmd->ul_latency = ll[params->wlm_latency_level];
9186 	cmd->dl_latency = ll[params->wlm_latency_level];
9187 	cmd->flags = params->wlm_latency_flags;
9188 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
9189 				 WMI_WLM_CONFIG_CMDID)) {
9190 		WMI_LOGE("%s: Failed to send setting latency config command",
9191 			 __func__);
9192 		wmi_buf_free(buf);
9193 		return QDF_STATUS_E_FAILURE;
9194 	}
9195 
9196 	return 0;
9197 }
9198 /**
9199  * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter
9200  * @wmi_handle: wmi handle
9201  * @vdev_id: vdev id
9202  *
9203  * Return: QDF_STATUS_SUCCESS for success or error code
9204  */
9205 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
9206 {
9207 	WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd;
9208 	wmi_buf_t buf;
9209 	int32_t len = sizeof(*cmd);
9210 
9211 	WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
9212 	buf = wmi_buf_alloc(wmi_handle, len);
9213 	if (!buf) {
9214 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9215 		return QDF_STATUS_E_NOMEM;
9216 	}
9217 	cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *)
9218 		wmi_buf_data(buf);
9219 	WMITLV_SET_HDR(&cmd->tlv_header,
9220 	WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param,
9221 		  WMITLV_GET_STRUCT_TLVLEN
9222 		  (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param));
9223 	cmd->vdev_id = vdev_id;
9224 	cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE;
9225 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
9226 				 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) {
9227 		WMI_LOGP("%s: Failed to send NAT keepalive enable command",
9228 			 __func__);
9229 		wmi_buf_free(buf);
9230 		return QDF_STATUS_E_FAILURE;
9231 	}
9232 
9233 	return 0;
9234 }
9235 
9236 /**
9237  * wmi_unified_csa_offload_enable() - sen CSA offload enable command
9238  * @wmi_handle: wmi handle
9239  * @vdev_id: vdev id
9240  *
9241  * Return: QDF_STATUS_SUCCESS for success or error code
9242  */
9243 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle,
9244 			uint8_t vdev_id)
9245 {
9246 	wmi_csa_offload_enable_cmd_fixed_param *cmd;
9247 	wmi_buf_t buf;
9248 	int32_t len = sizeof(*cmd);
9249 
9250 	WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
9251 	buf = wmi_buf_alloc(wmi_handle, len);
9252 	if (!buf) {
9253 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9254 		return QDF_STATUS_E_NOMEM;
9255 	}
9256 	cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf);
9257 	WMITLV_SET_HDR(&cmd->tlv_header,
9258 		       WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param,
9259 		       WMITLV_GET_STRUCT_TLVLEN
9260 			       (wmi_csa_offload_enable_cmd_fixed_param));
9261 	cmd->vdev_id = vdev_id;
9262 	cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE;
9263 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
9264 				 WMI_CSA_OFFLOAD_ENABLE_CMDID)) {
9265 		WMI_LOGP("%s: Failed to send CSA offload enable command",
9266 			 __func__);
9267 		wmi_buf_free(buf);
9268 		return QDF_STATUS_E_FAILURE;
9269 	}
9270 
9271 	return 0;
9272 }
9273 
9274 #ifdef WLAN_FEATURE_CIF_CFR
9275 /**
9276  * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings
9277  * @wmi_handle: wmi handle
9278  * @data_len: len of dma cfg req
9279  * @data: dma cfg req
9280  *
9281  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
9282  */
9283 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle,
9284 				wmi_oem_dma_ring_cfg_req_fixed_param *cfg)
9285 {
9286 	wmi_buf_t buf;
9287 	uint8_t *cmd;
9288 	QDF_STATUS ret;
9289 
9290 	WMITLV_SET_HDR(cfg,
9291 		WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param,
9292 		(sizeof(*cfg) - WMI_TLV_HDR_SIZE));
9293 
9294 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg));
9295 	if (!buf) {
9296 		WMI_LOGE(FL("wmi_buf_alloc failed"));
9297 		return QDF_STATUS_E_FAILURE;
9298 	}
9299 
9300 	cmd = (uint8_t *) wmi_buf_data(buf);
9301 	qdf_mem_copy(cmd, cfg, sizeof(*cfg));
9302 	WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"),
9303 		sizeof(*cfg));
9304 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg),
9305 				WMI_OEM_DMA_RING_CFG_REQ_CMDID);
9306 	if (QDF_IS_STATUS_ERROR(ret)) {
9307 		WMI_LOGE(FL(":wmi cmd send failed"));
9308 		wmi_buf_free(buf);
9309 	}
9310 
9311 	return ret;
9312 }
9313 #endif
9314 
9315 /**
9316  * send_dbr_cfg_cmd_tlv() - configure DMA rings for Direct Buf RX
9317  * @wmi_handle: wmi handle
9318  * @data_len: len of dma cfg req
9319  * @data: dma cfg req
9320  *
9321  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
9322  */
9323 static QDF_STATUS send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle,
9324 				struct direct_buf_rx_cfg_req *cfg)
9325 {
9326 	wmi_buf_t buf;
9327 	wmi_dma_ring_cfg_req_fixed_param *cmd;
9328 	QDF_STATUS ret;
9329 	int32_t len = sizeof(*cmd);
9330 
9331 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
9332 	if (!buf) {
9333 		WMI_LOGE(FL("wmi_buf_alloc failed"));
9334 		return QDF_STATUS_E_FAILURE;
9335 	}
9336 
9337 	cmd = (wmi_dma_ring_cfg_req_fixed_param *)wmi_buf_data(buf);
9338 
9339 	WMITLV_SET_HDR(&cmd->tlv_header,
9340 		WMITLV_TAG_STRUC_wmi_dma_ring_cfg_req_fixed_param,
9341 		WMITLV_GET_STRUCT_TLVLEN(wmi_dma_ring_cfg_req_fixed_param));
9342 
9343 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
9344 						cfg->pdev_id);
9345 	cmd->mod_id = cfg->mod_id;
9346 	cmd->base_paddr_lo = cfg->base_paddr_lo;
9347 	cmd->base_paddr_hi = cfg->base_paddr_hi;
9348 	cmd->head_idx_paddr_lo = cfg->head_idx_paddr_lo;
9349 	cmd->head_idx_paddr_hi = cfg->head_idx_paddr_hi;
9350 	cmd->tail_idx_paddr_lo = cfg->tail_idx_paddr_lo;
9351 	cmd->tail_idx_paddr_hi = cfg->tail_idx_paddr_hi;
9352 	cmd->num_elems = cfg->num_elems;
9353 	cmd->buf_size = cfg->buf_size;
9354 	cmd->num_resp_per_event = cfg->num_resp_per_event;
9355 	cmd->event_timeout_ms = cfg->event_timeout_ms;
9356 
9357 	WMI_LOGD("%s: wmi_dma_ring_cfg_req_fixed_param pdev id %d mod id %d"
9358 		  "base paddr lo %x base paddr hi %x head idx paddr lo %x"
9359 		  "head idx paddr hi %x tail idx paddr lo %x"
9360 		  "tail idx addr hi %x num elems %d buf size %d num resp %d"
9361 		  "event timeout %d\n", __func__, cmd->pdev_id,
9362 		  cmd->mod_id, cmd->base_paddr_lo, cmd->base_paddr_hi,
9363 		  cmd->head_idx_paddr_lo, cmd->head_idx_paddr_hi,
9364 		  cmd->tail_idx_paddr_lo, cmd->tail_idx_paddr_hi,
9365 		  cmd->num_elems, cmd->buf_size, cmd->num_resp_per_event,
9366 		  cmd->event_timeout_ms);
9367 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9368 				WMI_PDEV_DMA_RING_CFG_REQ_CMDID);
9369 	if (QDF_IS_STATUS_ERROR(ret)) {
9370 		WMI_LOGE(FL(":wmi cmd send failed"));
9371 		wmi_buf_free(buf);
9372 	}
9373 
9374 	return ret;
9375 }
9376 
9377 /**
9378  * send_start_11d_scan_cmd_tlv() - start 11d scan request
9379  * @wmi_handle: wmi handle
9380  * @start_11d_scan: 11d scan start request parameters
9381  *
9382  * This function request FW to start 11d scan.
9383  *
9384  * Return: QDF status
9385  */
9386 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle,
9387 			  struct reg_start_11d_scan_req *start_11d_scan)
9388 {
9389 	wmi_11d_scan_start_cmd_fixed_param *cmd;
9390 	int32_t len;
9391 	wmi_buf_t buf;
9392 	int ret;
9393 
9394 	len = sizeof(*cmd);
9395 	buf = wmi_buf_alloc(wmi_handle, len);
9396 	if (!buf) {
9397 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9398 		return QDF_STATUS_E_NOMEM;
9399 	}
9400 
9401 	cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf);
9402 
9403 	WMITLV_SET_HDR(&cmd->tlv_header,
9404 		       WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param,
9405 		       WMITLV_GET_STRUCT_TLVLEN
9406 		       (wmi_11d_scan_start_cmd_fixed_param));
9407 
9408 	cmd->vdev_id = start_11d_scan->vdev_id;
9409 	cmd->scan_period_msec = start_11d_scan->scan_period_msec;
9410 	cmd->start_interval_msec = start_11d_scan->start_interval_msec;
9411 
9412 	WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id);
9413 
9414 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9415 				   WMI_11D_SCAN_START_CMDID);
9416 	if (ret) {
9417 		WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__);
9418 		wmi_buf_free(buf);
9419 		return QDF_STATUS_E_FAILURE;
9420 	}
9421 
9422 	return QDF_STATUS_SUCCESS;
9423 }
9424 
9425 /**
9426  * send_stop_11d_scan_cmd_tlv() - stop 11d scan request
9427  * @wmi_handle: wmi handle
9428  * @start_11d_scan: 11d scan stop request parameters
9429  *
9430  * This function request FW to stop 11d scan.
9431  *
9432  * Return: QDF status
9433  */
9434 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle,
9435 			  struct reg_stop_11d_scan_req *stop_11d_scan)
9436 {
9437 	wmi_11d_scan_stop_cmd_fixed_param *cmd;
9438 	int32_t len;
9439 	wmi_buf_t buf;
9440 	int ret;
9441 
9442 	len = sizeof(*cmd);
9443 	buf = wmi_buf_alloc(wmi_handle, len);
9444 	if (!buf) {
9445 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9446 		return QDF_STATUS_E_NOMEM;
9447 	}
9448 
9449 	cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf);
9450 
9451 	WMITLV_SET_HDR(&cmd->tlv_header,
9452 		       WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param,
9453 		       WMITLV_GET_STRUCT_TLVLEN
9454 		       (wmi_11d_scan_stop_cmd_fixed_param));
9455 
9456 	cmd->vdev_id = stop_11d_scan->vdev_id;
9457 
9458 	WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id);
9459 
9460 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9461 				   WMI_11D_SCAN_STOP_CMDID);
9462 	if (ret) {
9463 		WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__);
9464 		wmi_buf_free(buf);
9465 		return QDF_STATUS_E_FAILURE;
9466 	}
9467 
9468 	return QDF_STATUS_SUCCESS;
9469 }
9470 
9471 /**
9472  * send_start_oem_data_cmd_tlv() - start OEM data request to target
9473  * @wmi_handle: wmi handle
9474  * @startOemDataReq: start request params
9475  *
9476  * Return: CDF status
9477  */
9478 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle,
9479 			  uint32_t data_len,
9480 			  uint8_t *data)
9481 {
9482 	wmi_buf_t buf;
9483 	uint8_t *cmd;
9484 	QDF_STATUS ret;
9485 
9486 	buf = wmi_buf_alloc(wmi_handle,
9487 			    (data_len + WMI_TLV_HDR_SIZE));
9488 	if (!buf) {
9489 		WMI_LOGE(FL("wmi_buf_alloc failed"));
9490 		return QDF_STATUS_E_FAILURE;
9491 	}
9492 
9493 	cmd = (uint8_t *) wmi_buf_data(buf);
9494 
9495 	WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len);
9496 	cmd += WMI_TLV_HDR_SIZE;
9497 	qdf_mem_copy(cmd, data,
9498 		     data_len);
9499 
9500 	WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"),
9501 		 data_len);
9502 
9503 	ret = wmi_unified_cmd_send(wmi_handle, buf,
9504 				   (data_len +
9505 				    WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID);
9506 
9507 	if (QDF_IS_STATUS_ERROR(ret)) {
9508 		WMI_LOGE(FL(":wmi cmd send failed"));
9509 		wmi_buf_free(buf);
9510 	}
9511 
9512 	return ret;
9513 }
9514 
9515 /**
9516  * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter
9517  * @wmi_handle: wmi handle
9518  * @dfs_phyerr_filter_offload: is dfs phyerr filter offload
9519  *
9520  * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or
9521  * WMI_DFS_PHYERR_FILTER_DIS_CMDID command
9522  * to firmware based on phyerr filtering
9523  * offload status.
9524  *
9525  * Return: 1 success, 0 failure
9526  */
9527 static QDF_STATUS
9528 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle,
9529 			bool dfs_phyerr_filter_offload)
9530 {
9531 	wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd;
9532 	wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd;
9533 	wmi_buf_t buf;
9534 	uint16_t len;
9535 	QDF_STATUS ret;
9536 
9537 
9538 	if (false == dfs_phyerr_filter_offload) {
9539 		WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini",
9540 			 __func__);
9541 		len = sizeof(*disable_phyerr_offload_cmd);
9542 		buf = wmi_buf_alloc(wmi_handle, len);
9543 		if (!buf) {
9544 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9545 			return 0;
9546 		}
9547 		disable_phyerr_offload_cmd =
9548 			(wmi_dfs_phyerr_filter_dis_cmd_fixed_param *)
9549 			wmi_buf_data(buf);
9550 
9551 		WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header,
9552 		     WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param,
9553 		     WMITLV_GET_STRUCT_TLVLEN
9554 		     (wmi_dfs_phyerr_filter_dis_cmd_fixed_param));
9555 
9556 		/*
9557 		 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID
9558 		 * to the firmware to disable the phyerror
9559 		 * filtering offload.
9560 		 */
9561 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9562 					   WMI_DFS_PHYERR_FILTER_DIS_CMDID);
9563 		if (QDF_IS_STATUS_ERROR(ret)) {
9564 			WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d",
9565 				__func__, ret);
9566 			wmi_buf_free(buf);
9567 		return QDF_STATUS_E_FAILURE;
9568 		}
9569 		WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success",
9570 			 __func__);
9571 	} else {
9572 		WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini",
9573 			 __func__);
9574 
9575 		len = sizeof(*enable_phyerr_offload_cmd);
9576 		buf = wmi_buf_alloc(wmi_handle, len);
9577 		if (!buf) {
9578 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9579 		return QDF_STATUS_E_FAILURE;
9580 		}
9581 
9582 		enable_phyerr_offload_cmd =
9583 			(wmi_dfs_phyerr_filter_ena_cmd_fixed_param *)
9584 			wmi_buf_data(buf);
9585 
9586 		WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header,
9587 		     WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param,
9588 		     WMITLV_GET_STRUCT_TLVLEN
9589 		     (wmi_dfs_phyerr_filter_ena_cmd_fixed_param));
9590 
9591 		/*
9592 		 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID
9593 		 * to the firmware to enable the phyerror
9594 		 * filtering offload.
9595 		 */
9596 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9597 					   WMI_DFS_PHYERR_FILTER_ENA_CMDID);
9598 
9599 		if (QDF_IS_STATUS_ERROR(ret)) {
9600 			WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d",
9601 				__func__, ret);
9602 			wmi_buf_free(buf);
9603 		return QDF_STATUS_E_FAILURE;
9604 		}
9605 		WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success",
9606 			 __func__);
9607 	}
9608 
9609 	return QDF_STATUS_SUCCESS;
9610 }
9611 
9612 /**
9613  * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware
9614  * will wake up host after specified time is elapsed
9615  * @wmi_handle: wmi handle
9616  * @vdev_id: vdev id
9617  * @cookie: value to identify reason why host set up wake call.
9618  * @time: time in ms
9619  *
9620  * Return: QDF status
9621  */
9622 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle,
9623 				uint8_t vdev_id, uint32_t cookie, uint32_t time)
9624 {
9625 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
9626 	wmi_buf_t buf;
9627 	uint8_t *buf_ptr;
9628 	int32_t len;
9629 	int ret;
9630 
9631 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
9632 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) +
9633 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
9634 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
9635 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
9636 		WMI_TLV_HDR_SIZE + 1 * sizeof(A_UINT32) +
9637 		WMI_TLV_HDR_SIZE + 1 * sizeof(A_UINT32);
9638 
9639 	buf = wmi_buf_alloc(wmi_handle, len);
9640 	if (!buf) {
9641 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9642 		return QDF_STATUS_E_NOMEM;
9643 	}
9644 
9645 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
9646 	buf_ptr = (uint8_t *) cmd;
9647 
9648 	WMITLV_SET_HDR(&cmd->tlv_header,
9649 		WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
9650 		WMITLV_GET_STRUCT_TLVLEN
9651 			(WMI_WOW_ADD_PATTERN_CMD_fixed_param));
9652 	cmd->vdev_id = vdev_id;
9653 	cmd->pattern_id = cookie,
9654 	cmd->pattern_type = WOW_TIMER_PATTERN;
9655 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
9656 
9657 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
9658 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9659 	buf_ptr += WMI_TLV_HDR_SIZE;
9660 
9661 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
9662 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9663 	buf_ptr += WMI_TLV_HDR_SIZE;
9664 
9665 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
9666 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9667 	buf_ptr += WMI_TLV_HDR_SIZE;
9668 
9669 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
9670 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
9671 	buf_ptr += WMI_TLV_HDR_SIZE;
9672 
9673 	/* Fill TLV for pattern_info_timeout, and time value */
9674 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(A_UINT32));
9675 	buf_ptr += WMI_TLV_HDR_SIZE;
9676 	*((A_UINT32 *) buf_ptr) = time;
9677 	buf_ptr += sizeof(A_UINT32);
9678 
9679 	/* Fill TLV for ra_ratelimit_interval. with dummy 0 value */
9680 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(A_UINT32));
9681 	buf_ptr += WMI_TLV_HDR_SIZE;
9682 	*((A_UINT32 *) buf_ptr) = 0;
9683 
9684 	WMI_LOGD("%s: send wake timer pattern with time[%d] to fw vdev = %d",
9685 		__func__, time, vdev_id);
9686 
9687 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9688 				WMI_WOW_ADD_WAKE_PATTERN_CMDID);
9689 	if (ret) {
9690 		WMI_LOGE("%s: Failed to send wake timer pattern to fw",
9691 			__func__);
9692 		wmi_buf_free(buf);
9693 		return QDF_STATUS_E_FAILURE;
9694 	}
9695 
9696 	return QDF_STATUS_SUCCESS;
9697 }
9698 
9699 #if !defined(REMOVE_PKT_LOG)
9700 /**
9701  * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target
9702  * @wmi_handle: wmi handle
9703  * @pktlog_event: pktlog event
9704  * @cmd_id: pktlog cmd id
9705  *
9706  * Return: CDF status
9707  */
9708 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle,
9709 				   WMI_PKTLOG_EVENT pktlog_event,
9710 				   WMI_CMD_ID cmd_id, uint8_t user_triggered)
9711 {
9712 	WMI_PKTLOG_EVENT PKTLOG_EVENT;
9713 	WMI_CMD_ID CMD_ID;
9714 	wmi_pdev_pktlog_enable_cmd_fixed_param *cmd;
9715 	wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd;
9716 	int len = 0;
9717 	wmi_buf_t buf;
9718 
9719 	PKTLOG_EVENT = pktlog_event;
9720 	CMD_ID = cmd_id;
9721 
9722 	switch (CMD_ID) {
9723 	case WMI_PDEV_PKTLOG_ENABLE_CMDID:
9724 		len = sizeof(*cmd);
9725 		buf = wmi_buf_alloc(wmi_handle, len);
9726 		if (!buf) {
9727 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9728 			return QDF_STATUS_E_NOMEM;
9729 		}
9730 		cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *)
9731 			wmi_buf_data(buf);
9732 		WMITLV_SET_HDR(&cmd->tlv_header,
9733 		       WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param,
9734 		       WMITLV_GET_STRUCT_TLVLEN
9735 		       (wmi_pdev_pktlog_enable_cmd_fixed_param));
9736 		cmd->evlist = PKTLOG_EVENT;
9737 		cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE
9738 					: WMI_PKTLOG_ENABLE_AUTO;
9739 		cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
9740 							WMI_HOST_PDEV_ID_SOC);
9741 		if (wmi_unified_cmd_send(wmi_handle, buf, len,
9742 					 WMI_PDEV_PKTLOG_ENABLE_CMDID)) {
9743 			WMI_LOGE("failed to send pktlog enable cmdid");
9744 			goto wmi_send_failed;
9745 		}
9746 		break;
9747 	case WMI_PDEV_PKTLOG_DISABLE_CMDID:
9748 		len = sizeof(*disable_cmd);
9749 		buf = wmi_buf_alloc(wmi_handle, len);
9750 		if (!buf) {
9751 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
9752 			return QDF_STATUS_E_NOMEM;
9753 		}
9754 		disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *)
9755 			      wmi_buf_data(buf);
9756 		WMITLV_SET_HDR(&disable_cmd->tlv_header,
9757 		     WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param,
9758 		     WMITLV_GET_STRUCT_TLVLEN
9759 		     (wmi_pdev_pktlog_disable_cmd_fixed_param));
9760 		disable_cmd->pdev_id =
9761 			wmi_handle->ops->convert_pdev_id_host_to_target(
9762 							WMI_HOST_PDEV_ID_SOC);
9763 		if (wmi_unified_cmd_send(wmi_handle, buf, len,
9764 					 WMI_PDEV_PKTLOG_DISABLE_CMDID)) {
9765 			WMI_LOGE("failed to send pktlog disable cmdid");
9766 			goto wmi_send_failed;
9767 		}
9768 		break;
9769 	default:
9770 		WMI_LOGD("%s: invalid PKTLOG command", __func__);
9771 		break;
9772 	}
9773 
9774 	return QDF_STATUS_SUCCESS;
9775 
9776 wmi_send_failed:
9777 	wmi_buf_free(buf);
9778 	return QDF_STATUS_E_FAILURE;
9779 }
9780 #endif /* REMOVE_PKT_LOG */
9781 
9782 /**
9783  * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target
9784  * @wmi_handle: wmi handle
9785  * @ptrn_id: pattern id
9786  * @vdev_id: vdev id
9787  *
9788  * Return: CDF status
9789  */
9790 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle,
9791 			uint8_t ptrn_id, uint8_t vdev_id)
9792 {
9793 	WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd;
9794 	wmi_buf_t buf;
9795 	int32_t len;
9796 	int ret;
9797 
9798 	len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param);
9799 
9800 
9801 	buf = wmi_buf_alloc(wmi_handle, len);
9802 	if (!buf) {
9803 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9804 		return QDF_STATUS_E_NOMEM;
9805 	}
9806 
9807 	cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
9808 
9809 	WMITLV_SET_HDR(&cmd->tlv_header,
9810 		       WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param,
9811 		       WMITLV_GET_STRUCT_TLVLEN(
9812 				WMI_WOW_DEL_PATTERN_CMD_fixed_param));
9813 	cmd->vdev_id = vdev_id;
9814 	cmd->pattern_id = ptrn_id;
9815 	cmd->pattern_type = WOW_BITMAP_PATTERN;
9816 
9817 	WMI_LOGI("Deleting pattern id: %d vdev id %d in fw",
9818 		cmd->pattern_id, vdev_id);
9819 
9820 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9821 				   WMI_WOW_DEL_WAKE_PATTERN_CMDID);
9822 	if (ret) {
9823 		WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__);
9824 		wmi_buf_free(buf);
9825 		return QDF_STATUS_E_FAILURE;
9826 	}
9827 
9828 	return QDF_STATUS_SUCCESS;
9829 }
9830 
9831 /**
9832  * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw
9833  * @wmi_handle: wmi handle
9834  *
9835  * Sends host wakeup indication to FW. On receiving this indication,
9836  * FW will come out of WOW.
9837  *
9838  * Return: CDF status
9839  */
9840 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle)
9841 {
9842 	wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd;
9843 	wmi_buf_t buf;
9844 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
9845 	int32_t len;
9846 	int ret;
9847 
9848 	len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param);
9849 
9850 	buf = wmi_buf_alloc(wmi_handle, len);
9851 	if (!buf) {
9852 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
9853 		return QDF_STATUS_E_NOMEM;
9854 	}
9855 
9856 	cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *)
9857 	      wmi_buf_data(buf);
9858 	WMITLV_SET_HDR(&cmd->tlv_header,
9859 		WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param,
9860 		WMITLV_GET_STRUCT_TLVLEN
9861 	       (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param));
9862 
9863 
9864 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
9865 				   WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID);
9866 	if (ret) {
9867 		WMI_LOGE("Failed to send host wakeup indication to fw");
9868 		wmi_buf_free(buf);
9869 		return QDF_STATUS_E_FAILURE;
9870 	}
9871 
9872 	return qdf_status;
9873 }
9874 
9875 /**
9876  * send_del_ts_cmd_tlv() - send DELTS request to fw
9877  * @wmi_handle: wmi handle
9878  * @msg: delts params
9879  *
9880  * Return: CDF status
9881  */
9882 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
9883 				uint8_t ac)
9884 {
9885 	wmi_vdev_wmm_delts_cmd_fixed_param *cmd;
9886 	wmi_buf_t buf;
9887 	int32_t len = sizeof(*cmd);
9888 
9889 	buf = wmi_buf_alloc(wmi_handle, len);
9890 	if (!buf) {
9891 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9892 		return QDF_STATUS_E_NOMEM;
9893 	}
9894 	cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf);
9895 	WMITLV_SET_HDR(&cmd->tlv_header,
9896 		       WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param,
9897 		       WMITLV_GET_STRUCT_TLVLEN
9898 			       (wmi_vdev_wmm_delts_cmd_fixed_param));
9899 	cmd->vdev_id = vdev_id;
9900 	cmd->ac = ac;
9901 
9902 	WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d",
9903 		 cmd->vdev_id, cmd->ac, __func__, __LINE__);
9904 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
9905 				 WMI_VDEV_WMM_DELTS_CMDID)) {
9906 		WMI_LOGP("%s: Failed to send vdev DELTS command", __func__);
9907 		wmi_buf_free(buf);
9908 		return QDF_STATUS_E_FAILURE;
9909 	}
9910 
9911 	return QDF_STATUS_SUCCESS;
9912 }
9913 
9914 /**
9915  * send_aggr_qos_cmd_tlv() - send aggr qos request to fw
9916  * @wmi_handle: handle to wmi
9917  * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests.
9918  *
9919  * A function to handle WMI_AGGR_QOS_REQ. This will send out
9920  * ADD_TS requestes to firmware in loop for all the ACs with
9921  * active flow.
9922  *
9923  * Return: CDF status
9924  */
9925 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle,
9926 		      struct aggr_add_ts_param *aggr_qos_rsp_msg)
9927 {
9928 	int i = 0;
9929 	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
9930 	wmi_buf_t buf;
9931 	int32_t len = sizeof(*cmd);
9932 
9933 	for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) {
9934 		/* if flow in this AC is active */
9935 		if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) {
9936 			/*
9937 			 * as per implementation of wma_add_ts_req() we
9938 			 * are not waiting any response from firmware so
9939 			 * apart from sending ADDTS to firmware just send
9940 			 * success to upper layers
9941 			 */
9942 			aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS;
9943 
9944 			buf = wmi_buf_alloc(wmi_handle, len);
9945 			if (!buf) {
9946 				WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
9947 				return QDF_STATUS_E_NOMEM;
9948 			}
9949 			cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *)
9950 				wmi_buf_data(buf);
9951 			WMITLV_SET_HDR(&cmd->tlv_header,
9952 			       WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
9953 			       WMITLV_GET_STRUCT_TLVLEN
9954 				       (wmi_vdev_wmm_addts_cmd_fixed_param));
9955 			cmd->vdev_id = aggr_qos_rsp_msg->sessionId;
9956 			cmd->ac =
9957 				WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo.
9958 					      traffic.userPrio);
9959 			cmd->medium_time_us =
9960 				aggr_qos_rsp_msg->tspec[i].mediumTime * 32;
9961 			cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO;
9962 			WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d",
9963 				__func__, __LINE__, cmd->vdev_id, cmd->ac,
9964 				cmd->medium_time_us, cmd->downgrade_type);
9965 			if (wmi_unified_cmd_send
9966 				    (wmi_handle, buf, len,
9967 				    WMI_VDEV_WMM_ADDTS_CMDID)) {
9968 				WMI_LOGP("%s: Failed to send vdev ADDTS command",
9969 					__func__);
9970 				aggr_qos_rsp_msg->status[i] =
9971 					QDF_STATUS_E_FAILURE;
9972 				wmi_buf_free(buf);
9973 				return QDF_STATUS_E_FAILURE;
9974 			}
9975 		}
9976 	}
9977 
9978 	return QDF_STATUS_SUCCESS;
9979 }
9980 
9981 /**
9982  * send_add_ts_cmd_tlv() - send ADDTS request to fw
9983  * @wmi_handle: wmi handle
9984  * @msg: ADDTS params
9985  *
9986  * Return: CDF status
9987  */
9988 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle,
9989 		 struct add_ts_param *msg)
9990 {
9991 	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
9992 	wmi_buf_t buf;
9993 	int32_t len = sizeof(*cmd);
9994 
9995 	msg->status = QDF_STATUS_SUCCESS;
9996 
9997 	buf = wmi_buf_alloc(wmi_handle, len);
9998 	if (!buf) {
9999 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
10000 		return QDF_STATUS_E_NOMEM;
10001 	}
10002 	cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf);
10003 	WMITLV_SET_HDR(&cmd->tlv_header,
10004 		       WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
10005 		       WMITLV_GET_STRUCT_TLVLEN
10006 			       (wmi_vdev_wmm_addts_cmd_fixed_param));
10007 	cmd->vdev_id = msg->sme_session_id;
10008 	cmd->ac = msg->tspec.tsinfo.traffic.userPrio;
10009 	cmd->medium_time_us = msg->tspec.mediumTime * 32;
10010 	cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP;
10011 	WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d",
10012 		 cmd->vdev_id, cmd->ac, cmd->medium_time_us,
10013 		 cmd->downgrade_type, __func__, __LINE__);
10014 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10015 				 WMI_VDEV_WMM_ADDTS_CMDID)) {
10016 		WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__);
10017 		msg->status = QDF_STATUS_E_FAILURE;
10018 		wmi_buf_free(buf);
10019 		return QDF_STATUS_E_FAILURE;
10020 	}
10021 
10022 	return QDF_STATUS_SUCCESS;
10023 }
10024 
10025 /**
10026  * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn
10027  * @wmi_handle: wmi handle
10028  * @pAddPeriodicTxPtrnParams: tx ptrn params
10029  *
10030  * Retrun: CDF status
10031  */
10032 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
10033 						struct periodic_tx_pattern  *
10034 						pAddPeriodicTxPtrnParams,
10035 						uint8_t vdev_id)
10036 {
10037 	WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
10038 	wmi_buf_t wmi_buf;
10039 	uint32_t len;
10040 	uint8_t *buf_ptr;
10041 	uint32_t ptrn_len, ptrn_len_aligned;
10042 	int j;
10043 
10044 	ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize;
10045 	ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t));
10046 	len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) +
10047 	      WMI_TLV_HDR_SIZE + ptrn_len_aligned;
10048 
10049 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10050 	if (!wmi_buf) {
10051 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
10052 		return QDF_STATUS_E_NOMEM;
10053 	}
10054 
10055 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
10056 
10057 	cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr;
10058 	WMITLV_SET_HDR(&cmd->tlv_header,
10059 	       WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
10060 	       WMITLV_GET_STRUCT_TLVLEN
10061 	       (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
10062 
10063 	/* Pass the pattern id to delete for the corresponding vdev id */
10064 	cmd->vdev_id = vdev_id;
10065 	cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId;
10066 	cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs;
10067 	cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize;
10068 
10069 	/* Pattern info */
10070 	buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
10071 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned);
10072 	buf_ptr += WMI_TLV_HDR_SIZE;
10073 	qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len);
10074 	for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++)
10075 		WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff);
10076 
10077 	WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d",
10078 		 __func__, cmd->pattern_id, cmd->vdev_id);
10079 
10080 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10081 				 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
10082 		WMI_LOGE("%s: failed to add pattern set state command",
10083 			 __func__);
10084 		wmi_buf_free(wmi_buf);
10085 		return QDF_STATUS_E_FAILURE;
10086 	}
10087 	return QDF_STATUS_SUCCESS;
10088 }
10089 
10090 /**
10091  * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn
10092  * @wmi_handle: wmi handle
10093  * @vdev_id: vdev id
10094  * @pattern_id: pattern id
10095  *
10096  * Retrun: CDF status
10097  */
10098 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
10099 						uint8_t vdev_id,
10100 						uint8_t pattern_id)
10101 {
10102 	WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
10103 	wmi_buf_t wmi_buf;
10104 	uint32_t len =
10105 		sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
10106 
10107 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10108 	if (!wmi_buf) {
10109 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
10110 		return QDF_STATUS_E_NOMEM;
10111 	}
10112 
10113 	cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)
10114 		wmi_buf_data(wmi_buf);
10115 	WMITLV_SET_HDR(&cmd->tlv_header,
10116 	       WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
10117 	       WMITLV_GET_STRUCT_TLVLEN
10118 	       (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
10119 
10120 	/* Pass the pattern id to delete for the corresponding vdev id */
10121 	cmd->vdev_id = vdev_id;
10122 	cmd->pattern_id = pattern_id;
10123 	WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d",
10124 		 __func__, cmd->pattern_id, cmd->vdev_id);
10125 
10126 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10127 				 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
10128 		WMI_LOGE("%s: failed to send del pattern command", __func__);
10129 		wmi_buf_free(wmi_buf);
10130 		return QDF_STATUS_E_FAILURE;
10131 	}
10132 	return QDF_STATUS_SUCCESS;
10133 }
10134 
10135 /**
10136  * send_stats_ext_req_cmd_tlv() - request ext stats from fw
10137  * @wmi_handle: wmi handle
10138  * @preq: stats ext params
10139  *
10140  * Return: CDF status
10141  */
10142 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle,
10143 			struct stats_ext_params *preq)
10144 {
10145 	QDF_STATUS ret;
10146 	wmi_req_stats_ext_cmd_fixed_param *cmd;
10147 	wmi_buf_t buf;
10148 	uint16_t len;
10149 	uint8_t *buf_ptr;
10150 
10151 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len;
10152 
10153 	buf = wmi_buf_alloc(wmi_handle, len);
10154 	if (!buf) {
10155 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
10156 		return QDF_STATUS_E_NOMEM;
10157 	}
10158 
10159 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
10160 	cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr;
10161 
10162 	WMITLV_SET_HDR(&cmd->tlv_header,
10163 		       WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param,
10164 		       WMITLV_GET_STRUCT_TLVLEN
10165 			       (wmi_req_stats_ext_cmd_fixed_param));
10166 	cmd->vdev_id = preq->vdev_id;
10167 	cmd->data_len = preq->request_data_len;
10168 
10169 	WMI_LOGD("%s: The data len value is %u and vdev id set is %u ",
10170 		 __func__, preq->request_data_len, preq->vdev_id);
10171 
10172 	buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param);
10173 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len);
10174 
10175 	buf_ptr += WMI_TLV_HDR_SIZE;
10176 	qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len);
10177 
10178 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
10179 				   WMI_REQUEST_STATS_EXT_CMDID);
10180 	if (QDF_IS_STATUS_ERROR(ret)) {
10181 		WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__,
10182 			 ret);
10183 		wmi_buf_free(buf);
10184 	}
10185 
10186 	return ret;
10187 }
10188 
10189 /**
10190  * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw
10191  * @wmi_handle: wmi handle
10192  * @params: ext wow params
10193  *
10194  * Return:0 for success or error code
10195  */
10196 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle,
10197 			struct ext_wow_params *params)
10198 {
10199 	wmi_extwow_enable_cmd_fixed_param *cmd;
10200 	wmi_buf_t buf;
10201 	int32_t len;
10202 	int ret;
10203 
10204 	len = sizeof(wmi_extwow_enable_cmd_fixed_param);
10205 	buf = wmi_buf_alloc(wmi_handle, len);
10206 	if (!buf) {
10207 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
10208 		return QDF_STATUS_E_NOMEM;
10209 	}
10210 
10211 	cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf);
10212 
10213 	WMITLV_SET_HDR(&cmd->tlv_header,
10214 		       WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param,
10215 		       WMITLV_GET_STRUCT_TLVLEN
10216 			       (wmi_extwow_enable_cmd_fixed_param));
10217 
10218 	cmd->vdev_id = params->vdev_id;
10219 	cmd->type = params->type;
10220 	cmd->wakeup_pin_num = params->wakeup_pin_num;
10221 
10222 	WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x",
10223 		 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num);
10224 
10225 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
10226 				   WMI_EXTWOW_ENABLE_CMDID);
10227 	if (ret) {
10228 		WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__);
10229 		wmi_buf_free(buf);
10230 		return QDF_STATUS_E_FAILURE;
10231 	}
10232 
10233 	return QDF_STATUS_SUCCESS;
10234 
10235 }
10236 
10237 /**
10238  * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw
10239  * @wmi_handle: wmi handle
10240  * @app_type1_params: app type1 params
10241  *
10242  * Return: CDF status
10243  */
10244 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
10245 				   struct app_type1_params *app_type1_params)
10246 {
10247 	wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd;
10248 	wmi_buf_t buf;
10249 	int32_t len;
10250 	int ret;
10251 
10252 	len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param);
10253 	buf = wmi_buf_alloc(wmi_handle, len);
10254 	if (!buf) {
10255 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
10256 		return QDF_STATUS_E_NOMEM;
10257 	}
10258 
10259 	cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *)
10260 	      wmi_buf_data(buf);
10261 
10262 	WMITLV_SET_HDR(&cmd->tlv_header,
10263 	       WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param,
10264 	       WMITLV_GET_STRUCT_TLVLEN
10265 	       (wmi_extwow_set_app_type1_params_cmd_fixed_param));
10266 
10267 	cmd->vdev_id = app_type1_params->vdev_id;
10268 	WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes,
10269 				   &cmd->wakee_mac);
10270 	qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8);
10271 	cmd->ident_len = app_type1_params->id_length;
10272 	qdf_mem_copy(cmd->passwd, app_type1_params->password, 16);
10273 	cmd->passwd_len = app_type1_params->pass_length;
10274 
10275 	WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM "
10276 		 "identification_id %.8s id_length %u "
10277 		 "password %.16s pass_length %u",
10278 		 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes,
10279 		 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len);
10280 
10281 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
10282 				   WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID);
10283 	if (ret) {
10284 		WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__);
10285 		wmi_buf_free(buf);
10286 		return QDF_STATUS_E_FAILURE;
10287 	}
10288 
10289 	return QDF_STATUS_SUCCESS;
10290 }
10291 
10292 /**
10293  * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw
10294  * @wmi_handle: wmi handle
10295  * @appType2Params: app type2 params
10296  *
10297  * Return: CDF status
10298  */
10299 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
10300 			  struct app_type2_params *appType2Params)
10301 {
10302 	wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd;
10303 	wmi_buf_t buf;
10304 	int32_t len;
10305 	int ret;
10306 
10307 	len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param);
10308 	buf = wmi_buf_alloc(wmi_handle, len);
10309 	if (!buf) {
10310 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
10311 		return QDF_STATUS_E_NOMEM;
10312 	}
10313 
10314 	cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *)
10315 	      wmi_buf_data(buf);
10316 
10317 	WMITLV_SET_HDR(&cmd->tlv_header,
10318 	       WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param,
10319 	       WMITLV_GET_STRUCT_TLVLEN
10320 	       (wmi_extwow_set_app_type2_params_cmd_fixed_param));
10321 
10322 	cmd->vdev_id = appType2Params->vdev_id;
10323 
10324 	qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16);
10325 	cmd->rc4_key_len = appType2Params->rc4_key_len;
10326 
10327 	cmd->ip_id = appType2Params->ip_id;
10328 	cmd->ip_device_ip = appType2Params->ip_device_ip;
10329 	cmd->ip_server_ip = appType2Params->ip_server_ip;
10330 
10331 	cmd->tcp_src_port = appType2Params->tcp_src_port;
10332 	cmd->tcp_dst_port = appType2Params->tcp_dst_port;
10333 	cmd->tcp_seq = appType2Params->tcp_seq;
10334 	cmd->tcp_ack_seq = appType2Params->tcp_ack_seq;
10335 
10336 	cmd->keepalive_init = appType2Params->keepalive_init;
10337 	cmd->keepalive_min = appType2Params->keepalive_min;
10338 	cmd->keepalive_max = appType2Params->keepalive_max;
10339 	cmd->keepalive_inc = appType2Params->keepalive_inc;
10340 
10341 	WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes,
10342 				   &cmd->gateway_mac);
10343 	cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val;
10344 	cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val;
10345 
10346 	WMI_LOGD("%s: vdev_id %d gateway_mac %pM "
10347 		 "rc4_key %.16s rc4_key_len %u "
10348 		 "ip_id %x ip_device_ip %x ip_server_ip %x "
10349 		 "tcp_src_port %u tcp_dst_port %u tcp_seq %u "
10350 		 "tcp_ack_seq %u keepalive_init %u keepalive_min %u "
10351 		 "keepalive_max %u keepalive_inc %u "
10352 		 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u",
10353 		 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes,
10354 		 cmd->rc4_key, cmd->rc4_key_len,
10355 		 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip,
10356 		 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq,
10357 		 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min,
10358 		 cmd->keepalive_max, cmd->keepalive_inc,
10359 		 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val);
10360 
10361 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
10362 				   WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID);
10363 	if (ret) {
10364 		WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__);
10365 		wmi_buf_free(buf);
10366 		return QDF_STATUS_E_FAILURE;
10367 	}
10368 
10369 	return QDF_STATUS_SUCCESS;
10370 
10371 }
10372 
10373 /**
10374  * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware
10375  * @wmi_handle: wmi handle
10376  * @timer_val: auto shutdown timer value
10377  *
10378  * Return: CDF status
10379  */
10380 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle,
10381 						  uint32_t timer_val)
10382 {
10383 	QDF_STATUS status;
10384 	wmi_buf_t buf = NULL;
10385 	uint8_t *buf_ptr;
10386 	wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd;
10387 	int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param);
10388 
10389 	WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d",
10390 		 __func__, timer_val);
10391 
10392 	buf = wmi_buf_alloc(wmi_handle, len);
10393 	if (!buf) {
10394 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
10395 		return QDF_STATUS_E_NOMEM;
10396 	}
10397 
10398 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
10399 	wmi_auto_sh_cmd =
10400 		(wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr;
10401 	wmi_auto_sh_cmd->timer_value = timer_val;
10402 
10403 	WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header,
10404 	       WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param,
10405 	       WMITLV_GET_STRUCT_TLVLEN
10406 	       (wmi_host_auto_shutdown_cfg_cmd_fixed_param));
10407 
10408 	status = wmi_unified_cmd_send(wmi_handle, buf,
10409 				      len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID);
10410 	if (QDF_IS_STATUS_ERROR(status)) {
10411 		WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d",
10412 			 __func__, status);
10413 		wmi_buf_free(buf);
10414 	}
10415 
10416 	return status;
10417 }
10418 
10419 /**
10420  * send_nan_req_cmd_tlv() - to send nan request to target
10421  * @wmi_handle: wmi handle
10422  * @nan_req: request data which will be non-null
10423  *
10424  * Return: CDF status
10425  */
10426 static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle,
10427 			struct nan_req_params *nan_req)
10428 {
10429 	QDF_STATUS ret;
10430 	wmi_nan_cmd_param *cmd;
10431 	wmi_buf_t buf;
10432 	uint16_t len = sizeof(*cmd);
10433 	uint16_t nan_data_len, nan_data_len_aligned;
10434 	uint8_t *buf_ptr;
10435 
10436 	/*
10437 	 *    <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ---->
10438 	 *    +------------+----------+-----------------------+--------------+
10439 	 *    | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data |
10440 	 *    +------------+----------+-----------------------+--------------+
10441 	 */
10442 	if (!nan_req) {
10443 		WMI_LOGE("%s:nan req is not valid", __func__);
10444 		return QDF_STATUS_E_FAILURE;
10445 	}
10446 	nan_data_len = nan_req->request_data_len;
10447 	nan_data_len_aligned = roundup(nan_req->request_data_len,
10448 				       sizeof(uint32_t));
10449 	len += WMI_TLV_HDR_SIZE + nan_data_len_aligned;
10450 	buf = wmi_buf_alloc(wmi_handle, len);
10451 	if (!buf) {
10452 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
10453 		return QDF_STATUS_E_NOMEM;
10454 	}
10455 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
10456 	cmd = (wmi_nan_cmd_param *) buf_ptr;
10457 	WMITLV_SET_HDR(&cmd->tlv_header,
10458 		       WMITLV_TAG_STRUC_wmi_nan_cmd_param,
10459 		       WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param));
10460 	cmd->data_len = nan_req->request_data_len;
10461 	WMI_LOGD("%s: The data len value is %u",
10462 		 __func__, nan_req->request_data_len);
10463 	buf_ptr += sizeof(wmi_nan_cmd_param);
10464 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned);
10465 	buf_ptr += WMI_TLV_HDR_SIZE;
10466 	qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len);
10467 
10468 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
10469 				   WMI_NAN_CMDID);
10470 	if (QDF_IS_STATUS_ERROR(ret)) {
10471 		WMI_LOGE("%s Failed to send set param command ret = %d",
10472 			 __func__, ret);
10473 		wmi_buf_free(buf);
10474 	}
10475 
10476 	return ret;
10477 }
10478 
10479 /**
10480  * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload
10481  * @wmi_handle: wmi handle
10482  * @params: DHCP server offload info
10483  *
10484  * Return: QDF_STATUS_SUCCESS for success or error code
10485  */
10486 static QDF_STATUS
10487 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle,
10488 					struct dhcp_offload_info_params *params)
10489 {
10490 	wmi_set_dhcp_server_offload_cmd_fixed_param *cmd;
10491 	wmi_buf_t buf;
10492 	QDF_STATUS status;
10493 
10494 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
10495 	if (!buf) {
10496 		WMI_LOGE("Failed to allocate buffer to send "
10497 			 "set_dhcp_server_offload cmd");
10498 		return QDF_STATUS_E_NOMEM;
10499 	}
10500 
10501 	cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf);
10502 
10503 	WMITLV_SET_HDR(&cmd->tlv_header,
10504 	       WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param,
10505 	       WMITLV_GET_STRUCT_TLVLEN
10506 	       (wmi_set_dhcp_server_offload_cmd_fixed_param));
10507 	cmd->vdev_id = params->vdev_id;
10508 	cmd->enable = params->dhcp_offload_enabled;
10509 	cmd->num_client = params->dhcp_client_num;
10510 	cmd->srv_ipv4 = params->dhcp_srv_addr;
10511 	cmd->start_lsb = 0;
10512 	status = wmi_unified_cmd_send(wmi_handle, buf,
10513 				   sizeof(*cmd),
10514 				   WMI_SET_DHCP_SERVER_OFFLOAD_CMDID);
10515 	if (QDF_IS_STATUS_ERROR(status)) {
10516 		WMI_LOGE("Failed to send set_dhcp_server_offload cmd");
10517 		wmi_buf_free(buf);
10518 		return QDF_STATUS_E_FAILURE;
10519 	}
10520 	WMI_LOGD("Set dhcp server offload to vdevId %d",
10521 		 params->vdev_id);
10522 
10523 	return status;
10524 }
10525 
10526 /**
10527  * send_set_led_flashing_cmd_tlv() - set led flashing in fw
10528  * @wmi_handle: wmi handle
10529  * @flashing: flashing request
10530  *
10531  * Return: CDF status
10532  */
10533 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle,
10534 				struct flashing_req_params *flashing)
10535 {
10536 	wmi_set_led_flashing_cmd_fixed_param *cmd;
10537 	QDF_STATUS status;
10538 	wmi_buf_t buf;
10539 	uint8_t *buf_ptr;
10540 	int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param);
10541 
10542 	buf = wmi_buf_alloc(wmi_handle, len);
10543 	if (!buf) {
10544 		WMI_LOGP(FL("wmi_buf_alloc failed"));
10545 		return QDF_STATUS_E_NOMEM;
10546 	}
10547 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
10548 	cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr;
10549 	WMITLV_SET_HDR(&cmd->tlv_header,
10550 		       WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param,
10551 		       WMITLV_GET_STRUCT_TLVLEN
10552 			       (wmi_set_led_flashing_cmd_fixed_param));
10553 	cmd->pattern_id = flashing->pattern_id;
10554 	cmd->led_x0 = flashing->led_x0;
10555 	cmd->led_x1 = flashing->led_x1;
10556 
10557 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
10558 				      WMI_PDEV_SET_LED_FLASHING_CMDID);
10559 	if (QDF_IS_STATUS_ERROR(status)) {
10560 		WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
10561 			 " returned Error %d", __func__, status);
10562 		wmi_buf_free(buf);
10563 	}
10564 
10565 	return status;
10566 }
10567 
10568 /**
10569  * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request
10570  * @wmi_handle: wmi handle
10571  * @ch_avoid_update_req: channel avoid update params
10572  *
10573  * Return: CDF status
10574  */
10575 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle)
10576 {
10577 	QDF_STATUS status;
10578 	wmi_buf_t buf = NULL;
10579 	uint8_t *buf_ptr;
10580 	wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp;
10581 	int len = sizeof(wmi_chan_avoid_update_cmd_param);
10582 
10583 
10584 	buf = wmi_buf_alloc(wmi_handle, len);
10585 	if (!buf) {
10586 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
10587 		return QDF_STATUS_E_NOMEM;
10588 	}
10589 
10590 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
10591 	ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr;
10592 	WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header,
10593 		       WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param,
10594 		       WMITLV_GET_STRUCT_TLVLEN
10595 			       (wmi_chan_avoid_update_cmd_param));
10596 
10597 	status = wmi_unified_cmd_send(wmi_handle, buf,
10598 				      len, WMI_CHAN_AVOID_UPDATE_CMDID);
10599 	if (QDF_IS_STATUS_ERROR(status)) {
10600 		WMI_LOGE("wmi_unified_cmd_send"
10601 			 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE"
10602 			 " returned Error %d", status);
10603 		wmi_buf_free(buf);
10604 	}
10605 
10606 	return status;
10607 }
10608 
10609 /**
10610  * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw
10611  * @wmi_handle: wmi handle
10612  * @param: pointer to pdev regdomain params
10613  *
10614  * Return: 0 for success or error code
10615  */
10616 static QDF_STATUS
10617 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle,
10618 				struct pdev_set_regdomain_params *param)
10619 {
10620 	wmi_buf_t buf;
10621 	wmi_pdev_set_regdomain_cmd_fixed_param *cmd;
10622 	int32_t len = sizeof(*cmd);
10623 
10624 
10625 	buf = wmi_buf_alloc(wmi_handle, len);
10626 	if (!buf) {
10627 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
10628 		return QDF_STATUS_E_NOMEM;
10629 	}
10630 	cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf);
10631 	WMITLV_SET_HDR(&cmd->tlv_header,
10632 		       WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param,
10633 		       WMITLV_GET_STRUCT_TLVLEN
10634 			       (wmi_pdev_set_regdomain_cmd_fixed_param));
10635 
10636 	cmd->reg_domain = param->currentRDinuse;
10637 	cmd->reg_domain_2G = param->currentRD2G;
10638 	cmd->reg_domain_5G = param->currentRD5G;
10639 	cmd->conformance_test_limit_2G = param->ctl_2G;
10640 	cmd->conformance_test_limit_5G = param->ctl_5G;
10641 	cmd->dfs_domain = param->dfsDomain;
10642 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
10643 							param->pdev_id);
10644 
10645 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10646 				 WMI_PDEV_SET_REGDOMAIN_CMDID)) {
10647 		WMI_LOGE("%s: Failed to send pdev set regdomain command",
10648 			 __func__);
10649 		wmi_buf_free(buf);
10650 		return QDF_STATUS_E_FAILURE;
10651 	}
10652 
10653 	return QDF_STATUS_SUCCESS;
10654 }
10655 
10656 /**
10657  * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw
10658  * @wmi_handle: wmi handle
10659  * @reg_dmn: reg domain
10660  * @regdmn2G: 2G reg domain
10661  * @regdmn5G: 5G reg domain
10662  * @ctl2G: 2G test limit
10663  * @ctl5G: 5G test limit
10664  *
10665  * Return: none
10666  */
10667 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle,
10668 				   uint32_t reg_dmn, uint16_t regdmn2G,
10669 				   uint16_t regdmn5G, uint8_t ctl2G,
10670 				   uint8_t ctl5G)
10671 {
10672 	wmi_buf_t buf;
10673 	wmi_pdev_set_regdomain_cmd_fixed_param *cmd;
10674 	int32_t len = sizeof(*cmd);
10675 
10676 
10677 	buf = wmi_buf_alloc(wmi_handle, len);
10678 	if (!buf) {
10679 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
10680 		return QDF_STATUS_E_NOMEM;
10681 	}
10682 	cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf);
10683 	WMITLV_SET_HDR(&cmd->tlv_header,
10684 		       WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param,
10685 		       WMITLV_GET_STRUCT_TLVLEN
10686 			       (wmi_pdev_set_regdomain_cmd_fixed_param));
10687 	cmd->reg_domain = reg_dmn;
10688 	cmd->reg_domain_2G = regdmn2G;
10689 	cmd->reg_domain_5G = regdmn5G;
10690 	cmd->conformance_test_limit_2G = ctl2G;
10691 	cmd->conformance_test_limit_5G = ctl5G;
10692 
10693 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
10694 				 WMI_PDEV_SET_REGDOMAIN_CMDID)) {
10695 		WMI_LOGP("%s: Failed to send pdev set regdomain command",
10696 			 __func__);
10697 		wmi_buf_free(buf);
10698 		return QDF_STATUS_E_FAILURE;
10699 	}
10700 
10701 	return QDF_STATUS_SUCCESS;
10702 }
10703 
10704 
10705 /**
10706  * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode
10707  * @wmi_handle: wmi handle
10708  * @chan_switch_params: Pointer to tdls channel switch parameter structure
10709  *
10710  * This function sets tdls off channel mode
10711  *
10712  * Return: 0 on success; Negative errno otherwise
10713  */
10714 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle,
10715 	      struct tdls_channel_switch_params *chan_switch_params)
10716 {
10717 	wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd;
10718 	wmi_buf_t wmi_buf;
10719 	u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param);
10720 
10721 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10722 	if (!wmi_buf) {
10723 		WMI_LOGE(FL("wmi_buf_alloc failed"));
10724 		return QDF_STATUS_E_FAILURE;
10725 	}
10726 	cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *)
10727 		wmi_buf_data(wmi_buf);
10728 	WMITLV_SET_HDR(&cmd->tlv_header,
10729 		WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param,
10730 		WMITLV_GET_STRUCT_TLVLEN(
10731 			wmi_tdls_set_offchan_mode_cmd_fixed_param));
10732 
10733 	WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr,
10734 				&cmd->peer_macaddr);
10735 	cmd->vdev_id = chan_switch_params->vdev_id;
10736 	cmd->offchan_mode = chan_switch_params->tdls_sw_mode;
10737 	cmd->is_peer_responder = chan_switch_params->is_responder;
10738 	cmd->offchan_num = chan_switch_params->tdls_off_ch;
10739 	cmd->offchan_bw_bitmap = chan_switch_params->tdls_off_ch_bw_offset;
10740 	cmd->offchan_oper_class = chan_switch_params->oper_class;
10741 
10742 	WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"),
10743 		 cmd->peer_macaddr.mac_addr31to0,
10744 		 cmd->peer_macaddr.mac_addr47to32);
10745 
10746 	WMI_LOGD(FL(
10747 		 "vdev_id: %d, off channel mode: %d, off channel Num: %d, "
10748 		 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d"
10749 		  ),
10750 		 cmd->vdev_id,
10751 		 cmd->offchan_mode,
10752 		 cmd->offchan_num,
10753 		 cmd->offchan_bw_bitmap,
10754 		 cmd->is_peer_responder,
10755 		 cmd->offchan_oper_class);
10756 
10757 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10758 		WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) {
10759 		WMI_LOGP(FL("failed to send tdls off chan command"));
10760 		wmi_buf_free(wmi_buf);
10761 		return QDF_STATUS_E_FAILURE;
10762 	}
10763 
10764 
10765 	return QDF_STATUS_SUCCESS;
10766 }
10767 
10768 /**
10769  * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev
10770  * @wmi_handle: wmi handle
10771  * @pwmaTdlsparams: TDLS params
10772  *
10773  * Return: 0 for sucess or error code
10774  */
10775 static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle,
10776 					 void *tdls_param, uint8_t tdls_state)
10777 {
10778 	wmi_tdls_set_state_cmd_fixed_param *cmd;
10779 	wmi_buf_t wmi_buf;
10780 
10781 	struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param;
10782 	uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param);
10783 
10784 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10785 	if (!wmi_buf) {
10786 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
10787 		return QDF_STATUS_E_FAILURE;
10788 	}
10789 	cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf);
10790 	WMITLV_SET_HDR(&cmd->tlv_header,
10791 		  WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param,
10792 		  WMITLV_GET_STRUCT_TLVLEN
10793 		  (wmi_tdls_set_state_cmd_fixed_param));
10794 	cmd->vdev_id = wmi_tdls->vdev_id;
10795 	cmd->state = tdls_state;
10796 	cmd->notification_interval_ms = wmi_tdls->notification_interval_ms;
10797 	cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold;
10798 	cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold;
10799 	cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold;
10800 	cmd->rssi_delta = wmi_tdls->rssi_delta;
10801 	cmd->tdls_options = wmi_tdls->tdls_options;
10802 	cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window;
10803 	cmd->tdls_peer_traffic_response_timeout_ms =
10804 		wmi_tdls->peer_traffic_response_timeout;
10805 	cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask;
10806 	cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time;
10807 	cmd->tdls_puapsd_rx_frame_threshold =
10808 		wmi_tdls->puapsd_rx_frame_threshold;
10809 	cmd->teardown_notification_ms =
10810 		wmi_tdls->teardown_notification_ms;
10811 	cmd->tdls_peer_kickout_threshold =
10812 		wmi_tdls->tdls_peer_kickout_threshold;
10813 
10814 	WMI_LOGD("%s: tdls_state: %d, state: %d, "
10815 		 "notification_interval_ms: %d, "
10816 		 "tx_discovery_threshold: %d, "
10817 		 "tx_teardown_threshold: %d, "
10818 		 "rssi_teardown_threshold: %d, "
10819 		 "rssi_delta: %d, "
10820 		 "tdls_options: 0x%x, "
10821 		 "tdls_peer_traffic_ind_window: %d, "
10822 		 "tdls_peer_traffic_response_timeout: %d, "
10823 		 "tdls_puapsd_mask: 0x%x, "
10824 		 "tdls_puapsd_inactivity_time: %d, "
10825 		 "tdls_puapsd_rx_frame_threshold: %d, "
10826 		 "teardown_notification_ms: %d, "
10827 		 "tdls_peer_kickout_threshold: %d",
10828 		 __func__, tdls_state, cmd->state,
10829 		 cmd->notification_interval_ms,
10830 		 cmd->tx_discovery_threshold,
10831 		 cmd->tx_teardown_threshold,
10832 		 cmd->rssi_teardown_threshold,
10833 		 cmd->rssi_delta,
10834 		 cmd->tdls_options,
10835 		 cmd->tdls_peer_traffic_ind_window,
10836 		 cmd->tdls_peer_traffic_response_timeout_ms,
10837 		 cmd->tdls_puapsd_mask,
10838 		 cmd->tdls_puapsd_inactivity_time_ms,
10839 		 cmd->tdls_puapsd_rx_frame_threshold,
10840 		 cmd->teardown_notification_ms,
10841 		 cmd->tdls_peer_kickout_threshold);
10842 
10843 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
10844 				 WMI_TDLS_SET_STATE_CMDID)) {
10845 		WMI_LOGP("%s: failed to send tdls set state command", __func__);
10846 		wmi_buf_free(wmi_buf);
10847 		return QDF_STATUS_E_FAILURE;
10848 	}
10849 	WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id);
10850 
10851 	return QDF_STATUS_SUCCESS;
10852 }
10853 
10854 /**
10855  * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state
10856  * @wmi_handle: wmi handle
10857  * @peerStateParams: TDLS peer state params
10858  *
10859  * Return: QDF_STATUS_SUCCESS for success or error code
10860  */
10861 static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle,
10862 			       struct tdls_peer_state_params *peerStateParams,
10863 				   uint32_t *ch_mhz)
10864 {
10865 	wmi_tdls_peer_update_cmd_fixed_param *cmd;
10866 	wmi_tdls_peer_capabilities *peer_cap;
10867 	wmi_channel *chan_info;
10868 	wmi_buf_t wmi_buf;
10869 	uint8_t *buf_ptr;
10870 	uint32_t i;
10871 	int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) +
10872 		      sizeof(wmi_tdls_peer_capabilities);
10873 
10874 
10875 	len += WMI_TLV_HDR_SIZE +
10876 	       sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen;
10877 
10878 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
10879 	if (!wmi_buf) {
10880 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
10881 		return QDF_STATUS_E_FAILURE;
10882 	}
10883 
10884 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
10885 	cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr;
10886 	WMITLV_SET_HDR(&cmd->tlv_header,
10887 		       WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param,
10888 		       WMITLV_GET_STRUCT_TLVLEN
10889 			       (wmi_tdls_peer_update_cmd_fixed_param));
10890 
10891 	cmd->vdev_id = peerStateParams->vdevId;
10892 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr,
10893 				   &cmd->peer_macaddr);
10894 
10895 
10896 	cmd->peer_state = peerStateParams->peerState;
10897 
10898 	WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, "
10899 		 "peer_macaddr.mac_addr31to0: 0x%x, "
10900 		 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d",
10901 		 __func__, cmd->vdev_id, peerStateParams->peerMacAddr,
10902 		 cmd->peer_macaddr.mac_addr31to0,
10903 		 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state);
10904 
10905 	buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param);
10906 	peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr;
10907 	WMITLV_SET_HDR(&peer_cap->tlv_header,
10908 		       WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities,
10909 		       WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities));
10910 
10911 	if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3)
10912 		WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap);
10913 	if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2)
10914 		WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap);
10915 	if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1)
10916 		WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap);
10917 	if (peerStateParams->peerCap.peerUapsdQueue & 0x01)
10918 		WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap);
10919 
10920 	/* Ack and More Data Ack are sent as 0, so no need to set
10921 	 * but fill SP
10922 	 */
10923 	WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap,
10924 				   peerStateParams->peerCap.peerMaxSp);
10925 
10926 	peer_cap->buff_sta_support =
10927 		peerStateParams->peerCap.peerBuffStaSupport;
10928 	peer_cap->off_chan_support =
10929 		peerStateParams->peerCap.peerOffChanSupport;
10930 	peer_cap->peer_curr_operclass =
10931 		peerStateParams->peerCap.peerCurrOperClass;
10932 	/* self curr operclass is not being used and so pass op class for
10933 	 * preferred off chan in it.
10934 	 */
10935 	peer_cap->self_curr_operclass =
10936 		peerStateParams->peerCap.opClassForPrefOffChan;
10937 	peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen;
10938 	peer_cap->peer_operclass_len =
10939 		peerStateParams->peerCap.peerOperClassLen;
10940 
10941 	WMI_LOGD("%s: peer_operclass_len: %d",
10942 		 __func__, peer_cap->peer_operclass_len);
10943 	for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) {
10944 		peer_cap->peer_operclass[i] =
10945 			peerStateParams->peerCap.peerOperClass[i];
10946 		WMI_LOGD("%s: peer_operclass[%d]: %d",
10947 			 __func__, i, peer_cap->peer_operclass[i]);
10948 	}
10949 
10950 	peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder;
10951 	peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum;
10952 	peer_cap->pref_offchan_bw =
10953 		peerStateParams->peerCap.prefOffChanBandwidth;
10954 
10955 	WMI_LOGD
10956 		("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, "
10957 		 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: "
10958 		 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:"
10959 		 " %d, pref_offchan_bw: %d",
10960 		__func__, peer_cap->peer_qos, peer_cap->buff_sta_support,
10961 		peer_cap->off_chan_support, peer_cap->peer_curr_operclass,
10962 		peer_cap->self_curr_operclass, peer_cap->peer_chan_len,
10963 		peer_cap->peer_operclass_len, peer_cap->is_peer_responder,
10964 		peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw);
10965 
10966 	/* next fill variable size array of peer chan info */
10967 	buf_ptr += sizeof(wmi_tdls_peer_capabilities);
10968 	WMITLV_SET_HDR(buf_ptr,
10969 		       WMITLV_TAG_ARRAY_STRUC,
10970 		       sizeof(wmi_channel) *
10971 		       peerStateParams->peerCap.peerChanLen);
10972 	chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE);
10973 
10974 	for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) {
10975 		WMITLV_SET_HDR(&chan_info->tlv_header,
10976 			       WMITLV_TAG_STRUC_wmi_channel,
10977 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
10978 		chan_info->mhz = ch_mhz[i];
10979 		chan_info->band_center_freq1 = chan_info->mhz;
10980 		chan_info->band_center_freq2 = 0;
10981 
10982 		WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz);
10983 
10984 		if (peerStateParams->peerCap.peerChan[i].dfsSet) {
10985 			WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE);
10986 			WMI_LOGI("chan[%d] DFS[%d]\n",
10987 				 peerStateParams->peerCap.peerChan[i].chanId,
10988 				 peerStateParams->peerCap.peerChan[i].dfsSet);
10989 		}
10990 
10991 		if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ)
10992 			WMI_SET_CHANNEL_MODE(chan_info, MODE_11G);
10993 		else
10994 			WMI_SET_CHANNEL_MODE(chan_info, MODE_11A);
10995 
10996 		WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
10997 					     peerStateParams->peerCap.
10998 					     peerChan[i].pwr);
10999 
11000 		WMI_SET_CHANNEL_REG_POWER(chan_info,
11001 					  peerStateParams->peerCap.peerChan[i].
11002 					  pwr);
11003 		WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz,
11004 			 peerStateParams->peerCap.peerChan[i].pwr);
11005 
11006 		chan_info++;
11007 	}
11008 
11009 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
11010 				 WMI_TDLS_PEER_UPDATE_CMDID)) {
11011 		WMI_LOGE("%s: failed to send tdls peer update state command",
11012 			 __func__);
11013 		wmi_buf_free(wmi_buf);
11014 		return QDF_STATUS_E_FAILURE;
11015 	}
11016 
11017 
11018 	return QDF_STATUS_SUCCESS;
11019 }
11020 
11021 /*
11022  * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware
11023  * @wmi_handle:    Pointer to WMi handle
11024  * @ie_data:       Pointer for ie data
11025  *
11026  * This function sends IE information to firmware
11027  *
11028  * Return: QDF_STATUS_SUCCESS for success otherwise failure
11029  *
11030  */
11031 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle,
11032 				   struct vdev_ie_info_param *ie_info)
11033 {
11034 	wmi_vdev_set_ie_cmd_fixed_param *cmd;
11035 	wmi_buf_t buf;
11036 	uint8_t *buf_ptr;
11037 	uint32_t len, ie_len_aligned;
11038 	QDF_STATUS ret;
11039 
11040 
11041 	ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t));
11042 	/* Allocate memory for the WMI command */
11043 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned;
11044 
11045 	buf = wmi_buf_alloc(wmi_handle, len);
11046 	if (!buf) {
11047 		WMI_LOGE(FL("wmi_buf_alloc failed"));
11048 		return QDF_STATUS_E_NOMEM;
11049 	}
11050 
11051 	buf_ptr = wmi_buf_data(buf);
11052 	qdf_mem_zero(buf_ptr, len);
11053 
11054 	/* Populate the WMI command */
11055 	cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr;
11056 
11057 	WMITLV_SET_HDR(&cmd->tlv_header,
11058 		       WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param,
11059 		       WMITLV_GET_STRUCT_TLVLEN(
11060 			wmi_vdev_set_ie_cmd_fixed_param));
11061 	cmd->vdev_id = ie_info->vdev_id;
11062 	cmd->ie_id = ie_info->ie_id;
11063 	cmd->ie_len = ie_info->length;
11064 	cmd->band = ie_info->band;
11065 
11066 	WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id,
11067 		 ie_info->length, ie_info->vdev_id);
11068 
11069 	buf_ptr += sizeof(*cmd);
11070 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
11071 	buf_ptr += WMI_TLV_HDR_SIZE;
11072 
11073 	qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len);
11074 
11075 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
11076 				   WMI_VDEV_SET_IE_CMDID);
11077 	if (QDF_IS_STATUS_ERROR(ret)) {
11078 		WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret);
11079 		wmi_buf_free(buf);
11080 	}
11081 
11082 	return ret;
11083 }
11084 
11085 /**
11086  *  send_smart_ant_enable_cmd_tlv() - WMI smart ant enable function
11087  *
11088  *  @param wmi_handle  : handle to WMI.
11089  *  @param param       : pointer to antenna param
11090  *
11091  *  This function sends smart antenna enable command to FW
11092  *
11093  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11094  */
11095 static QDF_STATUS send_smart_ant_enable_cmd_tlv(wmi_unified_t wmi_handle,
11096 				struct smart_ant_enable_params *param)
11097 {
11098 	/* Send WMI COMMAND to Enable */
11099 	wmi_pdev_smart_ant_enable_cmd_fixed_param *cmd;
11100 	wmi_pdev_smart_ant_gpio_handle *gpio_param;
11101 	wmi_buf_t buf;
11102 	uint8_t *buf_ptr;
11103 	int len = 0;
11104 	QDF_STATUS ret;
11105 	int loop = 0;
11106 
11107 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11108 	len += WMI_HAL_MAX_SANTENNA * sizeof(wmi_pdev_smart_ant_gpio_handle);
11109 	buf = wmi_buf_alloc(wmi_handle, len);
11110 
11111 	if (!buf) {
11112 			WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11113 			return QDF_STATUS_E_NOMEM;
11114 		}
11115 
11116 	buf_ptr = wmi_buf_data(buf);
11117 	qdf_mem_zero(buf_ptr, len);
11118 	cmd = (wmi_pdev_smart_ant_enable_cmd_fixed_param *)buf_ptr;
11119 
11120 	WMITLV_SET_HDR(&cmd->tlv_header,
11121 		WMITLV_TAG_STRUC_wmi_pdev_smart_ant_enable_cmd_fixed_param,
11122 		WMITLV_GET_STRUCT_TLVLEN(
11123 				wmi_pdev_smart_ant_enable_cmd_fixed_param));
11124 
11125 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
11126 								param->pdev_id);
11127 	cmd->enable = param->enable;
11128 	cmd->mode = param->mode;
11129 	cmd->rx_antenna = param->rx_antenna;
11130 	cmd->tx_default_antenna = param->rx_antenna;
11131 
11132 	/* TLV indicating array of structures to follow */
11133 	buf_ptr += sizeof(wmi_pdev_smart_ant_enable_cmd_fixed_param);
11134 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11135 		       WMI_HAL_MAX_SANTENNA *
11136 		       sizeof(wmi_pdev_smart_ant_gpio_handle));
11137 
11138 	buf_ptr += WMI_TLV_HDR_SIZE;
11139 	gpio_param = (wmi_pdev_smart_ant_gpio_handle *)buf_ptr;
11140 
11141 	for (loop = 0; loop < WMI_HAL_MAX_SANTENNA; loop++) {
11142 		WMITLV_SET_HDR(&gpio_param->tlv_header,
11143 			       WMITLV_TAG_STRUC_wmi_pdev_smart_ant_gpio_handle,
11144 			       WMITLV_GET_STRUCT_TLVLEN(
11145 			       wmi_pdev_smart_ant_gpio_handle));
11146 		if (param->mode == SMART_ANT_MODE_SERIAL) {
11147 			if (loop < WMI_HOST_MAX_SERIAL_ANTENNA) {
11148 				gpio_param->gpio_pin = param->gpio_pin[loop];
11149 				gpio_param->gpio_func = param->gpio_func[loop];
11150 			} else {
11151 				gpio_param->gpio_pin = 0;
11152 				gpio_param->gpio_func = 0;
11153 			}
11154 		} else if (param->mode == SMART_ANT_MODE_PARALLEL) {
11155 			gpio_param->gpio_pin = param->gpio_pin[loop];
11156 			gpio_param->gpio_func = param->gpio_func[loop];
11157 		}
11158 		/* Setting it to 0 for now */
11159 		gpio_param->pdev_id =
11160 			wmi_handle->ops->convert_pdev_id_host_to_target(
11161 								param->pdev_id);
11162 		gpio_param++;
11163 	}
11164 
11165 	ret = wmi_unified_cmd_send(wmi_handle,
11166 				buf,
11167 				len,
11168 				WMI_PDEV_SMART_ANT_ENABLE_CMDID);
11169 
11170 	if (ret != 0) {
11171 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11172 		WMI_LOGE("enable:%d mode:%d  rx_antenna: 0x%08x PINS: [%d %d %d %d] Func[%d %d %d %d] cmdstatus=%d\n",
11173 			 cmd->enable,
11174 			 cmd->mode,
11175 			 cmd->rx_antenna,
11176 			 param->gpio_pin[0], param->gpio_pin[1],
11177 			 param->gpio_pin[2], param->gpio_pin[3],
11178 			 param->gpio_func[0], param->gpio_func[1],
11179 			 param->gpio_func[2], param->gpio_func[3],
11180 			 ret);
11181 		wmi_buf_free(buf);
11182 	}
11183 
11184 	return ret;
11185 }
11186 
11187 /**
11188  *  send_smart_ant_set_rx_ant_cmd_tlv() - WMI set rx antenna function
11189  *
11190  *  @param wmi_handle     : handle to WMI.
11191  *  @param param          : pointer to rx antenna param
11192  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11193  */
11194 static QDF_STATUS send_smart_ant_set_rx_ant_cmd_tlv(wmi_unified_t wmi_handle,
11195 				struct smart_ant_rx_ant_params *param)
11196 {
11197 	wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *cmd;
11198 	wmi_buf_t buf;
11199 	uint8_t *buf_ptr;
11200 	uint32_t len;
11201 	QDF_STATUS ret;
11202 
11203 	len = sizeof(*cmd);
11204 	buf = wmi_buf_alloc(wmi_handle, len);
11205 	WMI_LOGD("%s:\n", __func__);
11206 	if (!buf) {
11207 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11208 		return QDF_STATUS_E_NOMEM;
11209 	}
11210 
11211 	buf_ptr = wmi_buf_data(buf);
11212 	cmd = (wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *)buf_ptr;
11213 	WMITLV_SET_HDR(&cmd->tlv_header,
11214 	    WMITLV_TAG_STRUC_wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param,
11215 	    WMITLV_GET_STRUCT_TLVLEN(
11216 		wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param));
11217 	cmd->rx_antenna = param->antenna;
11218 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
11219 								param->pdev_id);
11220 
11221 	ret = wmi_unified_cmd_send(wmi_handle,
11222 				buf,
11223 				len,
11224 				WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID);
11225 
11226 	if (ret != 0) {
11227 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11228 		WMI_LOGE("%s: rx_antenna: 0x%08x cmdstatus=%d\n",
11229 			 __func__,
11230 			 cmd->rx_antenna,
11231 			 ret);
11232 		wmi_buf_free(buf);
11233 	}
11234 
11235 	return ret;
11236 }
11237 
11238 /**
11239  * send_set_ctl_table_cmd_tlv() - send ctl table cmd to fw
11240  * @wmi_handle: wmi handle
11241  * @param: pointer to hold ctl table param
11242  *
11243  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11244  */
11245 static QDF_STATUS
11246 send_set_ctl_table_cmd_tlv(wmi_unified_t wmi_handle,
11247 			   struct ctl_table_params *param)
11248 {
11249 	uint16_t len, ctl_tlv_len;
11250 	uint8_t *buf_ptr;
11251 	wmi_buf_t buf;
11252 	wmi_pdev_set_ctl_table_cmd_fixed_param *cmd;
11253 	uint32_t *ctl_array;
11254 
11255 	if (!param->ctl_array)
11256 		return QDF_STATUS_E_FAILURE;
11257 
11258 	ctl_tlv_len = WMI_TLV_HDR_SIZE +
11259 		roundup(param->ctl_cmd_len, sizeof(A_UINT32));
11260 	len = sizeof(*cmd) + ctl_tlv_len;
11261 
11262 	buf = wmi_buf_alloc(wmi_handle, len);
11263 	if (!buf) {
11264 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11265 		return QDF_STATUS_E_FAILURE;
11266 	}
11267 
11268 	buf_ptr = wmi_buf_data(buf);
11269 	qdf_mem_zero(buf_ptr, len);
11270 
11271 	cmd = (wmi_pdev_set_ctl_table_cmd_fixed_param *)buf_ptr;
11272 
11273 	WMITLV_SET_HDR(&cmd->tlv_header,
11274 		       WMITLV_TAG_STRUC_wmi_pdev_set_ctl_table_cmd_fixed_param,
11275 		       WMITLV_GET_STRUCT_TLVLEN(
11276 				wmi_pdev_set_ctl_table_cmd_fixed_param));
11277 	cmd->ctl_len = param->ctl_cmd_len;
11278 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
11279 								param->pdev_id);
11280 
11281 	buf_ptr += sizeof(*cmd);
11282 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
11283 		       (cmd->ctl_len));
11284 	buf_ptr += WMI_TLV_HDR_SIZE;
11285 	ctl_array = (uint32_t *)buf_ptr;
11286 
11287 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[0], &param->ctl_band,
11288 					sizeof(param->ctl_band));
11289 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[1], param->ctl_array,
11290 					param->ctl_cmd_len -
11291 					sizeof(param->ctl_band));
11292 
11293 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11294 				 WMI_PDEV_SET_CTL_TABLE_CMDID)) {
11295 		WMI_LOGE("%s:Failed to send command\n", __func__);
11296 		wmi_buf_free(buf);
11297 		return QDF_STATUS_E_FAILURE;
11298 	}
11299 
11300 	return QDF_STATUS_SUCCESS;
11301 }
11302 
11303 /**
11304  * send_set_mimogain_table_cmd_tlv() - send mimogain table cmd to fw
11305  * @wmi_handle: wmi handle
11306  * @param: pointer to hold mimogain table param
11307  *
11308  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11309  */
11310 static QDF_STATUS
11311 send_set_mimogain_table_cmd_tlv(wmi_unified_t wmi_handle,
11312 				struct mimogain_table_params *param)
11313 {
11314 	uint16_t len, table_tlv_len;
11315 	wmi_buf_t buf;
11316 	uint8_t *buf_ptr;
11317 	wmi_pdev_set_mimogain_table_cmd_fixed_param *cmd;
11318 	uint32_t *gain_table;
11319 
11320 	if (!param->array_gain)
11321 		return QDF_STATUS_E_FAILURE;
11322 
11323 	/* len must be multiple of a single array gain table */
11324 	if (param->tbl_len %
11325 	    ((WMI_HOST_TX_NUM_CHAIN-1) * WMI_HOST_TPC_REGINDEX_MAX *
11326 	     WMI_HOST_ARRAY_GAIN_NUM_STREAMS) != 0) {
11327 		WMI_LOGE("Array gain table len not correct\n");
11328 		return QDF_STATUS_E_FAILURE;
11329 	}
11330 
11331 	table_tlv_len = WMI_TLV_HDR_SIZE +
11332 		roundup(param->tbl_len, sizeof(uint32_t));
11333 	len = sizeof(*cmd) + table_tlv_len;
11334 
11335 	buf = wmi_buf_alloc(wmi_handle, len);
11336 	if (!buf) {
11337 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11338 		return QDF_STATUS_E_FAILURE;
11339 	}
11340 
11341 	buf_ptr = wmi_buf_data(buf);
11342 	qdf_mem_zero(buf_ptr, len);
11343 
11344 	cmd = (wmi_pdev_set_mimogain_table_cmd_fixed_param *)buf_ptr;
11345 
11346 	WMITLV_SET_HDR(&cmd->tlv_header,
11347 		WMITLV_TAG_STRUC_wmi_pdev_set_mimogain_table_cmd_fixed_param,
11348 		WMITLV_GET_STRUCT_TLVLEN(
11349 		       wmi_pdev_set_mimogain_table_cmd_fixed_param));
11350 
11351 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
11352 								param->pdev_id);
11353 	WMI_MIMOGAIN_ARRAY_GAIN_LEN_SET(cmd->mimogain_info, param->tbl_len);
11354 	WMI_MIMOGAIN_MULTI_CHAIN_BYPASS_SET(cmd->mimogain_info,
11355 					    param->multichain_gain_bypass);
11356 
11357 	buf_ptr += sizeof(*cmd);
11358 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
11359 		       (param->tbl_len));
11360 	buf_ptr += WMI_TLV_HDR_SIZE;
11361 	gain_table = (uint32_t *)buf_ptr;
11362 
11363 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(gain_table,
11364 					param->array_gain,
11365 					param->tbl_len);
11366 
11367 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11368 				 WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID)) {
11369 		return QDF_STATUS_E_FAILURE;
11370 	}
11371 
11372 	return QDF_STATUS_SUCCESS;
11373 }
11374 
11375 /**
11376  * enum packet_power_tlv_flags: target defined
11377  * packet power rate flags for TLV
11378  * @WMI_TLV_FLAG_ONE_CHAIN: one chain
11379  * @WMI_TLV_FLAG_TWO_CHAIN: two chain
11380  * @WMI_TLV_FLAG_THREE_CHAIN: three chain
11381  * @WMI_TLV_FLAG_FOUR_CHAIN: four chain
11382  * @WMI_TLV_FLAG_FIVE_CHAIN: five chain
11383  * @WMI_TLV_FLAG_SIX_CHAIN: six chain
11384  * @WMI_TLV_FLAG_SEVEN_CHAIN: seven chain
11385  * @WMI_TLV_FLAG_EIGHT_CHAIN:eight chain
11386  * @WMI_TLV_FLAG_STBC: STBC is set
11387  * @WMI_TLV_FLAG_40MHZ: 40MHz chan width
11388  * @WMI_TLV_FLAG_80MHZ: 80MHz chan width
11389  * @WMI_TLV_FLAG_160MHZ: 160MHz chan width
11390  * @WMI_TLV_FLAG_TXBF: Tx Bf enabled
11391  * @WMI_TLV_FLAG_RTSENA: RTS enabled
11392  * @WMI_TLV_FLAG_CTSENA: CTS enabled
11393  * @WMI_TLV_FLAG_LDPC: LDPC is set
11394  * @WMI_TLV_FLAG_SGI: Short gaurd interval
11395  * @WMI_TLV_FLAG_SU: SU Data
11396  * @WMI_TLV_FLAG_DL_MU_MIMO_AC: DL AC MU data
11397  * @WMI_TLV_FLAG_DL_MU_MIMO_AX: DL AX MU data
11398  * @WMI_TLV_FLAG_DL_OFDMA: DL OFDMA data
11399  * @WMI_TLV_FLAG_UL_OFDMA: UL OFDMA data
11400  * @WMI_TLV_FLAG_UL_MU_MIMO: UL MU data
11401  *
11402  * @WMI_TLV_FLAG_BW_MASK: bandwidth mask
11403  * @WMI_TLV_FLAG_BW_SHIFT: bandwidth shift
11404  * @WMI_TLV_FLAG_SU_MU_OFDMA_MASK: su/mu/ofdma mask
11405  * @WMI_TLV_FLAG_SU_MU_OFDMA_shift: su/mu/ofdma shift
11406  */
11407 enum packet_power_tlv_flags {
11408 	WMI_TLV_FLAG_ONE_CHAIN         = 0x00000001,
11409 	WMI_TLV_FLAG_TWO_CHAIN         = 0x00000003,
11410 	WMI_TLV_FLAG_THREE_CHAIN       = 0x00000007,
11411 	WMI_TLV_FLAG_FOUR_CHAIN        = 0x0000000F,
11412 	WMI_TLV_FLAG_FIVE_CHAIN        = 0x0000001F,
11413 	WMI_TLV_FLAG_SIX_CHAIN         = 0x0000003F,
11414 	WMI_TLV_FLAG_SEVEN_CHAIN       = 0x0000007F,
11415 	WMI_TLV_FLAG_EIGHT_CHAIN       = 0x0000008F,
11416 	WMI_TLV_FLAG_STBC              = 0x00000100,
11417 	WMI_TLV_FLAG_40MHZ             = 0x00000200,
11418 	WMI_TLV_FLAG_80MHZ             = 0x00000300,
11419 	WMI_TLV_FLAG_160MHZ            = 0x00000400,
11420 	WMI_TLV_FLAG_TXBF              = 0x00000800,
11421 	WMI_TLV_FLAG_RTSENA            = 0x00001000,
11422 	WMI_TLV_FLAG_CTSENA            = 0x00002000,
11423 	WMI_TLV_FLAG_LDPC              = 0x00004000,
11424 	WMI_TLV_FLAG_SGI               = 0x00008000,
11425 	WMI_TLV_FLAG_SU                = 0x00100000,
11426 	WMI_TLV_FLAG_DL_MU_MIMO_AC     = 0x00200000,
11427 	WMI_TLV_FLAG_DL_MU_MIMO_AX     = 0x00300000,
11428 	WMI_TLV_FLAG_DL_OFDMA          = 0x00400000,
11429 	WMI_TLV_FLAG_UL_OFDMA          = 0x00500000,
11430 	WMI_TLV_FLAG_UL_MU_MIMO        = 0x00600000,
11431 
11432 	WMI_TLV_FLAG_CHAIN_MASK        = 0xff,
11433 	WMI_TLV_FLAG_BW_MASK           = 0x3,
11434 	WMI_TLV_FLAG_BW_SHIFT          = 9,
11435 	WMI_TLV_FLAG_SU_MU_OFDMA_MASK  = 0x7,
11436 	WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT = 20,
11437 };
11438 
11439 /**
11440  * convert_to_power_info_rate_flags() - convert packet_power_info_params
11441  * to FW understandable format
11442  * @param: pointer to hold packet power info param
11443  *
11444  * @return FW understandable 32 bit rate flags
11445  */
11446 static uint32_t
11447 convert_to_power_info_rate_flags(struct packet_power_info_params *param)
11448 {
11449 	uint32_t rateflags = 0;
11450 
11451 	if (param->chainmask)
11452 		rateflags |=
11453 			(param->chainmask & WMI_TLV_FLAG_CHAIN_MASK);
11454 	if (param->chan_width)
11455 		rateflags |=
11456 			((param->chan_width & WMI_TLV_FLAG_BW_MASK)
11457 			 << WMI_TLV_FLAG_BW_SHIFT);
11458 	if (param->su_mu_ofdma)
11459 		rateflags |=
11460 			((param->su_mu_ofdma & WMI_TLV_FLAG_SU_MU_OFDMA_MASK)
11461 			 << WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT);
11462 	if (param->rate_flags & WMI_HOST_FLAG_STBC)
11463 		rateflags |= WMI_TLV_FLAG_STBC;
11464 	if (param->rate_flags & WMI_HOST_FLAG_LDPC)
11465 		rateflags |= WMI_TLV_FLAG_LDPC;
11466 	if (param->rate_flags & WMI_HOST_FLAG_TXBF)
11467 		rateflags |= WMI_TLV_FLAG_TXBF;
11468 	if (param->rate_flags & WMI_HOST_FLAG_RTSENA)
11469 		rateflags |= WMI_TLV_FLAG_RTSENA;
11470 	if (param->rate_flags & WMI_HOST_FLAG_CTSENA)
11471 		rateflags |= WMI_TLV_FLAG_CTSENA;
11472 	if (param->rate_flags & WMI_HOST_FLAG_SGI)
11473 		rateflags |= WMI_TLV_FLAG_SGI;
11474 
11475 	return rateflags;
11476 }
11477 
11478 /**
11479  * send_packet_power_info_get_cmd_tlv() - send request to get packet power
11480  * info to fw
11481  * @wmi_handle: wmi handle
11482  * @param: pointer to hold packet power info param
11483  *
11484  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11485  */
11486 static QDF_STATUS
11487 send_packet_power_info_get_cmd_tlv(wmi_unified_t wmi_handle,
11488 				   struct packet_power_info_params *param)
11489 {
11490 	wmi_pdev_get_tpc_cmd_fixed_param *cmd;
11491 	wmi_buf_t wmibuf;
11492 	uint8_t *buf_ptr;
11493 	u_int32_t len = sizeof(wmi_pdev_get_tpc_cmd_fixed_param);
11494 
11495 	wmibuf = wmi_buf_alloc(wmi_handle, len);
11496 	if (wmibuf == NULL)
11497 		return QDF_STATUS_E_NOMEM;
11498 
11499 	buf_ptr = (uint8_t *)wmi_buf_data(wmibuf);
11500 
11501 	cmd = (wmi_pdev_get_tpc_cmd_fixed_param *)buf_ptr;
11502 	WMITLV_SET_HDR(&cmd->tlv_header,
11503 		       WMITLV_TAG_STRUC_wmi_pdev_get_tpc_cmd_fixed_param,
11504 		       WMITLV_GET_STRUCT_TLVLEN(
11505 				wmi_pdev_get_tpc_cmd_fixed_param));
11506 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
11507 								param->pdev_id);
11508 	cmd->rate_flags = convert_to_power_info_rate_flags(param);
11509 	cmd->nss = param->nss;
11510 	cmd->preamble = param->preamble;
11511 	cmd->hw_rate = param->hw_rate;
11512 
11513 	WMI_LOGI("%s[%d] commandID %d, wmi_pdev_get_tpc_cmd=0x%x,"
11514 		"rate_flags: 0x%x, nss: %d, preamble: %d, hw_rate: %d\n",
11515 		__func__, __LINE__, WMI_PDEV_GET_TPC_CMDID, *((u_int32_t *)cmd),
11516 		cmd->rate_flags, cmd->nss, cmd->preamble, cmd->hw_rate);
11517 
11518 	if (wmi_unified_cmd_send(wmi_handle, wmibuf, len,
11519 				 WMI_PDEV_GET_TPC_CMDID)) {
11520 			WMI_LOGE(FL("Failed to get tpc command\n"));
11521 			wmi_buf_free(wmibuf);
11522 			return QDF_STATUS_E_FAILURE;
11523 	}
11524 
11525 	return QDF_STATUS_SUCCESS;
11526 }
11527 
11528 /**
11529  * send_vdev_config_ratemask_cmd_tlv() - config ratemask param in fw
11530  * @wmi_handle: wmi handle
11531  * @param: pointer to hold config ratemask params
11532  *
11533  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11534  */
11535 static QDF_STATUS send_vdev_config_ratemask_cmd_tlv(wmi_unified_t wmi_handle,
11536 					struct config_ratemask_params *param)
11537 {
11538 	wmi_vdev_config_ratemask_cmd_fixed_param *cmd;
11539 	wmi_buf_t buf;
11540 	int32_t len = sizeof(*cmd);
11541 
11542 	buf = wmi_buf_alloc(wmi_handle, len);
11543 	if (!buf) {
11544 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11545 		return QDF_STATUS_E_FAILURE;
11546 	}
11547 	cmd = (wmi_vdev_config_ratemask_cmd_fixed_param *)wmi_buf_data(buf);
11548 	WMITLV_SET_HDR(&cmd->tlv_header,
11549 		       WMITLV_TAG_STRUC_wmi_vdev_config_ratemask_fixed_param,
11550 		       WMITLV_GET_STRUCT_TLVLEN(
11551 				wmi_vdev_config_ratemask_cmd_fixed_param));
11552 	cmd->vdev_id = param->vdev_id;
11553 	cmd->type = param->type;
11554 	cmd->mask_lower32 = param->lower32;
11555 	cmd->mask_higher32 = param->higher32;
11556 	WMI_LOGI("Setting vdev ratemask vdev id = 0x%X, type = 0x%X, mask_l32 = 0x%X mask_h32 = 0x%X\n",
11557 		 param->vdev_id, param->type, param->lower32, param->higher32);
11558 
11559 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11560 				 WMI_VDEV_RATEMASK_CMDID)) {
11561 			WMI_LOGE("Seting vdev ratemask failed\n");
11562 			wmi_buf_free(buf);
11563 			return QDF_STATUS_E_FAILURE;
11564 	}
11565 
11566 	return QDF_STATUS_SUCCESS;
11567 }
11568 
11569 /**
11570  * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs
11571  * @param: param sent from the host side
11572  * @cmd: param to be sent to the fw side
11573  */
11574 static inline void copy_custom_aggr_bitmap(
11575 		struct set_custom_aggr_size_params *param,
11576 		wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd)
11577 {
11578 	WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap,
11579 				    param->ac);
11580 	WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap,
11581 				      param->aggr_type);
11582 	WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap,
11583 					   param->tx_aggr_size_disable);
11584 	WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap,
11585 					   param->rx_aggr_size_disable);
11586 	WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap,
11587 				     param->tx_ac_enable);
11588 }
11589 
11590 /**
11591  * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw
11592  * @wmi_handle: wmi handle
11593  * @param: pointer to hold custom aggr size params
11594  *
11595  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11596  */
11597 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv(
11598 			wmi_unified_t wmi_handle,
11599 			struct set_custom_aggr_size_params *param)
11600 {
11601 	wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd;
11602 	wmi_buf_t buf;
11603 	int32_t len = sizeof(*cmd);
11604 
11605 	buf = wmi_buf_alloc(wmi_handle, len);
11606 	if (!buf) {
11607 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11608 		return QDF_STATUS_E_FAILURE;
11609 	}
11610 	cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *)
11611 		wmi_buf_data(buf);
11612 	WMITLV_SET_HDR(&cmd->tlv_header,
11613 		WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param,
11614 		WMITLV_GET_STRUCT_TLVLEN(
11615 		wmi_vdev_set_custom_aggr_size_cmd_fixed_param));
11616 	cmd->vdev_id = param->vdev_id;
11617 	cmd->tx_aggr_size = param->tx_aggr_size;
11618 	cmd->rx_aggr_size = param->rx_aggr_size;
11619 	copy_custom_aggr_bitmap(param, cmd);
11620 
11621 	WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X "
11622 		"rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X "
11623 		"tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X "
11624 		"tx_ac_enable=0x%X\n",
11625 		param->vdev_id, param->tx_aggr_size, param->rx_aggr_size,
11626 		param->ac, param->aggr_type, param->tx_aggr_size_disable,
11627 		param->rx_aggr_size_disable, param->tx_ac_enable);
11628 
11629 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11630 				 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) {
11631 		WMI_LOGE("Seting custom aggregation size failed\n");
11632 		wmi_buf_free(buf);
11633 		return QDF_STATUS_E_FAILURE;
11634 	}
11635 
11636 	return QDF_STATUS_SUCCESS;
11637 }
11638 
11639 /**
11640  *  send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold
11641  *  @param wmi_handle  : handle to WMI.
11642  *  @param param       : pointer to tx antenna param
11643  *
11644  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11645  */
11646 
11647 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle,
11648 				struct set_qdepth_thresh_params *param)
11649 {
11650 	wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd;
11651 	wmi_msduq_qdepth_thresh_update *cmd_update;
11652 	wmi_buf_t buf;
11653 	int32_t len = 0;
11654 	int i;
11655 	uint8_t *buf_ptr;
11656 	QDF_STATUS ret;
11657 
11658 	if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) {
11659 		WMI_LOGE("%s: Invalid Update Count!\n", __func__);
11660 		return QDF_STATUS_E_INVAL;
11661 	}
11662 
11663 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11664 	len += (sizeof(wmi_msduq_qdepth_thresh_update) *
11665 			param->num_of_msduq_updates);
11666 	buf = wmi_buf_alloc(wmi_handle, len);
11667 
11668 	if (!buf) {
11669 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11670 		return QDF_STATUS_E_NOMEM;
11671 	}
11672 
11673 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11674 	cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *)
11675 								buf_ptr;
11676 
11677 	WMITLV_SET_HDR(&cmd->tlv_header,
11678 	WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param
11679 	 , WMITLV_GET_STRUCT_TLVLEN(
11680 		wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param));
11681 
11682 	cmd->pdev_id =
11683 		wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id);
11684 	cmd->vdev_id = param->vdev_id;
11685 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address);
11686 	cmd->num_of_msduq_updates = param->num_of_msduq_updates;
11687 
11688 	buf_ptr += sizeof(
11689 		wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param);
11690 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11691 			param->num_of_msduq_updates *
11692 			sizeof(wmi_msduq_qdepth_thresh_update));
11693 	buf_ptr += WMI_TLV_HDR_SIZE;
11694 	cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr;
11695 
11696 	for (i = 0; i < cmd->num_of_msduq_updates; i++) {
11697 		WMITLV_SET_HDR(&cmd_update->tlv_header,
11698 		    WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update,
11699 		    WMITLV_GET_STRUCT_TLVLEN(
11700 				wmi_msduq_qdepth_thresh_update));
11701 		cmd_update->tid_num = param->update_params[i].tid_num;
11702 		cmd_update->msduq_update_mask =
11703 				param->update_params[i].msduq_update_mask;
11704 		cmd_update->qdepth_thresh_value =
11705 				param->update_params[i].qdepth_thresh_value;
11706 		WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X "
11707 			 "mac_addr_upper4=%X, mac_addr_lower2:%X,"
11708 			 " update mask=0x%X thresh val=0x%X\n",
11709 			 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num,
11710 			 cmd->peer_mac_address.mac_addr31to0,
11711 			 cmd->peer_mac_address.mac_addr47to32,
11712 			 cmd_update->msduq_update_mask,
11713 			 cmd_update->qdepth_thresh_value);
11714 		cmd_update++;
11715 	}
11716 
11717 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
11718 				WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID);
11719 
11720 	if (ret != 0) {
11721 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11722 		wmi_buf_free(buf);
11723 	}
11724 
11725 	return ret;
11726 }
11727 
11728 /**
11729  * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw
11730  * @wmi_handle: wmi handle
11731  * @param: pointer to hold vap dscp tid map param
11732  *
11733  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11734  */
11735 static QDF_STATUS
11736 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle,
11737 				  struct vap_dscp_tid_map_params *param)
11738 {
11739 	wmi_buf_t buf;
11740 	wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd;
11741 	int32_t len = sizeof(*cmd);
11742 
11743 	buf = wmi_buf_alloc(wmi_handle, len);
11744 	if (!buf) {
11745 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11746 		return QDF_STATUS_E_FAILURE;
11747 	}
11748 
11749 	cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf);
11750 	qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map,
11751 		     sizeof(A_UINT32) * WMI_DSCP_MAP_MAX);
11752 
11753 	cmd->vdev_id = param->vdev_id;
11754 	cmd->enable_override = 0;
11755 
11756 	WMI_LOGI("Setting dscp for vap id: %d\n", cmd->vdev_id);
11757 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11758 				 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) {
11759 			WMI_LOGE("Failed to set dscp cmd\n");
11760 			wmi_buf_free(buf);
11761 			return QDF_STATUS_E_FAILURE;
11762 	}
11763 
11764 	return QDF_STATUS_SUCCESS;
11765 }
11766 
11767 /**
11768  * send_vdev_set_neighbour_rx_cmd_tlv() - set neighbour rx param in fw
11769  * @wmi_handle: wmi handle
11770  * @macaddr: vdev mac address
11771  * @param: pointer to hold neigbour rx param
11772  *
11773  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11774  */
11775 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle,
11776 					uint8_t macaddr[IEEE80211_ADDR_LEN],
11777 					struct set_neighbour_rx_params *param)
11778 {
11779 	wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd;
11780 	wmi_buf_t buf;
11781 	int32_t len = sizeof(*cmd);
11782 
11783 	buf = wmi_buf_alloc(wmi_handle, len);
11784 	if (!buf) {
11785 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11786 		return QDF_STATUS_E_FAILURE;
11787 	}
11788 	cmd = (wmi_vdev_filter_nrp_config_cmd_fixed_param *)wmi_buf_data(buf);
11789 	WMITLV_SET_HDR(&cmd->tlv_header,
11790 		WMITLV_TAG_STRUC_wmi_vdev_filter_nrp_config_cmd_fixed_param,
11791 		WMITLV_GET_STRUCT_TLVLEN(
11792 			wmi_vdev_filter_nrp_config_cmd_fixed_param));
11793 	cmd->vdev_id = param->vdev_id;
11794 	cmd->bssid_idx = param->idx;
11795 	cmd->action = param->action;
11796 	cmd->type = param->type;
11797 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->addr);
11798 	cmd->flag = 0;
11799 
11800 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11801 				 WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID)) {
11802 			WMI_LOGE("Failed to set neighbour rx param\n");
11803 			wmi_buf_free(buf);
11804 			return QDF_STATUS_E_FAILURE;
11805 	}
11806 
11807 	return QDF_STATUS_SUCCESS;
11808 }
11809 
11810 /**
11811  *  send_smart_ant_set_tx_ant_cmd_tlv() - WMI set tx antenna function
11812  *  @param wmi_handle  : handle to WMI.
11813  *  @param macaddr     : vdev mac address
11814  *  @param param       : pointer to tx antenna param
11815  *
11816  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11817  */
11818 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle,
11819 				uint8_t macaddr[IEEE80211_ADDR_LEN],
11820 				struct smart_ant_tx_ant_params *param)
11821 {
11822 	wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd;
11823 	wmi_peer_smart_ant_set_tx_antenna_series *ant_tx_series;
11824 	wmi_buf_t buf;
11825 	int32_t len = 0;
11826 	int i;
11827 	uint8_t *buf_ptr;
11828 	QDF_STATUS ret;
11829 
11830 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11831 	len += (WMI_SMART_ANT_MAX_RATE_SERIES) *
11832 		sizeof(wmi_peer_smart_ant_set_tx_antenna_series);
11833 	buf = wmi_buf_alloc(wmi_handle, len);
11834 
11835 	if (!buf) {
11836 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11837 		return QDF_STATUS_E_NOMEM;
11838 	}
11839 
11840 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11841 	qdf_mem_zero(buf_ptr, len);
11842 	cmd = (wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *)buf_ptr;
11843 
11844 	WMITLV_SET_HDR(&cmd->tlv_header,
11845 	    WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param,
11846 	    WMITLV_GET_STRUCT_TLVLEN(
11847 			wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param));
11848 
11849 	cmd->vdev_id = param->vdev_id;
11850 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11851 
11852 	buf_ptr += sizeof(wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param);
11853 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11854 		       sizeof(wmi_peer_smart_ant_set_tx_antenna_series));
11855 	buf_ptr += WMI_TLV_HDR_SIZE;
11856 	ant_tx_series = (wmi_peer_smart_ant_set_tx_antenna_series *)buf_ptr;
11857 
11858 	for (i = 0; i < WMI_SMART_ANT_MAX_RATE_SERIES; i++) {
11859 		WMITLV_SET_HDR(&ant_tx_series->tlv_header,
11860 		    WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_series,
11861 		    WMITLV_GET_STRUCT_TLVLEN(
11862 				wmi_peer_smart_ant_set_tx_antenna_series));
11863 		ant_tx_series->antenna_series = param->antenna_array[i];
11864 		ant_tx_series++;
11865 	}
11866 
11867 	ret = wmi_unified_cmd_send(wmi_handle,
11868 				   buf,
11869 				   len,
11870 				   WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID);
11871 
11872 	if (ret != 0) {
11873 		WMI_LOGE(" %s :WMI Failed\n", __func__);
11874 		wmi_buf_free(buf);
11875 	}
11876 
11877 	return ret;
11878 }
11879 
11880 /**
11881  * send_set_ant_switch_tbl_cmd_tlv() - send ant switch tbl cmd to fw
11882  * @wmi_handle: wmi handle
11883  * @param: pointer to hold ant switch tbl param
11884  *
11885  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11886  */
11887 static QDF_STATUS
11888 send_set_ant_switch_tbl_cmd_tlv(wmi_unified_t wmi_handle,
11889 				struct ant_switch_tbl_params *param)
11890 {
11891 	uint8_t len;
11892 	wmi_buf_t buf;
11893 	wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *cmd;
11894 	wmi_pdev_set_ant_ctrl_chain *ctrl_chain;
11895 	uint8_t *buf_ptr;
11896 
11897 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11898 	len += sizeof(wmi_pdev_set_ant_ctrl_chain);
11899 	buf = wmi_buf_alloc(wmi_handle, len);
11900 
11901 	if (!buf) {
11902 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11903 		return QDF_STATUS_E_NOMEM;
11904 	}
11905 
11906 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11907 	qdf_mem_zero(buf_ptr, len);
11908 	cmd = (wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *)buf_ptr;
11909 
11910 	WMITLV_SET_HDR(&cmd->tlv_header,
11911 		WMITLV_TAG_STRUC_wmi_pdev_set_ant_switch_tbl_cmd_fixed_param,
11912 		WMITLV_GET_STRUCT_TLVLEN(
11913 			wmi_pdev_set_ant_switch_tbl_cmd_fixed_param));
11914 
11915 	cmd->antCtrlCommon1 = param->ant_ctrl_common1;
11916 	cmd->antCtrlCommon2 = param->ant_ctrl_common2;
11917 	cmd->mac_id =
11918 		wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id);
11919 
11920 	/* TLV indicating array of structures to follow */
11921 	buf_ptr += sizeof(wmi_pdev_set_ant_switch_tbl_cmd_fixed_param);
11922 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11923 		       sizeof(wmi_pdev_set_ant_ctrl_chain));
11924 	buf_ptr += WMI_TLV_HDR_SIZE;
11925 	ctrl_chain = (wmi_pdev_set_ant_ctrl_chain *)buf_ptr;
11926 
11927 	ctrl_chain->pdev_id =
11928 		wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id);
11929 	ctrl_chain->antCtrlChain = param->antCtrlChain;
11930 
11931 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
11932 				 WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) {
11933 		wmi_buf_free(buf);
11934 		return QDF_STATUS_E_FAILURE;
11935 	}
11936 
11937 	return QDF_STATUS_SUCCESS;
11938 }
11939 
11940 /**
11941  *  send_smart_ant_set_training_info_cmd_tlv() - WMI set smart antenna
11942  *  training information function
11943  *  @param wmi_handle  : handle to WMI.
11944  *  @macaddr           : vdev mac address
11945  *  @param param       : pointer to tx antenna param
11946  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
11947  */
11948 static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv(
11949 				wmi_unified_t wmi_handle,
11950 				uint8_t macaddr[IEEE80211_ADDR_LEN],
11951 				struct smart_ant_training_info_params *param)
11952 {
11953 	wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd;
11954 	wmi_peer_smart_ant_set_train_antenna_param *train_param;
11955 	wmi_buf_t buf;
11956 	uint8_t *buf_ptr;
11957 	int32_t len = 0;
11958 	QDF_STATUS ret;
11959 	int loop;
11960 
11961 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
11962 	len += (WMI_SMART_ANT_MAX_RATE_SERIES) *
11963 		 sizeof(wmi_peer_smart_ant_set_train_antenna_param);
11964 	buf = wmi_buf_alloc(wmi_handle, len);
11965 
11966 	if (!buf) {
11967 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
11968 		return QDF_STATUS_E_NOMEM;
11969 	}
11970 
11971 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
11972 	qdf_mem_zero(buf_ptr, len);
11973 	cmd = (wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *)buf_ptr;
11974 
11975 	WMITLV_SET_HDR(&cmd->tlv_header,
11976 	WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param,
11977 		WMITLV_GET_STRUCT_TLVLEN(
11978 			wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param));
11979 
11980 	cmd->vdev_id = param->vdev_id;
11981 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
11982 	cmd->num_pkts = param->numpkts;
11983 
11984 	buf_ptr += sizeof(wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param);
11985 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
11986 		       sizeof(wmi_peer_smart_ant_set_train_antenna_param) *
11987 		       WMI_SMART_ANT_MAX_RATE_SERIES);
11988 
11989 	buf_ptr += WMI_TLV_HDR_SIZE;
11990 	train_param = (wmi_peer_smart_ant_set_train_antenna_param *)buf_ptr;
11991 
11992 	for (loop = 0; loop < WMI_SMART_ANT_MAX_RATE_SERIES; loop++) {
11993 		WMITLV_SET_HDR(&train_param->tlv_header,
11994 		WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_param,
11995 			    WMITLV_GET_STRUCT_TLVLEN(
11996 				wmi_peer_smart_ant_set_train_antenna_param));
11997 		train_param->train_rate_series = param->rate_array[loop];
11998 		train_param->train_antenna_series = param->antenna_array[loop];
11999 		train_param->rc_flags = 0;
12000 		WMI_LOGI(FL("Series number:%d\n"), loop);
12001 		WMI_LOGI(FL("Rate [0x%02x] Tx_Antenna [0x%08x]\n"),
12002 			 train_param->train_rate_series,
12003 			 train_param->train_antenna_series);
12004 		train_param++;
12005 	}
12006 
12007 	ret = wmi_unified_cmd_send(wmi_handle,
12008 				buf,
12009 				len,
12010 				WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID);
12011 
12012 	if (ret != 0) {
12013 		WMI_LOGE(" %s :WMI Failed\n", __func__);
12014 		wmi_buf_free(buf);
12015 		return QDF_STATUS_E_FAILURE;
12016 	}
12017 
12018 	return ret;
12019 }
12020 
12021 /**
12022  *  send_smart_ant_set_node_config_cmd_tlv() - WMI set node
12023  *  configuration function
12024  *  @param wmi_handle		   : handle to WMI.
12025  *  @macaddr			   : vdev mad address
12026  *  @param param		   : pointer to tx antenna param
12027  *
12028  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
12029  */
12030 static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv(
12031 				wmi_unified_t wmi_handle,
12032 				uint8_t macaddr[IEEE80211_ADDR_LEN],
12033 				struct smart_ant_node_config_params *param)
12034 {
12035 	wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd;
12036 	wmi_buf_t buf;
12037 	uint8_t *buf_ptr;
12038 	int32_t len = 0, args_tlv_len;
12039 	int ret;
12040 	int i = 0;
12041 	A_UINT32 *node_config_args;
12042 
12043 	args_tlv_len = WMI_TLV_HDR_SIZE + param->args_count * sizeof(A_UINT32);
12044 	len = sizeof(*cmd) + args_tlv_len;
12045 
12046 	if ((param->args_count == 0)) {
12047 		WMI_LOGE("%s: Can't send a command with %d arguments\n",
12048 			  __func__, param->args_count);
12049 		return QDF_STATUS_E_FAILURE;
12050 	}
12051 
12052 	buf = wmi_buf_alloc(wmi_handle, len);
12053 	if (!buf) {
12054 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
12055 		return QDF_STATUS_E_NOMEM;
12056 	}
12057 
12058 	cmd = (wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *)
12059 						wmi_buf_data(buf);
12060 	buf_ptr = (uint8_t *)cmd;
12061 	WMITLV_SET_HDR(&cmd->tlv_header,
12062 	WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param,
12063 		WMITLV_GET_STRUCT_TLVLEN(
12064 		wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param));
12065 	cmd->vdev_id = param->vdev_id;
12066 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
12067 	cmd->cmd_id = param->cmd_id;
12068 	cmd->args_count = param->args_count;
12069 	buf_ptr += sizeof(
12070 		wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param);
12071 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
12072 			(cmd->args_count * sizeof(A_UINT32)));
12073 	buf_ptr += WMI_TLV_HDR_SIZE;
12074 	node_config_args = (A_UINT32 *)buf_ptr;
12075 
12076 	for (i = 0; i < param->args_count; i++) {
12077 		node_config_args[i] = param->args_arr[i];
12078 		WMI_LOGI("%d", param->args_arr[i]);
12079 	}
12080 
12081 	ret = wmi_unified_cmd_send(wmi_handle,
12082 			   buf,
12083 			   len,
12084 			   WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID);
12085 
12086 	if (ret != 0) {
12087 		WMI_LOGE("%s: WMI FAILED:Sent cmd_id: 0x%x\n Node: %02x:%02x:%02x:%02x:%02x:%02x cmdstatus=%d\n",
12088 			 __func__, param->cmd_id, macaddr[0],
12089 			 macaddr[1], macaddr[2], macaddr[3],
12090 			 macaddr[4], macaddr[5], ret);
12091 		wmi_buf_free(buf);
12092 	}
12093 
12094 	return ret;
12095 }
12096 
12097 /**
12098  * send_set_atf_cmd_tlv() - send set atf command to fw
12099  * @wmi_handle: wmi handle
12100  * @param: pointer to set atf param
12101  *
12102  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
12103  */
12104 static QDF_STATUS
12105 send_set_atf_cmd_tlv(wmi_unified_t wmi_handle,
12106 		     struct set_atf_params *param)
12107 {
12108 	wmi_atf_peer_info *peer_info;
12109 	wmi_peer_atf_request_fixed_param *cmd;
12110 	wmi_buf_t buf;
12111 	uint8_t *buf_ptr;
12112 	int i;
12113 	int32_t len = 0;
12114 	QDF_STATUS retval;
12115 
12116 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
12117 	len += param->num_peers * sizeof(wmi_atf_peer_info);
12118 	buf = wmi_buf_alloc(wmi_handle, len);
12119 	if (!buf) {
12120 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
12121 		return QDF_STATUS_E_FAILURE;
12122 	}
12123 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12124 	cmd = (wmi_peer_atf_request_fixed_param *)buf_ptr;
12125 	WMITLV_SET_HDR(&cmd->tlv_header,
12126 		       WMITLV_TAG_STRUC_wmi_peer_atf_request_fixed_param,
12127 		       WMITLV_GET_STRUCT_TLVLEN(
12128 				wmi_peer_atf_request_fixed_param));
12129 	cmd->num_peers = param->num_peers;
12130 
12131 	buf_ptr += sizeof(*cmd);
12132 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
12133 		       sizeof(wmi_atf_peer_info) *
12134 		       cmd->num_peers);
12135 	buf_ptr += WMI_TLV_HDR_SIZE;
12136 	peer_info = (wmi_atf_peer_info *)buf_ptr;
12137 
12138 	for (i = 0; i < cmd->num_peers; i++) {
12139 		WMITLV_SET_HDR(&peer_info->tlv_header,
12140 			    WMITLV_TAG_STRUC_wmi_atf_peer_info,
12141 			    WMITLV_GET_STRUCT_TLVLEN(
12142 				wmi_atf_peer_info));
12143 		qdf_mem_copy(&(peer_info->peer_macaddr),
12144 				&(param->peer_info[i].peer_macaddr),
12145 				sizeof(wmi_mac_addr));
12146 		peer_info->atf_units = param->peer_info[i].percentage_peer;
12147 		peer_info->vdev_id = param->peer_info[i].vdev_id;
12148 		peer_info->pdev_id =
12149 			wmi_handle->ops->convert_pdev_id_host_to_target(
12150 				param->peer_info[i].pdev_id);
12151 		/*
12152 		 * TLV definition for peer atf request fixed param combines
12153 		 * extension stats. Legacy FW for WIN (Non-TLV) has peer atf
12154 		 * stats and atf extension stats as two different
12155 		 * implementations.
12156 		 * Need to discuss with FW on this.
12157 		 *
12158 		 * peer_info->atf_groupid = param->peer_ext_info[i].group_index;
12159 		 * peer_info->atf_units_reserved =
12160 		 *		param->peer_ext_info[i].atf_index_reserved;
12161 		 */
12162 		peer_info++;
12163 	}
12164 
12165 	retval = wmi_unified_cmd_send(wmi_handle, buf, len,
12166 		WMI_PEER_ATF_REQUEST_CMDID);
12167 
12168 	if (retval != QDF_STATUS_SUCCESS) {
12169 		WMI_LOGE("%s : WMI Failed\n", __func__);
12170 		wmi_buf_free(buf);
12171 	}
12172 
12173 	return retval;
12174 }
12175 
12176 /**
12177  * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw
12178  * @wmi_handle: wmi handle
12179  * @param: pointer to hold fwtest param
12180  *
12181  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
12182  */
12183 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle,
12184 				struct set_fwtest_params *param)
12185 {
12186 	wmi_fwtest_set_param_cmd_fixed_param *cmd;
12187 	wmi_buf_t buf;
12188 	int32_t len = sizeof(*cmd);
12189 
12190 	buf = wmi_buf_alloc(wmi_handle, len);
12191 
12192 	if (!buf) {
12193 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
12194 		return QDF_STATUS_E_FAILURE;
12195 	}
12196 
12197 	cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf);
12198 	WMITLV_SET_HDR(&cmd->tlv_header,
12199 		       WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param,
12200 		       WMITLV_GET_STRUCT_TLVLEN(
12201 				wmi_fwtest_set_param_cmd_fixed_param));
12202 	cmd->param_id = param->arg;
12203 	cmd->param_value = param->value;
12204 
12205 	if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) {
12206 		WMI_LOGE("Setting FW test param failed\n");
12207 		wmi_buf_free(buf);
12208 		return QDF_STATUS_E_FAILURE;
12209 	}
12210 
12211 	return QDF_STATUS_SUCCESS;
12212 }
12213 
12214 /**
12215  * send_set_qboost_param_cmd_tlv() - send set qboost command to fw
12216  * @wmi_handle: wmi handle
12217  * @param: pointer to qboost params
12218  * @macaddr: vdev mac address
12219  *
12220  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
12221  */
12222 static QDF_STATUS
12223 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle,
12224 			      uint8_t macaddr[IEEE80211_ADDR_LEN],
12225 			      struct set_qboost_params *param)
12226 {
12227 	WMI_QBOOST_CFG_CMD_fixed_param *cmd;
12228 	wmi_buf_t buf;
12229 	int32_t len;
12230 	QDF_STATUS ret;
12231 
12232 	len = sizeof(*cmd);
12233 
12234 	buf = wmi_buf_alloc(wmi_handle, len);
12235 	if (!buf) {
12236 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12237 		return QDF_STATUS_E_FAILURE;
12238 	}
12239 
12240 	cmd = (WMI_QBOOST_CFG_CMD_fixed_param *)wmi_buf_data(buf);
12241 	WMITLV_SET_HDR(&cmd->tlv_header,
12242 		       WMITLV_TAG_STRUC_WMI_QBOOST_CFG_CMD_fixed_param,
12243 		       WMITLV_GET_STRUCT_TLVLEN(
12244 				WMI_QBOOST_CFG_CMD_fixed_param));
12245 	cmd->vdev_id = param->vdev_id;
12246 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
12247 	cmd->qb_enable = param->value;
12248 
12249 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
12250 			WMI_QBOOST_CFG_CMDID);
12251 
12252 	if (ret != 0) {
12253 		WMI_LOGE("Setting qboost cmd failed\n");
12254 		wmi_buf_free(buf);
12255 	}
12256 
12257 	return ret;
12258 }
12259 
12260 /**
12261  * send_gpio_config_cmd_tlv() - send gpio config to fw
12262  * @wmi_handle: wmi handle
12263  * @param: pointer to hold gpio config param
12264  *
12265  * Return: 0 for success or error code
12266  */
12267 static QDF_STATUS
12268 send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle,
12269 			 struct gpio_config_params *param)
12270 {
12271 	wmi_gpio_config_cmd_fixed_param *cmd;
12272 	wmi_buf_t buf;
12273 	int32_t len;
12274 	QDF_STATUS ret;
12275 
12276 	len = sizeof(*cmd);
12277 
12278 	/* Sanity Checks */
12279 	if (param->pull_type > WMI_GPIO_PULL_DOWN ||
12280 	    param->intr_mode > WMI_GPIO_INTTYPE_LEVEL_HIGH) {
12281 		return QDF_STATUS_E_FAILURE;
12282 	}
12283 
12284 	buf = wmi_buf_alloc(wmi_handle, len);
12285 	if (!buf) {
12286 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12287 		return QDF_STATUS_E_FAILURE;
12288 	}
12289 
12290 	cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf);
12291 	WMITLV_SET_HDR(&cmd->tlv_header,
12292 		       WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param,
12293 		       WMITLV_GET_STRUCT_TLVLEN(
12294 				wmi_gpio_config_cmd_fixed_param));
12295 	cmd->gpio_num = param->gpio_num;
12296 	cmd->input = param->input;
12297 	cmd->pull_type = param->pull_type;
12298 	cmd->intr_mode = param->intr_mode;
12299 
12300 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
12301 			WMI_GPIO_CONFIG_CMDID);
12302 
12303 	if (ret != 0) {
12304 		WMI_LOGE("Sending GPIO config cmd failed\n");
12305 		wmi_buf_free(buf);
12306 	}
12307 
12308 	return ret;
12309 }
12310 
12311 /**
12312  * send_gpio_output_cmd_tlv() - send gpio output to fw
12313  * @wmi_handle: wmi handle
12314  * @param: pointer to hold gpio output param
12315  *
12316  * Return: 0 for success or error code
12317  */
12318 static QDF_STATUS
12319 send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle,
12320 			 struct gpio_output_params *param)
12321 {
12322 	wmi_gpio_output_cmd_fixed_param *cmd;
12323 	wmi_buf_t buf;
12324 	int32_t len;
12325 	QDF_STATUS ret;
12326 
12327 	len = sizeof(*cmd);
12328 
12329 	buf = wmi_buf_alloc(wmi_handle, len);
12330 	if (!buf) {
12331 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12332 		return QDF_STATUS_E_FAILURE;
12333 	}
12334 
12335 	cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf);
12336 	WMITLV_SET_HDR(&cmd->tlv_header,
12337 		       WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param,
12338 		       WMITLV_GET_STRUCT_TLVLEN(
12339 				wmi_gpio_output_cmd_fixed_param));
12340 	cmd->gpio_num = param->gpio_num;
12341 	cmd->set = param->set;
12342 
12343 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
12344 			WMI_GPIO_OUTPUT_CMDID);
12345 
12346 	if (ret != 0) {
12347 		WMI_LOGE("Sending GPIO output cmd failed\n");
12348 		wmi_buf_free(buf);
12349 	}
12350 
12351 	return ret;
12352 
12353 }
12354 
12355 /**
12356  *  send_phyerr_disable_cmd_tlv() - WMI phyerr disable function
12357  *
12358  *  @param wmi_handle     : handle to WMI.
12359  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
12360  */
12361 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle)
12362 {
12363 	wmi_pdev_dfs_disable_cmd_fixed_param *cmd;
12364 	wmi_buf_t buf;
12365 	QDF_STATUS ret;
12366 	int32_t len;
12367 
12368 	len = sizeof(*cmd);
12369 
12370 	buf = wmi_buf_alloc(wmi_handle, len);
12371 	if (!buf) {
12372 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12373 		return QDF_STATUS_E_FAILURE;
12374 	}
12375 
12376 	cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf);
12377 	WMITLV_SET_HDR(&cmd->tlv_header,
12378 		       WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param,
12379 		       WMITLV_GET_STRUCT_TLVLEN(
12380 				wmi_pdev_dfs_disable_cmd_fixed_param));
12381 	/* Filling it with WMI_PDEV_ID_SOC for now */
12382 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
12383 							WMI_HOST_PDEV_ID_SOC);
12384 
12385 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
12386 			WMI_PDEV_DFS_DISABLE_CMDID);
12387 
12388 	if (ret != 0) {
12389 		WMI_LOGE("Sending PDEV DFS disable cmd failed\n");
12390 		wmi_buf_free(buf);
12391 	}
12392 
12393 	return ret;
12394 }
12395 
12396 /**
12397  *  send_phyerr_enable_cmd_tlv() - WMI phyerr disable function
12398  *
12399  *  @param wmi_handle     : handle to WMI.
12400  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
12401  */
12402 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle)
12403 {
12404 	wmi_pdev_dfs_enable_cmd_fixed_param *cmd;
12405 	wmi_buf_t buf;
12406 	QDF_STATUS ret;
12407 	int32_t len;
12408 
12409 	len = sizeof(*cmd);
12410 
12411 	buf = wmi_buf_alloc(wmi_handle, len);
12412 	if (!buf) {
12413 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12414 		return QDF_STATUS_E_FAILURE;
12415 	}
12416 
12417 	cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf);
12418 	WMITLV_SET_HDR(&cmd->tlv_header,
12419 		       WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param,
12420 		       WMITLV_GET_STRUCT_TLVLEN(
12421 				wmi_pdev_dfs_enable_cmd_fixed_param));
12422 	/* Reserved for future use */
12423 	cmd->reserved0 = 0;
12424 
12425 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
12426 			WMI_PDEV_DFS_ENABLE_CMDID);
12427 
12428 	if (ret != 0) {
12429 		WMI_LOGE("Sending PDEV DFS enable cmd failed\n");
12430 		wmi_buf_free(buf);
12431 	}
12432 
12433 	return ret;
12434 }
12435 
12436 /**
12437  * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd
12438  * to fw
12439  * @wmi_handle: wmi handle
12440  * @param: pointer to hold periodic chan stats param
12441  *
12442  * Return: 0 for success or error code
12443  */
12444 static QDF_STATUS
12445 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle,
12446 				struct periodic_chan_stats_params *param)
12447 {
12448 	wmi_set_periodic_channel_stats_config_fixed_param *cmd;
12449 	wmi_buf_t buf;
12450 	QDF_STATUS ret;
12451 	int32_t len;
12452 
12453 	len = sizeof(*cmd);
12454 
12455 	buf = wmi_buf_alloc(wmi_handle, len);
12456 	if (!buf) {
12457 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12458 		return QDF_STATUS_E_FAILURE;
12459 	}
12460 
12461 	cmd = (wmi_set_periodic_channel_stats_config_fixed_param *)
12462 					wmi_buf_data(buf);
12463 	WMITLV_SET_HDR(&cmd->tlv_header,
12464 	WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param,
12465 		WMITLV_GET_STRUCT_TLVLEN(
12466 		wmi_set_periodic_channel_stats_config_fixed_param));
12467 	cmd->enable = param->enable;
12468 	cmd->stats_period = param->stats_period;
12469 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
12470 						param->pdev_id);
12471 
12472 	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
12473 			WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID);
12474 
12475 	if (ret != 0) {
12476 		WMI_LOGE("Sending periodic chan stats config failed");
12477 		wmi_buf_free(buf);
12478 	}
12479 
12480 	return ret;
12481 }
12482 
12483 /**
12484  * send_nf_dbr_dbm_info_get_cmd_tlv() - send request to get nf to fw
12485  * @wmi_handle: wmi handle
12486  * @mac_id: radio context
12487  *
12488  * Return: 0 for success or error code
12489  */
12490 static QDF_STATUS
12491 send_nf_dbr_dbm_info_get_cmd_tlv(wmi_unified_t wmi_handle, uint8_t mac_id)
12492 {
12493 	wmi_buf_t buf;
12494 	QDF_STATUS ret;
12495 	wmi_pdev_get_nfcal_power_fixed_param *cmd;
12496 	int32_t len = sizeof(*cmd);
12497 
12498 	buf = wmi_buf_alloc(wmi_handle, len);
12499 	if (buf == NULL)
12500 		return QDF_STATUS_E_NOMEM;
12501 
12502 	cmd = (wmi_pdev_get_nfcal_power_fixed_param *)wmi_buf_data(buf);
12503 	WMITLV_SET_HDR(&cmd->tlv_header,
12504 		       WMITLV_TAG_STRUC_wmi_pdev_get_nfcal_power_fixed_param,
12505 		       WMITLV_GET_STRUCT_TLVLEN
12506 				(wmi_pdev_get_nfcal_power_fixed_param));
12507 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
12508 
12509 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12510 				   WMI_PDEV_GET_NFCAL_POWER_CMDID);
12511 	if (ret != 0) {
12512 		WMI_LOGE("Sending get nfcal power cmd failed\n");
12513 		wmi_buf_free(buf);
12514 	}
12515 
12516 	return ret;
12517 }
12518 
12519 /**
12520  * send_set_ht_ie_cmd_tlv() - send ht ie command to fw
12521  * @wmi_handle: wmi handle
12522  * @param: pointer to ht ie param
12523  *
12524  * Return: 0 for success or error code
12525  */
12526 static QDF_STATUS
12527 send_set_ht_ie_cmd_tlv(wmi_unified_t wmi_handle,
12528 		       struct ht_ie_params *param)
12529 {
12530 	wmi_pdev_set_ht_ie_cmd_fixed_param *cmd;
12531 	wmi_buf_t buf;
12532 	QDF_STATUS ret;
12533 	int32_t len;
12534 	uint8_t *buf_ptr;
12535 
12536 	len = sizeof(*cmd)  + WMI_TLV_HDR_SIZE +
12537 	      roundup(param->ie_len, sizeof(uint32_t));
12538 
12539 	buf = wmi_buf_alloc(wmi_handle, len);
12540 	if (!buf) {
12541 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12542 		return QDF_STATUS_E_FAILURE;
12543 	}
12544 
12545 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12546 	cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *)buf_ptr;
12547 	WMITLV_SET_HDR(&cmd->tlv_header,
12548 		       WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param,
12549 		       WMITLV_GET_STRUCT_TLVLEN(
12550 				wmi_pdev_set_ht_ie_cmd_fixed_param));
12551 	cmd->reserved0 = 0;
12552 	cmd->ie_len = param->ie_len;
12553 	cmd->tx_streams = param->tx_streams;
12554 	cmd->rx_streams = param->rx_streams;
12555 
12556 	buf_ptr += sizeof(*cmd);
12557 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len);
12558 	buf_ptr += WMI_TLV_HDR_SIZE;
12559 	if (param->ie_len)
12560 		WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data,
12561 						cmd->ie_len);
12562 
12563 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12564 				   WMI_PDEV_SET_HT_CAP_IE_CMDID);
12565 
12566 	if (ret != 0) {
12567 		WMI_LOGE("Sending set ht ie cmd failed\n");
12568 		wmi_buf_free(buf);
12569 	}
12570 
12571 	return ret;
12572 }
12573 
12574 /**
12575  * send_set_vht_ie_cmd_tlv() - send vht ie command to fw
12576  * @wmi_handle: wmi handle
12577  * @param: pointer to vht ie param
12578  *
12579  * Return: 0 for success or error code
12580  */
12581 static QDF_STATUS
12582 send_set_vht_ie_cmd_tlv(wmi_unified_t wmi_handle,
12583 			struct vht_ie_params *param)
12584 {
12585 	wmi_pdev_set_vht_ie_cmd_fixed_param *cmd;
12586 	wmi_buf_t buf;
12587 	QDF_STATUS ret;
12588 	int32_t len;
12589 	uint8_t *buf_ptr;
12590 
12591 	len = sizeof(*cmd)  + WMI_TLV_HDR_SIZE +
12592 	      roundup(param->ie_len, sizeof(uint32_t));
12593 
12594 	buf = wmi_buf_alloc(wmi_handle, len);
12595 	if (!buf) {
12596 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12597 		return QDF_STATUS_E_FAILURE;
12598 	}
12599 
12600 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12601 	cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *)buf_ptr;
12602 	WMITLV_SET_HDR(&cmd->tlv_header,
12603 		       WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param,
12604 		       WMITLV_GET_STRUCT_TLVLEN(
12605 				wmi_pdev_set_vht_ie_cmd_fixed_param));
12606 	cmd->reserved0 = 0;
12607 	cmd->ie_len = param->ie_len;
12608 	cmd->tx_streams = param->tx_streams;
12609 	cmd->rx_streams = param->rx_streams;
12610 
12611 	buf_ptr += sizeof(*cmd);
12612 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len);
12613 	buf_ptr += WMI_TLV_HDR_SIZE;
12614 	if (param->ie_len)
12615 		WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data,
12616 						cmd->ie_len);
12617 
12618 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12619 				   WMI_PDEV_SET_VHT_CAP_IE_CMDID);
12620 
12621 	if (ret != 0) {
12622 		WMI_LOGE("Sending set vht ie cmd failed\n");
12623 		wmi_buf_free(buf);
12624 	}
12625 
12626 	return ret;
12627 }
12628 
12629 /**
12630  * send_set_quiet_mode_cmd_tlv() - send set quiet mode command to fw
12631  * @wmi_handle: wmi handle
12632  * @param: pointer to quiet mode params
12633  *
12634  * Return: 0 for success or error code
12635  */
12636 static QDF_STATUS
12637 send_set_quiet_mode_cmd_tlv(wmi_unified_t wmi_handle,
12638 			    struct set_quiet_mode_params *param)
12639 {
12640 	wmi_pdev_set_quiet_cmd_fixed_param *quiet_cmd;
12641 	wmi_buf_t buf;
12642 	QDF_STATUS ret;
12643 	int32_t len;
12644 
12645 	len = sizeof(*quiet_cmd);
12646 	buf = wmi_buf_alloc(wmi_handle, len);
12647 	if (!buf) {
12648 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12649 		return QDF_STATUS_E_FAILURE;
12650 	}
12651 
12652 	quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf);
12653 	WMITLV_SET_HDR(&quiet_cmd->tlv_header,
12654 		       WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param,
12655 		       WMITLV_GET_STRUCT_TLVLEN(
12656 				wmi_pdev_set_quiet_cmd_fixed_param));
12657 	quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf);
12658 	quiet_cmd->enabled = param->enabled;
12659 	quiet_cmd->period = (param->period)*(param->intval);
12660 	quiet_cmd->duration = param->duration;
12661 	quiet_cmd->next_start = param->offset;
12662 	quiet_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
12663 							WMI_HOST_PDEV_ID_SOC);
12664 
12665 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12666 				   WMI_PDEV_SET_QUIET_MODE_CMDID);
12667 
12668 	if (ret != 0) {
12669 		WMI_LOGE("Sending set quiet cmd failed\n");
12670 		wmi_buf_free(buf);
12671 	}
12672 
12673 	return ret;
12674 }
12675 
12676 /**
12677  * send_set_bwf_cmd_tlv() - send set bwf command to fw
12678  * @wmi_handle: wmi handle
12679  * @param: pointer to set bwf param
12680  *
12681  * Return: 0 for success or error code
12682  */
12683 static QDF_STATUS
12684 send_set_bwf_cmd_tlv(wmi_unified_t wmi_handle,
12685 		     struct set_bwf_params *param)
12686 {
12687 	wmi_bwf_peer_info *peer_info;
12688 	wmi_peer_bwf_request_fixed_param *cmd;
12689 	wmi_buf_t buf;
12690 	QDF_STATUS retval;
12691 	int32_t len;
12692 	uint8_t *buf_ptr;
12693 	int i;
12694 
12695 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
12696 	len += param->num_peers * sizeof(wmi_bwf_peer_info);
12697 	buf = wmi_buf_alloc(wmi_handle, len);
12698 	if (!buf) {
12699 		WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
12700 		return QDF_STATUS_E_FAILURE;
12701 	}
12702 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
12703 	cmd = (wmi_peer_bwf_request_fixed_param *)buf_ptr;
12704 	WMITLV_SET_HDR(&cmd->tlv_header,
12705 		       WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param,
12706 		       WMITLV_GET_STRUCT_TLVLEN(
12707 				wmi_peer_bwf_request_fixed_param));
12708 	cmd->num_peers = param->num_peers;
12709 
12710 	buf_ptr += sizeof(*cmd);
12711 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
12712 		       sizeof(wmi_bwf_peer_info) *
12713 		       cmd->num_peers);
12714 	buf_ptr += WMI_TLV_HDR_SIZE;
12715 	peer_info = (wmi_bwf_peer_info *)buf_ptr;
12716 
12717 	for (i = 0; i < cmd->num_peers; i++) {
12718 		WMITLV_SET_HDR(&peer_info->tlv_header,
12719 			       WMITLV_TAG_STRUC_wmi_bwf_peer_info,
12720 			       WMITLV_GET_STRUCT_TLVLEN(wmi_bwf_peer_info));
12721 		peer_info->bwf_guaranteed_bandwidth =
12722 				param->peer_info[i].throughput;
12723 		peer_info->bwf_max_airtime =
12724 				param->peer_info[i].max_airtime;
12725 		peer_info->bwf_peer_priority =
12726 				param->peer_info[i].priority;
12727 		qdf_mem_copy(&peer_info->peer_macaddr,
12728 			     &param->peer_info[i].peer_macaddr,
12729 			     sizeof(param->peer_info[i].peer_macaddr));
12730 		peer_info->vdev_id =
12731 				param->peer_info[i].vdev_id;
12732 		peer_info->pdev_id =
12733 			wmi_handle->ops->convert_pdev_id_host_to_target(
12734 				param->peer_info[i].pdev_id);
12735 		peer_info++;
12736 	}
12737 
12738 	retval = wmi_unified_cmd_send(wmi_handle, buf, len,
12739 				      WMI_PEER_BWF_REQUEST_CMDID);
12740 
12741 	if (retval != QDF_STATUS_SUCCESS) {
12742 		WMI_LOGE("%s : WMI Failed\n", __func__);
12743 		wmi_buf_free(buf);
12744 	}
12745 
12746 	return retval;
12747 }
12748 
12749 /**
12750  * send_mcast_group_update_cmd_tlv() - send mcast group update cmd to fw
12751  * @wmi_handle: wmi handle
12752  * @param: pointer to hold mcast update param
12753  *
12754  * Return: 0 for success or error code
12755  */
12756 static QDF_STATUS
12757 send_mcast_group_update_cmd_tlv(wmi_unified_t wmi_handle,
12758 				struct mcast_group_update_params *param)
12759 {
12760 	wmi_peer_mcast_group_cmd_fixed_param *cmd;
12761 	wmi_buf_t buf;
12762 	QDF_STATUS ret;
12763 	int32_t len;
12764 	int offset = 0;
12765 	static char dummymask[4] = { 0xFF, 0xFF, 0xFF, 0xFF};
12766 
12767 	len = sizeof(*cmd);
12768 	buf = wmi_buf_alloc(wmi_handle, len);
12769 	if (!buf) {
12770 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12771 		return QDF_STATUS_E_FAILURE;
12772 	}
12773 	cmd = (wmi_peer_mcast_group_cmd_fixed_param *)wmi_buf_data(buf);
12774 	WMITLV_SET_HDR(&cmd->tlv_header,
12775 		       WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param,
12776 		       WMITLV_GET_STRUCT_TLVLEN(
12777 				wmi_peer_mcast_group_cmd_fixed_param));
12778 	/* confirm the buffer is 4-byte aligned */
12779 	QDF_ASSERT((((size_t) cmd) & 0x3) == 0);
12780 	qdf_mem_zero(cmd, sizeof(*cmd));
12781 
12782 	cmd->vdev_id = param->vap_id;
12783 	/* construct the message assuming our endianness matches the target */
12784 	cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_ACTION_M &
12785 		(param->action << WMI_PEER_MCAST_GROUP_FLAG_ACTION_S);
12786 	cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M &
12787 		(param->wildcard << WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S);
12788 	if (param->is_action_delete)
12789 		cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_DELETEALL_M;
12790 
12791 	if (param->is_mcast_addr_len)
12792 		cmd->flags |=  WMI_PEER_MCAST_GROUP_FLAG_IPV6_M;
12793 
12794 	if (param->is_filter_mode_snoop)
12795 		cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_SRC_FILTER_EXCLUDE_M;
12796 
12797 	/* unicast address spec only applies for non-wildcard cases */
12798 	if (!param->wildcard && param->ucast_mac_addr) {
12799 		WMI_CHAR_ARRAY_TO_MAC_ADDR(param->ucast_mac_addr,
12800 					   &cmd->ucast_mac_addr);
12801 	}
12802 
12803 	if (param->mcast_ip_addr) {
12804 		QDF_ASSERT(param->mcast_ip_addr_bytes <=
12805 			   sizeof(cmd->mcast_ip_addr));
12806 		offset = sizeof(cmd->mcast_ip_addr) -
12807 			 param->mcast_ip_addr_bytes;
12808 		qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_addr) + offset,
12809 			     param->mcast_ip_addr,
12810 			     param->mcast_ip_addr_bytes);
12811 	}
12812 	if (!param->mask)
12813 		param->mask = &dummymask[0];
12814 
12815 	qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_mask) + offset,
12816 		     param->mask,
12817 		     param->mcast_ip_addr_bytes);
12818 
12819 	if (param->srcs && param->nsrcs) {
12820 		cmd->num_filter_addr = param->nsrcs;
12821 		QDF_ASSERT((param->nsrcs * param->mcast_ip_addr_bytes) <=
12822 			sizeof(cmd->filter_addr));
12823 
12824 		qdf_mem_copy(((uint8_t *) &cmd->filter_addr), param->srcs,
12825 			     param->nsrcs * param->mcast_ip_addr_bytes);
12826 	}
12827 
12828 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12829 				      WMI_PEER_MCAST_GROUP_CMDID);
12830 
12831 	if (ret != QDF_STATUS_SUCCESS) {
12832 		WMI_LOGE("%s : WMI Failed\n", __func__);
12833 		wmi_buf_free(buf);
12834 	}
12835 
12836 	return ret;
12837 }
12838 
12839 /**
12840  * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure
12841  * command to fw
12842  * @wmi_handle: wmi handle
12843  * @param: pointer to hold spectral config parameter
12844  *
12845  * Return: 0 for success or error code
12846  */
12847 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle,
12848 				struct vdev_spectral_configure_params *param)
12849 {
12850 	wmi_vdev_spectral_configure_cmd_fixed_param *cmd;
12851 	wmi_buf_t buf;
12852 	QDF_STATUS ret;
12853 	int32_t len;
12854 
12855 	len = sizeof(*cmd);
12856 	buf = wmi_buf_alloc(wmi_handle, len);
12857 	if (!buf) {
12858 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12859 		return QDF_STATUS_E_FAILURE;
12860 	}
12861 
12862 	cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf);
12863 	WMITLV_SET_HDR(&cmd->tlv_header,
12864 		WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param,
12865 		WMITLV_GET_STRUCT_TLVLEN(
12866 		wmi_vdev_spectral_configure_cmd_fixed_param));
12867 
12868 	cmd->vdev_id = param->vdev_id;
12869 	cmd->spectral_scan_count = param->count;
12870 	cmd->spectral_scan_period = param->period;
12871 	cmd->spectral_scan_priority = param->spectral_pri;
12872 	cmd->spectral_scan_fft_size = param->fft_size;
12873 	cmd->spectral_scan_gc_ena = param->gc_enable;
12874 	cmd->spectral_scan_restart_ena = param->restart_enable;
12875 	cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref;
12876 	cmd->spectral_scan_init_delay = param->init_delay;
12877 	cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr;
12878 	cmd->spectral_scan_str_bin_thr = param->str_bin_thr;
12879 	cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode;
12880 	cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode;
12881 	cmd->spectral_scan_rssi_thr = param->rssi_thr;
12882 	cmd->spectral_scan_pwr_format = param->pwr_format;
12883 	cmd->spectral_scan_rpt_mode = param->rpt_mode;
12884 	cmd->spectral_scan_bin_scale = param->bin_scale;
12885 	cmd->spectral_scan_dBm_adj = param->dbm_adj;
12886 	cmd->spectral_scan_chn_mask = param->chn_mask;
12887 
12888 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12889 				   WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID);
12890 
12891 	if (ret != 0) {
12892 		WMI_LOGE("Sending set quiet cmd failed\n");
12893 		wmi_buf_free(buf);
12894 	}
12895 
12896 	WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID\n",
12897 		 __func__);
12898 
12899 	WMI_LOGI("vdev_id = %u\n"
12900 		 "spectral_scan_count = %u\n"
12901 		 "spectral_scan_period = %u\n"
12902 		 "spectral_scan_priority = %u\n"
12903 		 "spectral_scan_fft_size = %u\n"
12904 		 "spectral_scan_gc_ena = %u\n"
12905 		 "spectral_scan_restart_ena = %u\n"
12906 		 "spectral_scan_noise_floor_ref = %u\n"
12907 		 "spectral_scan_init_delay = %u\n"
12908 		 "spectral_scan_nb_tone_thr = %u\n"
12909 		 "spectral_scan_str_bin_thr = %u\n"
12910 		 "spectral_scan_wb_rpt_mode = %u\n"
12911 		 "spectral_scan_rssi_rpt_mode = %u\n"
12912 		 "spectral_scan_rssi_thr = %u\n"
12913 		 "spectral_scan_pwr_format = %u\n"
12914 		 "spectral_scan_rpt_mode = %u\n"
12915 		 "spectral_scan_bin_scale = %u\n"
12916 		 "spectral_scan_dBm_adj = %u\n"
12917 		 "spectral_scan_chn_mask = %u\n",
12918 		 param->vdev_id,
12919 		 param->count,
12920 		 param->period,
12921 		 param->spectral_pri,
12922 		 param->fft_size,
12923 		 param->gc_enable,
12924 		 param->restart_enable,
12925 		 param->noise_floor_ref,
12926 		 param->init_delay,
12927 		 param->nb_tone_thr,
12928 		 param->str_bin_thr,
12929 		 param->wb_rpt_mode,
12930 		 param->rssi_rpt_mode,
12931 		 param->rssi_thr,
12932 		 param->pwr_format,
12933 		 param->rpt_mode,
12934 		 param->bin_scale,
12935 		 param->dbm_adj,
12936 		 param->chn_mask);
12937 	WMI_LOGI("%s: Status: %d\n\n", __func__, ret);
12938 
12939 	return ret;
12940 }
12941 
12942 /**
12943  * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure
12944  * command to fw
12945  * @wmi_handle: wmi handle
12946  * @param: pointer to hold spectral enable parameter
12947  *
12948  * Return: 0 for success or error code
12949  */
12950 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle,
12951 				struct vdev_spectral_enable_params *param)
12952 {
12953 	wmi_vdev_spectral_enable_cmd_fixed_param *cmd;
12954 	wmi_buf_t buf;
12955 	QDF_STATUS ret;
12956 	int32_t len;
12957 
12958 	len = sizeof(*cmd);
12959 	buf = wmi_buf_alloc(wmi_handle, len);
12960 	if (!buf) {
12961 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
12962 		return QDF_STATUS_E_FAILURE;
12963 	}
12964 
12965 	cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf);
12966 	WMITLV_SET_HDR(&cmd->tlv_header,
12967 		WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param,
12968 		WMITLV_GET_STRUCT_TLVLEN(
12969 		wmi_vdev_spectral_enable_cmd_fixed_param));
12970 
12971 	cmd->vdev_id = param->vdev_id;
12972 
12973 	if (param->active_valid) {
12974 		cmd->trigger_cmd = param->active ? 1 : 2;
12975 		/* 1: Trigger, 2: Clear Trigger */
12976 	} else {
12977 		cmd->trigger_cmd = 0; /* 0: Ignore */
12978 	}
12979 
12980 	if (param->enabled_valid) {
12981 		cmd->enable_cmd = param->enabled ? 1 : 2;
12982 		/* 1: Enable 2: Disable */
12983 	} else {
12984 		cmd->enable_cmd = 0; /* 0: Ignore */
12985 	}
12986 
12987 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
12988 				   WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID);
12989 
12990 	if (ret != 0) {
12991 		WMI_LOGE("Sending scan enable CMD failed\n");
12992 		wmi_buf_free(buf);
12993 	}
12994 
12995 	WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID\n", __func__);
12996 
12997 	WMI_LOGI("vdev_id = %u\n"
12998 				 "trigger_cmd = %u\n"
12999 				 "enable_cmd = %u\n",
13000 				 cmd->vdev_id,
13001 				 cmd->trigger_cmd,
13002 				 cmd->enable_cmd);
13003 
13004 	WMI_LOGI("%s: Status: %d\n\n", __func__, ret);
13005 
13006 	return ret;
13007 }
13008 
13009 /**
13010  * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params
13011  * @param wmi_handle : handle to WMI.
13012  * @param param : pointer to hold thermal mitigation param
13013  *
13014  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
13015  */
13016 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv(
13017 		wmi_unified_t wmi_handle,
13018 		struct thermal_mitigation_params *param)
13019 {
13020 	wmi_therm_throt_config_request_fixed_param *tt_conf = NULL;
13021 	wmi_therm_throt_level_config_info *lvl_conf = NULL;
13022 	wmi_buf_t buf = NULL;
13023 	uint8_t *buf_ptr = NULL;
13024 	int error;
13025 	int32_t len;
13026 	int i;
13027 
13028 	len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE +
13029 			THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info);
13030 
13031 	buf = wmi_buf_alloc(wmi_handle, len);
13032 	if (!buf) {
13033 		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
13034 		return QDF_STATUS_E_NOMEM;
13035 	}
13036 	tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf);
13037 
13038 	/* init fixed params */
13039 	WMITLV_SET_HDR(tt_conf,
13040 		WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param,
13041 		(WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param)));
13042 
13043 	tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13044 								param->pdev_id);
13045 	tt_conf->enable = param->enable;
13046 	tt_conf->dc = param->dc;
13047 	tt_conf->dc_per_event = param->dc_per_event;
13048 	tt_conf->therm_throt_levels = THERMAL_LEVELS;
13049 
13050 	buf_ptr = (uint8_t *) ++tt_conf;
13051 	/* init TLV params */
13052 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
13053 			(THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info)));
13054 
13055 	lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr +  WMI_TLV_HDR_SIZE);
13056 	for (i = 0; i < THERMAL_LEVELS; i++) {
13057 		WMITLV_SET_HDR(&lvl_conf->tlv_header,
13058 			WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info,
13059 			WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info));
13060 		lvl_conf->temp_lwm = param->levelconf[i].tmplwm;
13061 		lvl_conf->temp_hwm = param->levelconf[i].tmphwm;
13062 		lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent;
13063 		lvl_conf->prio = param->levelconf[i].priority;
13064 		lvl_conf++;
13065 	}
13066 
13067 	error = wmi_unified_cmd_send(wmi_handle, buf, len,
13068 			WMI_THERM_THROT_SET_CONF_CMDID);
13069 	if (QDF_IS_STATUS_ERROR(error)) {
13070 		wmi_buf_free(buf);
13071 		WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command");
13072 	}
13073 
13074 	return error;
13075 }
13076 
13077 /**
13078  * send_pdev_qvit_cmd_tlv() - send qvit command to fw
13079  * @wmi_handle: wmi handle
13080  * @param: pointer to pdev_qvit_params
13081  *
13082  * Return: 0 for success or error code
13083  */
13084 static QDF_STATUS
13085 send_pdev_qvit_cmd_tlv(wmi_unified_t wmi_handle,
13086 		       struct pdev_qvit_params *param)
13087 {
13088 	wmi_buf_t buf;
13089 	QDF_STATUS ret = QDF_STATUS_E_INVAL;
13090 	uint8_t *cmd;
13091 	static uint8_t msgref = 1;
13092 	uint8_t segnumber = 0, seginfo, numsegments;
13093 	uint16_t chunk_len, total_bytes;
13094 	uint8_t *bufpos;
13095 	QVIT_SEG_HDR_INFO_STRUCT seghdrinfo;
13096 
13097 	bufpos = param->utf_payload;
13098 	total_bytes = param->len;
13099 	ASSERT(total_bytes / MAX_WMI_QVIT_LEN ==
13100 	       (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN));
13101 	numsegments = (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN);
13102 
13103 	if (param->len - (numsegments * MAX_WMI_QVIT_LEN))
13104 		numsegments++;
13105 
13106 	while (param->len) {
13107 		if (param->len > MAX_WMI_QVIT_LEN)
13108 			chunk_len = MAX_WMI_QVIT_LEN;    /* MAX messsage */
13109 		else
13110 			chunk_len = param->len;
13111 
13112 		buf = wmi_buf_alloc(wmi_handle,
13113 				    (chunk_len + sizeof(seghdrinfo) +
13114 				     WMI_TLV_HDR_SIZE));
13115 		if (!buf) {
13116 			WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
13117 			return QDF_STATUS_E_NOMEM;
13118 		}
13119 
13120 		cmd = (uint8_t *) wmi_buf_data(buf);
13121 
13122 		seghdrinfo.len = total_bytes;
13123 		seghdrinfo.msgref = msgref;
13124 		seginfo = ((numsegments << 4) & 0xF0) | (segnumber & 0xF);
13125 		seghdrinfo.segmentInfo = seginfo;
13126 
13127 		segnumber++;
13128 
13129 		WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE,
13130 			       (chunk_len + sizeof(seghdrinfo)));
13131 		cmd += WMI_TLV_HDR_SIZE;
13132 		qdf_mem_copy(cmd, &seghdrinfo, sizeof(seghdrinfo));
13133 		qdf_mem_copy(&cmd[sizeof(seghdrinfo)], bufpos, chunk_len);
13134 
13135 		ret = wmi_unified_cmd_send(wmi_handle, buf,
13136 					   (chunk_len + sizeof(seghdrinfo) +
13137 					    WMI_TLV_HDR_SIZE),
13138 					   WMI_PDEV_QVIT_CMDID);
13139 
13140 		if (ret != 0) {
13141 			WMI_LOGE("Failed to send WMI_PDEV_QVIT_CMDID command");
13142 			wmi_buf_free(buf);
13143 			break;
13144 		}
13145 
13146 		param->len -= chunk_len;
13147 		bufpos += chunk_len;
13148 	}
13149 	msgref++;
13150 
13151 	return ret;
13152 }
13153 
13154 /**
13155  * send_wmm_update_cmd_tlv() - send wmm update command to fw
13156  * @wmi_handle: wmi handle
13157  * @param: pointer to wmm update param
13158  *
13159  * Return: 0 for success or error code
13160  */
13161 static QDF_STATUS
13162 send_wmm_update_cmd_tlv(wmi_unified_t wmi_handle,
13163 			struct wmm_update_params *param)
13164 {
13165 	wmi_pdev_set_wmm_params_cmd_fixed_param *cmd;
13166 	wmi_wmm_params *wmm_param;
13167 	wmi_buf_t buf;
13168 	QDF_STATUS ret;
13169 	int32_t len;
13170 	int ac = 0;
13171 	struct wmi_host_wmeParams *wmep;
13172 	uint8_t *buf_ptr;
13173 
13174 	len = sizeof(*cmd) + (WME_NUM_AC * sizeof(*wmm_param));
13175 	buf = wmi_buf_alloc(wmi_handle, len);
13176 	if (!buf) {
13177 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
13178 		return QDF_STATUS_E_FAILURE;
13179 	}
13180 
13181 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
13182 	cmd = (wmi_pdev_set_wmm_params_cmd_fixed_param *) buf_ptr;
13183 	WMITLV_SET_HDR(&cmd->tlv_header,
13184 		       WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param,
13185 		       WMITLV_GET_STRUCT_TLVLEN
13186 			       (wmi_pdev_set_wmm_params_cmd_fixed_param));
13187 
13188 	cmd->reserved0 = WMI_HOST_PDEV_ID_SOC;
13189 
13190 	buf_ptr += sizeof(wmi_pdev_set_wmm_params_cmd_fixed_param);
13191 
13192 	for (ac = 0; ac < WME_NUM_AC; ac++) {
13193 		wmep = &param->wmep_array[ac];
13194 		wmm_param = (wmi_wmm_params *)buf_ptr;
13195 		WMITLV_SET_HDR(&wmm_param->tlv_header,
13196 			WMITLV_TAG_STRUC_wmi_wmm_params,
13197 			WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params));
13198 		wmm_param->aifs = wmep->wmep_aifsn;
13199 		wmm_param->cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
13200 		wmm_param->cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
13201 		wmm_param->txoplimit = ATH_TXOP_TO_US(wmep->wmep_txopLimit);
13202 		wmm_param->acm = wmep->wmep_acm;
13203 		wmm_param->no_ack = wmep->wmep_noackPolicy;
13204 		buf_ptr += sizeof(wmi_wmm_params);
13205 	}
13206 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
13207 				   WMI_PDEV_SET_WMM_PARAMS_CMDID);
13208 
13209 	if (ret != 0) {
13210 		WMI_LOGE("Sending WMM update CMD failed\n");
13211 		wmi_buf_free(buf);
13212 	}
13213 
13214 	return ret;
13215 }
13216 
13217 /**
13218  * send_coex_config_cmd_tlv() - send coex config command to fw
13219  * @wmi_handle: wmi handle
13220  * @param: pointer to coex config param
13221  *
13222  * Return: 0 for success or error code
13223  */
13224 static QDF_STATUS
13225 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle,
13226 			 struct coex_config_params *param)
13227 {
13228 	WMI_COEX_CONFIG_CMD_fixed_param *cmd;
13229 	wmi_buf_t buf;
13230 	QDF_STATUS ret;
13231 	int32_t len;
13232 
13233 	len = sizeof(*cmd);
13234 	buf = wmi_buf_alloc(wmi_handle, len);
13235 	if (!buf) {
13236 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
13237 		return QDF_STATUS_E_FAILURE;
13238 	}
13239 
13240 	cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf);
13241 	WMITLV_SET_HDR(&cmd->tlv_header,
13242 		       WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param,
13243 		       WMITLV_GET_STRUCT_TLVLEN(
13244 		       WMI_COEX_CONFIG_CMD_fixed_param));
13245 
13246 	cmd->vdev_id = param->vdev_id;
13247 	cmd->config_type = param->config_type;
13248 	cmd->config_arg1 = param->config_arg1;
13249 	cmd->config_arg2 = param->config_arg2;
13250 	cmd->config_arg3 = param->config_arg3;
13251 	cmd->config_arg4 = param->config_arg4;
13252 	cmd->config_arg5 = param->config_arg5;
13253 	cmd->config_arg6 = param->config_arg6;
13254 
13255 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
13256 				   WMI_COEX_CONFIG_CMDID);
13257 
13258 	if (ret != 0) {
13259 		WMI_LOGE("Sending COEX CONFIG CMD failed\n");
13260 		wmi_buf_free(buf);
13261 	}
13262 
13263 	return ret;
13264 }
13265 
13266 static
13267 void wmi_copy_resource_config(wmi_resource_config *resource_cfg,
13268 				target_resource_config *tgt_res_cfg)
13269 {
13270 	resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs;
13271 	resource_cfg->num_peers = tgt_res_cfg->num_peers;
13272 	resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers;
13273 	resource_cfg->num_offload_reorder_buffs =
13274 			tgt_res_cfg->num_offload_reorder_buffs;
13275 	resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys;
13276 	resource_cfg->num_tids = tgt_res_cfg->num_tids;
13277 	resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit;
13278 	resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask;
13279 	resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask;
13280 	resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0];
13281 	resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1];
13282 	resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2];
13283 	resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3];
13284 	resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode;
13285 	resource_cfg->scan_max_pending_req =
13286 			tgt_res_cfg->scan_max_pending_req;
13287 	resource_cfg->bmiss_offload_max_vdev =
13288 			tgt_res_cfg->bmiss_offload_max_vdev;
13289 	resource_cfg->roam_offload_max_vdev =
13290 			tgt_res_cfg->roam_offload_max_vdev;
13291 	resource_cfg->roam_offload_max_ap_profiles =
13292 			tgt_res_cfg->roam_offload_max_ap_profiles;
13293 	resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups;
13294 	resource_cfg->num_mcast_table_elems =
13295 			tgt_res_cfg->num_mcast_table_elems;
13296 	resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode;
13297 	resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size;
13298 	resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries;
13299 	resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size;
13300 	resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim;
13301 	resource_cfg->rx_skip_defrag_timeout_dup_detection_check =
13302 		tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check;
13303 	resource_cfg->vow_config = tgt_res_cfg->vow_config;
13304 	resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev;
13305 	resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc;
13306 	resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries;
13307 	resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs;
13308 	resource_cfg->num_tdls_conn_table_entries =
13309 			tgt_res_cfg->num_tdls_conn_table_entries;
13310 	resource_cfg->beacon_tx_offload_max_vdev =
13311 			tgt_res_cfg->beacon_tx_offload_max_vdev;
13312 	resource_cfg->num_multicast_filter_entries =
13313 			tgt_res_cfg->num_multicast_filter_entries;
13314 	resource_cfg->num_wow_filters =
13315 			tgt_res_cfg->num_wow_filters;
13316 	resource_cfg->num_keep_alive_pattern =
13317 			tgt_res_cfg->num_keep_alive_pattern;
13318 	resource_cfg->keep_alive_pattern_size =
13319 			tgt_res_cfg->keep_alive_pattern_size;
13320 	resource_cfg->max_tdls_concurrent_sleep_sta =
13321 			tgt_res_cfg->max_tdls_concurrent_sleep_sta;
13322 	resource_cfg->max_tdls_concurrent_buffer_sta =
13323 			tgt_res_cfg->max_tdls_concurrent_buffer_sta;
13324 	resource_cfg->wmi_send_separate =
13325 			tgt_res_cfg->wmi_send_separate;
13326 	resource_cfg->num_ocb_vdevs =
13327 			tgt_res_cfg->num_ocb_vdevs;
13328 	resource_cfg->num_ocb_channels =
13329 			tgt_res_cfg->num_ocb_channels;
13330 	resource_cfg->num_ocb_schedules =
13331 			tgt_res_cfg->num_ocb_schedules;
13332 	resource_cfg->bpf_instruction_size = tgt_res_cfg->bpf_instruction_size;
13333 	resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters;
13334 	resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id;
13335 	resource_cfg->max_num_dbs_scan_duty_cycle =
13336 		tgt_res_cfg->max_num_dbs_scan_duty_cycle;
13337 	resource_cfg->sched_params = tgt_res_cfg->scheduler_params;
13338 
13339 	if (tgt_res_cfg->atf_config)
13340 		WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1);
13341 	if (tgt_res_cfg->mgmt_comp_evt_bundle_support)
13342 		WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET(
13343 			resource_cfg->flag1, 1);
13344 	if (tgt_res_cfg->tx_msdu_new_partition_id_support)
13345 		WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET(
13346 			resource_cfg->flag1, 1);
13347 	if (tgt_res_cfg->cce_disable)
13348 		WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1);
13349 }
13350 
13351 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd
13352  * @wmi_handle: pointer to wmi handle
13353  * @buf_ptr: pointer to current position in init command buffer
13354  * @len: pointer to length. This will be updated with current lenght of cmd
13355  * @param: point host parameters for init command
13356  *
13357  * Return: Updated pointer of buf_ptr.
13358  */
13359 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle,
13360 		uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param)
13361 {
13362 	uint16_t idx;
13363 
13364 	if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) {
13365 		wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode;
13366 		wmi_pdev_band_to_mac *band_to_mac;
13367 
13368 		hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *)
13369 			(buf_ptr + sizeof(wmi_init_cmd_fixed_param) +
13370 			 sizeof(wmi_resource_config) +
13371 			 WMI_TLV_HDR_SIZE + (param->num_mem_chunks *
13372 				 sizeof(wlan_host_memory_chunk)));
13373 
13374 		WMITLV_SET_HDR(&hw_mode->tlv_header,
13375 			WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param,
13376 			(WMITLV_GET_STRUCT_TLVLEN
13377 			 (wmi_pdev_set_hw_mode_cmd_fixed_param)));
13378 
13379 		hw_mode->hw_mode_index = param->hw_mode_id;
13380 		hw_mode->num_band_to_mac = param->num_band_to_mac;
13381 
13382 		buf_ptr = (uint8_t *) (hw_mode + 1);
13383 		band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr +
13384 				WMI_TLV_HDR_SIZE);
13385 		for (idx = 0; idx < param->num_band_to_mac; idx++) {
13386 			WMITLV_SET_HDR(&band_to_mac[idx].tlv_header,
13387 					WMITLV_TAG_STRUC_wmi_pdev_band_to_mac,
13388 					WMITLV_GET_STRUCT_TLVLEN
13389 					(wmi_pdev_band_to_mac));
13390 			band_to_mac[idx].pdev_id =
13391 				wmi_handle->ops->convert_pdev_id_host_to_target(
13392 					param->band_to_mac[idx].pdev_id);
13393 			band_to_mac[idx].start_freq =
13394 				param->band_to_mac[idx].start_freq;
13395 			band_to_mac[idx].end_freq =
13396 				param->band_to_mac[idx].end_freq;
13397 		}
13398 		*len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) +
13399 			(param->num_band_to_mac *
13400 			 sizeof(wmi_pdev_band_to_mac)) +
13401 			WMI_TLV_HDR_SIZE;
13402 
13403 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
13404 				(param->num_band_to_mac *
13405 				 sizeof(wmi_pdev_band_to_mac)));
13406 	}
13407 
13408 	return buf_ptr;
13409 }
13410 
13411 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle,
13412 		wmi_init_cmd_fixed_param *cmd)
13413 {
13414 	int num_whitelist;
13415 	wmi_abi_version my_vers;
13416 
13417 	num_whitelist = sizeof(version_whitelist) /
13418 		sizeof(wmi_whitelist_version_info);
13419 	my_vers.abi_version_0 = WMI_ABI_VERSION_0;
13420 	my_vers.abi_version_1 = WMI_ABI_VERSION_1;
13421 	my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0;
13422 	my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1;
13423 	my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2;
13424 	my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3;
13425 
13426 	wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist,
13427 			&my_vers,
13428 			(struct _wmi_abi_version *)&wmi_handle->fw_abi_version,
13429 			&cmd->host_abi_vers);
13430 
13431 	qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x",
13432 			__func__,
13433 			WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0),
13434 			WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0),
13435 			cmd->host_abi_vers.abi_version_ns_0,
13436 			cmd->host_abi_vers.abi_version_ns_1,
13437 			cmd->host_abi_vers.abi_version_ns_2,
13438 			cmd->host_abi_vers.abi_version_ns_3);
13439 
13440 	/* Save version sent from host -
13441 	 * Will be used to check ready event
13442 	 */
13443 	qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers,
13444 			sizeof(wmi_abi_version));
13445 }
13446 
13447 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf)
13448 {
13449 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
13450 	wmi_service_ready_event_fixed_param *ev;
13451 
13452 
13453 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
13454 
13455 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
13456 	if (!ev)
13457 		return QDF_STATUS_E_FAILURE;
13458 
13459 	/*Save fw version from service ready message */
13460 	/*This will be used while sending INIT message */
13461 	qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
13462 			sizeof(wmi_handle->fw_abi_version));
13463 
13464 	return QDF_STATUS_SUCCESS;
13465 }
13466 
13467 /**
13468  * wmi_unified_save_fw_version_cmd() - save fw version
13469  * @wmi_handle:      pointer to wmi handle
13470  * @res_cfg:         resource config
13471  * @num_mem_chunks:  no of mem chunck
13472  * @mem_chunk:       pointer to mem chunck structure
13473  *
13474  * This function sends IE information to firmware
13475  *
13476  * Return: QDF_STATUS_SUCCESS for success otherwise failure
13477  *
13478  */
13479 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle,
13480 					  void *evt_buf)
13481 {
13482 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
13483 	wmi_ready_event_fixed_param *ev = NULL;
13484 
13485 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
13486 	ev = param_buf->fixed_param;
13487 	if (!wmi_versions_are_compatible((struct _wmi_abi_version *)
13488 				&wmi_handle->final_abi_vers,
13489 				&ev->fw_abi_vers)) {
13490 		/*
13491 		 * Error: Our host version and the given firmware version
13492 		 * are incompatible.
13493 		 **/
13494 		WMI_LOGD("%s: Error: Incompatible WMI version."
13495 			"Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n",
13496 				__func__,
13497 			WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers.
13498 				abi_version_0),
13499 			WMI_VER_GET_MINOR(wmi_handle->final_abi_vers.
13500 				abi_version_0),
13501 			wmi_handle->final_abi_vers.abi_version_ns_0,
13502 			wmi_handle->final_abi_vers.abi_version_ns_1,
13503 			wmi_handle->final_abi_vers.abi_version_ns_2,
13504 			wmi_handle->final_abi_vers.abi_version_ns_3,
13505 			WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0),
13506 			WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0),
13507 			ev->fw_abi_vers.abi_version_ns_0,
13508 			ev->fw_abi_vers.abi_version_ns_1,
13509 			ev->fw_abi_vers.abi_version_ns_2,
13510 			ev->fw_abi_vers.abi_version_ns_3);
13511 
13512 		return QDF_STATUS_E_FAILURE;
13513 	}
13514 	qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers,
13515 			sizeof(wmi_abi_version));
13516 	qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
13517 			sizeof(wmi_abi_version));
13518 
13519 	return QDF_STATUS_SUCCESS;
13520 }
13521 
13522 /**
13523  * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw
13524  * @wmi_handle: wmi handle
13525  * @custom_addr: base mac address
13526  *
13527  * Return: QDF_STATUS_SUCCESS for success or error code
13528  */
13529 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle,
13530 					 uint8_t *custom_addr)
13531 {
13532 	wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd;
13533 	wmi_buf_t buf;
13534 	int err;
13535 
13536 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
13537 	if (!buf) {
13538 		WMI_LOGE("Failed to allocate buffer to send base macaddr cmd");
13539 		return QDF_STATUS_E_NOMEM;
13540 	}
13541 
13542 	cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf);
13543 	qdf_mem_zero(cmd, sizeof(*cmd));
13544 
13545 	WMITLV_SET_HDR(&cmd->tlv_header,
13546 		   WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param,
13547 		       WMITLV_GET_STRUCT_TLVLEN
13548 			       (wmi_pdev_set_base_macaddr_cmd_fixed_param));
13549 	WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr);
13550 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13551 							WMI_HOST_PDEV_ID_SOC);
13552 	err = wmi_unified_cmd_send(wmi_handle, buf,
13553 				   sizeof(*cmd),
13554 				   WMI_PDEV_SET_BASE_MACADDR_CMDID);
13555 	if (err) {
13556 		WMI_LOGE("Failed to send set_base_macaddr cmd");
13557 		wmi_buf_free(buf);
13558 		return QDF_STATUS_E_FAILURE;
13559 	}
13560 
13561 	return 0;
13562 }
13563 
13564 /**
13565  * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events
13566  * @handle: wmi handle
13567  * @event:  Event received from FW
13568  * @len:    Length of the event
13569  *
13570  * Enables the low frequency events and disables the high frequency
13571  * events. Bit 17 indicates if the event if low/high frequency.
13572  * 1 - high frequency, 0 - low frequency
13573  *
13574  * Return: 0 on successfully enabling/disabling the events
13575  */
13576 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle,
13577 		uint8_t *event,
13578 		uint32_t len)
13579 {
13580 	uint32_t num_of_diag_events_logs;
13581 	wmi_diag_event_log_config_fixed_param *cmd;
13582 	wmi_buf_t buf;
13583 	uint8_t *buf_ptr;
13584 	uint32_t *cmd_args, *evt_args;
13585 	uint32_t buf_len, i;
13586 
13587 	WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf;
13588 	wmi_diag_event_log_supported_event_fixed_params *wmi_event;
13589 
13590 	WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID");
13591 
13592 	param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event;
13593 	if (!param_buf) {
13594 		WMI_LOGE("Invalid log supported event buffer");
13595 		return QDF_STATUS_E_INVAL;
13596 	}
13597 	wmi_event = param_buf->fixed_param;
13598 	num_of_diag_events_logs = wmi_event->num_of_diag_events_logs;
13599 
13600 	if (num_of_diag_events_logs >
13601 	    param_buf->num_diag_events_logs_list) {
13602 		WMI_LOGE("message number of events %d is more than tlv hdr content %d",
13603 			 num_of_diag_events_logs,
13604 			 param_buf->num_diag_events_logs_list);
13605 		return QDF_STATUS_E_INVAL;
13606 	}
13607 
13608 	evt_args = param_buf->diag_events_logs_list;
13609 	if (!evt_args) {
13610 		WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d",
13611 				__func__, num_of_diag_events_logs);
13612 		return QDF_STATUS_E_INVAL;
13613 	}
13614 
13615 	WMI_LOGD("%s: num_of_diag_events_logs=%d",
13616 			__func__, num_of_diag_events_logs);
13617 
13618 	/* Free any previous allocation */
13619 	if (wmi_handle->events_logs_list)
13620 		qdf_mem_free(wmi_handle->events_logs_list);
13621 
13622 	if (num_of_diag_events_logs >
13623 		(WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) {
13624 		WMI_LOGE("%s: excess num of logs:%d", __func__,
13625 			num_of_diag_events_logs);
13626 		QDF_ASSERT(0);
13627 		return QDF_STATUS_E_INVAL;
13628 	}
13629 	/* Store the event list for run time enable/disable */
13630 	wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs *
13631 			sizeof(uint32_t));
13632 	if (!wmi_handle->events_logs_list) {
13633 		WMI_LOGE("%s: event log list memory allocation failed",
13634 				__func__);
13635 		return QDF_STATUS_E_NOMEM;
13636 	}
13637 	wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs;
13638 
13639 	/* Prepare the send buffer */
13640 	buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
13641 		(num_of_diag_events_logs * sizeof(uint32_t));
13642 
13643 	buf = wmi_buf_alloc(wmi_handle, buf_len);
13644 	if (!buf) {
13645 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13646 		qdf_mem_free(wmi_handle->events_logs_list);
13647 		wmi_handle->events_logs_list = NULL;
13648 		return QDF_STATUS_E_NOMEM;
13649 	}
13650 
13651 	cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf);
13652 	buf_ptr = (uint8_t *) cmd;
13653 
13654 	WMITLV_SET_HDR(&cmd->tlv_header,
13655 			WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param,
13656 			WMITLV_GET_STRUCT_TLVLEN(
13657 				wmi_diag_event_log_config_fixed_param));
13658 
13659 	cmd->num_of_diag_events_logs = num_of_diag_events_logs;
13660 
13661 	buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param);
13662 
13663 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
13664 			(num_of_diag_events_logs * sizeof(uint32_t)));
13665 
13666 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
13667 
13668 	/* Populate the events */
13669 	for (i = 0; i < num_of_diag_events_logs; i++) {
13670 		/* Low freq (0) - Enable (1) the event
13671 		 * High freq (1) - Disable (0) the event
13672 		 */
13673 		WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i],
13674 				!(WMI_DIAG_FREQUENCY_GET(evt_args[i])));
13675 		/* Set the event ID */
13676 		WMI_DIAG_ID_SET(cmd_args[i],
13677 				WMI_DIAG_ID_GET(evt_args[i]));
13678 		/* Set the type */
13679 		WMI_DIAG_TYPE_SET(cmd_args[i],
13680 				WMI_DIAG_TYPE_GET(evt_args[i]));
13681 		/* Storing the event/log list in WMI */
13682 		wmi_handle->events_logs_list[i] = evt_args[i];
13683 	}
13684 
13685 	if (wmi_unified_cmd_send(wmi_handle, buf, buf_len,
13686 				WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) {
13687 		WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed",
13688 				__func__);
13689 		wmi_buf_free(buf);
13690 		/* Not clearing events_logs_list, though wmi cmd failed.
13691 		 * Host can still have this list
13692 		 */
13693 		return QDF_STATUS_E_INVAL;
13694 	}
13695 
13696 	return 0;
13697 }
13698 
13699 /**
13700  * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id
13701  * @wmi_handle: wmi handle
13702  * @start_log: Start logging related parameters
13703  *
13704  * Send the command to the FW based on which specific logging of diag
13705  * event/log id can be started/stopped
13706  *
13707  * Return: None
13708  */
13709 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle,
13710 		struct wmi_wifi_start_log *start_log)
13711 {
13712 	wmi_diag_event_log_config_fixed_param *cmd;
13713 	wmi_buf_t buf;
13714 	uint8_t *buf_ptr;
13715 	uint32_t len, count, log_level, i;
13716 	uint32_t *cmd_args;
13717 	uint32_t total_len;
13718 	count = 0;
13719 
13720 	if (!wmi_handle->events_logs_list) {
13721 		WMI_LOGE("%s: Not received event/log list from FW, yet",
13722 				__func__);
13723 		return QDF_STATUS_E_NOMEM;
13724 	}
13725 	/* total_len stores the number of events where BITS 17 and 18 are set.
13726 	 * i.e., events of high frequency (17) and for extended debugging (18)
13727 	 */
13728 	total_len = 0;
13729 	for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) {
13730 		if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) &&
13731 		    (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i])))
13732 			total_len++;
13733 	}
13734 
13735 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
13736 		(total_len * sizeof(uint32_t));
13737 
13738 	buf = wmi_buf_alloc(wmi_handle, len);
13739 	if (!buf) {
13740 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13741 		return QDF_STATUS_E_NOMEM;
13742 	}
13743 	cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf);
13744 	buf_ptr = (uint8_t *) cmd;
13745 
13746 	WMITLV_SET_HDR(&cmd->tlv_header,
13747 			WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param,
13748 			WMITLV_GET_STRUCT_TLVLEN(
13749 				wmi_diag_event_log_config_fixed_param));
13750 
13751 	cmd->num_of_diag_events_logs = total_len;
13752 
13753 	buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param);
13754 
13755 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
13756 			(total_len * sizeof(uint32_t)));
13757 
13758 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
13759 
13760 	if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE)
13761 		log_level = 1;
13762 	else
13763 		log_level = 0;
13764 
13765 	WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level);
13766 	for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) {
13767 		uint32_t val = wmi_handle->events_logs_list[i];
13768 		if ((WMI_DIAG_FREQUENCY_GET(val)) &&
13769 				(WMI_DIAG_EXT_FEATURE_GET(val))) {
13770 
13771 			WMI_DIAG_ID_SET(cmd_args[count],
13772 					WMI_DIAG_ID_GET(val));
13773 			WMI_DIAG_TYPE_SET(cmd_args[count],
13774 					WMI_DIAG_TYPE_GET(val));
13775 			WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count],
13776 					log_level);
13777 			WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val);
13778 			count++;
13779 		}
13780 	}
13781 
13782 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13783 				WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) {
13784 		WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed",
13785 				__func__);
13786 		wmi_buf_free(buf);
13787 		return QDF_STATUS_E_INVAL;
13788 	}
13789 
13790 	return QDF_STATUS_SUCCESS;
13791 }
13792 
13793 /**
13794  * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW
13795  * @wmi_handle: WMI handle
13796  *
13797  * This function is used to send the flush command to the FW,
13798  * that will flush the fw logs that are residue in the FW
13799  *
13800  * Return: None
13801  */
13802 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle)
13803 {
13804 	wmi_debug_mesg_flush_fixed_param *cmd;
13805 	wmi_buf_t buf;
13806 	int len = sizeof(*cmd);
13807 	QDF_STATUS ret;
13808 
13809 	buf = wmi_buf_alloc(wmi_handle, len);
13810 	if (!buf) {
13811 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
13812 		return QDF_STATUS_E_NOMEM;
13813 	}
13814 
13815 	cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf);
13816 	WMITLV_SET_HDR(&cmd->tlv_header,
13817 			WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param,
13818 			WMITLV_GET_STRUCT_TLVLEN(
13819 				wmi_debug_mesg_flush_fixed_param));
13820 	cmd->reserved0 = 0;
13821 
13822 	ret = wmi_unified_cmd_send(wmi_handle,
13823 			buf,
13824 			len,
13825 			WMI_DEBUG_MESG_FLUSH_CMDID);
13826 	if (QDF_IS_STATUS_ERROR(ret)) {
13827 		WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID");
13828 		wmi_buf_free(buf);
13829 		return QDF_STATUS_E_INVAL;
13830 	}
13831 	WMI_LOGI("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW");
13832 
13833 	return ret;
13834 }
13835 
13836 /**
13837  * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW
13838  * @wmi_handle: wmi handle
13839  * @msg: PCL structure containing the PCL and the number of channels
13840  *
13841  * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
13842  * firmware. The DBS Manager is the consumer of this information in the WLAN
13843  * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
13844  * to migrate to a new channel without host driver involvement. An example of
13845  * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
13846  * manage the channel selection without firmware involvement.
13847  *
13848  * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual
13849  * channel list. The weights corresponds to the channels sent in
13850  * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
13851  * weightage compared to the non PCL channels.
13852  *
13853  * Return: Success if the cmd is sent successfully to the firmware
13854  */
13855 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle,
13856 				struct wmi_pcl_chan_weights *msg)
13857 {
13858 	wmi_pdev_set_pcl_cmd_fixed_param *cmd;
13859 	wmi_buf_t buf;
13860 	uint8_t *buf_ptr;
13861 	uint32_t *cmd_args, i, len;
13862 	uint32_t chan_len;
13863 
13864 	chan_len = msg->saved_num_chan;
13865 
13866 	len = sizeof(*cmd) +
13867 		WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t));
13868 
13869 	buf = wmi_buf_alloc(wmi_handle, len);
13870 	if (!buf) {
13871 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13872 		return QDF_STATUS_E_NOMEM;
13873 	}
13874 
13875 	cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf);
13876 	buf_ptr = (uint8_t *) cmd;
13877 	WMITLV_SET_HDR(&cmd->tlv_header,
13878 		WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param,
13879 		WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param));
13880 
13881 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13882 							WMI_HOST_PDEV_ID_SOC);
13883 	cmd->num_chan = chan_len;
13884 	WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan);
13885 
13886 	buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param);
13887 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
13888 			(chan_len * sizeof(uint32_t)));
13889 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
13890 	for (i = 0; i < chan_len ; i++) {
13891 		cmd_args[i] = msg->weighed_valid_list[i];
13892 		WMI_LOGD("%s: chan:%d weight:%d", __func__,
13893 			msg->saved_chan_list[i], cmd_args[i]);
13894 	}
13895 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13896 				WMI_PDEV_SET_PCL_CMDID)) {
13897 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__);
13898 		wmi_buf_free(buf);
13899 		return QDF_STATUS_E_FAILURE;
13900 	}
13901 	return QDF_STATUS_SUCCESS;
13902 }
13903 
13904 /**
13905  * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW
13906  * @wmi_handle: wmi handle
13907  * @msg: Structure containing the following parameters
13908  *
13909  * - hw_mode_index: The HW_Mode field is a enumerated type that is selected
13910  * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID.
13911  *
13912  * Provides notification to the WLAN firmware that host driver is requesting a
13913  * HardWare (HW) Mode change. This command is needed to support iHelium in the
13914  * configurations that include the Dual Band Simultaneous (DBS) feature.
13915  *
13916  * Return: Success if the cmd is sent successfully to the firmware
13917  */
13918 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle,
13919 				uint32_t hw_mode_index)
13920 {
13921 	wmi_pdev_set_hw_mode_cmd_fixed_param *cmd;
13922 	wmi_buf_t buf;
13923 	uint32_t len;
13924 
13925 	len = sizeof(*cmd);
13926 
13927 	buf = wmi_buf_alloc(wmi_handle, len);
13928 	if (!buf) {
13929 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13930 		return QDF_STATUS_E_NOMEM;
13931 	}
13932 
13933 	cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf);
13934 	WMITLV_SET_HDR(&cmd->tlv_header,
13935 		WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param,
13936 		WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param));
13937 
13938 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13939 							WMI_HOST_PDEV_ID_SOC);
13940 	cmd->hw_mode_index = hw_mode_index;
13941 	WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index);
13942 
13943 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13944 				WMI_PDEV_SET_HW_MODE_CMDID)) {
13945 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID",
13946 			__func__);
13947 		wmi_buf_free(buf);
13948 		return QDF_STATUS_E_FAILURE;
13949 	}
13950 
13951 	return QDF_STATUS_SUCCESS;
13952 }
13953 
13954 /**
13955  * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW
13956  * @wmi_handle: wmi handle
13957  * @msg: Dual MAC config parameters
13958  *
13959  * Configures WLAN firmware with the dual MAC features
13960  *
13961  * Return: QDF_STATUS. 0 on success.
13962  */
13963 static
13964 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle,
13965 		struct wmi_dual_mac_config *msg)
13966 {
13967 	wmi_pdev_set_mac_config_cmd_fixed_param *cmd;
13968 	wmi_buf_t buf;
13969 	uint32_t len;
13970 
13971 	len = sizeof(*cmd);
13972 
13973 	buf = wmi_buf_alloc(wmi_handle, len);
13974 	if (!buf) {
13975 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
13976 		return QDF_STATUS_E_FAILURE;
13977 	}
13978 
13979 	cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf);
13980 	WMITLV_SET_HDR(&cmd->tlv_header,
13981 		WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param,
13982 		WMITLV_GET_STRUCT_TLVLEN(
13983 			wmi_pdev_set_mac_config_cmd_fixed_param));
13984 
13985 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
13986 							WMI_HOST_PDEV_ID_SOC);
13987 	cmd->concurrent_scan_config_bits = msg->scan_config;
13988 	cmd->fw_mode_config_bits = msg->fw_mode_config;
13989 	WMI_LOGI("%s: scan_config:%x fw_mode_config:%x",
13990 			__func__, msg->scan_config, msg->fw_mode_config);
13991 
13992 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
13993 				WMI_PDEV_SET_MAC_CONFIG_CMDID)) {
13994 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID",
13995 				__func__);
13996 		wmi_buf_free(buf);
13997 	}
13998 	return QDF_STATUS_SUCCESS;
13999 }
14000 
14001 #ifdef BIG_ENDIAN_HOST
14002 /**
14003 * fips_conv_data_be() - LE to BE conversion of FIPS ev data
14004 * @param data_len - data length
14005 * @param data - pointer to data
14006 *
14007 * Return: QDF_STATUS - success or error status
14008 */
14009 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle,
14010 			struct fips_params *param)
14011 {
14012 	unsigned char *key_unaligned, *data_unaligned;
14013 	int c;
14014 	u_int8_t *key_aligned = NULL;
14015 	u_int8_t *data_aligned = NULL;
14016 
14017 	/* Assigning unaligned space to copy the key */
14018 	key_unaligned = qdf_mem_malloc(
14019 		sizeof(u_int8_t)*param->key_len + FIPS_ALIGN);
14020 	data_unaligned = qdf_mem_malloc(
14021 		sizeof(u_int8_t)*param->data_len + FIPS_ALIGN);
14022 
14023 	/* Checking if kmalloc is succesful to allocate space */
14024 	if (key_unaligned == NULL)
14025 		return QDF_STATUS_SUCCESS;
14026 	/* Checking if space is aligned */
14027 	if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) {
14028 		/* align to 4 */
14029 		key_aligned =
14030 		(u_int8_t *)FIPS_ALIGNTO(key_unaligned,
14031 			FIPS_ALIGN);
14032 	} else {
14033 		key_aligned = (u_int8_t *)key_unaligned;
14034 	}
14035 
14036 	/* memset and copy content from key to key aligned */
14037 	OS_MEMSET(key_aligned, 0, param->key_len);
14038 	OS_MEMCPY(key_aligned, param->key, param->key_len);
14039 
14040 	/* print a hexdump for host debug */
14041 	print_hex_dump(KERN_DEBUG,
14042 		"\t Aligned and Copied Key:@@@@ ",
14043 		DUMP_PREFIX_NONE,
14044 		16, 1, key_aligned, param->key_len, true);
14045 
14046 	/* Checking if kmalloc is succesful to allocate space */
14047 	if (data_unaligned == NULL)
14048 		return QDF_STATUS_SUCCESS;
14049 	/* Checking of space is aligned */
14050 	if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) {
14051 		/* align to 4 */
14052 		data_aligned =
14053 		(u_int8_t *)FIPS_ALIGNTO(data_unaligned,
14054 				FIPS_ALIGN);
14055 	} else {
14056 		data_aligned = (u_int8_t *)data_unaligned;
14057 	}
14058 
14059 	/* memset and copy content from data to data aligned */
14060 	OS_MEMSET(data_aligned, 0, param->data_len);
14061 	OS_MEMCPY(data_aligned, param->data, param->data_len);
14062 
14063 	/* print a hexdump for host debug */
14064 	print_hex_dump(KERN_DEBUG,
14065 		"\t Properly Aligned and Copied Data:@@@@ ",
14066 	DUMP_PREFIX_NONE,
14067 	16, 1, data_aligned, param->data_len, true);
14068 
14069 	/* converting to little Endian both key_aligned and
14070 	* data_aligned*/
14071 	for (c = 0; c < param->key_len/4; c++) {
14072 		*((u_int32_t *)key_aligned+c) =
14073 		qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c));
14074 	}
14075 	for (c = 0; c < param->data_len/4; c++) {
14076 		*((u_int32_t *)data_aligned+c) =
14077 		qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c));
14078 	}
14079 
14080 	/* update endian data to key and data vectors */
14081 	OS_MEMCPY(param->key, key_aligned, param->key_len);
14082 	OS_MEMCPY(param->data, data_aligned, param->data_len);
14083 
14084 	/* clean up allocated spaces */
14085 	qdf_mem_free(key_unaligned);
14086 	key_unaligned = NULL;
14087 	key_aligned = NULL;
14088 
14089 	qdf_mem_free(data_unaligned);
14090 	data_unaligned = NULL;
14091 	data_aligned = NULL;
14092 
14093 	return QDF_STATUS_SUCCESS;
14094 }
14095 #else
14096 /**
14097 * fips_align_data_be() - DUMMY for LE platform
14098 *
14099 * Return: QDF_STATUS - success
14100 */
14101 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle,
14102 		struct fips_params *param)
14103 {
14104 	return QDF_STATUS_SUCCESS;
14105 }
14106 #endif
14107 
14108 
14109 /**
14110  * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw
14111  * @wmi_handle: wmi handle
14112  * @param: pointer to hold pdev fips param
14113  *
14114  * Return: 0 for success or error code
14115  */
14116 static QDF_STATUS
14117 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle,
14118 		struct fips_params *param)
14119 {
14120 	wmi_pdev_fips_cmd_fixed_param *cmd;
14121 	wmi_buf_t buf;
14122 	uint8_t *buf_ptr;
14123 	uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param);
14124 	QDF_STATUS retval = QDF_STATUS_SUCCESS;
14125 
14126 	/* Length TLV placeholder for array of bytes */
14127 	len += WMI_TLV_HDR_SIZE;
14128 	if (param->data_len)
14129 		len += (param->data_len*sizeof(uint8_t));
14130 
14131 	/*
14132 	* Data length must be multiples of 16 bytes - checked against 0xF -
14133 	* and must be less than WMI_SVC_MSG_SIZE - static size of
14134 	* wmi_pdev_fips_cmd structure
14135 	*/
14136 
14137 	/* do sanity on the input */
14138 	if (!(((param->data_len & 0xF) == 0) &&
14139 			((param->data_len > 0) &&
14140 			(param->data_len < (WMI_HOST_MAX_BUFFER_SIZE -
14141 		sizeof(wmi_pdev_fips_cmd_fixed_param)))))) {
14142 		return QDF_STATUS_E_INVAL;
14143 	}
14144 
14145 	buf = wmi_buf_alloc(wmi_handle, len);
14146 	if (!buf) {
14147 		qdf_print("%s:wmi_buf_alloc failed\n", __func__);
14148 		return QDF_STATUS_E_FAILURE;
14149 	}
14150 
14151 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
14152 	cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr;
14153 	WMITLV_SET_HDR(&cmd->tlv_header,
14154 		WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param,
14155 		WMITLV_GET_STRUCT_TLVLEN
14156 		(wmi_pdev_fips_cmd_fixed_param));
14157 
14158 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
14159 								param->pdev_id);
14160 	if (param->key != NULL && param->data != NULL) {
14161 		cmd->key_len = param->key_len;
14162 		cmd->data_len = param->data_len;
14163 		cmd->fips_cmd = !!(param->op);
14164 
14165 		if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS)
14166 			return QDF_STATUS_E_FAILURE;
14167 
14168 		qdf_mem_copy(cmd->key, param->key, param->key_len);
14169 
14170 		if (param->mode == FIPS_ENGINE_AES_CTR ||
14171 			param->mode == FIPS_ENGINE_AES_MIC) {
14172 			cmd->mode = param->mode;
14173 		} else {
14174 			cmd->mode = FIPS_ENGINE_AES_CTR;
14175 		}
14176 		qdf_print(KERN_ERR "Key len = %d, Data len = %d\n",
14177 			cmd->key_len, cmd->data_len);
14178 
14179 		print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1,
14180 				cmd->key, cmd->key_len, true);
14181 		buf_ptr += sizeof(*cmd);
14182 
14183 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len);
14184 
14185 		buf_ptr += WMI_TLV_HDR_SIZE;
14186 		if (param->data_len)
14187 			qdf_mem_copy(buf_ptr,
14188 				(uint8_t *) param->data, param->data_len);
14189 
14190 		print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE,
14191 			16, 1, buf_ptr, cmd->data_len, true);
14192 
14193 		buf_ptr += param->data_len;
14194 
14195 		retval = wmi_unified_cmd_send(wmi_handle, buf, len,
14196 			WMI_PDEV_FIPS_CMDID);
14197 		qdf_print("%s return value %d\n", __func__, retval);
14198 	} else {
14199 		qdf_print("\n%s:%d Key or Data is NULL\n", __func__, __LINE__);
14200 		wmi_buf_free(buf);
14201 		retval = -QDF_STATUS_E_BADMSG;
14202 	}
14203 
14204 	return retval;
14205 }
14206 
14207 #ifdef WLAN_PMO_ENABLE
14208 /**
14209  * send_add_wow_wakeup_event_cmd_tlv() -  Configures wow wakeup events.
14210  * @wmi_handle: wmi handle
14211  * @vdev_id: vdev id
14212  * @bitmap: Event bitmap
14213  * @enable: enable/disable
14214  *
14215  * Return: CDF status
14216  */
14217 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle,
14218 					uint32_t vdev_id,
14219 					uint32_t *bitmap,
14220 					bool enable)
14221 {
14222 	WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd;
14223 	uint16_t len;
14224 	wmi_buf_t buf;
14225 	int ret;
14226 
14227 	len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param);
14228 	buf = wmi_buf_alloc(wmi_handle, len);
14229 	if (!buf) {
14230 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
14231 		return QDF_STATUS_E_NOMEM;
14232 	}
14233 	cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf);
14234 	WMITLV_SET_HDR(&cmd->tlv_header,
14235 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param,
14236 		       WMITLV_GET_STRUCT_TLVLEN
14237 			       (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param));
14238 	cmd->vdev_id = vdev_id;
14239 	cmd->is_add = enable;
14240 	qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) *
14241 		     WMI_WOW_MAX_EVENT_BM_LEN);
14242 
14243 	WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0],
14244 		 cmd->event_bitmaps[1], cmd->event_bitmaps[2],
14245 		 cmd->event_bitmaps[3], enable ? "enabled" : "disabled");
14246 
14247 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
14248 				   WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
14249 	if (ret) {
14250 		WMI_LOGE("Failed to config wow wakeup event");
14251 		wmi_buf_free(buf);
14252 		return QDF_STATUS_E_FAILURE;
14253 	}
14254 
14255 	return QDF_STATUS_SUCCESS;
14256 }
14257 
14258 /**
14259  * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW.
14260  * @wmi_handle: wmi handle
14261  * @vdev_id: vdev id
14262  * @ptrn_id: pattern id
14263  * @ptrn: pattern
14264  * @ptrn_len: pattern length
14265  * @ptrn_offset: pattern offset
14266  * @mask: mask
14267  * @mask_len: mask length
14268  * @user: true for user configured pattern and false for default pattern
14269  * @default_patterns: default patterns
14270  *
14271  * Return: CDF status
14272  */
14273 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle,
14274 				uint8_t vdev_id, uint8_t ptrn_id,
14275 				const uint8_t *ptrn, uint8_t ptrn_len,
14276 				uint8_t ptrn_offset, const uint8_t *mask,
14277 				uint8_t mask_len, bool user,
14278 				uint8_t default_patterns)
14279 {
14280 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
14281 	WOW_BITMAP_PATTERN_T *bitmap_pattern;
14282 	wmi_buf_t buf;
14283 	uint8_t *buf_ptr;
14284 	int32_t len;
14285 	int ret;
14286 
14287 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
14288 		WMI_TLV_HDR_SIZE +
14289 		1 * sizeof(WOW_BITMAP_PATTERN_T) +
14290 		WMI_TLV_HDR_SIZE +
14291 		0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
14292 		WMI_TLV_HDR_SIZE +
14293 		0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
14294 		WMI_TLV_HDR_SIZE +
14295 		0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
14296 		WMI_TLV_HDR_SIZE +
14297 		0 * sizeof(A_UINT32) + WMI_TLV_HDR_SIZE + 1 * sizeof(A_UINT32);
14298 
14299 	buf = wmi_buf_alloc(wmi_handle, len);
14300 	if (!buf) {
14301 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
14302 		return QDF_STATUS_E_NOMEM;
14303 	}
14304 
14305 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
14306 	buf_ptr = (uint8_t *) cmd;
14307 
14308 	WMITLV_SET_HDR(&cmd->tlv_header,
14309 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
14310 		       WMITLV_GET_STRUCT_TLVLEN
14311 			       (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
14312 	cmd->vdev_id = vdev_id;
14313 	cmd->pattern_id = ptrn_id;
14314 
14315 	cmd->pattern_type = WOW_BITMAP_PATTERN;
14316 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
14317 
14318 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14319 		       sizeof(WOW_BITMAP_PATTERN_T));
14320 	buf_ptr += WMI_TLV_HDR_SIZE;
14321 	bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr;
14322 
14323 	WMITLV_SET_HDR(&bitmap_pattern->tlv_header,
14324 		       WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T,
14325 		       WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T));
14326 
14327 	qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len);
14328 	qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len);
14329 
14330 	bitmap_pattern->pattern_offset = ptrn_offset;
14331 	bitmap_pattern->pattern_len = ptrn_len;
14332 
14333 	if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE)
14334 		bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE;
14335 
14336 	if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE)
14337 		bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE;
14338 
14339 	bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len;
14340 	bitmap_pattern->pattern_id = ptrn_id;
14341 
14342 	WMI_LOGI("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d",
14343 		 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len,
14344 		 bitmap_pattern->pattern_offset, user);
14345 	WMI_LOGI("Pattern : ");
14346 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
14347 		&bitmap_pattern->patternbuf[0], bitmap_pattern->pattern_len);
14348 
14349 	WMI_LOGI("Mask : ");
14350 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
14351 		&bitmap_pattern->bitmaskbuf[0], bitmap_pattern->pattern_len);
14352 
14353 	buf_ptr += sizeof(WOW_BITMAP_PATTERN_T);
14354 
14355 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
14356 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14357 	buf_ptr += WMI_TLV_HDR_SIZE;
14358 
14359 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
14360 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14361 	buf_ptr += WMI_TLV_HDR_SIZE;
14362 
14363 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
14364 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14365 	buf_ptr += WMI_TLV_HDR_SIZE;
14366 
14367 	/* Fill TLV for pattern_info_timeout but no data. */
14368 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
14369 	buf_ptr += WMI_TLV_HDR_SIZE;
14370 
14371 	/* Fill TLV for ratelimit_interval with dummy data as this fix elem */
14372 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(A_UINT32));
14373 	buf_ptr += WMI_TLV_HDR_SIZE;
14374 	*(A_UINT32 *) buf_ptr = 0;
14375 
14376 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
14377 				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
14378 	if (ret) {
14379 		WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__);
14380 		wmi_buf_free(buf);
14381 		return QDF_STATUS_E_FAILURE;
14382 	}
14383 
14384 	return QDF_STATUS_SUCCESS;
14385 }
14386 
14387 /**
14388  * fill_arp_offload_params_tlv() - Fill ARP offload data
14389  * @wmi_handle: wmi handle
14390  * @offload_req: offload request
14391  * @buf_ptr: buffer pointer
14392  *
14393  * To fill ARP offload data to firmware
14394  * when target goes to wow mode.
14395  *
14396  * Return: None
14397  */
14398 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle,
14399 		struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr)
14400 {
14401 
14402 	int i;
14403 	WMI_ARP_OFFLOAD_TUPLE *arp_tuple;
14404 	bool enable_or_disable = offload_req->enable;
14405 
14406 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14407 		(WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE)));
14408 	*buf_ptr += WMI_TLV_HDR_SIZE;
14409 	for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) {
14410 		arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr;
14411 		WMITLV_SET_HDR(&arp_tuple->tlv_header,
14412 			WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE,
14413 			WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE));
14414 
14415 		/* Fill data for ARP and NS in the first tupple for LA */
14416 		if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) {
14417 			/* Copy the target ip addr and flags */
14418 			arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID;
14419 			qdf_mem_copy(&arp_tuple->target_ipaddr,
14420 					offload_req->host_ipv4_addr,
14421 					WMI_IPV4_ADDR_LEN);
14422 			WMI_LOGD("ARPOffload IP4 address: %pI4",
14423 					offload_req->host_ipv4_addr);
14424 		}
14425 		*buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE);
14426 	}
14427 }
14428 
14429 #ifdef WLAN_NS_OFFLOAD
14430 /**
14431  * fill_ns_offload_params_tlv() - Fill NS offload data
14432  * @wmi|_handle: wmi handle
14433  * @offload_req: offload request
14434  * @buf_ptr: buffer pointer
14435  *
14436  * To fill NS offload data to firmware
14437  * when target goes to wow mode.
14438  *
14439  * Return: None
14440  */
14441 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle,
14442 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14443 {
14444 
14445 	int i;
14446 	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
14447 
14448 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14449 		(WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE)));
14450 	*buf_ptr += WMI_TLV_HDR_SIZE;
14451 	for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) {
14452 		ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr;
14453 		WMITLV_SET_HDR(&ns_tuple->tlv_header,
14454 			WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
14455 			(sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE));
14456 
14457 		/*
14458 		 * Fill data only for NS offload in the first ARP tuple for LA
14459 		 */
14460 		if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) {
14461 			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
14462 			/* Copy the target/solicitation/remote ip addr */
14463 			if (ns_req->target_ipv6_addr_valid[i])
14464 				qdf_mem_copy(&ns_tuple->target_ipaddr[0],
14465 					&ns_req->target_ipv6_addr[i],
14466 					sizeof(WMI_IPV6_ADDR));
14467 			qdf_mem_copy(&ns_tuple->solicitation_ipaddr,
14468 				&ns_req->self_ipv6_addr[i],
14469 				sizeof(WMI_IPV6_ADDR));
14470 			if (ns_req->target_ipv6_addr_ac_type[i]) {
14471 				ns_tuple->flags |=
14472 					WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST;
14473 			}
14474 			WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6",
14475 				i, &ns_req->self_ipv6_addr[i],
14476 				&ns_req->target_ipv6_addr[i]);
14477 
14478 			/* target MAC is optional, check if it is valid,
14479 			 * if this is not valid, the target will use the known
14480 			 * local MAC address rather than the tuple
14481 			 */
14482 			WMI_CHAR_ARRAY_TO_MAC_ADDR(
14483 				ns_req->self_macaddr.bytes,
14484 				&ns_tuple->target_mac);
14485 			if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
14486 				(ns_tuple->target_mac.mac_addr47to32 != 0)) {
14487 				ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
14488 			}
14489 		}
14490 		*buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
14491 	}
14492 }
14493 
14494 
14495 /**
14496  * fill_nsoffload_ext_tlv() - Fill NS offload ext data
14497  * @wmi: wmi handle
14498  * @offload_req: offload request
14499  * @buf_ptr: buffer pointer
14500  *
14501  * To fill extended NS offload extended data to firmware
14502  * when target goes to wow mode.
14503  *
14504  * Return: None
14505  */
14506 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle,
14507 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14508 {
14509 	int i;
14510 	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
14511 	uint32_t count, num_ns_ext_tuples;
14512 
14513 	count = ns_req->num_ns_offload_count;
14514 	num_ns_ext_tuples = ns_req->num_ns_offload_count -
14515 		WMI_MAX_NS_OFFLOADS;
14516 
14517 	/* Populate extended NS offload tuples */
14518 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
14519 		(num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE)));
14520 	*buf_ptr += WMI_TLV_HDR_SIZE;
14521 	for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) {
14522 		ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr;
14523 		WMITLV_SET_HDR(&ns_tuple->tlv_header,
14524 			WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
14525 			(sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE));
14526 
14527 		/*
14528 		 * Fill data only for NS offload in the first ARP tuple for LA
14529 		 */
14530 		if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) {
14531 			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
14532 			/* Copy the target/solicitation/remote ip addr */
14533 			if (ns_req->target_ipv6_addr_valid[i])
14534 				qdf_mem_copy(&ns_tuple->target_ipaddr[0],
14535 					&ns_req->target_ipv6_addr[i],
14536 					sizeof(WMI_IPV6_ADDR));
14537 			qdf_mem_copy(&ns_tuple->solicitation_ipaddr,
14538 				&ns_req->self_ipv6_addr[i],
14539 				sizeof(WMI_IPV6_ADDR));
14540 			if (ns_req->target_ipv6_addr_ac_type[i]) {
14541 				ns_tuple->flags |=
14542 					WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST;
14543 			}
14544 			WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6",
14545 				i, &ns_req->self_ipv6_addr[i],
14546 				&ns_req->target_ipv6_addr[i]);
14547 
14548 			/* target MAC is optional, check if it is valid,
14549 			 * if this is not valid, the target will use the
14550 			 * known local MAC address rather than the tuple
14551 			 */
14552 			 WMI_CHAR_ARRAY_TO_MAC_ADDR(
14553 				ns_req->self_macaddr.bytes,
14554 				&ns_tuple->target_mac);
14555 			if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
14556 				(ns_tuple->target_mac.mac_addr47to32 != 0)) {
14557 				ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
14558 			}
14559 		}
14560 		*buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
14561 	}
14562 }
14563 #else
14564 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle,
14565 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14566 {
14567 }
14568 
14569 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle,
14570 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
14571 {
14572 }
14573 #endif
14574 
14575 /**
14576  * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload
14577  * @wma: wmi handle
14578  * @arp_offload_req: arp offload request
14579  * @ns_offload_req: ns offload request
14580  * @arp_only: flag
14581  *
14582  * To configure ARP NS off load data to firmware
14583  * when target goes to wow mode.
14584  *
14585  * Return: QDF Status
14586  */
14587 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle,
14588 			   struct pmo_arp_offload_params *arp_offload_req,
14589 			   struct pmo_ns_offload_params *ns_offload_req,
14590 			   uint8_t vdev_id)
14591 {
14592 	int32_t res;
14593 	WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd;
14594 	A_UINT8 *buf_ptr;
14595 	wmi_buf_t buf;
14596 	int32_t len;
14597 	uint32_t count = 0, num_ns_ext_tuples = 0;
14598 
14599 	count = ns_offload_req->num_ns_offload_count;
14600 
14601 	/*
14602 	 * TLV place holder size for array of NS tuples
14603 	 * TLV place holder size for array of ARP tuples
14604 	 */
14605 	len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) +
14606 		WMI_TLV_HDR_SIZE +
14607 		WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) +
14608 		WMI_TLV_HDR_SIZE +
14609 		WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE);
14610 
14611 	/*
14612 	 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate
14613 	 * extra length for extended NS offload tuples which follows ARP offload
14614 	 * tuples. Host needs to fill this structure in following format:
14615 	 * 2 NS ofload tuples
14616 	 * 2 ARP offload tuples
14617 	 * N numbers of extended NS offload tuples if HDD has given more than
14618 	 * 2 NS offload addresses
14619 	 */
14620 	if (count > WMI_MAX_NS_OFFLOADS) {
14621 		num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS;
14622 		len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples
14623 			   * sizeof(WMI_NS_OFFLOAD_TUPLE);
14624 	}
14625 
14626 	buf = wmi_buf_alloc(wmi_handle, len);
14627 	if (!buf) {
14628 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
14629 		return QDF_STATUS_E_NOMEM;
14630 	}
14631 
14632 	buf_ptr = (A_UINT8 *) wmi_buf_data(buf);
14633 	cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr;
14634 	WMITLV_SET_HDR(&cmd->tlv_header,
14635 		       WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param,
14636 		       WMITLV_GET_STRUCT_TLVLEN
14637 			       (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param));
14638 	cmd->flags = 0;
14639 	cmd->vdev_id = vdev_id;
14640 	cmd->num_ns_ext_tuples = num_ns_ext_tuples;
14641 
14642 	WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id);
14643 
14644 	buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param);
14645 	fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr);
14646 	fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr);
14647 	if (num_ns_ext_tuples)
14648 		fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr);
14649 
14650 	res = wmi_unified_cmd_send(wmi_handle, buf, len,
14651 				     WMI_SET_ARP_NS_OFFLOAD_CMDID);
14652 	if (res) {
14653 		WMI_LOGE("Failed to enable ARP NDP/NSffload");
14654 		wmi_buf_free(buf);
14655 		return QDF_STATUS_E_FAILURE;
14656 	}
14657 
14658 	return QDF_STATUS_SUCCESS;
14659 }
14660 
14661 /**
14662  * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload
14663  * @wmi_handle: wmi handle
14664  * @vdev_id: vdev id
14665  * @action: true for enable else false
14666  *
14667  * To enable enhance multicast offload to firmware
14668  * when target goes to wow mode.
14669  *
14670  * Return: QDF Status
14671  */
14672 
14673 static
14674 QDF_STATUS send_enable_enhance_multicast_offload_tlv(
14675 		wmi_unified_t wmi_handle,
14676 		uint8_t vdev_id, bool action)
14677 {
14678 	QDF_STATUS status;
14679 	wmi_buf_t buf;
14680 	wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd;
14681 
14682 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
14683 	if (!buf) {
14684 		WMI_LOGE("Failed to allocate buffer to send set key cmd");
14685 		return QDF_STATUS_E_NOMEM;
14686 	}
14687 
14688 	cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *)
14689 							wmi_buf_data(buf);
14690 
14691 	WMITLV_SET_HDR(&cmd->tlv_header,
14692 		WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param,
14693 		WMITLV_GET_STRUCT_TLVLEN(
14694 			wmi_config_enhanced_mcast_filter_cmd_fixed_param));
14695 
14696 	cmd->vdev_id = vdev_id;
14697 	cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED :
14698 			ENHANCED_MCAST_FILTER_ENABLED);
14699 	WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d",
14700 		__func__, action, vdev_id);
14701 	status = wmi_unified_cmd_send(wmi_handle, buf,
14702 			sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID);
14703 	if (status != QDF_STATUS_SUCCESS) {
14704 		qdf_nbuf_free(buf);
14705 		WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID",
14706 			__func__);
14707 	}
14708 
14709 	return status;
14710 }
14711 
14712 /**
14713  * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event
14714  * @wmi_handle: wmi handle
14715  * @param evt_buf: pointer to event buffer
14716  * @param hdr: Pointer to hold header
14717  * @param bufp: Pointer to hold pointer to rx param buffer
14718  *
14719  * Return: QDF_STATUS_SUCCESS for success or error code
14720  */
14721 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle,
14722 	void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len)
14723 {
14724 	WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param;
14725 	WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf;
14726 
14727 	param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf;
14728 	if (!param_buf) {
14729 		WMI_LOGE("gtk param_buf is NULL");
14730 		return QDF_STATUS_E_INVAL;
14731 	}
14732 
14733 	if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) {
14734 		WMI_LOGE("Invalid length for GTK status");
14735 		return QDF_STATUS_E_INVAL;
14736 	}
14737 
14738 	fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *)
14739 		param_buf->fixed_param;
14740 	gtk_rsp_param->vdev_id = fixed_param->vdev_id;
14741 	gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS;
14742 	gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt;
14743 	qdf_mem_copy(&gtk_rsp_param->replay_counter,
14744 		&fixed_param->replay_counter,
14745 		GTK_REPLAY_COUNTER_BYTES);
14746 
14747 	return QDF_STATUS_SUCCESS;
14748 
14749 }
14750 
14751 #ifdef FEATURE_WLAN_RA_FILTERING
14752 /**
14753  * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw
14754  * @wmi_handle: wmi handle
14755  * @vdev_id: vdev id
14756  *
14757  * Return: CDF status
14758  */
14759 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle,
14760 		   uint8_t vdev_id, uint8_t default_pattern,
14761 		   uint16_t rate_limit_interval)
14762 {
14763 
14764 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
14765 	wmi_buf_t buf;
14766 	uint8_t *buf_ptr;
14767 	int32_t len;
14768 	int ret;
14769 
14770 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
14771 	      WMI_TLV_HDR_SIZE +
14772 	      0 * sizeof(WOW_BITMAP_PATTERN_T) +
14773 	      WMI_TLV_HDR_SIZE +
14774 	      0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
14775 	      WMI_TLV_HDR_SIZE +
14776 	      0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
14777 	      WMI_TLV_HDR_SIZE +
14778 	      0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
14779 	      WMI_TLV_HDR_SIZE +
14780 	      0 * sizeof(A_UINT32) + WMI_TLV_HDR_SIZE + 1 * sizeof(A_UINT32);
14781 
14782 	buf = wmi_buf_alloc(wmi_handle, len);
14783 	if (!buf) {
14784 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
14785 		return QDF_STATUS_E_NOMEM;
14786 	}
14787 
14788 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
14789 	buf_ptr = (uint8_t *) cmd;
14790 
14791 	WMITLV_SET_HDR(&cmd->tlv_header,
14792 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
14793 		       WMITLV_GET_STRUCT_TLVLEN
14794 			       (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
14795 	cmd->vdev_id = vdev_id;
14796 	cmd->pattern_id = default_pattern,
14797 	cmd->pattern_type = WOW_IPV6_RA_PATTERN;
14798 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
14799 
14800 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
14801 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14802 	buf_ptr += WMI_TLV_HDR_SIZE;
14803 
14804 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
14805 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14806 	buf_ptr += WMI_TLV_HDR_SIZE;
14807 
14808 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
14809 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14810 	buf_ptr += WMI_TLV_HDR_SIZE;
14811 
14812 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
14813 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
14814 	buf_ptr += WMI_TLV_HDR_SIZE;
14815 
14816 	/* Fill TLV for pattern_info_timeout but no data. */
14817 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
14818 	buf_ptr += WMI_TLV_HDR_SIZE;
14819 
14820 	/* Fill TLV for ra_ratelimit_interval. */
14821 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(A_UINT32));
14822 	buf_ptr += WMI_TLV_HDR_SIZE;
14823 
14824 	*((A_UINT32 *) buf_ptr) = rate_limit_interval;
14825 
14826 	WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__,
14827 		 rate_limit_interval, vdev_id);
14828 
14829 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
14830 				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
14831 	if (ret) {
14832 		WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__);
14833 		wmi_buf_free(buf);
14834 		return QDF_STATUS_E_FAILURE;
14835 	}
14836 
14837 	return QDF_STATUS_SUCCESS;
14838 
14839 }
14840 #endif /* FEATURE_WLAN_RA_FILTERING */
14841 
14842 /**
14843  * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw
14844  * @wmi_handle: wmi handle
14845  * @vdev_id: vdev id
14846  * @multicastAddr: mcast address
14847  * @clearList: clear list flag
14848  *
14849  * Return: QDF_STATUS_SUCCESS for success or error code
14850  */
14851 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle,
14852 				     uint8_t vdev_id,
14853 				     struct qdf_mac_addr multicast_addr,
14854 				     bool clearList)
14855 {
14856 	WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd;
14857 	wmi_buf_t buf;
14858 	int err;
14859 
14860 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
14861 	if (!buf) {
14862 		WMI_LOGE("Failed to allocate buffer to send set_param cmd");
14863 		return QDF_STATUS_E_NOMEM;
14864 	}
14865 
14866 	cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf);
14867 	qdf_mem_zero(cmd, sizeof(*cmd));
14868 
14869 	WMITLV_SET_HDR(&cmd->tlv_header,
14870 	       WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param,
14871 	       WMITLV_GET_STRUCT_TLVLEN
14872 	       (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param));
14873 	cmd->action =
14874 		(clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET);
14875 	cmd->vdev_id = vdev_id;
14876 	WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr);
14877 
14878 	WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM",
14879 		 cmd->action, vdev_id, clearList, multicast_addr.bytes);
14880 
14881 	err = wmi_unified_cmd_send(wmi_handle, buf,
14882 				   sizeof(*cmd),
14883 				   WMI_SET_MCASTBCAST_FILTER_CMDID);
14884 	if (err) {
14885 		WMI_LOGE("Failed to send set_param cmd");
14886 		wmi_buf_free(buf);
14887 		return QDF_STATUS_E_FAILURE;
14888 	}
14889 
14890 	return QDF_STATUS_SUCCESS;
14891 }
14892 
14893 /**
14894  * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple  mcast filter
14895  *						   command to fw
14896  * @wmi_handle: wmi handle
14897  * @vdev_id: vdev id
14898  * @mcast_filter_params: mcast filter params
14899  *
14900  * Return: QDF_STATUS_SUCCESS for success or error code
14901  */
14902 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv(
14903 				wmi_unified_t wmi_handle,
14904 				uint8_t vdev_id,
14905 				struct pmo_mcast_filter_params *filter_param)
14906 
14907 {
14908 	WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd;
14909 	uint8_t *buf_ptr;
14910 	wmi_buf_t buf;
14911 	int err;
14912 	int i;
14913 	uint8_t *mac_addr_src_ptr = NULL;
14914 	wmi_mac_addr *mac_addr_dst_ptr;
14915 	uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
14916 		sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt;
14917 
14918 	buf = wmi_buf_alloc(wmi_handle, len);
14919 	if (!buf) {
14920 		WMI_LOGE("Failed to allocate memory");
14921 		return QDF_STATUS_E_NOMEM;
14922 	}
14923 
14924 	buf_ptr = (A_UINT8 *) wmi_buf_data(buf);
14925 	cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *)
14926 		wmi_buf_data(buf);
14927 	qdf_mem_zero(cmd, sizeof(*cmd));
14928 
14929 	WMITLV_SET_HDR(&cmd->tlv_header,
14930 	       WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param,
14931 	       WMITLV_GET_STRUCT_TLVLEN
14932 	       (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param));
14933 	cmd->operation =
14934 		((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE
14935 					: WMI_MULTIPLE_MCAST_FILTER_ADD);
14936 	cmd->vdev_id = vdev_id;
14937 	cmd->num_mcastaddrs = filter_param->multicast_addr_cnt;
14938 
14939 	buf_ptr += sizeof(*cmd);
14940 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
14941 		       sizeof(wmi_mac_addr) *
14942 			       filter_param->multicast_addr_cnt);
14943 
14944 	if (filter_param->multicast_addr_cnt == 0)
14945 		goto send_cmd;
14946 
14947 	mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr;
14948 	mac_addr_dst_ptr = (wmi_mac_addr *)
14949 			(buf_ptr + WMI_TLV_HDR_SIZE);
14950 
14951 	for (i = 0; i < filter_param->multicast_addr_cnt; i++) {
14952 		WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr);
14953 		mac_addr_src_ptr += ATH_MAC_LEN;
14954 		mac_addr_dst_ptr++;
14955 	}
14956 
14957 send_cmd:
14958 	err = wmi_unified_cmd_send(wmi_handle, buf,
14959 				   len,
14960 				   WMI_SET_MULTIPLE_MCAST_FILTER_CMDID);
14961 	if (err) {
14962 		WMI_LOGE("Failed to send set_param cmd");
14963 		wmi_buf_free(buf);
14964 		return QDF_STATUS_E_FAILURE;
14965 	}
14966 
14967 	return QDF_STATUS_SUCCESS;
14968 }
14969 
14970 
14971 /**
14972  * send_gtk_offload_cmd_tlv() - send GTK offload command to fw
14973  * @wmi_handle: wmi handle
14974  * @vdev_id: vdev id
14975  * @params: GTK offload parameters
14976  *
14977  * Return: CDF status
14978  */
14979 static
14980 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
14981 					   struct pmo_gtk_req *params,
14982 					   bool enable_offload,
14983 					   uint32_t gtk_offload_opcode)
14984 {
14985 	int len;
14986 	wmi_buf_t buf;
14987 	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
14988 	wmi_gtk_offload_fils_tlv_param *ext_param;
14989 	QDF_STATUS status = QDF_STATUS_SUCCESS;
14990 	uint8_t *buf_ptr;
14991 
14992 	WMI_LOGD("%s Enter", __func__);
14993 
14994 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*ext_param);
14995 
14996 	/* alloc wmi buffer */
14997 	buf = wmi_buf_alloc(wmi_handle, len);
14998 	if (!buf) {
14999 		WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD");
15000 		status = QDF_STATUS_E_NOMEM;
15001 		goto out;
15002 	}
15003 
15004 	cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
15005 	buf_ptr = (uint8_t *)cmd;
15006 	WMITLV_SET_HDR(&cmd->tlv_header,
15007 		       WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
15008 		       WMITLV_GET_STRUCT_TLVLEN
15009 			       (WMI_GTK_OFFLOAD_CMD_fixed_param));
15010 
15011 	cmd->vdev_id = vdev_id;
15012 
15013 	/* Request target to enable GTK offload */
15014 	if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) {
15015 		cmd->flags = gtk_offload_opcode;
15016 
15017 		/* Copy the keys and replay counter */
15018 		qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN);
15019 		qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY);
15020 		qdf_mem_copy(cmd->replay_counter, &params->replay_counter,
15021 			     GTK_REPLAY_COUNTER_BYTES);
15022 	} else {
15023 		cmd->flags = gtk_offload_opcode;
15024 	}
15025 
15026 	buf_ptr += sizeof(*cmd);
15027 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(*ext_param));
15028 	buf_ptr += WMI_TLV_HDR_SIZE;
15029 
15030 	ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr;
15031 	WMITLV_SET_HDR(&ext_param->tlv_header,
15032 			WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param,
15033 			WMITLV_GET_STRUCT_TLVLEN(
15034 				wmi_gtk_offload_fils_tlv_param));
15035 	ext_param->vdev_id = vdev_id;
15036 	ext_param->flags = cmd->flags;
15037 	ext_param->kek_len = params->kek_len;
15038 	qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len);
15039 	qdf_mem_copy(ext_param->KCK, params->kck, WMI_GTK_OFFLOAD_KCK_BYTES);
15040 	qdf_mem_copy(ext_param->replay_counter, &params->replay_counter,
15041 			GTK_REPLAY_COUNTER_BYTES);
15042 
15043 	WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len);
15044 	/* send the wmi command */
15045 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
15046 				 WMI_GTK_OFFLOAD_CMDID)) {
15047 		WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID");
15048 		wmi_buf_free(buf);
15049 		status = QDF_STATUS_E_FAILURE;
15050 	}
15051 
15052 out:
15053 	WMI_LOGD("%s Exit", __func__);
15054 	return status;
15055 }
15056 
15057 /**
15058  * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw
15059  * @wmi_handle: wmi handle
15060  * @params: GTK offload params
15061  *
15062  * Return: CDF status
15063  */
15064 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv(
15065 			wmi_unified_t wmi_handle,
15066 			uint8_t vdev_id,
15067 			uint64_t offload_req_opcode)
15068 {
15069 	int len;
15070 	wmi_buf_t buf;
15071 	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
15072 	QDF_STATUS status = QDF_STATUS_SUCCESS;
15073 
15074 	len = sizeof(*cmd);
15075 
15076 	/* alloc wmi buffer */
15077 	buf = wmi_buf_alloc(wmi_handle, len);
15078 	if (!buf) {
15079 		WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD");
15080 		status = QDF_STATUS_E_NOMEM;
15081 		goto out;
15082 	}
15083 
15084 	cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
15085 	WMITLV_SET_HDR(&cmd->tlv_header,
15086 		       WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
15087 		       WMITLV_GET_STRUCT_TLVLEN
15088 			       (WMI_GTK_OFFLOAD_CMD_fixed_param));
15089 
15090 	/* Request for GTK offload status */
15091 	cmd->flags = offload_req_opcode;
15092 	cmd->vdev_id = vdev_id;
15093 
15094 	/* send the wmi command */
15095 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
15096 				 WMI_GTK_OFFLOAD_CMDID)) {
15097 		WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info");
15098 		wmi_buf_free(buf);
15099 		status = QDF_STATUS_E_FAILURE;
15100 	}
15101 
15102 out:
15103 	return status;
15104 }
15105 
15106 /**
15107  * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params
15108  * @wmi_handle: wmi handler
15109  * @action_params: pointer to action_params
15110  *
15111  * Return: 0 for success, otherwise appropriate error code
15112  */
15113 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle,
15114 		struct pmo_action_wakeup_set_params *action_params)
15115 {
15116 	WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd;
15117 	wmi_buf_t buf;
15118 	int i;
15119 	int32_t err;
15120 	uint32_t len = 0, *cmd_args;
15121 	uint8_t *buf_ptr;
15122 
15123 	len = (PMO_SUPPORTED_ACTION_CATE * sizeof(A_UINT32))
15124 				+ WMI_TLV_HDR_SIZE + sizeof(*cmd);
15125 	buf = wmi_buf_alloc(wmi_handle, len);
15126 	if (!buf) {
15127 		WMI_LOGE("Failed to allocate buffer to send action filter cmd");
15128 		return QDF_STATUS_E_NOMEM;
15129 	}
15130 	cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf);
15131 	buf_ptr = (uint8_t *)cmd;
15132 	WMITLV_SET_HDR(&cmd->tlv_header,
15133 		WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param,
15134 		WMITLV_GET_STRUCT_TLVLEN(
15135 				WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param));
15136 
15137 	cmd->vdev_id = action_params->vdev_id;
15138 	cmd->operation = action_params->operation;
15139 
15140 	for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++)
15141 		cmd->action_category_map[i] =
15142 				action_params->action_category_map[i];
15143 
15144 	buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param);
15145 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
15146 			(PMO_SUPPORTED_ACTION_CATE * sizeof(A_UINT32)));
15147 	buf_ptr += WMI_TLV_HDR_SIZE;
15148 	cmd_args = (uint32_t *) buf_ptr;
15149 	for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++)
15150 		cmd_args[i] = action_params->action_per_category[i];
15151 
15152 	err = wmi_unified_cmd_send(wmi_handle, buf,
15153 			len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID);
15154 	if (err) {
15155 		WMI_LOGE("Failed to send ap_ps_egap cmd");
15156 		wmi_buf_free(buf);
15157 		return QDF_STATUS_E_FAILURE;
15158 	}
15159 
15160 	return QDF_STATUS_SUCCESS;
15161 }
15162 
15163 #ifdef FEATURE_WLAN_LPHB
15164 
15165 /**
15166  * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration
15167  * @wmi_handle: wmi handle
15168  * @lphb_conf_req: configuration info
15169  *
15170  * Return: CDF status
15171  */
15172 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle,
15173 				wmi_hb_set_enable_cmd_fixed_param *params)
15174 {
15175 	QDF_STATUS status;
15176 	wmi_buf_t buf = NULL;
15177 	uint8_t *buf_ptr;
15178 	wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp;
15179 	int len = sizeof(wmi_hb_set_enable_cmd_fixed_param);
15180 
15181 
15182 	buf = wmi_buf_alloc(wmi_handle, len);
15183 	if (!buf) {
15184 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15185 		return QDF_STATUS_E_NOMEM;
15186 	}
15187 
15188 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15189 	hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr;
15190 	WMITLV_SET_HDR(&hb_enable_fp->tlv_header,
15191 		       WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param,
15192 		       WMITLV_GET_STRUCT_TLVLEN
15193 			       (wmi_hb_set_enable_cmd_fixed_param));
15194 
15195 	/* fill in values */
15196 	hb_enable_fp->vdev_id = params->session;
15197 	hb_enable_fp->enable = params->enable;
15198 	hb_enable_fp->item = params->item;
15199 	hb_enable_fp->session = params->session;
15200 
15201 	status = wmi_unified_cmd_send(wmi_handle, buf,
15202 				      len, WMI_HB_SET_ENABLE_CMDID);
15203 	if (QDF_IS_STATUS_ERROR(status)) {
15204 		WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d",
15205 			status);
15206 		wmi_buf_free(buf);
15207 	}
15208 
15209 	return status;
15210 }
15211 
15212 /**
15213  * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration
15214  * @wmi_handle: wmi handle
15215  * @lphb_conf_req: lphb config request
15216  *
15217  * Return: CDF status
15218  */
15219 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle,
15220 	    wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req)
15221 {
15222 	QDF_STATUS status;
15223 	wmi_buf_t buf = NULL;
15224 	uint8_t *buf_ptr;
15225 	wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp;
15226 	int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param);
15227 
15228 	buf = wmi_buf_alloc(wmi_handle, len);
15229 	if (!buf) {
15230 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15231 		return QDF_STATUS_E_NOMEM;
15232 	}
15233 
15234 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15235 	hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr;
15236 	WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header,
15237 		       WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param,
15238 		       WMITLV_GET_STRUCT_TLVLEN
15239 			       (wmi_hb_set_tcp_params_cmd_fixed_param));
15240 
15241 	/* fill in values */
15242 	hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id;
15243 	hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip;
15244 	hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip;
15245 	hb_tcp_params_fp->seq = lphb_conf_req->seq;
15246 	hb_tcp_params_fp->src_port = lphb_conf_req->src_port;
15247 	hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port;
15248 	hb_tcp_params_fp->interval = lphb_conf_req->interval;
15249 	hb_tcp_params_fp->timeout = lphb_conf_req->timeout;
15250 	hb_tcp_params_fp->session = lphb_conf_req->session;
15251 	qdf_mem_copy(&hb_tcp_params_fp->gateway_mac,
15252 				   &lphb_conf_req->gateway_mac,
15253 				   sizeof(hb_tcp_params_fp->gateway_mac));
15254 
15255 	status = wmi_unified_cmd_send(wmi_handle, buf,
15256 				      len, WMI_HB_SET_TCP_PARAMS_CMDID);
15257 	if (QDF_IS_STATUS_ERROR(status)) {
15258 		WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d",
15259 			status);
15260 		wmi_buf_free(buf);
15261 	}
15262 
15263 	return status;
15264 }
15265 
15266 /**
15267  * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd
15268  * @wmi_handle: wmi handle
15269  * @lphb_conf_req: lphb config request
15270  *
15271  * Return: CDF status
15272  */
15273 static
15274 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
15275 		wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp)
15276 {
15277 	QDF_STATUS status;
15278 	wmi_buf_t buf = NULL;
15279 	uint8_t *buf_ptr;
15280 	wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp;
15281 	int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param);
15282 
15283 	buf = wmi_buf_alloc(wmi_handle, len);
15284 	if (!buf) {
15285 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15286 		return QDF_STATUS_E_NOMEM;
15287 	}
15288 
15289 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15290 	hb_tcp_filter_fp =
15291 		(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr;
15292 	WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header,
15293 		WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param,
15294 		WMITLV_GET_STRUCT_TLVLEN
15295 		       (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param));
15296 
15297 	/* fill in values */
15298 	hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id;
15299 	hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length;
15300 	hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset;
15301 	hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session;
15302 	memcpy((void *)&hb_tcp_filter_fp->filter,
15303 	       (void *)&g_hb_tcp_filter_fp->filter,
15304 	       WMI_WLAN_HB_MAX_FILTER_SIZE);
15305 
15306 	status = wmi_unified_cmd_send(wmi_handle, buf,
15307 				      len, WMI_HB_SET_TCP_PKT_FILTER_CMDID);
15308 	if (QDF_IS_STATUS_ERROR(status)) {
15309 		WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d",
15310 			status);
15311 		wmi_buf_free(buf);
15312 	}
15313 
15314 	return status;
15315 }
15316 
15317 /**
15318  * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB
15319  * @wmi_handle: wmi handle
15320  * @lphb_conf_req: lphb config request
15321  *
15322  * Return: CDF status
15323  */
15324 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle,
15325 		   wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req)
15326 {
15327 	QDF_STATUS status;
15328 	wmi_buf_t buf = NULL;
15329 	uint8_t *buf_ptr;
15330 	wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp;
15331 	int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param);
15332 
15333 	buf = wmi_buf_alloc(wmi_handle, len);
15334 	if (!buf) {
15335 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15336 		return QDF_STATUS_E_NOMEM;
15337 	}
15338 
15339 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15340 	hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr;
15341 	WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header,
15342 		       WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param,
15343 		       WMITLV_GET_STRUCT_TLVLEN
15344 			       (wmi_hb_set_udp_params_cmd_fixed_param));
15345 
15346 	/* fill in values */
15347 	hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id;
15348 	hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip;
15349 	hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip;
15350 	hb_udp_params_fp->src_port = lphb_conf_req->src_port;
15351 	hb_udp_params_fp->dst_port = lphb_conf_req->dst_port;
15352 	hb_udp_params_fp->interval = lphb_conf_req->interval;
15353 	hb_udp_params_fp->timeout = lphb_conf_req->timeout;
15354 	hb_udp_params_fp->session = lphb_conf_req->session;
15355 	qdf_mem_copy(&hb_udp_params_fp->gateway_mac,
15356 				   &lphb_conf_req->gateway_mac,
15357 				   sizeof(lphb_conf_req->gateway_mac));
15358 
15359 	status = wmi_unified_cmd_send(wmi_handle, buf,
15360 				      len, WMI_HB_SET_UDP_PARAMS_CMDID);
15361 	if (QDF_IS_STATUS_ERROR(status)) {
15362 		WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d",
15363 			status);
15364 		wmi_buf_free(buf);
15365 	}
15366 
15367 	return status;
15368 }
15369 
15370 /**
15371  * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command
15372  * @wmi_handle: wmi handle
15373  * @lphb_conf_req: lphb config request
15374  *
15375  * Return: CDF status
15376  */
15377 static
15378 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
15379 		wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req)
15380 {
15381 	QDF_STATUS status;
15382 	wmi_buf_t buf = NULL;
15383 	uint8_t *buf_ptr;
15384 	wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp;
15385 	int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param);
15386 
15387 	buf = wmi_buf_alloc(wmi_handle, len);
15388 	if (!buf) {
15389 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15390 		return QDF_STATUS_E_NOMEM;
15391 	}
15392 
15393 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15394 	hb_udp_filter_fp =
15395 		(wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr;
15396 	WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header,
15397 		WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param,
15398 		WMITLV_GET_STRUCT_TLVLEN
15399 		       (wmi_hb_set_udp_pkt_filter_cmd_fixed_param));
15400 
15401 	/* fill in values */
15402 	hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id;
15403 	hb_udp_filter_fp->length = lphb_conf_req->length;
15404 	hb_udp_filter_fp->offset = lphb_conf_req->offset;
15405 	hb_udp_filter_fp->session = lphb_conf_req->session;
15406 	memcpy((void *)&hb_udp_filter_fp->filter,
15407 	       (void *)&lphb_conf_req->filter,
15408 	       WMI_WLAN_HB_MAX_FILTER_SIZE);
15409 
15410 	status = wmi_unified_cmd_send(wmi_handle, buf,
15411 				      len, WMI_HB_SET_UDP_PKT_FILTER_CMDID);
15412 	if (QDF_IS_STATUS_ERROR(status)) {
15413 		WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d",
15414 			status);
15415 		wmi_buf_free(buf);
15416 	}
15417 
15418 	return status;
15419 }
15420 #endif /* FEATURE_WLAN_LPHB */
15421 
15422 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi,
15423 					      struct pmo_hw_filter_params *req)
15424 {
15425 	QDF_STATUS status;
15426 	wmi_hw_data_filter_cmd_fixed_param *cmd;
15427 	wmi_buf_t wmi_buf;
15428 
15429 	if (!req) {
15430 		WMI_LOGE("req is null");
15431 		return QDF_STATUS_E_INVAL;
15432 	}
15433 
15434 	wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd));
15435 	if (!wmi_buf) {
15436 		WMI_LOGE(FL("Out of memory"));
15437 		return QDF_STATUS_E_NOMEM;
15438 	}
15439 
15440 	cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf);
15441 	WMITLV_SET_HDR(&cmd->tlv_header,
15442 		  WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param,
15443 		  WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param));
15444 	cmd->vdev_id = req->vdev_id;
15445 	cmd->enable = req->mode != PMO_HW_FILTER_DISABLED;
15446 	cmd->hw_filter_bitmap = req->mode;
15447 
15448 	WMI_LOGD("configure hw filter (vdev_id: %d, mode: %d)",
15449 		 req->vdev_id, req->mode);
15450 
15451 	status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd),
15452 				      WMI_HW_DATA_FILTER_CMDID);
15453 	if (QDF_IS_STATUS_ERROR(status)) {
15454 		WMI_LOGE("Failed to configure hw filter");
15455 		wmi_buf_free(wmi_buf);
15456 	}
15457 
15458 	return status;
15459 }
15460 
15461 /**
15462  * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter
15463  * @wmi_handle: wmi handle
15464  * @vdev_id: vdev id
15465  * @enable: Flag to enable/disable packet filter
15466  *
15467  * Return: QDF_STATUS_SUCCESS for success or error code
15468  */
15469 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv(
15470 		wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable)
15471 {
15472 	int32_t len;
15473 	int ret = 0;
15474 	wmi_buf_t buf;
15475 	WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd;
15476 
15477 	len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param);
15478 
15479 	buf = wmi_buf_alloc(wmi_handle, len);
15480 	if (!buf) {
15481 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
15482 		return QDF_STATUS_E_NOMEM;
15483 	}
15484 
15485 	cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf);
15486 	WMITLV_SET_HDR(&cmd->tlv_header,
15487 		WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param,
15488 		WMITLV_GET_STRUCT_TLVLEN(
15489 		WMI_PACKET_FILTER_ENABLE_CMD_fixed_param));
15490 
15491 	cmd->vdev_id = vdev_id;
15492 	if (enable)
15493 		cmd->enable = PACKET_FILTER_SET_ENABLE;
15494 	else
15495 		cmd->enable = PACKET_FILTER_SET_DISABLE;
15496 
15497 	WMI_LOGE("%s: Packet filter enable %d for vdev_id %d",
15498 		__func__, cmd->enable, vdev_id);
15499 
15500 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
15501 			 WMI_PACKET_FILTER_ENABLE_CMDID);
15502 	if (ret) {
15503 		WMI_LOGE("Failed to send packet filter wmi cmd to fw");
15504 		wmi_buf_free(buf);
15505 	}
15506 
15507 	return ret;
15508 }
15509 
15510 /**
15511  * send_config_packet_filter_cmd_tlv() - configure packet filter in target
15512  * @wmi_handle: wmi handle
15513  * @vdev_id: vdev id
15514  * @rcv_filter_param: Packet filter parameters
15515  * @filter_id: Filter id
15516  * @enable: Flag to add/delete packet filter configuration
15517  *
15518  * Return: QDF_STATUS_SUCCESS for success or error code
15519  */
15520 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle,
15521 		uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param,
15522 		uint8_t filter_id, bool enable)
15523 {
15524 	int len, i;
15525 	int err = 0;
15526 	wmi_buf_t buf;
15527 	WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd;
15528 
15529 
15530 	/* allocate the memory */
15531 	len = sizeof(*cmd);
15532 	buf = wmi_buf_alloc(wmi_handle, len);
15533 	if (!buf) {
15534 		WMI_LOGE("Failed to allocate buffer to send set_param cmd");
15535 		return QDF_STATUS_E_NOMEM;
15536 	}
15537 
15538 	cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf);
15539 	WMITLV_SET_HDR(&cmd->tlv_header,
15540 		WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param,
15541 		WMITLV_GET_STRUCT_TLVLEN
15542 			       (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param));
15543 
15544 	cmd->vdev_id = vdev_id;
15545 	cmd->filter_id = filter_id;
15546 	if (enable)
15547 		cmd->filter_action = PACKET_FILTER_SET_ACTIVE;
15548 	else
15549 		cmd->filter_action = PACKET_FILTER_SET_INACTIVE;
15550 
15551 	if (enable) {
15552 		cmd->num_params = QDF_MIN(
15553 			WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER,
15554 			rcv_filter_param->num_params);
15555 		cmd->filter_type = rcv_filter_param->filter_type;
15556 		cmd->coalesce_time = rcv_filter_param->coalesce_time;
15557 
15558 		for (i = 0; i < cmd->num_params; i++) {
15559 			cmd->paramsData[i].proto_type =
15560 				rcv_filter_param->params_data[i].protocol_layer;
15561 			cmd->paramsData[i].cmp_type =
15562 				rcv_filter_param->params_data[i].compare_flag;
15563 			cmd->paramsData[i].data_length =
15564 				rcv_filter_param->params_data[i].data_length;
15565 			cmd->paramsData[i].data_offset =
15566 				rcv_filter_param->params_data[i].data_offset;
15567 			memcpy(&cmd->paramsData[i].compareData,
15568 				rcv_filter_param->params_data[i].compare_data,
15569 				sizeof(cmd->paramsData[i].compareData));
15570 			memcpy(&cmd->paramsData[i].dataMask,
15571 				rcv_filter_param->params_data[i].data_mask,
15572 				sizeof(cmd->paramsData[i].dataMask));
15573 		}
15574 	}
15575 
15576 	WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d",
15577 		cmd->filter_action, cmd->filter_id, cmd->num_params);
15578 	/* send the command along with data */
15579 	err = wmi_unified_cmd_send(wmi_handle, buf, len,
15580 				WMI_PACKET_FILTER_CONFIG_CMDID);
15581 	if (err) {
15582 		WMI_LOGE("Failed to send pkt_filter cmd");
15583 		wmi_buf_free(buf);
15584 		return QDF_STATUS_E_FAILURE;
15585 	}
15586 
15587 	return QDF_STATUS_SUCCESS;
15588 }
15589 #endif /* End of WLAN_PMO_ENABLE */
15590 
15591 /**
15592  * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request
15593  * @wmi_handle: wmi handle
15594  * @request: SSID hotlist set request
15595  *
15596  * Return: QDF_STATUS enumeration
15597  */
15598 static QDF_STATUS
15599 send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle,
15600 		     struct ssid_hotlist_request_params *request)
15601 {
15602 	wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd;
15603 	wmi_buf_t wmi_buf;
15604 	uint32_t len;
15605 	uint32_t array_size;
15606 	uint8_t *buf_ptr;
15607 
15608 	/* length of fixed portion */
15609 	len = sizeof(*cmd);
15610 
15611 	/* length of variable portion */
15612 	array_size =
15613 		request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry);
15614 	len += WMI_TLV_HDR_SIZE + array_size;
15615 
15616 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15617 	if (!wmi_buf) {
15618 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
15619 		return QDF_STATUS_E_NOMEM;
15620 	}
15621 
15622 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
15623 	cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *)
15624 						buf_ptr;
15625 	WMITLV_SET_HDR
15626 		(&cmd->tlv_header,
15627 		 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param,
15628 		 WMITLV_GET_STRUCT_TLVLEN
15629 			(wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param));
15630 
15631 	cmd->request_id = request->request_id;
15632 	cmd->requestor_id = 0;
15633 	cmd->vdev_id = request->session_id;
15634 	cmd->table_id = 0;
15635 	cmd->lost_ap_scan_count = request->lost_ssid_sample_size;
15636 	cmd->total_entries = request->ssid_count;
15637 	cmd->num_entries_in_page = request->ssid_count;
15638 	cmd->first_entry_index = 0;
15639 
15640 	buf_ptr += sizeof(*cmd);
15641 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size);
15642 
15643 	if (request->ssid_count) {
15644 		wmi_extscan_hotlist_ssid_entry *entry;
15645 		int i;
15646 
15647 		buf_ptr += WMI_TLV_HDR_SIZE;
15648 		entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr;
15649 		for (i = 0; i < request->ssid_count; i++) {
15650 			WMITLV_SET_HDR
15651 				(entry,
15652 				 WMITLV_TAG_ARRAY_STRUC,
15653 				 WMITLV_GET_STRUCT_TLVLEN
15654 					(wmi_extscan_hotlist_ssid_entry));
15655 			entry->ssid.ssid_len = request->ssids[i].ssid.length;
15656 			qdf_mem_copy(entry->ssid.ssid,
15657 				     request->ssids[i].ssid.mac_ssid,
15658 				     request->ssids[i].ssid.length);
15659 			entry->band = request->ssids[i].band;
15660 			entry->min_rssi = request->ssids[i].rssi_low;
15661 			entry->max_rssi = request->ssids[i].rssi_high;
15662 			entry++;
15663 		}
15664 		cmd->mode = WMI_EXTSCAN_MODE_START;
15665 	} else {
15666 		cmd->mode = WMI_EXTSCAN_MODE_STOP;
15667 	}
15668 
15669 	if (wmi_unified_cmd_send
15670 		(wmi_handle, wmi_buf, len,
15671 		 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) {
15672 		WMI_LOGE("%s: failed to send command", __func__);
15673 		wmi_buf_free(wmi_buf);
15674 		return QDF_STATUS_E_FAILURE;
15675 	}
15676 
15677 	return QDF_STATUS_SUCCESS;
15678 }
15679 
15680 /**
15681  * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw.
15682  * @wmi_handle: wmi handle
15683  * @vdev_id: vdev id
15684  *
15685  * This function sends roam synch complete event to fw.
15686  *
15687  * Return: CDF STATUS
15688  */
15689 static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle,
15690 		 uint8_t vdev_id)
15691 {
15692 	wmi_roam_synch_complete_fixed_param *cmd;
15693 	wmi_buf_t wmi_buf;
15694 	uint8_t *buf_ptr;
15695 	uint16_t len;
15696 	len = sizeof(wmi_roam_synch_complete_fixed_param);
15697 
15698 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15699 	if (!wmi_buf) {
15700 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
15701 		return QDF_STATUS_E_NOMEM;
15702 	}
15703 	cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf);
15704 	buf_ptr = (uint8_t *) cmd;
15705 	WMITLV_SET_HDR(&cmd->tlv_header,
15706 		       WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param,
15707 		       WMITLV_GET_STRUCT_TLVLEN
15708 			       (wmi_roam_synch_complete_fixed_param));
15709 	cmd->vdev_id = vdev_id;
15710 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15711 				 WMI_ROAM_SYNCH_COMPLETE)) {
15712 		WMI_LOGP("%s: failed to send roam synch confirmation",
15713 			 __func__);
15714 		wmi_buf_free(wmi_buf);
15715 		return QDF_STATUS_E_FAILURE;
15716 	}
15717 
15718 	return QDF_STATUS_SUCCESS;
15719 }
15720 
15721 /**
15722  * send_fw_test_cmd_tlv() - send fw test command to fw.
15723  * @wmi_handle: wmi handle
15724  * @wmi_fwtest: fw test command
15725  *
15726  * This function sends fw test command to fw.
15727  *
15728  * Return: CDF STATUS
15729  */
15730 static
15731 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle,
15732 			       struct set_fwtest_params *wmi_fwtest)
15733 {
15734 	wmi_fwtest_set_param_cmd_fixed_param *cmd;
15735 	wmi_buf_t wmi_buf;
15736 	uint16_t len;
15737 
15738 	len = sizeof(*cmd);
15739 
15740 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15741 	if (!wmi_buf) {
15742 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
15743 		return QDF_STATUS_E_NOMEM;
15744 	}
15745 
15746 	cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf);
15747 	WMITLV_SET_HDR(&cmd->tlv_header,
15748 		       WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param,
15749 		       WMITLV_GET_STRUCT_TLVLEN(
15750 		       wmi_fwtest_set_param_cmd_fixed_param));
15751 	cmd->param_id = wmi_fwtest->arg;
15752 	cmd->param_value = wmi_fwtest->value;
15753 
15754 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15755 				 WMI_FWTEST_CMDID)) {
15756 		WMI_LOGP("%s: failed to send fw test command", __func__);
15757 		qdf_nbuf_free(wmi_buf);
15758 		return QDF_STATUS_E_FAILURE;
15759 	}
15760 
15761 	return QDF_STATUS_SUCCESS;
15762 }
15763 
15764 /**
15765  * send_unit_test_cmd_tlv() - send unit test command to fw.
15766  * @wmi_handle: wmi handle
15767  * @wmi_utest: unit test command
15768  *
15769  * This function send unit test command to fw.
15770  *
15771  * Return: CDF STATUS
15772  */
15773 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle,
15774 			       struct wmi_unit_test_cmd *wmi_utest)
15775 {
15776 	wmi_unit_test_cmd_fixed_param *cmd;
15777 	wmi_buf_t wmi_buf;
15778 	uint8_t *buf_ptr;
15779 	int i;
15780 	uint16_t len, args_tlv_len;
15781 	A_UINT32 *unit_test_cmd_args;
15782 
15783 	args_tlv_len =
15784 		WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(A_UINT32);
15785 	len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len;
15786 
15787 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15788 	if (!wmi_buf) {
15789 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
15790 		return QDF_STATUS_E_NOMEM;
15791 	}
15792 
15793 	cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf);
15794 	buf_ptr = (uint8_t *) cmd;
15795 	WMITLV_SET_HDR(&cmd->tlv_header,
15796 		       WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param,
15797 		       WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param));
15798 	cmd->vdev_id = wmi_utest->vdev_id;
15799 	cmd->module_id = wmi_utest->module_id;
15800 	cmd->num_args = wmi_utest->num_args;
15801 	cmd->diag_token = wmi_utest->diag_token;
15802 	buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param);
15803 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
15804 		       (wmi_utest->num_args * sizeof(uint32_t)));
15805 	unit_test_cmd_args = (A_UINT32 *) (buf_ptr + WMI_TLV_HDR_SIZE);
15806 	WMI_LOGI("%s: VDEV ID: %d\n", __func__, cmd->vdev_id);
15807 	WMI_LOGI("%s: MODULE ID: %d\n", __func__, cmd->module_id);
15808 	WMI_LOGI("%s: TOKEN: %d\n", __func__, cmd->diag_token);
15809 	WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args);
15810 	for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) {
15811 		unit_test_cmd_args[i] = wmi_utest->args[i];
15812 		WMI_LOGI("%d,", wmi_utest->args[i]);
15813 	}
15814 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15815 				 WMI_UNIT_TEST_CMDID)) {
15816 		WMI_LOGP("%s: failed to send unit test command", __func__);
15817 		wmi_buf_free(wmi_buf);
15818 		return QDF_STATUS_E_FAILURE;
15819 	}
15820 
15821 	return QDF_STATUS_SUCCESS;
15822 }
15823 
15824 /**
15825  * send_roam_invoke_cmd_tlv() - send roam invoke command to fw.
15826  * @wmi_handle: wma handle
15827  * @roaminvoke: roam invoke command
15828  *
15829  * Send roam invoke command to fw for fastreassoc.
15830  *
15831  * Return: CDF STATUS
15832  */
15833 static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle,
15834 		struct wmi_roam_invoke_cmd *roaminvoke,
15835 		uint32_t ch_hz)
15836 {
15837 	wmi_roam_invoke_cmd_fixed_param *cmd;
15838 	wmi_buf_t wmi_buf;
15839 	u_int8_t *buf_ptr;
15840 	u_int16_t len, args_tlv_len;
15841 	A_UINT32 *channel_list;
15842 	wmi_mac_addr *bssid_list;
15843 	wmi_tlv_buf_len_param *buf_len_tlv;
15844 
15845 	/* Host sends only one channel and one bssid */
15846 	args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(A_UINT32) +
15847 			sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) +
15848 			roundup(roaminvoke->frame_len, sizeof(uint32_t));
15849 	len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len;
15850 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
15851 	if (!wmi_buf) {
15852 		WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
15853 		return QDF_STATUS_E_NOMEM;
15854 	}
15855 
15856 	cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf);
15857 	buf_ptr = (u_int8_t *) cmd;
15858 	WMITLV_SET_HDR(&cmd->tlv_header,
15859 	WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param,
15860 	WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param));
15861 	cmd->vdev_id = roaminvoke->vdev_id;
15862 	cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE);
15863 	if (roaminvoke->is_same_bssid)
15864 		cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP);
15865 	WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid);
15866 
15867 	if (roaminvoke->frame_len) {
15868 		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP;
15869 		/* packing 1 beacon/probe_rsp frame with WMI cmd */
15870 		cmd->num_buf = 1;
15871 	} else {
15872 		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH;
15873 		cmd->num_buf = 0;
15874 	}
15875 
15876 	cmd->roam_ap_sel_mode = 0;
15877 	cmd->roam_delay = 0;
15878 	cmd->num_chan = 1;
15879 	cmd->num_bssid = 1;
15880 
15881 	buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param);
15882 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
15883 				(sizeof(u_int32_t)));
15884 	channel_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE);
15885 	*channel_list = ch_hz;
15886 	buf_ptr += sizeof(A_UINT32) + WMI_TLV_HDR_SIZE;
15887 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
15888 				(sizeof(wmi_mac_addr)));
15889 	bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
15890 	WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list);
15891 
15892 	/* move to next tlv i.e. bcn_prb_buf_list */
15893 	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr);
15894 
15895 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
15896 			sizeof(wmi_tlv_buf_len_param));
15897 
15898 	buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE);
15899 	buf_len_tlv->buf_len = roaminvoke->frame_len;
15900 
15901 	/* move to next tlv i.e. bcn_prb_frm */
15902 	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param);
15903 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
15904 		roundup(roaminvoke->frame_len, sizeof(uint32_t)));
15905 
15906 	/* copy frame after the header */
15907 	qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
15908 			roaminvoke->frame_buf,
15909 			roaminvoke->frame_len);
15910 
15911 	WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len);
15912 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
15913 			buf_ptr + WMI_TLV_HDR_SIZE,
15914 			roaminvoke->frame_len);
15915 	WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"),
15916 			cmd->flags, cmd->roam_scan_mode,
15917 			cmd->roam_ap_sel_mode, cmd->roam_delay,
15918 			cmd->num_chan, cmd->num_bssid);
15919 	WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz);
15920 
15921 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
15922 					WMI_ROAM_INVOKE_CMDID)) {
15923 		WMI_LOGP("%s: failed to send roam invoke command", __func__);
15924 		wmi_buf_free(wmi_buf);
15925 		return QDF_STATUS_E_FAILURE;
15926 	}
15927 
15928 	return QDF_STATUS_SUCCESS;
15929 }
15930 
15931 /**
15932  * send_roam_scan_offload_cmd_tlv() - set roam offload command
15933  * @wmi_handle: wmi handle
15934  * @command: command
15935  * @vdev_id: vdev id
15936  *
15937  * This function set roam offload command to fw.
15938  *
15939  * Return: CDF status
15940  */
15941 static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle,
15942 					 uint32_t command, uint32_t vdev_id)
15943 {
15944 	QDF_STATUS status;
15945 	wmi_roam_scan_cmd_fixed_param *cmd_fp;
15946 	wmi_buf_t buf = NULL;
15947 	int len;
15948 	uint8_t *buf_ptr;
15949 
15950 	len = sizeof(wmi_roam_scan_cmd_fixed_param);
15951 	buf = wmi_buf_alloc(wmi_handle, len);
15952 	if (!buf) {
15953 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
15954 		return QDF_STATUS_E_NOMEM;
15955 	}
15956 
15957 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
15958 
15959 	cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr;
15960 	WMITLV_SET_HDR(&cmd_fp->tlv_header,
15961 		       WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param,
15962 		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param));
15963 	cmd_fp->vdev_id = vdev_id;
15964 	cmd_fp->command_arg = command;
15965 
15966 	status = wmi_unified_cmd_send(wmi_handle, buf,
15967 				      len, WMI_ROAM_SCAN_CMD);
15968 	if (QDF_IS_STATUS_ERROR(status)) {
15969 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d",
15970 			status);
15971 		goto error;
15972 	}
15973 
15974 	WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__);
15975 	return QDF_STATUS_SUCCESS;
15976 
15977 error:
15978 	wmi_buf_free(buf);
15979 
15980 	return status;
15981 }
15982 
15983 /**
15984  * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw
15985  * @wmi_handle: wmi handle
15986  * @ap_profile_p: ap profile
15987  * @vdev_id: vdev id
15988  *
15989  * Send WMI_ROAM_AP_PROFILE to firmware
15990  *
15991  * Return: CDF status
15992  */
15993 static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
15994 					    struct ap_profile_params *ap_profile)
15995 {
15996 	wmi_buf_t buf = NULL;
15997 	QDF_STATUS status;
15998 	int len;
15999 	uint8_t *buf_ptr;
16000 	wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp;
16001 	wmi_roam_cnd_scoring_param *score_param;
16002 	wmi_ap_profile *profile;
16003 
16004 	len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile);
16005 	len += sizeof(*score_param);
16006 	buf = wmi_buf_alloc(wmi_handle, len);
16007 	if (!buf) {
16008 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16009 		return QDF_STATUS_E_NOMEM;
16010 	}
16011 
16012 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16013 	roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr;
16014 	WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header,
16015 		       WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param,
16016 		       WMITLV_GET_STRUCT_TLVLEN
16017 			       (wmi_roam_ap_profile_fixed_param));
16018 	/* fill in threshold values */
16019 	roam_ap_profile_fp->vdev_id = ap_profile->vdev_id;
16020 	roam_ap_profile_fp->id = 0;
16021 	buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param);
16022 
16023 	profile = (wmi_ap_profile *)buf_ptr;
16024 	WMITLV_SET_HDR(&profile->tlv_header,
16025 		       WMITLV_TAG_STRUC_wmi_ap_profile,
16026 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile));
16027 	profile->flags = ap_profile->profile.flags;
16028 	profile->rssi_threshold = ap_profile->profile.rssi_threshold;
16029 	profile->ssid.ssid_len = ap_profile->profile.ssid.length;
16030 	qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid,
16031 		     profile->ssid.ssid_len);
16032 	profile->rsn_authmode = ap_profile->profile.rsn_authmode;
16033 	profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset;
16034 	profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset;
16035 	profile->rsn_mcastmgmtcipherset =
16036 				ap_profile->profile.rsn_mcastmgmtcipherset;
16037 	profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh;
16038 
16039 	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",
16040 		 profile->flags, profile->rssi_threshold,
16041 		 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid,
16042 		 profile->rsn_authmode, profile->rsn_ucastcipherset,
16043 		 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset,
16044 		 profile->rssi_abs_thresh);
16045 
16046 	buf_ptr += sizeof(wmi_ap_profile);
16047 
16048 	score_param = (wmi_roam_cnd_scoring_param *)buf_ptr;
16049 	WMITLV_SET_HDR(&score_param->tlv_header,
16050 		       WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param,
16051 		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param));
16052 	score_param->disable_bitmap = ap_profile->param.disable_bitmap;
16053 	score_param->rssi_weightage_pcnt =
16054 			ap_profile->param.rssi_weightage;
16055 	score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage;
16056 	score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage;
16057 	score_param->he_weightage_pcnt = ap_profile->param.he_weightage;
16058 	score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage;
16059 	score_param->band_weightage_pcnt = ap_profile->param.band_weightage;
16060 	score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage;
16061 	score_param->esp_qbss_weightage_pcnt =
16062 			ap_profile->param.esp_qbss_weightage;
16063 	score_param->beamforming_weightage_pcnt =
16064 			ap_profile->param.beamforming_weightage;
16065 	score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage;
16066 	score_param->oce_wan_weightage_pcnt =
16067 			ap_profile->param.oce_wan_weightage;
16068 
16069 	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",
16070 		 score_param->disable_bitmap, score_param->rssi_weightage_pcnt,
16071 		 score_param->ht_weightage_pcnt,
16072 		 score_param->vht_weightage_pcnt,
16073 		 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt,
16074 		 score_param->band_weightage_pcnt,
16075 		 score_param->nss_weightage_pcnt,
16076 		 score_param->esp_qbss_weightage_pcnt,
16077 		 score_param->beamforming_weightage_pcnt,
16078 		 score_param->pcl_weightage_pcnt,
16079 		 score_param->oce_wan_weightage_pcnt);
16080 
16081 	score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score;
16082 	score_param->band_scoring.score_pcnt =
16083 			ap_profile->param.band_index_score;
16084 	score_param->nss_scoring.score_pcnt =
16085 			ap_profile->param.nss_index_score;
16086 
16087 	WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x",
16088 		 score_param->bw_scoring.score_pcnt,
16089 		 score_param->band_scoring.score_pcnt,
16090 		 score_param->nss_scoring.score_pcnt);
16091 
16092 	score_param->rssi_scoring.best_rssi_threshold =
16093 		(-1) * ap_profile->param.rssi_scoring.best_rssi_threshold;
16094 	score_param->rssi_scoring.good_rssi_threshold =
16095 		(-1) * ap_profile->param.rssi_scoring.good_rssi_threshold;
16096 	score_param->rssi_scoring.bad_rssi_threshold =
16097 		(-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold;
16098 	score_param->rssi_scoring.good_rssi_pcnt =
16099 		ap_profile->param.rssi_scoring.good_rssi_pcnt;
16100 	score_param->rssi_scoring.bad_rssi_pcnt =
16101 		ap_profile->param.rssi_scoring.bad_rssi_pcnt;
16102 	score_param->rssi_scoring.good_bucket_size =
16103 		ap_profile->param.rssi_scoring.good_bucket_size;
16104 	score_param->rssi_scoring.bad_bucket_size =
16105 		ap_profile->param.rssi_scoring.bad_bucket_size;
16106 	score_param->rssi_scoring.rssi_pref_5g_rssi_thresh =
16107 		(-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh;
16108 
16109 	WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d",
16110 		 score_param->rssi_scoring.best_rssi_threshold,
16111 		 score_param->rssi_scoring.good_rssi_threshold,
16112 		 score_param->rssi_scoring.bad_rssi_threshold,
16113 		 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh);
16114 	WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d",
16115 		 score_param->rssi_scoring.good_rssi_pcnt,
16116 		 score_param->rssi_scoring.bad_rssi_pcnt,
16117 		 score_param->rssi_scoring.good_bucket_size,
16118 		 score_param->rssi_scoring.bad_bucket_size);
16119 
16120 	score_param->esp_qbss_scoring.num_slot =
16121 			ap_profile->param.esp_qbss_scoring.num_slot;
16122 	score_param->esp_qbss_scoring.score_pcnt3_to_0 =
16123 			ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0;
16124 	score_param->esp_qbss_scoring.score_pcnt7_to_4 =
16125 			ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4;
16126 	score_param->esp_qbss_scoring.score_pcnt11_to_8 =
16127 			ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8;
16128 	score_param->esp_qbss_scoring.score_pcnt15_to_12 =
16129 			ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12;
16130 
16131 	WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
16132 		 score_param->esp_qbss_scoring.num_slot,
16133 		 score_param->esp_qbss_scoring.score_pcnt3_to_0,
16134 		 score_param->esp_qbss_scoring.score_pcnt7_to_4,
16135 		 score_param->esp_qbss_scoring.score_pcnt11_to_8,
16136 		 score_param->esp_qbss_scoring.score_pcnt15_to_12);
16137 
16138 	score_param->oce_wan_scoring.num_slot =
16139 			ap_profile->param.oce_wan_scoring.num_slot;
16140 	score_param->oce_wan_scoring.score_pcnt3_to_0 =
16141 			ap_profile->param.oce_wan_scoring.score_pcnt3_to_0;
16142 	score_param->oce_wan_scoring.score_pcnt7_to_4 =
16143 			ap_profile->param.oce_wan_scoring.score_pcnt7_to_4;
16144 	score_param->oce_wan_scoring.score_pcnt11_to_8 =
16145 			ap_profile->param.oce_wan_scoring.score_pcnt11_to_8;
16146 	score_param->oce_wan_scoring.score_pcnt15_to_12 =
16147 			ap_profile->param.oce_wan_scoring.score_pcnt15_to_12;
16148 
16149 	WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
16150 		 score_param->oce_wan_scoring.num_slot,
16151 		 score_param->oce_wan_scoring.score_pcnt3_to_0,
16152 		 score_param->oce_wan_scoring.score_pcnt7_to_4,
16153 		 score_param->oce_wan_scoring.score_pcnt11_to_8,
16154 		 score_param->oce_wan_scoring.score_pcnt15_to_12);
16155 
16156 	status = wmi_unified_cmd_send(wmi_handle, buf,
16157 				      len, WMI_ROAM_AP_PROFILE);
16158 	if (QDF_IS_STATUS_ERROR(status)) {
16159 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d",
16160 			status);
16161 		wmi_buf_free(buf);
16162 	}
16163 
16164 	WMI_LOGI("WMI --> WMI_ROAM_AP_PROFILE and other parameters");
16165 
16166 	return status;
16167 }
16168 
16169 /**
16170  * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period
16171  * @wmi_handle: wmi handle
16172  * @scan_period: scan period
16173  * @scan_age: scan age
16174  * @vdev_id: vdev id
16175  *
16176  * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
16177  *
16178  * Return: CDF status
16179  */
16180 static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle,
16181 					     uint32_t scan_period,
16182 					     uint32_t scan_age,
16183 					     uint32_t vdev_id)
16184 {
16185 	QDF_STATUS status;
16186 	wmi_buf_t buf = NULL;
16187 	int len;
16188 	uint8_t *buf_ptr;
16189 	wmi_roam_scan_period_fixed_param *scan_period_fp;
16190 
16191 	/* Send scan period values */
16192 	len = sizeof(wmi_roam_scan_period_fixed_param);
16193 	buf = wmi_buf_alloc(wmi_handle, len);
16194 	if (!buf) {
16195 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16196 		return QDF_STATUS_E_NOMEM;
16197 	}
16198 
16199 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16200 	scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr;
16201 	WMITLV_SET_HDR(&scan_period_fp->tlv_header,
16202 		       WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param,
16203 		       WMITLV_GET_STRUCT_TLVLEN
16204 			       (wmi_roam_scan_period_fixed_param));
16205 	/* fill in scan period values */
16206 	scan_period_fp->vdev_id = vdev_id;
16207 	scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */
16208 	scan_period_fp->roam_scan_age = scan_age;
16209 
16210 	status = wmi_unified_cmd_send(wmi_handle, buf,
16211 				      len, WMI_ROAM_SCAN_PERIOD);
16212 	if (QDF_IS_STATUS_ERROR(status)) {
16213 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d",
16214 			status);
16215 		goto error;
16216 	}
16217 
16218 	WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d",
16219 		__func__, scan_period, scan_age);
16220 	return QDF_STATUS_SUCCESS;
16221 error:
16222 	wmi_buf_free(buf);
16223 
16224 	return status;
16225 }
16226 
16227 /**
16228  * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list
16229  * @wmi_handle: wmi handle
16230  * @chan_count: channel count
16231  * @chan_list: channel list
16232  * @list_type: list type
16233  * @vdev_id: vdev id
16234  *
16235  * Set roam offload channel list.
16236  *
16237  * Return: CDF status
16238  */
16239 static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
16240 				   uint8_t chan_count,
16241 				   uint32_t *chan_list,
16242 				   uint8_t list_type, uint32_t vdev_id)
16243 {
16244 	wmi_buf_t buf = NULL;
16245 	QDF_STATUS status;
16246 	int len, list_tlv_len;
16247 	int i;
16248 	uint8_t *buf_ptr;
16249 	wmi_roam_chan_list_fixed_param *chan_list_fp;
16250 	A_UINT32 *roam_chan_list_array;
16251 
16252 	if (chan_count == 0) {
16253 		WMI_LOGD("%s : invalid number of channels %d", __func__,
16254 			 chan_count);
16255 		return QDF_STATUS_E_EMPTY;
16256 	}
16257 	/* Channel list is a table of 2 TLV's */
16258 	list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(A_UINT32);
16259 	len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len;
16260 	buf = wmi_buf_alloc(wmi_handle, len);
16261 	if (!buf) {
16262 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16263 		return QDF_STATUS_E_NOMEM;
16264 	}
16265 
16266 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16267 	chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr;
16268 	WMITLV_SET_HDR(&chan_list_fp->tlv_header,
16269 		       WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param,
16270 		       WMITLV_GET_STRUCT_TLVLEN
16271 			       (wmi_roam_chan_list_fixed_param));
16272 	chan_list_fp->vdev_id = vdev_id;
16273 	chan_list_fp->num_chan = chan_count;
16274 	if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) {
16275 		/* external app is controlling channel list */
16276 		chan_list_fp->chan_list_type =
16277 			WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC;
16278 	} else {
16279 		/* umac supplied occupied channel list in LFR */
16280 		chan_list_fp->chan_list_type =
16281 			WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC;
16282 	}
16283 
16284 	buf_ptr += sizeof(wmi_roam_chan_list_fixed_param);
16285 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
16286 		       (chan_list_fp->num_chan * sizeof(uint32_t)));
16287 	roam_chan_list_array = (A_UINT32 *) (buf_ptr + WMI_TLV_HDR_SIZE);
16288 	WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan);
16289 	for (i = 0; ((i < chan_list_fp->num_chan) &&
16290 		     (i < WMI_ROAM_MAX_CHANNELS)); i++) {
16291 		roam_chan_list_array[i] = chan_list[i];
16292 		WMI_LOGI("%d,", roam_chan_list_array[i]);
16293 	}
16294 
16295 	status = wmi_unified_cmd_send(wmi_handle, buf,
16296 				      len, WMI_ROAM_CHAN_LIST);
16297 	if (QDF_IS_STATUS_ERROR(status)) {
16298 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d",
16299 			status);
16300 		goto error;
16301 	}
16302 
16303 	WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__);
16304 	return QDF_STATUS_SUCCESS;
16305 error:
16306 	wmi_buf_free(buf);
16307 
16308 	return status;
16309 }
16310 
16311 /**
16312  * send_per_roam_config_cmd_tlv() - set per roaming config to FW
16313  * @wmi_handle: wmi handle
16314  * @req_buf: per roam config buffer
16315  *
16316  * Return: QDF status
16317  */
16318 static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle,
16319 		struct wmi_per_roam_config_req *req_buf)
16320 {
16321 	wmi_buf_t buf = NULL;
16322 	QDF_STATUS status;
16323 	int len;
16324 	uint8_t *buf_ptr;
16325 	wmi_roam_per_config_fixed_param *wmi_per_config;
16326 
16327 	len = sizeof(wmi_roam_per_config_fixed_param);
16328 	buf = wmi_buf_alloc(wmi_handle, len);
16329 	if (!buf) {
16330 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16331 		return QDF_STATUS_E_NOMEM;
16332 	}
16333 
16334 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16335 	wmi_per_config =
16336 		(wmi_roam_per_config_fixed_param *) buf_ptr;
16337 	WMITLV_SET_HDR(&wmi_per_config->tlv_header,
16338 			WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param,
16339 			WMITLV_GET_STRUCT_TLVLEN
16340 			(wmi_roam_per_config_fixed_param));
16341 
16342 	/* fill in per roam config values */
16343 	wmi_per_config->vdev_id = req_buf->vdev_id;
16344 
16345 	wmi_per_config->enable = req_buf->per_config.enable;
16346 	wmi_per_config->high_rate_thresh =
16347 		(req_buf->per_config.tx_high_rate_thresh << 16) |
16348 		(req_buf->per_config.rx_high_rate_thresh & 0x0000ffff);
16349 	wmi_per_config->low_rate_thresh =
16350 		(req_buf->per_config.tx_low_rate_thresh << 16) |
16351 		(req_buf->per_config.rx_low_rate_thresh & 0x0000ffff);
16352 	wmi_per_config->pkt_err_rate_thresh_pct =
16353 		(req_buf->per_config.tx_rate_thresh_percnt << 16) |
16354 		(req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff);
16355 	wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time;
16356 	wmi_per_config->pkt_err_rate_mon_time =
16357 			(req_buf->per_config.tx_per_mon_time << 16) |
16358 			(req_buf->per_config.rx_per_mon_time & 0x0000ffff);
16359 	wmi_per_config->min_candidate_rssi =
16360 			req_buf->per_config.min_candidate_rssi;
16361 
16362 	/* Send per roam config parameters */
16363 	status = wmi_unified_cmd_send(wmi_handle, buf,
16364 			len, WMI_ROAM_PER_CONFIG_CMDID);
16365 	if (QDF_IS_STATUS_ERROR(status)) {
16366 		WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d",
16367 				status);
16368 		wmi_buf_free(buf);
16369 		return status;
16370 	}
16371 
16372 	WMI_LOGI(FL("per roam enable=%d, vdev=%d"),
16373 			req_buf->per_config.enable, req_buf->vdev_id);
16374 	return QDF_STATUS_SUCCESS;
16375 }
16376 
16377 /**
16378  * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th
16379  * @wmi_handle: wmi handle
16380  * @rssi_change_thresh: RSSI Change threshold
16381  * @bcn_rssi_weight: beacon RSSI weight
16382  * @vdev_id: vdev id
16383  *
16384  * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
16385  *
16386  * Return: CDF status
16387  */
16388 static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle,
16389 	uint32_t vdev_id,
16390 	int32_t rssi_change_thresh,
16391 	uint32_t bcn_rssi_weight,
16392 	uint32_t hirssi_delay_btw_scans)
16393 {
16394 	wmi_buf_t buf = NULL;
16395 	QDF_STATUS status;
16396 	int len;
16397 	uint8_t *buf_ptr;
16398 	wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp;
16399 
16400 	/* Send rssi change parameters */
16401 	len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param);
16402 	buf = wmi_buf_alloc(wmi_handle, len);
16403 	if (!buf) {
16404 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16405 		return QDF_STATUS_E_NOMEM;
16406 	}
16407 
16408 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16409 	rssi_change_fp =
16410 		(wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr;
16411 	WMITLV_SET_HDR(&rssi_change_fp->tlv_header,
16412 		       WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param,
16413 		       WMITLV_GET_STRUCT_TLVLEN
16414 			       (wmi_roam_scan_rssi_change_threshold_fixed_param));
16415 	/* fill in rssi change threshold (hysteresis) values */
16416 	rssi_change_fp->vdev_id = vdev_id;
16417 	rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh;
16418 	rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight;
16419 	rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans;
16420 
16421 	status = wmi_unified_cmd_send(wmi_handle, buf,
16422 				      len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD);
16423 	if (QDF_IS_STATUS_ERROR(status)) {
16424 		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d",
16425 			status);
16426 		goto error;
16427 	}
16428 
16429 	WMI_LOGI(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"),
16430 		rssi_change_thresh, bcn_rssi_weight);
16431 	WMI_LOGI(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans);
16432 	return QDF_STATUS_SUCCESS;
16433 error:
16434 	wmi_buf_free(buf);
16435 
16436 	return status;
16437 }
16438 
16439 /** wmi_get_hotlist_entries_per_page() - hotlist entries per page
16440  * @wmi_handle: wmi handle.
16441  * @cmd: size of command structure.
16442  * @per_entry_size: per entry size.
16443  *
16444  * This utility function calculates how many hotlist entries can
16445  * fit in one page.
16446  *
16447  * Return: number of entries
16448  */
16449 static inline int wmi_get_hotlist_entries_per_page(wmi_unified_t wmi_handle,
16450 						   size_t cmd_size,
16451 						   size_t per_entry_size)
16452 {
16453 	uint32_t avail_space = 0;
16454 	int num_entries = 0;
16455 	uint16_t max_msg_len = wmi_get_max_msg_len(wmi_handle);
16456 
16457 	/* Calculate number of hotlist entries that can
16458 	 * be passed in wma message request.
16459 	 */
16460 	avail_space = max_msg_len - cmd_size;
16461 	num_entries = avail_space / per_entry_size;
16462 	return num_entries;
16463 }
16464 
16465 /**
16466  * send_get_buf_extscan_hotlist_cmd_tlv() - prepare hotlist command
16467  * @wmi_handle: wmi handle
16468  * @photlist: hotlist command params
16469  * @buf_len: buffer length
16470  *
16471  * This function fills individual elements for  hotlist request and
16472  * TLV for bssid entries
16473  *
16474  * Return: CDF Status.
16475  */
16476 static QDF_STATUS send_get_buf_extscan_hotlist_cmd_tlv(wmi_unified_t wmi_handle,
16477 					   struct ext_scan_setbssi_hotlist_params *
16478 					   photlist, int *buf_len)
16479 {
16480 	wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd = NULL;
16481 	wmi_extscan_hotlist_entry *dest_hotlist;
16482 	struct ap_threshold_params *src_ap = photlist->ap;
16483 	wmi_buf_t buf;
16484 	uint8_t *buf_ptr;
16485 
16486 	int j, index = 0;
16487 	int cmd_len = 0;
16488 	int num_entries;
16489 	int min_entries = 0;
16490 	uint32_t numap = photlist->numAp;
16491 	int len = sizeof(*cmd);
16492 
16493 	len += WMI_TLV_HDR_SIZE;
16494 	cmd_len = len;
16495 
16496 	num_entries = wmi_get_hotlist_entries_per_page(wmi_handle,
16497 							cmd_len,
16498 							sizeof(*dest_hotlist));
16499 	/* setbssid hotlist expects the bssid list
16500 	 * to be non zero value
16501 	 */
16502 	if (!numap || (numap > WMI_WLAN_EXTSCAN_MAX_HOTLIST_APS)) {
16503 		WMI_LOGE("Invalid number of APs: %d", numap);
16504 		return QDF_STATUS_E_INVAL;
16505 	}
16506 
16507 	/* Split the hot list entry pages and send multiple command
16508 	 * requests if the buffer reaches the maximum request size
16509 	 */
16510 	while (index < numap) {
16511 		min_entries = QDF_MIN(num_entries, numap);
16512 		len += min_entries * sizeof(wmi_extscan_hotlist_entry);
16513 		buf = wmi_buf_alloc(wmi_handle, len);
16514 		if (!buf) {
16515 			WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
16516 			return QDF_STATUS_E_FAILURE;
16517 		}
16518 		buf_ptr = (uint8_t *) wmi_buf_data(buf);
16519 		cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *)
16520 		      buf_ptr;
16521 		WMITLV_SET_HDR(&cmd->tlv_header,
16522 			       WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param,
16523 			       WMITLV_GET_STRUCT_TLVLEN
16524 				       (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param));
16525 
16526 		/* Multiple requests are sent until the num_entries_in_page
16527 		 * matches the total_entries
16528 		 */
16529 		cmd->request_id = photlist->requestId;
16530 		cmd->vdev_id = photlist->sessionId;
16531 		cmd->total_entries = numap;
16532 		cmd->mode = 1;
16533 		cmd->num_entries_in_page = min_entries;
16534 		cmd->lost_ap_scan_count = photlist->lost_ap_sample_size;
16535 		cmd->first_entry_index = index;
16536 
16537 		WMI_LOGD("%s: vdev id:%d total_entries: %d num_entries: %d lost_ap_sample_size: %d",
16538 			__func__, cmd->vdev_id, cmd->total_entries,
16539 			cmd->num_entries_in_page,
16540 			cmd->lost_ap_scan_count);
16541 
16542 		buf_ptr += sizeof(*cmd);
16543 		WMITLV_SET_HDR(buf_ptr,
16544 			       WMITLV_TAG_ARRAY_STRUC,
16545 			       min_entries * sizeof(wmi_extscan_hotlist_entry));
16546 		dest_hotlist = (wmi_extscan_hotlist_entry *)
16547 			       (buf_ptr + WMI_TLV_HDR_SIZE);
16548 
16549 		/* Populate bssid, channel info and rssi
16550 		 * for the bssid's that are sent as hotlists.
16551 		 */
16552 		for (j = 0; j < min_entries; j++) {
16553 			WMITLV_SET_HDR(dest_hotlist,
16554 				       WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param,
16555 				       WMITLV_GET_STRUCT_TLVLEN
16556 					       (wmi_extscan_hotlist_entry));
16557 
16558 			dest_hotlist->min_rssi = src_ap->low;
16559 			WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes,
16560 						   &dest_hotlist->bssid);
16561 
16562 			WMI_LOGD("%s:channel:%d min_rssi %d",
16563 				 __func__, dest_hotlist->channel,
16564 				 dest_hotlist->min_rssi);
16565 			WMI_LOGD
16566 				("%s: bssid mac_addr31to0: 0x%x, mac_addr47to32: 0x%x",
16567 				__func__, dest_hotlist->bssid.mac_addr31to0,
16568 				dest_hotlist->bssid.mac_addr47to32);
16569 			dest_hotlist++;
16570 			src_ap++;
16571 		}
16572 		buf_ptr += WMI_TLV_HDR_SIZE +
16573 			   (min_entries * sizeof(wmi_extscan_hotlist_entry));
16574 
16575 		if (wmi_unified_cmd_send(wmi_handle, buf, len,
16576 					 WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) {
16577 			WMI_LOGE("%s: failed to send command", __func__);
16578 			wmi_buf_free(buf);
16579 			return QDF_STATUS_E_FAILURE;
16580 		}
16581 		index = index + min_entries;
16582 		num_entries = numap - min_entries;
16583 		len = cmd_len;
16584 	}
16585 	return QDF_STATUS_SUCCESS;
16586 }
16587 
16588 /**
16589  * send_set_active_bpf_mode_cmd_tlv() - configure active BPF mode in FW
16590  * @wmi_handle: the WMI handle
16591  * @vdev_id: the Id of the vdev to apply the configuration to
16592  * @ucast_mode: the active BPF mode to configure for unicast packets
16593  * @mcast_bcast_mode: the active BPF mode to configure for multicast/broadcast
16594  *	packets
16595  *
16596  * Return: QDF status
16597  */
16598 static QDF_STATUS send_set_active_bpf_mode_cmd_tlv(wmi_unified_t wmi_handle,
16599 				uint8_t vdev_id,
16600 				enum wmi_host_active_bpf_mode ucast_mode,
16601 				enum wmi_host_active_bpf_mode mcast_bcast_mode)
16602 {
16603 	const WMITLV_TAG_ID tag_id =
16604 		WMITLV_TAG_STRUC_wmi_bpf_set_vdev_active_mode_cmd_fixed_param;
16605 	const uint32_t tlv_len = WMITLV_GET_STRUCT_TLVLEN(
16606 				wmi_bpf_set_vdev_active_mode_cmd_fixed_param);
16607 	QDF_STATUS status;
16608 	wmi_bpf_set_vdev_active_mode_cmd_fixed_param *cmd;
16609 	wmi_buf_t buf;
16610 
16611 	WMI_LOGD("Sending WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID(%u, %d, %d)",
16612 		 vdev_id, ucast_mode, mcast_bcast_mode);
16613 
16614 	/* allocate command buffer */
16615 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
16616 	if (!buf) {
16617 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
16618 		return QDF_STATUS_E_NOMEM;
16619 	}
16620 
16621 	/* set TLV header */
16622 	cmd = (wmi_bpf_set_vdev_active_mode_cmd_fixed_param *)wmi_buf_data(buf);
16623 	WMITLV_SET_HDR(&cmd->tlv_header, tag_id, tlv_len);
16624 
16625 	/* populate data */
16626 	cmd->vdev_id = vdev_id;
16627 	cmd->uc_mode = ucast_mode;
16628 	cmd->mcbc_mode = mcast_bcast_mode;
16629 
16630 	/* send to FW */
16631 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
16632 				      WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID);
16633 	if (QDF_IS_STATUS_ERROR(status)) {
16634 		WMI_LOGE("Failed to send WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID:%d",
16635 			 status);
16636 		wmi_buf_free(buf);
16637 		return status;
16638 	}
16639 
16640 	WMI_LOGD("Sent WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID successfully");
16641 
16642 	return QDF_STATUS_SUCCESS;
16643 }
16644 
16645 /**
16646  * send_power_dbg_cmd_tlv() - send power debug commands
16647  * @wmi_handle: wmi handle
16648  * @param: wmi power debug parameter
16649  *
16650  * Send WMI_POWER_DEBUG_CMDID parameters to fw.
16651  *
16652  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16653  */
16654 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle,
16655 					 struct wmi_power_dbg_params *param)
16656 {
16657 	wmi_buf_t buf = NULL;
16658 	QDF_STATUS status;
16659 	int len, args_tlv_len;
16660 	uint8_t *buf_ptr;
16661 	uint8_t i;
16662 	wmi_pdev_wal_power_debug_cmd_fixed_param *cmd;
16663 	uint32_t *cmd_args;
16664 
16665 	/* Prepare and send power debug cmd parameters */
16666 	args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t);
16667 	len = sizeof(*cmd) + args_tlv_len;
16668 	buf = wmi_buf_alloc(wmi_handle, len);
16669 	if (!buf) {
16670 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16671 		return QDF_STATUS_E_NOMEM;
16672 	}
16673 
16674 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16675 	cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr;
16676 	WMITLV_SET_HDR(&cmd->tlv_header,
16677 		  WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param,
16678 		  WMITLV_GET_STRUCT_TLVLEN
16679 		  (wmi_pdev_wal_power_debug_cmd_fixed_param));
16680 
16681 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
16682 								param->pdev_id);
16683 	cmd->module_id = param->module_id;
16684 	cmd->num_args = param->num_args;
16685 	buf_ptr += sizeof(*cmd);
16686 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
16687 		       (param->num_args * sizeof(uint32_t)));
16688 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
16689 	WMI_LOGI("%s: %d num of args = ", __func__, param->num_args);
16690 	for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) {
16691 		cmd_args[i] = param->args[i];
16692 		WMI_LOGI("%d,", param->args[i]);
16693 	}
16694 
16695 	status = wmi_unified_cmd_send(wmi_handle, buf,
16696 				      len, WMI_PDEV_WAL_POWER_DEBUG_CMDID);
16697 	if (QDF_IS_STATUS_ERROR(status)) {
16698 		WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d",
16699 			status);
16700 		goto error;
16701 	}
16702 
16703 	return QDF_STATUS_SUCCESS;
16704 error:
16705 	wmi_buf_free(buf);
16706 
16707 	return status;
16708 }
16709 
16710 /**
16711  * send_multiple_vdev_restart_req_cmd_tlv() - send multiple vdev restart req
16712  * @wmi_handle: wmi handle
16713  * @param: wmi multiple vdev restart req param
16714  *
16715  * Send WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID parameters to fw.
16716  *
16717  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16718  */
16719 static QDF_STATUS send_multiple_vdev_restart_req_cmd_tlv(
16720 				wmi_unified_t wmi_handle,
16721 				struct multiple_vdev_restart_params *param)
16722 {
16723 	wmi_buf_t buf;
16724 	QDF_STATUS qdf_status;
16725 	wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *cmd;
16726 	int i;
16727 	uint8_t *buf_ptr;
16728 	uint32_t *vdev_ids;
16729 	wmi_channel *chan_info;
16730 	struct channel_param *tchan_info;
16731 	uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
16732 
16733 	len += sizeof(wmi_channel);
16734 	if (param->num_vdevs)
16735 		len += sizeof(uint32_t) * param->num_vdevs;
16736 
16737 	buf = wmi_buf_alloc(wmi_handle, len);
16738 	if (!buf) {
16739 		WMI_LOGE("Failed to allocate memory\n");
16740 		qdf_status = QDF_STATUS_E_NOMEM;
16741 		goto end;
16742 	}
16743 
16744 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
16745 	cmd = (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *)
16746 	       buf_ptr;
16747 
16748 	WMITLV_SET_HDR(&cmd->tlv_header,
16749 	WMITLV_TAG_STRUC_wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param,
16750 	WMITLV_GET_STRUCT_TLVLEN
16751 		(wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param));
16752 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
16753 								param->pdev_id);
16754 	cmd->requestor_id = param->requestor_id;
16755 	cmd->disable_hw_ack = param->disable_hw_ack;
16756 	cmd->cac_duration_ms = param->cac_duration_ms;
16757 	cmd->num_vdevs = param->num_vdevs;
16758 
16759 	WMI_LOGI("%s:cmd->pdev_id: %d ,cmd->requestor_id: %d ,"
16760 		"cmd->disable_hw_ack: %d , cmd->cac_duration_ms:%d ,"
16761 		" cmd->num_vdevs: %d ",
16762 		__func__, cmd->pdev_id, cmd->requestor_id,
16763 		cmd->disable_hw_ack, cmd->cac_duration_ms, cmd->num_vdevs);
16764 	buf_ptr += sizeof(*cmd);
16765 
16766 	WMITLV_SET_HDR(buf_ptr,
16767 		       WMITLV_TAG_ARRAY_UINT32,
16768 		       sizeof(A_UINT32) * param->num_vdevs);
16769 	vdev_ids = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
16770 	for (i = 0; i < param->num_vdevs; i++) {
16771 		vdev_ids[i] = param->vdev_ids[i];
16772 	}
16773 
16774 	buf_ptr += (sizeof(A_UINT32) * param->num_vdevs) + WMI_TLV_HDR_SIZE;
16775 
16776 	WMITLV_SET_HDR(buf_ptr,
16777 		       WMITLV_TAG_STRUC_wmi_channel,
16778 		       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
16779 	chan_info = (wmi_channel *)buf_ptr;
16780 	tchan_info = &(param->ch_param);
16781 	chan_info->mhz = tchan_info->mhz;
16782 	chan_info->band_center_freq1 = tchan_info->cfreq1;
16783 	chan_info->band_center_freq2 = tchan_info->cfreq2;
16784 	if (tchan_info->is_chan_passive)
16785 		WMI_SET_CHANNEL_FLAG(chan_info,
16786 				     WMI_CHAN_FLAG_PASSIVE);
16787 	if (tchan_info->dfs_set)
16788 		WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS);
16789 
16790 	if (tchan_info->allow_vht)
16791 		WMI_SET_CHANNEL_FLAG(chan_info,
16792 				     WMI_CHAN_FLAG_ALLOW_VHT);
16793 	else  if (tchan_info->allow_ht)
16794 		WMI_SET_CHANNEL_FLAG(chan_info,
16795 				     WMI_CHAN_FLAG_ALLOW_HT);
16796 	WMI_SET_CHANNEL_MODE(chan_info, tchan_info->phy_mode);
16797 	WMI_SET_CHANNEL_MIN_POWER(chan_info, tchan_info->minpower);
16798 	WMI_SET_CHANNEL_MAX_POWER(chan_info, tchan_info->maxpower);
16799 	WMI_SET_CHANNEL_REG_POWER(chan_info, tchan_info->maxregpower);
16800 	WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, tchan_info->antennamax);
16801 	WMI_SET_CHANNEL_REG_CLASSID(chan_info, tchan_info->reg_class_id);
16802 	WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, tchan_info->maxregpower);
16803 
16804 	WMI_LOGI("%s:tchan_info->is_chan_passive: %d ,"
16805 		"tchan_info->dfs_set : %d ,tchan_info->allow_vht:%d ,"
16806 		"tchan_info->allow_ht: %d ,tchan_info->antennamax: %d ,"
16807 		"tchan_info->phy_mode: %d ,tchan_info->minpower: %d,"
16808 		"tchan_info->maxpower: %d ,tchan_info->maxregpower: %d ,"
16809 		"tchan_info->reg_class_id: %d ,"
16810 		"tchan_info->maxregpower : %d ", __func__,
16811 		tchan_info->is_chan_passive, tchan_info->dfs_set,
16812 		tchan_info->allow_vht, tchan_info->allow_ht,
16813 		tchan_info->antennamax, tchan_info->phy_mode,
16814 		tchan_info->minpower, tchan_info->maxpower,
16815 		tchan_info->maxregpower, tchan_info->reg_class_id,
16816 		tchan_info->maxregpower);
16817 
16818 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
16819 				WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID);
16820 
16821 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
16822 		WMI_LOGE("%s: Failed to send\n", __func__);
16823 		wmi_buf_free(buf);
16824 	}
16825 
16826 end:
16827 	return qdf_status;
16828 }
16829 
16830 /**
16831  * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd
16832  * @wmi_handle: wmi handle
16833  * @pdev_id: pdev id
16834  *
16835  * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware.
16836  *
16837  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16838  */
16839 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle,
16840 		uint32_t pdev_id)
16841 {
16842 	wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd;
16843 	wmi_buf_t buf;
16844 	uint16_t len;
16845 	QDF_STATUS ret;
16846 
16847 	len = sizeof(*cmd);
16848 	buf = wmi_buf_alloc(wmi_handle, len);
16849 
16850 	WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id);
16851 
16852 	if (!buf) {
16853 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16854 		return QDF_STATUS_E_NOMEM;
16855 	}
16856 
16857 	cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *)
16858 		wmi_buf_data(buf);
16859 
16860 	WMITLV_SET_HDR(&cmd->tlv_header,
16861 	WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param,
16862 	WMITLV_GET_STRUCT_TLVLEN(
16863 		wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param));
16864 
16865 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
16866 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
16867 			WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID);
16868 	if (QDF_IS_STATUS_ERROR(ret)) {
16869 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d",
16870 			__func__, ret, pdev_id);
16871 		wmi_buf_free(buf);
16872 		return QDF_STATUS_E_FAILURE;
16873 	}
16874 
16875 	return QDF_STATUS_SUCCESS;
16876 }
16877 
16878 /**
16879  * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd
16880  * @wmi_handle: wmi handle
16881  * @pdev_id: pdev id
16882  *
16883  * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware.
16884  *
16885  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
16886  */
16887 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle,
16888 		uint32_t pdev_id)
16889 {
16890 	wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd;
16891 	wmi_buf_t buf;
16892 	uint16_t len;
16893 	QDF_STATUS ret;
16894 
16895 	len = sizeof(*cmd);
16896 	buf = wmi_buf_alloc(wmi_handle, len);
16897 
16898 	WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id);
16899 
16900 	if (!buf) {
16901 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
16902 		return QDF_STATUS_E_NOMEM;
16903 	}
16904 
16905 	cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *)
16906 		wmi_buf_data(buf);
16907 
16908 	WMITLV_SET_HDR(&cmd->tlv_header,
16909 	WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param,
16910 	WMITLV_GET_STRUCT_TLVLEN(
16911 		wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param));
16912 
16913 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
16914 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
16915 			WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID);
16916 	if (QDF_IS_STATUS_ERROR(ret)) {
16917 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d",
16918 			__func__, ret, pdev_id);
16919 		wmi_buf_free(buf);
16920 		return QDF_STATUS_E_FAILURE;
16921 	}
16922 
16923 	return QDF_STATUS_SUCCESS;
16924 }
16925 
16926 /**
16927  * init_cmd_send_tlv() - send initialization cmd to fw
16928  * @wmi_handle: wmi handle
16929  * @param param: pointer to wmi init param
16930  *
16931  * Return: QDF_STATUS_SUCCESS for success or error code
16932  */
16933 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle,
16934 				struct wmi_init_cmd_param *param)
16935 {
16936 	wmi_buf_t buf;
16937 	wmi_init_cmd_fixed_param *cmd;
16938 	uint8_t *buf_ptr;
16939 	wmi_resource_config *resource_cfg;
16940 	wlan_host_memory_chunk *host_mem_chunks;
16941 	uint32_t mem_chunk_len = 0, hw_mode_len = 0;
16942 	uint16_t idx;
16943 	int len;
16944 	QDF_STATUS ret;
16945 
16946 	len = sizeof(*cmd) + sizeof(wmi_resource_config) +
16947 		WMI_TLV_HDR_SIZE;
16948 	mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS);
16949 
16950 	if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX)
16951 		hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) +
16952 			WMI_TLV_HDR_SIZE +
16953 			(param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac));
16954 
16955 	buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len);
16956 	if (!buf) {
16957 		qdf_print("%s: wmi_buf_alloc failed\n", __func__);
16958 		return QDF_STATUS_E_FAILURE;
16959 	}
16960 
16961 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
16962 	cmd = (wmi_init_cmd_fixed_param *) buf_ptr;
16963 	resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd));
16964 
16965 	host_mem_chunks = (wlan_host_memory_chunk *)
16966 		(buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)
16967 		 + WMI_TLV_HDR_SIZE);
16968 
16969 	WMITLV_SET_HDR(&cmd->tlv_header,
16970 			WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param,
16971 			WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param));
16972 
16973 	wmi_copy_resource_config(resource_cfg, param->res_cfg);
16974 	WMITLV_SET_HDR(&resource_cfg->tlv_header,
16975 			WMITLV_TAG_STRUC_wmi_resource_config,
16976 			WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config));
16977 
16978 	for (idx = 0; idx < param->num_mem_chunks; ++idx) {
16979 		WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header),
16980 				WMITLV_TAG_STRUC_wlan_host_memory_chunk,
16981 				WMITLV_GET_STRUCT_TLVLEN
16982 				(wlan_host_memory_chunk));
16983 		host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr;
16984 		host_mem_chunks[idx].size = param->mem_chunks[idx].len;
16985 		host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id;
16986 		QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG,
16987 				"chunk %d len %d requested ,ptr  0x%x ",
16988 				idx, host_mem_chunks[idx].size,
16989 				host_mem_chunks[idx].ptr);
16990 	}
16991 	cmd->num_host_mem_chunks = param->num_mem_chunks;
16992 	len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk));
16993 
16994 	WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)),
16995 			WMITLV_TAG_ARRAY_STRUC,
16996 			(sizeof(wlan_host_memory_chunk) *
16997 			 param->num_mem_chunks));
16998 
16999 	/* Fill hw mode id config */
17000 	buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param);
17001 
17002 	/* Fill fw_abi_vers */
17003 	copy_fw_abi_version_tlv(wmi_handle, cmd);
17004 
17005 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID);
17006 	if (QDF_IS_STATUS_ERROR(ret)) {
17007 		WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d",
17008 			ret);
17009 		wmi_buf_free(buf);
17010 	}
17011 
17012 	return ret;
17013 
17014 }
17015 
17016 /**
17017  * send_addba_send_cmd_tlv() - send addba send command to fw
17018  * @wmi_handle: wmi handle
17019  * @param: pointer to delba send params
17020  * @macaddr: peer mac address
17021  *
17022  * Send WMI_ADDBA_SEND_CMDID command to firmware
17023  * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error
17024  */
17025 static QDF_STATUS
17026 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle,
17027 				uint8_t macaddr[IEEE80211_ADDR_LEN],
17028 				struct addba_send_params *param)
17029 {
17030 	wmi_addba_send_cmd_fixed_param *cmd;
17031 	wmi_buf_t buf;
17032 	uint16_t len;
17033 	QDF_STATUS ret;
17034 
17035 	len = sizeof(*cmd);
17036 
17037 	buf = wmi_buf_alloc(wmi_handle, len);
17038 	if (!buf) {
17039 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
17040 		return QDF_STATUS_E_NOMEM;
17041 	}
17042 
17043 	cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf);
17044 
17045 	WMITLV_SET_HDR(&cmd->tlv_header,
17046 			WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param,
17047 			WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param));
17048 
17049 	cmd->vdev_id = param->vdev_id;
17050 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
17051 	cmd->tid = param->tidno;
17052 	cmd->buffersize = param->buffersize;
17053 
17054 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID);
17055 	if (QDF_IS_STATUS_ERROR(ret)) {
17056 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret);
17057 		wmi_buf_free(buf);
17058 		return QDF_STATUS_E_FAILURE;
17059 	}
17060 
17061 	return QDF_STATUS_SUCCESS;
17062 }
17063 
17064 /**
17065  * send_delba_send_cmd_tlv() - send delba send command to fw
17066  * @wmi_handle: wmi handle
17067  * @param: pointer to delba send params
17068  * @macaddr: peer mac address
17069  *
17070  * Send WMI_DELBA_SEND_CMDID command to firmware
17071  * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error
17072  */
17073 static QDF_STATUS
17074 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle,
17075 				uint8_t macaddr[IEEE80211_ADDR_LEN],
17076 				struct delba_send_params *param)
17077 {
17078 	wmi_delba_send_cmd_fixed_param *cmd;
17079 	wmi_buf_t buf;
17080 	uint16_t len;
17081 	QDF_STATUS ret;
17082 
17083 	len = sizeof(*cmd);
17084 
17085 	buf = wmi_buf_alloc(wmi_handle, len);
17086 	if (!buf) {
17087 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
17088 		return QDF_STATUS_E_NOMEM;
17089 	}
17090 
17091 	cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf);
17092 
17093 	WMITLV_SET_HDR(&cmd->tlv_header,
17094 			WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param,
17095 			WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param));
17096 
17097 	cmd->vdev_id = param->vdev_id;
17098 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
17099 	cmd->tid = param->tidno;
17100 	cmd->initiator = param->initiator;
17101 	cmd->reasoncode = param->reasoncode;
17102 
17103 	ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID);
17104 	if (QDF_IS_STATUS_ERROR(ret)) {
17105 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret);
17106 		wmi_buf_free(buf);
17107 		return QDF_STATUS_E_FAILURE;
17108 	}
17109 
17110 	return QDF_STATUS_SUCCESS;
17111 }
17112 
17113 /**
17114  * send_addba_clearresponse_cmd_tlv() - send addba clear response command
17115  * to fw
17116  * @wmi_handle: wmi handle
17117  * @param: pointer to addba clearresp params
17118  * @macaddr: peer mac address
17119  * Return: 0 for success or error code
17120  */
17121 static QDF_STATUS
17122 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle,
17123 			uint8_t macaddr[IEEE80211_ADDR_LEN],
17124 			struct addba_clearresponse_params *param)
17125 {
17126 	wmi_addba_clear_resp_cmd_fixed_param *cmd;
17127 	wmi_buf_t buf;
17128 	uint16_t len;
17129 	QDF_STATUS ret;
17130 
17131 	len = sizeof(*cmd);
17132 
17133 	buf = wmi_buf_alloc(wmi_handle, len);
17134 	if (!buf) {
17135 		WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__);
17136 		return QDF_STATUS_E_FAILURE;
17137 	}
17138 	cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf);
17139 
17140 	WMITLV_SET_HDR(&cmd->tlv_header,
17141 		WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param,
17142 		WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param));
17143 
17144 	cmd->vdev_id = param->vdev_id;
17145 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
17146 
17147 	ret = wmi_unified_cmd_send(wmi_handle,
17148 				buf, len, WMI_ADDBA_CLEAR_RESP_CMDID);
17149 	if (QDF_IS_STATUS_ERROR(ret)) {
17150 		WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret);
17151 		wmi_buf_free(buf);
17152 		return QDF_STATUS_E_FAILURE;
17153 	}
17154 
17155 	return QDF_STATUS_SUCCESS;
17156 }
17157 
17158 /**
17159  * send_bcn_offload_control_cmd_tlv - send beacon ofload control cmd to fw
17160  * @wmi_handle: wmi handle
17161  * @bcn_ctrl_param: pointer to bcn_offload_control param
17162  *
17163  * Return: QDF_STATUS_SUCCESS for success or error code
17164  */
17165 static
17166 QDF_STATUS send_bcn_offload_control_cmd_tlv(wmi_unified_t wmi_handle,
17167 			struct bcn_offload_control *bcn_ctrl_param)
17168 {
17169 	wmi_buf_t buf;
17170 	wmi_bcn_offload_ctrl_cmd_fixed_param *cmd;
17171 	QDF_STATUS ret;
17172 	uint32_t len;
17173 
17174 	len = sizeof(*cmd);
17175 
17176 	buf = wmi_buf_alloc(wmi_handle, len);
17177 	if (!buf) {
17178 		qdf_print("%s: wmi_buf_alloc failed\n", __func__);
17179 		return QDF_STATUS_E_FAILURE;
17180 	}
17181 
17182 	cmd = (wmi_bcn_offload_ctrl_cmd_fixed_param *) wmi_buf_data(buf);
17183 	WMITLV_SET_HDR(&cmd->tlv_header,
17184 			WMITLV_TAG_STRUC_wmi_bcn_offload_ctrl_cmd_fixed_param,
17185 			WMITLV_GET_STRUCT_TLVLEN
17186 			(wmi_bcn_offload_ctrl_cmd_fixed_param));
17187 	cmd->vdev_id = bcn_ctrl_param->vdev_id;
17188 	if (bcn_ctrl_param->bcn_tx_enable)
17189 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_ENABLE;
17190 	else
17191 		cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_DISABLE;
17192 
17193 
17194 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
17195 			WMI_BCN_OFFLOAD_CTRL_CMDID);
17196 
17197 	if (QDF_IS_STATUS_ERROR(ret)) {
17198 		WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID send returned Error %d",
17199 				ret);
17200 		wmi_buf_free(buf);
17201 	}
17202 
17203 	return ret;
17204 }
17205 
17206 #ifdef WLAN_FEATURE_NAN_CONVERGENCE
17207 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle,
17208 				struct nan_datapath_initiator_req *ndp_req)
17209 {
17210 	uint16_t len;
17211 	wmi_buf_t buf;
17212 	uint8_t *tlv_ptr;
17213 	QDF_STATUS status;
17214 	wmi_channel *ch_tlv;
17215 	wmi_ndp_initiator_req_fixed_param *cmd;
17216 	uint32_t passphrase_len, service_name_len;
17217 	uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len;
17218 
17219 	/*
17220 	 * WMI command expects 4 byte alligned len:
17221 	 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes
17222 	 */
17223 	ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4);
17224 	ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4);
17225 	pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4);
17226 	passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4);
17227 	service_name_len =
17228 		   qdf_roundup(ndp_req->service_name.service_name_len, 4);
17229 	/* allocated memory for fixed params as well as variable size data */
17230 	len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE)
17231 		+ ndp_cfg_len + ndp_app_info_len + pmk_len
17232 		+ passphrase_len + service_name_len;
17233 
17234 	buf = wmi_buf_alloc(wmi_handle, len);
17235 	if (!buf) {
17236 		WMI_LOGE("wmi_buf_alloc failed");
17237 		return QDF_STATUS_E_NOMEM;
17238 	}
17239 
17240 	cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf);
17241 	WMITLV_SET_HDR(&cmd->tlv_header,
17242 		       WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param,
17243 		       WMITLV_GET_STRUCT_TLVLEN(
17244 				wmi_ndp_initiator_req_fixed_param));
17245 	cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev);
17246 	cmd->transaction_id = ndp_req->transaction_id;
17247 	cmd->service_instance_id = ndp_req->service_instance_id;
17248 	WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes,
17249 				   &cmd->peer_discovery_mac_addr);
17250 
17251 	cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len;
17252 	cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len;
17253 	cmd->ndp_channel_cfg = ndp_req->channel_cfg;
17254 	cmd->nan_pmk_len = ndp_req->pmk.pmk_len;
17255 	cmd->nan_csid = ndp_req->ncs_sk_type;
17256 	cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len;
17257 	cmd->nan_servicename_len = ndp_req->service_name.service_name_len;
17258 
17259 	ch_tlv = (wmi_channel *)&cmd[1];
17260 	WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel,
17261 			WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
17262 	ch_tlv->mhz = ndp_req->channel;
17263 	tlv_ptr = (uint8_t *)&ch_tlv[1];
17264 
17265 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len);
17266 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
17267 		     ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len);
17268 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len;
17269 
17270 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len);
17271 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
17272 		     ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len);
17273 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len;
17274 
17275 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len);
17276 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk,
17277 		     cmd->nan_pmk_len);
17278 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len;
17279 
17280 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len);
17281 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase,
17282 		     cmd->nan_passphrase_len);
17283 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len;
17284 
17285 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len);
17286 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
17287 		     ndp_req->service_name.service_name,
17288 		     cmd->nan_servicename_len);
17289 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len;
17290 
17291 	WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d",
17292 		 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id,
17293 		 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid);
17294 	WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x",
17295 		 cmd->peer_discovery_mac_addr.mac_addr31to0,
17296 		 cmd->peer_discovery_mac_addr.mac_addr47to32);
17297 
17298 	WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len);
17299 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17300 			   ndp_req->ndp_config.ndp_cfg,
17301 			   ndp_req->ndp_config.ndp_cfg_len);
17302 
17303 	WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len);
17304 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17305 			   ndp_req->ndp_info.ndp_app_info,
17306 			   ndp_req->ndp_info.ndp_app_info_len);
17307 
17308 	WMI_LOGD("pmk len: %d", cmd->nan_pmk_len);
17309 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17310 			   ndp_req->pmk.pmk, cmd->nan_pmk_len);
17311 
17312 	WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len);
17313 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17314 			   ndp_req->passphrase.passphrase,
17315 			   cmd->nan_passphrase_len);
17316 
17317 	WMI_LOGD("service name len: %d", cmd->nan_servicename_len);
17318 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17319 			   ndp_req->service_name.service_name,
17320 			   cmd->nan_servicename_len);
17321 
17322 	WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)",
17323 		 WMI_NDP_INITIATOR_REQ_CMDID);
17324 
17325 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
17326 				      WMI_NDP_INITIATOR_REQ_CMDID);
17327 	if (QDF_IS_STATUS_ERROR(status)) {
17328 		WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status);
17329 		wmi_buf_free(buf);
17330 	}
17331 
17332 	return status;
17333 }
17334 
17335 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle,
17336 					struct nan_datapath_responder_req *req)
17337 {
17338 	uint16_t len;
17339 	wmi_buf_t buf;
17340 	uint8_t *tlv_ptr;
17341 	QDF_STATUS status;
17342 	wmi_ndp_responder_req_fixed_param *cmd;
17343 	uint32_t passphrase_len, service_name_len;
17344 	uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len;
17345 
17346 	vdev_id = wlan_vdev_get_id(req->vdev);
17347 	WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d",
17348 		 vdev_id, req->transaction_id,
17349 		 req->ndp_rsp,
17350 		 req->ndp_instance_id,
17351 		 req->ndp_info.ndp_app_info_len);
17352 
17353 	/*
17354 	 * WMI command expects 4 byte alligned len:
17355 	 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes
17356 	 */
17357 	ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4);
17358 	ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4);
17359 	pmk_len = qdf_roundup(req->pmk.pmk_len, 4);
17360 	passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4);
17361 	service_name_len =
17362 		qdf_roundup(req->service_name.service_name_len, 4);
17363 
17364 	/* allocated memory for fixed params as well as variable size data */
17365 	len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len
17366 		+ pmk_len + passphrase_len + service_name_len;
17367 
17368 	buf = wmi_buf_alloc(wmi_handle, len);
17369 	if (!buf) {
17370 		WMI_LOGE("wmi_buf_alloc failed");
17371 		return QDF_STATUS_E_NOMEM;
17372 	}
17373 	cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf);
17374 	WMITLV_SET_HDR(&cmd->tlv_header,
17375 		       WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param,
17376 		       WMITLV_GET_STRUCT_TLVLEN(
17377 				wmi_ndp_responder_req_fixed_param));
17378 	cmd->vdev_id = vdev_id;
17379 	cmd->transaction_id = req->transaction_id;
17380 	cmd->ndp_instance_id = req->ndp_instance_id;
17381 	cmd->rsp_code = req->ndp_rsp;
17382 	cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len;
17383 	cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len;
17384 	cmd->nan_pmk_len = req->pmk.pmk_len;
17385 	cmd->nan_csid = req->ncs_sk_type;
17386 	cmd->nan_passphrase_len = req->passphrase.passphrase_len;
17387 	cmd->nan_servicename_len = req->service_name.service_name_len;
17388 
17389 	tlv_ptr = (uint8_t *)&cmd[1];
17390 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len);
17391 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
17392 		     req->ndp_config.ndp_cfg, cmd->ndp_cfg_len);
17393 
17394 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len;
17395 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len);
17396 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
17397 		     req->ndp_info.ndp_app_info,
17398 		     req->ndp_info.ndp_app_info_len);
17399 
17400 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len;
17401 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len);
17402 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk,
17403 		     cmd->nan_pmk_len);
17404 
17405 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len;
17406 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len);
17407 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
17408 		     req->passphrase.passphrase,
17409 		     cmd->nan_passphrase_len);
17410 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len;
17411 
17412 	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len);
17413 	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
17414 		     req->service_name.service_name,
17415 		     cmd->nan_servicename_len);
17416 
17417 	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len;
17418 
17419 	WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d",
17420 		 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid);
17421 
17422 	WMI_LOGD("ndp_config len: %d",
17423 		 req->ndp_config.ndp_cfg_len);
17424 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17425 			req->ndp_config.ndp_cfg,
17426 			req->ndp_config.ndp_cfg_len);
17427 
17428 	WMI_LOGD("ndp_app_info len: %d",
17429 		 req->ndp_info.ndp_app_info_len);
17430 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17431 			   req->ndp_info.ndp_app_info,
17432 			   req->ndp_info.ndp_app_info_len);
17433 
17434 	WMI_LOGD("pmk len: %d", cmd->nan_pmk_len);
17435 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17436 			   req->pmk.pmk, cmd->nan_pmk_len);
17437 
17438 	WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len);
17439 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17440 			   req->passphrase.passphrase,
17441 			   cmd->nan_passphrase_len);
17442 
17443 	WMI_LOGD("service name len: %d", cmd->nan_servicename_len);
17444 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17445 			   req->service_name.service_name,
17446 			   cmd->nan_servicename_len);
17447 
17448 	WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)",
17449 		 WMI_NDP_RESPONDER_REQ_CMDID);
17450 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
17451 				      WMI_NDP_RESPONDER_REQ_CMDID);
17452 	if (QDF_IS_STATUS_ERROR(status)) {
17453 		WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status);
17454 		wmi_buf_free(buf);
17455 	}
17456 	return status;
17457 }
17458 
17459 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle,
17460 				      struct nan_datapath_end_req *req)
17461 {
17462 	uint16_t len;
17463 	wmi_buf_t buf;
17464 	QDF_STATUS status;
17465 	uint32_t ndp_end_req_len, i;
17466 	wmi_ndp_end_req *ndp_end_req_lst;
17467 	wmi_ndp_end_req_fixed_param *cmd;
17468 
17469 	/* len of tlv following fixed param  */
17470 	ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances;
17471 	/* above comes out to 4 byte alligned already, no need of padding */
17472 	len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE;
17473 	buf = wmi_buf_alloc(wmi_handle, len);
17474 	if (!buf) {
17475 		WMI_LOGE("Malloc failed");
17476 		return QDF_STATUS_E_NOMEM;
17477 	}
17478 
17479 	cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf);
17480 	WMITLV_SET_HDR(&cmd->tlv_header,
17481 		       WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param,
17482 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param));
17483 
17484 	cmd->transaction_id = req->transaction_id;
17485 
17486 	/* set tlv pointer to end of fixed param */
17487 	WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC,
17488 			ndp_end_req_len);
17489 
17490 	ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] +
17491 						WMI_TLV_HDR_SIZE);
17492 	for (i = 0; i < req->num_ndp_instances; i++) {
17493 		WMITLV_SET_HDR(&ndp_end_req_lst[i],
17494 				WMITLV_TAG_ARRAY_FIXED_STRUC,
17495 				(sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE));
17496 
17497 		ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i];
17498 	}
17499 
17500 	WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW");
17501 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
17502 				   WMI_NDP_END_REQ_CMDID);
17503 	if (QDF_IS_STATUS_ERROR(status)) {
17504 		WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status);
17505 		wmi_buf_free(buf);
17506 	}
17507 
17508 	return status;
17509 }
17510 
17511 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle,
17512 			uint8_t *data, struct nan_datapath_initiator_rsp **rsp)
17513 {
17514 	WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event;
17515 	wmi_ndp_initiator_rsp_event_fixed_param  *fixed_params;
17516 
17517 	event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data;
17518 	fixed_params = event->fixed_param;
17519 
17520 	*rsp = qdf_mem_malloc(sizeof(**rsp));
17521 	if (!(*rsp)) {
17522 		WMI_LOGE("malloc failed");
17523 		return QDF_STATUS_E_NOMEM;
17524 	}
17525 
17526 	(*rsp)->vdev =
17527 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17528 						     fixed_params->vdev_id,
17529 						     WLAN_NAN_ID);
17530 	if (!(*rsp)->vdev) {
17531 		WMI_LOGE("vdev is null");
17532 		qdf_mem_free(*rsp);
17533 		return QDF_STATUS_E_INVAL;
17534 	}
17535 
17536 	(*rsp)->transaction_id = fixed_params->transaction_id;
17537 	(*rsp)->ndp_instance_id = fixed_params->ndp_instance_id;
17538 	(*rsp)->status = fixed_params->rsp_status;
17539 	(*rsp)->reason = fixed_params->reason_code;
17540 
17541 	return QDF_STATUS_SUCCESS;
17542 }
17543 
17544 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle,
17545 		uint8_t *data, struct nan_datapath_indication_event **rsp)
17546 {
17547 	WMI_NDP_INDICATION_EVENTID_param_tlvs *event;
17548 	wmi_ndp_indication_event_fixed_param *fixed_params;
17549 
17550 	event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data;
17551 	fixed_params =
17552 		(wmi_ndp_indication_event_fixed_param *)event->fixed_param;
17553 
17554 	if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) {
17555 		WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d",
17556 			 fixed_params->ndp_cfg_len, event->num_ndp_cfg);
17557 		return QDF_STATUS_E_INVAL;
17558 	}
17559 
17560 	if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) {
17561 		WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d",
17562 			 fixed_params->ndp_app_info_len,
17563 			 event->num_ndp_app_info);
17564 		return QDF_STATUS_E_INVAL;
17565 	}
17566 
17567 	*rsp = qdf_mem_malloc(sizeof(**rsp));
17568 	if (!(*rsp)) {
17569 		WMI_LOGE("malloc failed");
17570 		return QDF_STATUS_E_NOMEM;
17571 	}
17572 
17573 	(*rsp)->vdev =
17574 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17575 						     fixed_params->vdev_id,
17576 						     WLAN_NAN_ID);
17577 	if (!(*rsp)->vdev) {
17578 		WMI_LOGE("vdev is null");
17579 		qdf_mem_free(*rsp);
17580 		return QDF_STATUS_E_INVAL;
17581 	}
17582 	(*rsp)->service_instance_id = fixed_params->service_instance_id;
17583 	(*rsp)->ndp_instance_id = fixed_params->ndp_instance_id;
17584 	(*rsp)->role = fixed_params->self_ndp_role;
17585 	(*rsp)->policy = fixed_params->accept_policy;
17586 
17587 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
17588 				(*rsp)->peer_mac_addr.bytes);
17589 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr,
17590 				(*rsp)->peer_discovery_mac_addr.bytes);
17591 
17592 	WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n"
17593 		"service_instance %d, ndp_instance %d, role %d, policy %d,\n"
17594 		"csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM",
17595 		 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id,
17596 		 fixed_params->service_instance_id,
17597 		 fixed_params->ndp_instance_id, fixed_params->self_ndp_role,
17598 		 fixed_params->accept_policy,
17599 		 fixed_params->nan_csid, fixed_params->nan_scid_len,
17600 		 (*rsp)->peer_mac_addr.bytes,
17601 		 (*rsp)->peer_discovery_mac_addr.bytes);
17602 
17603 	WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len);
17604 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17605 			   &event->ndp_cfg, fixed_params->ndp_cfg_len);
17606 
17607 	WMI_LOGD("ndp_app_info - %d bytes",
17608 			fixed_params->ndp_app_info_len);
17609 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17610 			&event->ndp_app_info, fixed_params->ndp_app_info_len);
17611 
17612 	(*rsp)->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len;
17613 	(*rsp)->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len;
17614 	(*rsp)->ncs_sk_type = fixed_params->nan_csid;
17615 	(*rsp)->scid.scid_len = fixed_params->nan_scid_len;
17616 	qdf_mem_copy((*rsp)->ndp_config.ndp_cfg, event->ndp_cfg,
17617 		     (*rsp)->ndp_config.ndp_cfg_len);
17618 	qdf_mem_copy((*rsp)->ndp_info.ndp_app_info, event->ndp_app_info,
17619 		     (*rsp)->ndp_info.ndp_app_info_len);
17620 	qdf_mem_copy((*rsp)->scid.scid, event->ndp_scid, (*rsp)->scid.scid_len);
17621 	WMI_LOGD("scid hex dump:");
17622 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17623 			   (*rsp)->scid.scid, (*rsp)->scid.scid_len);
17624 
17625 	return QDF_STATUS_SUCCESS;
17626 }
17627 
17628 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle,
17629 			uint8_t *data, struct nan_datapath_confirm_event **rsp)
17630 {
17631 	WMI_NDP_CONFIRM_EVENTID_param_tlvs *event;
17632 	wmi_ndp_confirm_event_fixed_param *fixed_params;
17633 
17634 	event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data;
17635 	fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param;
17636 	WMI_LOGD("WMI_NDP_CONFIRM_EVENTID(0x%X) recieved. vdev %d, ndp_instance %d, rsp_code %d, reason_code: %d, num_active_ndps_on_peer: %d",
17637 		 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id,
17638 		 fixed_params->ndp_instance_id, fixed_params->rsp_code,
17639 		 fixed_params->reason_code,
17640 		 fixed_params->num_active_ndps_on_peer);
17641 
17642 	if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) {
17643 		WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d",
17644 			 fixed_params->ndp_cfg_len, event->num_ndp_cfg);
17645 		return QDF_STATUS_E_INVAL;
17646 	}
17647 
17648 	WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len);
17649 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17650 		&event->ndp_cfg, fixed_params->ndp_cfg_len);
17651 
17652 	if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) {
17653 		WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d",
17654 			 fixed_params->ndp_app_info_len,
17655 			 event->num_ndp_app_info);
17656 		return QDF_STATUS_E_INVAL;
17657 	}
17658 
17659 	WMI_LOGD("ndp_app_info - %d bytes",
17660 			fixed_params->ndp_app_info_len);
17661 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
17662 		&event->ndp_app_info, fixed_params->ndp_app_info_len);
17663 
17664 	*rsp = qdf_mem_malloc(sizeof(**rsp));
17665 	if (!(*rsp)) {
17666 		WMI_LOGE("malloc failed");
17667 		return QDF_STATUS_E_NOMEM;
17668 	}
17669 
17670 	(*rsp)->vdev =
17671 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17672 						     fixed_params->vdev_id,
17673 						     WLAN_NAN_ID);
17674 	if (!(*rsp)->vdev) {
17675 		WMI_LOGE("vdev is null");
17676 		qdf_mem_free(*rsp);
17677 		return QDF_STATUS_E_INVAL;
17678 	}
17679 	(*rsp)->ndp_instance_id = fixed_params->ndp_instance_id;
17680 	(*rsp)->rsp_code = fixed_params->rsp_code;
17681 	(*rsp)->reason_code = fixed_params->reason_code;
17682 	(*rsp)->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer;
17683 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
17684 				   (*rsp)->peer_ndi_mac_addr.bytes);
17685 	(*rsp)->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len;
17686 	qdf_mem_copy((*rsp)->ndp_info.ndp_app_info, event->ndp_app_info,
17687 		     (*rsp)->ndp_info.ndp_app_info_len);
17688 
17689 	return QDF_STATUS_SUCCESS;
17690 }
17691 
17692 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle,
17693 			uint8_t *data, struct nan_datapath_responder_rsp **rsp)
17694 {
17695 	WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event;
17696 	wmi_ndp_responder_rsp_event_fixed_param  *fixed_params;
17697 
17698 	event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data;
17699 	fixed_params = event->fixed_param;
17700 
17701 	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",
17702 		 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id,
17703 		 (*rsp)->peer_mac_addr.bytes, (*rsp)->transaction_id,
17704 		 (*rsp)->status, (*rsp)->reason, (*rsp)->create_peer);
17705 
17706 	*rsp = qdf_mem_malloc(sizeof(**rsp));
17707 	if (!(*rsp)) {
17708 		WMI_LOGE("malloc failed");
17709 		return QDF_STATUS_E_NOMEM;
17710 	}
17711 
17712 	(*rsp)->vdev =
17713 		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
17714 						     fixed_params->vdev_id,
17715 						     WLAN_NAN_ID);
17716 	if (!(*rsp)->vdev) {
17717 		WMI_LOGE("vdev is null");
17718 		qdf_mem_free(*rsp);
17719 		return QDF_STATUS_E_INVAL;
17720 	}
17721 	(*rsp)->transaction_id = fixed_params->transaction_id;
17722 	(*rsp)->reason = fixed_params->reason_code;
17723 	(*rsp)->status = fixed_params->rsp_status;
17724 	(*rsp)->create_peer = fixed_params->create_peer;
17725 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
17726 				(*rsp)->peer_mac_addr.bytes);
17727 
17728 	return QDF_STATUS_SUCCESS;
17729 }
17730 
17731 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle,
17732 			uint8_t *data, struct nan_datapath_end_rsp_event **rsp)
17733 {
17734 	WMI_NDP_END_RSP_EVENTID_param_tlvs *event;
17735 	wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL;
17736 
17737 	event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data;
17738 	fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param;
17739 	WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) recieved. transaction_id: %d, rsp_status: %d, reason_code: %d",
17740 		 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id,
17741 		 fixed_params->rsp_status, fixed_params->reason_code);
17742 
17743 	*rsp = qdf_mem_malloc(sizeof(**rsp));
17744 	if (!(*rsp)) {
17745 		WMI_LOGE("malloc failed");
17746 		return QDF_STATUS_E_NOMEM;
17747 	}
17748 
17749 	(*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
17750 			wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID);
17751 	if (!(*rsp)->vdev) {
17752 		WMI_LOGE("vdev is null");
17753 		qdf_mem_free(*rsp);
17754 		return QDF_STATUS_E_INVAL;
17755 	}
17756 	(*rsp)->transaction_id = fixed_params->transaction_id;
17757 	(*rsp)->reason = fixed_params->reason_code;
17758 	(*rsp)->status = fixed_params->rsp_status;
17759 
17760 	return QDF_STATUS_SUCCESS;
17761 }
17762 
17763 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle,
17764 		uint8_t *data, struct nan_datapath_end_indication_event **rsp)
17765 {
17766 	uint32_t i, buf_size;
17767 	wmi_ndp_end_indication *ind;
17768 	struct qdf_mac_addr peer_addr;
17769 	WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event;
17770 
17771 	event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data;
17772 	ind = event->ndp_end_indication_list;
17773 
17774 	if (event->num_ndp_end_indication_list == 0) {
17775 		WMI_LOGE("Error: Event ignored, 0 ndp instances");
17776 		return -EINVAL;
17777 	}
17778 
17779 	(*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
17780 			wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID);
17781 	if (!(*rsp)->vdev) {
17782 		WMI_LOGE("vdev is null");
17783 		qdf_mem_free(*rsp);
17784 		return QDF_STATUS_E_INVAL;
17785 	}
17786 
17787 	WMI_LOGD("number of ndp instances = %d",
17788 		 event->num_ndp_end_indication_list);
17789 	buf_size = sizeof(*rsp) + event->num_ndp_end_indication_list *
17790 			sizeof((*rsp)->ndp_map[0]);
17791 	*rsp = qdf_mem_malloc(buf_size);
17792 	if (!(*rsp)) {
17793 		WMI_LOGE("Failed to allocate memory");
17794 		return -ENOMEM;
17795 	}
17796 
17797 	(*rsp)->num_ndp_ids = event->num_ndp_end_indication_list;
17798 	for (i = 0; i < (*rsp)->num_ndp_ids; i++) {
17799 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr,
17800 					   peer_addr.bytes);
17801 		WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ",
17802 			 i, ind[i].type, ind[i].reason_code,
17803 			 ind[i].ndp_instance_id,
17804 			 ind[i].num_active_ndps_on_peer);
17805 		/* Add each instance entry to the list */
17806 		(*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id;
17807 		(*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id;
17808 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr,
17809 			(*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes);
17810 		(*rsp)->ndp_map[i].num_active_ndp_sessions =
17811 			ind[i].num_active_ndps_on_peer;
17812 		(*rsp)->ndp_map[i].type = ind[i].type;
17813 		(*rsp)->ndp_map[i].reason_code = ind[i].reason_code;
17814 	}
17815 
17816 	return QDF_STATUS_SUCCESS;
17817 }
17818 #endif
17819 
17820 /**
17821  * save_service_bitmap_tlv() - save service bitmap
17822  * @wmi_handle: wmi handle
17823  * @param evt_buf: pointer to event buffer
17824  * @param bitmap_buf: bitmap buffer, for converged legacy support
17825  *
17826  * Return: QDF_STATUS
17827  */
17828 static
17829 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
17830 			     void *bitmap_buf)
17831 {
17832 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17833 	struct wmi_soc *soc = wmi_handle->soc;
17834 
17835 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17836 
17837 	/* If it is already allocated, use that buffer. This can happen
17838 	 * during target stop/start scenarios where host allocation is skipped.
17839 	 */
17840 	if (!soc->wmi_service_bitmap) {
17841 		soc->wmi_service_bitmap =
17842 			qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t));
17843 		if (!soc->wmi_service_bitmap) {
17844 			WMI_LOGE("Failed memory allocation for service bitmap");
17845 			return QDF_STATUS_E_NOMEM;
17846 		}
17847 	}
17848 
17849 	qdf_mem_copy(soc->wmi_service_bitmap,
17850 			param_buf->wmi_service_bitmap,
17851 			(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
17852 
17853 	if (bitmap_buf)
17854 		qdf_mem_copy(bitmap_buf,
17855 			     param_buf->wmi_service_bitmap,
17856 			     (WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
17857 
17858 	return QDF_STATUS_SUCCESS;
17859 }
17860 
17861 /**
17862  * save_ext_service_bitmap_tlv() - save extendend service bitmap
17863  * @wmi_handle: wmi handle
17864  * @param evt_buf: pointer to event buffer
17865  * @param bitmap_buf: bitmap buffer, for converged legacy support
17866  *
17867  * Return: QDF_STATUS
17868  */
17869 static
17870 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
17871 			     void *bitmap_buf)
17872 {
17873 	WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf;
17874 	wmi_service_available_event_fixed_param *ev;
17875 	struct wmi_soc *soc = wmi_handle->soc;
17876 
17877 	param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf;
17878 
17879 	ev = param_buf->fixed_param;
17880 
17881 	/* If it is already allocated, use that buffer. This can happen
17882 	 * during target stop/start scenarios where host allocation is skipped.
17883 	 */
17884 	if (!soc->wmi_ext_service_bitmap) {
17885 		soc->wmi_ext_service_bitmap = qdf_mem_malloc(
17886 			WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t));
17887 		if (!soc->wmi_ext_service_bitmap) {
17888 			WMI_LOGE("Failed memory allocation for service bitmap");
17889 			return QDF_STATUS_E_NOMEM;
17890 		}
17891 	}
17892 
17893 	qdf_mem_copy(soc->wmi_ext_service_bitmap,
17894 			ev->wmi_service_segment_bitmap,
17895 			(WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)));
17896 
17897 	WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n",
17898 			soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1],
17899 			soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]);
17900 
17901 	if (bitmap_buf)
17902 		qdf_mem_copy(bitmap_buf,
17903 			soc->wmi_ext_service_bitmap,
17904 			(WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)));
17905 
17906 	return QDF_STATUS_SUCCESS;
17907 }
17908 /**
17909  * is_service_enabled_tlv() - Check if service enabled
17910  * @param wmi_handle: wmi handle
17911  * @param service_id: service identifier
17912  *
17913  * Return: 1 enabled, 0 disabled
17914  */
17915 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle,
17916 		uint32_t service_id)
17917 {
17918 	struct wmi_soc *soc = wmi_handle->soc;
17919 
17920 	if (!soc->wmi_service_bitmap) {
17921 		WMI_LOGE("WMI service bit map is not saved yet\n");
17922 		return false;
17923 	}
17924 
17925 	/* if wmi_service_enabled was received with extended bitmap,
17926 	 * use WMI_SERVICE_EXT_IS_ENABLED to check the services.
17927 	 */
17928 	if (soc->wmi_ext_service_bitmap)
17929 		return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap,
17930 				soc->wmi_ext_service_bitmap,
17931 				service_id);
17932 
17933 	return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap,
17934 				service_id);
17935 }
17936 
17937 static inline void copy_ht_cap_info(uint32_t ev_target_cap,
17938 		struct wlan_psoc_target_capability_info *cap)
17939 {
17940        /* except LDPC all flags are common betwen legacy and here
17941 	*  also IBFEER is not defined for TLV
17942 	*/
17943 	cap->ht_cap_info |= ev_target_cap & (
17944 					WMI_HT_CAP_ENABLED
17945 					| WMI_HT_CAP_HT20_SGI
17946 					| WMI_HT_CAP_DYNAMIC_SMPS
17947 					| WMI_HT_CAP_TX_STBC
17948 					| WMI_HT_CAP_TX_STBC_MASK_SHIFT
17949 					| WMI_HT_CAP_RX_STBC
17950 					| WMI_HT_CAP_RX_STBC_MASK_SHIFT
17951 					| WMI_HT_CAP_LDPC
17952 					| WMI_HT_CAP_L_SIG_TXOP_PROT
17953 					| WMI_HT_CAP_MPDU_DENSITY
17954 					| WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT
17955 					| WMI_HT_CAP_HT40_SGI);
17956 	if (ev_target_cap & WMI_HT_CAP_LDPC)
17957 		cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC |
17958 			WMI_HOST_HT_CAP_TX_LDPC;
17959 }
17960 /**
17961  * extract_service_ready_tlv() - extract service ready event
17962  * @wmi_handle: wmi handle
17963  * @param evt_buf: pointer to received event buffer
17964  * @param cap: pointer to hold target capability information extracted from even
17965  *
17966  * Return: QDF_STATUS_SUCCESS for success or error code
17967  */
17968 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle,
17969 		void *evt_buf, struct wlan_psoc_target_capability_info *cap)
17970 {
17971 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
17972 	wmi_service_ready_event_fixed_param *ev;
17973 
17974 
17975 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
17976 
17977 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
17978 	if (!ev) {
17979 		qdf_print("%s: wmi_buf_alloc failed\n", __func__);
17980 		return QDF_STATUS_E_FAILURE;
17981 	}
17982 
17983 	cap->phy_capability = ev->phy_capability;
17984 	cap->max_frag_entry = ev->max_frag_entry;
17985 	cap->num_rf_chains = ev->num_rf_chains;
17986 	copy_ht_cap_info(ev->ht_cap_info, cap);
17987 	cap->vht_cap_info = ev->vht_cap_info;
17988 	cap->vht_supp_mcs = ev->vht_supp_mcs;
17989 	cap->hw_min_tx_power = ev->hw_min_tx_power;
17990 	cap->hw_max_tx_power = ev->hw_max_tx_power;
17991 	cap->sys_cap_info = ev->sys_cap_info;
17992 	cap->min_pkt_size_enable = ev->min_pkt_size_enable;
17993 	cap->max_bcn_ie_size = ev->max_bcn_ie_size;
17994 	cap->max_num_scan_channels = ev->max_num_scan_channels;
17995 	cap->max_supported_macs = ev->max_supported_macs;
17996 	cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps;
17997 	cap->txrx_chainmask = ev->txrx_chainmask;
17998 	cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index;
17999 	cap->num_msdu_desc = ev->num_msdu_desc;
18000 	cap->fw_version = ev->fw_build_vers;
18001 	/* fw_version_1 is not available in TLV. */
18002 	cap->fw_version_1 = 0;
18003 
18004 	return QDF_STATUS_SUCCESS;
18005 }
18006 
18007 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target
18008  *         to host internal WMI_HOST_REGDMN_MODE values.
18009  *         REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the
18010  *         host currently. Add this in the future if required.
18011  *         11AX (Phase II) : 11ax related values are not currently
18012  *         advertised separately by FW. As part of phase II regulatory bring-up,
18013  *         finalize the advertisement mechanism.
18014  * @target_wireless_mode: target wireless mode received in message
18015  *
18016  * Return: returns the host internal wireless mode.
18017  */
18018 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode)
18019 {
18020 
18021 	uint32_t wireless_modes = 0;
18022 
18023 	if (target_wireless_mode & REGDMN_MODE_11A)
18024 		wireless_modes |= WMI_HOST_REGDMN_MODE_11A;
18025 
18026 	if (target_wireless_mode & REGDMN_MODE_TURBO)
18027 		wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO;
18028 
18029 	if (target_wireless_mode & REGDMN_MODE_11B)
18030 		wireless_modes |= WMI_HOST_REGDMN_MODE_11B;
18031 
18032 	if (target_wireless_mode & REGDMN_MODE_PUREG)
18033 		wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG;
18034 
18035 	if (target_wireless_mode & REGDMN_MODE_11G)
18036 		wireless_modes |= WMI_HOST_REGDMN_MODE_11G;
18037 
18038 	if (target_wireless_mode & REGDMN_MODE_108G)
18039 		wireless_modes |= WMI_HOST_REGDMN_MODE_108G;
18040 
18041 	if (target_wireless_mode & REGDMN_MODE_108A)
18042 		wireless_modes |= WMI_HOST_REGDMN_MODE_108A;
18043 
18044 	if (target_wireless_mode & REGDMN_MODE_XR)
18045 		wireless_modes |= WMI_HOST_REGDMN_MODE_XR;
18046 
18047 	if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE)
18048 		wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE;
18049 
18050 	if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE)
18051 		wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE;
18052 
18053 	if (target_wireless_mode & REGDMN_MODE_11NG_HT20)
18054 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20;
18055 
18056 	if (target_wireless_mode & REGDMN_MODE_11NA_HT20)
18057 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20;
18058 
18059 	if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS)
18060 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS;
18061 
18062 	if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS)
18063 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS;
18064 
18065 	if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS)
18066 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS;
18067 
18068 	if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS)
18069 		wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS;
18070 
18071 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT20)
18072 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20;
18073 
18074 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS)
18075 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS;
18076 
18077 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS)
18078 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS;
18079 
18080 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT80)
18081 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80;
18082 
18083 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT160)
18084 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160;
18085 
18086 	if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80)
18087 		wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80;
18088 
18089 	return wireless_modes;
18090 }
18091 
18092 /**
18093  * extract_hal_reg_cap_tlv() - extract HAL registered capabilities
18094  * @wmi_handle: wmi handle
18095  * @param evt_buf: Pointer to event buffer
18096  * @param cap: pointer to hold HAL reg capabilities
18097  *
18098  * Return: QDF_STATUS_SUCCESS for success or error code
18099  */
18100 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle,
18101 	void *evt_buf, struct wlan_psoc_hal_reg_capability *cap)
18102 {
18103 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
18104 
18105 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
18106 
18107 	qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) +
18108 		sizeof(uint32_t)),
18109 		sizeof(struct wlan_psoc_hal_reg_capability));
18110 
18111 	cap->wireless_modes = convert_wireless_modes_tlv(
18112 			param_buf->hal_reg_capabilities->wireless_modes);
18113 
18114 	return QDF_STATUS_SUCCESS;
18115 }
18116 
18117 /**
18118  * extract_host_mem_req_tlv() - Extract host memory request event
18119  * @wmi_handle: wmi handle
18120  * @param evt_buf: pointer to event buffer
18121  * @param num_entries: pointer to hold number of entries requested
18122  *
18123  * Return: Number of entries requested
18124  */
18125 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle,
18126 		void *evt_buf, uint8_t *num_entries)
18127 {
18128 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
18129 	wmi_service_ready_event_fixed_param *ev;
18130 
18131 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
18132 
18133 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
18134 	if (!ev) {
18135 		qdf_print("%s: wmi_buf_alloc failed\n", __func__);
18136 		return NULL;
18137 	}
18138 
18139 	*num_entries = ev->num_mem_reqs;
18140 
18141 	return (host_mem_req *)param_buf->mem_reqs;
18142 }
18143 
18144 /**
18145  * save_fw_version_in_service_ready_tlv() - Save fw version in service
18146  * ready function
18147  * @wmi_handle: wmi handle
18148  * @param evt_buf: pointer to event buffer
18149  *
18150  * Return: QDF_STATUS_SUCCESS for success or error code
18151  */
18152 static QDF_STATUS
18153 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf)
18154 {
18155 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
18156 	wmi_service_ready_event_fixed_param *ev;
18157 
18158 
18159 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
18160 
18161 	ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
18162 	if (!ev) {
18163 		qdf_print("%s: wmi_buf_alloc failed\n", __func__);
18164 		return QDF_STATUS_E_FAILURE;
18165 	}
18166 
18167 	/*Save fw version from service ready message */
18168 	/*This will be used while sending INIT message */
18169 	qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
18170 			sizeof(wmi_handle->fw_abi_version));
18171 
18172 	return QDF_STATUS_SUCCESS;
18173 }
18174 
18175 /**
18176  * ready_extract_init_status_tlv() - Extract init status from ready event
18177  * @wmi_handle: wmi handle
18178  * @param evt_buf: Pointer to event buffer
18179  *
18180  * Return: ready status
18181  */
18182 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle,
18183 	void *evt_buf)
18184 {
18185 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
18186 	wmi_ready_event_fixed_param *ev = NULL;
18187 
18188 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
18189 	ev = param_buf->fixed_param;
18190 
18191 	qdf_print("%s:%d\n", __func__, ev->status);
18192 
18193 	return ev->status;
18194 }
18195 
18196 /**
18197  * ready_extract_mac_addr_tlv() - extract mac address from ready event
18198  * @wmi_handle: wmi handle
18199  * @param evt_buf: pointer to event buffer
18200  * @param macaddr: Pointer to hold MAC address
18201  *
18202  * Return: QDF_STATUS_SUCCESS for success or error code
18203  */
18204 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle,
18205 	void *evt_buf, uint8_t *macaddr)
18206 {
18207 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
18208 	wmi_ready_event_fixed_param *ev = NULL;
18209 
18210 
18211 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
18212 	ev = param_buf->fixed_param;
18213 
18214 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr);
18215 
18216 	return QDF_STATUS_SUCCESS;
18217 }
18218 
18219 /**
18220  * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event
18221  * @wmi_handle: wmi handle
18222  * @param evt_buf: pointer to event buffer
18223  * @param macaddr: Pointer to hold number of MAC addresses
18224  *
18225  * Return: Pointer to addr list
18226  */
18227 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle,
18228 	void *evt_buf, uint8_t *num_mac)
18229 {
18230 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
18231 	wmi_ready_event_fixed_param *ev = NULL;
18232 
18233 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
18234 	ev = param_buf->fixed_param;
18235 
18236 	*num_mac = ev->num_extra_mac_addr;
18237 
18238 	return (wmi_host_mac_addr *) param_buf->mac_addr_list;
18239 }
18240 
18241 /**
18242  * extract_ready_params_tlv() - Extract data from ready event apart from
18243  *                     status, macaddr and version.
18244  * @wmi_handle: Pointer to WMI handle.
18245  * @evt_buf: Pointer to Ready event buffer.
18246  * @ev_param: Pointer to host defined struct to copy the data from event.
18247  *
18248  * Return: QDF_STATUS_SUCCESS on success.
18249  */
18250 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle,
18251 		void *evt_buf, struct wmi_host_ready_ev_param *ev_param)
18252 {
18253 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
18254 	wmi_ready_event_fixed_param *ev = NULL;
18255 
18256 	param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
18257 	ev = param_buf->fixed_param;
18258 
18259 	ev_param->status = ev->status;
18260 	ev_param->num_dscp_table = ev->num_dscp_table;
18261 	ev_param->num_extra_mac_addr = ev->num_extra_mac_addr;
18262 	ev_param->num_total_peer = ev->num_total_peers;
18263 	ev_param->num_extra_peer = ev->num_extra_peers;
18264 	/* Agile_cap in ready event is not supported in TLV target */
18265 	ev_param->agile_capability = false;
18266 
18267 	return QDF_STATUS_SUCCESS;
18268 }
18269 
18270 /**
18271  * extract_dbglog_data_len_tlv() - extract debuglog data length
18272  * @wmi_handle: wmi handle
18273  * @param evt_buf: pointer to event buffer
18274  *
18275  * Return: length
18276  */
18277 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle,
18278 	void *evt_buf, uint32_t *len)
18279 {
18280 	 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf;
18281 
18282 	 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf;
18283 
18284 	 *len = param_buf->num_bufp;
18285 
18286 	 return param_buf->bufp;
18287 }
18288 
18289 /**
18290  * extract_vdev_start_resp_tlv() - extract vdev start response
18291  * @wmi_handle: wmi handle
18292  * @param evt_buf: pointer to event buffer
18293  * @param vdev_rsp: Pointer to hold vdev response
18294  *
18295  * Return: QDF_STATUS_SUCCESS for success or error code
18296  */
18297 static QDF_STATUS extract_vdev_start_resp_tlv(wmi_unified_t wmi_handle,
18298 	void *evt_buf, wmi_host_vdev_start_resp *vdev_rsp)
18299 {
18300 	WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf;
18301 	wmi_vdev_start_response_event_fixed_param *ev;
18302 
18303 	param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) evt_buf;
18304 	if (!param_buf) {
18305 		qdf_print("Invalid start response event buffer\n");
18306 		return QDF_STATUS_E_INVAL;
18307 	}
18308 
18309 	ev = param_buf->fixed_param;
18310 	if (!ev) {
18311 		qdf_print("Invalid start response event buffer\n");
18312 		return QDF_STATUS_E_INVAL;
18313 	}
18314 
18315 	qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp));
18316 
18317 	vdev_rsp->vdev_id = ev->vdev_id;
18318 	vdev_rsp->requestor_id = ev->requestor_id;
18319 	switch (ev->resp_type) {
18320 	case WMI_VDEV_START_RESP_EVENT:
18321 		vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT;
18322 		break;
18323 	case WMI_VDEV_RESTART_RESP_EVENT:
18324 		vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT;
18325 		break;
18326 	default:
18327 		qdf_print("Invalid start response event buffer\n");
18328 		break;
18329 	};
18330 	vdev_rsp->status = ev->status;
18331 	vdev_rsp->chain_mask = ev->chain_mask;
18332 	vdev_rsp->smps_mode = ev->smps_mode;
18333 	vdev_rsp->mac_id = ev->mac_id;
18334 	vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams;
18335 	vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams;
18336 
18337 	return QDF_STATUS_SUCCESS;
18338 }
18339 
18340 /**
18341  * extract_vdev_delete_resp_tlv() - extract vdev delete response
18342  * @wmi_handle: wmi handle
18343  * @param evt_buf: pointer to event buffer
18344  * @param delete_rsp: Pointer to hold vdev delete response
18345  *
18346  * Return: QDF_STATUS_SUCCESS for success or error code
18347  */
18348 static QDF_STATUS extract_vdev_delete_resp_tlv(wmi_unified_t wmi_handle,
18349 	void *evt_buf, struct wmi_host_vdev_delete_resp *delete_rsp)
18350 {
18351 	WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf;
18352 	wmi_vdev_delete_resp_event_fixed_param *ev;
18353 
18354 	param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *) evt_buf;
18355 	if (!param_buf) {
18356 		WMI_LOGE("Invalid vdev delete response event buffer\n");
18357 		return QDF_STATUS_E_INVAL;
18358 	}
18359 
18360 	ev = param_buf->fixed_param;
18361 	if (!ev) {
18362 		WMI_LOGE("Invalid vdev delete response event\n");
18363 		return QDF_STATUS_E_INVAL;
18364 	}
18365 
18366 	qdf_mem_zero(delete_rsp, sizeof(*delete_rsp));
18367 	delete_rsp->vdev_id = ev->vdev_id;
18368 
18369 	return QDF_STATUS_SUCCESS;
18370 }
18371 
18372 
18373 /**
18374  * extract_tbttoffset_num_vdevs_tlv() - extract tbtt offset num vdev
18375  * @wmi_handle: wmi handle
18376  * @param evt_buf: pointer to event buffer
18377  * @param num_vdevs: Pointer to hold num vdev
18378  *
18379  * Return: QDF_STATUS_SUCCESS for success or error code
18380  */
18381 static QDF_STATUS extract_tbttoffset_num_vdevs_tlv(void *wmi_hdl,
18382 	void *evt_buf, uint32_t *num_vdevs)
18383 {
18384 	WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
18385 	wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
18386 	uint32_t vdev_map;
18387 
18388 	param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf;
18389 	if (!param_buf) {
18390 		qdf_print("Invalid tbtt update ext event buffer\n");
18391 		return QDF_STATUS_E_INVAL;
18392 	}
18393 	tbtt_offset_event = param_buf->fixed_param;
18394 	vdev_map = tbtt_offset_event->vdev_map;
18395 	*num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map);
18396 
18397 	return QDF_STATUS_SUCCESS;
18398 }
18399 
18400 /**
18401  * extract_ext_tbttoffset_num_vdevs_tlv() - extract ext tbtt offset num vdev
18402  * @wmi_handle: wmi handle
18403  * @param evt_buf: pointer to event buffer
18404  * @param num_vdevs: Pointer to hold num vdev
18405  *
18406  * Return: QDF_STATUS_SUCCESS for success or error code
18407  */
18408 static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(void *wmi_hdl,
18409 	void *evt_buf, uint32_t *num_vdevs)
18410 {
18411 	WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf;
18412 	wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event;
18413 
18414 	param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf;
18415 	if (!param_buf) {
18416 		qdf_print("Invalid tbtt update ext event buffer\n");
18417 		return QDF_STATUS_E_INVAL;
18418 	}
18419 	tbtt_offset_ext_event = param_buf->fixed_param;
18420 
18421 	*num_vdevs = tbtt_offset_ext_event->num_vdevs;
18422 
18423 	return QDF_STATUS_SUCCESS;
18424 }
18425 
18426 /**
18427  * extract_tbttoffset_update_params_tlv() - extract tbtt offset param
18428  * @wmi_handle: wmi handle
18429  * @param evt_buf: pointer to event buffer
18430  * @param idx: Index refering to a vdev
18431  * @param tbtt_param: Pointer to tbttoffset event param
18432  *
18433  * Return: QDF_STATUS_SUCCESS for success or error code
18434  */
18435 static QDF_STATUS extract_tbttoffset_update_params_tlv(void *wmi_hdl,
18436 	void *evt_buf, uint8_t idx,
18437 	struct tbttoffset_params *tbtt_param)
18438 {
18439 	WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
18440 	wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
18441 	uint32_t vdev_map;
18442 
18443 	param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) evt_buf;
18444 	if (!param_buf) {
18445 		qdf_print("Invalid tbtt update event buffer\n");
18446 		return QDF_STATUS_E_INVAL;
18447 	}
18448 
18449 	tbtt_offset_event = param_buf->fixed_param;
18450 	vdev_map = tbtt_offset_event->vdev_map;
18451 	tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx);
18452 	if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID)
18453 		return QDF_STATUS_E_INVAL;
18454 	tbtt_param->tbttoffset =
18455 		param_buf->tbttoffset_list[tbtt_param->vdev_id];
18456 
18457 	return QDF_STATUS_SUCCESS;
18458 }
18459 
18460 /**
18461  * extract_ext_tbttoffset_update_params_tlv() - extract ext tbtt offset param
18462  * @wmi_handle: wmi handle
18463  * @param evt_buf: pointer to event buffer
18464  * @param idx: Index refering to a vdev
18465  * @param tbtt_param: Pointer to tbttoffset event param
18466  *
18467  * Return: QDF_STATUS_SUCCESS for success or error code
18468  */
18469 static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(void *wmi_hdl,
18470 	void *evt_buf, uint8_t idx,
18471 	struct tbttoffset_params *tbtt_param)
18472 {
18473 	WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf;
18474 	wmi_tbtt_offset_info *tbtt_offset_info;
18475 
18476 	param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf;
18477 	if (!param_buf) {
18478 		qdf_print("Invalid tbtt update event buffer\n");
18479 		return QDF_STATUS_E_INVAL;
18480 	}
18481 	tbtt_offset_info = &param_buf->tbtt_offset_info[idx];
18482 
18483 	tbtt_param->vdev_id = tbtt_offset_info->vdev_id;
18484 	tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset;
18485 
18486 	return QDF_STATUS_SUCCESS;
18487 }
18488 
18489 /**
18490  * extract_mgmt_rx_params_tlv() - extract management rx params from event
18491  * @wmi_handle: wmi handle
18492  * @param evt_buf: pointer to event buffer
18493  * @param hdr: Pointer to hold header
18494  * @param bufp: Pointer to hold pointer to rx param buffer
18495  *
18496  * Return: QDF_STATUS_SUCCESS for success or error code
18497  */
18498 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle,
18499 	void *evt_buf, struct mgmt_rx_event_params *hdr,
18500 	uint8_t **bufp)
18501 {
18502 	WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL;
18503 	wmi_mgmt_rx_hdr *ev_hdr = NULL;
18504 	int i;
18505 
18506 	param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf;
18507 	if (!param_tlvs) {
18508 		WMI_LOGE("Get NULL point message from FW");
18509 		return QDF_STATUS_E_INVAL;
18510 	}
18511 
18512 	ev_hdr = param_tlvs->hdr;
18513 	if (!hdr) {
18514 		WMI_LOGE("Rx event is NULL");
18515 		return QDF_STATUS_E_INVAL;
18516 	}
18517 
18518 	hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18519 							ev_hdr->pdev_id);
18520 
18521 	hdr->channel = ev_hdr->channel;
18522 	hdr->snr = ev_hdr->snr;
18523 	hdr->rate = ev_hdr->rate;
18524 	hdr->phy_mode = ev_hdr->phy_mode;
18525 	hdr->buf_len = ev_hdr->buf_len;
18526 	hdr->status = ev_hdr->status;
18527 	hdr->flags = ev_hdr->flags;
18528 	hdr->rssi = ev_hdr->rssi;
18529 	hdr->tsf_delta = ev_hdr->tsf_delta;
18530 	for (i = 0; i < ATH_MAX_ANTENNA; i++)
18531 		hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i];
18532 
18533 	*bufp = param_tlvs->bufp;
18534 
18535 	return QDF_STATUS_SUCCESS;
18536 }
18537 
18538 /**
18539  * extract_vdev_stopped_param_tlv() - extract vdev stop param from event
18540  * @wmi_handle: wmi handle
18541  * @param evt_buf: pointer to event buffer
18542  * @param vdev_id: Pointer to hold vdev identifier
18543  *
18544  * Return: QDF_STATUS_SUCCESS for success or error code
18545  */
18546 static QDF_STATUS extract_vdev_stopped_param_tlv(wmi_unified_t wmi_handle,
18547 	void *evt_buf, uint32_t *vdev_id)
18548 {
18549 	WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf;
18550 	wmi_vdev_stopped_event_fixed_param *resp_event;
18551 
18552 	param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) evt_buf;
18553 	if (!param_buf) {
18554 		WMI_LOGE("Invalid event buffer");
18555 		return QDF_STATUS_E_INVAL;
18556 	}
18557 	resp_event = param_buf->fixed_param;
18558 	*vdev_id = resp_event->vdev_id;
18559 
18560 	return QDF_STATUS_SUCCESS;
18561 }
18562 
18563 /**
18564  * extract_vdev_roam_param_tlv() - extract vdev roam param from event
18565  * @wmi_handle: wmi handle
18566  * @param evt_buf: pointer to event buffer
18567  * @param param: Pointer to hold roam param
18568  *
18569  * Return: QDF_STATUS_SUCCESS for success or error code
18570  */
18571 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle,
18572 	void *evt_buf, wmi_host_roam_event *param)
18573 {
18574 	WMI_ROAM_EVENTID_param_tlvs *param_buf;
18575 	wmi_roam_event_fixed_param *evt;
18576 
18577 	param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf;
18578 	if (!param_buf) {
18579 		WMI_LOGE("Invalid roam event buffer");
18580 		return QDF_STATUS_E_INVAL;
18581 	}
18582 
18583 	evt = param_buf->fixed_param;
18584 	qdf_mem_zero(param, sizeof(*param));
18585 
18586 	param->vdev_id = evt->vdev_id;
18587 	param->reason = evt->reason;
18588 	param->rssi = evt->rssi;
18589 
18590 	return QDF_STATUS_SUCCESS;
18591 }
18592 
18593 /**
18594  * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event
18595  * @wmi_handle: wmi handle
18596  * @param evt_buf: pointer to event buffer
18597  * @param param: Pointer to hold vdev scan param
18598  *
18599  * Return: QDF_STATUS_SUCCESS for success or error code
18600  */
18601 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle,
18602 	void *evt_buf, struct scan_event *param)
18603 {
18604 	WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL;
18605 	wmi_scan_event_fixed_param *evt = NULL;
18606 
18607 	param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf;
18608 	evt = param_buf->fixed_param;
18609 
18610 	qdf_mem_zero(param, sizeof(*param));
18611 
18612 	switch (evt->event) {
18613 	case WMI_SCAN_EVENT_STARTED:
18614 		param->type = SCAN_EVENT_TYPE_STARTED;
18615 		break;
18616 	case WMI_SCAN_EVENT_COMPLETED:
18617 		param->type = SCAN_EVENT_TYPE_COMPLETED;
18618 		break;
18619 	case WMI_SCAN_EVENT_BSS_CHANNEL:
18620 		param->type = SCAN_EVENT_TYPE_BSS_CHANNEL;
18621 		break;
18622 	case WMI_SCAN_EVENT_FOREIGN_CHANNEL:
18623 		param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL;
18624 		break;
18625 	case WMI_SCAN_EVENT_DEQUEUED:
18626 		param->type = SCAN_EVENT_TYPE_DEQUEUED;
18627 		break;
18628 	case WMI_SCAN_EVENT_PREEMPTED:
18629 		param->type = SCAN_EVENT_TYPE_PREEMPTED;
18630 		break;
18631 	case WMI_SCAN_EVENT_START_FAILED:
18632 		param->type = SCAN_EVENT_TYPE_START_FAILED;
18633 		break;
18634 	case WMI_SCAN_EVENT_RESTARTED:
18635 		param->type = SCAN_EVENT_TYPE_RESTARTED;
18636 		break;
18637 	case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT:
18638 		param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT;
18639 		break;
18640 	case WMI_SCAN_EVENT_MAX:
18641 	default:
18642 		param->type = SCAN_EVENT_TYPE_MAX;
18643 		break;
18644 	};
18645 
18646 	switch (evt->reason) {
18647 	case WMI_SCAN_REASON_NONE:
18648 		param->reason = SCAN_REASON_NONE;
18649 		break;
18650 	case WMI_SCAN_REASON_COMPLETED:
18651 		param->reason = SCAN_REASON_COMPLETED;
18652 		break;
18653 	case WMI_SCAN_REASON_CANCELLED:
18654 		param->reason = SCAN_REASON_CANCELLED;
18655 		break;
18656 	case WMI_SCAN_REASON_PREEMPTED:
18657 		param->reason = SCAN_REASON_PREEMPTED;
18658 		break;
18659 	case WMI_SCAN_REASON_TIMEDOUT:
18660 		param->reason = SCAN_REASON_TIMEDOUT;
18661 		break;
18662 	case WMI_SCAN_REASON_INTERNAL_FAILURE:
18663 		param->reason = SCAN_REASON_INTERNAL_FAILURE;
18664 		break;
18665 	case WMI_SCAN_REASON_SUSPENDED:
18666 		param->reason = SCAN_REASON_SUSPENDED;
18667 		break;
18668 	case WMI_SCAN_REASON_MAX:
18669 		param->reason = SCAN_REASON_MAX;
18670 		break;
18671 	default:
18672 		param->reason = SCAN_REASON_MAX;
18673 		break;
18674 	};
18675 
18676 	param->chan_freq = evt->channel_freq;
18677 	param->requester = evt->requestor;
18678 	param->scan_id = evt->scan_id;
18679 	param->vdev_id = evt->vdev_id;
18680 	param->timestamp = evt->tsf_timestamp;
18681 
18682 	return QDF_STATUS_SUCCESS;
18683 }
18684 
18685 #ifdef CONVERGED_TDLS_ENABLE
18686 /**
18687  * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event
18688  * @wmi_handle: wmi handle
18689  * @param evt_buf: pointer to event buffer
18690  * @param param: Pointer to hold vdev tdls param
18691  *
18692  * Return: QDF_STATUS_SUCCESS for success or error code
18693  */
18694 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle,
18695 	void *evt_buf, struct tdls_event_info *param)
18696 {
18697 	WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf;
18698 	wmi_tdls_peer_event_fixed_param *evt;
18699 
18700 	param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf;
18701 	if (!param_buf) {
18702 		WMI_LOGE("%s: NULL param_buf", __func__);
18703 		return QDF_STATUS_E_NULL_VALUE;
18704 	}
18705 
18706 	evt = param_buf->fixed_param;
18707 
18708 	qdf_mem_zero(param, sizeof(*param));
18709 
18710 	param->vdev_id = evt->vdev_id;
18711 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr,
18712 				   param->peermac.bytes);
18713 	switch (evt->peer_status) {
18714 	case WMI_TDLS_SHOULD_DISCOVER:
18715 		param->message_type = TDLS_SHOULD_DISCOVER;
18716 		break;
18717 	case WMI_TDLS_SHOULD_TEARDOWN:
18718 		param->message_type = TDLS_SHOULD_TEARDOWN;
18719 		break;
18720 	case WMI_TDLS_PEER_DISCONNECTED:
18721 		param->message_type = TDLS_PEER_DISCONNECTED;
18722 		break;
18723 	case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION:
18724 		param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY;
18725 		break;
18726 	default:
18727 		WMI_LOGE("%s: Discarding unknown tdls event %d from target",
18728 			 __func__, evt->peer_status);
18729 		return QDF_STATUS_E_INVAL;
18730 	};
18731 
18732 	switch (evt->peer_reason) {
18733 	case WMI_TDLS_TEARDOWN_REASON_TX:
18734 		param->peer_reason = TDLS_TEARDOWN_TX;
18735 		break;
18736 	case WMI_TDLS_TEARDOWN_REASON_RSSI:
18737 		param->peer_reason = TDLS_TEARDOWN_RSSI;
18738 		break;
18739 	case WMI_TDLS_TEARDOWN_REASON_SCAN:
18740 		param->peer_reason = TDLS_TEARDOWN_SCAN;
18741 		break;
18742 	case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE:
18743 		param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE;
18744 		break;
18745 	case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
18746 		param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT;
18747 		break;
18748 	case WMI_TDLS_TEARDOWN_REASON_BAD_PTR:
18749 		param->peer_reason = TDLS_TEARDOWN_BAD_PTR;
18750 		break;
18751 	case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
18752 		param->peer_reason = TDLS_TEARDOWN_NO_RSP;
18753 		break;
18754 	case WMI_TDLS_ENTER_BUF_STA:
18755 		param->peer_reason = TDLS_PEER_ENTER_BUF_STA;
18756 		break;
18757 	case WMI_TDLS_EXIT_BUF_STA:
18758 		param->peer_reason = TDLS_PEER_EXIT_BUF_STA;
18759 		break;
18760 	case WMI_TDLS_ENTER_BT_BUSY_MODE:
18761 		param->peer_reason = TDLS_ENTER_BT_BUSY;
18762 		break;
18763 	case WMI_TDLS_EXIT_BT_BUSY_MODE:
18764 		param->peer_reason = TDLS_EXIT_BT_BUSY;
18765 		break;
18766 	case WMI_TDLS_SCAN_STARTED_EVENT:
18767 		param->peer_reason = TDLS_SCAN_STARTED;
18768 		break;
18769 	case WMI_TDLS_SCAN_COMPLETED_EVENT:
18770 		param->peer_reason = TDLS_SCAN_COMPLETED;
18771 		break;
18772 
18773 	default:
18774 		WMI_LOGE("%s: unknown reason %d in tdls event %d from target",
18775 			 __func__, evt->peer_reason, evt->peer_status);
18776 		return QDF_STATUS_E_INVAL;
18777 	};
18778 
18779 	WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d",
18780 		 __func__, param->peermac.bytes, param->message_type,
18781 		 param->peer_reason, param->vdev_id);
18782 
18783 	return QDF_STATUS_SUCCESS;
18784 }
18785 #endif
18786 
18787 /**
18788  * extract_mgmt_tx_compl_param_tlv() - extract MGMT tx completion event params
18789  * @wmi_handle: wmi handle
18790  * @param evt_buf: pointer to event buffer
18791  * @param param: Pointer to hold MGMT TX completion params
18792  *
18793  * Return: QDF_STATUS_SUCCESS for success or error code
18794  */
18795 static QDF_STATUS extract_mgmt_tx_compl_param_tlv(wmi_unified_t wmi_handle,
18796 	void *evt_buf, wmi_host_mgmt_tx_compl_event *param)
18797 {
18798 	WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf;
18799 	wmi_mgmt_tx_compl_event_fixed_param *cmpl_params;
18800 
18801 	param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *)
18802 		evt_buf;
18803 	if (!param_buf) {
18804 		WMI_LOGE("%s: Invalid mgmt Tx completion event", __func__);
18805 		return QDF_STATUS_E_INVAL;
18806 	}
18807 	cmpl_params = param_buf->fixed_param;
18808 
18809 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18810 							cmpl_params->pdev_id);
18811 	param->desc_id = cmpl_params->desc_id;
18812 	param->status = cmpl_params->status;
18813 
18814 	return QDF_STATUS_SUCCESS;
18815 }
18816 
18817 /**
18818  * extract_offchan_data_tx_compl_param_tlv() -
18819  *            extract Offchan data tx completion event params
18820  * @wmi_handle: wmi handle
18821  * @param evt_buf: pointer to event buffer
18822  * @param param: Pointer to hold offchan data TX completion params
18823  *
18824  * Return: QDF_STATUS_SUCCESS for success or error code
18825  */
18826 static QDF_STATUS extract_offchan_data_tx_compl_param_tlv(
18827 		wmi_unified_t wmi_handle, void *evt_buf,
18828 		struct wmi_host_offchan_data_tx_compl_event *param)
18829 {
18830 	WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *param_buf;
18831 	wmi_offchan_data_tx_compl_event_fixed_param *cmpl_params;
18832 
18833 	param_buf = (WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *)
18834 		evt_buf;
18835 	if (!param_buf) {
18836 		WMI_LOGE("%s: Invalid offchan data Tx compl event", __func__);
18837 		return QDF_STATUS_E_INVAL;
18838 	}
18839 	cmpl_params = param_buf->fixed_param;
18840 
18841 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18842 							cmpl_params->pdev_id);
18843 	param->desc_id = cmpl_params->desc_id;
18844 	param->status = cmpl_params->status;
18845 
18846 	return QDF_STATUS_SUCCESS;
18847 }
18848 
18849 /**
18850  * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count
18851  *                                              status tlv
18852  * @wmi_handle: wmi handle
18853  * @param evt_buf: pointer to event buffer
18854  * @param param: Pointer to hold csa switch count status event param
18855  *
18856  * Return: QDF_STATUS_SUCCESS for success or error code
18857  */
18858 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv(
18859 				wmi_unified_t wmi_handle,
18860 				void *evt_buf,
18861 				struct pdev_csa_switch_count_status *param)
18862 {
18863 	WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf;
18864 	wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status;
18865 
18866 	param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *)
18867 		     evt_buf;
18868 	if (!param_buf) {
18869 		WMI_LOGE("%s: Invalid CSA status event\n", __func__);
18870 		return QDF_STATUS_E_INVAL;
18871 	}
18872 
18873 	csa_status = param_buf->fixed_param;
18874 
18875 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
18876 							csa_status->pdev_id);
18877 	param->current_switch_count = csa_status->current_switch_count;
18878 	param->num_vdevs = csa_status->num_vdevs;
18879 	param->vdev_ids = param_buf->vdev_ids;
18880 
18881 	return QDF_STATUS_SUCCESS;
18882 }
18883 
18884 /**
18885  * extract_pdev_tpc_config_ev_param_tlv() - extract pdev tpc configuration
18886  * param from event
18887  * @wmi_handle: wmi handle
18888  * @param evt_buf: pointer to event buffer
18889  * @param param: Pointer to hold tpc configuration
18890  *
18891  * Return: 0 for success or error code
18892  */
18893 static QDF_STATUS extract_pdev_tpc_config_ev_param_tlv(wmi_unified_t wmi_handle,
18894 		void *evt_buf,
18895 		wmi_host_pdev_tpc_config_event *param)
18896 {
18897 	wmi_pdev_tpc_config_event_fixed_param *event =
18898 		(wmi_pdev_tpc_config_event_fixed_param *)evt_buf;
18899 
18900 	if (!event) {
18901 		WMI_LOGE("Invalid event buffer");
18902 		return QDF_STATUS_E_INVAL;
18903 	}
18904 
18905 	param->pdev_id = event->pdev_id;
18906 	param->regDomain = event->regDomain;
18907 	param->chanFreq = event->chanFreq;
18908 	param->phyMode = event->phyMode;
18909 	param->twiceAntennaReduction = event->twiceAntennaReduction;
18910 	param->twiceMaxRDPower = event->twiceMaxRDPower;
18911 	param->powerLimit = event->powerLimit;
18912 	param->rateMax = event->rateMax;
18913 	param->numTxChain = event->numTxChain;
18914 	param->ctl = event->ctl;
18915 	param->flags = event->flags;
18916 
18917 	qdf_mem_copy(param->maxRegAllowedPower, event->maxRegAllowedPower,
18918 		sizeof(param->maxRegAllowedPower));
18919 	qdf_mem_copy(param->maxRegAllowedPowerAGCDD,
18920 		event->maxRegAllowedPowerAGCDD,
18921 		sizeof(param->maxRegAllowedPowerAGCDD));
18922 	qdf_mem_copy(param->maxRegAllowedPowerAGSTBC,
18923 		event->maxRegAllowedPowerAGSTBC,
18924 		sizeof(param->maxRegAllowedPowerAGSTBC));
18925 	qdf_mem_copy(param->maxRegAllowedPowerAGTXBF,
18926 		event->maxRegAllowedPowerAGTXBF,
18927 		sizeof(param->maxRegAllowedPowerAGTXBF));
18928 	WMI_LOGD("%s:extract success", __func__);
18929 
18930 	return QDF_STATUS_SUCCESS;
18931 }
18932 
18933 /**
18934  * extract_swba_num_vdevs_tlv() - extract swba num vdevs from event
18935  * @wmi_handle: wmi handle
18936  * @param evt_buf: pointer to event buffer
18937  * @param num_vdevs: Pointer to hold num vdevs
18938  *
18939  * Return: QDF_STATUS_SUCCESS for success or error code
18940  */
18941 static QDF_STATUS extract_swba_num_vdevs_tlv(wmi_unified_t wmi_handle,
18942 	void *evt_buf, uint32_t *num_vdevs)
18943 {
18944 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
18945 	wmi_host_swba_event_fixed_param *swba_event;
18946 	uint32_t vdev_map;
18947 
18948 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf;
18949 	if (!param_buf) {
18950 		WMI_LOGE("Invalid swba event buffer");
18951 		return QDF_STATUS_E_INVAL;
18952 	}
18953 
18954 	swba_event = param_buf->fixed_param;
18955 	*num_vdevs = swba_event->num_vdevs;
18956 	if (!(*num_vdevs)) {
18957 		vdev_map = swba_event->vdev_map;
18958 		*num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map);
18959 	}
18960 
18961 	return QDF_STATUS_SUCCESS;
18962 }
18963 
18964 /**
18965  * extract_swba_tim_info_tlv() - extract swba tim info from event
18966  * @wmi_handle: wmi handle
18967  * @param evt_buf: pointer to event buffer
18968  * @param idx: Index to bcn info
18969  * @param tim_info: Pointer to hold tim info
18970  *
18971  * Return: QDF_STATUS_SUCCESS for success or error code
18972  */
18973 static QDF_STATUS extract_swba_tim_info_tlv(wmi_unified_t wmi_handle,
18974 	void *evt_buf, uint32_t idx, wmi_host_tim_info *tim_info)
18975 {
18976 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
18977 	wmi_tim_info *tim_info_ev;
18978 
18979 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf;
18980 	if (!param_buf) {
18981 		WMI_LOGE("Invalid swba event buffer");
18982 		return QDF_STATUS_E_INVAL;
18983 	}
18984 
18985 	tim_info_ev = &param_buf->tim_info[idx];
18986 
18987 	tim_info->tim_len = tim_info_ev->tim_len;
18988 	tim_info->tim_mcast = tim_info_ev->tim_mcast;
18989 	qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap,
18990 			(sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE));
18991 	tim_info->tim_changed = tim_info_ev->tim_changed;
18992 	tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending;
18993 	tim_info->vdev_id = tim_info_ev->vdev_id;
18994 
18995 	return QDF_STATUS_SUCCESS;
18996 }
18997 
18998 /**
18999  * extract_swba_noa_info_tlv() - extract swba NoA information from event
19000  * @wmi_handle: wmi handle
19001  * @param evt_buf: pointer to event buffer
19002  * @param idx: Index to bcn info
19003  * @param p2p_desc: Pointer to hold p2p NoA info
19004  *
19005  * Return: QDF_STATUS_SUCCESS for success or error code
19006  */
19007 static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle,
19008 	void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc)
19009 {
19010 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
19011 	wmi_p2p_noa_info *p2p_noa_info;
19012 	uint8_t i = 0;
19013 
19014 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf;
19015 	if (!param_buf) {
19016 		WMI_LOGE("Invalid swba event buffer");
19017 		return QDF_STATUS_E_INVAL;
19018 	}
19019 
19020 	p2p_noa_info = &param_buf->p2p_noa_info[idx];
19021 
19022 	p2p_desc->modified = false;
19023 	p2p_desc->num_descriptors = 0;
19024 	if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) {
19025 		p2p_desc->modified = true;
19026 		p2p_desc->index =
19027 			(uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info);
19028 		p2p_desc->oppPS =
19029 			(uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info);
19030 		p2p_desc->ctwindow =
19031 			(uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info);
19032 		p2p_desc->num_descriptors =
19033 			(uint8_t) WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET
19034 							(p2p_noa_info);
19035 		for (i = 0; i < p2p_desc->num_descriptors; i++) {
19036 			p2p_desc->noa_descriptors[i].type_count =
19037 				(uint8_t) p2p_noa_info->noa_descriptors[i].
19038 				type_count;
19039 			p2p_desc->noa_descriptors[i].duration =
19040 				p2p_noa_info->noa_descriptors[i].duration;
19041 			p2p_desc->noa_descriptors[i].interval =
19042 				p2p_noa_info->noa_descriptors[i].interval;
19043 			p2p_desc->noa_descriptors[i].start_time =
19044 				p2p_noa_info->noa_descriptors[i].start_time;
19045 		}
19046 		p2p_desc->vdev_id = p2p_noa_info->vdev_id;
19047 	}
19048 
19049 	return QDF_STATUS_SUCCESS;
19050 }
19051 
19052 #ifdef CONVERGED_P2P_ENABLE
19053 /**
19054  * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event
19055  * @wmi_handle: wmi handle
19056  * @param evt_buf: pointer to event buffer
19057  * @param param: Pointer to hold p2p noa info
19058  *
19059  * Return: QDF_STATUS_SUCCESS for success or error code
19060  */
19061 static QDF_STATUS extract_p2p_noa_ev_param_tlv(
19062 	wmi_unified_t wmi_handle, void *evt_buf,
19063 	struct p2p_noa_info *param)
19064 {
19065 	WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs;
19066 	wmi_p2p_noa_event_fixed_param *fixed_param;
19067 	uint8_t i;
19068 	wmi_p2p_noa_info *wmi_noa_info;
19069 	uint8_t *buf_ptr;
19070 	uint32_t descriptors;
19071 
19072 	param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf;
19073 	if (!param_tlvs) {
19074 		WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__);
19075 		return QDF_STATUS_E_INVAL;
19076 	}
19077 
19078 	if (!param) {
19079 		WMI_LOGE("noa information param is null");
19080 		return QDF_STATUS_E_INVAL;
19081 	}
19082 
19083 	fixed_param = param_tlvs->fixed_param;
19084 	buf_ptr = (uint8_t *) fixed_param;
19085 	buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param);
19086 	wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr);
19087 
19088 	if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) {
19089 		WMI_LOGE("%s: noa attr is not modified", __func__);
19090 		return QDF_STATUS_E_INVAL;
19091 	}
19092 
19093 	param->vdev_id = fixed_param->vdev_id;
19094 	param->index =
19095 		(uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info);
19096 	param->opps_ps =
19097 		(uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info);
19098 	param->ct_window =
19099 		(uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info);
19100 	descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info);
19101 	param->num_desc = (uint8_t) descriptors;
19102 
19103 	WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__,
19104 		param->index, param->opps_ps, param->ct_window,
19105 		param->num_desc);
19106 	for (i = 0; i < param->num_desc; i++) {
19107 		param->noa_desc[i].type_count =
19108 			(uint8_t) wmi_noa_info->noa_descriptors[i].
19109 			type_count;
19110 		param->noa_desc[i].duration =
19111 			wmi_noa_info->noa_descriptors[i].duration;
19112 		param->noa_desc[i].interval =
19113 			wmi_noa_info->noa_descriptors[i].interval;
19114 		param->noa_desc[i].start_time =
19115 			wmi_noa_info->noa_descriptors[i].start_time;
19116 		WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u",
19117 			__func__, i, param->noa_desc[i].type_count,
19118 			param->noa_desc[i].duration,
19119 			param->noa_desc[i].interval,
19120 			param->noa_desc[i].start_time);
19121 	}
19122 
19123 	return QDF_STATUS_SUCCESS;
19124 }
19125 
19126 /**
19127  * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop
19128  * information from event
19129  * @wmi_handle: wmi handle
19130  * @param evt_buf: pointer to event buffer
19131  * @param param: Pointer to hold p2p lo stop event information
19132  *
19133  * Return: QDF_STATUS_SUCCESS for success or error code
19134  */
19135 static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv(
19136 	wmi_unified_t wmi_handle, void *evt_buf,
19137 	struct p2p_lo_event *param)
19138 {
19139 	WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs;
19140 	wmi_p2p_lo_stopped_event_fixed_param *lo_param;
19141 
19142 	param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *)
19143 					evt_buf;
19144 	if (!param_tlvs) {
19145 		WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__);
19146 		return QDF_STATUS_E_INVAL;
19147 	}
19148 
19149 	if (!param) {
19150 		WMI_LOGE("lo stop event param is null");
19151 		return QDF_STATUS_E_INVAL;
19152 	}
19153 
19154 	lo_param = param_tlvs->fixed_param;
19155 	param->vdev_id = lo_param->vdev_id;
19156 	param->reason_code = lo_param->reason;
19157 	WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__,
19158 		param->vdev_id, param->reason_code);
19159 
19160 	return QDF_STATUS_SUCCESS;
19161 }
19162 #endif /* End of CONVERGED_P2P_ENABLE */
19163 
19164 /**
19165  * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event
19166  * @wmi_handle: wmi handle
19167  * @param evt_buf: pointer to event buffer
19168  * @param ev: Pointer to hold peer param
19169  *
19170  * Return: QDF_STATUS_SUCCESS for success or error code
19171  */
19172 static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle,
19173 	void *evt_buf, wmi_host_peer_sta_kickout_event *ev)
19174 {
19175 	WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL;
19176 	wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL;
19177 
19178 	param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) evt_buf;
19179 	kickout_event = param_buf->fixed_param;
19180 
19181 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr,
19182 							ev->peer_macaddr);
19183 
19184 	ev->reason = kickout_event->reason;
19185 	ev->rssi = kickout_event->rssi;
19186 
19187 	return QDF_STATUS_SUCCESS;
19188 }
19189 
19190 /**
19191  * extract_all_stats_counts_tlv() - extract all stats count from event
19192  * @wmi_handle: wmi handle
19193  * @param evt_buf: pointer to event buffer
19194  * @param stats_param: Pointer to hold stats count
19195  *
19196  * Return: QDF_STATUS_SUCCESS for success or error code
19197  */
19198 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle,
19199 	void *evt_buf, wmi_host_stats_event *stats_param)
19200 {
19201 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19202 	wmi_stats_event_fixed_param *ev;
19203 
19204 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19205 
19206 	ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19207 	if (!ev) {
19208 		WMI_LOGE("%s: Failed to alloc memory\n", __func__);
19209 		return QDF_STATUS_E_FAILURE;
19210 	}
19211 
19212 	switch (ev->stats_id) {
19213 	case WMI_REQUEST_PEER_STAT:
19214 		stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT;
19215 		break;
19216 
19217 	case WMI_REQUEST_AP_STAT:
19218 		stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT;
19219 		break;
19220 
19221 	case WMI_REQUEST_PDEV_STAT:
19222 		stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT;
19223 		break;
19224 
19225 	case WMI_REQUEST_VDEV_STAT:
19226 		stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT;
19227 		break;
19228 
19229 	case WMI_REQUEST_BCNFLT_STAT:
19230 		stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT;
19231 		break;
19232 
19233 	case WMI_REQUEST_VDEV_RATE_STAT:
19234 		stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT;
19235 		break;
19236 
19237 	case WMI_REQUEST_BCN_STAT:
19238 		stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT;
19239 		break;
19240 
19241 	default:
19242 		stats_param->stats_id = 0;
19243 		break;
19244 
19245 	}
19246 
19247 	stats_param->num_pdev_stats = ev->num_pdev_stats;
19248 	stats_param->num_pdev_ext_stats = 0;
19249 	stats_param->num_vdev_stats = ev->num_vdev_stats;
19250 	stats_param->num_peer_stats = ev->num_peer_stats;
19251 	stats_param->num_bcnflt_stats = ev->num_bcnflt_stats;
19252 	stats_param->num_chan_stats = ev->num_chan_stats;
19253 	stats_param->num_bcn_stats = ev->num_bcn_stats;
19254 	stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19255 							ev->pdev_id);
19256 
19257 	return QDF_STATUS_SUCCESS;
19258 }
19259 
19260 /**
19261  * extract_pdev_tx_stats() - extract pdev tx stats from event
19262  */
19263 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, struct wlan_dbg_tx_stats *tx_stats)
19264 {
19265 	/* Tx Stats */
19266 	tx->comp_queued = tx_stats->comp_queued;
19267 	tx->comp_delivered = tx_stats->comp_delivered;
19268 	tx->msdu_enqued = tx_stats->msdu_enqued;
19269 	tx->mpdu_enqued = tx_stats->mpdu_enqued;
19270 	tx->wmm_drop = tx_stats->wmm_drop;
19271 	tx->local_enqued = tx_stats->local_enqued;
19272 	tx->local_freed = tx_stats->local_freed;
19273 	tx->hw_queued = tx_stats->hw_queued;
19274 	tx->hw_reaped = tx_stats->hw_reaped;
19275 	tx->underrun = tx_stats->underrun;
19276 	tx->tx_abort = tx_stats->tx_abort;
19277 	tx->mpdus_requed = tx_stats->mpdus_requed;
19278 	tx->data_rc = tx_stats->data_rc;
19279 	tx->self_triggers = tx_stats->self_triggers;
19280 	tx->sw_retry_failure = tx_stats->sw_retry_failure;
19281 	tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err;
19282 	tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry;
19283 	tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout;
19284 	tx->pdev_resets = tx_stats->pdev_resets;
19285 	tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure;
19286 	tx->phy_underrun = tx_stats->phy_underrun;
19287 	tx->txop_ovf = tx_stats->txop_ovf;
19288 
19289 	return;
19290 }
19291 
19292 
19293 /**
19294  * extract_pdev_rx_stats() - extract pdev rx stats from event
19295  */
19296 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, struct wlan_dbg_rx_stats *rx_stats)
19297 {
19298 	/* Rx Stats */
19299 	rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change;
19300 	rx->status_rcvd = rx_stats->status_rcvd;
19301 	rx->r0_frags = rx_stats->r0_frags;
19302 	rx->r1_frags = rx_stats->r1_frags;
19303 	rx->r2_frags = rx_stats->r2_frags;
19304 	/* Only TLV */
19305 	rx->r3_frags = 0;
19306 	rx->htt_msdus = rx_stats->htt_msdus;
19307 	rx->htt_mpdus = rx_stats->htt_mpdus;
19308 	rx->loc_msdus = rx_stats->loc_msdus;
19309 	rx->loc_mpdus = rx_stats->loc_mpdus;
19310 	rx->oversize_amsdu = rx_stats->oversize_amsdu;
19311 	rx->phy_errs = rx_stats->phy_errs;
19312 	rx->phy_err_drop = rx_stats->phy_err_drop;
19313 	rx->mpdu_errs = rx_stats->mpdu_errs;
19314 
19315 	return;
19316 }
19317 
19318 /**
19319  * extract_pdev_stats_tlv() - extract pdev stats from event
19320  * @wmi_handle: wmi handle
19321  * @param evt_buf: pointer to event buffer
19322  * @param index: Index into pdev stats
19323  * @param pdev_stats: Pointer to hold pdev stats
19324  *
19325  * Return: QDF_STATUS_SUCCESS for success or error code
19326  */
19327 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle,
19328 	void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats)
19329 {
19330 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19331 	wmi_stats_event_fixed_param *ev_param;
19332 	uint8_t *data;
19333 
19334 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19335 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19336 
19337 	data = param_buf->data;
19338 
19339 	if (index < ev_param->num_pdev_stats) {
19340 		wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) +
19341 				(index * sizeof(wmi_pdev_stats)));
19342 
19343 		pdev_stats->chan_nf = ev->chan_nf;
19344 		pdev_stats->tx_frame_count = ev->tx_frame_count;
19345 		pdev_stats->rx_frame_count = ev->rx_frame_count;
19346 		pdev_stats->rx_clear_count = ev->rx_clear_count;
19347 		pdev_stats->cycle_count = ev->cycle_count;
19348 		pdev_stats->phy_err_count = ev->phy_err_count;
19349 		pdev_stats->chan_tx_pwr = ev->chan_tx_pwr;
19350 
19351 		extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx),
19352 			&(ev->pdev_stats.tx));
19353 		extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx),
19354 			&(ev->pdev_stats.rx));
19355 	}
19356 
19357 	return QDF_STATUS_SUCCESS;
19358 }
19359 
19360 /**
19361  * extract_unit_test_tlv() - extract unit test data
19362  * @wmi_handle: wmi handle
19363  * @param evt_buf: pointer to event buffer
19364  * @param unit_test: pointer to hold unit test data
19365  * @param maxspace: Amount of space in evt_buf
19366  *
19367  * Return: QDF_STATUS_SUCCESS for success or error code
19368  */
19369 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle,
19370 	void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace)
19371 {
19372 	WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf;
19373 	wmi_unit_test_event_fixed_param *ev_param;
19374 	uint32_t num_bufp;
19375 	uint32_t copy_size;
19376 	uint8_t *bufp;
19377 
19378 	param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf;
19379 	ev_param = param_buf->fixed_param;
19380 	bufp = param_buf->bufp;
19381 	num_bufp = param_buf->num_bufp;
19382 	unit_test->vdev_id = ev_param->vdev_id;
19383 	unit_test->module_id = ev_param->module_id;
19384 	unit_test->diag_token = ev_param->diag_token;
19385 	unit_test->flag = ev_param->flag;
19386 	unit_test->payload_len = ev_param->payload_len;
19387 	WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d\n", __func__,
19388 			ev_param->vdev_id,
19389 			ev_param->module_id,
19390 			ev_param->diag_token,
19391 			ev_param->flag);
19392 	WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp);
19393 	qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
19394 			bufp, num_bufp);
19395 	copy_size = (num_bufp < maxspace) ? num_bufp : maxspace;
19396 	qdf_mem_copy(unit_test->buffer, bufp, copy_size);
19397 	unit_test->buffer_len = copy_size;
19398 
19399 	return QDF_STATUS_SUCCESS;
19400 }
19401 
19402 /**
19403  * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event
19404  * @wmi_handle: wmi handle
19405  * @param evt_buf: pointer to event buffer
19406  * @param index: Index into extended pdev stats
19407  * @param pdev_ext_stats: Pointer to hold extended pdev stats
19408  *
19409  * Return: QDF_STATUS_SUCCESS for success or error code
19410  */
19411 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle,
19412 	void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats)
19413 {
19414 	return QDF_STATUS_SUCCESS;
19415 }
19416 
19417 /**
19418  * extract_vdev_stats_tlv() - extract vdev stats from event
19419  * @wmi_handle: wmi handle
19420  * @param evt_buf: pointer to event buffer
19421  * @param index: Index into vdev stats
19422  * @param vdev_stats: Pointer to hold vdev stats
19423  *
19424  * Return: QDF_STATUS_SUCCESS for success or error code
19425  */
19426 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle,
19427 	void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats)
19428 {
19429 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19430 	wmi_stats_event_fixed_param *ev_param;
19431 	uint8_t *data;
19432 
19433 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19434 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19435 	data = (uint8_t *) param_buf->data;
19436 
19437 	if (index < ev_param->num_vdev_stats) {
19438 		wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) +
19439 				((ev_param->num_pdev_stats) *
19440 				sizeof(wmi_pdev_stats)) +
19441 				(index * sizeof(wmi_vdev_stats)));
19442 
19443 		vdev_stats->vdev_id = ev->vdev_id;
19444 		vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr;
19445 		vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr;
19446 
19447 		OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt,
19448 			sizeof(ev->tx_frm_cnt));
19449 		vdev_stats->rx_frm_cnt = ev->rx_frm_cnt;
19450 		OS_MEMCPY(vdev_stats->multiple_retry_cnt,
19451 				ev->multiple_retry_cnt,
19452 				sizeof(ev->multiple_retry_cnt));
19453 		OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt,
19454 				sizeof(ev->fail_cnt));
19455 		vdev_stats->rts_fail_cnt = ev->rts_fail_cnt;
19456 		vdev_stats->rts_succ_cnt = ev->rts_succ_cnt;
19457 		vdev_stats->rx_err_cnt = ev->rx_err_cnt;
19458 		vdev_stats->rx_discard_cnt = ev->rx_discard_cnt;
19459 		vdev_stats->ack_fail_cnt = ev->ack_fail_cnt;
19460 		OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history,
19461 			sizeof(ev->tx_rate_history));
19462 		OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history,
19463 			sizeof(ev->bcn_rssi_history));
19464 
19465 	}
19466 
19467 	return QDF_STATUS_SUCCESS;
19468 }
19469 
19470 /**
19471  * extract_bcn_stats_tlv() - extract bcn stats from event
19472  * @wmi_handle: wmi handle
19473  * @param evt_buf: pointer to event buffer
19474  * @param index: Index into vdev stats
19475  * @param bcn_stats: Pointer to hold bcn stats
19476  *
19477  * Return: QDF_STATUS_SUCCESS for success or error code
19478  */
19479 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle,
19480 	void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats)
19481 {
19482 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19483 	wmi_stats_event_fixed_param *ev_param;
19484 	uint8_t *data;
19485 
19486 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19487 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19488 	data = (uint8_t *) param_buf->data;
19489 
19490 	if (index < ev_param->num_bcn_stats) {
19491 		wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) +
19492 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19493 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19494 			((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) +
19495 			((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) +
19496 			((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) +
19497 			(index * sizeof(wmi_bcn_stats)));
19498 
19499 		bcn_stats->vdev_id = ev->vdev_id;
19500 		bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt;
19501 		bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt;
19502 	}
19503 
19504 	return QDF_STATUS_SUCCESS;
19505 }
19506 
19507 /**
19508  * extract_peer_stats_tlv() - extract peer stats from event
19509  * @wmi_handle: wmi handle
19510  * @param evt_buf: pointer to event buffer
19511  * @param index: Index into peer stats
19512  * @param peer_stats: Pointer to hold peer stats
19513  *
19514  * Return: QDF_STATUS_SUCCESS for success or error code
19515  */
19516 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle,
19517 	void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats)
19518 {
19519 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19520 	wmi_stats_event_fixed_param *ev_param;
19521 	uint8_t *data;
19522 
19523 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19524 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19525 	data = (uint8_t *) param_buf->data;
19526 
19527 	if (index < ev_param->num_peer_stats) {
19528 		wmi_peer_stats *ev = (wmi_peer_stats *) ((data) +
19529 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19530 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19531 			(index * sizeof(wmi_peer_stats)));
19532 
19533 		OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats));
19534 
19535 		OS_MEMCPY(&(peer_stats->peer_macaddr),
19536 			&(ev->peer_macaddr), sizeof(wmi_mac_addr));
19537 
19538 		peer_stats->peer_rssi = ev->peer_rssi;
19539 		peer_stats->peer_tx_rate = ev->peer_tx_rate;
19540 		peer_stats->peer_rx_rate = ev->peer_rx_rate;
19541 	}
19542 
19543 	return QDF_STATUS_SUCCESS;
19544 }
19545 
19546 /**
19547  * extract_bcnflt_stats_tlv() - extract bcn fault stats from event
19548  * @wmi_handle: wmi handle
19549  * @param evt_buf: pointer to event buffer
19550  * @param index: Index into bcn fault stats
19551  * @param bcnflt_stats: Pointer to hold bcn fault stats
19552  *
19553  * Return: QDF_STATUS_SUCCESS for success or error code
19554  */
19555 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle,
19556 	void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats)
19557 {
19558 	return QDF_STATUS_SUCCESS;
19559 }
19560 
19561 /**
19562  * extract_peer_extd_stats_tlv() - extract extended peer stats from event
19563  * @wmi_handle: wmi handle
19564  * @param evt_buf: pointer to event buffer
19565  * @param index: Index into extended peer stats
19566  * @param peer_extd_stats: Pointer to hold extended peer stats
19567  *
19568  * Return: QDF_STATUS_SUCCESS for success or error code
19569  */
19570 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle,
19571 		void *evt_buf, uint32_t index,
19572 		wmi_host_peer_extd_stats *peer_extd_stats)
19573 {
19574 	return QDF_STATUS_SUCCESS;
19575 }
19576 
19577 /**
19578  * extract_chan_stats_tlv() - extract chan stats from event
19579  * @wmi_handle: wmi handle
19580  * @param evt_buf: pointer to event buffer
19581  * @param index: Index into chan stats
19582  * @param vdev_extd_stats: Pointer to hold chan stats
19583  *
19584  * Return: QDF_STATUS_SUCCESS for success or error code
19585  */
19586 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle,
19587 	void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats)
19588 {
19589 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
19590 	wmi_stats_event_fixed_param *ev_param;
19591 	uint8_t *data;
19592 
19593 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
19594 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
19595 	data = (uint8_t *) param_buf->data;
19596 
19597 	if (index < ev_param->num_chan_stats) {
19598 		wmi_chan_stats *ev = (wmi_chan_stats *) ((data) +
19599 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
19600 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
19601 			((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) +
19602 			(index * sizeof(wmi_chan_stats)));
19603 
19604 
19605 		/* Non-TLV doesnt have num_chan_stats */
19606 		chan_stats->chan_mhz = ev->chan_mhz;
19607 		chan_stats->sampling_period_us = ev->sampling_period_us;
19608 		chan_stats->rx_clear_count = ev->rx_clear_count;
19609 		chan_stats->tx_duration_us = ev->tx_duration_us;
19610 		chan_stats->rx_duration_us = ev->rx_duration_us;
19611 	}
19612 
19613 	return QDF_STATUS_SUCCESS;
19614 }
19615 
19616 /**
19617  * extract_profile_ctx_tlv() - extract profile context from event
19618  * @wmi_handle: wmi handle
19619  * @param evt_buf: pointer to event buffer
19620  * @idx: profile stats index to extract
19621  * @param profile_ctx: Pointer to hold profile context
19622  *
19623  * Return: QDF_STATUS_SUCCESS for success or error code
19624  */
19625 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle,
19626 	void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx)
19627 {
19628 	return QDF_STATUS_SUCCESS;
19629 }
19630 
19631 /**
19632  * extract_profile_data_tlv() - extract profile data from event
19633  * @wmi_handle: wmi handle
19634  * @param evt_buf: pointer to event buffer
19635  * @param profile_data: Pointer to hold profile data
19636  *
19637  * Return: QDF_STATUS_SUCCESS for success or error code
19638  */
19639 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle,
19640 	void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data)
19641 {
19642 
19643 	return QDF_STATUS_SUCCESS;
19644 }
19645 
19646 /**
19647  * extract_chan_info_event_tlv() - extract chan information from event
19648  * @wmi_handle: wmi handle
19649  * @param evt_buf: pointer to event buffer
19650  * @param chan_info: Pointer to hold chan information
19651  *
19652  * Return: QDF_STATUS_SUCCESS for success or error code
19653  */
19654 static QDF_STATUS extract_chan_info_event_tlv(wmi_unified_t wmi_handle,
19655 	void *evt_buf, wmi_host_chan_info_event *chan_info)
19656 {
19657 	WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf;
19658 	wmi_chan_info_event_fixed_param *ev;
19659 
19660 	param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) evt_buf;
19661 
19662 	ev = (wmi_chan_info_event_fixed_param *) param_buf->fixed_param;
19663 	if (!ev) {
19664 		WMI_LOGE("%s: Failed to allocmemory\n", __func__);
19665 		return QDF_STATUS_E_FAILURE;
19666 	}
19667 
19668 	chan_info->err_code = ev->err_code;
19669 	chan_info->freq = ev->freq;
19670 	chan_info->cmd_flags = ev->cmd_flags;
19671 	chan_info->noise_floor = ev->noise_floor;
19672 	chan_info->rx_clear_count = ev->rx_clear_count;
19673 	chan_info->cycle_count = ev->cycle_count;
19674 	chan_info->tx_frame_cnt = ev->tx_frame_cnt;
19675 	chan_info->mac_clk_mhz = ev->mac_clk_mhz;
19676 	chan_info->pdev_id = wlan_get_pdev_id_from_vdev_id(
19677 			(struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc,
19678 			ev->vdev_id, WLAN_SCAN_ID);
19679 	chan_info->chan_tx_pwr_range = ev->chan_tx_pwr_range;
19680 	chan_info->chan_tx_pwr_tp = ev->chan_tx_pwr_tp;
19681 	chan_info->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count;
19682 	chan_info->rx_11b_mode_data_duration = ev->rx_11b_mode_data_duration;
19683 	chan_info->tx_frame_cnt = ev->tx_frame_cnt;
19684 	chan_info->rx_frame_count = ev->rx_frame_count;
19685 	chan_info->mac_clk_mhz = ev->mac_clk_mhz;
19686 	chan_info->vdev_id = ev->vdev_id;
19687 
19688 	return QDF_STATUS_SUCCESS;
19689 }
19690 
19691 /**
19692  * extract_pdev_utf_event_tlv() - extract UTF data info from event
19693  * @wmi_handle: WMI handle
19694  * @param evt_buf: Pointer to event buffer
19695  * @param param: Pointer to hold data
19696  *
19697  * Return : QDF_STATUS_SUCCESS for success or error code
19698  */
19699 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle,
19700 			     uint8_t *evt_buf,
19701 			     struct wmi_host_pdev_utf_event *event)
19702 {
19703 	WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf;
19704 	struct wmi_host_utf_seg_header_info *seg_hdr;
19705 
19706 	param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf;
19707 	event->data = param_buf->data;
19708 	event->datalen = param_buf->num_data;
19709 	seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data;
19710 	/* Set pdev_id=1 until FW adds support to include pdev_id */
19711 	event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19712 							seg_hdr->pdev_id);
19713 
19714 	return QDF_STATUS_SUCCESS;
19715 }
19716 
19717 /**
19718  * extract_chainmask_tables_tlv() - extract chain mask tables from event
19719  * @wmi_handle: wmi handle
19720  * @param evt_buf: pointer to event buffer
19721  * @param param: Pointer to hold evt buf
19722  *
19723  * Return: QDF_STATUS_SUCCESS for success or error code
19724  */
19725 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle,
19726 		uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table)
19727 {
19728 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19729 	WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps;
19730 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19731 	uint8_t i = 0, j = 0;
19732 
19733 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19734 	if (!param_buf)
19735 		return QDF_STATUS_E_INVAL;
19736 
19737 	hw_caps = param_buf->soc_hw_mode_caps;
19738 	if (!hw_caps)
19739 		return QDF_STATUS_E_INVAL;
19740 
19741 	if (!hw_caps->num_chainmask_tables)
19742 		return QDF_STATUS_E_INVAL;
19743 
19744 	chainmask_caps = param_buf->mac_phy_chainmask_caps;
19745 
19746 	if (chainmask_caps == NULL)
19747 		return QDF_STATUS_E_INVAL;
19748 
19749 	for (i = 0; i < hw_caps->num_chainmask_tables; i++) {
19750 
19751 		qdf_print("Dumping chain mask combo data for table : %d\n", i);
19752 		for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) {
19753 
19754 			chainmask_table[i].cap_list[j].chainmask =
19755 				chainmask_caps->chainmask;
19756 
19757 			chainmask_table[i].cap_list[j].supports_chan_width_20 =
19758 				WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags);
19759 
19760 			chainmask_table[i].cap_list[j].supports_chan_width_40 =
19761 				WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags);
19762 
19763 			chainmask_table[i].cap_list[j].supports_chan_width_80 =
19764 				WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags);
19765 
19766 			chainmask_table[i].cap_list[j].supports_chan_width_160 =
19767 				WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags);
19768 
19769 			chainmask_table[i].cap_list[j].supports_chan_width_80P80 =
19770 				WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags);
19771 
19772 			chainmask_table[i].cap_list[j].chain_mask_2G =
19773 				WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags);
19774 
19775 			chainmask_table[i].cap_list[j].chain_mask_5G =
19776 				WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags);
19777 
19778 			chainmask_table[i].cap_list[j].chain_mask_tx =
19779 				WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags);
19780 
19781 			chainmask_table[i].cap_list[j].chain_mask_rx =
19782 				WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags);
19783 
19784 			chainmask_table[i].cap_list[j].supports_aDFS =
19785 				WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags);
19786 
19787 			qdf_print("supported_flags: 0x%08x  chainmasks: 0x%08x\n",
19788 					chainmask_caps->supported_flags,
19789 					chainmask_caps->chainmask
19790 				 );
19791 			chainmask_caps++;
19792 		}
19793 	}
19794 
19795 	return QDF_STATUS_SUCCESS;
19796 }
19797 
19798 /**
19799  * extract_service_ready_ext_tlv() - extract basic extended service ready params
19800  * from event
19801  * @wmi_handle: wmi handle
19802  * @param evt_buf: pointer to event buffer
19803  * @param param: Pointer to hold evt buf
19804  *
19805  * Return: QDF_STATUS_SUCCESS for success or error code
19806  */
19807 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle,
19808 		uint8_t *event, struct wlan_psoc_host_service_ext_param *param)
19809 {
19810 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19811 	wmi_service_ready_ext_event_fixed_param *ev;
19812 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19813 	WMI_SOC_HAL_REG_CAPABILITIES *reg_caps;
19814 	WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo;
19815 	uint8_t i = 0;
19816 
19817 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19818 	if (!param_buf)
19819 		return QDF_STATUS_E_INVAL;
19820 
19821 	ev = param_buf->fixed_param;
19822 	if (!ev)
19823 		return QDF_STATUS_E_INVAL;
19824 
19825 	/* Move this to host based bitmap */
19826 	param->default_conc_scan_config_bits =
19827 				ev->default_conc_scan_config_bits;
19828 	param->default_fw_config_bits = ev->default_fw_config_bits;
19829 	param->he_cap_info = ev->he_cap_info;
19830 	param->mpdu_density = ev->mpdu_density;
19831 	param->max_bssid_rx_filters = ev->max_bssid_rx_filters;
19832 	param->fw_build_vers_ext = ev->fw_build_vers_ext;
19833 	param->num_dbr_ring_caps = param_buf->num_dma_ring_caps;
19834 	qdf_mem_copy(&param->ppet, &ev->ppet, sizeof(param->ppet));
19835 
19836 	hw_caps = param_buf->soc_hw_mode_caps;
19837 	if (hw_caps)
19838 		param->num_hw_modes = hw_caps->num_hw_modes;
19839 	else
19840 		param->num_hw_modes = 0;
19841 
19842 	reg_caps = param_buf->soc_hal_reg_caps;
19843 	if (reg_caps)
19844 		param->num_phy = reg_caps->num_phy;
19845 	else
19846 		param->num_phy = 0;
19847 
19848 	if (hw_caps) {
19849 		param->num_chainmask_tables = hw_caps->num_chainmask_tables;
19850 		qdf_print("Num chain mask tables: %d\n", hw_caps->num_chainmask_tables);
19851 	} else
19852 		param->num_chainmask_tables = 0;
19853 
19854 	chain_mask_combo = param_buf->mac_phy_chainmask_combo;
19855 
19856 	if (chain_mask_combo == NULL)
19857 		return QDF_STATUS_SUCCESS;
19858 
19859 	qdf_print("Dumping chain mask combo data\n");
19860 
19861 	for (i = 0; i < param->num_chainmask_tables; i++) {
19862 
19863 		qdf_print("table_id : %d Num valid chainmasks: %d\n",
19864 				chain_mask_combo->chainmask_table_id,
19865 				chain_mask_combo->num_valid_chainmask
19866 			 );
19867 
19868 		param->chainmask_table[i].table_id =
19869 			chain_mask_combo->chainmask_table_id;
19870 		param->chainmask_table[i].num_valid_chainmasks =
19871 			chain_mask_combo->num_valid_chainmask;
19872 		chain_mask_combo++;
19873 	}
19874 	qdf_print("chain mask combo end\n");
19875 
19876 	return QDF_STATUS_SUCCESS;
19877 }
19878 
19879 /**
19880  * extract_hw_mode_cap_service_ready_ext_tlv() -
19881  *       extract HW mode cap from service ready event
19882  * @wmi_handle: wmi handle
19883  * @param evt_buf: pointer to event buffer
19884  * @param param: Pointer to hold evt buf
19885  * @param hw_mode_idx: hw mode idx should be less than num_mode
19886  *
19887  * Return: QDF_STATUS_SUCCESS for success or error code
19888  */
19889 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv(
19890 			wmi_unified_t wmi_handle,
19891 			uint8_t *event, uint8_t hw_mode_idx,
19892 			struct wlan_psoc_host_hw_mode_caps *param)
19893 {
19894 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19895 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19896 
19897 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19898 	if (!param_buf)
19899 		return QDF_STATUS_E_INVAL;
19900 
19901 	hw_caps = param_buf->soc_hw_mode_caps;
19902 	if (!hw_caps)
19903 		return QDF_STATUS_E_INVAL;
19904 
19905 	if (hw_mode_idx >= hw_caps->num_hw_modes)
19906 		return QDF_STATUS_E_INVAL;
19907 
19908 	param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id;
19909 	param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map;
19910 
19911 	param->hw_mode_config_type =
19912 		param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type;
19913 
19914 	return QDF_STATUS_SUCCESS;
19915 }
19916 
19917 /**
19918  * extract_mac_phy_cap_service_ready_ext_tlv() -
19919  *       extract MAC phy cap from service ready event
19920  * @wmi_handle: wmi handle
19921  * @param evt_buf: pointer to event buffer
19922  * @param param: Pointer to hold evt buf
19923  * @param hw_mode_idx: hw mode idx should be less than num_mode
19924  * @param phy_id: phy id within hw_mode
19925  *
19926  * Return: QDF_STATUS_SUCCESS for success or error code
19927  */
19928 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv(
19929 			wmi_unified_t wmi_handle,
19930 			uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id,
19931 			struct wlan_psoc_host_mac_phy_caps *param)
19932 {
19933 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
19934 	WMI_MAC_PHY_CAPABILITIES *mac_phy_caps;
19935 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
19936 	uint32_t phy_map;
19937 	uint8_t hw_idx, phy_idx = 0;
19938 
19939 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
19940 	if (!param_buf)
19941 		return QDF_STATUS_E_INVAL;
19942 
19943 	hw_caps = param_buf->soc_hw_mode_caps;
19944 	if (!hw_caps)
19945 		return QDF_STATUS_E_INVAL;
19946 
19947 	for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) {
19948 		if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id)
19949 			break;
19950 
19951 		phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map;
19952 		while (phy_map) {
19953 			phy_map >>= 1;
19954 			phy_idx++;
19955 		}
19956 	}
19957 
19958 	if (hw_idx == hw_caps->num_hw_modes)
19959 		return QDF_STATUS_E_INVAL;
19960 
19961 	phy_idx += phy_id;
19962 	if (phy_idx >= param_buf->num_mac_phy_caps)
19963 		return QDF_STATUS_E_INVAL;
19964 
19965 	mac_phy_caps = &param_buf->mac_phy_caps[phy_idx];
19966 
19967 	param->hw_mode_id = mac_phy_caps->hw_mode_id;
19968 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
19969 							mac_phy_caps->pdev_id);
19970 	param->phy_id = mac_phy_caps->phy_id;
19971 	param->supports_11b =
19972 			WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags);
19973 	param->supports_11g =
19974 			WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags);
19975 	param->supports_11a =
19976 			WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags);
19977 	param->supports_11n =
19978 			WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags);
19979 	param->supports_11ac =
19980 			WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags);
19981 	param->supports_11ax =
19982 			WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags);
19983 
19984 	param->supported_bands = mac_phy_caps->supported_bands;
19985 	param->ampdu_density = mac_phy_caps->ampdu_density;
19986 	param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G;
19987 	param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G;
19988 	param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G;
19989 	param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G;
19990 	param->he_cap_info_2G = mac_phy_caps->he_cap_info_2G;
19991 	param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G;
19992 	param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G;
19993 	param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G;
19994 	param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G;
19995 	param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G;
19996 	param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G;
19997 	param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G;
19998 	param->he_cap_info_5G = mac_phy_caps->he_cap_info_5G;
19999 	param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G;
20000 	param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G;
20001 	param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G;
20002 	qdf_mem_copy(&param->he_cap_phy_info_2G,
20003 			&mac_phy_caps->he_cap_phy_info_2G,
20004 			sizeof(param->he_cap_phy_info_2G));
20005 	qdf_mem_copy(&param->he_cap_phy_info_5G,
20006 			&mac_phy_caps->he_cap_phy_info_5G,
20007 			sizeof(param->he_cap_phy_info_5G));
20008 	qdf_mem_copy(&param->he_ppet2G, &mac_phy_caps->he_ppet2G,
20009 				 sizeof(param->he_ppet2G));
20010 	qdf_mem_copy(&param->he_ppet5G, &mac_phy_caps->he_ppet5G,
20011 				sizeof(param->he_ppet5G));
20012 	param->chainmask_table_id = mac_phy_caps->chainmask_table_id;
20013 
20014 	return QDF_STATUS_SUCCESS;
20015 }
20016 
20017 /**
20018  * extract_reg_cap_service_ready_ext_tlv() -
20019  *       extract REG cap from service ready event
20020  * @wmi_handle: wmi handle
20021  * @param evt_buf: pointer to event buffer
20022  * @param param: Pointer to hold evt buf
20023  * @param phy_idx: phy idx should be less than num_mode
20024  *
20025  * Return: QDF_STATUS_SUCCESS for success or error code
20026  */
20027 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv(
20028 			wmi_unified_t wmi_handle,
20029 			uint8_t *event, uint8_t phy_idx,
20030 			struct wlan_psoc_host_hal_reg_capabilities_ext *param)
20031 {
20032 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
20033 	WMI_SOC_HAL_REG_CAPABILITIES *reg_caps;
20034 	WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap;
20035 
20036 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
20037 	if (!param_buf)
20038 		return QDF_STATUS_E_INVAL;
20039 
20040 	reg_caps = param_buf->soc_hal_reg_caps;
20041 	if (!reg_caps)
20042 		return QDF_STATUS_E_INVAL;
20043 
20044 	if (phy_idx >= reg_caps->num_phy)
20045 		return QDF_STATUS_E_INVAL;
20046 
20047 	ext_reg_cap = &param_buf->hal_reg_caps[phy_idx];
20048 
20049 	param->phy_id = ext_reg_cap->phy_id;
20050 	param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain;
20051 	param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext;
20052 	param->regcap1 = ext_reg_cap->regcap1;
20053 	param->regcap2 = ext_reg_cap->regcap2;
20054 	param->wireless_modes = convert_wireless_modes_tlv(
20055 						ext_reg_cap->wireless_modes);
20056 	param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan;
20057 	param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan;
20058 	param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan;
20059 	param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan;
20060 
20061 	return QDF_STATUS_SUCCESS;
20062 }
20063 
20064 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv(
20065 			wmi_unified_t wmi_handle,
20066 			uint8_t *event, uint8_t idx,
20067 			struct wlan_psoc_host_dbr_ring_caps *param)
20068 {
20069 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
20070 	WMI_DMA_RING_CAPABILITIES *dbr_ring_caps;
20071 
20072 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event;
20073 	if (!param_buf)
20074 		return QDF_STATUS_E_INVAL;
20075 
20076 	dbr_ring_caps = &param_buf->dma_ring_caps[idx];
20077 
20078 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20079 				dbr_ring_caps->pdev_id);
20080 	param->mod_id = dbr_ring_caps->mod_id;
20081 	param->ring_elems_min = dbr_ring_caps->ring_elems_min;
20082 	param->min_buf_size = dbr_ring_caps->min_buf_size;
20083 	param->min_buf_align = dbr_ring_caps->min_buf_align;
20084 
20085 	return QDF_STATUS_SUCCESS;
20086 }
20087 
20088 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle,
20089 		uint8_t *event, struct direct_buf_rx_rsp *param)
20090 {
20091 	WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
20092 	wmi_dma_buf_release_fixed_param *ev;
20093 
20094 	param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
20095 	if (!param_buf)
20096 		return QDF_STATUS_E_INVAL;
20097 
20098 	ev = param_buf->fixed_param;
20099 	if (!ev)
20100 		return QDF_STATUS_E_INVAL;
20101 
20102 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20103 								ev->pdev_id);
20104 	param->mod_id = ev->mod_id;
20105 	param->num_buf_release_entry = ev->num_buf_release_entry;
20106 	WMI_LOGD("%s:pdev id %d mod id %d num buf release entry %d\n", __func__,
20107 		 param->pdev_id, param->mod_id, param->num_buf_release_entry);
20108 
20109 	return QDF_STATUS_SUCCESS;
20110 }
20111 
20112 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle,
20113 		uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param)
20114 {
20115 	WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
20116 	wmi_dma_buf_release_entry *entry;
20117 
20118 	param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
20119 	if (!param_buf)
20120 		return QDF_STATUS_E_INVAL;
20121 
20122 	entry = &param_buf->entries[idx];
20123 
20124 	if (!entry) {
20125 		WMI_LOGE("%s: Entry is NULL\n", __func__);
20126 		return QDF_STATUS_E_FAILURE;
20127 	}
20128 
20129 	WMI_LOGD("%s: paddr_lo[%d] = %x\n", __func__, idx, entry->paddr_lo);
20130 
20131 	param->paddr_lo = entry->paddr_lo;
20132 	param->paddr_hi = entry->paddr_hi;
20133 
20134 	return QDF_STATUS_SUCCESS;
20135 }
20136 
20137 /**
20138  * extract_dcs_interference_type_tlv() - extract dcs interference type
20139  * from event
20140  * @wmi_handle: wmi handle
20141  * @param evt_buf: pointer to event buffer
20142  * @param param: Pointer to hold dcs interference param
20143  *
20144  * Return: 0 for success or error code
20145  */
20146 static QDF_STATUS extract_dcs_interference_type_tlv(
20147 		wmi_unified_t wmi_handle,
20148 		void *evt_buf, struct wmi_host_dcs_interference_param *param)
20149 {
20150 	WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf;
20151 
20152 	param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf;
20153 	if (!param_buf)
20154 		return QDF_STATUS_E_INVAL;
20155 
20156 	param->interference_type = param_buf->fixed_param->interference_type;
20157 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20158 					param_buf->fixed_param->pdev_id);
20159 
20160 	return QDF_STATUS_SUCCESS;
20161 }
20162 
20163 /*
20164  * extract_dcs_cw_int_tlv() - extract dcs cw interference from event
20165  * @wmi_handle: wmi handle
20166  * @param evt_buf: pointer to event buffer
20167  * @param cw_int: Pointer to hold cw interference
20168  *
20169  * Return: 0 for success or error code
20170  */
20171 static QDF_STATUS extract_dcs_cw_int_tlv(wmi_unified_t wmi_handle,
20172 		void *evt_buf,
20173 		wmi_host_ath_dcs_cw_int *cw_int)
20174 {
20175 	WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf;
20176 	wlan_dcs_cw_int *ev;
20177 
20178 	param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf;
20179 	if (!param_buf)
20180 		return QDF_STATUS_E_INVAL;
20181 
20182 	ev = param_buf->cw_int;
20183 
20184 	cw_int->channel = ev->channel;
20185 
20186 	return QDF_STATUS_SUCCESS;
20187 }
20188 
20189 /**
20190  * extract_dcs_im_tgt_stats_tlv() - extract dcs im target stats from event
20191  * @wmi_handle: wmi handle
20192  * @param evt_buf: pointer to event buffer
20193  * @param wlan_stat: Pointer to hold wlan stats
20194  *
20195  * Return: 0 for success or error code
20196  */
20197 static QDF_STATUS extract_dcs_im_tgt_stats_tlv(wmi_unified_t wmi_handle,
20198 		void *evt_buf,
20199 		wmi_host_dcs_im_tgt_stats_t *wlan_stat)
20200 {
20201 	WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf;
20202 	wlan_dcs_im_tgt_stats_t *ev;
20203 
20204 	param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf;
20205 	if (!param_buf)
20206 		return QDF_STATUS_E_INVAL;
20207 
20208 	ev = param_buf->wlan_stat;
20209 	wlan_stat->reg_tsf32 = ev->reg_tsf32;
20210 	wlan_stat->last_ack_rssi = ev->last_ack_rssi;
20211 	wlan_stat->tx_waste_time = ev->tx_waste_time;
20212 	wlan_stat->rx_time = ev->rx_time;
20213 	wlan_stat->phyerr_cnt = ev->phyerr_cnt;
20214 	wlan_stat->mib_stats.listen_time = ev->listen_time;
20215 	wlan_stat->mib_stats.reg_tx_frame_cnt = ev->reg_tx_frame_cnt;
20216 	wlan_stat->mib_stats.reg_rx_frame_cnt = ev->reg_rx_frame_cnt;
20217 	wlan_stat->mib_stats.reg_rxclr_cnt = ev->reg_rxclr_cnt;
20218 	wlan_stat->mib_stats.reg_cycle_cnt = ev->reg_cycle_cnt;
20219 	wlan_stat->mib_stats.reg_rxclr_ext_cnt = ev->reg_rxclr_ext_cnt;
20220 	wlan_stat->mib_stats.reg_ofdm_phyerr_cnt = ev->reg_ofdm_phyerr_cnt;
20221 	wlan_stat->mib_stats.reg_cck_phyerr_cnt = ev->reg_cck_phyerr_cnt;
20222 	wlan_stat->chan_nf = ev->chan_nf;
20223 	wlan_stat->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count;
20224 
20225 	return QDF_STATUS_SUCCESS;
20226 }
20227 
20228 /**
20229  * extract_thermal_stats_tlv() - extract thermal stats from event
20230  * @wmi_handle: wmi handle
20231  * @param evt_buf: Pointer to event buffer
20232  * @param temp: Pointer to hold extracted temperature
20233  * @param level: Pointer to hold extracted level
20234  *
20235  * Return: 0 for success or error code
20236  */
20237 static QDF_STATUS
20238 extract_thermal_stats_tlv(wmi_unified_t wmi_handle,
20239 		void *evt_buf, uint32_t *temp,
20240 		uint32_t *level, uint32_t *pdev_id)
20241 {
20242 	WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf;
20243 	wmi_therm_throt_stats_event_fixed_param *tt_stats_event;
20244 
20245 	param_buf =
20246 		(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf;
20247 	if (!param_buf)
20248 		return QDF_STATUS_E_INVAL;
20249 
20250 	tt_stats_event = param_buf->fixed_param;
20251 
20252 	*pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20253 						tt_stats_event->pdev_id);
20254 	*temp = tt_stats_event->temp;
20255 	*level = tt_stats_event->level;
20256 
20257 	return QDF_STATUS_SUCCESS;
20258 }
20259 
20260 /**
20261  * extract_thermal_level_stats_tlv() - extract thermal level stats from event
20262  * @wmi_handle: wmi handle
20263  * @param evt_buf: pointer to event buffer
20264  * @param idx: Index to level stats
20265  * @param levelcount: Pointer to hold levelcount
20266  * @param dccount: Pointer to hold dccount
20267  *
20268  * Return: 0 for success or error code
20269  */
20270 static QDF_STATUS
20271 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle,
20272 		void *evt_buf, uint8_t idx, uint32_t *levelcount,
20273 		uint32_t *dccount)
20274 {
20275 	WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf;
20276 	wmi_therm_throt_level_stats_info *tt_level_info;
20277 
20278 	param_buf =
20279 		(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf;
20280 	if (!param_buf)
20281 		return QDF_STATUS_E_INVAL;
20282 
20283 	tt_level_info = param_buf->therm_throt_level_stats_info;
20284 
20285 	if (idx < THERMAL_LEVELS) {
20286 		*levelcount = tt_level_info[idx].level_count;
20287 		*dccount = tt_level_info[idx].dc_count;
20288 		return QDF_STATUS_SUCCESS;
20289 	}
20290 
20291 	return QDF_STATUS_E_FAILURE;
20292 }
20293 #ifdef BIG_ENDIAN_HOST
20294 /**
20295  * fips_conv_data_be() - LE to BE conversion of FIPS ev data
20296  * @param data_len - data length
20297  * @param data - pointer to data
20298  *
20299  * Return: QDF_STATUS - success or error status
20300  */
20301 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data)
20302 {
20303 	uint8_t *data_aligned = NULL;
20304 	int c;
20305 	unsigned char *data_unaligned;
20306 
20307 	data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) +
20308 					FIPS_ALIGN));
20309 	/* Assigning unaligned space to copy the data */
20310 	/* Checking if kmalloc does succesful allocation */
20311 	if (data_unaligned == NULL)
20312 		return QDF_STATUS_E_FAILURE;
20313 
20314 	/* Checking if space is alligned */
20315 	if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) {
20316 		/* align the data space */
20317 		data_aligned =
20318 			(uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN);
20319 	} else {
20320 		data_aligned = (u_int8_t *)data_unaligned;
20321 	}
20322 
20323 	/* memset and copy content from data to data aligned */
20324 	OS_MEMSET(data_aligned, 0, data_len);
20325 	OS_MEMCPY(data_aligned, data, data_len);
20326 	/* Endianness to LE */
20327 	for (c = 0; c < data_len/4; c++) {
20328 		*((u_int32_t *)data_aligned + c) =
20329 			qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c));
20330 	}
20331 
20332 	/* Copy content to event->data */
20333 	OS_MEMCPY(data, data_aligned, data_len);
20334 
20335 	/* clean up allocated space */
20336 	qdf_mem_free(data_unaligned);
20337 	data_aligned = NULL;
20338 	data_unaligned = NULL;
20339 
20340 	/*************************************************************/
20341 
20342 	return QDF_STATUS_SUCCESS;
20343 }
20344 #else
20345 /**
20346  * fips_conv_data_be() - DUMMY for LE platform
20347  *
20348  * Return: QDF_STATUS - success
20349  */
20350 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data)
20351 {
20352 	return QDF_STATUS_SUCCESS;
20353 }
20354 #endif
20355 
20356 /**
20357  * extract_fips_event_data_tlv() - extract fips event data
20358  * @wmi_handle: wmi handle
20359  * @param evt_buf: pointer to event buffer
20360  * @param param: pointer FIPS event params
20361  *
20362  * Return: 0 for success or error code
20363  */
20364 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle,
20365 		void *evt_buf, struct wmi_host_fips_event_param *param)
20366 {
20367 	WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf;
20368 	wmi_pdev_fips_event_fixed_param *event;
20369 
20370 	param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf;
20371 	event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param;
20372 
20373 	if (fips_conv_data_be(event->data_len, param_buf->data) !=
20374 							QDF_STATUS_SUCCESS)
20375 		return QDF_STATUS_E_FAILURE;
20376 
20377 	param->data = (uint32_t *)param_buf->data;
20378 	param->data_len = event->data_len;
20379 	param->error_status = event->error_status;
20380 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20381 								event->pdev_id);
20382 
20383 	return QDF_STATUS_SUCCESS;
20384 }
20385 
20386 /*
20387  * extract_peer_delete_response_event_tlv() - extract peer delete response event
20388  * @wmi_handle: wmi handle
20389  * @param evt_buf: pointer to event buffer
20390  * @param vdev_id: Pointer to hold vdev_id
20391  * @param mac_addr: Pointer to hold peer mac address
20392  *
20393  * Return: QDF_STATUS_SUCCESS for success or error code
20394  */
20395 static QDF_STATUS extract_peer_delete_response_event_tlv(wmi_unified_t wmi_hdl,
20396 	void *evt_buf, struct wmi_host_peer_delete_response_event *param)
20397 {
20398 	WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf;
20399 	wmi_peer_delete_resp_event_fixed_param *ev;
20400 
20401 	param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)evt_buf;
20402 
20403 	ev = (wmi_peer_delete_resp_event_fixed_param *) param_buf->fixed_param;
20404 	if (!ev) {
20405 		WMI_LOGE("%s: Invalid peer_delete response\n", __func__);
20406 		return QDF_STATUS_E_FAILURE;
20407 	}
20408 
20409 	param->vdev_id = ev->vdev_id;
20410 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr,
20411 			&param->mac_address.bytes[0]);
20412 
20413 	return QDF_STATUS_SUCCESS;
20414 }
20415 
20416 static bool is_management_record_tlv(uint32_t cmd_id)
20417 {
20418 	if ((cmd_id == WMI_MGMT_TX_COMPLETION_EVENTID) ||
20419 			(cmd_id == WMI_MGMT_TX_SEND_CMDID) ||
20420 			(cmd_id == WMI_OFFCHAN_DATA_TX_SEND_CMDID)) {
20421 		return true;
20422 	}
20423 
20424 	return false;
20425 }
20426 
20427 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf)
20428 {
20429 	wmi_vdev_set_param_cmd_fixed_param *set_cmd;
20430 
20431 	set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf);
20432 
20433 	switch (set_cmd->param_id) {
20434 	case WMI_VDEV_PARAM_LISTEN_INTERVAL:
20435 	case WMI_VDEV_PARAM_DTIM_POLICY:
20436 		return HTC_TX_PACKET_TAG_AUTO_PM;
20437 	default:
20438 		break;
20439 	}
20440 
20441 	return 0;
20442 }
20443 
20444 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf)
20445 {
20446 	wmi_sta_powersave_param_cmd_fixed_param *ps_cmd;
20447 
20448 	ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf);
20449 
20450 	switch (ps_cmd->param) {
20451 	case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD:
20452 	case WMI_STA_PS_PARAM_INACTIVITY_TIME:
20453 	case WMI_STA_PS_ENABLE_QPOWER:
20454 		return HTC_TX_PACKET_TAG_AUTO_PM;
20455 	default:
20456 		break;
20457 	}
20458 
20459 	return 0;
20460 }
20461 
20462 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf,
20463 				   uint32_t cmd_id)
20464 {
20465 	if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended))
20466 		return 0;
20467 
20468 	switch (cmd_id) {
20469 	case WMI_VDEV_SET_PARAM_CMDID:
20470 		return wmi_tag_vdev_set_cmd(wmi_hdl, buf);
20471 	case WMI_STA_POWERSAVE_PARAM_CMDID:
20472 		return wmi_tag_sta_powersave_cmd(wmi_hdl, buf);
20473 	default:
20474 		break;
20475 	}
20476 
20477 	return 0;
20478 }
20479 
20480 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle)
20481 {
20482 	uint16_t tag = 0;
20483 
20484 	if (qdf_atomic_read(&wmi_handle->is_target_suspended)) {
20485 		pr_err("%s: Target is already suspended, Ignore FW Hang Command\n",
20486 			__func__);
20487 		return tag;
20488 	}
20489 
20490 	if (wmi_handle->tag_crash_inject)
20491 		tag = HTC_TX_PACKET_TAG_AUTO_PM;
20492 
20493 	wmi_handle->tag_crash_inject = false;
20494 	return tag;
20495 }
20496 
20497 /**
20498  * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands
20499  * @wmi_handle: WMI handle
20500  * @buf:	WMI buffer
20501  * @cmd_id:	WMI command Id
20502  *
20503  * Return htc_tx_tag
20504  */
20505 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle,
20506 				wmi_buf_t buf,
20507 				uint32_t cmd_id)
20508 {
20509 	uint16_t htc_tx_tag = 0;
20510 
20511 	switch (cmd_id) {
20512 	case WMI_WOW_ENABLE_CMDID:
20513 	case WMI_PDEV_SUSPEND_CMDID:
20514 	case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID:
20515 	case WMI_WOW_ADD_WAKE_PATTERN_CMDID:
20516 	case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID:
20517 	case WMI_PDEV_RESUME_CMDID:
20518 	case WMI_WOW_DEL_WAKE_PATTERN_CMDID:
20519 	case WMI_WOW_SET_ACTION_WAKE_UP_CMDID:
20520 #ifdef FEATURE_WLAN_D0WOW
20521 	case WMI_D0_WOW_ENABLE_DISABLE_CMDID:
20522 #endif
20523 		htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM;
20524 		break;
20525 	case WMI_FORCE_FW_HANG_CMDID:
20526 		htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle);
20527 		break;
20528 	case WMI_VDEV_SET_PARAM_CMDID:
20529 	case WMI_STA_POWERSAVE_PARAM_CMDID:
20530 		htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id);
20531 	default:
20532 		break;
20533 	}
20534 
20535 	return htc_tx_tag;
20536 }
20537 
20538 /**
20539  * extract_channel_hopping_event_tlv() - extract channel hopping param
20540  * from event
20541  * @wmi_handle: wmi handle
20542  * @param evt_buf: pointer to event buffer
20543  * @param ch_hopping: Pointer to hold channel hopping param
20544  *
20545  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20546  */
20547 static QDF_STATUS extract_channel_hopping_event_tlv(
20548 	wmi_unified_t wmi_handle, void *evt_buf,
20549 	wmi_host_pdev_channel_hopping_event *ch_hopping)
20550 {
20551 	WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *param_buf;
20552 	wmi_pdev_channel_hopping_event_fixed_param *event;
20553 
20554 	param_buf = (WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *)evt_buf;
20555 	event = (wmi_pdev_channel_hopping_event_fixed_param *)
20556 						param_buf->fixed_param;
20557 
20558 	ch_hopping->noise_floor_report_iter = event->noise_floor_report_iter;
20559 	ch_hopping->noise_floor_total_iter = event->noise_floor_total_iter;
20560 	ch_hopping->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20561 								event->pdev_id);
20562 
20563 	return QDF_STATUS_SUCCESS;
20564 }
20565 
20566 /**
20567  * extract_pdev_tpc_ev_param_tlv() - extract tpc param from event
20568  * @wmi_handle: wmi handle
20569  * @param evt_buf: pointer to event buffer
20570  * @param param: Pointer to hold tpc param
20571  *
20572  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20573  */
20574 static QDF_STATUS extract_pdev_tpc_ev_param_tlv(wmi_unified_t wmi_handle,
20575 		void *evt_buf,
20576 		wmi_host_pdev_tpc_event *param)
20577 {
20578 	WMI_PDEV_TPC_EVENTID_param_tlvs *param_buf;
20579 	wmi_pdev_tpc_event_fixed_param *event;
20580 
20581 	param_buf = (WMI_PDEV_TPC_EVENTID_param_tlvs *)evt_buf;
20582 	event = (wmi_pdev_tpc_event_fixed_param *)param_buf->fixed_param;
20583 
20584 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
20585 								event->pdev_id);
20586 	qdf_mem_copy(param->tpc, param_buf->tpc, sizeof(param->tpc));
20587 
20588 	return QDF_STATUS_SUCCESS;
20589 }
20590 
20591 /**
20592  * extract_nfcal_power_ev_param_tlv() - extract noise floor calibration
20593  * power param from event
20594  * @wmi_handle: wmi handle
20595  * @param evt_buf: pointer to event buffer
20596  * @param param: Pointer to hold nf cal power param
20597  *
20598  * Return: 0 for success or error code
20599  */
20600 static QDF_STATUS
20601 extract_nfcal_power_ev_param_tlv(wmi_unified_t wmi_handle,
20602 				 void *evt_buf,
20603 				 wmi_host_pdev_nfcal_power_all_channels_event *param)
20604 {
20605 	WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *param_buf;
20606 	wmi_pdev_nfcal_power_all_channels_event_fixed_param *event;
20607 	wmi_pdev_nfcal_power_all_channels_nfdBr *ch_nfdbr;
20608 	wmi_pdev_nfcal_power_all_channels_nfdBm *ch_nfdbm;
20609 	wmi_pdev_nfcal_power_all_channels_freqNum *ch_freqnum;
20610 	uint32_t i;
20611 
20612 	param_buf =
20613 		(WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *)evt_buf;
20614 	event = param_buf->fixed_param;
20615 	ch_nfdbr = param_buf->nfdbr;
20616 	ch_nfdbm = param_buf->nfdbm;
20617 	ch_freqnum = param_buf->freqnum;
20618 
20619 	WMI_LOGD("pdev_id[%x], num_nfdbr[%d], num_nfdbm[%d] num_freqnum[%d]\n",
20620 		 event->pdev_id, param_buf->num_nfdbr,
20621 		 param_buf->num_nfdbm, param_buf->num_freqnum);
20622 
20623 	if (param_buf->num_nfdbr >
20624 	    WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) {
20625 		WMI_LOGE("invalid number of nfdBr");
20626 		return QDF_STATUS_E_FAILURE;
20627 	}
20628 
20629 	if (param_buf->num_nfdbm >
20630 	    WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) {
20631 		WMI_LOGE("invalid number of nfdBm");
20632 		return QDF_STATUS_E_FAILURE;
20633 	}
20634 
20635 	if (param_buf->num_freqnum > WMI_HOST_RXG_CAL_CHAN_MAX) {
20636 		WMI_LOGE("invalid number of freqNum");
20637 		return QDF_STATUS_E_FAILURE;
20638 	}
20639 
20640 	for (i = 0; i < param_buf->num_nfdbr; i++) {
20641 		param->nfdbr[i] = (int8_t)ch_nfdbr->nfdBr;
20642 		param->nfdbm[i] = (int8_t)ch_nfdbm->nfdBm;
20643 		ch_nfdbr++;
20644 		ch_nfdbm++;
20645 	}
20646 
20647 	for (i = 0; i < param_buf->num_freqnum; i++) {
20648 		param->freqnum[i] = ch_freqnum->freqNum;
20649 		ch_freqnum++;
20650 	}
20651 
20652 	param->pdev_id = event->pdev_id;
20653 
20654 	return QDF_STATUS_SUCCESS;
20655 }
20656 
20657 
20658 #ifdef BIG_ENDIAN_HOST
20659 /**
20660  * wds_addr_ev_conv_data_be() - LE to BE conversion of wds addr event
20661  * @param data_len - data length
20662  * @param data - pointer to data
20663  *
20664  * Return: QDF_STATUS - success or error status
20665  */
20666 static QDF_STATUS wds_addr_ev_conv_data_be(uint16_t data_len, uint8_t *ev)
20667 {
20668 	uint8_t *datap = (uint8_t *)ev;
20669 	int i;
20670 	/* Skip swapping the first word */
20671 	datap += sizeof(uint32_t);
20672 	for (i = 0; i < ((data_len / sizeof(uint32_t))-1);
20673 			i++, datap += sizeof(uint32_t)) {
20674 		*(uint32_t *)datap = qdf_le32_to_cpu(*(uint32_t *)datap);
20675 	}
20676 
20677 	return QDF_STATUS_SUCCESS;
20678 }
20679 #else
20680 /**
20681  * wds_addr_ev_conv_data_be() - Dummy operation for LE platforms
20682  * @param data_len - data length
20683  * @param data - pointer to data
20684  *
20685  * Return: QDF_STATUS - success or error status
20686  */
20687 static QDF_STATUS wds_addr_ev_conv_data_be(uint32_t data_len, uint8_t *ev)
20688 {
20689 	return QDF_STATUS_SUCCESS;
20690 }
20691 #endif
20692 
20693 /**
20694  * extract_wds_addr_event_tlv() - extract wds address from event
20695  * @wmi_handle: wmi handle
20696  * @param evt_buf: pointer to event buffer
20697  * @param wds_ev: Pointer to hold wds address
20698  *
20699  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20700  */
20701 static QDF_STATUS extract_wds_addr_event_tlv(wmi_unified_t wmi_handle,
20702 		void *evt_buf,
20703 		uint16_t len, wds_addr_event_t *wds_ev)
20704 {
20705 	WMI_WDS_PEER_EVENTID_param_tlvs *param_buf;
20706 	wmi_wds_addr_event_fixed_param *ev;
20707 	int i;
20708 
20709 	param_buf = (WMI_WDS_PEER_EVENTID_param_tlvs *)evt_buf;
20710 	ev = (wmi_wds_addr_event_fixed_param *)param_buf->fixed_param;
20711 
20712 	if (wds_addr_ev_conv_data_be(len, (uint8_t *)ev) != QDF_STATUS_SUCCESS)
20713 		return QDF_STATUS_E_FAILURE;
20714 
20715 	qdf_mem_copy(wds_ev->event_type, ev->event_type,
20716 		     sizeof(wds_ev->event_type));
20717 	for (i = 0; i < 4; i++) {
20718 		wds_ev->peer_mac[i] =
20719 			((u_int8_t *)&(ev->peer_mac.mac_addr31to0))[i];
20720 		wds_ev->dest_mac[i] =
20721 			((u_int8_t *)&(ev->dest_mac.mac_addr31to0))[i];
20722 	}
20723 	for (i = 0; i < 2; i++) {
20724 		wds_ev->peer_mac[4+i] =
20725 			((u_int8_t *)&(ev->peer_mac.mac_addr47to32))[i];
20726 		wds_ev->dest_mac[4+i] =
20727 			((u_int8_t *)&(ev->dest_mac.mac_addr47to32))[i];
20728 	}
20729 	return QDF_STATUS_SUCCESS;
20730 }
20731 
20732 /**
20733  * extract_peer_sta_ps_statechange_ev_tlv() - extract peer sta ps state
20734  * from event
20735  * @wmi_handle: wmi handle
20736  * @param evt_buf: pointer to event buffer
20737  * @param ev: Pointer to hold peer param and ps state
20738  *
20739  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20740  */
20741 static QDF_STATUS extract_peer_sta_ps_statechange_ev_tlv(wmi_unified_t wmi_handle,
20742 		void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev)
20743 {
20744 	WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf;
20745 	wmi_peer_sta_ps_statechange_event_fixed_param *event;
20746 
20747 	param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)evt_buf;
20748 	event = (wmi_peer_sta_ps_statechange_event_fixed_param *)
20749 						param_buf->fixed_param;
20750 
20751 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, ev->peer_macaddr);
20752 	ev->peer_ps_state = event->peer_ps_state;
20753 
20754 	return QDF_STATUS_SUCCESS;
20755 }
20756 
20757 /**
20758  * extract_inst_rssi_stats_event_tlv() - extract inst rssi stats from event
20759  * @wmi_handle: wmi handle
20760  * @param evt_buf: pointer to event buffer
20761  * @param inst_rssi_resp: Pointer to hold inst rssi response
20762  *
20763  * @return QDF_STATUS_SUCCESS  on success and -ve on failure.
20764  */
20765 static QDF_STATUS extract_inst_rssi_stats_event_tlv(
20766 	wmi_unified_t wmi_handle, void *evt_buf,
20767 	wmi_host_inst_stats_resp *inst_rssi_resp)
20768 {
20769 	WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf;
20770 	wmi_inst_rssi_stats_resp_fixed_param *event;
20771 
20772 	param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf;
20773 	event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param;
20774 
20775 	qdf_mem_copy(&(inst_rssi_resp->peer_macaddr),
20776 		     &(event->peer_macaddr), sizeof(wmi_mac_addr));
20777 	inst_rssi_resp->iRSSI = event->iRSSI;
20778 
20779 	return QDF_STATUS_SUCCESS;
20780 }
20781 
20782 static struct cur_reg_rule
20783 *create_reg_rules_from_wmi(uint32_t num_reg_rules,
20784 		wmi_regulatory_rule_struct *wmi_reg_rule)
20785 {
20786 	struct cur_reg_rule *reg_rule_ptr;
20787 	uint32_t count;
20788 
20789 	reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr));
20790 
20791 	if (NULL == reg_rule_ptr) {
20792 		WMI_LOGE("memory allocation failure");
20793 		return NULL;
20794 	}
20795 
20796 	for (count = 0; count < num_reg_rules; count++) {
20797 		reg_rule_ptr[count].start_freq =
20798 			WMI_REG_RULE_START_FREQ_GET(
20799 					wmi_reg_rule[count].freq_info);
20800 		reg_rule_ptr[count].end_freq =
20801 			WMI_REG_RULE_END_FREQ_GET(
20802 					wmi_reg_rule[count].freq_info);
20803 		reg_rule_ptr[count].max_bw =
20804 			WMI_REG_RULE_MAX_BW_GET(
20805 					wmi_reg_rule[count].bw_pwr_info);
20806 		reg_rule_ptr[count].reg_power =
20807 			WMI_REG_RULE_REG_POWER_GET(
20808 					wmi_reg_rule[count].bw_pwr_info);
20809 		reg_rule_ptr[count].ant_gain =
20810 			WMI_REG_RULE_ANTENNA_GAIN_GET(
20811 					wmi_reg_rule[count].bw_pwr_info);
20812 		reg_rule_ptr[count].flags =
20813 			WMI_REG_RULE_FLAGS_GET(
20814 					wmi_reg_rule[count].flag_info);
20815 	}
20816 
20817 	return reg_rule_ptr;
20818 }
20819 
20820 static QDF_STATUS extract_reg_chan_list_update_event_tlv(
20821 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
20822 	struct cur_regulatory_info *reg_info, uint32_t len)
20823 {
20824 	WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf;
20825 	wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr;
20826 	wmi_regulatory_rule_struct *wmi_reg_rule;
20827 	uint32_t num_2g_reg_rules, num_5g_reg_rules;
20828 
20829 	WMI_LOGD("processing regulatory channel list");
20830 
20831 	param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf;
20832 	if (!param_buf) {
20833 		WMI_LOGE("invalid channel list event buf");
20834 		return QDF_STATUS_E_FAILURE;
20835 	}
20836 
20837 	chan_list_event_hdr = param_buf->fixed_param;
20838 
20839 	reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules;
20840 	reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules;
20841 	qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2),
20842 		     REG_ALPHA2_LEN);
20843 	reg_info->dfs_region = chan_list_event_hdr->dfs_region;
20844 	reg_info->phybitmap = chan_list_event_hdr->phybitmap;
20845 	reg_info->offload_enabled = true;
20846 	reg_info->num_phy = chan_list_event_hdr->num_phy;
20847 	reg_info->phy_id = chan_list_event_hdr->phy_id;
20848 	reg_info->ctry_code = chan_list_event_hdr->country_id;
20849 	reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code;
20850 	if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS)
20851 		reg_info->status_code = REG_SET_CC_STATUS_PASS;
20852 	else if (chan_list_event_hdr->status_code ==
20853 		 WMI_REG_CURRENT_ALPHA2_NOT_FOUND)
20854 		reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND;
20855 	else if (chan_list_event_hdr->status_code ==
20856 		 WMI_REG_INIT_ALPHA2_NOT_FOUND)
20857 		reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND;
20858 	else if (chan_list_event_hdr->status_code ==
20859 		 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED)
20860 		reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED;
20861 	else if (chan_list_event_hdr->status_code ==
20862 		 WMI_REG_SET_CC_STATUS_NO_MEMORY)
20863 		reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY;
20864 	else if (chan_list_event_hdr->status_code ==
20865 		 WMI_REG_SET_CC_STATUS_FAIL)
20866 		reg_info->status_code = REG_SET_CC_STATUS_FAIL;
20867 
20868 	reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g;
20869 	reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g;
20870 	reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g;
20871 	reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g;
20872 
20873 	num_2g_reg_rules = reg_info->num_2g_reg_rules;
20874 	num_5g_reg_rules = reg_info->num_5g_reg_rules;
20875 
20876 	WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d",
20877 			__func__, reg_info->alpha2, reg_info->dfs_region,
20878 			reg_info->min_bw_2g, reg_info->max_bw_2g,
20879 			reg_info->min_bw_5g, reg_info->max_bw_5g);
20880 
20881 	WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__,
20882 			num_2g_reg_rules, num_5g_reg_rules);
20883 	wmi_reg_rule =
20884 		(wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr
20885 			+ sizeof(wmi_reg_chan_list_cc_event_fixed_param)
20886 			+ WMI_TLV_HDR_SIZE);
20887 	reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules,
20888 			wmi_reg_rule);
20889 	wmi_reg_rule += num_2g_reg_rules;
20890 
20891 	reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules,
20892 			wmi_reg_rule);
20893 
20894 	WMI_LOGD("processed regulatory channel list");
20895 
20896 	return QDF_STATUS_SUCCESS;
20897 }
20898 
20899 static QDF_STATUS extract_reg_11d_new_country_event_tlv(
20900 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
20901 	struct reg_11d_new_country *reg_11d_country, uint32_t len)
20902 {
20903 	wmi_11d_new_country_event_fixed_param *reg_11d_country_event;
20904 	WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf;
20905 
20906 	param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf;
20907 	if (!param_buf) {
20908 		WMI_LOGE("invalid 11d country event buf");
20909 		return QDF_STATUS_E_FAILURE;
20910 	}
20911 
20912 	reg_11d_country_event = param_buf->fixed_param;
20913 
20914 	qdf_mem_copy(reg_11d_country->alpha2,
20915 			&reg_11d_country_event->new_alpha2, REG_ALPHA2_LEN);
20916 
20917 	WMI_LOGD("processed 11d country event, new cc %s",
20918 			reg_11d_country->alpha2);
20919 
20920 	return QDF_STATUS_SUCCESS;
20921 }
20922 
20923 static QDF_STATUS extract_reg_ch_avoid_event_tlv(
20924 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
20925 	struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len)
20926 {
20927 	wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param;
20928 	wmi_avoid_freq_range_desc *afr_desc;
20929 	uint32_t num_freq_ranges, freq_range_idx;
20930 	WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf =
20931 		(WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf;
20932 
20933 	if (!param_buf) {
20934 		WMI_LOGE("Invalid channel avoid event buffer");
20935 		return QDF_STATUS_E_INVAL;
20936 	}
20937 
20938 	afr_fixed_param = param_buf->fixed_param;
20939 	if (!afr_fixed_param) {
20940 		WMI_LOGE("Invalid channel avoid event fixed param buffer");
20941 		return QDF_STATUS_E_INVAL;
20942 	}
20943 
20944 	if (!ch_avoid_ind) {
20945 		WMI_LOGE("Invalid channel avoid indication buffer");
20946 		return QDF_STATUS_E_INVAL;
20947 	}
20948 	num_freq_ranges = (afr_fixed_param->num_freq_ranges >
20949 			CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE :
20950 			afr_fixed_param->num_freq_ranges;
20951 
20952 	WMI_LOGD("Channel avoid event received with %d ranges",
20953 		 num_freq_ranges);
20954 
20955 	ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges;
20956 	afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range);
20957 	for (freq_range_idx = 0; freq_range_idx < num_freq_ranges;
20958 	     freq_range_idx++) {
20959 		ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq =
20960 			afr_desc->start_freq;
20961 		ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq =
20962 			afr_desc->end_freq;
20963 		WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u",
20964 				freq_range_idx, afr_desc->tlv_header,
20965 				afr_desc->start_freq, afr_desc->end_freq);
20966 		afr_desc++;
20967 	}
20968 
20969 	return QDF_STATUS_SUCCESS;
20970 }
20971 #ifdef DFS_COMPONENT_ENABLE
20972 /**
20973  * extract_dfs_cac_complete_event_tlv() - extract cac complete event
20974  * @wmi_handle: wma handle
20975  * @evt_buf: event buffer
20976  * @vdev_id: vdev id
20977  * @len: length of buffer
20978  *
20979  * Return: 0 for success or error code
20980  */
20981 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle,
20982 		uint8_t *evt_buf,
20983 		uint32_t *vdev_id,
20984 		uint32_t len)
20985 {
20986 	WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs;
20987 	wmi_vdev_dfs_cac_complete_event_fixed_param  *cac_event;
20988 
20989 	param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf;
20990 	if (!param_tlvs) {
20991 		WMI_LOGE("invalid cac complete event buf");
20992 		return QDF_STATUS_E_FAILURE;
20993 	}
20994 
20995 	cac_event = param_tlvs->fixed_param;
20996 	*vdev_id = cac_event->vdev_id;
20997 	WMI_LOGD("processed cac complete event vdev %d", *vdev_id);
20998 
20999 	return QDF_STATUS_SUCCESS;
21000 }
21001 
21002 /**
21003  * extract_dfs_radar_detection_event_tlv() - extract radar found event
21004  * @wmi_handle: wma handle
21005  * @evt_buf: event buffer
21006  * @radar_found: radar found event info
21007  * @len: length of buffer
21008  *
21009  * Return: 0 for success or error code
21010  */
21011 static QDF_STATUS extract_dfs_radar_detection_event_tlv(
21012 		wmi_unified_t wmi_handle,
21013 		uint8_t *evt_buf,
21014 		struct radar_found_info *radar_found,
21015 		uint32_t len)
21016 {
21017 	WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv;
21018 	wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event;
21019 
21020 	param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf;
21021 	if (!param_tlv) {
21022 		WMI_LOGE("invalid radar detection event buf");
21023 		return QDF_STATUS_E_FAILURE;
21024 	}
21025 
21026 	radar_event = param_tlv->fixed_param;
21027 	radar_found->pdev_id = wmi_handle->ops->
21028 		convert_pdev_id_target_to_host(radar_event->pdev_id);
21029 	radar_found->detection_mode = radar_event->detection_mode;
21030 	radar_found->chan_freq = radar_event->chan_freq;
21031 	radar_found->chan_width = radar_event->chan_width;
21032 	radar_found->detector_id = radar_event->detector_id;
21033 	radar_found->segment_id = radar_event->segment_id;
21034 	radar_found->timestamp = radar_event->timestamp;
21035 	radar_found->is_chirp = radar_event->is_chirp;
21036 	radar_found->freq_offset = radar_event->freq_offset;
21037 	radar_found->sidx = radar_event->sidx;
21038 
21039 	WMI_LOGI("processed radar found event pdev %d,"
21040 		"Radar Event Info:pdev_id %d,timestamp %d,chan_freq  (dur) %d,"
21041 		"chan_width (RSSI) %d,detector_id (false_radar) %d,"
21042 		"freq_offset (radar_check) %d,segment_id %d,sidx %d,"
21043 		"is_chirp %d,detection mode %d\n",
21044 		radar_event->pdev_id, radar_event->pdev_id,
21045 		radar_event->timestamp, radar_event->chan_freq,
21046 		radar_event->chan_width, radar_event->detector_id,
21047 		radar_event->freq_offset, radar_event->segment_id,
21048 		radar_event->sidx, radar_event->is_chirp,
21049 		radar_event->detection_mode);
21050 
21051 	return QDF_STATUS_SUCCESS;
21052 }
21053 
21054 #ifdef QCA_MCL_DFS_SUPPORT
21055 /**
21056  * extract_wlan_radar_event_info_tlv() - extract radar pulse event
21057  * @wmi_handle: wma handle
21058  * @evt_buf: event buffer
21059  * @wlan_radar_event: Pointer to struct radar_event_info
21060  * @len: length of buffer
21061  *
21062  * Return: QDF_STATUS
21063  */
21064 static QDF_STATUS extract_wlan_radar_event_info_tlv(
21065 		wmi_unified_t wmi_handle,
21066 		uint8_t *evt_buf,
21067 		struct radar_event_info *wlan_radar_event,
21068 		uint32_t len)
21069 {
21070 	WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv;
21071 	wmi_dfs_radar_event_fixed_param *radar_event;
21072 
21073 	param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf;
21074 	if (!param_tlv) {
21075 		WMI_LOGE("invalid wlan radar event buf");
21076 		return QDF_STATUS_E_FAILURE;
21077 	}
21078 
21079 	radar_event = param_tlv->fixed_param;
21080 	wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp;
21081 	wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq;
21082 	wlan_radar_event->pulse_duration = radar_event->pulse_duration;
21083 	wlan_radar_event->rssi = radar_event->rssi;
21084 	wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts;
21085 	wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high;
21086 	wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low;
21087 	wlan_radar_event->peak_sidx = radar_event->peak_sidx;
21088 	wlan_radar_event->delta_peak = radar_event->pulse_delta_peak;
21089 	wlan_radar_event->delta_diff = radar_event->pulse_delta_diff;
21090 	wlan_radar_event->pdev_id = radar_event->pdev_id;
21091 
21092 	return QDF_STATUS_SUCCESS;
21093 }
21094 #else
21095 static QDF_STATUS extract_wlan_radar_event_info_tlv(
21096 		wmi_unified_t wmi_handle,
21097 		uint8_t *evt_buf,
21098 		struct radar_event_info *wlan_radar_event,
21099 		uint32_t len)
21100 {
21101 	return QDF_STATUS_SUCCESS;
21102 }
21103 #endif
21104 #endif
21105 
21106 /**
21107  * send_get_rcpi_cmd_tlv() - send request for rcpi value
21108  * @wmi_handle: wmi handle
21109  * @get_rcpi_param: rcpi params
21110  *
21111  * Return: QDF status
21112  */
21113 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle,
21114 					struct rcpi_req  *get_rcpi_param)
21115 {
21116 	wmi_buf_t buf;
21117 	wmi_request_rcpi_cmd_fixed_param *cmd;
21118 	uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param);
21119 
21120 	buf = wmi_buf_alloc(wmi_handle, len);
21121 	if (!buf) {
21122 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
21123 		return QDF_STATUS_E_NOMEM;
21124 	}
21125 
21126 	cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf);
21127 	WMITLV_SET_HDR(&cmd->tlv_header,
21128 		       WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param,
21129 		       WMITLV_GET_STRUCT_TLVLEN
21130 		       (wmi_request_rcpi_cmd_fixed_param));
21131 
21132 	cmd->vdev_id = get_rcpi_param->vdev_id;
21133 	WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr,
21134 				   &cmd->peer_macaddr);
21135 	cmd->measurement_type = get_rcpi_param->measurement_type;
21136 	WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id);
21137 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21138 				 WMI_REQUEST_RCPI_CMDID)) {
21139 
21140 		WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID",
21141 			 __func__);
21142 		wmi_buf_free(buf);
21143 		return QDF_STATUS_E_FAILURE;
21144 	}
21145 
21146 	return QDF_STATUS_SUCCESS;
21147 }
21148 
21149 /**
21150  * extract_rcpi_response_event_tlv() - Extract RCPI event params
21151  * @wmi_handle: wmi handle
21152  * @evt_buf: pointer to event buffer
21153  * @res: pointer to hold rcpi response from firmware
21154  *
21155  * Return: QDF_STATUS_SUCCESS for successful event parse
21156  *         else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE
21157  */
21158 static QDF_STATUS
21159 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle,
21160 				void *evt_buf, struct rcpi_res *res)
21161 {
21162 	WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf;
21163 	wmi_update_rcpi_event_fixed_param *event;
21164 
21165 	param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf;
21166 	if (!param_buf) {
21167 		WMI_LOGE(FL("Invalid rcpi event"));
21168 		return QDF_STATUS_E_INVAL;
21169 	}
21170 
21171 	event = param_buf->fixed_param;
21172 	res->vdev_id = event->vdev_id;
21173 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr);
21174 
21175 	switch (event->measurement_type) {
21176 
21177 	case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT:
21178 		res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT;
21179 		break;
21180 
21181 	case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA:
21182 		res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA;
21183 		break;
21184 
21185 	case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT:
21186 		res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT;
21187 		break;
21188 
21189 	case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA:
21190 		res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA;
21191 		break;
21192 
21193 	default:
21194 		WMI_LOGE(FL("Invalid rcpi measurement type from firmware"));
21195 		res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID;
21196 		return QDF_STATUS_E_FAILURE;
21197 	}
21198 
21199 	if (event->status)
21200 		return QDF_STATUS_E_FAILURE;
21201 	else
21202 		return QDF_STATUS_SUCCESS;
21203 }
21204 
21205 /**
21206  * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from
21207  *           host to target defines. For legacy there is not conversion
21208  *           required. Just return pdev_id as it is.
21209  * @param pdev_id: host pdev_id to be converted.
21210  * Return: target pdev_id after conversion.
21211  */
21212 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy(
21213 							uint32_t pdev_id)
21214 {
21215 	if (pdev_id == WMI_HOST_PDEV_ID_SOC)
21216 		return WMI_PDEV_ID_SOC;
21217 
21218 	/*No conversion required*/
21219 	return pdev_id;
21220 }
21221 
21222 /**
21223  * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from
21224  *           target to host defines. For legacy there is not conversion
21225  *           required. Just return pdev_id as it is.
21226  * @param pdev_id: target pdev_id to be converted.
21227  * Return: host pdev_id after conversion.
21228  */
21229 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy(
21230 							uint32_t pdev_id)
21231 {
21232 	/*No conversion required*/
21233 	return pdev_id;
21234 }
21235 
21236 /**
21237  *  send_set_country_cmd_tlv() - WMI scan channel list function
21238  *  @param wmi_handle      : handle to WMI.
21239  *  @param param    : pointer to hold scan channel list parameter
21240  *
21241  *  Return: 0  on success and -ve on failure.
21242  */
21243 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle,
21244 				struct set_country *params)
21245 {
21246 	wmi_buf_t buf;
21247 	QDF_STATUS qdf_status;
21248 	wmi_set_current_country_cmd_fixed_param *cmd;
21249 	uint16_t len = sizeof(*cmd);
21250 
21251 	buf = wmi_buf_alloc(wmi_handle, len);
21252 	if (!buf) {
21253 		WMI_LOGE("Failed to allocate memory");
21254 		qdf_status = QDF_STATUS_E_NOMEM;
21255 		goto end;
21256 	}
21257 
21258 	cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf);
21259 	WMITLV_SET_HDR(&cmd->tlv_header,
21260 		       WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param,
21261 		       WMITLV_GET_STRUCT_TLVLEN
21262 			       (wmi_set_current_country_cmd_fixed_param));
21263 
21264 	WMI_LOGD("setting cuurnet country to  %s", params->country);
21265 
21266 	qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3);
21267 
21268 	cmd->pdev_id = params->pdev_id;
21269 
21270 	qdf_status = wmi_unified_cmd_send(wmi_handle,
21271 			buf, len, WMI_SET_CURRENT_COUNTRY_CMDID);
21272 
21273 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
21274 		WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID");
21275 		wmi_buf_free(buf);
21276 	}
21277 
21278 end:
21279 	return qdf_status;
21280 }
21281 
21282 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2)          do { \
21283 	    WMI_SET_BITS(alpha, 0, 8, val0); \
21284 	    WMI_SET_BITS(alpha, 8, 8, val1); \
21285 	    WMI_SET_BITS(alpha, 16, 8, val2); \
21286 	    } while (0)
21287 
21288 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle,
21289 		uint8_t pdev_id, struct cc_regdmn_s *rd)
21290 {
21291 	wmi_set_init_country_cmd_fixed_param *cmd;
21292 	uint16_t len;
21293 	wmi_buf_t buf;
21294 	int ret;
21295 
21296 	len = sizeof(wmi_set_init_country_cmd_fixed_param);
21297 	buf = wmi_buf_alloc(wmi_handle, len);
21298 	if (!buf) {
21299 		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
21300 		return QDF_STATUS_E_NOMEM;
21301 	}
21302 	cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf);
21303 	WMITLV_SET_HDR(&cmd->tlv_header,
21304 			WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param,
21305 			WMITLV_GET_STRUCT_TLVLEN
21306 			(wmi_set_init_country_cmd_fixed_param));
21307 
21308 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
21309 
21310 	if (rd->flags == CC_IS_SET) {
21311 		cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID;
21312 		cmd->country_code.country_id = rd->cc.country_code;
21313 	} else if (rd->flags == ALPHA_IS_SET) {
21314 		cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2;
21315 		WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2,
21316 				rd->cc.alpha[0],
21317 				rd->cc.alpha[1],
21318 				rd->cc.alpha[2]);
21319 	} else if (rd->flags == REGDMN_IS_SET) {
21320 		cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE;
21321 		cmd->country_code.domain_code = rd->cc.regdmn_id;
21322 	}
21323 
21324 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
21325 			WMI_SET_INIT_COUNTRY_CMDID);
21326 	if (ret) {
21327 		WMI_LOGE("Failed to config wow wakeup event");
21328 		wmi_buf_free(buf);
21329 		return QDF_STATUS_E_FAILURE;
21330 	}
21331 
21332 	return QDF_STATUS_SUCCESS;
21333 }
21334 
21335 /**
21336  * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan
21337  * configuration params
21338  * @wmi_handle: wmi handler
21339  * @limit_off_chan_param: pointer to wmi_off_chan_param
21340  *
21341  * Return: 0 for success and non zero for failure
21342  */
21343 static
21344 QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle,
21345 		struct wmi_limit_off_chan_param *limit_off_chan_param)
21346 {
21347 	wmi_vdev_limit_offchan_cmd_fixed_param *cmd;
21348 	wmi_buf_t buf;
21349 	uint32_t len = sizeof(*cmd);
21350 	int err;
21351 
21352 	buf = wmi_buf_alloc(wmi_handle, len);
21353 	if (!buf) {
21354 		WMI_LOGP("%s: failed to allocate memory for limit off chan cmd",
21355 				__func__);
21356 		return QDF_STATUS_E_NOMEM;
21357 	}
21358 
21359 	cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf);
21360 
21361 	WMITLV_SET_HDR(&cmd->tlv_header,
21362 			WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param,
21363 			WMITLV_GET_STRUCT_TLVLEN(
21364 				wmi_vdev_limit_offchan_cmd_fixed_param));
21365 
21366 	cmd->vdev_id = limit_off_chan_param->vdev_id;
21367 
21368 	cmd->flags &= 0;
21369 	if (limit_off_chan_param->status)
21370 		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE;
21371 	if (limit_off_chan_param->skip_dfs_chans)
21372 		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS;
21373 
21374 	cmd->max_offchan_time = limit_off_chan_param->max_offchan_time;
21375 	cmd->rest_time = limit_off_chan_param->rest_time;
21376 
21377 	WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d",
21378 			__func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time,
21379 			cmd->rest_time);
21380 
21381 	err = wmi_unified_cmd_send(wmi_handle, buf,
21382 			len, WMI_VDEV_LIMIT_OFFCHAN_CMDID);
21383 	if (QDF_IS_STATUS_ERROR(err)) {
21384 		WMI_LOGE("Failed to send limit off chan cmd err=%d", err);
21385 		wmi_buf_free(buf);
21386 		return QDF_STATUS_E_FAILURE;
21387 	}
21388 
21389 	return QDF_STATUS_SUCCESS;
21390 }
21391 
21392 /**
21393  * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request
21394  * @wmi_handle: wmi handler
21395  * @req_buf: set arp stats request buffer
21396  *
21397  * Return: 0 for success and non zero for failure
21398  */
21399 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
21400 					  struct set_arp_stats *req_buf)
21401 {
21402 	wmi_buf_t buf = NULL;
21403 	QDF_STATUS status;
21404 	int len;
21405 	uint8_t *buf_ptr;
21406 	wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp;
21407 
21408 	len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
21409 	if (req_buf->pkt_type_bitmap) {
21410 		len += WMI_TLV_HDR_SIZE;
21411 		len += sizeof(wmi_vdev_set_connectivity_check_stats);
21412 	}
21413 	buf = wmi_buf_alloc(wmi_handle, len);
21414 	if (!buf) {
21415 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
21416 		return QDF_STATUS_E_NOMEM;
21417 	}
21418 
21419 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21420 	wmi_set_arp =
21421 		(wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr;
21422 	WMITLV_SET_HDR(&wmi_set_arp->tlv_header,
21423 		       WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param,
21424 		       WMITLV_GET_STRUCT_TLVLEN
21425 		       (wmi_vdev_set_arp_stats_cmd_fixed_param));
21426 
21427 	/* fill in per roam config values */
21428 	wmi_set_arp->vdev_id = req_buf->vdev_id;
21429 
21430 	wmi_set_arp->set_clr = req_buf->flag;
21431 	wmi_set_arp->pkt_type = req_buf->pkt_type;
21432 	wmi_set_arp->ipv4 = req_buf->ip_addr;
21433 
21434 	WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u",
21435 			 wmi_set_arp->vdev_id, wmi_set_arp->set_clr,
21436 			 wmi_set_arp->pkt_type, wmi_set_arp->ipv4);
21437 
21438 	/*
21439 	 * pkt_type_bitmap should be non-zero to ensure
21440 	 * presence of additional stats.
21441 	 */
21442 	if (req_buf->pkt_type_bitmap) {
21443 		wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats;
21444 
21445 		buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
21446 		WMITLV_SET_HDR(buf_ptr,
21447 			   WMITLV_TAG_ARRAY_STRUC,
21448 			   sizeof(wmi_vdev_set_connectivity_check_stats));
21449 		buf_ptr += WMI_TLV_HDR_SIZE;
21450 		wmi_set_connect_stats =
21451 			(wmi_vdev_set_connectivity_check_stats *)buf_ptr;
21452 		WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header,
21453 			WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats,
21454 			WMITLV_GET_STRUCT_TLVLEN(
21455 					wmi_vdev_set_connectivity_check_stats));
21456 		wmi_set_connect_stats->pkt_type_bitmap =
21457 						req_buf->pkt_type_bitmap;
21458 		wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port;
21459 		wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port;
21460 		wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4;
21461 
21462 		WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u",
21463 			 wmi_set_connect_stats->pkt_type_bitmap,
21464 			 wmi_set_connect_stats->tcp_src_port,
21465 			 wmi_set_connect_stats->tcp_dst_port,
21466 			 wmi_set_connect_stats->icmp_ipv4);
21467 	}
21468 
21469 	/* Send per roam config parameters */
21470 	status = wmi_unified_cmd_send(wmi_handle, buf,
21471 				      len, WMI_VDEV_SET_ARP_STAT_CMDID);
21472 	if (QDF_IS_STATUS_ERROR(status)) {
21473 		WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d",
21474 			 status);
21475 		goto error;
21476 	}
21477 
21478 	WMI_LOGI(FL("set arp stats flag=%d, vdev=%d"),
21479 		 req_buf->flag, req_buf->vdev_id);
21480 	return QDF_STATUS_SUCCESS;
21481 error:
21482 	wmi_buf_free(buf);
21483 
21484 	return status;
21485 }
21486 
21487 /**
21488  * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request
21489  * @wmi_handle: wmi handler
21490  * @req_buf: get arp stats request buffer
21491  *
21492  * Return: 0 for success and non zero for failure
21493  */
21494 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
21495 					  struct get_arp_stats *req_buf)
21496 {
21497 	wmi_buf_t buf = NULL;
21498 	QDF_STATUS status;
21499 	int len;
21500 	uint8_t *buf_ptr;
21501 	wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats;
21502 
21503 	len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param);
21504 	buf = wmi_buf_alloc(wmi_handle, len);
21505 	if (!buf) {
21506 		WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
21507 		return QDF_STATUS_E_NOMEM;
21508 	}
21509 
21510 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21511 	get_arp_stats =
21512 		(wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr;
21513 	WMITLV_SET_HDR(&get_arp_stats->tlv_header,
21514 		       WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param,
21515 		       WMITLV_GET_STRUCT_TLVLEN
21516 		       (wmi_vdev_get_arp_stats_cmd_fixed_param));
21517 
21518 	/* fill in arp stats req cmd values */
21519 	get_arp_stats->vdev_id = req_buf->vdev_id;
21520 
21521 	WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id);
21522 	/* Send per roam config parameters */
21523 	status = wmi_unified_cmd_send(wmi_handle, buf,
21524 				      len, WMI_VDEV_GET_ARP_STAT_CMDID);
21525 	if (QDF_IS_STATUS_ERROR(status)) {
21526 		WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d",
21527 			 status);
21528 		goto error;
21529 	}
21530 
21531 	return QDF_STATUS_SUCCESS;
21532 error:
21533 	wmi_buf_free(buf);
21534 
21535 	return status;
21536 }
21537 
21538 /**
21539  * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid
21540  * @wmi_handle: wmi handler
21541  * @pmk_info: pointer to PMK cache entry
21542  * @vdev_id: vdev id
21543  *
21544  * Return: 0 for success and non zero for failure
21545  */
21546 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle,
21547 				struct wmi_unified_pmk_cache *pmk_info)
21548 {
21549 	wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd;
21550 	wmi_buf_t buf;
21551 	QDF_STATUS status;
21552 	uint8_t *buf_ptr;
21553 	wmi_pmk_cache *pmksa;
21554 	uint32_t len = sizeof(*cmd);
21555 
21556 	if (pmk_info->pmk_len)
21557 		len += WMI_TLV_HDR_SIZE + sizeof(*pmksa);
21558 
21559 	buf = wmi_buf_alloc(wmi_handle, len);
21560 	if (!buf) {
21561 		WMI_LOGP("%s: failed to allocate memory for set del pmkid cache",
21562 			 __func__);
21563 		return QDF_STATUS_E_NOMEM;
21564 	}
21565 
21566 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21567 	cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr;
21568 
21569 	WMITLV_SET_HDR(&cmd->tlv_header,
21570 		 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param,
21571 		 WMITLV_GET_STRUCT_TLVLEN(
21572 			wmi_pdev_update_pmk_cache_cmd_fixed_param));
21573 
21574 	cmd->vdev_id = pmk_info->session_id;
21575 
21576 	/* If pmk_info->pmk_len is 0, this is a flush request */
21577 	if (!pmk_info->pmk_len) {
21578 		cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL;
21579 		cmd->num_cache = 0;
21580 		goto send_cmd;
21581 	}
21582 
21583 	cmd->num_cache = 1;
21584 	buf_ptr += sizeof(*cmd);
21585 
21586 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
21587 			sizeof(*pmksa));
21588 	buf_ptr += WMI_TLV_HDR_SIZE;
21589 
21590 	pmksa = (wmi_pmk_cache *)buf_ptr;
21591 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache,
21592 			WMITLV_GET_STRUCT_TLVLEN
21593 				(wmi_pmk_cache));
21594 	pmksa->pmk_len = pmk_info->pmk_len;
21595 	qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len);
21596 	pmksa->pmkid_len = pmk_info->pmkid_len;
21597 	qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len);
21598 	qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr));
21599 	pmksa->ssid.ssid_len = pmk_info->ssid.length;
21600 	qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid),
21601 			pmksa->ssid.ssid_len);
21602 	pmksa->cache_id = pmk_info->cache_id;
21603 	pmksa->cat_flag = pmk_info->cat_flag;
21604 	pmksa->action_flag = pmk_info->action_flag;
21605 
21606 send_cmd:
21607 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
21608 			WMI_PDEV_UPDATE_PMK_CACHE_CMDID);
21609 	if (status != QDF_STATUS_SUCCESS) {
21610 		WMI_LOGE("%s: failed to send set del pmkid cache command %d",
21611 			 __func__, status);
21612 		wmi_buf_free(buf);
21613 	}
21614 
21615 	return status;
21616 }
21617 
21618 /**
21619  * send_pdev_caldata_version_check_cmd_tlv() - send caldata check cmd to fw
21620  * @wmi_handle: wmi handle
21621  * @param:	reserved param
21622  *
21623  * Return: 0 for success or error code
21624  */
21625 static QDF_STATUS
21626 send_pdev_caldata_version_check_cmd_tlv(wmi_unified_t wmi_handle,
21627 						uint32_t param)
21628 {
21629 	wmi_pdev_check_cal_version_cmd_fixed_param *cmd;
21630 	wmi_buf_t buf;
21631 	int32_t len = sizeof(wmi_pdev_check_cal_version_cmd_fixed_param);
21632 
21633 	buf = wmi_buf_alloc(wmi_handle, len);
21634 	if (!buf) {
21635 		qdf_print("%s:wmi_buf_alloc failed\n", __func__);
21636 		return QDF_STATUS_E_FAILURE;
21637 	}
21638 	cmd = (wmi_pdev_check_cal_version_cmd_fixed_param *)wmi_buf_data(buf);
21639 	WMITLV_SET_HDR(&cmd->tlv_header,
21640 			WMITLV_TAG_STRUC_wmi_pdev_check_cal_version_cmd_fixed_param,
21641 			WMITLV_GET_STRUCT_TLVLEN
21642 			(wmi_pdev_check_cal_version_cmd_fixed_param));
21643 	cmd->pdev_id = param; /* set to 0x0 as expected from FW */
21644 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21645 			WMI_PDEV_CHECK_CAL_VERSION_CMDID)) {
21646 		wmi_buf_free(buf);
21647 		return QDF_STATUS_E_FAILURE;
21648 	}
21649 
21650 	return QDF_STATUS_SUCCESS;
21651 }
21652 
21653 /**
21654  * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from
21655  *           host to target defines.
21656  * @param pdev_id: host pdev_id to be converted.
21657  * Return: target pdev_id after conversion.
21658  */
21659 static uint32_t convert_host_pdev_id_to_target_pdev_id(uint32_t pdev_id)
21660 {
21661 	switch (pdev_id) {
21662 	case WMI_HOST_PDEV_ID_SOC:
21663 		return WMI_PDEV_ID_SOC;
21664 	case WMI_HOST_PDEV_ID_0:
21665 		return WMI_PDEV_ID_1ST;
21666 	case WMI_HOST_PDEV_ID_1:
21667 		return WMI_PDEV_ID_2ND;
21668 	case WMI_HOST_PDEV_ID_2:
21669 		return WMI_PDEV_ID_3RD;
21670 	}
21671 
21672 	QDF_ASSERT(0);
21673 
21674 	return WMI_PDEV_ID_SOC;
21675 }
21676 
21677 /**
21678  * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from
21679  *           target to host defines.
21680  * @param pdev_id: target pdev_id to be converted.
21681  * Return: host pdev_id after conversion.
21682  */
21683 static uint32_t convert_target_pdev_id_to_host_pdev_id(uint32_t pdev_id)
21684 {
21685 	switch (pdev_id) {
21686 	case WMI_PDEV_ID_SOC:
21687 		return WMI_HOST_PDEV_ID_SOC;
21688 	case WMI_PDEV_ID_1ST:
21689 		return WMI_HOST_PDEV_ID_0;
21690 	case WMI_PDEV_ID_2ND:
21691 		return WMI_HOST_PDEV_ID_1;
21692 	case WMI_PDEV_ID_3RD:
21693 		return WMI_HOST_PDEV_ID_2;
21694 	}
21695 
21696 	QDF_ASSERT(0);
21697 
21698 	return WMI_HOST_PDEV_ID_SOC;
21699 }
21700 
21701 /**
21702  * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion
21703  *
21704  * Return None.
21705  */
21706 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle)
21707 {
21708 	wmi_handle->ops->convert_pdev_id_host_to_target =
21709 		convert_host_pdev_id_to_target_pdev_id;
21710 	wmi_handle->ops->convert_pdev_id_target_to_host =
21711 		convert_target_pdev_id_to_host_pdev_id;
21712 }
21713 
21714 /**
21715  * extract_pdev_caldata_version_check_ev_param_tlv() - extract caldata from event
21716  * @wmi_handle: wmi handle
21717  * @param evt_buf: pointer to event buffer
21718  * @param param: Pointer to hold peer caldata version data
21719  *
21720  * Return: 0 for success or error code
21721  */
21722 static QDF_STATUS extract_pdev_caldata_version_check_ev_param_tlv(
21723 			wmi_unified_t wmi_handle,
21724 			void *evt_buf,
21725 			wmi_host_pdev_check_cal_version_event *param)
21726 {
21727 	WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *param_tlvs;
21728 	wmi_pdev_check_cal_version_event_fixed_param *event;
21729 
21730 	param_tlvs = (WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *) evt_buf;
21731 	if (!param_tlvs) {
21732 		WMI_LOGE("invalid cal version event buf");
21733 		return QDF_STATUS_E_FAILURE;
21734 	}
21735 	event =  param_tlvs->fixed_param;
21736 	if (event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] != '\0')
21737 		event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] = '\0';
21738 	WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(param->board_mcn_detail,
21739 			event->board_mcn_detail, WMI_BOARD_MCN_STRING_BUF_SIZE);
21740 
21741 	param->software_cal_version = event->software_cal_version;
21742 	param->board_cal_version = event->board_cal_version;
21743 	param->cal_ok  = event->cal_status;
21744 
21745 	return QDF_STATUS_SUCCESS;
21746 }
21747 
21748 /*
21749  * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config
21750  * @wmi_handle: wmi handle
21751  * @params: pointer to wmi_btm_config
21752  *
21753  * Return: QDF_STATUS
21754  */
21755 static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle,
21756 					  struct wmi_btm_config *params)
21757 {
21758 
21759 	wmi_btm_config_fixed_param *cmd;
21760 	wmi_buf_t buf;
21761 	uint32_t len;
21762 
21763 	len = sizeof(*cmd);
21764 	buf = wmi_buf_alloc(wmi_handle, len);
21765 	if (!buf) {
21766 		qdf_print("%s:wmi_buf_alloc failed\n", __func__);
21767 		return QDF_STATUS_E_NOMEM;
21768 	}
21769 
21770 	cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf);
21771 	WMITLV_SET_HDR(&cmd->tlv_header,
21772 		       WMITLV_TAG_STRUC_wmi_btm_config_fixed_param,
21773 		       WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param));
21774 	cmd->vdev_id = params->vdev_id;
21775 	cmd->flags = params->btm_offload_config;
21776 	cmd->max_attempt_cnt = params->btm_max_attempt_cnt;
21777 	cmd->solicited_timeout_ms = params->btm_solicited_timeout;
21778 	cmd->stick_time_seconds = params->btm_sticky_time;
21779 
21780 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21781 	    WMI_ROAM_BTM_CONFIG_CMDID)) {
21782 		WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID",
21783 			 __func__);
21784 		wmi_buf_free(buf);
21785 		return QDF_STATUS_E_FAILURE;
21786 	}
21787 
21788 	return QDF_STATUS_SUCCESS;
21789 }
21790 
21791 /**
21792  * send_obss_detection_cfg_cmd_tlv() - send obss detection
21793  *   configurations to firmware.
21794  * @wmi_handle: wmi handle
21795  * @obss_cfg_param: obss detection configurations
21796  *
21797  * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw.
21798  *
21799  * Return: QDF_STATUS
21800  */
21801 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle,
21802 		struct wmi_obss_detection_cfg_param *obss_cfg_param)
21803 {
21804 	wmi_buf_t buf;
21805 	wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd;
21806 	uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param);
21807 
21808 	buf = wmi_buf_alloc(wmi_handle, len);
21809 	if (!buf) {
21810 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
21811 		return QDF_STATUS_E_NOMEM;
21812 	}
21813 
21814 	cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf);
21815 	WMITLV_SET_HDR(&cmd->tlv_header,
21816 		WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param,
21817 		       WMITLV_GET_STRUCT_TLVLEN
21818 		       (wmi_sap_obss_detection_cfg_cmd_fixed_param));
21819 
21820 	cmd->vdev_id = obss_cfg_param->vdev_id;
21821 	cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms;
21822 	cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode;
21823 	cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode;
21824 	cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode;
21825 	cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode;
21826 	cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode;
21827 	cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode;
21828 	cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode;
21829 
21830 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
21831 				 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) {
21832 		WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID");
21833 		wmi_buf_free(buf);
21834 		return QDF_STATUS_E_FAILURE;
21835 	}
21836 
21837 	return QDF_STATUS_SUCCESS;
21838 }
21839 
21840 /**
21841  * extract_obss_detection_info_tlv() - Extract obss detection info
21842  *   received from firmware.
21843  * @evt_buf: pointer to event buffer
21844  * @obss_detection: Pointer to hold obss detection info
21845  *
21846  * Return: QDF_STATUS
21847  */
21848 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf,
21849 						  struct wmi_obss_detect_info
21850 						  *obss_detection)
21851 {
21852 	WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf;
21853 	wmi_sap_obss_detection_info_evt_fixed_param *fix_param;
21854 
21855 	if (!obss_detection) {
21856 		WMI_LOGE("%s: Invalid obss_detection event buffer", __func__);
21857 		return QDF_STATUS_E_INVAL;
21858 	}
21859 
21860 	param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf;
21861 	if (!param_buf) {
21862 		WMI_LOGE("%s: Invalid evt_buf", __func__);
21863 		return QDF_STATUS_E_INVAL;
21864 	}
21865 
21866 	fix_param = param_buf->fixed_param;
21867 	obss_detection->vdev_id = fix_param->vdev_id;
21868 	obss_detection->matched_detection_masks =
21869 		fix_param->matched_detection_masks;
21870 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr,
21871 				   &obss_detection->matched_bssid_addr[0]);
21872 	switch (fix_param->reason) {
21873 	case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT:
21874 		obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED;
21875 		break;
21876 	case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY:
21877 		obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT;
21878 		break;
21879 	case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT:
21880 		obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT;
21881 		break;
21882 	default:
21883 		WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason);
21884 		return QDF_STATUS_E_INVAL;
21885 	}
21886 
21887 	return QDF_STATUS_SUCCESS;
21888 }
21889 
21890 /**
21891  * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params
21892  * @wmi_handle: wmi handler
21893  * @params: pointer to 11k offload params
21894  *
21895  * Return: 0 for success and non zero for failure
21896  */
21897 static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle,
21898 				struct wmi_11k_offload_params *params)
21899 {
21900 	wmi_11k_offload_report_fixed_param *cmd;
21901 	wmi_buf_t buf;
21902 	QDF_STATUS status;
21903 	uint8_t *buf_ptr;
21904 	wmi_neighbor_report_11k_offload_tlv_param
21905 					*neighbor_report_offload_params;
21906 	wmi_neighbor_report_offload *neighbor_report_offload;
21907 
21908 	uint32_t len = sizeof(*cmd);
21909 
21910 	if (params->offload_11k_bitmask &
21911 	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ)
21912 		len += WMI_TLV_HDR_SIZE +
21913 			sizeof(wmi_neighbor_report_11k_offload_tlv_param);
21914 
21915 	buf = wmi_buf_alloc(wmi_handle, len);
21916 	if (!buf) {
21917 		WMI_LOGP("%s: failed to allocate memory for 11k offload params",
21918 			 __func__);
21919 		return QDF_STATUS_E_NOMEM;
21920 	}
21921 
21922 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
21923 	cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr;
21924 
21925 	WMITLV_SET_HDR(&cmd->tlv_header,
21926 		 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param,
21927 		 WMITLV_GET_STRUCT_TLVLEN(
21928 			wmi_11k_offload_report_fixed_param));
21929 
21930 	cmd->vdev_id = params->vdev_id;
21931 	cmd->offload_11k = params->offload_11k_bitmask;
21932 
21933 	if (params->offload_11k_bitmask &
21934 	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) {
21935 		buf_ptr += sizeof(wmi_11k_offload_report_fixed_param);
21936 
21937 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
21938 			sizeof(wmi_neighbor_report_11k_offload_tlv_param));
21939 		buf_ptr += WMI_TLV_HDR_SIZE;
21940 
21941 		neighbor_report_offload_params =
21942 			(wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr;
21943 		WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header,
21944 			WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param,
21945 			WMITLV_GET_STRUCT_TLVLEN(
21946 			wmi_neighbor_report_11k_offload_tlv_param));
21947 
21948 		neighbor_report_offload = &neighbor_report_offload_params->
21949 			neighbor_rep_ofld_params;
21950 
21951 		neighbor_report_offload->time_offset =
21952 			params->neighbor_report_params.time_offset;
21953 		neighbor_report_offload->low_rssi_offset =
21954 			params->neighbor_report_params.low_rssi_offset;
21955 		neighbor_report_offload->bmiss_count_trigger =
21956 			params->neighbor_report_params.bmiss_count_trigger;
21957 		neighbor_report_offload->per_threshold_offset =
21958 			params->neighbor_report_params.per_threshold_offset;
21959 		neighbor_report_offload->neighbor_report_cache_timeout =
21960 			params->neighbor_report_params.
21961 			neighbor_report_cache_timeout;
21962 		neighbor_report_offload->max_neighbor_report_req_cap =
21963 			params->neighbor_report_params.
21964 			max_neighbor_report_req_cap;
21965 		neighbor_report_offload->ssid.ssid_len =
21966 			params->neighbor_report_params.ssid.length;
21967 		qdf_mem_copy(neighbor_report_offload->ssid.ssid,
21968 			&params->neighbor_report_params.ssid.mac_ssid,
21969 			neighbor_report_offload->ssid.ssid_len);
21970 	}
21971 
21972 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
21973 			WMI_11K_OFFLOAD_REPORT_CMDID);
21974 	if (status != QDF_STATUS_SUCCESS) {
21975 		WMI_LOGE("%s: failed to send 11k offload command %d",
21976 			 __func__, status);
21977 		wmi_buf_free(buf);
21978 	}
21979 
21980 	return status;
21981 }
21982 
21983 /**
21984  * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report
21985  * command
21986  * @wmi_handle: wmi handler
21987  * @params: pointer to neighbor report invoke params
21988  *
21989  * Return: 0 for success and non zero for failure
21990  */
21991 static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle,
21992 			struct wmi_invoke_neighbor_report_params *params)
21993 {
21994 	wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd;
21995 	wmi_buf_t buf;
21996 	QDF_STATUS status;
21997 	uint8_t *buf_ptr;
21998 	uint32_t len = sizeof(*cmd);
21999 
22000 	buf = wmi_buf_alloc(wmi_handle, len);
22001 	if (!buf) {
22002 		WMI_LOGP("%s:failed to allocate memory for neighbor invoke cmd",
22003 			 __func__);
22004 		return QDF_STATUS_E_NOMEM;
22005 	}
22006 
22007 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
22008 	cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr;
22009 
22010 	WMITLV_SET_HDR(&cmd->tlv_header,
22011 		 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param,
22012 		 WMITLV_GET_STRUCT_TLVLEN(
22013 			wmi_11k_offload_invoke_neighbor_report_fixed_param));
22014 
22015 	cmd->vdev_id = params->vdev_id;
22016 	cmd->flags = params->send_resp_to_host;
22017 
22018 	cmd->ssid.ssid_len = params->ssid.length;
22019 	qdf_mem_copy(cmd->ssid.ssid,
22020 		     &params->ssid.mac_ssid,
22021 		     cmd->ssid.ssid_len);
22022 
22023 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
22024 			WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID);
22025 	if (status != QDF_STATUS_SUCCESS) {
22026 		WMI_LOGE("%s: failed to send invoke neighbor report command %d",
22027 			 __func__, status);
22028 		wmi_buf_free(buf);
22029 	}
22030 
22031 	return status;
22032 }
22033 
22034 #ifdef WLAN_SUPPORT_GREEN_AP
22035 static QDF_STATUS extract_green_ap_egap_status_info_tlv(
22036 		uint8_t *evt_buf,
22037 		struct wlan_green_ap_egap_status_info *egap_status_info_params)
22038 {
22039 	WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf;
22040 	wmi_ap_ps_egap_info_event_fixed_param  *egap_info_event;
22041 	wmi_ap_ps_egap_info_chainmask_list *chainmask_event;
22042 
22043 	param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf;
22044 	if (!param_buf) {
22045 		WMI_LOGE("Invalid EGAP Info status event buffer");
22046 		return QDF_STATUS_E_INVAL;
22047 	}
22048 
22049 	egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *)
22050 				param_buf->fixed_param;
22051 	chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *)
22052 				param_buf->chainmask_list;
22053 
22054 	egap_status_info_params->status = egap_info_event->status;
22055 	egap_status_info_params->mac_id = chainmask_event->mac_id;
22056 	egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask;
22057 	egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask;
22058 
22059 	return QDF_STATUS_SUCCESS;
22060 }
22061 #endif
22062 
22063 /*
22064  * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of
22065  * updating bss color change within firmware when AP announces bss color change.
22066  * @wmi_handle: wmi handle
22067  * @vdev_id: vdev ID
22068  * @enable: enable bss color change within firmware
22069  *
22070  * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw.
22071  *
22072  * Return: QDF_STATUS
22073  */
22074 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle,
22075 						       uint32_t vdev_id,
22076 						       bool enable)
22077 {
22078 	wmi_buf_t buf;
22079 	wmi_bss_color_change_enable_fixed_param *cmd;
22080 	uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param);
22081 
22082 	buf = wmi_buf_alloc(wmi_handle, len);
22083 	if (!buf) {
22084 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
22085 		return QDF_STATUS_E_NOMEM;
22086 	}
22087 
22088 	cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf);
22089 	WMITLV_SET_HDR(&cmd->tlv_header,
22090 		WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param,
22091 		       WMITLV_GET_STRUCT_TLVLEN
22092 		       (wmi_bss_color_change_enable_fixed_param));
22093 	cmd->vdev_id = vdev_id;
22094 	cmd->enable = enable;
22095 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
22096 				 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) {
22097 		WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID");
22098 		wmi_buf_free(buf);
22099 		return QDF_STATUS_E_FAILURE;
22100 	}
22101 
22102 	return QDF_STATUS_SUCCESS;
22103 }
22104 
22105 /**
22106  * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection
22107  *   configurations to firmware.
22108  * @wmi_handle: wmi handle
22109  * @cfg_param: obss detection configurations
22110  *
22111  * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw.
22112  *
22113  * Return: QDF_STATUS
22114  */
22115 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv(
22116 		wmi_unified_t wmi_handle,
22117 		struct wmi_obss_color_collision_cfg_param *cfg_param)
22118 {
22119 	wmi_buf_t buf;
22120 	wmi_obss_color_collision_det_config_fixed_param *cmd;
22121 	uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param);
22122 
22123 	buf = wmi_buf_alloc(wmi_handle, len);
22124 	if (!buf) {
22125 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
22126 		return QDF_STATUS_E_NOMEM;
22127 	}
22128 
22129 	cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data(
22130 			buf);
22131 	WMITLV_SET_HDR(&cmd->tlv_header,
22132 	WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param,
22133 		       WMITLV_GET_STRUCT_TLVLEN
22134 		       (wmi_obss_color_collision_det_config_fixed_param));
22135 	cmd->vdev_id = cfg_param->vdev_id;
22136 	cmd->flags = cfg_param->flags;
22137 	cmd->current_bss_color = cfg_param->current_bss_color;
22138 	cmd->detection_period_ms = cfg_param->detection_period_ms;
22139 	cmd->scan_period_ms = cfg_param->scan_period_ms;
22140 	cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms;
22141 
22142 	switch (cfg_param->evt_type) {
22143 	case OBSS_COLOR_COLLISION_DETECTION_DISABLE:
22144 		cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE;
22145 		break;
22146 	case OBSS_COLOR_COLLISION_DETECTION:
22147 		cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION;
22148 		break;
22149 	case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY:
22150 		cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY;
22151 		break;
22152 	case OBSS_COLOR_FREE_SLOT_AVAILABLE:
22153 		cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE;
22154 		break;
22155 	default:
22156 		WMI_LOGE("%s: invalid event type: %d",
22157 			 __func__, cfg_param->evt_type);
22158 		wmi_buf_free(buf);
22159 		return QDF_STATUS_E_FAILURE;
22160 	}
22161 
22162 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
22163 				 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) {
22164 		WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d",
22165 			 __func__, cfg_param->vdev_id);
22166 		wmi_buf_free(buf);
22167 		return QDF_STATUS_E_FAILURE;
22168 	}
22169 
22170 	return QDF_STATUS_SUCCESS;
22171 }
22172 
22173 /**
22174  * extract_obss_color_collision_info_tlv() - Extract bss color collision info
22175  *   received from firmware.
22176  * @evt_buf: pointer to event buffer
22177  * @info: Pointer to hold bss collision  info
22178  *
22179  * Return: QDF_STATUS
22180  */
22181 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf,
22182 		struct wmi_obss_color_collision_info *info)
22183 {
22184 	WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf;
22185 	wmi_obss_color_collision_evt_fixed_param *fix_param;
22186 
22187 	if (!info) {
22188 		WMI_LOGE("%s: Invalid obss color buffer", __func__);
22189 		return QDF_STATUS_E_INVAL;
22190 	}
22191 
22192 	param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *)
22193 		    evt_buf;
22194 	if (!param_buf) {
22195 		WMI_LOGE("%s: Invalid evt_buf", __func__);
22196 		return QDF_STATUS_E_INVAL;
22197 	}
22198 
22199 	fix_param = param_buf->fixed_param;
22200 	info->vdev_id = fix_param->vdev_id;
22201 	info->obss_color_bitmap_bit0to31 = fix_param->bss_color_bitmap_bit0to31;
22202 	info->obss_color_bitmap_bit32to63 =
22203 		fix_param->bss_color_bitmap_bit32to63;
22204 
22205 	switch (fix_param->evt_type) {
22206 	case WMI_BSS_COLOR_COLLISION_DISABLE:
22207 		info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE;
22208 		break;
22209 	case WMI_BSS_COLOR_COLLISION_DETECTION:
22210 		info->evt_type = OBSS_COLOR_COLLISION_DETECTION;
22211 		break;
22212 	case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY:
22213 		info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY;
22214 		break;
22215 	case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE:
22216 		info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE;
22217 		break;
22218 	default:
22219 		WMI_LOGE("%s: invalid event type: %d, vdev_id: %d",
22220 			 __func__, fix_param->evt_type, fix_param->vdev_id);
22221 		return QDF_STATUS_E_FAILURE;
22222 	}
22223 
22224 	return QDF_STATUS_SUCCESS;
22225 }
22226 
22227 /*
22228  * extract_comb_phyerr_tlv() - extract comb phy error from event
22229  * @wmi_handle: wmi handle
22230  * @evt_buf: pointer to event buffer
22231  * @datalen: data length of event buffer
22232  * @buf_offset: Pointer to hold value of current event buffer offset
22233  * post extraction
22234  * @phyerr: Pointer to hold phyerr
22235  *
22236  * Return: QDF_STATUS
22237  */
22238 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle,
22239 					  void *evt_buf,
22240 					  uint16_t datalen,
22241 					  uint16_t *buf_offset,
22242 					  wmi_host_phyerr_t *phyerr)
22243 {
22244 	WMI_PHYERR_EVENTID_param_tlvs *param_tlvs;
22245 	wmi_comb_phyerr_rx_hdr *pe_hdr;
22246 
22247 	param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf;
22248 	if (!param_tlvs) {
22249 		WMI_LOGD("%s: Received null data from FW", __func__);
22250 		return QDF_STATUS_E_FAILURE;
22251 	}
22252 
22253 	pe_hdr = param_tlvs->hdr;
22254 	if (!pe_hdr) {
22255 		WMI_LOGD("%s: Received Data PE Header is NULL", __func__);
22256 		return QDF_STATUS_E_FAILURE;
22257 	}
22258 
22259 	/* Ensure it's at least the size of the header */
22260 	if (datalen < sizeof(*pe_hdr)) {
22261 		WMI_LOGD("%s: Expected minimum size %zu, received %d",
22262 			 __func__, sizeof(*pe_hdr), datalen);
22263 		return QDF_STATUS_E_FAILURE;
22264 	}
22265 
22266 	phyerr->pdev_id = wmi_handle->ops->
22267 		convert_pdev_id_target_to_host(pe_hdr->pdev_id);
22268 	phyerr->tsf64 = pe_hdr->tsf_l32;
22269 	phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32);
22270 	phyerr->bufp = param_tlvs->bufp;
22271 	phyerr->buf_len = pe_hdr->buf_len;
22272 	phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0;
22273 	phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1;
22274 	*buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t);
22275 
22276 	return QDF_STATUS_SUCCESS;
22277 }
22278 
22279 /**
22280  * extract_single_phyerr_tlv() - extract single phy error from event
22281  * @wmi_handle: wmi handle
22282  * @evt_buf: pointer to event buffer
22283  * @datalen: data length of event buffer
22284  * @buf_offset: Pointer to hold value of current event buffer offset
22285  * post extraction
22286  * @phyerr: Pointer to hold phyerr
22287  *
22288  * Return: QDF_STATUS
22289  */
22290 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle,
22291 					    void *evt_buf,
22292 					    uint16_t datalen,
22293 					    uint16_t *buf_offset,
22294 					    wmi_host_phyerr_t *phyerr)
22295 {
22296 	wmi_single_phyerr_rx_event *ev;
22297 	uint16_t n = *buf_offset;
22298 	uint8_t *data = (uint8_t *)evt_buf;
22299 
22300 	if (n < datalen) {
22301 		if ((datalen - n) < sizeof(ev->hdr)) {
22302 			WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu",
22303 				 __func__, datalen, n, sizeof(ev->hdr));
22304 			return QDF_STATUS_E_FAILURE;
22305 		}
22306 
22307 		/*
22308 		 * Obtain a pointer to the beginning of the current event.
22309 		 * data[0] is the beginning of the WMI payload.
22310 		 */
22311 		ev = (wmi_single_phyerr_rx_event *)&data[n];
22312 
22313 		/*
22314 		 * Sanity check the buffer length of the event against
22315 		 * what we currently have.
22316 		 *
22317 		 * Since buf_len is 32 bits, we check if it overflows
22318 		 * a large 32 bit value.  It's not 0x7fffffff because
22319 		 * we increase n by (buf_len + sizeof(hdr)), which would
22320 		 * in itself cause n to overflow.
22321 		 *
22322 		 * If "int" is 64 bits then this becomes a moot point.
22323 		 */
22324 		if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) {
22325 			WMI_LOGD("%s: buf_len is garbage 0x%x",
22326 				 __func__, ev->hdr.buf_len);
22327 			return QDF_STATUS_E_FAILURE;
22328 		}
22329 
22330 		if ((n + ev->hdr.buf_len) > datalen) {
22331 			WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d",
22332 				 __func__, n, ev->hdr.buf_len, datalen);
22333 			return QDF_STATUS_E_FAILURE;
22334 		}
22335 
22336 		phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr);
22337 		phyerr->tsf_timestamp = ev->hdr.tsf_timestamp;
22338 		phyerr->bufp = &ev->bufp[0];
22339 		phyerr->buf_len = ev->hdr.buf_len;
22340 		phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr);
22341 
22342 		/*
22343 		 * Advance the buffer pointer to the next PHY error.
22344 		 * buflen is the length of this payload, so we need to
22345 		 * advance past the current header _AND_ the payload.
22346 		 */
22347 		n += sizeof(*ev) + ev->hdr.buf_len;
22348 	}
22349 	*buf_offset = n;
22350 
22351 	return QDF_STATUS_SUCCESS;
22352 }
22353 
22354 struct wmi_ops tlv_ops =  {
22355 	.send_vdev_create_cmd = send_vdev_create_cmd_tlv,
22356 	.send_vdev_delete_cmd = send_vdev_delete_cmd_tlv,
22357 	.send_vdev_down_cmd = send_vdev_down_cmd_tlv,
22358 	.send_vdev_start_cmd = send_vdev_start_cmd_tlv,
22359 	.send_hidden_ssid_vdev_restart_cmd =
22360 		send_hidden_ssid_vdev_restart_cmd_tlv,
22361 	.send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv,
22362 	.send_peer_param_cmd = send_peer_param_cmd_tlv,
22363 	.send_vdev_up_cmd = send_vdev_up_cmd_tlv,
22364 	.send_vdev_stop_cmd = send_vdev_stop_cmd_tlv,
22365 	.send_peer_create_cmd = send_peer_create_cmd_tlv,
22366 	.send_peer_delete_cmd = send_peer_delete_cmd_tlv,
22367 	.send_peer_rx_reorder_queue_setup_cmd =
22368 		send_peer_rx_reorder_queue_setup_cmd_tlv,
22369 	.send_peer_rx_reorder_queue_remove_cmd =
22370 		send_peer_rx_reorder_queue_remove_cmd_tlv,
22371 	.send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv,
22372 	.send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv,
22373 	.send_peer_update_wds_entry_cmd = send_peer_update_wds_entry_cmd_tlv,
22374 	.send_pdev_utf_cmd = send_pdev_utf_cmd_tlv,
22375 	.send_pdev_param_cmd = send_pdev_param_cmd_tlv,
22376 	.send_pdev_get_tpc_config_cmd = send_pdev_get_tpc_config_cmd_tlv,
22377 	.send_suspend_cmd = send_suspend_cmd_tlv,
22378 	.send_resume_cmd = send_resume_cmd_tlv,
22379 #ifdef FEATURE_WLAN_D0WOW
22380 	.send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv,
22381 	.send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv,
22382 #endif
22383 	.send_wow_enable_cmd = send_wow_enable_cmd_tlv,
22384 	.send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv,
22385 	.send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv,
22386 	.send_crash_inject_cmd = send_crash_inject_cmd_tlv,
22387 	.send_dbglog_cmd = send_dbglog_cmd_tlv,
22388 	.send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv,
22389 	.send_stats_request_cmd = send_stats_request_cmd_tlv,
22390 	.send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv,
22391 	.send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv,
22392 	.send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv,
22393 	.send_beacon_send_cmd = send_beacon_send_cmd_tlv,
22394 	.send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv,
22395 	.send_peer_assoc_cmd = send_peer_assoc_cmd_tlv,
22396 	.send_scan_start_cmd = send_scan_start_cmd_tlv,
22397 	.send_scan_stop_cmd = send_scan_stop_cmd_tlv,
22398 	.send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv,
22399 	.send_mgmt_cmd = send_mgmt_cmd_tlv,
22400 	.send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv,
22401 	.send_modem_power_state_cmd = send_modem_power_state_cmd_tlv,
22402 	.send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv,
22403 	.send_set_sta_uapsd_auto_trig_cmd =
22404 		send_set_sta_uapsd_auto_trig_cmd_tlv,
22405 	.send_get_temperature_cmd = send_get_temperature_cmd_tlv,
22406 	.send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv,
22407 	.send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv,
22408 #ifdef CONVERGED_P2P_ENABLE
22409 	.send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv,
22410 	.send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv,
22411 #endif
22412 	.send_set_smps_params_cmd = send_set_smps_params_cmd_tlv,
22413 	.send_set_mimops_cmd = send_set_mimops_cmd_tlv,
22414 #ifdef WLAN_FEATURE_DSRC
22415 	.send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv,
22416 	.send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv,
22417 	.send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv,
22418 	.send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv,
22419 	.send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv,
22420 	.send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv,
22421 	.send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv,
22422 	.send_ocb_start_timing_advert_cmd =
22423 		send_ocb_start_timing_advert_cmd_tlv,
22424 	.extract_ocb_chan_config_resp = extract_ocb_channel_config_resp_tlv,
22425 	.extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv,
22426 	.extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv,
22427 	.extract_dcc_stats = extract_ocb_dcc_stats_tlv,
22428 #endif
22429 	.send_set_enable_disable_mcc_adaptive_scheduler_cmd =
22430 		 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv,
22431 	.send_set_mcc_channel_time_latency_cmd =
22432 			 send_set_mcc_channel_time_latency_cmd_tlv,
22433 	.send_set_mcc_channel_time_quota_cmd =
22434 			 send_set_mcc_channel_time_quota_cmd_tlv,
22435 	.send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv,
22436 	.send_lro_config_cmd = send_lro_config_cmd_tlv,
22437 	.send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv,
22438 	.send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv,
22439 	.send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv,
22440 	.send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv,
22441 	.send_probe_rsp_tmpl_send_cmd =
22442 				send_probe_rsp_tmpl_send_cmd_tlv,
22443 	.send_p2p_go_set_beacon_ie_cmd =
22444 				send_p2p_go_set_beacon_ie_cmd_tlv,
22445 	.send_setup_install_key_cmd =
22446 				send_setup_install_key_cmd_tlv,
22447 	.send_set_gateway_params_cmd =
22448 				send_set_gateway_params_cmd_tlv,
22449 	.send_set_rssi_monitoring_cmd =
22450 			 send_set_rssi_monitoring_cmd_tlv,
22451 	.send_scan_probe_setoui_cmd =
22452 				send_scan_probe_setoui_cmd_tlv,
22453 	.send_reset_passpoint_network_list_cmd =
22454 				send_reset_passpoint_network_list_cmd_tlv,
22455 	.send_set_passpoint_network_list_cmd =
22456 			 send_set_passpoint_network_list_cmd_tlv,
22457 	.send_roam_scan_offload_rssi_thresh_cmd =
22458 			send_roam_scan_offload_rssi_thresh_cmd_tlv,
22459 	.send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv,
22460 	.send_roam_scan_filter_cmd =
22461 			send_roam_scan_filter_cmd_tlv,
22462 	.send_set_epno_network_list_cmd =
22463 			 send_set_epno_network_list_cmd_tlv,
22464 	.send_ipa_offload_control_cmd =
22465 			 send_ipa_offload_control_cmd_tlv,
22466 	.send_extscan_get_capabilities_cmd =
22467 			 send_extscan_get_capabilities_cmd_tlv,
22468 	.send_extscan_get_cached_results_cmd =
22469 		 send_extscan_get_cached_results_cmd_tlv,
22470 	.send_extscan_stop_change_monitor_cmd =
22471 		  send_extscan_stop_change_monitor_cmd_tlv,
22472 	.send_extscan_start_change_monitor_cmd =
22473 		  send_extscan_start_change_monitor_cmd_tlv,
22474 	.send_extscan_stop_hotlist_monitor_cmd =
22475 		  send_extscan_stop_hotlist_monitor_cmd_tlv,
22476 	.send_stop_extscan_cmd = send_stop_extscan_cmd_tlv,
22477 	.send_start_extscan_cmd = send_start_extscan_cmd_tlv,
22478 	.send_plm_stop_cmd = send_plm_stop_cmd_tlv,
22479 	.send_plm_start_cmd = send_plm_start_cmd_tlv,
22480 	.send_pno_stop_cmd = send_pno_stop_cmd_tlv,
22481 	.send_pno_start_cmd = send_pno_start_cmd_tlv,
22482 	.send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv,
22483 	.send_set_ric_req_cmd = send_set_ric_req_cmd_tlv,
22484 	.send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv,
22485 	.send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv,
22486 	.send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv,
22487 	.send_congestion_cmd = send_congestion_cmd_tlv,
22488 	.send_snr_request_cmd = send_snr_request_cmd_tlv,
22489 	.send_snr_cmd = send_snr_cmd_tlv,
22490 	.send_link_status_req_cmd = send_link_status_req_cmd_tlv,
22491 #ifdef WLAN_PMO_ENABLE
22492 	.send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv,
22493 	.send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv,
22494 	.send_enable_arp_ns_offload_cmd = send_enable_arp_ns_offload_cmd_tlv,
22495 	.send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv,
22496 	.send_multiple_add_clear_mcbc_filter_cmd =
22497 		send_multiple_add_clear_mcbc_filter_cmd_tlv,
22498 	.send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv,
22499 	.send_gtk_offload_cmd = send_gtk_offload_cmd_tlv,
22500 	.send_process_gtk_offload_getinfo_cmd =
22501 		send_process_gtk_offload_getinfo_cmd_tlv,
22502 	.send_enable_enhance_multicast_offload_cmd =
22503 		send_enable_enhance_multicast_offload_tlv,
22504 	.extract_gtk_rsp_event = extract_gtk_rsp_event_tlv,
22505 #ifdef FEATURE_WLAN_RA_FILTERING
22506 	.send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv,
22507 #endif
22508 	.send_action_frame_patterns_cmd = send_action_frame_patterns_cmd_tlv,
22509 	.send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv,
22510 	.send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv,
22511 	.send_lphb_config_tcp_pkt_filter_cmd =
22512 		send_lphb_config_tcp_pkt_filter_cmd_tlv,
22513 	.send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv,
22514 	.send_lphb_config_udp_pkt_filter_cmd =
22515 		send_lphb_config_udp_pkt_filter_cmd_tlv,
22516 	.send_enable_disable_packet_filter_cmd =
22517 		send_enable_disable_packet_filter_cmd_tlv,
22518 	.send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv,
22519 #endif /* End of WLAN_PMO_ENABLE */
22520 #ifdef CONFIG_MCL
22521 	.send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv,
22522 	.send_get_link_speed_cmd = send_get_link_speed_cmd_tlv,
22523 	.send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv,
22524 	.send_roam_scan_offload_mode_cmd =
22525 			send_roam_scan_offload_mode_cmd_tlv,
22526 	.send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv,
22527 	.send_roam_scan_offload_ap_profile_cmd =
22528 			send_roam_scan_offload_ap_profile_cmd_tlv,
22529 #endif
22530 #ifdef WLAN_SUPPORT_GREEN_AP
22531 	.send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv,
22532 	.send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv,
22533 	.extract_green_ap_egap_status_info =
22534 			extract_green_ap_egap_status_info_tlv,
22535 #endif
22536 	.send_fw_profiling_cmd = send_fw_profiling_cmd_tlv,
22537 	.send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv,
22538 	.send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv,
22539 	.send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv,
22540 	.send_start_oem_data_cmd = send_start_oem_data_cmd_tlv,
22541 #ifdef WLAN_FEATURE_CIF_CFR
22542 	.send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv,
22543 #endif
22544 	.send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv,
22545 	.send_dfs_phyerr_filter_offload_en_cmd =
22546 		 send_dfs_phyerr_filter_offload_en_cmd_tlv,
22547 	.send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv,
22548 	.send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv,
22549 	.send_del_ts_cmd = send_del_ts_cmd_tlv,
22550 	.send_aggr_qos_cmd = send_aggr_qos_cmd_tlv,
22551 	.send_add_ts_cmd = send_add_ts_cmd_tlv,
22552 	.send_process_add_periodic_tx_ptrn_cmd =
22553 		send_process_add_periodic_tx_ptrn_cmd_tlv,
22554 	.send_process_del_periodic_tx_ptrn_cmd =
22555 		send_process_del_periodic_tx_ptrn_cmd_tlv,
22556 	.send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv,
22557 	.send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv,
22558 	.send_set_app_type2_params_in_fw_cmd =
22559 		send_set_app_type2_params_in_fw_cmd_tlv,
22560 	.send_set_auto_shutdown_timer_cmd =
22561 		send_set_auto_shutdown_timer_cmd_tlv,
22562 	.send_nan_req_cmd = send_nan_req_cmd_tlv,
22563 	.send_process_dhcpserver_offload_cmd =
22564 		send_process_dhcpserver_offload_cmd_tlv,
22565 	.send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv,
22566 	.send_process_ch_avoid_update_cmd =
22567 		send_process_ch_avoid_update_cmd_tlv,
22568 	.send_pdev_set_regdomain_cmd =
22569 				send_pdev_set_regdomain_cmd_tlv,
22570 	.send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv,
22571 	.send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv,
22572 	.send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv,
22573 	.send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv,
22574 	.send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv,
22575 	.save_fw_version_cmd = save_fw_version_cmd_tlv,
22576 	.check_and_update_fw_version =
22577 		 check_and_update_fw_version_cmd_tlv,
22578 	.send_set_base_macaddr_indicate_cmd =
22579 		 send_set_base_macaddr_indicate_cmd_tlv,
22580 	.send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv,
22581 	.send_enable_specific_fw_logs_cmd =
22582 		 send_enable_specific_fw_logs_cmd_tlv,
22583 	.send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv,
22584 	.send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv,
22585 	.send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv,
22586 	.send_pdev_set_dual_mac_config_cmd =
22587 		 send_pdev_set_dual_mac_config_cmd_tlv,
22588 	.send_app_type1_params_in_fw_cmd =
22589 		 send_app_type1_params_in_fw_cmd_tlv,
22590 	.send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv,
22591 	.send_process_roam_synch_complete_cmd =
22592 		 send_process_roam_synch_complete_cmd_tlv,
22593 	.send_unit_test_cmd = send_unit_test_cmd_tlv,
22594 	.send_roam_invoke_cmd = send_roam_invoke_cmd_tlv,
22595 	.send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv,
22596 	.send_roam_scan_offload_scan_period_cmd =
22597 		 send_roam_scan_offload_scan_period_cmd_tlv,
22598 	.send_roam_scan_offload_chan_list_cmd =
22599 		 send_roam_scan_offload_chan_list_cmd_tlv,
22600 	.send_roam_scan_offload_rssi_change_cmd =
22601 		 send_roam_scan_offload_rssi_change_cmd_tlv,
22602 	.send_get_buf_extscan_hotlist_cmd =
22603 		 send_get_buf_extscan_hotlist_cmd_tlv,
22604 	.send_set_active_bpf_mode_cmd = send_set_active_bpf_mode_cmd_tlv,
22605 	.send_adapt_dwelltime_params_cmd =
22606 		send_adapt_dwelltime_params_cmd_tlv,
22607 	.send_dbs_scan_sel_params_cmd =
22608 		send_dbs_scan_sel_params_cmd_tlv,
22609 	.init_cmd_send = init_cmd_send_tlv,
22610 	.send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv,
22611 	.send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv,
22612 	.send_set_ctl_table_cmd = send_set_ctl_table_cmd_tlv,
22613 	.send_set_mimogain_table_cmd = send_set_mimogain_table_cmd_tlv,
22614 	.send_packet_power_info_get_cmd = send_packet_power_info_get_cmd_tlv,
22615 	.send_vdev_config_ratemask_cmd = send_vdev_config_ratemask_cmd_tlv,
22616 	.send_vdev_set_custom_aggr_size_cmd =
22617 		send_vdev_set_custom_aggr_size_cmd_tlv,
22618 	.send_vdev_set_qdepth_thresh_cmd =
22619 		send_vdev_set_qdepth_thresh_cmd_tlv,
22620 	.send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv,
22621 	.send_vdev_set_neighbour_rx_cmd = send_vdev_set_neighbour_rx_cmd_tlv,
22622 	.send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_tlv,
22623 	.send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_tlv,
22624 	.send_smart_ant_set_training_info_cmd =
22625 		send_smart_ant_set_training_info_cmd_tlv,
22626 	.send_smart_ant_set_node_config_cmd =
22627 		send_smart_ant_set_node_config_cmd_tlv,
22628 	.send_set_atf_cmd = send_set_atf_cmd_tlv,
22629 	.send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv,
22630 	.send_set_qboost_param_cmd = send_set_qboost_param_cmd_tlv,
22631 	.send_gpio_config_cmd = send_gpio_config_cmd_tlv,
22632 	.send_gpio_output_cmd = send_gpio_output_cmd_tlv,
22633 	.send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv,
22634 	.send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv,
22635 	.send_periodic_chan_stats_config_cmd =
22636 		send_periodic_chan_stats_config_cmd_tlv,
22637 	.send_nf_dbr_dbm_info_get_cmd = send_nf_dbr_dbm_info_get_cmd_tlv,
22638 	.send_set_ht_ie_cmd = send_set_ht_ie_cmd_tlv,
22639 	.send_set_vht_ie_cmd = send_set_vht_ie_cmd_tlv,
22640 	.send_set_quiet_mode_cmd = send_set_quiet_mode_cmd_tlv,
22641 	.send_set_bwf_cmd = send_set_bwf_cmd_tlv,
22642 	.send_mcast_group_update_cmd = send_mcast_group_update_cmd_tlv,
22643 	.send_vdev_spectral_configure_cmd =
22644 				send_vdev_spectral_configure_cmd_tlv,
22645 	.send_vdev_spectral_enable_cmd =
22646 				send_vdev_spectral_enable_cmd_tlv,
22647 	.send_thermal_mitigation_param_cmd =
22648 		send_thermal_mitigation_param_cmd_tlv,
22649 	.send_pdev_qvit_cmd = send_pdev_qvit_cmd_tlv,
22650 	.send_wmm_update_cmd = send_wmm_update_cmd_tlv,
22651 	.send_process_update_edca_param_cmd =
22652 				 send_process_update_edca_param_cmd_tlv,
22653 	.send_coex_config_cmd = send_coex_config_cmd_tlv,
22654 	.send_set_country_cmd = send_set_country_cmd_tlv,
22655 	.send_bcn_offload_control_cmd = send_bcn_offload_control_cmd_tlv,
22656 	.send_addba_send_cmd = send_addba_send_cmd_tlv,
22657 	.send_delba_send_cmd = send_delba_send_cmd_tlv,
22658 	.send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv,
22659 	.get_target_cap_from_service_ready = extract_service_ready_tlv,
22660 	.extract_hal_reg_cap = extract_hal_reg_cap_tlv,
22661 	.extract_host_mem_req = extract_host_mem_req_tlv,
22662 	.save_service_bitmap = save_service_bitmap_tlv,
22663 	.save_ext_service_bitmap = save_ext_service_bitmap_tlv,
22664 	.is_service_enabled = is_service_enabled_tlv,
22665 	.save_fw_version = save_fw_version_in_service_ready_tlv,
22666 	.ready_extract_init_status = ready_extract_init_status_tlv,
22667 	.ready_extract_mac_addr = ready_extract_mac_addr_tlv,
22668 	.ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv,
22669 	.extract_ready_event_params = extract_ready_event_params_tlv,
22670 	.extract_dbglog_data_len = extract_dbglog_data_len_tlv,
22671 	.extract_vdev_start_resp = extract_vdev_start_resp_tlv,
22672 	.extract_vdev_delete_resp = extract_vdev_delete_resp_tlv,
22673 	.extract_tbttoffset_update_params =
22674 				extract_tbttoffset_update_params_tlv,
22675 	.extract_ext_tbttoffset_update_params =
22676 				extract_ext_tbttoffset_update_params_tlv,
22677 	.extract_tbttoffset_num_vdevs =
22678 				extract_tbttoffset_num_vdevs_tlv,
22679 	.extract_ext_tbttoffset_num_vdevs =
22680 				extract_ext_tbttoffset_num_vdevs_tlv,
22681 	.extract_mgmt_rx_params = extract_mgmt_rx_params_tlv,
22682 	.extract_vdev_stopped_param = extract_vdev_stopped_param_tlv,
22683 	.extract_vdev_roam_param = extract_vdev_roam_param_tlv,
22684 	.extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv,
22685 #ifdef CONVERGED_TDLS_ENABLE
22686 	.extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv,
22687 #endif
22688 	.extract_mgmt_tx_compl_param = extract_mgmt_tx_compl_param_tlv,
22689 	.extract_swba_num_vdevs = extract_swba_num_vdevs_tlv,
22690 	.extract_swba_tim_info = extract_swba_tim_info_tlv,
22691 	.extract_swba_noa_info = extract_swba_noa_info_tlv,
22692 #ifdef CONVERGED_P2P_ENABLE
22693 	.extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv,
22694 	.extract_p2p_lo_stop_ev_param =
22695 				extract_p2p_lo_stop_ev_param_tlv,
22696 #endif
22697 	.extract_offchan_data_tx_compl_param =
22698 				extract_offchan_data_tx_compl_param_tlv,
22699 	.extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv,
22700 	.extract_all_stats_count = extract_all_stats_counts_tlv,
22701 	.extract_pdev_stats = extract_pdev_stats_tlv,
22702 	.extract_unit_test = extract_unit_test_tlv,
22703 	.extract_pdev_ext_stats = extract_pdev_ext_stats_tlv,
22704 	.extract_vdev_stats = extract_vdev_stats_tlv,
22705 	.extract_peer_stats = extract_peer_stats_tlv,
22706 	.extract_bcn_stats = extract_bcn_stats_tlv,
22707 	.extract_bcnflt_stats = extract_bcnflt_stats_tlv,
22708 	.extract_peer_extd_stats = extract_peer_extd_stats_tlv,
22709 	.extract_chan_stats = extract_chan_stats_tlv,
22710 	.extract_profile_ctx = extract_profile_ctx_tlv,
22711 	.extract_profile_data = extract_profile_data_tlv,
22712 	.extract_chan_info_event = extract_chan_info_event_tlv,
22713 	.extract_channel_hopping_event = extract_channel_hopping_event_tlv,
22714 	.send_fw_test_cmd = send_fw_test_cmd_tlv,
22715 #ifdef WLAN_FEATURE_DISA
22716 	.send_encrypt_decrypt_send_cmd =
22717 				send_encrypt_decrypt_send_cmd_tlv,
22718 	.extract_encrypt_decrypt_resp_event =
22719 				extract_encrypt_decrypt_resp_event_tlv,
22720 #endif
22721 	.send_sar_limit_cmd = send_sar_limit_cmd_tlv,
22722 	.get_sar_limit_cmd = get_sar_limit_cmd_tlv,
22723 	.extract_sar_limit_event = extract_sar_limit_event_tlv,
22724 	.send_power_dbg_cmd = send_power_dbg_cmd_tlv,
22725 	.send_multiple_vdev_restart_req_cmd =
22726 				send_multiple_vdev_restart_req_cmd_tlv,
22727 	.extract_service_ready_ext = extract_service_ready_ext_tlv,
22728 	.extract_hw_mode_cap_service_ready_ext =
22729 				extract_hw_mode_cap_service_ready_ext_tlv,
22730 	.extract_mac_phy_cap_service_ready_ext =
22731 				extract_mac_phy_cap_service_ready_ext_tlv,
22732 	.extract_reg_cap_service_ready_ext =
22733 				extract_reg_cap_service_ready_ext_tlv,
22734 	.extract_dbr_ring_cap_service_ready_ext =
22735 				extract_dbr_ring_cap_service_ready_ext_tlv,
22736 	.extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv,
22737 	.extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv,
22738 	.extract_pdev_utf_event = extract_pdev_utf_event_tlv,
22739 	.wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv,
22740 	.extract_dcs_interference_type = extract_dcs_interference_type_tlv,
22741 	.extract_dcs_cw_int = extract_dcs_cw_int_tlv,
22742 	.extract_dcs_im_tgt_stats = extract_dcs_im_tgt_stats_tlv,
22743 	.extract_fips_event_data = extract_fips_event_data_tlv,
22744 	.send_pdev_fips_cmd = send_pdev_fips_cmd_tlv,
22745 	.extract_peer_delete_response_event =
22746 				extract_peer_delete_response_event_tlv,
22747 	.is_management_record = is_management_record_tlv,
22748 	.extract_pdev_csa_switch_count_status =
22749 				extract_pdev_csa_switch_count_status_tlv,
22750 	.extract_pdev_tpc_ev_param = extract_pdev_tpc_ev_param_tlv,
22751 	.extract_pdev_tpc_config_ev_param =
22752 			extract_pdev_tpc_config_ev_param_tlv,
22753 	.extract_nfcal_power_ev_param = extract_nfcal_power_ev_param_tlv,
22754 	.extract_wds_addr_event = extract_wds_addr_event_tlv,
22755 	.extract_peer_sta_ps_statechange_ev =
22756 		extract_peer_sta_ps_statechange_ev_tlv,
22757 	.extract_inst_rssi_stats_event = extract_inst_rssi_stats_event_tlv,
22758 	.send_per_roam_config_cmd = send_per_roam_config_cmd_tlv,
22759 	.send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv,
22760 	.send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv,
22761 	.extract_reg_chan_list_update_event =
22762 		extract_reg_chan_list_update_event_tlv,
22763 	.extract_chainmask_tables =
22764 		extract_chainmask_tables_tlv,
22765 	.extract_thermal_stats = extract_thermal_stats_tlv,
22766 	.extract_thermal_level_stats = extract_thermal_level_stats_tlv,
22767 	.send_get_rcpi_cmd = send_get_rcpi_cmd_tlv,
22768 	.extract_rcpi_response_event = extract_rcpi_response_event_tlv,
22769 #ifdef DFS_COMPONENT_ENABLE
22770 	.extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv,
22771 	.extract_dfs_radar_detection_event =
22772 		extract_dfs_radar_detection_event_tlv,
22773 	.extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv,
22774 #endif
22775 	.convert_pdev_id_host_to_target =
22776 		convert_host_pdev_id_to_target_pdev_id_legacy,
22777 	.convert_pdev_id_target_to_host =
22778 		convert_target_pdev_id_to_host_pdev_id_legacy,
22779 
22780 	.send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv,
22781 	.send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv,
22782 	.extract_reg_11d_new_country_event =
22783 		extract_reg_11d_new_country_event_tlv,
22784 	.send_user_country_code_cmd = send_user_country_code_cmd_tlv,
22785 	.send_limit_off_chan_cmd =
22786 		send_limit_off_chan_cmd_tlv,
22787 	.extract_reg_ch_avoid_event =
22788 		extract_reg_ch_avoid_event_tlv,
22789 	.send_pdev_caldata_version_check_cmd =
22790 			send_pdev_caldata_version_check_cmd_tlv,
22791 	.extract_pdev_caldata_version_check_ev_param =
22792 			extract_pdev_caldata_version_check_ev_param_tlv,
22793 	.send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv,
22794 	.send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv,
22795 	.send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv,
22796 #if defined(WLAN_FEATURE_FILS_SK)
22797 	.send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv,
22798 #endif
22799 	.send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv,
22800 #ifdef WLAN_FEATURE_NAN_CONVERGENCE
22801 	.send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv,
22802 	.send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv,
22803 	.send_ndp_end_req_cmd = nan_ndp_end_req_tlv,
22804 	.extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv,
22805 	.extract_ndp_ind = extract_ndp_ind_tlv,
22806 	.extract_ndp_confirm = extract_ndp_confirm_tlv,
22807 	.extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv,
22808 	.extract_ndp_end_rsp = extract_ndp_end_rsp_tlv,
22809 	.extract_ndp_end_ind = extract_ndp_end_ind_tlv,
22810 #endif
22811 	.send_btm_config = send_btm_config_cmd_tlv,
22812 	.send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv,
22813 	.extract_obss_detection_info = extract_obss_detection_info_tlv,
22814 #ifdef WLAN_SUPPORT_FILS
22815 	.send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_tlv,
22816 	.extract_swfda_vdev_id = extract_swfda_vdev_id_tlv,
22817 	.send_fils_discovery_send_cmd = send_fils_discovery_send_cmd_tlv,
22818 #endif /* WLAN_SUPPORT_FILS */
22819 	.send_offload_11k_cmd = send_offload_11k_cmd_tlv,
22820 	.send_invoke_neighbor_report_cmd = send_invoke_neighbor_report_cmd_tlv,
22821 	.wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable,
22822 	.wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs,
22823 	.wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs,
22824 	.wmi_check_command_params = wmitlv_check_command_tlv_params,
22825 	.send_bss_color_change_enable_cmd =
22826 		send_bss_color_change_enable_cmd_tlv,
22827 	.send_obss_color_collision_cfg_cmd =
22828 		send_obss_color_collision_cfg_cmd_tlv,
22829 	.extract_obss_color_collision_info =
22830 		extract_obss_color_collision_info_tlv,
22831 	.extract_comb_phyerr = extract_comb_phyerr_tlv,
22832 	.extract_single_phyerr = extract_single_phyerr_tlv,
22833 };
22834 
22835 /**
22836  * populate_tlv_event_id() - populates wmi event ids
22837  *
22838  * @param event_ids: Pointer to hold event ids
22839  * Return: None
22840  */
22841 static void populate_tlv_events_id(uint32_t *event_ids)
22842 {
22843 	event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID;
22844 	event_ids[wmi_ready_event_id] = WMI_READY_EVENTID;
22845 	event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID;
22846 	event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID;
22847 	event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID;
22848 	event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID;
22849 	event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID;
22850 	event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID;
22851 	event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID;
22852 	event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID;
22853 	event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID;
22854 	event_ids[wmi_service_ready_ext_event_id] =
22855 						WMI_SERVICE_READY_EXT_EVENTID;
22856 	event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID;
22857 	event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID;
22858 	event_ids[wmi_vdev_install_key_complete_event_id] =
22859 				WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID;
22860 	event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] =
22861 				WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID;
22862 
22863 	event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID;
22864 	event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID;
22865 	event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID;
22866 	event_ids[wmi_peer_tx_fail_cnt_thr_event_id] =
22867 				WMI_PEER_TX_FAIL_CNT_THR_EVENTID;
22868 	event_ids[wmi_peer_estimated_linkspeed_event_id] =
22869 				WMI_PEER_ESTIMATED_LINKSPEED_EVENTID;
22870 	event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID;
22871 	event_ids[wmi_peer_delete_response_event_id] =
22872 					WMI_PEER_DELETE_RESP_EVENTID;
22873 	event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID;
22874 	event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID;
22875 	event_ids[wmi_tbttoffset_update_event_id] =
22876 					WMI_TBTTOFFSET_UPDATE_EVENTID;
22877 	event_ids[wmi_ext_tbttoffset_update_event_id] =
22878 					WMI_TBTTOFFSET_EXT_UPDATE_EVENTID;
22879 	event_ids[wmi_offload_bcn_tx_status_event_id] =
22880 				WMI_OFFLOAD_BCN_TX_STATUS_EVENTID;
22881 	event_ids[wmi_offload_prob_resp_tx_status_event_id] =
22882 				WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID;
22883 	event_ids[wmi_mgmt_tx_completion_event_id] =
22884 				WMI_MGMT_TX_COMPLETION_EVENTID;
22885 	event_ids[wmi_pdev_nfcal_power_all_channels_event_id] =
22886 				WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID;
22887 	event_ids[wmi_tx_delba_complete_event_id] =
22888 					WMI_TX_DELBA_COMPLETE_EVENTID;
22889 	event_ids[wmi_tx_addba_complete_event_id] =
22890 					WMI_TX_ADDBA_COMPLETE_EVENTID;
22891 	event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID;
22892 
22893 	event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID;
22894 
22895 	event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID;
22896 	event_ids[wmi_profile_match] = WMI_PROFILE_MATCH;
22897 
22898 	event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID;
22899 	event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID;
22900 
22901 	event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID;
22902 
22903 	event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID;
22904 	event_ids[wmi_p2p_lo_stop_event_id] =
22905 				WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID;
22906 	event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID;
22907 	event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID;
22908 	event_ids[wmi_d0_wow_disable_ack_event_id] =
22909 				WMI_D0_WOW_DISABLE_ACK_EVENTID;
22910 	event_ids[wmi_wow_initial_wakeup_event_id] =
22911 				WMI_WOW_INITIAL_WAKEUP_EVENTID;
22912 
22913 	event_ids[wmi_rtt_meas_report_event_id] =
22914 				WMI_RTT_MEASUREMENT_REPORT_EVENTID;
22915 	event_ids[wmi_tsf_meas_report_event_id] =
22916 				WMI_TSF_MEASUREMENT_REPORT_EVENTID;
22917 	event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID;
22918 	event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID;
22919 	event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID;
22920 	event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID;
22921 	event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID;
22922 	event_ids[wmi_diag_event_id_log_supported_event_id] =
22923 				WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID;
22924 	event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID;
22925 	event_ids[wmi_nlo_scan_complete_event_id] =
22926 					WMI_NLO_SCAN_COMPLETE_EVENTID;
22927 	event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID;
22928 	event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID;
22929 
22930 	event_ids[wmi_gtk_offload_status_event_id] =
22931 				WMI_GTK_OFFLOAD_STATUS_EVENTID;
22932 	event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID;
22933 	event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID;
22934 	event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID;
22935 
22936 	event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID;
22937 
22938 	event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID;
22939 
22940 	event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID;
22941 	event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID;
22942 	event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID;
22943 	event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID;
22944 	event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID;
22945 	event_ids[wmi_wlan_profile_data_event_id] =
22946 						WMI_WLAN_PROFILE_DATA_EVENTID;
22947 	event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID;
22948 	event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID;
22949 	event_ids[wmi_vdev_get_keepalive_event_id] =
22950 				WMI_VDEV_GET_KEEPALIVE_EVENTID;
22951 	event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID;
22952 
22953 	event_ids[wmi_diag_container_event_id] =
22954 						WMI_DIAG_DATA_CONTAINER_EVENTID;
22955 
22956 	event_ids[wmi_host_auto_shutdown_event_id] =
22957 				WMI_HOST_AUTO_SHUTDOWN_EVENTID;
22958 
22959 	event_ids[wmi_update_whal_mib_stats_event_id] =
22960 				WMI_UPDATE_WHAL_MIB_STATS_EVENTID;
22961 
22962 	/*update ht/vht info based on vdev (rx and tx NSS and preamble) */
22963 	event_ids[wmi_update_vdev_rate_stats_event_id] =
22964 				WMI_UPDATE_VDEV_RATE_STATS_EVENTID;
22965 
22966 	event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID;
22967 	event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID;
22968 
22969 	/** Set OCB Sched Response, deprecated */
22970 	event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID;
22971 
22972 	event_ids[wmi_dbg_mesg_flush_complete_event_id] =
22973 				WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID;
22974 	event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID;
22975 
22976 	/* GPIO Event */
22977 	event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID;
22978 	event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID;
22979 
22980 	event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID;
22981 	event_ids[wmi_rfkill_state_change_event_id] =
22982 				WMI_RFKILL_STATE_CHANGE_EVENTID;
22983 
22984 	/* TDLS Event */
22985 	event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID;
22986 
22987 	event_ids[wmi_batch_scan_enabled_event_id] =
22988 				WMI_BATCH_SCAN_ENABLED_EVENTID;
22989 	event_ids[wmi_batch_scan_result_event_id] =
22990 				WMI_BATCH_SCAN_RESULT_EVENTID;
22991 	/* OEM Event */
22992 	event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID;
22993 	event_ids[wmi_oem_meas_report_event_id] =
22994 				WMI_OEM_MEASUREMENT_REPORT_EVENTID;
22995 	event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID;
22996 
22997 	/* NAN Event */
22998 	event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID;
22999 
23000 	/* LPI Event */
23001 	event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID;
23002 	event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID;
23003 	event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID;
23004 
23005 	/* ExtScan events */
23006 	event_ids[wmi_extscan_start_stop_event_id] =
23007 				WMI_EXTSCAN_START_STOP_EVENTID;
23008 	event_ids[wmi_extscan_operation_event_id] =
23009 				WMI_EXTSCAN_OPERATION_EVENTID;
23010 	event_ids[wmi_extscan_table_usage_event_id] =
23011 				WMI_EXTSCAN_TABLE_USAGE_EVENTID;
23012 	event_ids[wmi_extscan_cached_results_event_id] =
23013 				WMI_EXTSCAN_CACHED_RESULTS_EVENTID;
23014 	event_ids[wmi_extscan_wlan_change_results_event_id] =
23015 				WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID;
23016 	event_ids[wmi_extscan_hotlist_match_event_id] =
23017 				WMI_EXTSCAN_HOTLIST_MATCH_EVENTID;
23018 	event_ids[wmi_extscan_capabilities_event_id] =
23019 				WMI_EXTSCAN_CAPABILITIES_EVENTID;
23020 	event_ids[wmi_extscan_hotlist_ssid_match_event_id] =
23021 				WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID;
23022 
23023 	/* mDNS offload events */
23024 	event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID;
23025 
23026 	/* SAP Authentication offload events */
23027 	event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID;
23028 	event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID;
23029 
23030 	/** Out-of-context-of-bss (OCB) events */
23031 	event_ids[wmi_ocb_set_config_resp_event_id] =
23032 				WMI_OCB_SET_CONFIG_RESP_EVENTID;
23033 	event_ids[wmi_ocb_get_tsf_timer_resp_event_id] =
23034 				WMI_OCB_GET_TSF_TIMER_RESP_EVENTID;
23035 	event_ids[wmi_dcc_get_stats_resp_event_id] =
23036 				WMI_DCC_GET_STATS_RESP_EVENTID;
23037 	event_ids[wmi_dcc_update_ndl_resp_event_id] =
23038 				WMI_DCC_UPDATE_NDL_RESP_EVENTID;
23039 	event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID;
23040 	/* System-On-Chip events */
23041 	event_ids[wmi_soc_set_hw_mode_resp_event_id] =
23042 				WMI_SOC_SET_HW_MODE_RESP_EVENTID;
23043 	event_ids[wmi_soc_hw_mode_transition_event_id] =
23044 				WMI_SOC_HW_MODE_TRANSITION_EVENTID;
23045 	event_ids[wmi_soc_set_dual_mac_config_resp_event_id] =
23046 				WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID;
23047 	event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID;
23048 	event_ids[wmi_pdev_csa_switch_count_status_event_id] =
23049 				WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID;
23050 	event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID;
23051 	event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID;
23052 	event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID;
23053 	event_ids[wmi_peer_sta_ps_statechg_event_id] =
23054 					WMI_PEER_STA_PS_STATECHG_EVENTID;
23055 	event_ids[wmi_pdev_channel_hopping_event_id] =
23056 					WMI_PDEV_CHANNEL_HOPPING_EVENTID;
23057 	event_ids[wmi_offchan_data_tx_completion_event] =
23058 				WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID;
23059 	event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID;
23060 	event_ids[wmi_dfs_radar_detection_event_id] =
23061 		WMI_PDEV_DFS_RADAR_DETECTION_EVENTID;
23062 	event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID;
23063 	event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID;
23064 	event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID;
23065 	event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID;
23066 	event_ids[wmi_service_available_event_id] =
23067 						WMI_SERVICE_AVAILABLE_EVENTID;
23068 	event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID;
23069 	event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID;
23070 	/* NDP events */
23071 	event_ids[wmi_ndp_initiator_rsp_event_id] =
23072 		WMI_NDP_INITIATOR_RSP_EVENTID;
23073 	event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID;
23074 	event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID;
23075 	event_ids[wmi_ndp_responder_rsp_event_id] =
23076 		WMI_NDP_RESPONDER_RSP_EVENTID;
23077 	event_ids[wmi_ndp_end_indication_event_id] =
23078 		WMI_NDP_END_INDICATION_EVENTID;
23079 	event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID;
23080 
23081 	event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID;
23082 	event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID;
23083 	event_ids[wmi_pdev_chip_power_stats_event_id] =
23084 		WMI_PDEV_CHIP_POWER_STATS_EVENTID;
23085 	event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID;
23086 	event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID;
23087 	event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID;
23088 	event_ids[wmi_bpf_capability_info_event_id] =
23089 		WMI_BPF_CAPABILIY_INFO_EVENTID;
23090 	event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] =
23091 		WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID;
23092 	event_ids[wmi_report_rx_aggr_failure_event_id] =
23093 		WMI_REPORT_RX_AGGR_FAILURE_EVENTID;
23094 	event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] =
23095 		WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID;
23096 	event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID;
23097 	event_ids[wmi_pdev_set_hw_mode_rsp_event_id] =
23098 		WMI_PDEV_SET_HW_MODE_RESP_EVENTID;
23099 	event_ids[wmi_pdev_hw_mode_transition_event_id] =
23100 		WMI_PDEV_HW_MODE_TRANSITION_EVENTID;
23101 	event_ids[wmi_pdev_set_mac_config_resp_event_id] =
23102 		WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID;
23103 	event_ids[wmi_coex_bt_activity_event_id] =
23104 		WMI_WLAN_COEX_BT_ACTIVITY_EVENTID;
23105 	event_ids[wmi_mgmt_tx_bundle_completion_event_id] =
23106 		WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID;
23107 	event_ids[wmi_radio_tx_power_level_stats_event_id] =
23108 		WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID;
23109 	event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID;
23110 	event_ids[wmi_dma_buf_release_event_id] =
23111 					WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID;
23112 	event_ids[wmi_sap_obss_detection_report_event_id] =
23113 		WMI_SAP_OBSS_DETECTION_REPORT_EVENTID;
23114 	event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID;
23115 	event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID;
23116 	event_ids[wmi_obss_color_collision_report_event_id] =
23117 		WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID;
23118 }
23119 
23120 /**
23121  * populate_tlv_service() - populates wmi services
23122  *
23123  * @param wmi_service: Pointer to hold wmi_service
23124  * Return: None
23125  */
23126 static void populate_tlv_service(uint32_t *wmi_service)
23127 {
23128 	wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD;
23129 	wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT;
23130 	wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD;
23131 	wmi_service[wmi_service_roam_scan_offload] =
23132 					WMI_SERVICE_ROAM_SCAN_OFFLOAD;
23133 	wmi_service[wmi_service_bcn_miss_offload] =
23134 					WMI_SERVICE_BCN_MISS_OFFLOAD;
23135 	wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE;
23136 	wmi_service[wmi_service_sta_advanced_pwrsave] =
23137 				WMI_SERVICE_STA_ADVANCED_PWRSAVE;
23138 	wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD;
23139 	wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS;
23140 	wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC;
23141 	wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK;
23142 	wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR;
23143 	wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER;
23144 	wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT;
23145 	wmi_service[wmi_service_wow] = WMI_SERVICE_WOW;
23146 	wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE;
23147 	wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS;
23148 	wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD;
23149 	wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO;
23150 	wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD;
23151 	wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH;
23152 	wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD;
23153 	wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER;
23154 	wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID;
23155 	wmi_service[wmi_service_packet_power_save] =
23156 					WMI_SERVICE_PACKET_POWER_SAVE;
23157 	wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG;
23158 	wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO;
23159 	wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] =
23160 				WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM;
23161 	wmi_service[wmi_sta_uapsd_basic_auto_trig] =
23162 					WMI_STA_UAPSD_BASIC_AUTO_TRIG;
23163 	wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG;
23164 	wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE;
23165 	wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP;
23166 	wmi_service[wmi_service_ap_ps_detect_out_of_sync] =
23167 				WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC;
23168 	wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX;
23169 	wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS;
23170 	wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST;
23171 	wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC;
23172 	wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS;
23173 	wmi_service[wmi_service_burst] = WMI_SERVICE_BURST;
23174 	wmi_service[wmi_service_mcc_bcn_interval_change] =
23175 				WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE;
23176 	wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS;
23177 	wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT;
23178 	wmi_service[wmi_service_filter_ipsec_natkeepalive] =
23179 				WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE;
23180 	wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB;
23181 	wmi_service[wmi_service_lte_ant_share_support] =
23182 				WMI_SERVICE_LTE_ANT_SHARE_SUPPORT;
23183 	wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN;
23184 	wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER;
23185 	wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ;
23186 	wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT;
23187 	wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC;
23188 	wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD;
23189 	wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR;
23190 	wmi_service[wmi_service_bcn_txrate_override] =
23191 				WMI_SERVICE_BCN_TXRATE_OVERRIDE;
23192 	wmi_service[wmi_service_nan] = WMI_SERVICE_NAN;
23193 	wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT;
23194 	wmi_service[wmi_service_estimate_linkspeed] =
23195 				WMI_SERVICE_ESTIMATE_LINKSPEED;
23196 	wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN;
23197 	wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN;
23198 	wmi_service[wmi_service_tdls_uapsd_buffer_sta] =
23199 				WMI_SERVICE_TDLS_UAPSD_BUFFER_STA;
23200 	wmi_service[wmi_service_tdls_uapsd_sleep_sta] =
23201 				WMI_SERVICE_TDLS_UAPSD_SLEEP_STA;
23202 	wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE;
23203 	wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS;
23204 	wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN;
23205 	wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW;
23206 	wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD;
23207 	wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD;
23208 	wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER;
23209 	wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD;
23210 	wmi_service[wmi_service_sta_rx_ipa_offload_support] =
23211 				WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT;
23212 	wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD;
23213 	wmi_service[wmi_service_sap_auth_offload] =
23214 					WMI_SERVICE_SAP_AUTH_OFFLOAD;
23215 	wmi_service[wmi_service_dual_band_simultaneous_support] =
23216 				WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT;
23217 	wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB;
23218 	wmi_service[wmi_service_ap_arpns_offload] =
23219 					WMI_SERVICE_AP_ARPNS_OFFLOAD;
23220 	wmi_service[wmi_service_per_band_chainmask_support] =
23221 				WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT;
23222 	wmi_service[wmi_service_packet_filter_offload] =
23223 				WMI_SERVICE_PACKET_FILTER_OFFLOAD;
23224 	wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT;
23225 	wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI;
23226 	wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG;
23227 	wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC;
23228 	wmi_service[wmi_service_multiple_vdev_restart] =
23229 			WMI_SERVICE_MULTIPLE_VDEV_RESTART;
23230 
23231 	wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE;
23232 	wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE;
23233 	wmi_service[wmi_service_smart_antenna_sw_support] =
23234 				WMI_SERVICE_UNAVAILABLE;
23235 	wmi_service[wmi_service_smart_antenna_hw_support] =
23236 				WMI_SERVICE_UNAVAILABLE;
23237 	wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE;
23238 	wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT;
23239 	wmi_service[wmi_service_atf] = WMI_SERVICE_ATF;
23240 	wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE;
23241 	wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE;
23242 	wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE;
23243 	wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE;
23244 	wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE;
23245 	wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE;
23246 	wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE;
23247 	wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE;
23248 	wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE;
23249 	wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE;
23250 	wmi_service[wmi_service_periodic_chan_stat_support] =
23251 			WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT;
23252 	wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE;
23253 	wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE;
23254 	wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE;
23255 	wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE;
23256 	wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE;
23257 	wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH;
23258 	wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF;
23259 	wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP;
23260 	wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD;
23261 	wmi_service[wmi_service_unified_wow_capability] =
23262 				WMI_SERVICE_UNIFIED_WOW_CAPABILITY;
23263 	wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH;
23264 	wmi_service[wmi_service_bpf_offload] = WMI_SERVICE_BPF_OFFLOAD;
23265 	wmi_service[wmi_service_sync_delete_cmds] =
23266 				WMI_SERVICE_SYNC_DELETE_CMDS;
23267 	wmi_service[wmi_service_ratectrl_limit_max_min_rates] =
23268 				WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES;
23269 	wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA;
23270 	wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT;
23271 	wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX;
23272 	wmi_service[wmi_service_deprecated_replace] =
23273 				WMI_SERVICE_DEPRECATED_REPLACE;
23274 	wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] =
23275 				WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE;
23276 	wmi_service[wmi_service_enhanced_mcast_filter] =
23277 				WMI_SERVICE_ENHANCED_MCAST_FILTER;
23278 	wmi_service[wmi_service_half_rate_quarter_rate_support] =
23279 				WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT;
23280 	wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER;
23281 	wmi_service[wmi_service_p2p_listen_offload_support] =
23282 				WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT;
23283 	wmi_service[wmi_service_mark_first_wakeup_packet] =
23284 				WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET;
23285 	wmi_service[wmi_service_multiple_mcast_filter_set] =
23286 				WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET;
23287 	wmi_service[wmi_service_host_managed_rx_reorder] =
23288 				WMI_SERVICE_HOST_MANAGED_RX_REORDER;
23289 	wmi_service[wmi_service_flash_rdwr_support] =
23290 				WMI_SERVICE_FLASH_RDWR_SUPPORT;
23291 	wmi_service[wmi_service_wlan_stats_report] =
23292 				WMI_SERVICE_WLAN_STATS_REPORT;
23293 	wmi_service[wmi_service_tx_msdu_id_new_partition_support] =
23294 				WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT;
23295 	wmi_service[wmi_service_dfs_phyerr_offload] =
23296 				WMI_SERVICE_DFS_PHYERR_OFFLOAD;
23297 	wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT;
23298 	wmi_service[wmi_service_fw_mem_dump_support] =
23299 				WMI_SERVICE_FW_MEM_DUMP_SUPPORT;
23300 	wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO;
23301 	wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB;
23302 	wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD;
23303 	wmi_service[wmi_service_hw_data_filtering] =
23304 				WMI_SERVICE_HW_DATA_FILTERING;
23305 	wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING;
23306 	wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI;
23307 	wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO;
23308 	wmi_service[wmi_service_extended_nss_support] =
23309 				WMI_SERVICE_EXTENDED_NSS_SUPPORT;
23310 	wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT;
23311 	wmi_service[wmi_service_bcn_offload_start_stop_support] =
23312 				WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT;
23313 	wmi_service[wmi_service_offchan_data_tid_support] =
23314 				WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT;
23315 	wmi_service[wmi_service_support_dma] =
23316 				WMI_SERVICE_SUPPORT_DIRECT_DMA;
23317 	wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE;
23318 	wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT;
23319 	wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT;
23320 	wmi_service[wmi_service_11k_neighbour_report_support] =
23321 				WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT;
23322 	wmi_service[wmi_service_ap_obss_detection_offload] =
23323 				WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD;
23324 	wmi_service[wmi_service_bss_color_offload] =
23325 				WMI_SERVICE_BSS_COLOR_OFFLOAD;
23326 	wmi_service[wmi_service_gmac_offload_support] =
23327 				WMI_SERVICE_GMAC_OFFLOAD_SUPPORT;
23328 
23329 }
23330 
23331 #ifndef CONFIG_MCL
23332 
23333 /**
23334  * populate_pdev_param_tlv() - populates pdev params
23335  *
23336  * @param pdev_param: Pointer to hold pdev params
23337  * Return: None
23338  */
23339 static void populate_pdev_param_tlv(uint32_t *pdev_param)
23340 {
23341 	pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK;
23342 	pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK;
23343 	pdev_param[wmi_pdev_param_txpower_limit2g] =
23344 				WMI_PDEV_PARAM_TXPOWER_LIMIT2G;
23345 	pdev_param[wmi_pdev_param_txpower_limit5g] =
23346 				WMI_PDEV_PARAM_TXPOWER_LIMIT5G;
23347 	pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE;
23348 	pdev_param[wmi_pdev_param_beacon_gen_mode] =
23349 				WMI_PDEV_PARAM_BEACON_GEN_MODE;
23350 	pdev_param[wmi_pdev_param_beacon_tx_mode] =
23351 				WMI_PDEV_PARAM_BEACON_TX_MODE;
23352 	pdev_param[wmi_pdev_param_resmgr_offchan_mode] =
23353 				WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE;
23354 	pdev_param[wmi_pdev_param_protection_mode] =
23355 				WMI_PDEV_PARAM_PROTECTION_MODE;
23356 	pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW;
23357 	pdev_param[wmi_pdev_param_non_agg_sw_retry_th] =
23358 				WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH;
23359 	pdev_param[wmi_pdev_param_agg_sw_retry_th] =
23360 				WMI_PDEV_PARAM_AGG_SW_RETRY_TH;
23361 	pdev_param[wmi_pdev_param_sta_kickout_th] =
23362 				WMI_PDEV_PARAM_STA_KICKOUT_TH;
23363 	pdev_param[wmi_pdev_param_ac_aggrsize_scaling] =
23364 				WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING;
23365 	pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE;
23366 	pdev_param[wmi_pdev_param_ltr_ac_latency_be] =
23367 				WMI_PDEV_PARAM_LTR_AC_LATENCY_BE;
23368 	pdev_param[wmi_pdev_param_ltr_ac_latency_bk] =
23369 				WMI_PDEV_PARAM_LTR_AC_LATENCY_BK;
23370 	pdev_param[wmi_pdev_param_ltr_ac_latency_vi] =
23371 				WMI_PDEV_PARAM_LTR_AC_LATENCY_VI;
23372 	pdev_param[wmi_pdev_param_ltr_ac_latency_vo] =
23373 				WMI_PDEV_PARAM_LTR_AC_LATENCY_VO;
23374 	pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] =
23375 				WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT;
23376 	pdev_param[wmi_pdev_param_ltr_sleep_override] =
23377 				WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE;
23378 	pdev_param[wmi_pdev_param_ltr_rx_override] =
23379 				WMI_PDEV_PARAM_LTR_RX_OVERRIDE;
23380 	pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] =
23381 				WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT;
23382 	pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE;
23383 	pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE;
23384 	pdev_param[wmi_pdev_param_pcielp_txbuf_flush] =
23385 				WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH;
23386 	pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] =
23387 				WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK;
23388 	pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] =
23389 				WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN;
23390 	pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] =
23391 				WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE;
23392 	pdev_param[wmi_pdev_param_pdev_stats_update_period] =
23393 				WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD;
23394 	pdev_param[wmi_pdev_param_vdev_stats_update_period] =
23395 				WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD;
23396 	pdev_param[wmi_pdev_param_peer_stats_update_period] =
23397 				WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD;
23398 	pdev_param[wmi_pdev_param_bcnflt_stats_update_period] =
23399 				WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD;
23400 	pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS;
23401 	pdev_param[wmi_pdev_param_arp_ac_override] =
23402 				WMI_PDEV_PARAM_ARP_AC_OVERRIDE;
23403 	pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS;
23404 	pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE;
23405 	pdev_param[wmi_pdev_param_ani_poll_period] =
23406 				WMI_PDEV_PARAM_ANI_POLL_PERIOD;
23407 	pdev_param[wmi_pdev_param_ani_listen_period] =
23408 				WMI_PDEV_PARAM_ANI_LISTEN_PERIOD;
23409 	pdev_param[wmi_pdev_param_ani_ofdm_level] =
23410 				WMI_PDEV_PARAM_ANI_OFDM_LEVEL;
23411 	pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL;
23412 	pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN;
23413 	pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA;
23414 	pdev_param[wmi_pdev_param_idle_ps_config] =
23415 				WMI_PDEV_PARAM_IDLE_PS_CONFIG;
23416 	pdev_param[wmi_pdev_param_power_gating_sleep] =
23417 				WMI_PDEV_PARAM_POWER_GATING_SLEEP;
23418 	pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE;
23419 	pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR;
23420 	pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE;
23421 	pdev_param[wmi_pdev_param_hw_rfkill_config] =
23422 				WMI_PDEV_PARAM_HW_RFKILL_CONFIG;
23423 	pdev_param[wmi_pdev_param_low_power_rf_enable] =
23424 				WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE;
23425 	pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK;
23426 	pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN;
23427 	pdev_param[wmi_pdev_param_power_collapse_enable] =
23428 				WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE;
23429 	pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE;
23430 	pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE;
23431 	pdev_param[wmi_pdev_param_audio_over_wlan_latency] =
23432 				WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY;
23433 	pdev_param[wmi_pdev_param_audio_over_wlan_enable] =
23434 				WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE;
23435 	pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] =
23436 				WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE;
23437 	pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] =
23438 				WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD;
23439 	pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW;
23440 	pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG;
23441 	pdev_param[wmi_pdev_param_adaptive_early_rx_enable] =
23442 				WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE;
23443 	pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] =
23444 				WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP;
23445 	pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] =
23446 				WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP;
23447 	pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] =
23448 				WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP;
23449 	pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] =
23450 				WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE;
23451 	pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] =
23452 				WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT;
23453 	pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] =
23454 				WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP;
23455 	pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] =
23456 				WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT;
23457 	pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] =
23458 				WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE;
23459 	pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] =
23460 				WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE;
23461 	pdev_param[wmi_pdev_param_tx_chain_mask_2g] =
23462 				WMI_PDEV_PARAM_TX_CHAIN_MASK_2G;
23463 	pdev_param[wmi_pdev_param_rx_chain_mask_2g] =
23464 				WMI_PDEV_PARAM_RX_CHAIN_MASK_2G;
23465 	pdev_param[wmi_pdev_param_tx_chain_mask_5g] =
23466 				WMI_PDEV_PARAM_TX_CHAIN_MASK_5G;
23467 	pdev_param[wmi_pdev_param_rx_chain_mask_5g] =
23468 				WMI_PDEV_PARAM_RX_CHAIN_MASK_5G;
23469 	pdev_param[wmi_pdev_param_tx_chain_mask_cck] =
23470 				WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK;
23471 	pdev_param[wmi_pdev_param_tx_chain_mask_1ss] =
23472 				WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS;
23473 	pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER;
23474 	pdev_param[wmi_pdev_set_mcast_to_ucast_tid] =
23475 				WMI_PDEV_SET_MCAST_TO_UCAST_TID;
23476 	pdev_param[wmi_pdev_param_mgmt_retry_limit] =
23477 					WMI_PDEV_PARAM_MGMT_RETRY_LIMIT;
23478 	pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST;
23479 	pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] =
23480 					WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE;
23481 	pdev_param[wmi_pdev_param_proxy_sta_mode] =
23482 				WMI_PDEV_PARAM_PROXY_STA_MODE;
23483 	pdev_param[wmi_pdev_param_mu_group_policy] =
23484 				WMI_PDEV_PARAM_MU_GROUP_POLICY;
23485 	pdev_param[wmi_pdev_param_noise_detection] =
23486 				WMI_PDEV_PARAM_NOISE_DETECTION;
23487 	pdev_param[wmi_pdev_param_noise_threshold] =
23488 				WMI_PDEV_PARAM_NOISE_THRESHOLD;
23489 	pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE;
23490 	pdev_param[wmi_pdev_param_set_mcast_bcast_echo] =
23491 				WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO;
23492 	pdev_param[wmi_pdev_param_atf_strict_sch] =
23493 		WMI_PDEV_PARAM_ATF_STRICT_SCH;
23494 	pdev_param[wmi_pdev_param_atf_sched_duration] =
23495 		WMI_PDEV_PARAM_ATF_SCHED_DURATION;
23496 	pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN;
23497 	pdev_param[wmi_pdev_param_sensitivity_level] =
23498 				WMI_PDEV_PARAM_SENSITIVITY_LEVEL;
23499 	pdev_param[wmi_pdev_param_signed_txpower_2g] =
23500 				WMI_PDEV_PARAM_SIGNED_TXPOWER_2G;
23501 	pdev_param[wmi_pdev_param_signed_txpower_5g] =
23502 				WMI_PDEV_PARAM_SIGNED_TXPOWER_5G;
23503 	pdev_param[wmi_pdev_param_enable_per_tid_amsdu] =
23504 		WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU;
23505 	pdev_param[wmi_pdev_param_enable_per_tid_ampdu] =
23506 		WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU;
23507 	pdev_param[wmi_pdev_param_cca_threshold] =
23508 				WMI_PDEV_PARAM_CCA_THRESHOLD;
23509 	pdev_param[wmi_pdev_param_rts_fixed_rate] =
23510 				WMI_PDEV_PARAM_RTS_FIXED_RATE;
23511 	pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM;
23512 	pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET;
23513 	pdev_param[wmi_pdev_param_wapi_mbssid_offset] =
23514 				WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET;
23515 	pdev_param[wmi_pdev_param_arp_srcaddr] =
23516 				WMI_PDEV_PARAM_ARP_DBG_SRCADDR;
23517 	pdev_param[wmi_pdev_param_arp_dstaddr] =
23518 				WMI_PDEV_PARAM_ARP_DBG_DSTADDR;
23519 	pdev_param[wmi_pdev_param_txpower_decr_db] =
23520 				WMI_PDEV_PARAM_TXPOWER_DECR_DB;
23521 	pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM;
23522 	pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM;
23523 	pdev_param[wmi_pdev_param_atf_obss_noise_sch] =
23524 		WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH;
23525 	pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] =
23526 		WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR;
23527 	pdev_param[wmi_pdev_param_cust_txpower_scale] =
23528 				WMI_PDEV_PARAM_CUST_TXPOWER_SCALE;
23529 	pdev_param[wmi_pdev_param_atf_dynamic_enable] =
23530 		WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE;
23531 	pdev_param[wmi_pdev_param_atf_ssid_group_policy] =
23532 						WMI_UNAVAILABLE_PARAM;
23533 	pdev_param[wmi_pdev_param_igmpmld_override] = WMI_UNAVAILABLE_PARAM;
23534 	pdev_param[wmi_pdev_param_igmpmld_tid] = WMI_UNAVAILABLE_PARAM;
23535 	pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN;
23536 	pdev_param[wmi_pdev_param_block_interbss] =
23537 				WMI_PDEV_PARAM_BLOCK_INTERBSS;
23538 	pdev_param[wmi_pdev_param_set_disable_reset_cmdid] =
23539 				WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID;
23540 	pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] =
23541 				WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID;
23542 	pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] =
23543 				WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID;
23544 	pdev_param[wmi_pdev_param_set_burst_mode_cmdid] =
23545 					WMI_PDEV_PARAM_SET_BURST_MODE_CMDID;
23546 	pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS;
23547 	pdev_param[wmi_pdev_param_mesh_mcast_enable] =
23548 					WMI_PDEV_PARAM_MESH_MCAST_ENABLE;
23549 	pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] =
23550 					WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID;
23551 	pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] =
23552 					WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID;
23553 	pdev_param[wmi_pdev_param_igmpmld_ac_override] =
23554 					WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE;
23555 	pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] =
23556 				WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER;
23557 	pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] =
23558 				WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER;
23559 	pdev_param[wmi_pdev_param_set_mcast2ucast_mode] =
23560 				WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE;
23561 	pdev_param[wmi_pdev_param_smart_antenna_default_antenna] =
23562 				WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA;
23563 	pdev_param[wmi_pdev_param_fast_channel_reset] =
23564 				WMI_PDEV_PARAM_FAST_CHANNEL_RESET;
23565 	pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE;
23566 	pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT;
23567 	pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE;
23568 }
23569 
23570 /**
23571  * populate_vdev_param_tlv() - populates vdev params
23572  *
23573  * @param vdev_param: Pointer to hold vdev params
23574  * Return: None
23575  */
23576 static void populate_vdev_param_tlv(uint32_t *vdev_param)
23577 {
23578 	vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD;
23579 	vdev_param[wmi_vdev_param_fragmentation_threshold] =
23580 				WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD;
23581 	vdev_param[wmi_vdev_param_beacon_interval] =
23582 				WMI_VDEV_PARAM_BEACON_INTERVAL;
23583 	vdev_param[wmi_vdev_param_listen_interval] =
23584 				WMI_VDEV_PARAM_LISTEN_INTERVAL;
23585 	vdev_param[wmi_vdev_param_multicast_rate] =
23586 				WMI_VDEV_PARAM_MULTICAST_RATE;
23587 	vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE;
23588 	vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME;
23589 	vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE;
23590 	vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME;
23591 	vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD;
23592 	vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME;
23593 	vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL;
23594 	vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD;
23595 	vdev_param[wmi_vdev_oc_scheduler_air_time_limit] =
23596 				WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT;
23597 	vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS;
23598 	vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW;
23599 	vdev_param[wmi_vdev_param_bmiss_count_max] =
23600 				WMI_VDEV_PARAM_BMISS_COUNT_MAX;
23601 	vdev_param[wmi_vdev_param_bmiss_first_bcnt] =
23602 				WMI_VDEV_PARAM_BMISS_FIRST_BCNT;
23603 	vdev_param[wmi_vdev_param_bmiss_final_bcnt] =
23604 				WMI_VDEV_PARAM_BMISS_FINAL_BCNT;
23605 	vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM;
23606 	vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH;
23607 	vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET;
23608 	vdev_param[wmi_vdev_param_disable_htprotection] =
23609 				WMI_VDEV_PARAM_DISABLE_HTPROTECTION;
23610 	vdev_param[wmi_vdev_param_sta_quickkickout] =
23611 				WMI_VDEV_PARAM_STA_QUICKKICKOUT;
23612 	vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE;
23613 	vdev_param[wmi_vdev_param_protection_mode] =
23614 				WMI_VDEV_PARAM_PROTECTION_MODE;
23615 	vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE;
23616 	vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI;
23617 	vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC;
23618 	vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC;
23619 	vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC;
23620 	vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD;
23621 	vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID;
23622 	vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS;
23623 	vdev_param[wmi_vdev_param_bcast_data_rate] =
23624 				WMI_VDEV_PARAM_BCAST_DATA_RATE;
23625 	vdev_param[wmi_vdev_param_mcast_data_rate] =
23626 				WMI_VDEV_PARAM_MCAST_DATA_RATE;
23627 	vdev_param[wmi_vdev_param_mcast_indicate] =
23628 				WMI_VDEV_PARAM_MCAST_INDICATE;
23629 	vdev_param[wmi_vdev_param_dhcp_indicate] =
23630 				WMI_VDEV_PARAM_DHCP_INDICATE;
23631 	vdev_param[wmi_vdev_param_unknown_dest_indicate] =
23632 				WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE;
23633 	vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] =
23634 		WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS;
23635 	vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] =
23636 		WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS;
23637 	vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] =
23638 		WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS;
23639 	vdev_param[wmi_vdev_param_ap_enable_nawds] =
23640 				WMI_VDEV_PARAM_AP_ENABLE_NAWDS;
23641 	vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS;
23642 	vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF;
23643 	vdev_param[wmi_vdev_param_packet_powersave] =
23644 				WMI_VDEV_PARAM_PACKET_POWERSAVE;
23645 	vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY;
23646 	vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
23647 	vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] =
23648 		WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS;
23649 	vdev_param[wmi_vdev_param_early_rx_adjust_enable] =
23650 				WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE;
23651 	vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] =
23652 				WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM;
23653 	vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] =
23654 				WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE;
23655 	vdev_param[wmi_vdev_param_early_rx_slop_step] =
23656 				WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP;
23657 	vdev_param[wmi_vdev_param_early_rx_init_slop] =
23658 				WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP;
23659 	vdev_param[wmi_vdev_param_early_rx_adjust_pause] =
23660 				WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE;
23661 	vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT;
23662 	vdev_param[wmi_vdev_param_snr_num_for_cal] =
23663 				WMI_VDEV_PARAM_SNR_NUM_FOR_CAL;
23664 	vdev_param[wmi_vdev_param_roam_fw_offload] =
23665 				WMI_VDEV_PARAM_ROAM_FW_OFFLOAD;
23666 	vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC;
23667 	vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] =
23668 				WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS;
23669 	vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE;
23670 	vdev_param[wmi_vdev_param_early_rx_drift_sample] =
23671 				WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE;
23672 	vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] =
23673 				WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR;
23674 	vdev_param[wmi_vdev_param_ebt_resync_timeout] =
23675 				WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT;
23676 	vdev_param[wmi_vdev_param_aggr_trig_event_enable] =
23677 				WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE;
23678 	vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] =
23679 				WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED;
23680 	vdev_param[wmi_vdev_param_is_power_collapse_allowed] =
23681 				WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED;
23682 	vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] =
23683 				WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED;
23684 	vdev_param[wmi_vdev_param_inactivity_cnt] =
23685 		WMI_VDEV_PARAM_INACTIVITY_CNT;
23686 	vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] =
23687 				WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS;
23688 	vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY;
23689 	vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] =
23690 				WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS;
23691 	vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] =
23692 			WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE;
23693 	vdev_param[wmi_vdev_param_rx_leak_window] =
23694 			WMI_VDEV_PARAM_RX_LEAK_WINDOW;
23695 	vdev_param[wmi_vdev_param_stats_avg_factor] =
23696 				WMI_VDEV_PARAM_STATS_AVG_FACTOR;
23697 	vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH;
23698 	vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE;
23699 	vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] =
23700 				WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE;
23701 	vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] =
23702 				WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE;
23703 	vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER;
23704 	vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE;
23705 	vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE;
23706 	vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM;
23707 	vdev_param[wmi_vdev_param_he_range_ext_enable] =
23708 				 WMI_VDEV_PARAM_HE_RANGE_EXT;
23709 	vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR;
23710 	vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE;
23711 	vdev_param[wmi_vdev_param_set_heop]      = WMI_VDEV_PARAM_HEOPS_0_31;
23712 	vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP;
23713 	vdev_param[wmi_vdev_param_dtim_enable_cts] =
23714 					WMI_VDEV_PARAM_DTIM_ENABLE_CTS;
23715 	vdev_param[wmi_vdev_param_atf_ssid_sched_policy] =
23716 					WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY;
23717 	vdev_param[wmi_vdev_param_disable_dyn_bw_rts] =
23718 					WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS;
23719 	vdev_param[wmi_vdev_param_mcast2ucast_set] =
23720 					WMI_VDEV_PARAM_MCAST2UCAST_SET;
23721 	vdev_param[wmi_vdev_param_rc_num_retries] =
23722 					WMI_VDEV_PARAM_RC_NUM_RETRIES;
23723 	vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR;
23724 	vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET;
23725 	vdev_param[wmi_vdev_param_rts_fixed_rate] =
23726 					WMI_VDEV_PARAM_RTS_FIXED_RATE;
23727 	vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK;
23728 	vdev_param[wmi_vdev_param_vht80_ratemask] =
23729 					WMI_VDEV_PARAM_VHT80_RATEMASK;
23730 	vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA;
23731 	vdev_param[wmi_vdev_param_bw_nss_ratemask] =
23732 					WMI_VDEV_PARAM_BW_NSS_RATEMASK;
23733 	vdev_param[wmi_vdev_param_set_he_ltf] = WMI_VDEV_PARAM_HE_LTF;
23734 	vdev_param[wmi_vdev_param_rate_dropdown_bmap] =
23735 					WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP;
23736 	vdev_param[wmi_vdev_param_set_ba_mode] =
23737 					WMI_VDEV_PARAM_BA_MODE;
23738 }
23739 #endif
23740 
23741 /**
23742  * populate_target_defines_tlv() - Populate target defines and params
23743  * @wmi_handle: pointer to wmi handle
23744  *
23745  * Return: None
23746  */
23747 #ifndef CONFIG_MCL
23748 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle)
23749 {
23750 	populate_pdev_param_tlv(wmi_handle->pdev_param);
23751 	populate_vdev_param_tlv(wmi_handle->vdev_param);
23752 }
23753 #else
23754 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle)
23755 { }
23756 #endif
23757 
23758 /**
23759  * wmi_ocb_ut_attach() - Attach OCB test framework
23760  * @wmi_handle: wmi handle
23761  *
23762  * Return: None
23763  */
23764 #ifdef WLAN_OCB_UT
23765 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle);
23766 #else
23767 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle)
23768 {
23769 	return;
23770 }
23771 #endif
23772 
23773 /**
23774  * wmi_tlv_attach() - Attach TLV APIs
23775  *
23776  * Return: None
23777  */
23778 void wmi_tlv_attach(wmi_unified_t wmi_handle)
23779 {
23780 	wmi_handle->ops = &tlv_ops;
23781 	wmi_ocb_ut_attach(wmi_handle);
23782 	wmi_handle->soc->svc_ids = &multi_svc_ids[0];
23783 #ifdef WMI_INTERFACE_EVENT_LOGGING
23784 	/* Skip saving WMI_CMD_HDR and TLV HDR */
23785 	wmi_handle->log_info.buf_offset_command = 8;
23786 	/* WMI_CMD_HDR is already stripped, skip saving TLV HDR */
23787 	wmi_handle->log_info.buf_offset_event = 4;
23788 #endif
23789 	populate_tlv_events_id(wmi_handle->wmi_events);
23790 	populate_tlv_service(wmi_handle->services);
23791 	populate_target_defines_tlv(wmi_handle);
23792 }
23793 EXPORT_SYMBOL(wmi_tlv_attach);
23794 
23795 /**
23796  * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine
23797  *
23798  * Return: None
23799  */
23800 void wmi_tlv_init(void)
23801 {
23802 	wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach);
23803 }
23804