xref: /wlan-driver/qcacld-3.0/components/target_if/coap/src/target_if_coap.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: contains CoAP target if functions
19*5113495bSYour Name  */
20*5113495bSYour Name #include <wlan_coap_main.h>
21*5113495bSYour Name #include <target_if_coap.h>
22*5113495bSYour Name #include <wmi_unified_coap_api.h>
23*5113495bSYour Name 
24*5113495bSYour Name /**
25*5113495bSYour Name  * target_if_wow_coap_buf_info_event_handler() - function to handle CoAP
26*5113495bSYour Name  * buf info event from firmware.
27*5113495bSYour Name  * @scn: scn handle
28*5113495bSYour Name  * @data: data buffer for event
29*5113495bSYour Name  * @datalen: data length
30*5113495bSYour Name  *
31*5113495bSYour Name  * Return: status of operation.
32*5113495bSYour Name  */
33*5113495bSYour Name static int
target_if_wow_coap_buf_info_event_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)34*5113495bSYour Name target_if_wow_coap_buf_info_event_handler(ol_scn_t scn, uint8_t *data,
35*5113495bSYour Name 					  uint32_t datalen)
36*5113495bSYour Name {
37*5113495bSYour Name 	QDF_STATUS status;
38*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
39*5113495bSYour Name 	struct wmi_unified *wmi_handle;
40*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev = NULL;
41*5113495bSYour Name 	struct wlan_coap_comp_priv *coap_priv;
42*5113495bSYour Name 	struct coap_buf_info info = {0};
43*5113495bSYour Name 	struct coap_buf_node *cur, *next;
44*5113495bSYour Name 
45*5113495bSYour Name 	if (!scn || !data) {
46*5113495bSYour Name 		coap_err("scn: 0x%pK, data: 0x%pK", scn, data);
47*5113495bSYour Name 		return -EINVAL;
48*5113495bSYour Name 	}
49*5113495bSYour Name 
50*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
51*5113495bSYour Name 	if (!psoc) {
52*5113495bSYour Name 		coap_err("null psoc");
53*5113495bSYour Name 		return -EINVAL;
54*5113495bSYour Name 	}
55*5113495bSYour Name 
56*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
57*5113495bSYour Name 	if (!wmi_handle) {
58*5113495bSYour Name 		coap_err("wmi_handle is null");
59*5113495bSYour Name 		return -EINVAL;
60*5113495bSYour Name 	}
61*5113495bSYour Name 
62*5113495bSYour Name 	qdf_list_create(&info.info_list, 0);
63*5113495bSYour Name 	status = wmi_unified_coap_extract_buf_info(wmi_handle, data,
64*5113495bSYour Name 						   &info);
65*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
66*5113495bSYour Name 		goto out;
67*5113495bSYour Name 
68*5113495bSYour Name 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, info.vdev_id,
69*5113495bSYour Name 						    WLAN_COAP_ID);
70*5113495bSYour Name 	if (!vdev) {
71*5113495bSYour Name 		coap_err("vdev is NULL, vdev_id: %d", info.vdev_id);
72*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
73*5113495bSYour Name 		goto out;
74*5113495bSYour Name 	}
75*5113495bSYour Name 
76*5113495bSYour Name 	coap_priv = wlan_get_vdev_coap_obj(vdev);
77*5113495bSYour Name 	if (!coap_priv->cache_get_cbk || !coap_priv->cache_get_context) {
78*5113495bSYour Name 		coap_err("req id %d: callback or context is NULL",
79*5113495bSYour Name 			 coap_priv->req_id);
80*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
81*5113495bSYour Name 		goto out;
82*5113495bSYour Name 	}
83*5113495bSYour Name 
84*5113495bSYour Name 	coap_priv->cache_get_cbk(coap_priv->cache_get_context, &info);
85*5113495bSYour Name out:
86*5113495bSYour Name 	qdf_list_for_each_del(&info.info_list, cur, next, node) {
87*5113495bSYour Name 		qdf_list_remove_node(&info.info_list, &cur->node);
88*5113495bSYour Name 		qdf_mem_free(cur->payload);
89*5113495bSYour Name 		qdf_mem_free(cur);
90*5113495bSYour Name 	}
91*5113495bSYour Name 
92*5113495bSYour Name 	if (vdev)
93*5113495bSYour Name 		wlan_objmgr_vdev_release_ref(vdev, WLAN_COAP_ID);
94*5113495bSYour Name 	return qdf_status_to_os_return(status);
95*5113495bSYour Name }
96*5113495bSYour Name 
97*5113495bSYour Name /**
98*5113495bSYour Name  * target_if_coap_register_event_handler() - Register CoAP related wmi events
99*5113495bSYour Name  * @psoc: psoc handle
100*5113495bSYour Name  *
101*5113495bSYour Name  * Register CoAP related WMI events
102*5113495bSYour Name  *
103*5113495bSYour Name  * return: QDF_STATUS
104*5113495bSYour Name  */
105*5113495bSYour Name static QDF_STATUS
target_if_coap_register_event_handler(struct wlan_objmgr_psoc * psoc)106*5113495bSYour Name target_if_coap_register_event_handler(struct wlan_objmgr_psoc *psoc)
107*5113495bSYour Name {
108*5113495bSYour Name 	QDF_STATUS ret_val;
109*5113495bSYour Name 	struct wmi_unified *wmi_handle;
110*5113495bSYour Name 
111*5113495bSYour Name 	if (!psoc) {
112*5113495bSYour Name 		coap_err("PSOC is NULL!");
113*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
114*5113495bSYour Name 	}
115*5113495bSYour Name 
116*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
117*5113495bSYour Name 	if (!wmi_handle) {
118*5113495bSYour Name 		coap_err("wmi_handle is null");
119*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
120*5113495bSYour Name 	}
121*5113495bSYour Name 
122*5113495bSYour Name 	ret_val = wmi_unified_register_event_handler(wmi_handle,
123*5113495bSYour Name 			wmi_wow_coap_buf_info_eventid,
124*5113495bSYour Name 			target_if_wow_coap_buf_info_event_handler,
125*5113495bSYour Name 			WMI_RX_WORK_CTX);
126*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret_val))
127*5113495bSYour Name 		coap_err("Failed to register coap buf info event cb");
128*5113495bSYour Name 
129*5113495bSYour Name 	return ret_val;
130*5113495bSYour Name }
131*5113495bSYour Name 
132*5113495bSYour Name /**
133*5113495bSYour Name  * target_if_coap_unregister_event_handler() - Unregister CoAP related wmi
134*5113495bSYour Name  * events
135*5113495bSYour Name  * @psoc: psoc handle
136*5113495bSYour Name  *
137*5113495bSYour Name  * Register CoAP related WMI events
138*5113495bSYour Name  *
139*5113495bSYour Name  * return: QDF_STATUS
140*5113495bSYour Name  */
141*5113495bSYour Name static QDF_STATUS
target_if_coap_unregister_event_handler(struct wlan_objmgr_psoc * psoc)142*5113495bSYour Name target_if_coap_unregister_event_handler(struct wlan_objmgr_psoc *psoc)
143*5113495bSYour Name {
144*5113495bSYour Name 	struct wmi_unified *wmi_handle;
145*5113495bSYour Name 
146*5113495bSYour Name 	if (!psoc) {
147*5113495bSYour Name 		coap_err("PSOC is NULL!");
148*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
149*5113495bSYour Name 	}
150*5113495bSYour Name 
151*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
152*5113495bSYour Name 	if (!wmi_handle) {
153*5113495bSYour Name 		coap_err("wmi_handle is null");
154*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
155*5113495bSYour Name 	}
156*5113495bSYour Name 	wmi_unified_unregister_event_handler(wmi_handle,
157*5113495bSYour Name 					     wmi_wow_coap_buf_info_eventid);
158*5113495bSYour Name 
159*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
160*5113495bSYour Name }
161*5113495bSYour Name 
162*5113495bSYour Name /**
163*5113495bSYour Name  * target_if_coap_offload_reply_enable() - enable CoAP offload reply
164*5113495bSYour Name  * @vdev: pointer to vdev object
165*5113495bSYour Name  * @param: parameters for CoAP offload reply
166*5113495bSYour Name  *
167*5113495bSYour Name  * Return: status of operation
168*5113495bSYour Name  */
169*5113495bSYour Name static QDF_STATUS
target_if_coap_offload_reply_enable(struct wlan_objmgr_vdev * vdev,struct coap_offload_reply_param * param)170*5113495bSYour Name target_if_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
171*5113495bSYour Name 				    struct coap_offload_reply_param *param)
172*5113495bSYour Name {
173*5113495bSYour Name 	wmi_unified_t wmi_handle;
174*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
175*5113495bSYour Name 
176*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
177*5113495bSYour Name 	wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
178*5113495bSYour Name 	if (!wmi_handle) {
179*5113495bSYour Name 		coap_err("Invalid PDEV WMI handle");
180*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
181*5113495bSYour Name 	}
182*5113495bSYour Name 
183*5113495bSYour Name 	return wmi_unified_coap_add_pattern_cmd(wmi_handle, param);
184*5113495bSYour Name }
185*5113495bSYour Name 
186*5113495bSYour Name /**
187*5113495bSYour Name  * target_if_coap_offload_reply_disable() - disable CoAP offload reply
188*5113495bSYour Name  * @vdev: pointer to vdev object
189*5113495bSYour Name  * @req_id: request id
190*5113495bSYour Name  *
191*5113495bSYour Name  * Return: status of operation
192*5113495bSYour Name  */
193*5113495bSYour Name static QDF_STATUS
target_if_coap_offload_reply_disable(struct wlan_objmgr_vdev * vdev,uint32_t req_id)194*5113495bSYour Name target_if_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev,
195*5113495bSYour Name 				     uint32_t req_id)
196*5113495bSYour Name {
197*5113495bSYour Name 	wmi_unified_t wmi_handle;
198*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
199*5113495bSYour Name 
200*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
201*5113495bSYour Name 	wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
202*5113495bSYour Name 	if (!wmi_handle) {
203*5113495bSYour Name 		coap_err("Invalid PDEV WMI handle");
204*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
205*5113495bSYour Name 	}
206*5113495bSYour Name 
207*5113495bSYour Name 	return wmi_unified_coap_del_pattern_cmd(wmi_handle,
208*5113495bSYour Name 						wlan_vdev_get_id(vdev),
209*5113495bSYour Name 						req_id);
210*5113495bSYour Name }
211*5113495bSYour Name 
212*5113495bSYour Name /**
213*5113495bSYour Name  * target_if_coap_offload_periodic_tx_enable() - enable CoAP offload
214*5113495bSYour Name  * periodic transmitting
215*5113495bSYour Name  * @vdev: pointer to vdev object
216*5113495bSYour Name  * @param: parameters for CoAP periodic transmitting
217*5113495bSYour Name  *
218*5113495bSYour Name  * Return: status of operation
219*5113495bSYour Name  */
220*5113495bSYour Name static QDF_STATUS
target_if_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev * vdev,struct coap_offload_periodic_tx_param * param)221*5113495bSYour Name target_if_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
222*5113495bSYour Name 			struct coap_offload_periodic_tx_param *param)
223*5113495bSYour Name {
224*5113495bSYour Name 	wmi_unified_t wmi_handle;
225*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
226*5113495bSYour Name 
227*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
228*5113495bSYour Name 	wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
229*5113495bSYour Name 	if (!wmi_handle) {
230*5113495bSYour Name 		coap_err("Invalid PDEV WMI handle");
231*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
232*5113495bSYour Name 	}
233*5113495bSYour Name 
234*5113495bSYour Name 	return wmi_unified_coap_add_keepalive_pattern_cmd(wmi_handle, param);
235*5113495bSYour Name }
236*5113495bSYour Name 
237*5113495bSYour Name /**
238*5113495bSYour Name  * target_if_coap_offload_periodic_tx_disable() - disable CoAP offload
239*5113495bSYour Name  * periodic transmitting
240*5113495bSYour Name  * @vdev: pointer to vdev object
241*5113495bSYour Name  * @req_id: request id
242*5113495bSYour Name  *
243*5113495bSYour Name  * Return: status of operation
244*5113495bSYour Name  */
245*5113495bSYour Name static QDF_STATUS
target_if_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev * vdev,uint32_t req_id)246*5113495bSYour Name target_if_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
247*5113495bSYour Name 					   uint32_t req_id)
248*5113495bSYour Name {
249*5113495bSYour Name 	wmi_unified_t wmi_handle;
250*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
251*5113495bSYour Name 	uint8_t vdev_id;
252*5113495bSYour Name 
253*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
254*5113495bSYour Name 	wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
255*5113495bSYour Name 	if (!wmi_handle) {
256*5113495bSYour Name 		coap_err("Invalid PDEV WMI handle");
257*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
258*5113495bSYour Name 	}
259*5113495bSYour Name 
260*5113495bSYour Name 	vdev_id = wlan_vdev_get_id(vdev);
261*5113495bSYour Name 	return wmi_unified_coap_del_keepalive_pattern_cmd(wmi_handle,
262*5113495bSYour Name 							  vdev_id, req_id);
263*5113495bSYour Name }
264*5113495bSYour Name 
265*5113495bSYour Name /**
266*5113495bSYour Name  * target_if_coap_offload_cache_get() - get cached CoAP messages
267*5113495bSYour Name  * @vdev: pointer to vdev object
268*5113495bSYour Name  * @req_id: request id
269*5113495bSYour Name  *
270*5113495bSYour Name  * Return: status of operation
271*5113495bSYour Name  */
272*5113495bSYour Name static QDF_STATUS
target_if_coap_offload_cache_get(struct wlan_objmgr_vdev * vdev,uint32_t req_id)273*5113495bSYour Name target_if_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev,
274*5113495bSYour Name 				 uint32_t req_id)
275*5113495bSYour Name {
276*5113495bSYour Name 	wmi_unified_t wmi_handle;
277*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
278*5113495bSYour Name 
279*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
280*5113495bSYour Name 	wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
281*5113495bSYour Name 	if (!wmi_handle) {
282*5113495bSYour Name 		coap_err("Invalid PDEV WMI handle");
283*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
284*5113495bSYour Name 	}
285*5113495bSYour Name 
286*5113495bSYour Name 	return wmi_unified_coap_cache_get(wmi_handle, wlan_vdev_get_id(vdev),
287*5113495bSYour Name 					  req_id);
288*5113495bSYour Name }
289*5113495bSYour Name 
290*5113495bSYour Name QDF_STATUS
target_if_coap_register_tx_ops(struct wlan_lmac_if_tx_ops * tx_ops)291*5113495bSYour Name target_if_coap_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
292*5113495bSYour Name {
293*5113495bSYour Name 	struct wlan_lmac_if_coap_tx_ops *coap_ops;
294*5113495bSYour Name 
295*5113495bSYour Name 	if (!tx_ops) {
296*5113495bSYour Name 		coap_err("target if tx ops is NULL!");
297*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
298*5113495bSYour Name 	}
299*5113495bSYour Name 
300*5113495bSYour Name 	coap_ops = &tx_ops->coap_ops;
301*5113495bSYour Name 	coap_ops->attach = target_if_coap_register_event_handler;
302*5113495bSYour Name 	coap_ops->detach = target_if_coap_unregister_event_handler;
303*5113495bSYour Name 	coap_ops->offload_reply_enable =
304*5113495bSYour Name 		target_if_coap_offload_reply_enable;
305*5113495bSYour Name 	coap_ops->offload_reply_disable =
306*5113495bSYour Name 		target_if_coap_offload_reply_disable;
307*5113495bSYour Name 	coap_ops->offload_periodic_tx_enable =
308*5113495bSYour Name 		target_if_coap_offload_periodic_tx_enable;
309*5113495bSYour Name 	coap_ops->offload_periodic_tx_disable =
310*5113495bSYour Name 		target_if_coap_offload_periodic_tx_disable;
311*5113495bSYour Name 	coap_ops->offload_cache_get = target_if_coap_offload_cache_get;
312*5113495bSYour Name 
313*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
314*5113495bSYour Name }
315