xref: /wlan-driver/qcacld-3.0/components/wmi/src/wmi_unified_coap_tlv.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
3*5113495bSYour Name  *
4*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
5*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
6*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
7*5113495bSYour Name  *
8*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*5113495bSYour Name  */
16*5113495bSYour Name 
17*5113495bSYour Name /**
18*5113495bSYour Name  * DOC: Implement API's specific to CoAP component.
19*5113495bSYour Name  */
20*5113495bSYour Name 
21*5113495bSYour Name #include <wmi_unified_priv.h>
22*5113495bSYour Name #include "wmi.h"
23*5113495bSYour Name #include "ol_defines.h"
24*5113495bSYour Name 
25*5113495bSYour Name /*
26*5113495bSYour Name  * send_coap_add_pattern_cmd_tlv() - Send wmi cmd for adding CoAP pattern
27*5113495bSYour Name  * @wmi_handle: wmi handle
28*5113495bSYour Name  * @param: parameter for CoAP add pattern
29*5113495bSYour Name  *
30*5113495bSYour Name  * Return: QDF_STATUS
31*5113495bSYour Name  */
32*5113495bSYour Name static QDF_STATUS
send_coap_add_pattern_cmd_tlv(wmi_unified_t wmi_handle,struct coap_offload_reply_param * param)33*5113495bSYour Name send_coap_add_pattern_cmd_tlv(wmi_unified_t wmi_handle,
34*5113495bSYour Name 			      struct coap_offload_reply_param *param)
35*5113495bSYour Name {
36*5113495bSYour Name 	WMI_WOW_COAP_ADD_PATTERN_CMD_fixed_param *cmd;
37*5113495bSYour Name 	wmi_buf_t buf;
38*5113495bSYour Name 	QDF_STATUS status;
39*5113495bSYour Name 	uint8_t *buf_ptr;
40*5113495bSYour Name 	uint32_t len, coapmsg_len_align, verify_len_align;
41*5113495bSYour Name 
42*5113495bSYour Name 	wmi_debug("vdev id %d pattern id %d timeout %d src ip 0x%x:%d coap msg len %d",
43*5113495bSYour Name 		  param->vdev_id, param->pattern_id, param->cache_timeout,
44*5113495bSYour Name 		  param->src_ip_v4, param->src_udp_port,
45*5113495bSYour Name 		  param->coapmsg_len);
46*5113495bSYour Name 
47*5113495bSYour Name 	wmi_debug("filter: dest ip 0x%x:%d is bc %d verify offset %d len %d",
48*5113495bSYour Name 		  param->dest_ip_v4, param->dest_udp_port,
49*5113495bSYour Name 		  param->dest_ip_v4_is_bc, param->verify_offset,
50*5113495bSYour Name 		  param->verify_len);
51*5113495bSYour Name 
52*5113495bSYour Name 	if (!param->verify || !param->verify_len ||
53*5113495bSYour Name 	    !param->coapmsg || !param->coapmsg_len) {
54*5113495bSYour Name 		wmi_err("invalid param");
55*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
56*5113495bSYour Name 	}
57*5113495bSYour Name 
58*5113495bSYour Name 	coapmsg_len_align = qdf_align(param->coapmsg_len, 4);
59*5113495bSYour Name 	verify_len_align = qdf_align(param->verify_len, 4);
60*5113495bSYour Name 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + coapmsg_len_align +
61*5113495bSYour Name 		WMI_TLV_HDR_SIZE + verify_len_align;
62*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
63*5113495bSYour Name 	if (!buf)
64*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
65*5113495bSYour Name 
66*5113495bSYour Name 	buf_ptr = wmi_buf_data(buf);
67*5113495bSYour Name 	cmd = (WMI_WOW_COAP_ADD_PATTERN_CMD_fixed_param *)buf_ptr;
68*5113495bSYour Name 
69*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
70*5113495bSYour Name 		WMITLV_TAG_STRUC_WMI_WOW_COAP_ADD_PATTERN_CMD_fixed_param,
71*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
72*5113495bSYour Name 			WMI_WOW_COAP_ADD_PATTERN_CMD_fixed_param));
73*5113495bSYour Name 
74*5113495bSYour Name 	cmd->vdev_id = param->vdev_id;
75*5113495bSYour Name 	cmd->pattern_id = param->pattern_id;
76*5113495bSYour Name 	cmd->timeout = param->cache_timeout;
77*5113495bSYour Name 	WMI_COAP_IPV6_SET(cmd->pattern_type, 0);
78*5113495bSYour Name 	WMI_COAP_ADDR_TYPE_SET(cmd->pattern_type,
79*5113495bSYour Name 			       param->dest_ip_v4_is_bc ? 1 : 0);
80*5113495bSYour Name 	qdf_mem_copy(cmd->match_udp_ip.ipv4_addr, &param->dest_ip_v4,
81*5113495bSYour Name 		     sizeof(param->dest_ip_v4));
82*5113495bSYour Name 	cmd->match_udp_port = param->dest_udp_port;
83*5113495bSYour Name 	qdf_mem_copy(cmd->udp_local_ip.ipv4_addr, &param->src_ip_v4,
84*5113495bSYour Name 		     sizeof(param->src_ip_v4));
85*5113495bSYour Name 	cmd->udp_local_port = param->src_udp_port;
86*5113495bSYour Name 	cmd->verify_offset = param->verify_offset;
87*5113495bSYour Name 	cmd->verify_len = param->verify_len;
88*5113495bSYour Name 	cmd->coapmsg_len = param->coapmsg_len;
89*5113495bSYour Name 
90*5113495bSYour Name 	buf_ptr += sizeof(*cmd);
91*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, verify_len_align);
92*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
93*5113495bSYour Name 	qdf_mem_copy(buf_ptr, param->verify, param->verify_len);
94*5113495bSYour Name 
95*5113495bSYour Name 	buf_ptr += verify_len_align;
96*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, coapmsg_len_align);
97*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
98*5113495bSYour Name 	qdf_mem_copy(buf_ptr, param->coapmsg, param->coapmsg_len);
99*5113495bSYour Name 	buf_ptr += coapmsg_len_align;
100*5113495bSYour Name 
101*5113495bSYour Name 	wmi_mtrace(WMI_WOW_COAP_ADD_PATTERN_CMDID,
102*5113495bSYour Name 		   cmd->vdev_id, cmd->pattern_id);
103*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
104*5113495bSYour Name 				      WMI_WOW_COAP_ADD_PATTERN_CMDID);
105*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
106*5113495bSYour Name 		wmi_err("Failed to send wow coap add pattern command %d",
107*5113495bSYour Name 			status);
108*5113495bSYour Name 		wmi_buf_free(buf);
109*5113495bSYour Name 	}
110*5113495bSYour Name 
111*5113495bSYour Name 	return status;
112*5113495bSYour Name }
113*5113495bSYour Name 
114*5113495bSYour Name /*
115*5113495bSYour Name  * send_coap_del_pattern_cmd_tlv() - Send wmi cmd for deleting CoAP pattern
116*5113495bSYour Name  * @wmi_handle: wmi handle
117*5113495bSYour Name  * @vdev_id: vdev id
118*5113495bSYour Name  * @pattern_id: pattern id
119*5113495bSYour Name  *
120*5113495bSYour Name  * Return: QDF_STATUS
121*5113495bSYour Name  */
122*5113495bSYour Name static QDF_STATUS
send_coap_del_pattern_cmd_tlv(wmi_unified_t wmi_handle,uint8_t vdev_id,uint32_t pattern_id)123*5113495bSYour Name send_coap_del_pattern_cmd_tlv(wmi_unified_t wmi_handle,
124*5113495bSYour Name 			      uint8_t vdev_id, uint32_t pattern_id)
125*5113495bSYour Name {
126*5113495bSYour Name 	WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param *cmd;
127*5113495bSYour Name 	wmi_buf_t buf;
128*5113495bSYour Name 	QDF_STATUS status;
129*5113495bSYour Name 	uint32_t len = sizeof(*cmd);
130*5113495bSYour Name 
131*5113495bSYour Name 	wmi_debug("vdev id %d pattern id %d", vdev_id, pattern_id);
132*5113495bSYour Name 
133*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
134*5113495bSYour Name 	if (!buf)
135*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
136*5113495bSYour Name 
137*5113495bSYour Name 	cmd = (WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param *)wmi_buf_data(buf);
138*5113495bSYour Name 
139*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
140*5113495bSYour Name 		 WMITLV_TAG_STRUC_WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param,
141*5113495bSYour Name 		 WMITLV_GET_STRUCT_TLVLEN(
142*5113495bSYour Name 			WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param));
143*5113495bSYour Name 
144*5113495bSYour Name 	cmd->vdev_id = vdev_id;
145*5113495bSYour Name 	cmd->pattern_id = pattern_id;
146*5113495bSYour Name 	wmi_mtrace(WMI_WOW_COAP_DEL_PATTERN_CMDID,
147*5113495bSYour Name 		   cmd->vdev_id, cmd->pattern_id);
148*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
149*5113495bSYour Name 				      WMI_WOW_COAP_DEL_PATTERN_CMDID);
150*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
151*5113495bSYour Name 		wmi_err("Failed to send wow coap del pattern command %d",
152*5113495bSYour Name 			status);
153*5113495bSYour Name 		wmi_buf_free(buf);
154*5113495bSYour Name 	}
155*5113495bSYour Name 
156*5113495bSYour Name 	return status;
157*5113495bSYour Name }
158*5113495bSYour Name 
159*5113495bSYour Name /*
160*5113495bSYour Name  * send_coap_add_pattern_cmd_tlv() - Send wmi cmd for adding CoAP keepalive
161*5113495bSYour Name  * pattern
162*5113495bSYour Name  * @wmi_handle: wmi handle
163*5113495bSYour Name  * @param: parameter for CoAP add pattern
164*5113495bSYour Name  *
165*5113495bSYour Name  * Return: QDF_STATUS
166*5113495bSYour Name  */
167*5113495bSYour Name static QDF_STATUS
send_coap_add_keepalive_pattern_cmd_tlv(wmi_unified_t wmi_handle,struct coap_offload_periodic_tx_param * param)168*5113495bSYour Name send_coap_add_keepalive_pattern_cmd_tlv(wmi_unified_t wmi_handle,
169*5113495bSYour Name 			struct coap_offload_periodic_tx_param *param)
170*5113495bSYour Name {
171*5113495bSYour Name 	WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMD_fixed_param *cmd;
172*5113495bSYour Name 	wmi_buf_t buf;
173*5113495bSYour Name 	QDF_STATUS status;
174*5113495bSYour Name 	uint8_t *buf_ptr;
175*5113495bSYour Name 	uint32_t len, coapmsg_len_align;
176*5113495bSYour Name 
177*5113495bSYour Name 	wmi_debug("vdev id %d pattern id %d ip src 0x%x:%d dest 0x%x:%d bc %d timeout %d",
178*5113495bSYour Name 		  param->vdev_id, param->pattern_id, param->src_ip_v4,
179*5113495bSYour Name 		  param->src_udp_port, param->dest_ip_v4,
180*5113495bSYour Name 		  param->dest_udp_port, param->dest_ip_v4_is_bc,
181*5113495bSYour Name 		  param->timeout);
182*5113495bSYour Name 
183*5113495bSYour Name 	if (!param->coapmsg || !param->coapmsg_len) {
184*5113495bSYour Name 		wmi_err("invalid CoAP message");
185*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
186*5113495bSYour Name 	}
187*5113495bSYour Name 
188*5113495bSYour Name 	coapmsg_len_align = qdf_align(param->coapmsg_len, 4);
189*5113495bSYour Name 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + coapmsg_len_align;
190*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
191*5113495bSYour Name 	if (!buf)
192*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
193*5113495bSYour Name 
194*5113495bSYour Name 	buf_ptr = wmi_buf_data(buf);
195*5113495bSYour Name 	cmd = (WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMD_fixed_param *)buf_ptr;
196*5113495bSYour Name 
197*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
198*5113495bSYour Name 	WMITLV_TAG_STRUC_WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMD_fixed_param,
199*5113495bSYour Name 	WMITLV_GET_STRUCT_TLVLEN(
200*5113495bSYour Name 		WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMD_fixed_param));
201*5113495bSYour Name 
202*5113495bSYour Name 	cmd->vdev_id = param->vdev_id;
203*5113495bSYour Name 	cmd->pattern_id = param->pattern_id;
204*5113495bSYour Name 
205*5113495bSYour Name 	/* only support IPv4 in current stage */
206*5113495bSYour Name 	WMI_COAP_IPV6_SET(cmd->pattern_type, 0);
207*5113495bSYour Name 	WMI_COAP_ADDR_TYPE_SET(cmd->pattern_type,
208*5113495bSYour Name 			       param->dest_ip_v4_is_bc ? 1 : 0);
209*5113495bSYour Name 	qdf_mem_copy(cmd->udp_remote_ip.ipv4_addr, &param->dest_ip_v4,
210*5113495bSYour Name 		     sizeof(param->dest_ip_v4));
211*5113495bSYour Name 	cmd->udp_remote_port = param->dest_udp_port;
212*5113495bSYour Name 	qdf_mem_copy(cmd->udp_local_ip.ipv4_addr, &param->src_ip_v4,
213*5113495bSYour Name 		     sizeof(param->src_ip_v4));
214*5113495bSYour Name 	cmd->udp_local_port = param->src_udp_port;
215*5113495bSYour Name 	cmd->timeout = param->timeout;
216*5113495bSYour Name 	cmd->coapmsg_len = param->coapmsg_len;
217*5113495bSYour Name 
218*5113495bSYour Name 	buf_ptr += sizeof(*cmd);
219*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, coapmsg_len_align);
220*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
221*5113495bSYour Name 	qdf_mem_copy(buf_ptr, param->coapmsg, param->coapmsg_len);
222*5113495bSYour Name 	buf_ptr += coapmsg_len_align;
223*5113495bSYour Name 
224*5113495bSYour Name 	wmi_mtrace(WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMDID,
225*5113495bSYour Name 		   cmd->vdev_id, cmd->pattern_id);
226*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
227*5113495bSYour Name 				      WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMDID);
228*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
229*5113495bSYour Name 		wmi_err("Failed to send wow coap add keepalive pattern command %d",
230*5113495bSYour Name 			status);
231*5113495bSYour Name 		wmi_buf_free(buf);
232*5113495bSYour Name 	}
233*5113495bSYour Name 
234*5113495bSYour Name 	return status;
235*5113495bSYour Name }
236*5113495bSYour Name 
237*5113495bSYour Name /*
238*5113495bSYour Name  * send_coap_del_pattern_cmd_tlv() - Send wmi cmd for deleting CoAP
239*5113495bSYour Name  * keepalive pattern
240*5113495bSYour Name  * @wmi_handle: wmi handle
241*5113495bSYour Name  * @vdev_id: vdev id
242*5113495bSYour Name  * @pattern_id: pattern id
243*5113495bSYour Name  *
244*5113495bSYour Name  * Return: QDF_STATUS
245*5113495bSYour Name  */
246*5113495bSYour Name static QDF_STATUS
send_coap_del_keepalive_pattern_cmd_tlv(wmi_unified_t wmi_handle,uint8_t vdev_id,uint32_t pattern_id)247*5113495bSYour Name send_coap_del_keepalive_pattern_cmd_tlv(wmi_unified_t wmi_handle,
248*5113495bSYour Name 					uint8_t vdev_id, uint32_t pattern_id)
249*5113495bSYour Name {
250*5113495bSYour Name 	WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMD_fixed_param *cmd;
251*5113495bSYour Name 	wmi_buf_t buf;
252*5113495bSYour Name 	QDF_STATUS status;
253*5113495bSYour Name 	uint8_t *buf_ptr;
254*5113495bSYour Name 	uint32_t len = sizeof(*cmd);
255*5113495bSYour Name 
256*5113495bSYour Name 	wmi_debug("vdev id %d pattern id %d", vdev_id, pattern_id);
257*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
258*5113495bSYour Name 	if (!buf)
259*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
260*5113495bSYour Name 
261*5113495bSYour Name 	buf_ptr = wmi_buf_data(buf);
262*5113495bSYour Name 	cmd = (WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMD_fixed_param *)buf_ptr;
263*5113495bSYour Name 
264*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
265*5113495bSYour Name 		WMITLV_TAG_STRUC_WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMD_fixed_param,
266*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
267*5113495bSYour Name 			WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param));
268*5113495bSYour Name 
269*5113495bSYour Name 	cmd->vdev_id = vdev_id;
270*5113495bSYour Name 	cmd->pattern_id = pattern_id;
271*5113495bSYour Name 	wmi_mtrace(WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMDID,
272*5113495bSYour Name 		   cmd->vdev_id, cmd->pattern_id);
273*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
274*5113495bSYour Name 				      WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMDID);
275*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
276*5113495bSYour Name 		wmi_err("Failed to send wow coap del keepalive pattern command %d",
277*5113495bSYour Name 			status);
278*5113495bSYour Name 		wmi_buf_free(buf);
279*5113495bSYour Name 	}
280*5113495bSYour Name 
281*5113495bSYour Name 	return status;
282*5113495bSYour Name }
283*5113495bSYour Name 
284*5113495bSYour Name /*
285*5113495bSYour Name  * send_coap_cache_get_cmd_tlv() - Send wmi cmd for getting cached CoAP
286*5113495bSYour Name  * messages
287*5113495bSYour Name  * @wmi_handle: wmi handle
288*5113495bSYour Name  * @vdev_id: vdev id
289*5113495bSYour Name  * @pattern_id: pattern id
290*5113495bSYour Name  *
291*5113495bSYour Name  * Return: QDF_STATUS
292*5113495bSYour Name  */
293*5113495bSYour Name static QDF_STATUS
send_coap_cache_get_cmd_tlv(wmi_unified_t wmi_handle,uint8_t vdev_id,uint32_t pattern_id)294*5113495bSYour Name send_coap_cache_get_cmd_tlv(wmi_unified_t wmi_handle,
295*5113495bSYour Name 			    uint8_t vdev_id, uint32_t pattern_id)
296*5113495bSYour Name {
297*5113495bSYour Name 	WMI_WOW_COAP_GET_BUF_INFO_CMD_fixed_param *cmd;
298*5113495bSYour Name 	wmi_buf_t buf;
299*5113495bSYour Name 	QDF_STATUS status;
300*5113495bSYour Name 	uint32_t len = sizeof(*cmd);
301*5113495bSYour Name 
302*5113495bSYour Name 	wmi_debug("vdev id %d pattern id %d", vdev_id, pattern_id);
303*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
304*5113495bSYour Name 	if (!buf)
305*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
306*5113495bSYour Name 
307*5113495bSYour Name 	cmd = (WMI_WOW_COAP_GET_BUF_INFO_CMD_fixed_param *)wmi_buf_data(buf);
308*5113495bSYour Name 
309*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
310*5113495bSYour Name 		WMITLV_TAG_STRUC_WMI_WOW_COAP_GET_BUF_INFO_CMD_fixed_param,
311*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
312*5113495bSYour Name 			WMI_WOW_COAP_GET_BUF_INFO_CMD_fixed_param));
313*5113495bSYour Name 
314*5113495bSYour Name 	cmd->vdev_id = vdev_id;
315*5113495bSYour Name 	cmd->pattern_id = pattern_id;
316*5113495bSYour Name 	wmi_mtrace(WMI_WOW_COAP_GET_BUF_INFO_CMDID,
317*5113495bSYour Name 		   cmd->vdev_id, cmd->pattern_id);
318*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
319*5113495bSYour Name 				      WMI_WOW_COAP_GET_BUF_INFO_CMDID);
320*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
321*5113495bSYour Name 		wmi_err("Failed to send wow coap get buf info command %d",
322*5113495bSYour Name 			status);
323*5113495bSYour Name 		wmi_buf_free(buf);
324*5113495bSYour Name 	}
325*5113495bSYour Name 
326*5113495bSYour Name 	return status;
327*5113495bSYour Name }
328*5113495bSYour Name 
329*5113495bSYour Name /**
330*5113495bSYour Name  * coap_extract_buf_info_tlv() - Extract CoAP buf info event
331*5113495bSYour Name  * @wmi_handle: wmi handle
332*5113495bSYour Name  * @evt_buf: Pointer to the event buffer
333*5113495bSYour Name  * @info: pointer to CoAP buf info
334*5113495bSYour Name  *
335*5113495bSYour Name  * The caller needs to free any possible nodes in info->info_list
336*5113495bSYour Name  * regardless of failure or success.
337*5113495bSYour Name  *
338*5113495bSYour Name  * Return: QDF_STATUS
339*5113495bSYour Name  */
340*5113495bSYour Name static QDF_STATUS
coap_extract_buf_info_tlv(wmi_unified_t wmi_handle,void * evt_buf,struct coap_buf_info * info)341*5113495bSYour Name coap_extract_buf_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
342*5113495bSYour Name 			  struct coap_buf_info *info)
343*5113495bSYour Name {
344*5113495bSYour Name 	WMI_WOW_COAP_BUF_INFO_EVENT_fixed_param *buf_info_ev;
345*5113495bSYour Name 	WMI_WOW_COAP_BUF_INFO_EVENTID_param_tlvs *param_buf = evt_buf;
346*5113495bSYour Name 	wmi_coap_tuple *tuple;
347*5113495bSYour Name 	uint8_t *payload;
348*5113495bSYour Name 	uint32_t num_tuple, num_payload;
349*5113495bSYour Name 	struct coap_buf_node *buf_node;
350*5113495bSYour Name 	int i, j;
351*5113495bSYour Name 
352*5113495bSYour Name 	buf_info_ev = param_buf->fixed_param;
353*5113495bSYour Name 	if (!buf_info_ev) {
354*5113495bSYour Name 		wmi_debug("received null event data from target");
355*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
356*5113495bSYour Name 	}
357*5113495bSYour Name 
358*5113495bSYour Name 	if (buf_info_ev->vdev_id > WLAN_MAX_VDEVS) {
359*5113495bSYour Name 		wmi_debug("received invalid vdev_id %d",
360*5113495bSYour Name 			  buf_info_ev->vdev_id);
361*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
362*5113495bSYour Name 	}
363*5113495bSYour Name 
364*5113495bSYour Name 	info->vdev_id = buf_info_ev->vdev_id;
365*5113495bSYour Name 	info->req_id = buf_info_ev->pattern_id;
366*5113495bSYour Name 	info->more_info = buf_info_ev->more_tuples;
367*5113495bSYour Name 
368*5113495bSYour Name 	num_tuple = param_buf->num_coap_tuple;
369*5113495bSYour Name 	num_payload = param_buf->num_payloads;
370*5113495bSYour Name 	for (i = 0, j = 0; i < num_tuple && j < num_payload; i++) {
371*5113495bSYour Name 		tuple = &param_buf->coap_tuple[i];
372*5113495bSYour Name 		if (!tuple->payload_len) {
373*5113495bSYour Name 			wmi_err("idx %d: invalid payload len 0", i);
374*5113495bSYour Name 			continue;
375*5113495bSYour Name 		}
376*5113495bSYour Name 
377*5113495bSYour Name 		payload = &param_buf->payloads[j];
378*5113495bSYour Name 		j += qdf_align(tuple->payload_len, 4);
379*5113495bSYour Name 		if (j > num_payload) {
380*5113495bSYour Name 			wmi_err("idx %d: payload len overflow, pos %d - total %d",
381*5113495bSYour Name 				i, j, num_payload);
382*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
383*5113495bSYour Name 		}
384*5113495bSYour Name 
385*5113495bSYour Name 		buf_node = qdf_mem_malloc(sizeof(*buf_node));
386*5113495bSYour Name 		if (!buf_node)
387*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
388*5113495bSYour Name 
389*5113495bSYour Name 		buf_node->payload = qdf_mem_malloc(tuple->payload_len);
390*5113495bSYour Name 		if (!buf_node->payload) {
391*5113495bSYour Name 			qdf_mem_free(buf_node);
392*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
393*5113495bSYour Name 		}
394*5113495bSYour Name 
395*5113495bSYour Name 		buf_node->tsf = tuple->tsf;
396*5113495bSYour Name 		qdf_mem_copy(&buf_node->src_ip, tuple->src_ip.ipv4_addr,
397*5113495bSYour Name 			     sizeof(buf_node->src_ip));
398*5113495bSYour Name 		buf_node->len = tuple->payload_len;
399*5113495bSYour Name 		qdf_mem_copy(buf_node->payload, payload, buf_node->len);
400*5113495bSYour Name 		qdf_list_insert_back(&info->info_list, &buf_node->node);
401*5113495bSYour Name 
402*5113495bSYour Name 		wmi_debug("idx %d: src ip 0x%x tsf 0x%llx payload len %d",
403*5113495bSYour Name 			  i, buf_node->src_ip, buf_node->tsf, buf_node->len);
404*5113495bSYour Name 	}
405*5113495bSYour Name 
406*5113495bSYour Name 	wmi_debug("vdev_id %d req_id %d num_tuple %d payload len %d more info %d",
407*5113495bSYour Name 		  info->vdev_id, info->req_id, num_tuple,
408*5113495bSYour Name 		  num_payload, info->more_info);
409*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
410*5113495bSYour Name }
411*5113495bSYour Name 
412*5113495bSYour Name /**
413*5113495bSYour Name  * wmi_coap_attach_tlv() - attach CoAP tlv handlers
414*5113495bSYour Name  * @wmi_handle: wmi handle
415*5113495bSYour Name  *
416*5113495bSYour Name  * Return: void
417*5113495bSYour Name  */
wmi_coap_attach_tlv(wmi_unified_t wmi_handle)418*5113495bSYour Name void wmi_coap_attach_tlv(wmi_unified_t wmi_handle)
419*5113495bSYour Name {
420*5113495bSYour Name 	struct wmi_ops *ops = wmi_handle->ops;
421*5113495bSYour Name 
422*5113495bSYour Name 	ops->send_coap_add_pattern_cmd = send_coap_add_pattern_cmd_tlv;
423*5113495bSYour Name 	ops->send_coap_del_pattern_cmd = send_coap_del_pattern_cmd_tlv;
424*5113495bSYour Name 	ops->send_coap_add_keepalive_pattern_cmd =
425*5113495bSYour Name 		send_coap_add_keepalive_pattern_cmd_tlv;
426*5113495bSYour Name 	ops->send_coap_del_keepalive_pattern_cmd =
427*5113495bSYour Name 		send_coap_del_keepalive_pattern_cmd_tlv;
428*5113495bSYour Name 	ops->send_coap_cache_get_cmd = send_coap_cache_get_cmd_tlv;
429*5113495bSYour Name 	ops->extract_coap_buf_info = coap_extract_buf_info_tlv;
430*5113495bSYour Name }
431