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