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