xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_sta_tlv.c (revision 45a38684b07295822dc8eba39e293408f203eec8)
1 /*
2  * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <osdep.h>
20 #include "wmi.h"
21 #include "wmi_version.h"
22 #include "wmi_unified_priv.h"
23 #include "wmi_unified_sta_param.h"
24 #include "wmi_unified_sta_api.h"
25 #ifdef FEATURE_WLAN_TDLS
26 #include <wlan_tdls_public_structs.h>
27 #endif
28 
29 /**
30  * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters
31  * @wmi_handle: wmi handle
32  * @vdev_id: vdev id
33  * @max_retries: max retries
34  * @retry_interval: retry interval
35  * This function sets sta query related parameters in fw.
36  *
37  * Return: QDF_STATUS_SUCCESS for success otherwise failure
38  */
39 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle,
40 						      uint8_t vdev_id,
41 						      uint32_t max_retries,
42 						      uint32_t retry_interval)
43 {
44 	wmi_buf_t buf;
45 	WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd;
46 	int len;
47 
48 	len = sizeof(*cmd);
49 	buf = wmi_buf_alloc(wmi_handle, len);
50 	if (!buf) {
51 		return QDF_STATUS_E_FAILURE;
52 	}
53 
54 	cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf);
55 	WMITLV_SET_HDR(&cmd->tlv_header,
56 		WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param,
57 		WMITLV_GET_STRUCT_TLVLEN
58 			(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param));
59 
60 	cmd->vdev_id = vdev_id;
61 	cmd->sa_query_max_retry_count = max_retries;
62 	cmd->sa_query_retry_interval = retry_interval;
63 
64 	WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"),
65 		 vdev_id, retry_interval, max_retries);
66 
67 	wmi_mtrace(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID, cmd->vdev_id, 0);
68 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
69 				 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) {
70 		WMI_LOGE(FL("Failed to offload STA SA Query"));
71 		wmi_buf_free(buf);
72 		return QDF_STATUS_E_FAILURE;
73 	}
74 
75 	WMI_LOGD(FL("Exit :"));
76 	return 0;
77 }
78 
79 /**
80  * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters
81  * @wmi_handle: wmi handle
82  * @params: sta keep alive parameter
83  *
84  * This function sets keep alive related parameters in fw.
85  *
86  * Return: CDF status
87  */
88 static QDF_STATUS
89 send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle,
90 				struct sta_keep_alive_params *params)
91 {
92 	wmi_buf_t buf;
93 	WMI_STA_KEEPALIVE_CMD_fixed_param *cmd;
94 	WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp;
95 	uint8_t *buf_ptr;
96 	int len;
97 	QDF_STATUS ret;
98 
99 	WMI_LOGD("%s: Enter", __func__);
100 
101 	len = sizeof(*cmd) + sizeof(*arp_rsp);
102 	buf = wmi_buf_alloc(wmi_handle, len);
103 	if (!buf) {
104 		return QDF_STATUS_E_FAILURE;
105 	}
106 
107 	cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf);
108 	buf_ptr = (uint8_t *) cmd;
109 	WMITLV_SET_HDR(&cmd->tlv_header,
110 		       WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param,
111 		       WMITLV_GET_STRUCT_TLVLEN
112 			       (WMI_STA_KEEPALIVE_CMD_fixed_param));
113 	cmd->interval = params->timeperiod;
114 	cmd->enable = (params->timeperiod) ? 1 : 0;
115 	cmd->vdev_id = params->vdev_id;
116 	WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d",
117 		 params->vdev_id, params->timeperiod, params->method);
118 	arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd));
119 	WMITLV_SET_HDR(&arp_rsp->tlv_header,
120 		       WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE,
121 		       WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE));
122 
123 	if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) ||
124 	    (params->method ==
125 	     WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) {
126 		cmd->method = params->method;
127 		qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr,
128 			     QDF_IPV4_ADDR_SIZE);
129 		qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr,
130 			     QDF_IPV4_ADDR_SIZE);
131 		WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac,
132 					   &arp_rsp->dest_mac_addr);
133 	} else {
134 		cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
135 	}
136 
137 	wmi_mtrace(WMI_STA_KEEPALIVE_CMDID, cmd->vdev_id, 0);
138 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
139 				   WMI_STA_KEEPALIVE_CMDID);
140 	if (QDF_IS_STATUS_ERROR(ret)) {
141 		WMI_LOGE("Failed to set KeepAlive");
142 		wmi_buf_free(buf);
143 	}
144 
145 	WMI_LOGD("%s: Exit", __func__);
146 	return ret;
147 }
148 
149 /**
150  * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params
151  * @wmi_handle: wmi handle
152  * @if_id: vdev id
153  * @gtx_info: GTX config params
154  *
155  * This function set GTX related params in firmware.
156  *
157  * Return: QDF_STATUS_SUCCESS for success or error code
158  */
159 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id,
160 				  struct wmi_gtx_config *gtx_info)
161 {
162 	wmi_vdev_set_gtx_params_cmd_fixed_param *cmd;
163 	wmi_buf_t buf;
164 	QDF_STATUS ret;
165 	int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param);
166 
167 	buf = wmi_buf_alloc(wmi_handle, len);
168 	if (!buf) {
169 		return QDF_STATUS_E_NOMEM;
170 	}
171 	cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf);
172 	WMITLV_SET_HDR(&cmd->tlv_header,
173 		       WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param,
174 		       WMITLV_GET_STRUCT_TLVLEN
175 			       (wmi_vdev_set_gtx_params_cmd_fixed_param));
176 	cmd->vdev_id = if_id;
177 
178 	cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0];
179 	cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1];
180 	cmd->userGtxMask = gtx_info->gtx_usrcfg;
181 	cmd->gtxPERThreshold = gtx_info->gtx_threshold;
182 	cmd->gtxPERMargin = gtx_info->gtx_margin;
183 	cmd->gtxTPCstep = gtx_info->gtx_tpcstep;
184 	cmd->gtxTPCMin = gtx_info->gtx_tpcmin;
185 	cmd->gtxBWMask = gtx_info->gtx_bwmask;
186 
187 	WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \
188 		 gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \
189 		 gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1],
190 		 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin,
191 		 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask);
192 
193 	wmi_mtrace(WMI_VDEV_SET_GTX_PARAMS_CMDID, cmd->vdev_id, 0);
194 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
195 				   WMI_VDEV_SET_GTX_PARAMS_CMDID);
196 	if (QDF_IS_STATUS_ERROR(ret)) {
197 		WMI_LOGE("Failed to set GTX PARAMS");
198 		wmi_buf_free(buf);
199 	}
200 	return ret;
201 }
202 
203 /**
204  * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME
205  * @wmi_handle: wmi handle
206  * @ta_dhcp_ind: DHCP indication parameter
207  *
208  * Return: CDF Status
209  */
210 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle,
211 				wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind)
212 {
213 	QDF_STATUS status;
214 	wmi_buf_t buf = NULL;
215 	uint8_t *buf_ptr;
216 	wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp;
217 	int len = sizeof(wmi_peer_set_param_cmd_fixed_param);
218 
219 	buf = wmi_buf_alloc(wmi_handle, len);
220 	if (!buf) {
221 		return QDF_STATUS_E_NOMEM;
222 	}
223 
224 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
225 	peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr;
226 	WMITLV_SET_HDR(&peer_set_param_fp->tlv_header,
227 		       WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
228 		       WMITLV_GET_STRUCT_TLVLEN
229 			       (wmi_peer_set_param_cmd_fixed_param));
230 
231 	/* fill in values */
232 	peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id;
233 	peer_set_param_fp->param_id = ta_dhcp_ind->param_id;
234 	peer_set_param_fp->param_value = ta_dhcp_ind->param_value;
235 	qdf_mem_copy(&peer_set_param_fp->peer_macaddr,
236 		     &ta_dhcp_ind->peer_macaddr,
237 		     sizeof(ta_dhcp_ind->peer_macaddr));
238 
239 	wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, NO_SESSION, 0);
240 	status = wmi_unified_cmd_send(wmi_handle, buf,
241 				      len, WMI_PEER_SET_PARAM_CMDID);
242 	if (QDF_IS_STATUS_ERROR(status)) {
243 		WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
244 			 " returned Error %d", __func__, status);
245 		wmi_buf_free(buf);
246 	}
247 
248 	return status;
249 }
250 
251 /**
252  * send_get_link_speed_cmd_tlv() -send command to get linkspeed
253  * @wmi_handle: wmi handle
254  * @pLinkSpeed: link speed info
255  *
256  * Return: CDF status
257  */
258 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle,
259 					      wmi_mac_addr peer_macaddr)
260 {
261 	wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd;
262 	wmi_buf_t wmi_buf;
263 	uint32_t len;
264 	uint8_t *buf_ptr;
265 
266 	len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param);
267 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
268 	if (!wmi_buf) {
269 		return QDF_STATUS_E_NOMEM;
270 	}
271 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
272 
273 	cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr;
274 	WMITLV_SET_HDR(&cmd->tlv_header,
275 	       WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param,
276 	       WMITLV_GET_STRUCT_TLVLEN
277 			(wmi_peer_get_estimated_linkspeed_cmd_fixed_param));
278 
279 	/* Copy the peer macaddress to the wma buffer */
280 	qdf_mem_copy(&cmd->peer_macaddr,
281 		     &peer_macaddr,
282 		     sizeof(peer_macaddr));
283 
284 	wmi_mtrace(WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID, cmd->vdev_id, 0);
285 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
286 				 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) {
287 		WMI_LOGE("%s: failed to send link speed command", __func__);
288 		wmi_buf_free(wmi_buf);
289 		return QDF_STATUS_E_FAILURE;
290 	}
291 	return QDF_STATUS_SUCCESS;
292 }
293 
294 /**
295  * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW
296  * @wmi_handl: wmi handle
297  * @cmd: Profiling command index
298  * @value1: parameter1 value
299  * @value2: parameter2 value
300  *
301  * Return: QDF_STATUS_SUCCESS for success else error code
302  */
303 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle,
304 			uint32_t cmd, uint32_t value1, uint32_t value2)
305 {
306 	wmi_buf_t buf;
307 	int32_t len = 0;
308 	int ret;
309 	wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd;
310 	wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd;
311 	wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd;
312 	wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd;
313 
314 	switch (cmd) {
315 	case WMI_WLAN_PROFILE_TRIGGER_CMDID:
316 		len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param);
317 		buf = wmi_buf_alloc(wmi_handle, len);
318 		if (!buf) {
319 			return QDF_STATUS_E_NOMEM;
320 		}
321 		prof_trig_cmd =
322 			(wmi_wlan_profile_trigger_cmd_fixed_param *)
323 				wmi_buf_data(buf);
324 		WMITLV_SET_HDR(&prof_trig_cmd->tlv_header,
325 		     WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param,
326 		     WMITLV_GET_STRUCT_TLVLEN
327 				(wmi_wlan_profile_trigger_cmd_fixed_param));
328 		prof_trig_cmd->enable = value1;
329 		wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0);
330 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
331 					   WMI_WLAN_PROFILE_TRIGGER_CMDID);
332 		if (ret) {
333 			WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d",
334 				 value1);
335 			wmi_buf_free(buf);
336 			return ret;
337 		}
338 		break;
339 
340 	case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
341 		len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param);
342 		buf = wmi_buf_alloc(wmi_handle, len);
343 		if (!buf) {
344 			return QDF_STATUS_E_NOMEM;
345 		}
346 		profile_getdata_cmd =
347 			(wmi_wlan_profile_get_prof_data_cmd_fixed_param *)
348 				wmi_buf_data(buf);
349 		WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header,
350 		      WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param,
351 		      WMITLV_GET_STRUCT_TLVLEN
352 		      (wmi_wlan_profile_get_prof_data_cmd_fixed_param));
353 		wmi_mtrace(WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
354 			   NO_SESSION, 0);
355 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
356 				WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID);
357 		if (ret) {
358 			WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d",
359 				 value1, value2);
360 			wmi_buf_free(buf);
361 			return ret;
362 		}
363 		break;
364 
365 	case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
366 		len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param);
367 		buf = wmi_buf_alloc(wmi_handle, len);
368 		if (!buf) {
369 			return QDF_STATUS_E_NOMEM;
370 		}
371 		hist_intvl_cmd =
372 			(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *)
373 				wmi_buf_data(buf);
374 		WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header,
375 		      WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param,
376 		      WMITLV_GET_STRUCT_TLVLEN
377 		      (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param));
378 		hist_intvl_cmd->profile_id = value1;
379 		hist_intvl_cmd->value = value2;
380 		wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
381 			   NO_SESSION, 0);
382 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
383 				WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID);
384 		if (ret) {
385 			WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d",
386 				 value1, value2);
387 			wmi_buf_free(buf);
388 			return ret;
389 		}
390 		break;
391 
392 	case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
393 		len =
394 		sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param);
395 		buf = wmi_buf_alloc(wmi_handle, len);
396 		if (!buf) {
397 			return QDF_STATUS_E_NOMEM;
398 		}
399 		profile_enable_cmd =
400 			(wmi_wlan_profile_enable_profile_id_cmd_fixed_param *)
401 				wmi_buf_data(buf);
402 		WMITLV_SET_HDR(&profile_enable_cmd->tlv_header,
403 		      WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param,
404 		      WMITLV_GET_STRUCT_TLVLEN
405 		      (wmi_wlan_profile_enable_profile_id_cmd_fixed_param));
406 		profile_enable_cmd->profile_id = value1;
407 		profile_enable_cmd->enable = value2;
408 		wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
409 			   NO_SESSION, 0);
410 		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
411 				WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID);
412 		if (ret) {
413 			WMI_LOGE("enable cmd Failed for id %d value %d",
414 				 value1, value2);
415 			wmi_buf_free(buf);
416 			return ret;
417 		}
418 		break;
419 
420 	default:
421 		WMI_LOGD("%s: invalid profiling command", __func__);
422 		break;
423 	}
424 
425 	return 0;
426 }
427 
428 /**
429  * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter
430  * @wmi_handle: wmi handle
431  * @vdev_id: vdev id
432  *
433  * Return: QDF_STATUS_SUCCESS for success or error code
434  */
435 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
436 {
437 	WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd;
438 	wmi_buf_t buf;
439 	int32_t len = sizeof(*cmd);
440 
441 	WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
442 	buf = wmi_buf_alloc(wmi_handle, len);
443 	if (!buf) {
444 		return QDF_STATUS_E_NOMEM;
445 	}
446 	cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *)
447 		wmi_buf_data(buf);
448 	WMITLV_SET_HDR(&cmd->tlv_header,
449 	WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param,
450 		  WMITLV_GET_STRUCT_TLVLEN
451 		  (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param));
452 	cmd->vdev_id = vdev_id;
453 	cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE;
454 	wmi_mtrace(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID, cmd->vdev_id, 0);
455 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
456 				 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) {
457 		WMI_LOGP("%s: Failed to send NAT keepalive enable command",
458 			 __func__);
459 		wmi_buf_free(buf);
460 		return QDF_STATUS_E_FAILURE;
461 	}
462 
463 	return 0;
464 }
465 
466 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle,
467 				struct wlm_latency_level_param *params)
468 {
469 	wmi_wlm_config_cmd_fixed_param *cmd;
470 	wmi_buf_t buf;
471 	uint32_t len = sizeof(*cmd);
472 	static uint32_t ll[4] = {100, 60, 40, 20};
473 
474 	buf = wmi_buf_alloc(wmi_handle, len);
475 	if (!buf) {
476 		return QDF_STATUS_E_NOMEM;
477 	}
478 	cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf);
479 	WMITLV_SET_HDR(&cmd->tlv_header,
480 		       WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param,
481 		       WMITLV_GET_STRUCT_TLVLEN
482 		       (wmi_wlm_config_cmd_fixed_param));
483 	cmd->vdev_id = params->vdev_id;
484 	cmd->latency_level = params->wlm_latency_level;
485 	cmd->ul_latency = ll[params->wlm_latency_level];
486 	cmd->dl_latency = ll[params->wlm_latency_level];
487 	cmd->flags = params->wlm_latency_flags;
488 	wmi_mtrace(WMI_WLM_CONFIG_CMDID, cmd->vdev_id, 0);
489 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
490 				 WMI_WLM_CONFIG_CMDID)) {
491 		WMI_LOGE("%s: Failed to send setting latency config command",
492 			 __func__);
493 		wmi_buf_free(buf);
494 		return QDF_STATUS_E_FAILURE;
495 	}
496 
497 	return 0;
498 }
499 
500 #ifdef FEATURE_WLAN_TDLS
501 /**
502  * tdls_get_wmi_offchannel_mode - Get WMI tdls off channel mode
503  * @tdls_sw_mode: tdls_sw_mode
504  *
505  * This function returns wmi tdls offchannel mode
506  *
507  * Return: enum value of wmi tdls offchannel mode
508  */
509 static uint8_t tdls_get_wmi_offchannel_mode(uint8_t tdls_sw_mode)
510 {
511 	uint8_t off_chan_mode;
512 
513 	switch (tdls_sw_mode) {
514 	case ENABLE_CHANSWITCH:
515 		off_chan_mode = WMI_TDLS_ENABLE_OFFCHANNEL;
516 		break;
517 
518 	case DISABLE_CHANSWITCH:
519 		off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL;
520 		break;
521 
522 	default:
523 		WMI_LOGD(FL("unknown tdls_sw_mode %d"), tdls_sw_mode);
524 		off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL;
525 	}
526 	return off_chan_mode;
527 }
528 
529 /**
530  * tdls_get_wmi_offchannel_bw - Get WMI tdls off channel Bandwidth
531  * @tdls_sw_mode: tdls_sw_mode
532  *
533  * This function returns wmi tdls offchannel bandwidth
534  *
535  * Return: TDLS offchannel bandwidth
536  */
537 static uint8_t tdls_get_wmi_offchannel_bw(uint16_t tdls_off_ch_bw_offset)
538 {
539 	uint8_t off_chan_bw;
540 
541 	switch (tdls_off_ch_bw_offset) {
542 	case BW20:
543 		off_chan_bw = WMI_TDLS_OFFCHAN_20MHZ;
544 		break;
545 	case BW40_LOW_PRIMARY:
546 	case BW40_HIGH_PRIMARY:
547 		off_chan_bw = WMI_TDLS_OFFCHAN_40MHZ;
548 		break;
549 	case BW80:
550 		off_chan_bw = WMI_TDLS_OFFCHAN_80MHZ;
551 		break;
552 	case BWALL:
553 		off_chan_bw = WMI_TDLS_OFFCHAN_160MHZ;
554 		break;
555 	default:
556 		WMI_LOGD(FL("unknown tdls offchannel bw offset %d"),
557 			 tdls_off_ch_bw_offset);
558 		off_chan_bw = WMI_TDLS_OFFCHAN_20MHZ;
559 	}
560 	return off_chan_bw;
561 }
562 
563 /**
564  * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode
565  * @wmi_handle: wmi handle
566  * @chan_switch_params: Pointer to tdls channel switch parameter structure
567  *
568  * This function sets tdls off channel mode
569  *
570  * Return: 0 on success; Negative errno otherwise
571  */
572 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle,
573 	      struct tdls_channel_switch_params *chan_switch_params)
574 {
575 	wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd;
576 	wmi_buf_t wmi_buf;
577 	u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param);
578 
579 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
580 	if (!wmi_buf) {
581 		return QDF_STATUS_E_FAILURE;
582 	}
583 	cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *)
584 		wmi_buf_data(wmi_buf);
585 	WMITLV_SET_HDR(&cmd->tlv_header,
586 		WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param,
587 		WMITLV_GET_STRUCT_TLVLEN(
588 			wmi_tdls_set_offchan_mode_cmd_fixed_param));
589 
590 	WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr,
591 				&cmd->peer_macaddr);
592 	cmd->vdev_id = chan_switch_params->vdev_id;
593 	cmd->offchan_mode =
594 		tdls_get_wmi_offchannel_mode(chan_switch_params->tdls_sw_mode);
595 	cmd->is_peer_responder = chan_switch_params->is_responder;
596 	cmd->offchan_freq = chan_switch_params->tdls_off_chan_freq;
597 	cmd->offchan_num = chan_switch_params->tdls_off_ch;
598 	cmd->offchan_bw_bitmap =
599 		tdls_get_wmi_offchannel_bw(
600 			chan_switch_params->tdls_off_ch_bw_offset);
601 	cmd->offchan_oper_class = chan_switch_params->oper_class;
602 
603 	WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"),
604 		 cmd->peer_macaddr.mac_addr31to0,
605 		 cmd->peer_macaddr.mac_addr47to32);
606 
607 	WMI_LOGD(FL(
608 		 "vdev_id: %d, off channel mode: %d, off channel Num: %d, "
609 		 "off channel frequency: %u off channel offset: 0x%x, "
610 		 " is_peer_responder: %d, operating class: %d"),
611 		 cmd->vdev_id,
612 		 cmd->offchan_mode,
613 		 cmd->offchan_num,
614 		 cmd->offchan_freq,
615 		 cmd->offchan_bw_bitmap,
616 		 cmd->is_peer_responder,
617 		 cmd->offchan_oper_class);
618 
619 	wmi_mtrace(WMI_TDLS_SET_OFFCHAN_MODE_CMDID, cmd->vdev_id, 0);
620 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
621 		WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) {
622 		WMI_LOGP(FL("failed to send tdls off chan command"));
623 		wmi_buf_free(wmi_buf);
624 		return QDF_STATUS_E_FAILURE;
625 	}
626 
627 	return QDF_STATUS_SUCCESS;
628 }
629 
630 /**
631  * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev
632  * @wmi_handle: wmi handle
633  * @pwmaTdlsparams: TDLS params
634  *
635  * Return: 0 for success or error code
636  */
637 static QDF_STATUS
638 send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle,
639 				  struct tdls_info *tdls_param,
640 				  enum wmi_tdls_state tdls_state)
641 {
642 	wmi_tdls_set_state_cmd_fixed_param *cmd;
643 	wmi_buf_t wmi_buf;
644 
645 	uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param);
646 
647 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
648 	if (!wmi_buf) {
649 		return QDF_STATUS_E_FAILURE;
650 	}
651 	cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf);
652 	WMITLV_SET_HDR(&cmd->tlv_header,
653 		  WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param,
654 		  WMITLV_GET_STRUCT_TLVLEN
655 			(wmi_tdls_set_state_cmd_fixed_param));
656 	cmd->vdev_id = tdls_param->vdev_id;
657 	cmd->state = (A_UINT32)tdls_state;
658 	cmd->notification_interval_ms = tdls_param->notification_interval_ms;
659 	cmd->tx_discovery_threshold = tdls_param->tx_discovery_threshold;
660 	cmd->tx_teardown_threshold = tdls_param->tx_teardown_threshold;
661 	cmd->rssi_teardown_threshold = tdls_param->rssi_teardown_threshold;
662 	cmd->rssi_delta = tdls_param->rssi_delta;
663 	cmd->tdls_options = tdls_param->tdls_options;
664 	cmd->tdls_peer_traffic_ind_window = tdls_param->peer_traffic_ind_window;
665 	cmd->tdls_peer_traffic_response_timeout_ms =
666 		tdls_param->peer_traffic_response_timeout;
667 	cmd->tdls_puapsd_mask = tdls_param->puapsd_mask;
668 	cmd->tdls_puapsd_inactivity_time_ms =
669 		tdls_param->puapsd_inactivity_time;
670 	cmd->tdls_puapsd_rx_frame_threshold =
671 		tdls_param->puapsd_rx_frame_threshold;
672 	cmd->teardown_notification_ms =
673 		tdls_param->teardown_notification_ms;
674 	cmd->tdls_peer_kickout_threshold =
675 		tdls_param->tdls_peer_kickout_threshold;
676 	cmd->tdls_discovery_wake_timeout =
677 		tdls_param->tdls_discovery_wake_timeout;
678 
679 	WMI_LOGD("%s: vdev %d tdls_state: %d, state: %d, "
680 		 "notification_interval_ms: %d, "
681 		 "tx_discovery_threshold: %d, "
682 		 "tx_teardown_threshold: %d, "
683 		 "rssi_teardown_threshold: %d, "
684 		 "rssi_delta: %d, "
685 		 "tdls_options: 0x%x, "
686 		 "tdls_peer_traffic_ind_window: %d, "
687 		 "tdls_peer_traffic_response_timeout: %d, "
688 		 "tdls_puapsd_mask: 0x%x, "
689 		 "tdls_puapsd_inactivity_time: %d, "
690 		 "tdls_puapsd_rx_frame_threshold: %d, "
691 		 "teardown_notification_ms: %d, "
692 		 "tdls_peer_kickout_threshold: %d, "
693 		 "tdls_discovery_wake_timeout: %d",
694 		 __func__,tdls_param->vdev_id, tdls_state, cmd->state,
695 		 cmd->notification_interval_ms,
696 		 cmd->tx_discovery_threshold,
697 		 cmd->tx_teardown_threshold,
698 		 cmd->rssi_teardown_threshold,
699 		 cmd->rssi_delta,
700 		 cmd->tdls_options,
701 		 cmd->tdls_peer_traffic_ind_window,
702 		 cmd->tdls_peer_traffic_response_timeout_ms,
703 		 cmd->tdls_puapsd_mask,
704 		 cmd->tdls_puapsd_inactivity_time_ms,
705 		 cmd->tdls_puapsd_rx_frame_threshold,
706 		 cmd->teardown_notification_ms,
707 		 cmd->tdls_peer_kickout_threshold,
708 		 cmd->tdls_discovery_wake_timeout);
709 
710 	wmi_mtrace(WMI_TDLS_SET_STATE_CMDID, cmd->vdev_id, 0);
711 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
712 				 WMI_TDLS_SET_STATE_CMDID)) {
713 		WMI_LOGP("%s: failed to send tdls set state command", __func__);
714 		wmi_buf_free(wmi_buf);
715 		return QDF_STATUS_E_FAILURE;
716 	}
717 
718 	return QDF_STATUS_SUCCESS;
719 }
720 
721 /**
722  * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state
723  * @wmi_handle: wmi handle
724  * @peer_state: TDLS peer state params
725  *
726  * Return: QDF_STATUS_SUCCESS for success or error code
727  */
728 static QDF_STATUS
729 send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle,
730 				    struct tdls_peer_update_state *peer_state,
731 				    uint32_t *ch_mhz)
732 {
733 	struct tdls_peer_params *in_peer_cap;
734 	struct tdls_ch_params *in_chan_info;
735 	wmi_tdls_peer_update_cmd_fixed_param *cmd;
736 	wmi_tdls_peer_capabilities *peer_cap;
737 	wmi_channel *chan_info;
738 	wmi_buf_t wmi_buf;
739 	uint8_t *buf_ptr;
740 	uint32_t i;
741 	int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) +
742 		      sizeof(wmi_tdls_peer_capabilities);
743 
744 	in_peer_cap = &peer_state->peer_cap;
745 	len += WMI_TLV_HDR_SIZE +
746 	       sizeof(wmi_channel) * in_peer_cap->peer_chanlen;
747 
748 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
749 	if (!wmi_buf) {
750 		return QDF_STATUS_E_FAILURE;
751 	}
752 
753 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
754 	cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr;
755 	WMITLV_SET_HDR(&cmd->tlv_header,
756 		       WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param,
757 		       WMITLV_GET_STRUCT_TLVLEN
758 			       (wmi_tdls_peer_update_cmd_fixed_param));
759 
760 	cmd->vdev_id = peer_state->vdev_id;
761 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_state->peer_macaddr,
762 				   &cmd->peer_macaddr);
763 
764 	cmd->peer_state = peer_state->peer_state;
765 
766 	WMI_LOGD("%s: vdev_id: %d, peermac: %pM, "
767 		 "peer_macaddr.mac_addr31to0: 0x%x, "
768 		 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d",
769 		 __func__, cmd->vdev_id, peer_state->peer_macaddr,
770 		 cmd->peer_macaddr.mac_addr31to0,
771 		 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state);
772 
773 	buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param);
774 	peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr;
775 	WMITLV_SET_HDR(&peer_cap->tlv_header,
776 		       WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities,
777 		       WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities));
778 
779 	if ((in_peer_cap->peer_uapsd_queue & 0x08) >> 3)
780 		WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap);
781 	if ((in_peer_cap->peer_uapsd_queue & 0x04) >> 2)
782 		WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap);
783 	if ((in_peer_cap->peer_uapsd_queue & 0x02) >> 1)
784 		WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap);
785 	if (in_peer_cap->peer_uapsd_queue & 0x01)
786 		WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap);
787 
788 	/* Ack and More Data Ack are sent as 0, so no need to set
789 	 * but fill SP
790 	 */
791 	WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap, in_peer_cap->peer_max_sp);
792 
793 	peer_cap->buff_sta_support = in_peer_cap->peer_buff_sta_support;
794 	peer_cap->off_chan_support = in_peer_cap->peer_off_chan_support;
795 	peer_cap->peer_curr_operclass = in_peer_cap->peer_curr_operclass;
796 	/* self curr operclass is not being used and so pass op class for
797 	 * preferred off chan in it.
798 	 */
799 	peer_cap->self_curr_operclass = in_peer_cap->opclass_for_prefoffchan;
800 	peer_cap->peer_chan_len = in_peer_cap->peer_chanlen;
801 	peer_cap->peer_operclass_len = in_peer_cap->peer_oper_classlen;
802 
803 	WMI_LOGD("peer_operclass_len: %d", peer_cap->peer_operclass_len);
804 	for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) {
805 		peer_cap->peer_operclass[i] = in_peer_cap->peer_oper_class[i];
806 	}
807 	qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
808 			   (uint8_t *)peer_cap->peer_operclass,
809 			   WMI_TDLS_MAX_SUPP_OPER_CLASSES);
810 
811 	peer_cap->is_peer_responder = in_peer_cap->is_peer_responder;
812 	peer_cap->pref_offchan_freq = in_peer_cap->pref_offchan_freq;
813 	peer_cap->pref_offchan_num = in_peer_cap->pref_off_channum;
814 	peer_cap->pref_offchan_bw = in_peer_cap->pref_off_chan_bandwidth;
815 
816 	WMI_LOGD
817 		("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, "
818 		 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: "
819 		 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:"
820 		 " %d, pref_offchan_bw: %d, pref_offchan_freq: %u",
821 		 __func__, peer_cap->peer_qos, peer_cap->buff_sta_support,
822 		 peer_cap->off_chan_support, peer_cap->peer_curr_operclass,
823 		 peer_cap->self_curr_operclass, peer_cap->peer_chan_len,
824 		 peer_cap->peer_operclass_len, peer_cap->is_peer_responder,
825 		 peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw,
826 		 peer_cap->pref_offchan_freq);
827 
828 	/* next fill variable size array of peer chan info */
829 	buf_ptr += sizeof(wmi_tdls_peer_capabilities);
830 	WMITLV_SET_HDR(buf_ptr,
831 		       WMITLV_TAG_ARRAY_STRUC,
832 		       sizeof(wmi_channel) *
833 		       in_peer_cap->peer_chanlen);
834 
835 	chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE);
836 	in_chan_info = in_peer_cap->peer_chan;
837 
838 	for (i = 0; i < in_peer_cap->peer_chanlen; ++i) {
839 		WMITLV_SET_HDR(&chan_info->tlv_header,
840 			       WMITLV_TAG_STRUC_wmi_channel,
841 			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
842 		chan_info->mhz = ch_mhz[i];
843 		chan_info->band_center_freq1 = chan_info->mhz;
844 		chan_info->band_center_freq2 = 0;
845 
846 		WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz);
847 
848 		if (in_chan_info->dfs_set) {
849 			WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE);
850 			WMI_LOGI("chan[%d] DFS[%d]",
851 				 in_chan_info->chan_id,
852 				 in_chan_info->dfs_set);
853 		}
854 
855 		if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ)
856 			WMI_SET_CHANNEL_MODE(chan_info, MODE_11G);
857 		else
858 			WMI_SET_CHANNEL_MODE(chan_info, MODE_11A);
859 
860 		WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, in_chan_info->pwr);
861 		WMI_SET_CHANNEL_REG_POWER(chan_info, in_chan_info->pwr);
862 		WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz,
863 			 in_chan_info->pwr);
864 
865 		chan_info++;
866 		in_chan_info++;
867 	}
868 
869 	wmi_mtrace(WMI_TDLS_PEER_UPDATE_CMDID, cmd->vdev_id, 0);
870 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
871 				 WMI_TDLS_PEER_UPDATE_CMDID)) {
872 		WMI_LOGE("%s: failed to send tdls peer update state command",
873 			 __func__);
874 		wmi_buf_free(wmi_buf);
875 		return QDF_STATUS_E_FAILURE;
876 	}
877 
878 	return QDF_STATUS_SUCCESS;
879 }
880 
881 /**
882  * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event
883  * @wmi_handle: wmi handle
884  * @param evt_buf: pointer to event buffer
885  * @param param: Pointer to hold vdev tdls param
886  *
887  * Return: QDF_STATUS_SUCCESS for success or error code
888  */
889 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle,
890 	void *evt_buf, struct tdls_event_info *param)
891 {
892 	WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf;
893 	wmi_tdls_peer_event_fixed_param *evt;
894 
895 	param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf;
896 	if (!param_buf) {
897 		WMI_LOGE("%s: NULL param_buf", __func__);
898 		return QDF_STATUS_E_NULL_VALUE;
899 	}
900 
901 	evt = param_buf->fixed_param;
902 
903 	qdf_mem_zero(param, sizeof(*param));
904 
905 	param->vdev_id = evt->vdev_id;
906 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr,
907 				   param->peermac.bytes);
908 	switch (evt->peer_status) {
909 	case WMI_TDLS_SHOULD_DISCOVER:
910 		param->message_type = TDLS_SHOULD_DISCOVER;
911 		break;
912 	case WMI_TDLS_SHOULD_TEARDOWN:
913 		param->message_type = TDLS_SHOULD_TEARDOWN;
914 		break;
915 	case WMI_TDLS_PEER_DISCONNECTED:
916 		param->message_type = TDLS_PEER_DISCONNECTED;
917 		break;
918 	case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION:
919 		param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY;
920 		break;
921 	default:
922 		WMI_LOGE("%s: Discarding unknown tdls event %d from target",
923 			 __func__, evt->peer_status);
924 		return QDF_STATUS_E_INVAL;
925 	};
926 
927 	switch (evt->peer_reason) {
928 	case WMI_TDLS_TEARDOWN_REASON_TX:
929 		param->peer_reason = TDLS_TEARDOWN_TX;
930 		break;
931 	case WMI_TDLS_TEARDOWN_REASON_RSSI:
932 		param->peer_reason = TDLS_TEARDOWN_RSSI;
933 		break;
934 	case WMI_TDLS_TEARDOWN_REASON_SCAN:
935 		param->peer_reason = TDLS_TEARDOWN_SCAN;
936 		break;
937 	case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE:
938 		param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE;
939 		break;
940 	case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
941 		param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT;
942 		break;
943 	case WMI_TDLS_TEARDOWN_REASON_BAD_PTR:
944 		param->peer_reason = TDLS_TEARDOWN_BAD_PTR;
945 		break;
946 	case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
947 		param->peer_reason = TDLS_TEARDOWN_NO_RSP;
948 		break;
949 	case WMI_TDLS_ENTER_BUF_STA:
950 		param->peer_reason = TDLS_PEER_ENTER_BUF_STA;
951 		break;
952 	case WMI_TDLS_EXIT_BUF_STA:
953 		param->peer_reason = TDLS_PEER_EXIT_BUF_STA;
954 		break;
955 	case WMI_TDLS_ENTER_BT_BUSY_MODE:
956 		param->peer_reason = TDLS_ENTER_BT_BUSY;
957 		break;
958 	case WMI_TDLS_EXIT_BT_BUSY_MODE:
959 		param->peer_reason = TDLS_EXIT_BT_BUSY;
960 		break;
961 	case WMI_TDLS_SCAN_STARTED_EVENT:
962 		param->peer_reason = TDLS_SCAN_STARTED;
963 		break;
964 	case WMI_TDLS_SCAN_COMPLETED_EVENT:
965 		param->peer_reason = TDLS_SCAN_COMPLETED;
966 		break;
967 
968 	default:
969 		WMI_LOGE("%s: unknown reason %d in tdls event %d from target",
970 			 __func__, evt->peer_reason, evt->peer_status);
971 		return QDF_STATUS_E_INVAL;
972 	};
973 
974 	WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d",
975 		 __func__, param->peermac.bytes, param->message_type,
976 		 param->peer_reason, param->vdev_id);
977 
978 	return QDF_STATUS_SUCCESS;
979 }
980 
981 void wmi_tdls_attach_tlv(struct wmi_unified *wmi_handle)
982 {
983 	struct wmi_ops *ops = wmi_handle->ops;
984 
985 	ops->send_set_tdls_offchan_mode_cmd =
986 		send_set_tdls_offchan_mode_cmd_tlv;
987 	ops->send_update_fw_tdls_state_cmd =
988 		send_update_fw_tdls_state_cmd_tlv;
989 	ops->send_update_tdls_peer_state_cmd =
990 		send_update_tdls_peer_state_cmd_tlv;
991 	ops->extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv;
992 }
993 #endif /* FEATURE_WLAN_TDLS */
994 
995 /*
996  * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware
997  * @wmi_handle:    Pointer to WMi handle
998  * @ie_data:       Pointer for ie data
999  *
1000  * This function sends IE information to firmware
1001  *
1002  * Return: QDF_STATUS_SUCCESS for success otherwise failure
1003  *
1004  */
1005 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle,
1006 				   struct vdev_ie_info_param *ie_info)
1007 {
1008 	wmi_vdev_set_ie_cmd_fixed_param *cmd;
1009 	wmi_buf_t buf;
1010 	uint8_t *buf_ptr;
1011 	uint32_t len, ie_len_aligned;
1012 	QDF_STATUS ret;
1013 
1014 	ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t));
1015 	/* Allocate memory for the WMI command */
1016 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned;
1017 
1018 	buf = wmi_buf_alloc(wmi_handle, len);
1019 	if (!buf) {
1020 		return QDF_STATUS_E_NOMEM;
1021 	}
1022 
1023 	buf_ptr = wmi_buf_data(buf);
1024 	qdf_mem_zero(buf_ptr, len);
1025 
1026 	/* Populate the WMI command */
1027 	cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr;
1028 
1029 	WMITLV_SET_HDR(&cmd->tlv_header,
1030 		       WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param,
1031 		       WMITLV_GET_STRUCT_TLVLEN(
1032 				wmi_vdev_set_ie_cmd_fixed_param));
1033 	cmd->vdev_id = ie_info->vdev_id;
1034 	cmd->ie_id = ie_info->ie_id;
1035 	cmd->ie_len = ie_info->length;
1036 	cmd->band = ie_info->band;
1037 
1038 	WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id,
1039 		    ie_info->length, ie_info->vdev_id);
1040 
1041 	buf_ptr += sizeof(*cmd);
1042 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
1043 	buf_ptr += WMI_TLV_HDR_SIZE;
1044 
1045 	qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len);
1046 
1047 	wmi_mtrace(WMI_VDEV_SET_IE_CMDID, cmd->vdev_id, 0);
1048 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1049 				   WMI_VDEV_SET_IE_CMDID);
1050 	if (QDF_IS_STATUS_ERROR(ret)) {
1051 		WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret);
1052 		wmi_buf_free(buf);
1053 	}
1054 
1055 	return ret;
1056 }
1057 
1058 /**
1059  * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw
1060  * @wmi_handle: wmi handle
1061  * @custom_addr: base mac address
1062  *
1063  * Return: QDF_STATUS_SUCCESS for success or error code
1064  */
1065 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle,
1066 					 uint8_t *custom_addr)
1067 {
1068 	wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd;
1069 	wmi_buf_t buf;
1070 	int err;
1071 
1072 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
1073 	if (!buf) {
1074 		return QDF_STATUS_E_NOMEM;
1075 	}
1076 
1077 	cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf);
1078 	qdf_mem_zero(cmd, sizeof(*cmd));
1079 
1080 	WMITLV_SET_HDR(&cmd->tlv_header,
1081 		WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param,
1082 		       WMITLV_GET_STRUCT_TLVLEN
1083 			       (wmi_pdev_set_base_macaddr_cmd_fixed_param));
1084 	WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr);
1085 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
1086 							wmi_handle,
1087 							WMI_HOST_PDEV_ID_SOC);
1088 	wmi_mtrace(WMI_PDEV_SET_BASE_MACADDR_CMDID, NO_SESSION, 0);
1089 	err = wmi_unified_cmd_send(wmi_handle, buf,
1090 				   sizeof(*cmd),
1091 				   WMI_PDEV_SET_BASE_MACADDR_CMDID);
1092 	if (err) {
1093 		WMI_LOGE("Failed to send set_base_macaddr cmd");
1094 		wmi_buf_free(buf);
1095 		return QDF_STATUS_E_FAILURE;
1096 	}
1097 
1098 	return 0;
1099 }
1100 
1101 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(FEATURE_BLACKLIST_MGR)
1102 
1103 static WMI_BSSID_DISALLOW_LIST_TYPE
1104 wmi_get_wmi_reject_ap_type(enum blm_reject_ap_type reject_ap_type)
1105 {
1106 	switch (reject_ap_type) {
1107 	case USERSPACE_AVOID_TYPE:
1108 		return WMI_BSSID_DISALLOW_USER_SPACE_AVOID_LIST;
1109 	case DRIVER_AVOID_TYPE:
1110 		return WMI_BSSID_DISALLOW_DRIVER_AVOID_LIST;
1111 	case USERSPACE_BLACKLIST_TYPE:
1112 		return WMI_BSSID_DISALLOW_USER_SPACE_BLACK_LIST;
1113 	case DRIVER_BLACKLIST_TYPE:
1114 		return WMI_BSSID_DISALLOW_DRIVER_BLACK_LIST;
1115 	case DRIVER_RSSI_REJECT_TYPE:
1116 		return WMI_BSSID_DISALLOW_RSSI_REJECT_LIST;
1117 	default:
1118 		return WMI_BSSID_DISALLOW_DRIVER_AVOID_LIST;
1119 	}
1120 }
1121 
1122 static WMI_BLACKLIST_REASON_ID
1123 wmi_get_reject_reason(enum blm_reject_ap_reason reject_reason)
1124 {
1125 	switch(reject_reason) {
1126 	case REASON_NUD_FAILURE:
1127 		return WMI_BL_REASON_NUD_FAILURE;
1128 	case REASON_STA_KICKOUT:
1129 		return WMI_BL_REASON_STA_KICKOUT;
1130 	case REASON_ROAM_HO_FAILURE:
1131 		return WMI_BL_REASON_ROAM_HO_FAILURE;
1132 	case REASON_ASSOC_REJECT_POOR_RSSI:
1133 		return WMI_BL_REASON_ASSOC_REJECT_POOR_RSSI;
1134 	case REASON_ASSOC_REJECT_OCE:
1135 		return WMI_BL_REASON_ASSOC_REJECT_OCE;
1136 	case REASON_USERSPACE_BL:
1137 		return WMI_BL_REASON_USERSPACE_BL;
1138 	case REASON_USERSPACE_AVOID_LIST:
1139 		return WMI_BL_REASON_USERSPACE_AVOID_LIST;
1140 	case REASON_BTM_DISASSOC_IMMINENT:
1141 		return WMI_BL_REASON_BTM_DIASSOC_IMMINENT;
1142 	case REASON_BTM_BSS_TERMINATION:
1143 		return WMI_BL_REASON_BTM_BSS_TERMINATION;
1144 	case REASON_BTM_MBO_RETRY:
1145 		return WMI_BL_REASON_BTM_MBO_RETRY;
1146 	case REASON_REASSOC_RSSI_REJECT:
1147 		return WMI_BL_REASON_REASSOC_RSSI_REJECT;
1148 	case REASON_REASSOC_NO_MORE_STAS:
1149 		return WMI_BL_REASON_REASSOC_NO_MORE_STAS;
1150 	default:
1151 		return 0;
1152 	}
1153 }
1154 
1155 static QDF_STATUS
1156 send_reject_ap_list_cmd_tlv(wmi_unified_t wmi_handle,
1157 			    struct reject_ap_params *reject_params)
1158 {
1159 	wmi_buf_t buf;
1160 	QDF_STATUS status;
1161 	uint32_t len, list_tlv_len;
1162 	int i;
1163 	uint8_t *buf_ptr;
1164 	wmi_pdev_dsm_filter_fixed_param *chan_list_fp;
1165 	wmi_pdev_bssid_disallow_list_config_param *chan_list;
1166 	struct reject_ap_config_params *reject_list = reject_params->bssid_list;
1167 	uint8_t num_of_reject_bssid = reject_params->num_of_reject_bssid;
1168 
1169 	list_tlv_len = sizeof(*chan_list) * num_of_reject_bssid;
1170 
1171 	len = sizeof(*chan_list_fp) + list_tlv_len + WMI_TLV_HDR_SIZE;
1172 	buf = wmi_buf_alloc(wmi_handle, len);
1173 	if (!buf)
1174 		return QDF_STATUS_E_NOMEM;
1175 
1176 	WMI_LOGD("num of reject BSSIDs %d", num_of_reject_bssid);
1177 
1178 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
1179 	chan_list_fp = (wmi_pdev_dsm_filter_fixed_param *)buf_ptr;
1180 	WMITLV_SET_HDR(&chan_list_fp->tlv_header,
1181 		       WMITLV_TAG_STRUC_wmi_pdev_dsm_filter_fixed_param,
1182 		       WMITLV_GET_STRUCT_TLVLEN
1183 			       (wmi_pdev_dsm_filter_fixed_param));
1184 
1185 	buf_ptr += sizeof(wmi_pdev_dsm_filter_fixed_param);
1186 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, list_tlv_len);
1187 
1188 	buf_ptr += WMI_TLV_HDR_SIZE;
1189 	chan_list = (wmi_pdev_bssid_disallow_list_config_param *)buf_ptr;
1190 	for (i = 0; i < num_of_reject_bssid; i++) {
1191 
1192 		WMITLV_SET_HDR(&chan_list->tlv_header,
1193 		     WMITLV_TAG_STRUC_wmi_pdev_bssid_disallow_list_config_param,
1194 			       WMITLV_GET_STRUCT_TLVLEN
1195 				  (wmi_pdev_bssid_disallow_list_config_param));
1196 		WMI_CHAR_ARRAY_TO_MAC_ADDR(reject_list[i].bssid.bytes,
1197 					   &chan_list->bssid);
1198 		chan_list->bssid_type =
1199 		    wmi_get_wmi_reject_ap_type(reject_list[i].reject_ap_type);
1200 		chan_list->expected_rssi = reject_list[i].expected_rssi;
1201 		chan_list->remaining_disallow_duration =
1202 					reject_list[i].reject_duration;
1203 		chan_list->reason =
1204 			wmi_get_reject_reason(reject_list[i].reject_reason);
1205 		chan_list->original_timeout = reject_list[i].original_timeout;
1206 		chan_list->timestamp = reject_list[i].received_time;
1207 		chan_list->source = reject_list[i].source;
1208 		chan_list++;
1209 	}
1210 
1211 	wmi_mtrace(WMI_PDEV_DSM_FILTER_CMDID, NO_SESSION, 0);
1212 	status = wmi_unified_cmd_send(wmi_handle, buf,
1213 				      len, WMI_PDEV_DSM_FILTER_CMDID);
1214 	if (QDF_IS_STATUS_ERROR(status)) {
1215 		WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_DSM_FILTER_CMDID returned Error %d",
1216 			 status);
1217 		goto error;
1218 	}
1219 
1220 	return QDF_STATUS_SUCCESS;
1221 error:
1222 	wmi_buf_free(buf);
1223 	return status;
1224 }
1225 
1226 void wmi_blacklist_mgr_attach_tlv(struct wmi_unified *wmi_handle)
1227 {
1228 	struct wmi_ops *ops = wmi_handle->ops;
1229 
1230 	ops->send_reject_ap_list_cmd = send_reject_ap_list_cmd_tlv;
1231 }
1232 #endif
1233 
1234 /**
1235  * send_sar_limit_cmd_tlv() - send sar limit cmd to fw
1236  * @wmi_handle: wmi handle
1237  * @params: sar limit params
1238  *
1239  * Return: QDF_STATUS_SUCCESS for success or error code
1240  */
1241 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle,
1242 		struct sar_limit_cmd_params *sar_limit_params)
1243 {
1244 	wmi_buf_t buf;
1245 	QDF_STATUS qdf_status;
1246 	wmi_sar_limits_cmd_fixed_param *cmd;
1247 	int i;
1248 	uint8_t *buf_ptr;
1249 	wmi_sar_limit_cmd_row *wmi_sar_rows_list;
1250 	struct sar_limit_cmd_row *sar_rows_list;
1251 	uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
1252 
1253 	len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows;
1254 	buf = wmi_buf_alloc(wmi_handle, len);
1255 	if (!buf) {
1256 		qdf_status = QDF_STATUS_E_NOMEM;
1257 		goto end;
1258 	}
1259 
1260 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
1261 	cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr;
1262 	WMITLV_SET_HDR(&cmd->tlv_header,
1263 		       WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param,
1264 		       WMITLV_GET_STRUCT_TLVLEN
1265 				(wmi_sar_limits_cmd_fixed_param));
1266 	cmd->sar_enable = sar_limit_params->sar_enable;
1267 	cmd->commit_limits = sar_limit_params->commit_limits;
1268 	cmd->num_limit_rows = sar_limit_params->num_limit_rows;
1269 
1270 	WMI_LOGD("no of sar rows = %d, len = %d",
1271 		 sar_limit_params->num_limit_rows, len);
1272 	buf_ptr += sizeof(*cmd);
1273 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1274 		       sizeof(wmi_sar_limit_cmd_row) *
1275 			      sar_limit_params->num_limit_rows);
1276 	if (cmd->num_limit_rows == 0)
1277 		goto send_sar_limits;
1278 
1279 	wmi_sar_rows_list = (wmi_sar_limit_cmd_row *)
1280 				(buf_ptr + WMI_TLV_HDR_SIZE);
1281 	sar_rows_list = sar_limit_params->sar_limit_row_list;
1282 
1283 	for (i = 0; i < sar_limit_params->num_limit_rows; i++) {
1284 		WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header,
1285 			       WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row,
1286 			       WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row));
1287 		wmi_sar_rows_list->band_id = sar_rows_list->band_id;
1288 		wmi_sar_rows_list->chain_id = sar_rows_list->chain_id;
1289 		wmi_sar_rows_list->mod_id = sar_rows_list->mod_id;
1290 		wmi_sar_rows_list->limit_value = sar_rows_list->limit_value;
1291 		wmi_sar_rows_list->validity_bitmap =
1292 						sar_rows_list->validity_bitmap;
1293 		WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d",
1294 			 i, wmi_sar_rows_list->band_id,
1295 			 wmi_sar_rows_list->chain_id,
1296 			 wmi_sar_rows_list->mod_id,
1297 			 wmi_sar_rows_list->limit_value,
1298 			 wmi_sar_rows_list->validity_bitmap);
1299 		sar_rows_list++;
1300 		wmi_sar_rows_list++;
1301 	}
1302 send_sar_limits:
1303 	wmi_mtrace(WMI_SAR_LIMITS_CMDID, NO_SESSION, 0);
1304 	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
1305 					  WMI_SAR_LIMITS_CMDID);
1306 
1307 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
1308 		WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID");
1309 		wmi_buf_free(buf);
1310 	}
1311 
1312 end:
1313 	return qdf_status;
1314 }
1315 
1316 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle)
1317 {
1318 	wmi_sar_get_limits_cmd_fixed_param *cmd;
1319 	wmi_buf_t wmi_buf;
1320 	uint32_t len;
1321 	QDF_STATUS status;
1322 
1323 	WMI_LOGD(FL("Enter"));
1324 
1325 	len = sizeof(*cmd);
1326 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
1327 	if (!wmi_buf) {
1328 		return QDF_STATUS_E_NOMEM;
1329 	}
1330 
1331 	cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf);
1332 
1333 	WMITLV_SET_HDR(&cmd->tlv_header,
1334 		       WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param,
1335 		       WMITLV_GET_STRUCT_TLVLEN
1336 				(wmi_sar_get_limits_cmd_fixed_param));
1337 
1338 	cmd->reserved = 0;
1339 
1340 	wmi_mtrace(WMI_SAR_GET_LIMITS_CMDID, NO_SESSION, 0);
1341 	status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
1342 				      WMI_SAR_GET_LIMITS_CMDID);
1343 	if (QDF_IS_STATUS_ERROR(status)) {
1344 		WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status);
1345 		wmi_buf_free(wmi_buf);
1346 	}
1347 
1348 	WMI_LOGD(FL("Exit"));
1349 
1350 	return status;
1351 }
1352 
1353 /**
1354  * wmi_sar2_result_string() - return string conversion of sar2 result
1355  * @result: sar2 result value
1356  *
1357  * This utility function helps log string conversion of sar2 result.
1358  *
1359  * Return: string conversion of sar 2 result, if match found;
1360  *	   "Unknown response" otherwise.
1361  */
1362 static const char *wmi_sar2_result_string(uint32_t result)
1363 {
1364 	switch (result) {
1365 	CASE_RETURN_STRING(WMI_SAR2_SUCCESS);
1366 	CASE_RETURN_STRING(WMI_SAR2_INVALID_ANTENNA_INDEX);
1367 	CASE_RETURN_STRING(WMI_SAR2_INVALID_TABLE_INDEX);
1368 	CASE_RETURN_STRING(WMI_SAR2_STATE_ERROR);
1369 	CASE_RETURN_STRING(WMI_SAR2_BDF_NO_TABLE);
1370 	default:
1371 		return "Unknown response";
1372 	}
1373 }
1374 
1375 /**
1376  * extract_sar2_result_event_tlv() -  process sar response event from FW.
1377  * @handle: wma handle
1378  * @event: event buffer
1379  * @len: buffer length
1380  *
1381  * Return: 0 for success or error code
1382  */
1383 static QDF_STATUS extract_sar2_result_event_tlv(void *handle,
1384 						uint8_t *event,
1385 						uint32_t len)
1386 {
1387 	wmi_sar2_result_event_fixed_param *sar2_fixed_param;
1388 
1389 	WMI_SAR2_RESULT_EVENTID_param_tlvs *param_buf =
1390 		(WMI_SAR2_RESULT_EVENTID_param_tlvs *)event;
1391 
1392 	if (!param_buf) {
1393 		WMI_LOGI("Invalid sar2 result event buffer");
1394 		return QDF_STATUS_E_INVAL;
1395 	}
1396 
1397 	sar2_fixed_param = param_buf->fixed_param;
1398 	if (!sar2_fixed_param) {
1399 		WMI_LOGI("Invalid sar2 result event fixed param buffer");
1400 		return QDF_STATUS_E_INVAL;
1401 	}
1402 
1403 	WMI_LOGI("SAR2 result: %s",
1404 		 wmi_sar2_result_string(sar2_fixed_param->result));
1405 
1406 	return QDF_STATUS_SUCCESS;
1407 }
1408 
1409 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle,
1410 					      uint8_t *evt_buf,
1411 					      struct sar_limit_event *event)
1412 {
1413 	wmi_sar_get_limits_event_fixed_param *fixed_param;
1414 	WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf;
1415 	wmi_sar_get_limit_event_row *row_in;
1416 	struct sar_limit_event_row *row_out;
1417 	uint32_t row;
1418 
1419 	if (!evt_buf) {
1420 		WMI_LOGE(FL("input event is NULL"));
1421 		return QDF_STATUS_E_INVAL;
1422 	}
1423 	if (!event) {
1424 		WMI_LOGE(FL("output event is NULL"));
1425 		return QDF_STATUS_E_INVAL;
1426 	}
1427 
1428 	param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf;
1429 
1430 	fixed_param = param_buf->fixed_param;
1431 	if (!fixed_param) {
1432 		WMI_LOGE(FL("Invalid fixed param"));
1433 		return QDF_STATUS_E_INVAL;
1434 	}
1435 
1436 	event->sar_enable = fixed_param->sar_enable;
1437 	event->num_limit_rows = fixed_param->num_limit_rows;
1438 
1439 	if (event->num_limit_rows > param_buf->num_sar_get_limits) {
1440 		WMI_LOGE(FL("Num rows %d exceeds sar_get_limits rows len %d"),
1441 			 event->num_limit_rows, param_buf->num_sar_get_limits);
1442 		return QDF_STATUS_E_INVAL;
1443 	}
1444 
1445 	if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) {
1446 		QDF_ASSERT(0);
1447 		WMI_LOGE(FL("Num rows %d exceeds max of %d"),
1448 			 event->num_limit_rows,
1449 			 MAX_SAR_LIMIT_ROWS_SUPPORTED);
1450 		event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED;
1451 	}
1452 
1453 	row_in = param_buf->sar_get_limits;
1454 	if (!row_in) {
1455 		WMI_LOGD("sar_get_limits is NULL");
1456 	} else {
1457 		row_out = &event->sar_limit_row[0];
1458 		for (row = 0; row < event->num_limit_rows; row++) {
1459 			row_out->band_id = row_in->band_id;
1460 			row_out->chain_id = row_in->chain_id;
1461 			row_out->mod_id = row_in->mod_id;
1462 			row_out->limit_value = row_in->limit_value;
1463 			row_out++;
1464 			row_in++;
1465 		}
1466 	}
1467 
1468 	return QDF_STATUS_SUCCESS;
1469 }
1470 
1471 /**
1472  * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid
1473  * @wmi_handle: wmi handler
1474  * @pmk_info: pointer to PMK cache entry
1475  * @vdev_id: vdev id
1476  *
1477  * Return: 0 for success and non zero for failure
1478  */
1479 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle,
1480 				struct wmi_unified_pmk_cache *pmk_info)
1481 {
1482 	wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd;
1483 	wmi_buf_t buf;
1484 	QDF_STATUS status;
1485 	uint8_t *buf_ptr;
1486 	wmi_pmk_cache *pmksa;
1487 	uint32_t len = sizeof(*cmd);
1488 
1489 	if (!pmk_info)
1490 		return QDF_STATUS_E_INVAL;
1491 
1492 	if (!pmk_info->is_flush_all)
1493 		len += WMI_TLV_HDR_SIZE + sizeof(*pmksa);
1494 
1495 	buf = wmi_buf_alloc(wmi_handle, len);
1496 	if (!buf) {
1497 		return QDF_STATUS_E_NOMEM;
1498 	}
1499 
1500 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
1501 	cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr;
1502 
1503 	WMITLV_SET_HDR(&cmd->tlv_header,
1504 		 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param,
1505 		 WMITLV_GET_STRUCT_TLVLEN(
1506 			wmi_pdev_update_pmk_cache_cmd_fixed_param));
1507 
1508 	cmd->vdev_id = pmk_info->vdev_id;
1509 
1510 	/* If pmk_info->is_flush_all is true, this is a flush request */
1511 	if (pmk_info->is_flush_all) {
1512 		cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL;
1513 		cmd->num_cache = 0;
1514 		goto send_cmd;
1515 	}
1516 
1517 	cmd->num_cache = 1;
1518 	buf_ptr += sizeof(*cmd);
1519 
1520 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1521 			sizeof(*pmksa));
1522 	buf_ptr += WMI_TLV_HDR_SIZE;
1523 
1524 	pmksa = (wmi_pmk_cache *)buf_ptr;
1525 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache,
1526 			WMITLV_GET_STRUCT_TLVLEN
1527 				(wmi_pmk_cache));
1528 	pmksa->pmk_len = pmk_info->pmk_len;
1529 	qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len);
1530 	pmksa->pmkid_len = pmk_info->pmkid_len;
1531 	qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len);
1532 	qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr));
1533 	pmksa->ssid.ssid_len = pmk_info->ssid.length;
1534 	qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.ssid),
1535 		     pmksa->ssid.ssid_len);
1536 	pmksa->cache_id = pmk_info->cache_id;
1537 	pmksa->cat_flag = pmk_info->cat_flag;
1538 	pmksa->action_flag = pmk_info->action_flag;
1539 
1540 send_cmd:
1541 	wmi_mtrace(WMI_PDEV_UPDATE_PMK_CACHE_CMDID, cmd->vdev_id, 0);
1542 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
1543 				      WMI_PDEV_UPDATE_PMK_CACHE_CMDID);
1544 	if (status != QDF_STATUS_SUCCESS) {
1545 		WMI_LOGE("%s: failed to send set del pmkid cache command %d",
1546 			 __func__, status);
1547 		wmi_buf_free(buf);
1548 	}
1549 
1550 	return status;
1551 }
1552 
1553 /**
1554  * send_del_ts_cmd_tlv() - send DELTS request to fw
1555  * @wmi_handle: wmi handle
1556  * @msg: delts params
1557  *
1558  * Return: CDF status
1559  */
1560 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
1561 				uint8_t ac)
1562 {
1563 	wmi_vdev_wmm_delts_cmd_fixed_param *cmd;
1564 	wmi_buf_t buf;
1565 	int32_t len = sizeof(*cmd);
1566 
1567 	buf = wmi_buf_alloc(wmi_handle, len);
1568 	if (!buf) {
1569 		return QDF_STATUS_E_NOMEM;
1570 	}
1571 	cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf);
1572 	WMITLV_SET_HDR(&cmd->tlv_header,
1573 		       WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param,
1574 		       WMITLV_GET_STRUCT_TLVLEN
1575 			       (wmi_vdev_wmm_delts_cmd_fixed_param));
1576 	cmd->vdev_id = vdev_id;
1577 	cmd->ac = ac;
1578 
1579 	WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d",
1580 		 cmd->vdev_id, cmd->ac, __func__, __LINE__);
1581 	wmi_mtrace(WMI_VDEV_WMM_DELTS_CMDID, cmd->vdev_id, 0);
1582 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1583 				 WMI_VDEV_WMM_DELTS_CMDID)) {
1584 		WMI_LOGP("%s: Failed to send vdev DELTS command", __func__);
1585 		wmi_buf_free(buf);
1586 		return QDF_STATUS_E_FAILURE;
1587 	}
1588 
1589 	return QDF_STATUS_SUCCESS;
1590 }
1591 
1592 /**
1593  * send_aggr_qos_cmd_tlv() - send aggr qos request to fw
1594  * @wmi_handle: handle to wmi
1595  * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests.
1596  *
1597  * A function to handle WMI_AGGR_QOS_REQ. This will send out
1598  * ADD_TS requests to firmware in loop for all the ACs with
1599  * active flow.
1600  *
1601  * Return: CDF status
1602  */
1603 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle,
1604 		      struct aggr_add_ts_param *aggr_qos_rsp_msg)
1605 {
1606 	int i = 0;
1607 	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
1608 	wmi_buf_t buf;
1609 	int32_t len = sizeof(*cmd);
1610 
1611 	for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) {
1612 		/* if flow in this AC is active */
1613 		if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) {
1614 			/*
1615 			 * as per implementation of wma_add_ts_req() we
1616 			 * are not waiting any response from firmware so
1617 			 * apart from sending ADDTS to firmware just send
1618 			 * success to upper layers
1619 			 */
1620 			aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS;
1621 
1622 			buf = wmi_buf_alloc(wmi_handle, len);
1623 			if (!buf) {
1624 				return QDF_STATUS_E_NOMEM;
1625 			}
1626 			cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *)
1627 				wmi_buf_data(buf);
1628 			WMITLV_SET_HDR(&cmd->tlv_header,
1629 			       WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
1630 			       WMITLV_GET_STRUCT_TLVLEN
1631 				       (wmi_vdev_wmm_addts_cmd_fixed_param));
1632 			cmd->vdev_id = aggr_qos_rsp_msg->vdev_id;
1633 			cmd->ac =
1634 				WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo.
1635 					      traffic.userPrio);
1636 			cmd->medium_time_us =
1637 				aggr_qos_rsp_msg->tspec[i].mediumTime * 32;
1638 			cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO;
1639 			WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d",
1640 				 __func__, __LINE__, cmd->vdev_id, cmd->ac,
1641 				 cmd->medium_time_us, cmd->downgrade_type);
1642 			wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
1643 			if (wmi_unified_cmd_send(wmi_handle, buf, len,
1644 						 WMI_VDEV_WMM_ADDTS_CMDID)) {
1645 				WMI_LOGP("%s: Failed to send vdev ADDTS command",
1646 					 __func__);
1647 				aggr_qos_rsp_msg->status[i] =
1648 							QDF_STATUS_E_FAILURE;
1649 				wmi_buf_free(buf);
1650 				return QDF_STATUS_E_FAILURE;
1651 			}
1652 		}
1653 	}
1654 
1655 	return QDF_STATUS_SUCCESS;
1656 }
1657 
1658 /**
1659  * send_add_ts_cmd_tlv() - send ADDTS request to fw
1660  * @wmi_handle: wmi handle
1661  * @msg: ADDTS params
1662  *
1663  * Return: CDF status
1664  */
1665 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle,
1666 		 struct add_ts_param *msg)
1667 {
1668 	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
1669 	wmi_buf_t buf;
1670 	int32_t len = sizeof(*cmd);
1671 
1672 	msg->status = QDF_STATUS_SUCCESS;
1673 
1674 	buf = wmi_buf_alloc(wmi_handle, len);
1675 	if (!buf) {
1676 		return QDF_STATUS_E_NOMEM;
1677 	}
1678 	cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf);
1679 	WMITLV_SET_HDR(&cmd->tlv_header,
1680 		       WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
1681 		       WMITLV_GET_STRUCT_TLVLEN
1682 			       (wmi_vdev_wmm_addts_cmd_fixed_param));
1683 	cmd->vdev_id = msg->vdev_id;
1684 	cmd->ac = msg->tspec.tsinfo.traffic.userPrio;
1685 	cmd->medium_time_us = msg->tspec.mediumTime * 32;
1686 	cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP;
1687 	WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d",
1688 		 cmd->vdev_id, cmd->ac, cmd->medium_time_us,
1689 		 cmd->downgrade_type, __func__, __LINE__);
1690 	wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
1691 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1692 				 WMI_VDEV_WMM_ADDTS_CMDID)) {
1693 		WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__);
1694 		msg->status = QDF_STATUS_E_FAILURE;
1695 		wmi_buf_free(buf);
1696 		return QDF_STATUS_E_FAILURE;
1697 	}
1698 
1699 	return QDF_STATUS_SUCCESS;
1700 }
1701 
1702 /**
1703  * send_process_add_periodic_tx_ptrn_cmd_tlv() - add periodic tx pattern
1704  * @wmi_handle: wmi handle
1705  * @pattern: tx pattern params
1706  * @vdev_id: vdev id
1707  *
1708  * Return: QDF status
1709  */
1710 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(
1711 					wmi_unified_t wmi_handle,
1712 					struct periodic_tx_pattern *pattern,
1713 					uint8_t vdev_id)
1714 {
1715 	WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
1716 	wmi_buf_t wmi_buf;
1717 	uint32_t len;
1718 	uint8_t *buf_ptr;
1719 	uint32_t ptrn_len, ptrn_len_aligned;
1720 	int j;
1721 
1722 	ptrn_len = pattern->ucPtrnSize;
1723 	ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t));
1724 	len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) +
1725 	      WMI_TLV_HDR_SIZE + ptrn_len_aligned;
1726 
1727 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
1728 	if (!wmi_buf) {
1729 		return QDF_STATUS_E_NOMEM;
1730 	}
1731 
1732 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
1733 
1734 	cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr;
1735 	WMITLV_SET_HDR(&cmd->tlv_header,
1736 	       WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
1737 	       WMITLV_GET_STRUCT_TLVLEN
1738 	       (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
1739 
1740 	/* Pass the pattern id to delete for the corresponding vdev id */
1741 	cmd->vdev_id = vdev_id;
1742 	cmd->pattern_id = pattern->ucPtrnId;
1743 	cmd->timeout = pattern->usPtrnIntervalMs;
1744 	cmd->length = pattern->ucPtrnSize;
1745 
1746 	/* Pattern info */
1747 	buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
1748 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned);
1749 	buf_ptr += WMI_TLV_HDR_SIZE;
1750 	qdf_mem_copy(buf_ptr, pattern->ucPattern, ptrn_len);
1751 	for (j = 0; j < pattern->ucPtrnSize; j++)
1752 		WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff);
1753 
1754 	WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d",
1755 		 __func__, cmd->pattern_id, cmd->vdev_id);
1756 
1757 	wmi_mtrace(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
1758 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
1759 				 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
1760 		WMI_LOGE("%s: failed to add pattern set state command",
1761 			 __func__);
1762 		wmi_buf_free(wmi_buf);
1763 		return QDF_STATUS_E_FAILURE;
1764 	}
1765 	return QDF_STATUS_SUCCESS;
1766 }
1767 
1768 /**
1769  * send_process_del_periodic_tx_ptrn_cmd_tlv() - del periodic tx pattern
1770  * @wmi_handle: wmi handle
1771  * @vdev_id: vdev id
1772  * @pattern_id: pattern id
1773  *
1774  * Return: QDF status
1775  */
1776 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(
1777 						wmi_unified_t wmi_handle,
1778 						uint8_t vdev_id,
1779 						uint8_t pattern_id)
1780 {
1781 	WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
1782 	wmi_buf_t wmi_buf;
1783 	uint32_t len =
1784 		sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
1785 
1786 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
1787 	if (!wmi_buf) {
1788 		return QDF_STATUS_E_NOMEM;
1789 	}
1790 
1791 	cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)
1792 		wmi_buf_data(wmi_buf);
1793 	WMITLV_SET_HDR(&cmd->tlv_header,
1794 	       WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
1795 	       WMITLV_GET_STRUCT_TLVLEN
1796 	       (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
1797 
1798 	/* Pass the pattern id to delete for the corresponding vdev id */
1799 	cmd->vdev_id = vdev_id;
1800 	cmd->pattern_id = pattern_id;
1801 	WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d",
1802 		 __func__, cmd->pattern_id, cmd->vdev_id);
1803 
1804 	wmi_mtrace(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
1805 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
1806 				 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
1807 		WMI_LOGE("%s: failed to send del pattern command", __func__);
1808 		wmi_buf_free(wmi_buf);
1809 		return QDF_STATUS_E_FAILURE;
1810 	}
1811 	return QDF_STATUS_SUCCESS;
1812 }
1813 
1814 /**
1815  * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware
1816  * @wmi_handle: wmi handle
1817  * @timer_val: auto shutdown timer value
1818  *
1819  * Return: CDF status
1820  */
1821 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle,
1822 						  uint32_t timer_val)
1823 {
1824 	QDF_STATUS status;
1825 	wmi_buf_t buf = NULL;
1826 	uint8_t *buf_ptr;
1827 	wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd;
1828 	int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param);
1829 
1830 	WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d",
1831 		 __func__, timer_val);
1832 
1833 	buf = wmi_buf_alloc(wmi_handle, len);
1834 	if (!buf) {
1835 		return QDF_STATUS_E_NOMEM;
1836 	}
1837 
1838 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
1839 	wmi_auto_sh_cmd =
1840 		(wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr;
1841 	wmi_auto_sh_cmd->timer_value = timer_val;
1842 
1843 	WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header,
1844 	       WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param,
1845 	       WMITLV_GET_STRUCT_TLVLEN
1846 	       (wmi_host_auto_shutdown_cfg_cmd_fixed_param));
1847 
1848 	wmi_mtrace(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID, NO_SESSION, 0);
1849 	status = wmi_unified_cmd_send(wmi_handle, buf,
1850 				      len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID);
1851 	if (QDF_IS_STATUS_ERROR(status)) {
1852 		WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d",
1853 			 __func__, status);
1854 		wmi_buf_free(buf);
1855 	}
1856 
1857 	return status;
1858 }
1859 
1860 /**
1861  * send_set_led_flashing_cmd_tlv() - set led flashing in fw
1862  * @wmi_handle: wmi handle
1863  * @flashing: flashing request
1864  *
1865  * Return: CDF status
1866  */
1867 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle,
1868 				struct flashing_req_params *flashing)
1869 {
1870 	wmi_set_led_flashing_cmd_fixed_param *cmd;
1871 	QDF_STATUS status;
1872 	wmi_buf_t buf;
1873 	uint8_t *buf_ptr;
1874 	int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param);
1875 
1876 	buf = wmi_buf_alloc(wmi_handle, len);
1877 	if (!buf) {
1878 		return QDF_STATUS_E_NOMEM;
1879 	}
1880 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
1881 	cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr;
1882 	WMITLV_SET_HDR(&cmd->tlv_header,
1883 		       WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param,
1884 		       WMITLV_GET_STRUCT_TLVLEN
1885 			       (wmi_set_led_flashing_cmd_fixed_param));
1886 	cmd->pattern_id = flashing->pattern_id;
1887 	cmd->led_x0 = flashing->led_x0;
1888 	cmd->led_x1 = flashing->led_x1;
1889 
1890 	wmi_mtrace(WMI_PDEV_SET_LED_FLASHING_CMDID, NO_SESSION, 0);
1891 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
1892 				      WMI_PDEV_SET_LED_FLASHING_CMDID);
1893 	if (QDF_IS_STATUS_ERROR(status)) {
1894 		WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
1895 			 " returned Error %d", __func__, status);
1896 		wmi_buf_free(buf);
1897 	}
1898 
1899 	return status;
1900 }
1901 
1902 /**
1903  * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request
1904  * @wmi_handle: wmi handle
1905  * @ch_avoid_update_req: channel avoid update params
1906  *
1907  * Return: CDF status
1908  */
1909 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle)
1910 {
1911 	QDF_STATUS status;
1912 	wmi_buf_t buf = NULL;
1913 	uint8_t *buf_ptr;
1914 	wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp;
1915 	int len = sizeof(wmi_chan_avoid_update_cmd_param);
1916 
1917 	buf = wmi_buf_alloc(wmi_handle, len);
1918 	if (!buf) {
1919 		return QDF_STATUS_E_NOMEM;
1920 	}
1921 
1922 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
1923 	ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr;
1924 	WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header,
1925 		       WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param,
1926 		       WMITLV_GET_STRUCT_TLVLEN
1927 			       (wmi_chan_avoid_update_cmd_param));
1928 
1929 	wmi_mtrace(WMI_CHAN_AVOID_UPDATE_CMDID, NO_SESSION, 0);
1930 	status = wmi_unified_cmd_send(wmi_handle, buf,
1931 				      len, WMI_CHAN_AVOID_UPDATE_CMDID);
1932 	if (QDF_IS_STATUS_ERROR(status)) {
1933 		WMI_LOGE("wmi_unified_cmd_send"
1934 			 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE"
1935 			 " returned Error %d", status);
1936 		wmi_buf_free(buf);
1937 	}
1938 
1939 	return status;
1940 }
1941 
1942 /**
1943  * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW
1944  * @wmi_handle: wmi handle
1945  * @msg: PCL structure containing the PCL and the number of channels
1946  *
1947  * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
1948  * firmware. The DBS Manager is the consumer of this information in the WLAN
1949  * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
1950  * to migrate to a new channel without host driver involvement. An example of
1951  * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
1952  * manage the channel selection without firmware involvement.
1953  *
1954  * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual
1955  * channel list. The weights corresponds to the channels sent in
1956  * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
1957  * weightage compared to the non PCL channels.
1958  *
1959  * Return: Success if the cmd is sent successfully to the firmware
1960  */
1961 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle,
1962 				struct wmi_pcl_chan_weights *msg)
1963 {
1964 	wmi_pdev_set_pcl_cmd_fixed_param *cmd;
1965 	wmi_buf_t buf;
1966 	uint8_t *buf_ptr;
1967 	uint32_t *cmd_args, i, len;
1968 	uint32_t chan_len;
1969 
1970 	chan_len = msg->saved_num_chan;
1971 
1972 	len = sizeof(*cmd) +
1973 		WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t));
1974 
1975 	buf = wmi_buf_alloc(wmi_handle, len);
1976 	if (!buf) {
1977 		return QDF_STATUS_E_NOMEM;
1978 	}
1979 
1980 	cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf);
1981 	buf_ptr = (uint8_t *) cmd;
1982 	WMITLV_SET_HDR(&cmd->tlv_header,
1983 		WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param,
1984 		WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param));
1985 
1986 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
1987 							wmi_handle,
1988 							WMI_HOST_PDEV_ID_SOC);
1989 	cmd->num_chan = chan_len;
1990 	buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param);
1991 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
1992 			(chan_len * sizeof(uint32_t)));
1993 	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
1994 	for (i = 0; i < chan_len ; i++)
1995 		cmd_args[i] = msg->weighed_valid_list[i];
1996 	wmi_mtrace(WMI_PDEV_SET_PCL_CMDID, NO_SESSION, 0);
1997 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1998 				 WMI_PDEV_SET_PCL_CMDID)) {
1999 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__);
2000 		wmi_buf_free(buf);
2001 		return QDF_STATUS_E_FAILURE;
2002 	}
2003 	return QDF_STATUS_SUCCESS;
2004 }
2005 
2006 #ifdef WLAN_POLICY_MGR_ENABLE
2007 /**
2008  * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW
2009  * @wmi_handle: wmi handle
2010  * @msg: Dual MAC config parameters
2011  *
2012  * Configures WLAN firmware with the dual MAC features
2013  *
2014  * Return: QDF_STATUS. 0 on success.
2015  */
2016 static
2017 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle,
2018 		struct policy_mgr_dual_mac_config *msg)
2019 {
2020 	wmi_pdev_set_mac_config_cmd_fixed_param *cmd;
2021 	wmi_buf_t buf;
2022 	uint32_t len;
2023 
2024 	len = sizeof(*cmd);
2025 
2026 	buf = wmi_buf_alloc(wmi_handle, len);
2027 	if (!buf) {
2028 		return QDF_STATUS_E_FAILURE;
2029 	}
2030 
2031 	cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf);
2032 	WMITLV_SET_HDR(&cmd->tlv_header,
2033 		WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param,
2034 		WMITLV_GET_STRUCT_TLVLEN(
2035 			wmi_pdev_set_mac_config_cmd_fixed_param));
2036 
2037 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
2038 							wmi_handle,
2039 							WMI_HOST_PDEV_ID_SOC);
2040 	cmd->concurrent_scan_config_bits = msg->scan_config;
2041 	cmd->fw_mode_config_bits = msg->fw_mode_config;
2042 	WMI_LOGD("%s: scan_config:%x fw_mode_config:%x",
2043 		 __func__, msg->scan_config, msg->fw_mode_config);
2044 
2045 	wmi_mtrace(WMI_PDEV_SET_MAC_CONFIG_CMDID, NO_SESSION, 0);
2046 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
2047 				 WMI_PDEV_SET_MAC_CONFIG_CMDID)) {
2048 		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID",
2049 			 __func__);
2050 		wmi_buf_free(buf);
2051 		return QDF_STATUS_E_FAILURE;
2052 	}
2053 	return QDF_STATUS_SUCCESS;
2054 }
2055 
2056 void wmi_policy_mgr_attach_tlv(struct wmi_unified *wmi_handle)
2057 {
2058 	struct wmi_ops *ops = wmi_handle->ops;
2059 
2060 	ops->send_pdev_set_dual_mac_config_cmd =
2061 		send_pdev_set_dual_mac_config_cmd_tlv;
2062 }
2063 #endif /* WLAN_POLICY_MGR_ENABLE */
2064 
2065 /**
2066  * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime
2067  * configuration params
2068  * @wma_handle:  wma handler
2069  * @dwelltime_params: pointer to dwelltime_params
2070  *
2071  * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
2072  */
2073 static
2074 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle,
2075 		struct wmi_adaptive_dwelltime_params *dwelltime_params)
2076 {
2077 	wmi_scan_adaptive_dwell_config_fixed_param *dwell_param;
2078 	wmi_scan_adaptive_dwell_parameters_tlv *cmd;
2079 	wmi_buf_t buf;
2080 	uint8_t *buf_ptr;
2081 	int32_t err;
2082 	int len;
2083 
2084 	len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
2085 	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
2086 	len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv);
2087 	buf = wmi_buf_alloc(wmi_handle, len);
2088 	if (!buf) {
2089 		return QDF_STATUS_E_NOMEM;
2090 	}
2091 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
2092 	dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr;
2093 	WMITLV_SET_HDR(&dwell_param->tlv_header,
2094 		WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param,
2095 		WMITLV_GET_STRUCT_TLVLEN
2096 		(wmi_scan_adaptive_dwell_config_fixed_param));
2097 
2098 	dwell_param->enable = dwelltime_params->is_enabled;
2099 	buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
2100 	WMITLV_SET_HDR(buf_ptr,
2101 		       WMITLV_TAG_ARRAY_STRUC,
2102 		       sizeof(wmi_scan_adaptive_dwell_parameters_tlv));
2103 	buf_ptr += WMI_TLV_HDR_SIZE;
2104 
2105 	cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr;
2106 	WMITLV_SET_HDR(&cmd->tlv_header,
2107 		       WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv,
2108 		       WMITLV_GET_STRUCT_TLVLEN(
2109 		       wmi_scan_adaptive_dwell_parameters_tlv));
2110 
2111 	cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode;
2112 	cmd->adapative_lpf_weight = dwelltime_params->lpf_weight;
2113 	cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval;
2114 	cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold;
2115 	wmi_mtrace(WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID, NO_SESSION, 0);
2116 	err = wmi_unified_cmd_send(wmi_handle, buf,
2117 				   len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID);
2118 	if (err) {
2119 		WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err);
2120 		wmi_buf_free(buf);
2121 		return QDF_STATUS_E_FAILURE;
2122 	}
2123 
2124 	return QDF_STATUS_SUCCESS;
2125 }
2126 
2127 /**
2128  * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection
2129  * configuration params
2130  * @wmi_handle: wmi handler
2131  * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params
2132  *
2133  * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
2134  */
2135 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle,
2136 			struct wmi_dbs_scan_sel_params *dbs_scan_params)
2137 {
2138 	wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param;
2139 	wmi_scan_dbs_duty_cycle_tlv_param *cmd;
2140 	wmi_buf_t buf;
2141 	uint8_t *buf_ptr;
2142 	QDF_STATUS err;
2143 	uint32_t i;
2144 	int len;
2145 
2146 	len = sizeof(*dbs_scan_param);
2147 	len += WMI_TLV_HDR_SIZE;
2148 	len += dbs_scan_params->num_clients * sizeof(*cmd);
2149 
2150 	buf = wmi_buf_alloc(wmi_handle, len);
2151 	if (!buf) {
2152 		return QDF_STATUS_E_NOMEM;
2153 	}
2154 
2155 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
2156 	dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr;
2157 	WMITLV_SET_HDR(&dbs_scan_param->tlv_header,
2158 		       WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param,
2159 		       WMITLV_GET_STRUCT_TLVLEN
2160 				(wmi_scan_dbs_duty_cycle_fixed_param));
2161 
2162 	dbs_scan_param->num_clients = dbs_scan_params->num_clients;
2163 	dbs_scan_param->pdev_id = dbs_scan_params->pdev_id;
2164 	buf_ptr += sizeof(*dbs_scan_param);
2165 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2166 		       (sizeof(*cmd) * dbs_scan_params->num_clients));
2167 	buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE;
2168 
2169 	for (i = 0; i < dbs_scan_params->num_clients; i++) {
2170 		cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr;
2171 		WMITLV_SET_HDR(&cmd->tlv_header,
2172 			WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv,
2173 			WMITLV_GET_STRUCT_TLVLEN(
2174 					wmi_scan_dbs_duty_cycle_tlv_param));
2175 		cmd->module_id = dbs_scan_params->module_id[i];
2176 		cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i];
2177 		cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i];
2178 		buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd);
2179 	}
2180 
2181 	wmi_mtrace(WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID, NO_SESSION, 0);
2182 	err = wmi_unified_cmd_send(wmi_handle, buf,
2183 				   len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID);
2184 	if (QDF_IS_STATUS_ERROR(err)) {
2185 		WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err);
2186 		wmi_buf_free(buf);
2187 		return QDF_STATUS_E_FAILURE;
2188 	}
2189 
2190 	return QDF_STATUS_SUCCESS;
2191 }
2192 
2193 /**
2194  * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request
2195  * @wmi_handle: wmi handler
2196  * @req_buf: set arp stats request buffer
2197  *
2198  * Return: 0 for success and non zero for failure
2199  */
2200 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
2201 					  struct set_arp_stats *req_buf)
2202 {
2203 	wmi_buf_t buf = NULL;
2204 	QDF_STATUS status;
2205 	int len;
2206 	uint8_t *buf_ptr;
2207 	wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp;
2208 
2209 	len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
2210 	if (req_buf->pkt_type_bitmap) {
2211 		len += WMI_TLV_HDR_SIZE;
2212 		len += sizeof(wmi_vdev_set_connectivity_check_stats);
2213 	}
2214 	buf = wmi_buf_alloc(wmi_handle, len);
2215 	if (!buf) {
2216 		return QDF_STATUS_E_NOMEM;
2217 	}
2218 
2219 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
2220 	wmi_set_arp =
2221 		(wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr;
2222 	WMITLV_SET_HDR(&wmi_set_arp->tlv_header,
2223 		       WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param,
2224 		       WMITLV_GET_STRUCT_TLVLEN
2225 				(wmi_vdev_set_arp_stats_cmd_fixed_param));
2226 
2227 	/* fill in per roam config values */
2228 	wmi_set_arp->vdev_id = req_buf->vdev_id;
2229 
2230 	wmi_set_arp->set_clr = req_buf->flag;
2231 	wmi_set_arp->pkt_type = req_buf->pkt_type;
2232 	wmi_set_arp->ipv4 = req_buf->ip_addr;
2233 
2234 	WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u",
2235 		 wmi_set_arp->vdev_id, wmi_set_arp->set_clr,
2236 		 wmi_set_arp->pkt_type, wmi_set_arp->ipv4);
2237 
2238 	/*
2239 	 * pkt_type_bitmap should be non-zero to ensure
2240 	 * presence of additional stats.
2241 	 */
2242 	if (req_buf->pkt_type_bitmap) {
2243 		wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats;
2244 
2245 		buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
2246 		WMITLV_SET_HDR(buf_ptr,
2247 			       WMITLV_TAG_ARRAY_STRUC,
2248 			       sizeof(wmi_vdev_set_connectivity_check_stats));
2249 		buf_ptr += WMI_TLV_HDR_SIZE;
2250 		wmi_set_connect_stats =
2251 			(wmi_vdev_set_connectivity_check_stats *)buf_ptr;
2252 		WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header,
2253 			WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats,
2254 			WMITLV_GET_STRUCT_TLVLEN(
2255 					wmi_vdev_set_connectivity_check_stats));
2256 		wmi_set_connect_stats->pkt_type_bitmap =
2257 						req_buf->pkt_type_bitmap;
2258 		wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port;
2259 		wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port;
2260 		wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4;
2261 
2262 		WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u",
2263 			 wmi_set_connect_stats->pkt_type_bitmap,
2264 			 wmi_set_connect_stats->tcp_src_port,
2265 			 wmi_set_connect_stats->tcp_dst_port,
2266 			 wmi_set_connect_stats->icmp_ipv4);
2267 	}
2268 
2269 	/* Send per roam config parameters */
2270 	wmi_mtrace(WMI_VDEV_SET_ARP_STAT_CMDID, NO_SESSION, 0);
2271 	status = wmi_unified_cmd_send(wmi_handle, buf,
2272 				      len, WMI_VDEV_SET_ARP_STAT_CMDID);
2273 	if (QDF_IS_STATUS_ERROR(status)) {
2274 		WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d",
2275 			 status);
2276 		goto error;
2277 	}
2278 
2279 	WMI_LOGD(FL("set arp stats flag=%d, vdev=%d"),
2280 		 req_buf->flag, req_buf->vdev_id);
2281 	return QDF_STATUS_SUCCESS;
2282 error:
2283 	wmi_buf_free(buf);
2284 
2285 	return status;
2286 }
2287 
2288 /**
2289  * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request
2290  * @wmi_handle: wmi handler
2291  * @req_buf: get arp stats request buffer
2292  *
2293  * Return: 0 for success and non zero for failure
2294  */
2295 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
2296 					  struct get_arp_stats *req_buf)
2297 {
2298 	wmi_buf_t buf = NULL;
2299 	QDF_STATUS status;
2300 	int len;
2301 	uint8_t *buf_ptr;
2302 	wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats;
2303 
2304 	len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param);
2305 	buf = wmi_buf_alloc(wmi_handle, len);
2306 	if (!buf) {
2307 		return QDF_STATUS_E_NOMEM;
2308 	}
2309 
2310 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
2311 	get_arp_stats =
2312 		(wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr;
2313 	WMITLV_SET_HDR(&get_arp_stats->tlv_header,
2314 		       WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param,
2315 		       WMITLV_GET_STRUCT_TLVLEN
2316 				(wmi_vdev_get_arp_stats_cmd_fixed_param));
2317 
2318 	/* fill in arp stats req cmd values */
2319 	get_arp_stats->vdev_id = req_buf->vdev_id;
2320 
2321 	WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id);
2322 	/* Send per roam config parameters */
2323 	wmi_mtrace(WMI_VDEV_GET_ARP_STAT_CMDID, NO_SESSION, 0);
2324 	status = wmi_unified_cmd_send(wmi_handle, buf,
2325 				      len, WMI_VDEV_GET_ARP_STAT_CMDID);
2326 	if (QDF_IS_STATUS_ERROR(status)) {
2327 		WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d",
2328 			 status);
2329 		goto error;
2330 	}
2331 
2332 	return QDF_STATUS_SUCCESS;
2333 error:
2334 	wmi_buf_free(buf);
2335 
2336 	return status;
2337 }
2338 
2339 /**
2340  * send_peer_unmap_conf_cmd_tlv() - send PEER UNMAP conf command to fw
2341  * @wmi: wmi handle
2342  * @vdev_id: vdev id
2343  * @peer_id_cnt: no. of peer ids
2344  * @peer_id_list: list of peer ids
2345  *
2346  * Return: QDF_STATUS_SUCCESS for success or error code
2347  */
2348 static QDF_STATUS send_peer_unmap_conf_cmd_tlv(wmi_unified_t wmi,
2349 					       uint8_t vdev_id,
2350 					       uint32_t peer_id_cnt,
2351 					       uint16_t *peer_id_list)
2352 {
2353 	int i;
2354 	wmi_buf_t buf;
2355 	uint8_t *buf_ptr;
2356 	A_UINT32 *peer_ids;
2357 	wmi_peer_unmap_response_cmd_fixed_param *cmd;
2358 	uint32_t peer_id_list_len;
2359 	uint32_t len = sizeof(*cmd);
2360 	QDF_STATUS status;
2361 
2362 	if (!peer_id_cnt || !peer_id_list)
2363 		return QDF_STATUS_E_FAILURE;
2364 
2365 	len += WMI_TLV_HDR_SIZE;
2366 
2367 	peer_id_list_len = peer_id_cnt * sizeof(A_UINT32);
2368 
2369 	len += peer_id_list_len;
2370 
2371 	buf = wmi_buf_alloc(wmi, len);
2372 
2373 	if (!buf) {
2374 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
2375 		return QDF_STATUS_E_NOMEM;
2376 	}
2377 
2378 	cmd = (wmi_peer_unmap_response_cmd_fixed_param *)wmi_buf_data(buf);
2379 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
2380 
2381 	WMITLV_SET_HDR(&cmd->tlv_header,
2382 		       WMITLV_TAG_STRUC_wmi_peer_unmap_response_cmd_fixed_param,
2383 		       WMITLV_GET_STRUCT_TLVLEN
2384 			       (wmi_peer_unmap_response_cmd_fixed_param));
2385 
2386 	buf_ptr += sizeof(wmi_peer_unmap_response_cmd_fixed_param);
2387 
2388 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
2389 		       peer_id_list_len);
2390 
2391 	peer_ids = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE);
2392 
2393 	for (i = 0; i < peer_id_cnt; i++)
2394 		peer_ids[i] = peer_id_list[i];
2395 
2396 	WMI_LOGD("%s: vdev_id %d peer_id_cnt %d", __func__,
2397 		 vdev_id, peer_id_cnt);
2398 	wmi_mtrace(WMI_PEER_UNMAP_RESPONSE_CMDID, vdev_id, 0);
2399 	status = wmi_unified_cmd_send(wmi, buf, len,
2400 				      WMI_PEER_UNMAP_RESPONSE_CMDID);
2401 	if (QDF_IS_STATUS_ERROR(status)) {
2402 		WMI_LOGE("%s: Failed to send peer unmap conf command: Err[%d]",
2403 			 __func__, status);
2404 		wmi_buf_free(buf);
2405 		return status;
2406 	}
2407 
2408 	return QDF_STATUS_SUCCESS;
2409 }
2410 
2411 /**
2412  * send_ocl_cmd_tlv() - send ocl command to fw
2413  * @wmi_handle: wmi handle
2414  * @param: pointer to coex config param
2415  *
2416  * Return: 0 for success or error code
2417  */
2418 static QDF_STATUS
2419 send_ocl_cmd_tlv(wmi_unified_t wmi_handle, struct ocl_cmd_params *param)
2420 {
2421 	wmi_set_ocl_cmd_fixed_param *cmd;
2422 	wmi_buf_t buf;
2423 	QDF_STATUS ret;
2424 	int32_t len;
2425 
2426 	len = sizeof(*cmd);
2427 	buf = wmi_buf_alloc(wmi_handle, len);
2428 	if (!buf)
2429 		return QDF_STATUS_E_FAILURE;
2430 
2431 	cmd = (wmi_set_ocl_cmd_fixed_param *)wmi_buf_data(buf);
2432 	WMITLV_SET_HDR(&cmd->tlv_header,
2433 		       WMITLV_TAG_STRUC_wmi_set_ocl_cmd_fixed_param,
2434 		       WMITLV_GET_STRUCT_TLVLEN(
2435 		       wmi_set_ocl_cmd_fixed_param));
2436 
2437 	cmd->vdev_id = param->vdev_id;
2438 	cmd->en_dis_chain = param->en_dis_chain;
2439 
2440 	wmi_mtrace(WMI_SET_OCL_CMDID, cmd->vdev_id, 0);
2441 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2442 				   WMI_SET_OCL_CMDID);
2443 
2444 	if (ret != 0) {
2445 		WMI_LOGE("Sending OCL CMD failed");
2446 		wmi_buf_free(buf);
2447 	}
2448 
2449 	return ret;
2450 }
2451 
2452 void wmi_sta_attach_tlv(wmi_unified_t wmi_handle)
2453 {
2454 	struct wmi_ops *ops = wmi_handle->ops;
2455 
2456 	ops->send_set_sta_sa_query_param_cmd =
2457 		send_set_sta_sa_query_param_cmd_tlv;
2458 	ops->send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv;
2459 	ops->send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv;
2460 	ops->send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv;
2461 	ops->send_get_link_speed_cmd = send_get_link_speed_cmd_tlv;
2462 	ops->send_fw_profiling_cmd = send_fw_profiling_cmd_tlv;
2463 	ops->send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv;
2464 	ops->send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv;
2465 	ops->send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv;
2466 	ops->send_set_base_macaddr_indicate_cmd =
2467 		 send_set_base_macaddr_indicate_cmd_tlv;
2468 	ops->send_sar_limit_cmd = send_sar_limit_cmd_tlv;
2469 	ops->get_sar_limit_cmd = get_sar_limit_cmd_tlv;
2470 	ops->extract_sar_limit_event = extract_sar_limit_event_tlv;
2471 	ops->extract_sar2_result_event = extract_sar2_result_event_tlv;
2472 	ops->send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv;
2473 	ops->send_del_ts_cmd = send_del_ts_cmd_tlv;
2474 	ops->send_aggr_qos_cmd = send_aggr_qos_cmd_tlv;
2475 	ops->send_add_ts_cmd = send_add_ts_cmd_tlv;
2476 	ops->send_process_add_periodic_tx_ptrn_cmd =
2477 		send_process_add_periodic_tx_ptrn_cmd_tlv;
2478 	ops->send_process_del_periodic_tx_ptrn_cmd =
2479 		send_process_del_periodic_tx_ptrn_cmd_tlv;
2480 	ops->send_set_auto_shutdown_timer_cmd =
2481 		send_set_auto_shutdown_timer_cmd_tlv;
2482 	ops->send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv;
2483 	ops->send_process_ch_avoid_update_cmd =
2484 		send_process_ch_avoid_update_cmd_tlv;
2485 	ops->send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv;
2486 	ops->send_adapt_dwelltime_params_cmd =
2487 		send_adapt_dwelltime_params_cmd_tlv;
2488 	ops->send_dbs_scan_sel_params_cmd =
2489 		send_dbs_scan_sel_params_cmd_tlv;
2490 	ops->send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv;
2491 	ops->send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv;
2492 	ops->send_peer_unmap_conf_cmd = send_peer_unmap_conf_cmd_tlv;
2493 	ops->send_ocl_cmd = send_ocl_cmd_tlv;
2494 
2495 	wmi_tdls_attach_tlv(wmi_handle);
2496 	wmi_policy_mgr_attach_tlv(wmi_handle);
2497 	wmi_blacklist_mgr_attach_tlv(wmi_handle);
2498 }
2499 
2500