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