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