xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_pmo_tlv.c (revision 2f4b444fb7e689b83a4ab0e7b3b38f0bf4def8e0)
1 /*
2  * Copyright (c) 2018-2021 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_unified_priv.h"
22 #include "wmi_unified_pmo_api.h"
23 
24 #ifdef FEATURE_WLAN_D0WOW
25 /**
26  *  send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function
27  *  @param wmi_handle: handle to WMI.
28  *  @mac_id: radio context
29  *
30  *  Return: 0  on success  and  error code on failure.
31  */
32 static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle,
33 					    uint8_t mac_id)
34 {
35 	wmi_d0_wow_enable_disable_cmd_fixed_param *cmd;
36 	wmi_buf_t buf;
37 	int32_t len;
38 	QDF_STATUS status;
39 
40 	len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param);
41 
42 	buf = wmi_buf_alloc(wmi_handle, len);
43 	if (!buf) {
44 		return QDF_STATUS_E_NOMEM;
45 	}
46 	cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf);
47 	WMITLV_SET_HDR(&cmd->tlv_header,
48 		WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param,
49 		WMITLV_GET_STRUCT_TLVLEN
50 			(wmi_d0_wow_enable_disable_cmd_fixed_param));
51 
52 	cmd->enable = true;
53 
54 	wmi_mtrace(WMI_D0_WOW_ENABLE_DISABLE_CMDID, NO_SESSION, 0);
55 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
56 				      WMI_D0_WOW_ENABLE_DISABLE_CMDID);
57 	if (QDF_IS_STATUS_ERROR(status))
58 		wmi_buf_free(buf);
59 
60 	return status;
61 }
62 
63 /**
64  *  send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function
65  *  @param wmi_handle: handle to WMI.
66  *  @mac_id: radio context
67  *
68  *  Return: 0  on success  and  error code on failure.
69  */
70 static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle,
71 					     uint8_t mac_id)
72 {
73 	wmi_d0_wow_enable_disable_cmd_fixed_param *cmd;
74 	wmi_buf_t buf;
75 	int32_t len;
76 	QDF_STATUS status;
77 
78 	len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param);
79 
80 	buf = wmi_buf_alloc(wmi_handle, len);
81 	if (!buf) {
82 		return QDF_STATUS_E_NOMEM;
83 	}
84 	cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf);
85 	WMITLV_SET_HDR(&cmd->tlv_header,
86 		WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param,
87 		WMITLV_GET_STRUCT_TLVLEN
88 			(wmi_d0_wow_enable_disable_cmd_fixed_param));
89 
90 	cmd->enable = false;
91 
92 	wmi_mtrace(WMI_D0_WOW_ENABLE_DISABLE_CMDID, NO_SESSION, 0);
93 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
94 				      WMI_D0_WOW_ENABLE_DISABLE_CMDID);
95 	if (QDF_IS_STATUS_ERROR(status))
96 		wmi_buf_free(buf);
97 
98 	return status;
99 }
100 
101 void wmi_d0wow_attach_tlv(struct wmi_unified *wmi_handle)
102 {
103 	struct wmi_ops *ops = wmi_handle->ops;
104 
105 	ops->send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv;
106 	ops->send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv;
107 }
108 #endif /* FEATURE_WLAN_D0WOW */
109 
110 /**
111  * send_add_wow_wakeup_event_cmd_tlv() -  Configures wow wakeup events.
112  * @wmi_handle: wmi handle
113  * @vdev_id: vdev id
114  * @bitmap: Event bitmap
115  * @enable: enable/disable
116  *
117  * Return: CDF status
118  */
119 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle,
120 						    uint32_t vdev_id,
121 						    uint32_t *bitmap,
122 						    bool enable)
123 {
124 	WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd;
125 	uint16_t len;
126 	wmi_buf_t buf;
127 	int ret;
128 
129 	len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param);
130 	buf = wmi_buf_alloc(wmi_handle, len);
131 	if (!buf) {
132 		return QDF_STATUS_E_NOMEM;
133 	}
134 	cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf);
135 	WMITLV_SET_HDR(&cmd->tlv_header,
136 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param,
137 		       WMITLV_GET_STRUCT_TLVLEN
138 			       (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param));
139 	cmd->vdev_id = vdev_id;
140 	cmd->is_add = enable;
141 	qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) *
142 		     WMI_WOW_MAX_EVENT_BM_LEN);
143 
144 	wmi_debug("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0],
145 		 cmd->event_bitmaps[1], cmd->event_bitmaps[2],
146 		 cmd->event_bitmaps[3], enable ? "enabled" : "disabled");
147 
148 	wmi_mtrace(WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, cmd->vdev_id, 0);
149 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
150 				   WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
151 	if (ret) {
152 		wmi_err("Failed to config wow wakeup event");
153 		wmi_buf_free(buf);
154 		return QDF_STATUS_E_FAILURE;
155 	}
156 
157 	return QDF_STATUS_SUCCESS;
158 }
159 
160 /**
161  * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW.
162  * @wmi_handle: wmi handle
163  * @vdev_id: vdev id
164  * @ptrn_id: pattern id
165  * @ptrn: pattern
166  * @ptrn_len: pattern length
167  * @ptrn_offset: pattern offset
168  * @mask: mask
169  * @mask_len: mask length
170  * @user: true for user configured pattern and false for default pattern
171  * @default_patterns: default patterns
172  *
173  * Return: CDF status
174  */
175 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle,
176 				uint8_t vdev_id, uint8_t ptrn_id,
177 				const uint8_t *ptrn, uint8_t ptrn_len,
178 				uint8_t ptrn_offset, const uint8_t *mask,
179 				uint8_t mask_len, bool user,
180 				uint8_t default_patterns)
181 {
182 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
183 	WOW_BITMAP_PATTERN_T *bitmap_pattern;
184 	wmi_buf_t buf;
185 	uint8_t *buf_ptr;
186 	int32_t len;
187 	int ret;
188 
189 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
190 		WMI_TLV_HDR_SIZE +
191 		1 * sizeof(WOW_BITMAP_PATTERN_T) +
192 		WMI_TLV_HDR_SIZE +
193 		0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
194 		WMI_TLV_HDR_SIZE +
195 		0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
196 		WMI_TLV_HDR_SIZE +
197 		0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
198 		WMI_TLV_HDR_SIZE +
199 		0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
200 
201 	buf = wmi_buf_alloc(wmi_handle, len);
202 	if (!buf) {
203 		return QDF_STATUS_E_NOMEM;
204 	}
205 
206 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
207 	buf_ptr = (uint8_t *) cmd;
208 
209 	WMITLV_SET_HDR(&cmd->tlv_header,
210 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
211 		       WMITLV_GET_STRUCT_TLVLEN
212 			       (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
213 	cmd->vdev_id = vdev_id;
214 	cmd->pattern_id = ptrn_id;
215 
216 	cmd->pattern_type = WOW_BITMAP_PATTERN;
217 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
218 
219 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
220 		       sizeof(WOW_BITMAP_PATTERN_T));
221 	buf_ptr += WMI_TLV_HDR_SIZE;
222 	bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr;
223 
224 	WMITLV_SET_HDR(&bitmap_pattern->tlv_header,
225 		       WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T,
226 		       WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T));
227 
228 	qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len);
229 	qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len);
230 
231 	bitmap_pattern->pattern_offset = ptrn_offset;
232 	bitmap_pattern->pattern_len = ptrn_len;
233 
234 	if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE)
235 		bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE;
236 
237 	if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE)
238 		bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE;
239 
240 	bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len;
241 	bitmap_pattern->pattern_id = ptrn_id;
242 
243 	wmi_debug("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d",
244 		 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len,
245 		 bitmap_pattern->pattern_offset, user);
246 	wmi_debug("Pattern: ");
247 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
248 			   &bitmap_pattern->patternbuf[0],
249 			   bitmap_pattern->pattern_len);
250 
251 	wmi_debug("Mask: ");
252 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
253 			   &bitmap_pattern->bitmaskbuf[0],
254 			   bitmap_pattern->pattern_len);
255 
256 	buf_ptr += sizeof(WOW_BITMAP_PATTERN_T);
257 
258 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
259 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
260 	buf_ptr += WMI_TLV_HDR_SIZE;
261 
262 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
263 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
264 	buf_ptr += WMI_TLV_HDR_SIZE;
265 
266 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
267 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
268 	buf_ptr += WMI_TLV_HDR_SIZE;
269 
270 	/* Fill TLV for pattern_info_timeout but no data. */
271 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
272 	buf_ptr += WMI_TLV_HDR_SIZE;
273 
274 	/* Fill TLV for ratelimit_interval with dummy data as this fix elem */
275 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t));
276 	buf_ptr += WMI_TLV_HDR_SIZE;
277 	*(uint32_t *) buf_ptr = 0;
278 
279 	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
280 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
281 				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
282 	if (ret) {
283 		wmi_err("Failed to send wow ptrn to fw");
284 		wmi_buf_free(buf);
285 		return QDF_STATUS_E_FAILURE;
286 	}
287 
288 	return QDF_STATUS_SUCCESS;
289 }
290 
291 /**
292  * fill_arp_offload_params_tlv() - Fill ARP offload data
293  * @wmi_handle: wmi handle
294  * @offload_req: offload request
295  * @buf_ptr: buffer pointer
296  *
297  * To fill ARP offload data to firmware
298  * when target goes to wow mode.
299  *
300  * Return: None
301  */
302 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle,
303 		struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr)
304 {
305 
306 	int i;
307 	WMI_ARP_OFFLOAD_TUPLE *arp_tuple;
308 	bool enable_or_disable = offload_req->enable;
309 
310 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
311 		(WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE)));
312 	*buf_ptr += WMI_TLV_HDR_SIZE;
313 	for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) {
314 		arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr;
315 		WMITLV_SET_HDR(&arp_tuple->tlv_header,
316 			WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE,
317 			WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE));
318 
319 		/* Fill data for ARP and NS in the first tupple for LA */
320 		if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) {
321 			/* Copy the target ip addr and flags */
322 			arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID;
323 			qdf_mem_copy(&arp_tuple->target_ipaddr,
324 					offload_req->host_ipv4_addr,
325 					WMI_IPV4_ADDR_LEN);
326 			wmi_debug("ARPOffload IP4 address: %pI4",
327 				 offload_req->host_ipv4_addr);
328 		}
329 		*buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE);
330 	}
331 }
332 
333 #ifdef WLAN_NS_OFFLOAD
334 /**
335  * fill_ns_offload_params_tlv() - Fill NS offload data
336  * @wmi|_handle: wmi handle
337  * @offload_req: offload request
338  * @buf_ptr: buffer pointer
339  *
340  * To fill NS offload data to firmware
341  * when target goes to wow mode.
342  *
343  * Return: None
344  */
345 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle,
346 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
347 {
348 
349 	int i;
350 	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
351 
352 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
353 		       (WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE)));
354 	*buf_ptr += WMI_TLV_HDR_SIZE;
355 	for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) {
356 		ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr;
357 		WMITLV_SET_HDR(&ns_tuple->tlv_header,
358 			WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
359 			(sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE));
360 
361 		/*
362 		 * Fill data only for NS offload in the first ARP tuple for LA
363 		 */
364 		if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) {
365 			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
366 			/* Copy the target/solicitation/remote ip addr */
367 			if (ns_req->target_ipv6_addr_valid[i])
368 				qdf_mem_copy(&ns_tuple->target_ipaddr[0],
369 					&ns_req->target_ipv6_addr[i],
370 					sizeof(WMI_IPV6_ADDR));
371 			qdf_mem_copy(&ns_tuple->solicitation_ipaddr,
372 				&ns_req->self_ipv6_addr[i],
373 				sizeof(WMI_IPV6_ADDR));
374 			if (ns_req->target_ipv6_addr_ac_type[i]) {
375 				ns_tuple->flags |=
376 					WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST;
377 			}
378 			wmi_debug("Index %d NS solicitedIp %pI6, targetIp %pI6",
379 				i, &ns_req->self_ipv6_addr[i],
380 				&ns_req->target_ipv6_addr[i]);
381 
382 			/* target MAC is optional, check if it is valid,
383 			 * if this is not valid, the target will use the known
384 			 * local MAC address rather than the tuple
385 			 */
386 			WMI_CHAR_ARRAY_TO_MAC_ADDR(
387 				ns_req->self_macaddr.bytes,
388 				&ns_tuple->target_mac);
389 			if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
390 				(ns_tuple->target_mac.mac_addr47to32 != 0)) {
391 				ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
392 			}
393 		}
394 		*buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
395 	}
396 }
397 
398 /**
399  * fill_nsoffload_ext_tlv() - Fill NS offload ext data
400  * @wmi: wmi handle
401  * @offload_req: offload request
402  * @buf_ptr: buffer pointer
403  *
404  * To fill extended NS offload extended data to firmware
405  * when target goes to wow mode.
406  *
407  * Return: None
408  */
409 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle,
410 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
411 {
412 	int i;
413 	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
414 	uint32_t count, num_ns_ext_tuples;
415 
416 	count = ns_req->num_ns_offload_count;
417 	num_ns_ext_tuples = ns_req->num_ns_offload_count -
418 		WMI_MAX_NS_OFFLOADS;
419 
420 	/* Populate extended NS offload tuples */
421 	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
422 		(num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE)));
423 	*buf_ptr += WMI_TLV_HDR_SIZE;
424 	for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) {
425 		ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr;
426 		WMITLV_SET_HDR(&ns_tuple->tlv_header,
427 			WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
428 			(sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE));
429 
430 		/*
431 		 * Fill data only for NS offload in the first ARP tuple for LA
432 		 */
433 		if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) {
434 			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
435 			/* Copy the target/solicitation/remote ip addr */
436 			if (ns_req->target_ipv6_addr_valid[i])
437 				qdf_mem_copy(&ns_tuple->target_ipaddr[0],
438 					&ns_req->target_ipv6_addr[i],
439 					sizeof(WMI_IPV6_ADDR));
440 			qdf_mem_copy(&ns_tuple->solicitation_ipaddr,
441 				&ns_req->self_ipv6_addr[i],
442 				sizeof(WMI_IPV6_ADDR));
443 			if (ns_req->target_ipv6_addr_ac_type[i]) {
444 				ns_tuple->flags |=
445 					WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST;
446 			}
447 			wmi_debug("Index %d NS solicitedIp %pI6, targetIp %pI6",
448 				i, &ns_req->self_ipv6_addr[i],
449 				&ns_req->target_ipv6_addr[i]);
450 
451 			/* target MAC is optional, check if it is valid,
452 			 * if this is not valid, the target will use the
453 			 * known local MAC address rather than the tuple
454 			 */
455 			 WMI_CHAR_ARRAY_TO_MAC_ADDR(
456 				ns_req->self_macaddr.bytes,
457 				&ns_tuple->target_mac);
458 			if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
459 				(ns_tuple->target_mac.mac_addr47to32 != 0)) {
460 				ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
461 			}
462 		}
463 		*buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
464 	}
465 }
466 #else
467 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle,
468 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
469 {
470 }
471 
472 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle,
473 		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
474 {
475 }
476 #endif
477 
478 /**
479  * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload
480  * @wma: wmi handle
481  * @arp_offload_req: arp offload request
482  * @ns_offload_req: ns offload request
483  * @arp_only: flag
484  *
485  * To configure ARP NS off load data to firmware
486  * when target goes to wow mode.
487  *
488  * Return: QDF Status
489  */
490 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle,
491 			   struct pmo_arp_offload_params *arp_offload_req,
492 			   struct pmo_ns_offload_params *ns_offload_req,
493 			   uint8_t vdev_id)
494 {
495 	int32_t res;
496 	WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd;
497 	uint8_t *buf_ptr;
498 	wmi_buf_t buf;
499 	int32_t len;
500 	uint32_t count = 0, num_ns_ext_tuples = 0;
501 
502 	count = ns_offload_req->num_ns_offload_count;
503 
504 	/*
505 	 * TLV place holder size for array of NS tuples
506 	 * TLV place holder size for array of ARP tuples
507 	 */
508 	len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) +
509 		WMI_TLV_HDR_SIZE +
510 		WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) +
511 		WMI_TLV_HDR_SIZE +
512 		WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE);
513 
514 	/*
515 	 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate
516 	 * extra length for extended NS offload tuples which follows ARP offload
517 	 * tuples. Host needs to fill this structure in following format:
518 	 * 2 NS ofload tuples
519 	 * 2 ARP offload tuples
520 	 * N numbers of extended NS offload tuples if HDD has given more than
521 	 * 2 NS offload addresses
522 	 */
523 	if (count > WMI_MAX_NS_OFFLOADS) {
524 		num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS;
525 		len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples
526 			   * sizeof(WMI_NS_OFFLOAD_TUPLE);
527 	}
528 
529 	buf = wmi_buf_alloc(wmi_handle, len);
530 	if (!buf) {
531 		return QDF_STATUS_E_NOMEM;
532 	}
533 
534 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
535 	cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr;
536 	WMITLV_SET_HDR(&cmd->tlv_header,
537 		       WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param,
538 		       WMITLV_GET_STRUCT_TLVLEN
539 			       (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param));
540 	cmd->flags = 0;
541 	cmd->vdev_id = vdev_id;
542 	cmd->num_ns_ext_tuples = num_ns_ext_tuples;
543 
544 	wmi_debug("ARP NS Offload vdev_id: %d", cmd->vdev_id);
545 
546 	buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param);
547 	fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr);
548 	fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr);
549 	if (num_ns_ext_tuples)
550 		fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr);
551 
552 	wmi_mtrace(WMI_SET_ARP_NS_OFFLOAD_CMDID, cmd->vdev_id, 0);
553 	res = wmi_unified_cmd_send(wmi_handle, buf, len,
554 				     WMI_SET_ARP_NS_OFFLOAD_CMDID);
555 	if (res) {
556 		wmi_err("Failed to enable ARP NDP/NSffload");
557 		wmi_buf_free(buf);
558 		return QDF_STATUS_E_FAILURE;
559 	}
560 
561 	return QDF_STATUS_SUCCESS;
562 }
563 
564 /**
565  * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw
566  * @wmi_handle: wmi handle
567  * @vdev_id: vdev id
568  * @multicastAddr: mcast address
569  * @clearList: clear list flag
570  *
571  * Return: QDF_STATUS_SUCCESS for success or error code
572  */
573 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle,
574 				     uint8_t vdev_id,
575 				     struct qdf_mac_addr multicast_addr,
576 				     bool clearList)
577 {
578 	WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd;
579 	wmi_buf_t buf;
580 	int err;
581 
582 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
583 	if (!buf) {
584 		return QDF_STATUS_E_NOMEM;
585 	}
586 
587 	cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf);
588 	qdf_mem_zero(cmd, sizeof(*cmd));
589 
590 	WMITLV_SET_HDR(&cmd->tlv_header,
591 	       WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param,
592 	       WMITLV_GET_STRUCT_TLVLEN
593 	       (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param));
594 	cmd->action =
595 		(clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET);
596 	cmd->vdev_id = vdev_id;
597 	WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr);
598 
599 	wmi_debug("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: "QDF_MAC_ADDR_FMT,
600 		 cmd->action, vdev_id, clearList,
601 		 QDF_MAC_ADDR_REF(multicast_addr.bytes));
602 
603 	wmi_mtrace(WMI_SET_MCASTBCAST_FILTER_CMDID, cmd->vdev_id, 0);
604 	err = wmi_unified_cmd_send(wmi_handle, buf,
605 				   sizeof(*cmd),
606 				   WMI_SET_MCASTBCAST_FILTER_CMDID);
607 	if (err) {
608 		wmi_err("Failed to send set_param cmd");
609 		wmi_buf_free(buf);
610 		return QDF_STATUS_E_FAILURE;
611 	}
612 
613 	return QDF_STATUS_SUCCESS;
614 }
615 
616 /**
617  * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple  mcast filter
618  *						   command to fw
619  * @wmi_handle: wmi handle
620  * @vdev_id: vdev id
621  * @mcast_filter_params: mcast filter params
622  *
623  * Return: QDF_STATUS_SUCCESS for success or error code
624  */
625 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv(
626 				wmi_unified_t wmi_handle,
627 				uint8_t vdev_id,
628 				struct pmo_mcast_filter_params *filter_param)
629 
630 {
631 	WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd;
632 	uint8_t *buf_ptr;
633 	wmi_buf_t buf;
634 	int err;
635 	int i;
636 	uint8_t *mac_addr_src_ptr = NULL;
637 	wmi_mac_addr *mac_addr_dst_ptr;
638 	uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
639 		       sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt;
640 
641 	buf = wmi_buf_alloc(wmi_handle, len);
642 	if (!buf) {
643 		return QDF_STATUS_E_NOMEM;
644 	}
645 
646 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
647 	cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *)
648 		wmi_buf_data(buf);
649 	qdf_mem_zero(cmd, sizeof(*cmd));
650 
651 	WMITLV_SET_HDR(&cmd->tlv_header,
652 	       WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param,
653 	       WMITLV_GET_STRUCT_TLVLEN
654 	       (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param));
655 	cmd->operation =
656 		((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE
657 					: WMI_MULTIPLE_MCAST_FILTER_ADD);
658 	cmd->vdev_id = vdev_id;
659 	cmd->num_mcastaddrs = filter_param->multicast_addr_cnt;
660 
661 	buf_ptr += sizeof(*cmd);
662 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
663 		       sizeof(wmi_mac_addr) *
664 			       filter_param->multicast_addr_cnt);
665 
666 	if (filter_param->multicast_addr_cnt == 0)
667 		goto send_cmd;
668 
669 	mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr;
670 	mac_addr_dst_ptr = (wmi_mac_addr *)
671 			(buf_ptr + WMI_TLV_HDR_SIZE);
672 
673 	for (i = 0; i < filter_param->multicast_addr_cnt; i++) {
674 		WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr);
675 		mac_addr_src_ptr += ATH_MAC_LEN;
676 		mac_addr_dst_ptr++;
677 	}
678 
679 send_cmd:
680 	wmi_mtrace(WMI_SET_MULTIPLE_MCAST_FILTER_CMDID, cmd->vdev_id, 0);
681 	err = wmi_unified_cmd_send(wmi_handle, buf,
682 				   len,
683 				   WMI_SET_MULTIPLE_MCAST_FILTER_CMDID);
684 	if (err) {
685 		wmi_err("Failed to send set_param cmd");
686 		wmi_buf_free(buf);
687 		return QDF_STATUS_E_FAILURE;
688 	}
689 
690 	return QDF_STATUS_SUCCESS;
691 }
692 
693 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi,
694 					      struct pmo_hw_filter_params *req)
695 {
696 	QDF_STATUS status;
697 	wmi_hw_data_filter_cmd_fixed_param *cmd;
698 	wmi_buf_t wmi_buf;
699 
700 	if (!req) {
701 		wmi_err("req is null");
702 		return QDF_STATUS_E_INVAL;
703 	}
704 
705 	wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd));
706 	if (!wmi_buf) {
707 		return QDF_STATUS_E_NOMEM;
708 	}
709 
710 	cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf);
711 	WMITLV_SET_HDR(&cmd->tlv_header,
712 		  WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param,
713 		  WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param));
714 	cmd->vdev_id = req->vdev_id;
715 	cmd->enable = req->enable;
716 	/* Set all modes in case of disable */
717 	if (!cmd->enable)
718 		cmd->hw_filter_bitmap = ((uint32_t)~0U);
719 	else
720 		cmd->hw_filter_bitmap = req->mode_bitmap;
721 
722 	wmi_debug("Send %s hw filter mode: 0x%X for vdev id %d",
723 		 req->enable ? "enable" : "disable", req->mode_bitmap,
724 		 req->vdev_id);
725 
726 	wmi_mtrace(WMI_HW_DATA_FILTER_CMDID, cmd->vdev_id, 0);
727 	status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd),
728 				      WMI_HW_DATA_FILTER_CMDID);
729 	if (QDF_IS_STATUS_ERROR(status)) {
730 		wmi_err("Failed to configure hw filter");
731 		wmi_buf_free(wmi_buf);
732 	}
733 
734 	return status;
735 }
736 
737 static void
738 fill_fils_tlv_params(WMI_GTK_OFFLOAD_CMD_fixed_param *cmd,
739 			  uint8_t vdev_id,
740 			  struct pmo_gtk_req *params)
741 {
742 	uint8_t *buf_ptr;
743 	wmi_gtk_offload_fils_tlv_param *ext_param;
744 
745 	buf_ptr = (uint8_t *) cmd + sizeof(*cmd);
746 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
747 		       sizeof(*ext_param));
748 	buf_ptr += WMI_TLV_HDR_SIZE;
749 
750 	ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr;
751 	WMITLV_SET_HDR(&ext_param->tlv_header,
752 		       WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param,
753 		       WMITLV_GET_STRUCT_TLVLEN(
754 				wmi_gtk_offload_fils_tlv_param));
755 	ext_param->vdev_id = vdev_id;
756 	ext_param->flags = cmd->flags;
757 	ext_param->kek_len = params->kek_len;
758 	qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len);
759 	qdf_mem_copy(ext_param->KCK, params->kck,
760 		     WMI_GTK_OFFLOAD_KCK_BYTES);
761 	qdf_mem_copy(ext_param->replay_counter, &params->replay_counter,
762 		     GTK_REPLAY_COUNTER_BYTES);
763 }
764 
765 #ifdef WLAN_FEATURE_IGMP_OFFLOAD
766 /**
767  * send_igmp_offload_cmd_tlv() - send IGMP offload command to fw
768  * @wmi_handle: wmi handle
769  * @params: IGMP offload parameters
770  *
771  * Return: CDF status
772  */
773 static
774 QDF_STATUS send_igmp_offload_cmd_tlv(wmi_unified_t wmi_handle,
775 				     struct pmo_igmp_offload_req *pmo_igmp_req)
776 {
777 	wmi_buf_t buf;
778 	uint8_t *buf_ptr;
779 	int len;
780 	int i = 0;
781 	WMI_IPV4_ADDR *ipv4_list;
782 	wmi_igmp_offload_fixed_param *cmd;
783 	QDF_STATUS status = QDF_STATUS_SUCCESS;
784 
785 	len = sizeof(wmi_igmp_offload_fixed_param) + WMI_TLV_HDR_SIZE +
786 	     (pmo_igmp_req->num_grp_ip_address) * sizeof(WMI_IPV4_ADDR);
787 	/* alloc wmi buffer */
788 	buf = wmi_buf_alloc(wmi_handle, len);
789 	if (!buf) {
790 		status = QDF_STATUS_E_NOMEM;
791 		goto out;
792 	}
793 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
794 	cmd = (wmi_igmp_offload_fixed_param *)wmi_buf_data(buf);
795 
796 	WMITLV_SET_HDR(&cmd->tlv_header,
797 		       WMITLV_TAG_STRUC_wmi_igmp_offload_fixed_param,
798 		       WMITLV_GET_STRUCT_TLVLEN(wmi_igmp_offload_fixed_param));
799 
800 	cmd->vdev_id = pmo_igmp_req->vdev_id;
801 	cmd->enable = pmo_igmp_req->enable;
802 	cmd->version_support_bitmask =
803 				pmo_igmp_req->version_support;
804 
805 	buf_ptr += sizeof(*cmd);
806 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
807 		       sizeof(WMI_IPV4_ADDR) *
808 		       pmo_igmp_req->num_grp_ip_address);
809 
810 	ipv4_list = (WMI_IPV4_ADDR *)(buf_ptr + WMI_TLV_HDR_SIZE);
811 
812 	while (i < pmo_igmp_req->num_grp_ip_address) {
813 		qdf_mem_copy((void *)((*(ipv4_list + i)).address),
814 			     (void *)&(pmo_igmp_req->grp_ip_address[i]),
815 			     WMI_IPV4_ADDR_LEN);
816 		wmi_debug("piv4[%d]:%x", i, *(uint32_t *)(ipv4_list + i));
817 		i++;
818 	}
819 
820 	wmi_debug("VDEVID:%d, FLAG:x%x version support:%d",
821 		  cmd->vdev_id, cmd->enable,
822 		  cmd->version_support_bitmask);
823 
824 	/* send the wmi command */
825 	wmi_mtrace(WMI_VDEV_IGMP_OFFLOAD_CMDID, cmd->vdev_id, 0);
826 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
827 				 WMI_VDEV_IGMP_OFFLOAD_CMDID)) {
828 		wmi_err("Failed to send WMI_VDEV_IGMP_OFFLOAD_CMDID");
829 		wmi_buf_free(buf);
830 		status = QDF_STATUS_E_FAILURE;
831 	}
832 out:
833 	return status;
834 }
835 #endif
836 
837 /**
838  * send_gtk_offload_cmd_tlv() - send GTK offload command to fw
839  * @wmi_handle: wmi handle
840  * @vdev_id: vdev id
841  * @params: GTK offload parameters
842  *
843  * Return: CDF status
844  */
845 static
846 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
847 				    struct pmo_gtk_req *params,
848 				    bool enable_offload,
849 				    uint32_t gtk_offload_opcode)
850 {
851 	int len;
852 	wmi_buf_t buf;
853 	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
854 	QDF_STATUS status = QDF_STATUS_SUCCESS;
855 
856 	len = sizeof(*cmd);
857 
858 	if (params->is_fils_connection)
859 		len += WMI_TLV_HDR_SIZE +
860 		       sizeof(wmi_gtk_offload_fils_tlv_param);
861 
862 	/* alloc wmi buffer */
863 	buf = wmi_buf_alloc(wmi_handle, len);
864 	if (!buf) {
865 		status = QDF_STATUS_E_NOMEM;
866 		goto out;
867 	}
868 
869 	cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
870 	WMITLV_SET_HDR(&cmd->tlv_header,
871 		       WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
872 		       WMITLV_GET_STRUCT_TLVLEN
873 			       (WMI_GTK_OFFLOAD_CMD_fixed_param));
874 
875 	cmd->vdev_id = vdev_id;
876 
877 	/* Request target to enable GTK offload */
878 	if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) {
879 		cmd->flags = gtk_offload_opcode;
880 
881 		/* Copy the keys and replay counter */
882 		qdf_mem_copy(cmd->KCK, params->kck, sizeof(cmd->KCK));
883 		qdf_mem_copy(cmd->KEK, params->kek, sizeof(cmd->KEK));
884 		qdf_mem_copy(cmd->replay_counter, &params->replay_counter,
885 			     GTK_REPLAY_COUNTER_BYTES);
886 	} else {
887 		cmd->flags = gtk_offload_opcode;
888 	}
889 	if (params->is_fils_connection)
890 		fill_fils_tlv_params(cmd, vdev_id, params);
891 
892 	wmi_debug("VDEVID: %d, GTK_FLAGS: x%x kek len %d",
893 		 vdev_id, cmd->flags, params->kek_len);
894 	/* send the wmi command */
895 	wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0);
896 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
897 				 WMI_GTK_OFFLOAD_CMDID)) {
898 		wmi_err("Failed to send WMI_GTK_OFFLOAD_CMDID");
899 		wmi_buf_free(buf);
900 		status = QDF_STATUS_E_FAILURE;
901 	}
902 
903 out:
904 	return status;
905 }
906 
907 /**
908  * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw
909  * @wmi_handle: wmi handle
910  * @params: GTK offload params
911  *
912  * Return: CDF status
913  */
914 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv(
915 			wmi_unified_t wmi_handle,
916 			uint8_t vdev_id,
917 			uint64_t offload_req_opcode)
918 {
919 	int len;
920 	wmi_buf_t buf;
921 	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
922 	QDF_STATUS status = QDF_STATUS_SUCCESS;
923 
924 	len = sizeof(*cmd);
925 
926 	/* alloc wmi buffer */
927 	buf = wmi_buf_alloc(wmi_handle, len);
928 	if (!buf) {
929 		status = QDF_STATUS_E_NOMEM;
930 		goto out;
931 	}
932 
933 	cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
934 	WMITLV_SET_HDR(&cmd->tlv_header,
935 		       WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
936 		       WMITLV_GET_STRUCT_TLVLEN
937 			       (WMI_GTK_OFFLOAD_CMD_fixed_param));
938 
939 	/* Request for GTK offload status */
940 	cmd->flags = offload_req_opcode;
941 	cmd->vdev_id = vdev_id;
942 
943 	/* send the wmi command */
944 	wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0);
945 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
946 				 WMI_GTK_OFFLOAD_CMDID)) {
947 		wmi_err("Failed to send WMI_GTK_OFFLOAD_CMDID for req info");
948 		wmi_buf_free(buf);
949 		status = QDF_STATUS_E_FAILURE;
950 	}
951 
952 out:
953 	return status;
954 }
955 
956 /**
957  * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload
958  * @wmi_handle: wmi handle
959  * @vdev_id: vdev id
960  * @action: true for enable else false
961  *
962  * To enable enhance multicast offload to firmware
963  * when target goes to wow mode.
964  *
965  * Return: QDF Status
966  */
967 
968 static
969 QDF_STATUS send_enable_enhance_multicast_offload_tlv(
970 		wmi_unified_t wmi_handle,
971 		uint8_t vdev_id, bool action)
972 {
973 	QDF_STATUS status;
974 	wmi_buf_t buf;
975 	wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd;
976 
977 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
978 	if (!buf) {
979 		return QDF_STATUS_E_NOMEM;
980 	}
981 
982 	cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *)
983 							wmi_buf_data(buf);
984 
985 	WMITLV_SET_HDR(&cmd->tlv_header,
986 		WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param,
987 		WMITLV_GET_STRUCT_TLVLEN(
988 			wmi_config_enhanced_mcast_filter_cmd_fixed_param));
989 
990 	cmd->vdev_id = vdev_id;
991 	cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED :
992 			ENHANCED_MCAST_FILTER_ENABLED);
993 	wmi_debug("config enhance multicast offload action %d for vdev %d",
994 		 action, vdev_id);
995 	wmi_mtrace(WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID, cmd->vdev_id, 0);
996 	status = wmi_unified_cmd_send(wmi_handle, buf,
997 			sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID);
998 	if (status != QDF_STATUS_SUCCESS) {
999 		wmi_buf_free(buf);
1000 		wmi_err("Failed to send ENHANCED_MCAST_FILTER_CMDID");
1001 	}
1002 
1003 	return status;
1004 }
1005 
1006 /**
1007  * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event
1008  * @wmi_handle: wmi handle
1009  * @param evt_buf: pointer to event buffer
1010  * @param hdr: Pointer to hold header
1011  * @param bufp: Pointer to hold pointer to rx param buffer
1012  *
1013  * Return: QDF_STATUS_SUCCESS for success or error code
1014  */
1015 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle,
1016 	void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len)
1017 {
1018 	WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param;
1019 	WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf;
1020 
1021 	param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf;
1022 	if (!param_buf) {
1023 		wmi_err("gtk param_buf is NULL");
1024 		return QDF_STATUS_E_INVAL;
1025 	}
1026 
1027 	if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) {
1028 		wmi_err("Invalid length for GTK status");
1029 		return QDF_STATUS_E_INVAL;
1030 	}
1031 
1032 	fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *)
1033 		param_buf->fixed_param;
1034 
1035 	if (fixed_param->vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
1036 		wmi_err_rl("Invalid vdev_id %u", fixed_param->vdev_id);
1037 		return QDF_STATUS_E_INVAL;
1038 	}
1039 
1040 	gtk_rsp_param->vdev_id = fixed_param->vdev_id;
1041 	gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS;
1042 	gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt;
1043 	qdf_mem_copy(&gtk_rsp_param->replay_counter,
1044 		&fixed_param->replay_counter,
1045 		GTK_REPLAY_COUNTER_BYTES);
1046 
1047 	return QDF_STATUS_SUCCESS;
1048 
1049 }
1050 
1051 #ifdef FEATURE_WLAN_RA_FILTERING
1052 /**
1053  * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw
1054  * @wmi_handle: wmi handle
1055  * @vdev_id: vdev id
1056  *
1057  * Return: CDF status
1058  */
1059 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle,
1060 						 uint8_t vdev_id,
1061 						 uint8_t default_pattern,
1062 						 uint16_t rate_limit_interval)
1063 {
1064 
1065 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
1066 	wmi_buf_t buf;
1067 	uint8_t *buf_ptr;
1068 	int32_t len;
1069 	int ret;
1070 
1071 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
1072 	      WMI_TLV_HDR_SIZE +
1073 	      0 * sizeof(WOW_BITMAP_PATTERN_T) +
1074 	      WMI_TLV_HDR_SIZE +
1075 	      0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
1076 	      WMI_TLV_HDR_SIZE +
1077 	      0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
1078 	      WMI_TLV_HDR_SIZE +
1079 	      0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
1080 	      WMI_TLV_HDR_SIZE +
1081 	      0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
1082 
1083 	buf = wmi_buf_alloc(wmi_handle, len);
1084 	if (!buf) {
1085 		return QDF_STATUS_E_NOMEM;
1086 	}
1087 
1088 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
1089 	buf_ptr = (uint8_t *) cmd;
1090 
1091 	WMITLV_SET_HDR(&cmd->tlv_header,
1092 		       WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
1093 		       WMITLV_GET_STRUCT_TLVLEN
1094 			       (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
1095 	cmd->vdev_id = vdev_id;
1096 	cmd->pattern_id = default_pattern,
1097 	cmd->pattern_type = WOW_IPV6_RA_PATTERN;
1098 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
1099 
1100 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
1101 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
1102 	buf_ptr += WMI_TLV_HDR_SIZE;
1103 
1104 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
1105 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
1106 	buf_ptr += WMI_TLV_HDR_SIZE;
1107 
1108 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
1109 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
1110 	buf_ptr += WMI_TLV_HDR_SIZE;
1111 
1112 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
1113 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
1114 	buf_ptr += WMI_TLV_HDR_SIZE;
1115 
1116 	/* Fill TLV for pattern_info_timeout but no data. */
1117 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
1118 	buf_ptr += WMI_TLV_HDR_SIZE;
1119 
1120 	/* Fill TLV for ra_ratelimit_interval. */
1121 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
1122 	buf_ptr += WMI_TLV_HDR_SIZE;
1123 
1124 	*((uint32_t *) buf_ptr) = rate_limit_interval;
1125 
1126 	wmi_debug("send RA rate limit [%d] to fw vdev = %d",
1127 		 rate_limit_interval, vdev_id);
1128 
1129 	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
1130 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1131 				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
1132 	if (ret) {
1133 		wmi_err("Failed to send RA rate limit to fw");
1134 		wmi_buf_free(buf);
1135 		return QDF_STATUS_E_FAILURE;
1136 	}
1137 
1138 	return QDF_STATUS_SUCCESS;
1139 }
1140 
1141 void wmi_ra_filtering_attach_tlv(struct wmi_unified *wmi_handle)
1142 {
1143 	struct wmi_ops *ops = wmi_handle->ops;
1144 
1145 	ops->send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv;
1146 }
1147 #endif /* FEATURE_WLAN_RA_FILTERING */
1148 
1149 /**
1150  * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params
1151  * @wmi_handle: wmi handler
1152  * @action_params: pointer to action_params
1153  *
1154  * Return: 0 for success, otherwise appropriate error code
1155  */
1156 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle,
1157 		struct pmo_action_wakeup_set_params *action_params)
1158 {
1159 	WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd;
1160 	wmi_buf_t buf;
1161 	int i;
1162 	int32_t err;
1163 	uint32_t len = 0, *cmd_args;
1164 	uint8_t *buf_ptr;
1165 
1166 	len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))
1167 				+ WMI_TLV_HDR_SIZE + sizeof(*cmd);
1168 	buf = wmi_buf_alloc(wmi_handle, len);
1169 	if (!buf) {
1170 		return QDF_STATUS_E_NOMEM;
1171 	}
1172 	cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf);
1173 	buf_ptr = (uint8_t *)cmd;
1174 	WMITLV_SET_HDR(&cmd->tlv_header,
1175 		WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param,
1176 		WMITLV_GET_STRUCT_TLVLEN(
1177 				WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param));
1178 
1179 	cmd->vdev_id = action_params->vdev_id;
1180 	cmd->operation = action_params->operation;
1181 
1182 	for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++)
1183 		cmd->action_category_map[i] =
1184 				action_params->action_category_map[i];
1185 
1186 	buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param);
1187 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
1188 		       (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)));
1189 	buf_ptr += WMI_TLV_HDR_SIZE;
1190 	cmd_args = (uint32_t *) buf_ptr;
1191 	for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++)
1192 		cmd_args[i] = action_params->action_per_category[i];
1193 
1194 	wmi_mtrace(WMI_WOW_SET_ACTION_WAKE_UP_CMDID, cmd->vdev_id, 0);
1195 	err = wmi_unified_cmd_send(wmi_handle, buf,
1196 				   len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID);
1197 	if (err) {
1198 		wmi_err("Failed to send ap_ps_egap cmd");
1199 		wmi_buf_free(buf);
1200 		return QDF_STATUS_E_FAILURE;
1201 	}
1202 
1203 	return QDF_STATUS_SUCCESS;
1204 }
1205 
1206 #ifdef FEATURE_WLAN_LPHB
1207 /**
1208  * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration
1209  * @wmi_handle: wmi handle
1210  * @lphb_conf_req: configuration info
1211  *
1212  * Return: CDF status
1213  */
1214 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle,
1215 				wmi_hb_set_enable_cmd_fixed_param *params)
1216 {
1217 	QDF_STATUS status;
1218 	wmi_buf_t buf = NULL;
1219 	uint8_t *buf_ptr;
1220 	wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp;
1221 	int len = sizeof(wmi_hb_set_enable_cmd_fixed_param);
1222 
1223 	buf = wmi_buf_alloc(wmi_handle, len);
1224 	if (!buf) {
1225 		return QDF_STATUS_E_NOMEM;
1226 	}
1227 
1228 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
1229 	hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr;
1230 	WMITLV_SET_HDR(&hb_enable_fp->tlv_header,
1231 		       WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param,
1232 		       WMITLV_GET_STRUCT_TLVLEN
1233 			       (wmi_hb_set_enable_cmd_fixed_param));
1234 
1235 	/* fill in values */
1236 	hb_enable_fp->vdev_id = params->session;
1237 	hb_enable_fp->enable = params->enable;
1238 	hb_enable_fp->item = params->item;
1239 	hb_enable_fp->session = params->session;
1240 
1241 	wmi_mtrace(WMI_HB_SET_ENABLE_CMDID, NO_SESSION, 0);
1242 	status = wmi_unified_cmd_send(wmi_handle, buf,
1243 				      len, WMI_HB_SET_ENABLE_CMDID);
1244 	if (QDF_IS_STATUS_ERROR(status)) {
1245 		wmi_err("cmd_send WMI_HB_SET_ENABLE returned Error %d",
1246 			 status);
1247 		wmi_buf_free(buf);
1248 	}
1249 
1250 	return status;
1251 }
1252 
1253 /**
1254  * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration
1255  * @wmi_handle: wmi handle
1256  * @lphb_conf_req: lphb config request
1257  *
1258  * Return: CDF status
1259  */
1260 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle,
1261 	    wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req)
1262 {
1263 	QDF_STATUS status;
1264 	wmi_buf_t buf = NULL;
1265 	uint8_t *buf_ptr;
1266 	wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp;
1267 	int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param);
1268 
1269 	buf = wmi_buf_alloc(wmi_handle, len);
1270 	if (!buf) {
1271 		return QDF_STATUS_E_NOMEM;
1272 	}
1273 
1274 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
1275 	hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr;
1276 	WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header,
1277 		       WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param,
1278 		       WMITLV_GET_STRUCT_TLVLEN
1279 			       (wmi_hb_set_tcp_params_cmd_fixed_param));
1280 
1281 	/* fill in values */
1282 	hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id;
1283 	hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip;
1284 	hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip;
1285 	hb_tcp_params_fp->seq = lphb_conf_req->seq;
1286 	hb_tcp_params_fp->src_port = lphb_conf_req->src_port;
1287 	hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port;
1288 	hb_tcp_params_fp->interval = lphb_conf_req->interval;
1289 	hb_tcp_params_fp->timeout = lphb_conf_req->timeout;
1290 	hb_tcp_params_fp->session = lphb_conf_req->session;
1291 	qdf_mem_copy(&hb_tcp_params_fp->gateway_mac,
1292 		     &lphb_conf_req->gateway_mac,
1293 		     sizeof(hb_tcp_params_fp->gateway_mac));
1294 
1295 	wmi_mtrace(WMI_HB_SET_TCP_PARAMS_CMDID, NO_SESSION, 0);
1296 	status = wmi_unified_cmd_send(wmi_handle, buf,
1297 				      len, WMI_HB_SET_TCP_PARAMS_CMDID);
1298 	if (QDF_IS_STATUS_ERROR(status)) {
1299 		wmi_err("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d",
1300 			 status);
1301 		wmi_buf_free(buf);
1302 	}
1303 
1304 	return status;
1305 }
1306 
1307 /**
1308  * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd
1309  * @wmi_handle: wmi handle
1310  * @lphb_conf_req: lphb config request
1311  *
1312  * Return: CDF status
1313  */
1314 static
1315 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
1316 		wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp)
1317 {
1318 	QDF_STATUS status;
1319 	wmi_buf_t buf = NULL;
1320 	uint8_t *buf_ptr;
1321 	wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp;
1322 	int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param);
1323 
1324 	buf = wmi_buf_alloc(wmi_handle, len);
1325 	if (!buf) {
1326 		return QDF_STATUS_E_NOMEM;
1327 	}
1328 
1329 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
1330 	hb_tcp_filter_fp =
1331 		(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr;
1332 	WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header,
1333 		WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param,
1334 		WMITLV_GET_STRUCT_TLVLEN
1335 		       (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param));
1336 
1337 	/* fill in values */
1338 	hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id;
1339 	hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length;
1340 	hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset;
1341 	hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session;
1342 	memcpy((void *)&hb_tcp_filter_fp->filter,
1343 	       (void *)&g_hb_tcp_filter_fp->filter,
1344 	       WMI_WLAN_HB_MAX_FILTER_SIZE);
1345 
1346 	wmi_mtrace(WMI_HB_SET_TCP_PKT_FILTER_CMDID, NO_SESSION, 0);
1347 	status = wmi_unified_cmd_send(wmi_handle, buf,
1348 				      len, WMI_HB_SET_TCP_PKT_FILTER_CMDID);
1349 	if (QDF_IS_STATUS_ERROR(status)) {
1350 		wmi_err("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d",
1351 			 status);
1352 		wmi_buf_free(buf);
1353 	}
1354 
1355 	return status;
1356 }
1357 
1358 /**
1359  * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB
1360  * @wmi_handle: wmi handle
1361  * @lphb_conf_req: lphb config request
1362  *
1363  * Return: CDF status
1364  */
1365 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle,
1366 		   wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req)
1367 {
1368 	QDF_STATUS status;
1369 	wmi_buf_t buf = NULL;
1370 	uint8_t *buf_ptr;
1371 	wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp;
1372 	int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param);
1373 
1374 	buf = wmi_buf_alloc(wmi_handle, len);
1375 	if (!buf) {
1376 		return QDF_STATUS_E_NOMEM;
1377 	}
1378 
1379 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
1380 	hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr;
1381 	WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header,
1382 		       WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param,
1383 		       WMITLV_GET_STRUCT_TLVLEN
1384 			       (wmi_hb_set_udp_params_cmd_fixed_param));
1385 
1386 	/* fill in values */
1387 	hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id;
1388 	hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip;
1389 	hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip;
1390 	hb_udp_params_fp->src_port = lphb_conf_req->src_port;
1391 	hb_udp_params_fp->dst_port = lphb_conf_req->dst_port;
1392 	hb_udp_params_fp->interval = lphb_conf_req->interval;
1393 	hb_udp_params_fp->timeout = lphb_conf_req->timeout;
1394 	hb_udp_params_fp->session = lphb_conf_req->session;
1395 	qdf_mem_copy(&hb_udp_params_fp->gateway_mac,
1396 		     &lphb_conf_req->gateway_mac,
1397 		     sizeof(lphb_conf_req->gateway_mac));
1398 
1399 	wmi_mtrace(WMI_HB_SET_UDP_PARAMS_CMDID, NO_SESSION, 0);
1400 	status = wmi_unified_cmd_send(wmi_handle, buf,
1401 				      len, WMI_HB_SET_UDP_PARAMS_CMDID);
1402 	if (QDF_IS_STATUS_ERROR(status)) {
1403 		wmi_err("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d",
1404 			 status);
1405 		wmi_buf_free(buf);
1406 	}
1407 
1408 	return status;
1409 }
1410 
1411 /**
1412  * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command
1413  * @wmi_handle: wmi handle
1414  * @lphb_conf_req: lphb config request
1415  *
1416  * Return: CDF status
1417  */
1418 static
1419 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
1420 		wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req)
1421 {
1422 	QDF_STATUS status;
1423 	wmi_buf_t buf = NULL;
1424 	uint8_t *buf_ptr;
1425 	wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp;
1426 	int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param);
1427 
1428 	buf = wmi_buf_alloc(wmi_handle, len);
1429 	if (!buf) {
1430 		return QDF_STATUS_E_NOMEM;
1431 	}
1432 
1433 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
1434 	hb_udp_filter_fp =
1435 		(wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr;
1436 	WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header,
1437 		WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param,
1438 		WMITLV_GET_STRUCT_TLVLEN
1439 		       (wmi_hb_set_udp_pkt_filter_cmd_fixed_param));
1440 
1441 	/* fill in values */
1442 	hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id;
1443 	hb_udp_filter_fp->length = lphb_conf_req->length;
1444 	hb_udp_filter_fp->offset = lphb_conf_req->offset;
1445 	hb_udp_filter_fp->session = lphb_conf_req->session;
1446 	memcpy((void *)&hb_udp_filter_fp->filter,
1447 	       (void *)&lphb_conf_req->filter,
1448 	       WMI_WLAN_HB_MAX_FILTER_SIZE);
1449 
1450 	wmi_mtrace(WMI_HB_SET_UDP_PKT_FILTER_CMDID, NO_SESSION, 0);
1451 	status = wmi_unified_cmd_send(wmi_handle, buf,
1452 				      len, WMI_HB_SET_UDP_PKT_FILTER_CMDID);
1453 	if (QDF_IS_STATUS_ERROR(status)) {
1454 		wmi_err("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d",
1455 			 status);
1456 		wmi_buf_free(buf);
1457 	}
1458 
1459 	return status;
1460 }
1461 
1462 void wmi_lphb_attach_tlv(struct wmi_unified *wmi_handle)
1463 {
1464 	struct wmi_ops *ops = wmi_handle->ops;
1465 
1466 	ops->send_lphb_config_hbenable_cmd =
1467 		send_lphb_config_hbenable_cmd_tlv;
1468 	ops->send_lphb_config_tcp_params_cmd =
1469 		send_lphb_config_tcp_params_cmd_tlv;
1470 	ops->send_lphb_config_tcp_pkt_filter_cmd =
1471 		send_lphb_config_tcp_pkt_filter_cmd_tlv;
1472 	ops->send_lphb_config_udp_params_cmd =
1473 		send_lphb_config_udp_params_cmd_tlv;
1474 	ops->send_lphb_config_udp_pkt_filter_cmd =
1475 		send_lphb_config_udp_pkt_filter_cmd_tlv;
1476 }
1477 #endif /* FEATURE_WLAN_LPHB */
1478 
1479 #ifdef WLAN_FEATURE_PACKET_FILTERING
1480 /**
1481  * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter
1482  * @wmi_handle: wmi handle
1483  * @vdev_id: vdev id
1484  * @enable: Flag to enable/disable packet filter
1485  *
1486  * Return: QDF_STATUS_SUCCESS for success or error code
1487  */
1488 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv(
1489 		wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable)
1490 {
1491 	int32_t len;
1492 	int ret = 0;
1493 	wmi_buf_t buf;
1494 	WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd;
1495 
1496 	len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param);
1497 
1498 	buf = wmi_buf_alloc(wmi_handle, len);
1499 	if (!buf) {
1500 		return QDF_STATUS_E_NOMEM;
1501 	}
1502 
1503 	cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf);
1504 	WMITLV_SET_HDR(&cmd->tlv_header,
1505 		WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param,
1506 		WMITLV_GET_STRUCT_TLVLEN(
1507 			WMI_PACKET_FILTER_ENABLE_CMD_fixed_param));
1508 
1509 	cmd->vdev_id = vdev_id;
1510 	if (enable)
1511 		cmd->enable = PACKET_FILTER_SET_ENABLE;
1512 	else
1513 		cmd->enable = PACKET_FILTER_SET_DISABLE;
1514 
1515 	wmi_err("Packet filter enable %d for vdev_id %d", cmd->enable, vdev_id);
1516 
1517 	wmi_mtrace(WMI_PACKET_FILTER_ENABLE_CMDID, cmd->vdev_id, 0);
1518 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1519 				   WMI_PACKET_FILTER_ENABLE_CMDID);
1520 	if (ret) {
1521 		wmi_err("Failed to send packet filter wmi cmd to fw");
1522 		wmi_buf_free(buf);
1523 	}
1524 
1525 	return ret;
1526 }
1527 
1528 /**
1529  * send_config_packet_filter_cmd_tlv() - configure packet filter in target
1530  * @wmi_handle: wmi handle
1531  * @vdev_id: vdev id
1532  * @rcv_filter_param: Packet filter parameters
1533  * @filter_id: Filter id
1534  * @enable: Flag to add/delete packet filter configuration
1535  *
1536  * Return: QDF_STATUS_SUCCESS for success or error code
1537  */
1538 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle,
1539 		uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param,
1540 		uint8_t filter_id, bool enable)
1541 {
1542 	int len, i;
1543 	int err = 0;
1544 	wmi_buf_t buf;
1545 	WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd;
1546 
1547 	/* allocate the memory */
1548 	len = sizeof(*cmd);
1549 	buf = wmi_buf_alloc(wmi_handle, len);
1550 	if (!buf) {
1551 		return QDF_STATUS_E_NOMEM;
1552 	}
1553 
1554 	cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf);
1555 	WMITLV_SET_HDR(&cmd->tlv_header,
1556 		WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param,
1557 		WMITLV_GET_STRUCT_TLVLEN
1558 			       (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param));
1559 
1560 	cmd->vdev_id = vdev_id;
1561 	cmd->filter_id = filter_id;
1562 	if (enable)
1563 		cmd->filter_action = PACKET_FILTER_SET_ACTIVE;
1564 	else
1565 		cmd->filter_action = PACKET_FILTER_SET_INACTIVE;
1566 
1567 	if (enable) {
1568 		cmd->num_params = QDF_MIN(
1569 			WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER,
1570 			rcv_filter_param->num_params);
1571 		cmd->filter_type = rcv_filter_param->filter_type;
1572 		cmd->coalesce_time = rcv_filter_param->coalesce_time;
1573 
1574 		for (i = 0; i < cmd->num_params; i++) {
1575 			cmd->paramsData[i].proto_type =
1576 				rcv_filter_param->params_data[i].protocol_layer;
1577 			cmd->paramsData[i].cmp_type =
1578 				rcv_filter_param->params_data[i].compare_flag;
1579 			cmd->paramsData[i].data_length =
1580 				rcv_filter_param->params_data[i].data_length;
1581 			cmd->paramsData[i].data_offset =
1582 				rcv_filter_param->params_data[i].data_offset;
1583 			memcpy(&cmd->paramsData[i].compareData,
1584 				rcv_filter_param->params_data[i].compare_data,
1585 				sizeof(cmd->paramsData[i].compareData));
1586 			memcpy(&cmd->paramsData[i].dataMask,
1587 				rcv_filter_param->params_data[i].data_mask,
1588 				sizeof(cmd->paramsData[i].dataMask));
1589 		}
1590 	}
1591 
1592 	wmi_err("Packet filter action %d filter with id: %d, num_params=%d",
1593 		 cmd->filter_action, cmd->filter_id, cmd->num_params);
1594 	/* send the command along with data */
1595 	wmi_mtrace(WMI_PACKET_FILTER_CONFIG_CMDID, cmd->vdev_id, 0);
1596 	err = wmi_unified_cmd_send(wmi_handle, buf, len,
1597 				   WMI_PACKET_FILTER_CONFIG_CMDID);
1598 	if (err) {
1599 		wmi_err("Failed to send pkt_filter cmd");
1600 		wmi_buf_free(buf);
1601 		return QDF_STATUS_E_FAILURE;
1602 	}
1603 
1604 	return QDF_STATUS_SUCCESS;
1605 }
1606 
1607 void wmi_packet_filtering_attach_tlv(struct wmi_unified *wmi_handle)
1608 {
1609 	struct wmi_ops *ops = wmi_handle->ops;
1610 
1611 	ops->send_enable_disable_packet_filter_cmd =
1612 		send_enable_disable_packet_filter_cmd_tlv;
1613 	ops->send_config_packet_filter_cmd =
1614 		send_config_packet_filter_cmd_tlv;
1615 }
1616 #endif /* WLAN_FEATURE_PACKET_FILTERING */
1617 
1618 /**
1619  * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target
1620  * @wmi_handle: wmi handle
1621  * @ptrn_id: pattern id
1622  * @vdev_id: vdev id
1623  *
1624  * Return: CDF status
1625  */
1626 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle,
1627 						  uint8_t ptrn_id,
1628 						  uint8_t vdev_id)
1629 {
1630 	WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd;
1631 	wmi_buf_t buf;
1632 	int32_t len;
1633 	int ret;
1634 
1635 	len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param);
1636 
1637 	buf = wmi_buf_alloc(wmi_handle, len);
1638 	if (!buf) {
1639 		return QDF_STATUS_E_NOMEM;
1640 	}
1641 
1642 	cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
1643 
1644 	WMITLV_SET_HDR(&cmd->tlv_header,
1645 		       WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param,
1646 		       WMITLV_GET_STRUCT_TLVLEN(
1647 				WMI_WOW_DEL_PATTERN_CMD_fixed_param));
1648 	cmd->vdev_id = vdev_id;
1649 	cmd->pattern_id = ptrn_id;
1650 	cmd->pattern_type = WOW_BITMAP_PATTERN;
1651 
1652 	wmi_mtrace(WMI_WOW_DEL_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
1653 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1654 				   WMI_WOW_DEL_WAKE_PATTERN_CMDID);
1655 	if (ret) {
1656 		wmi_err("Failed to delete wow ptrn from fw");
1657 		wmi_buf_free(buf);
1658 		return QDF_STATUS_E_FAILURE;
1659 	}
1660 
1661 	return QDF_STATUS_SUCCESS;
1662 }
1663 
1664 #ifdef WMI_HOST_WAKEUP_OVER_QMI
1665 static inline
1666 QDF_STATUS wmi_unified_cmd_send_chk(struct wmi_unified *wmi_handle,
1667 				    wmi_buf_t buf,
1668 				    uint32_t buflen, uint32_t cmd_id)
1669 {
1670 	wmi_debug("Send WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID over QMI");
1671 	return wmi_unified_cmd_send_over_qmi(wmi_handle, buf,
1672 					     buflen, cmd_id);
1673 }
1674 #else
1675 static inline
1676 QDF_STATUS wmi_unified_cmd_send_chk(struct wmi_unified *wmi_handle,
1677 				    wmi_buf_t buf,
1678 				    uint32_t buflen, uint32_t cmd_id)
1679 {
1680 	return wmi_unified_cmd_send(wmi_handle, buf,
1681 				    buflen, cmd_id);
1682 }
1683 #endif
1684 
1685 /**
1686  * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw
1687  * @wmi_handle: wmi handle
1688  *
1689  * Sends host wakeup indication to FW. On receiving this indication,
1690  * FW will come out of WOW.
1691  *
1692  * Return: CDF status
1693  */
1694 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle)
1695 {
1696 	wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd;
1697 	wmi_buf_t buf;
1698 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1699 	int32_t len;
1700 	int ret;
1701 
1702 	len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param);
1703 
1704 	buf = wmi_buf_alloc(wmi_handle, len);
1705 	if (!buf) {
1706 		return QDF_STATUS_E_NOMEM;
1707 	}
1708 
1709 	cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *)
1710 	      wmi_buf_data(buf);
1711 	WMITLV_SET_HDR(&cmd->tlv_header,
1712 		WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param,
1713 		WMITLV_GET_STRUCT_TLVLEN
1714 			(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param));
1715 
1716 	wmi_mtrace(WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, NO_SESSION, 0);
1717 	ret = wmi_unified_cmd_send_chk(wmi_handle, buf, len,
1718 				       WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID);
1719 	if (ret) {
1720 		wmi_err("Failed to send host wakeup indication to fw");
1721 		wmi_buf_free(buf);
1722 		return QDF_STATUS_E_FAILURE;
1723 	}
1724 
1725 	return qdf_status;
1726 }
1727 
1728 /**
1729  * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware
1730  * will wake up host after specified time is elapsed
1731  * @wmi_handle: wmi handle
1732  * @vdev_id: vdev id
1733  * @cookie: value to identify reason why host set up wake call.
1734  * @time: time in ms
1735  *
1736  * Return: QDF status
1737  */
1738 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle,
1739 				uint8_t vdev_id, uint32_t cookie, uint32_t time)
1740 {
1741 	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
1742 	wmi_buf_t buf;
1743 	uint8_t *buf_ptr;
1744 	int32_t len;
1745 	int ret;
1746 
1747 	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
1748 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) +
1749 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
1750 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
1751 		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
1752 		WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) +
1753 		WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
1754 
1755 	buf = wmi_buf_alloc(wmi_handle, len);
1756 	if (!buf) {
1757 		return QDF_STATUS_E_NOMEM;
1758 	}
1759 
1760 	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
1761 	buf_ptr = (uint8_t *) cmd;
1762 
1763 	WMITLV_SET_HDR(&cmd->tlv_header,
1764 		WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
1765 		WMITLV_GET_STRUCT_TLVLEN
1766 			(WMI_WOW_ADD_PATTERN_CMD_fixed_param));
1767 	cmd->vdev_id = vdev_id;
1768 	cmd->pattern_id = cookie,
1769 	cmd->pattern_type = WOW_TIMER_PATTERN;
1770 	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
1771 
1772 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
1773 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
1774 	buf_ptr += WMI_TLV_HDR_SIZE;
1775 
1776 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
1777 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
1778 	buf_ptr += WMI_TLV_HDR_SIZE;
1779 
1780 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
1781 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
1782 	buf_ptr += WMI_TLV_HDR_SIZE;
1783 
1784 	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
1785 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
1786 	buf_ptr += WMI_TLV_HDR_SIZE;
1787 
1788 	/* Fill TLV for pattern_info_timeout, and time value */
1789 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
1790 	buf_ptr += WMI_TLV_HDR_SIZE;
1791 	*((uint32_t *) buf_ptr) = time;
1792 	buf_ptr += sizeof(uint32_t);
1793 
1794 	/* Fill TLV for ra_ratelimit_interval. with dummy 0 value */
1795 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
1796 	buf_ptr += WMI_TLV_HDR_SIZE;
1797 	*((uint32_t *) buf_ptr) = 0;
1798 
1799 	wmi_debug("send wake timer pattern with time[%d] to fw vdev = %d",
1800 		 time, vdev_id);
1801 
1802 	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
1803 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1804 				WMI_WOW_ADD_WAKE_PATTERN_CMDID);
1805 	if (ret) {
1806 		wmi_err("Failed to send wake timer pattern to fw");
1807 		wmi_buf_free(buf);
1808 		return QDF_STATUS_E_FAILURE;
1809 	}
1810 
1811 	return QDF_STATUS_SUCCESS;
1812 }
1813 
1814 #ifdef WLAN_FEATURE_EXTWOW_SUPPORT
1815 /**
1816  * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw
1817  * @wmi_handle: wmi handle
1818  * @params: ext wow params
1819  *
1820  * Return:0 for success or error code
1821  */
1822 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle,
1823 					      struct ext_wow_params *params)
1824 {
1825 	wmi_extwow_enable_cmd_fixed_param *cmd;
1826 	wmi_buf_t buf;
1827 	int32_t len;
1828 	int ret;
1829 
1830 	len = sizeof(wmi_extwow_enable_cmd_fixed_param);
1831 	buf = wmi_buf_alloc(wmi_handle, len);
1832 	if (!buf) {
1833 		return QDF_STATUS_E_NOMEM;
1834 	}
1835 
1836 	cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf);
1837 
1838 	WMITLV_SET_HDR(&cmd->tlv_header,
1839 		       WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param,
1840 		       WMITLV_GET_STRUCT_TLVLEN
1841 			       (wmi_extwow_enable_cmd_fixed_param));
1842 
1843 	cmd->vdev_id = params->vdev_id;
1844 	cmd->type = params->type;
1845 	cmd->wakeup_pin_num = params->wakeup_pin_num;
1846 
1847 	wmi_debug("vdev_id %d type %d Wakeup_pin_num %x",
1848 		 cmd->vdev_id, cmd->type, cmd->wakeup_pin_num);
1849 
1850 	wmi_mtrace(WMI_EXTWOW_ENABLE_CMDID, cmd->vdev_id, 0);
1851 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1852 				   WMI_EXTWOW_ENABLE_CMDID);
1853 	if (ret) {
1854 		wmi_err("Failed to set EXTWOW Enable");
1855 		wmi_buf_free(buf);
1856 		return QDF_STATUS_E_FAILURE;
1857 	}
1858 
1859 	return QDF_STATUS_SUCCESS;
1860 
1861 }
1862 
1863 /**
1864  * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw
1865  * @wmi_handle: wmi handle
1866  * @appType2Params: app type2 params
1867  *
1868  * Return: CDF status
1869  */
1870 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
1871 			  struct app_type2_params *appType2Params)
1872 {
1873 	wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd;
1874 	wmi_buf_t buf;
1875 	int32_t len;
1876 	int ret;
1877 
1878 	len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param);
1879 	buf = wmi_buf_alloc(wmi_handle, len);
1880 	if (!buf) {
1881 		return QDF_STATUS_E_NOMEM;
1882 	}
1883 
1884 	cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *)
1885 	      wmi_buf_data(buf);
1886 
1887 	WMITLV_SET_HDR(&cmd->tlv_header,
1888 	       WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param,
1889 	       WMITLV_GET_STRUCT_TLVLEN
1890 			(wmi_extwow_set_app_type2_params_cmd_fixed_param));
1891 
1892 	cmd->vdev_id = appType2Params->vdev_id;
1893 
1894 	qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16);
1895 	cmd->rc4_key_len = appType2Params->rc4_key_len;
1896 
1897 	cmd->ip_id = appType2Params->ip_id;
1898 	cmd->ip_device_ip = appType2Params->ip_device_ip;
1899 	cmd->ip_server_ip = appType2Params->ip_server_ip;
1900 
1901 	cmd->tcp_src_port = appType2Params->tcp_src_port;
1902 	cmd->tcp_dst_port = appType2Params->tcp_dst_port;
1903 	cmd->tcp_seq = appType2Params->tcp_seq;
1904 	cmd->tcp_ack_seq = appType2Params->tcp_ack_seq;
1905 
1906 	cmd->keepalive_init = appType2Params->keepalive_init;
1907 	cmd->keepalive_min = appType2Params->keepalive_min;
1908 	cmd->keepalive_max = appType2Params->keepalive_max;
1909 	cmd->keepalive_inc = appType2Params->keepalive_inc;
1910 
1911 	WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes,
1912 				   &cmd->gateway_mac);
1913 	cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val;
1914 	cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val;
1915 
1916 	wmi_debug("vdev_id %d gateway_mac "QDF_MAC_ADDR_FMT" "
1917 		 "rc4_key %.16s rc4_key_len %u "
1918 		 "ip_id %x ip_device_ip %x ip_server_ip %x "
1919 		 "tcp_src_port %u tcp_dst_port %u tcp_seq %u "
1920 		 "tcp_ack_seq %u keepalive_init %u keepalive_min %u "
1921 		 "keepalive_max %u keepalive_inc %u "
1922 		 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u",
1923 		 cmd->vdev_id,
1924 		 QDF_MAC_ADDR_REF(appType2Params->gateway_mac.bytes),
1925 		 cmd->rc4_key, cmd->rc4_key_len,
1926 		 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip,
1927 		 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq,
1928 		 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min,
1929 		 cmd->keepalive_max, cmd->keepalive_inc,
1930 		 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val);
1931 
1932 	wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID, cmd->vdev_id, 0);
1933 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1934 				   WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID);
1935 	if (ret) {
1936 		wmi_err("Failed to set APP TYPE2 PARAMS");
1937 		wmi_buf_free(buf);
1938 		return QDF_STATUS_E_FAILURE;
1939 	}
1940 
1941 	return QDF_STATUS_SUCCESS;
1942 
1943 }
1944 
1945 /**
1946  * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw
1947  * @wmi_handle: wmi handle
1948  * @app_type1_params: app type1 params
1949  *
1950  * Return: CDF status
1951  */
1952 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
1953 				   struct app_type1_params *app_type1_params)
1954 {
1955 	wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd;
1956 	wmi_buf_t buf;
1957 	int32_t len;
1958 	int ret;
1959 
1960 	len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param);
1961 	buf = wmi_buf_alloc(wmi_handle, len);
1962 	if (!buf) {
1963 		return QDF_STATUS_E_NOMEM;
1964 	}
1965 
1966 	cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *)
1967 	      wmi_buf_data(buf);
1968 
1969 	WMITLV_SET_HDR(&cmd->tlv_header,
1970 	       WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param,
1971 	       WMITLV_GET_STRUCT_TLVLEN
1972 	       (wmi_extwow_set_app_type1_params_cmd_fixed_param));
1973 
1974 	cmd->vdev_id = app_type1_params->vdev_id;
1975 	WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes,
1976 				   &cmd->wakee_mac);
1977 	qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8);
1978 	cmd->ident_len = app_type1_params->id_length;
1979 	qdf_mem_copy(cmd->passwd, app_type1_params->password, 16);
1980 	cmd->passwd_len = app_type1_params->pass_length;
1981 
1982 	wmi_debug("vdev_id %d wakee_mac_addr "QDF_MAC_ADDR_FMT" "
1983 		 "identification_id %.8s id_length %u "
1984 		 "password %.16s pass_length %u",
1985 		 cmd->vdev_id,
1986 		 QDF_MAC_ADDR_REF(app_type1_params->wakee_mac_addr.bytes),
1987 		 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len);
1988 
1989 	wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID, cmd->vdev_id, 0);
1990 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1991 				   WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID);
1992 	if (ret) {
1993 		wmi_err("Failed to set APP TYPE1 PARAMS");
1994 		wmi_buf_free(buf);
1995 		return QDF_STATUS_E_FAILURE;
1996 	}
1997 
1998 	return QDF_STATUS_SUCCESS;
1999 }
2000 
2001 void wmi_extwow_attach_tlv(struct wmi_unified *wmi_handle)
2002 {
2003 	struct wmi_ops *ops = wmi_handle->ops;
2004 
2005 	ops->send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv;
2006 	ops->send_set_app_type2_params_in_fw_cmd =
2007 		send_set_app_type2_params_in_fw_cmd_tlv;
2008 	ops->send_app_type1_params_in_fw_cmd =
2009 		send_app_type1_params_in_fw_cmd_tlv;
2010 }
2011 #endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
2012 
2013 void wmi_pmo_attach_tlv(wmi_unified_t wmi_handle)
2014 {
2015 	struct wmi_ops *ops = wmi_handle->ops;
2016 
2017 	ops->send_add_wow_wakeup_event_cmd =
2018 		send_add_wow_wakeup_event_cmd_tlv;
2019 	ops->send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv;
2020 	ops->send_enable_arp_ns_offload_cmd =
2021 		send_enable_arp_ns_offload_cmd_tlv;
2022 	ops->send_add_clear_mcbc_filter_cmd =
2023 		send_add_clear_mcbc_filter_cmd_tlv;
2024 	ops->send_multiple_add_clear_mcbc_filter_cmd =
2025 		send_multiple_add_clear_mcbc_filter_cmd_tlv;
2026 	ops->send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv;
2027 	ops->send_gtk_offload_cmd = send_gtk_offload_cmd_tlv;
2028 #ifdef WLAN_FEATURE_IGMP_OFFLOAD
2029 	ops->send_igmp_offload_cmd = send_igmp_offload_cmd_tlv;
2030 #endif
2031 	ops->send_process_gtk_offload_getinfo_cmd =
2032 		send_process_gtk_offload_getinfo_cmd_tlv;
2033 	ops->send_enable_enhance_multicast_offload_cmd =
2034 		send_enable_enhance_multicast_offload_tlv;
2035 	ops->extract_gtk_rsp_event = extract_gtk_rsp_event_tlv;
2036 	ops->send_action_frame_patterns_cmd =
2037 		send_action_frame_patterns_cmd_tlv;
2038 	ops->send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv;
2039 	ops->send_host_wakeup_ind_to_fw_cmd =
2040 		send_host_wakeup_ind_to_fw_cmd_tlv;
2041 	ops->send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv;
2042 
2043 	wmi_d0wow_attach_tlv(wmi_handle);
2044 	wmi_ra_filtering_attach_tlv(wmi_handle);
2045 	wmi_lphb_attach_tlv(wmi_handle);
2046 	wmi_packet_filtering_attach_tlv(wmi_handle);
2047 	wmi_extwow_attach_tlv(wmi_handle);
2048 }
2049