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