xref: /wlan-driver/qcacld-3.0/components/fw_offload/dispatcher/src/wlan_fwol_tgt_api.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  *
4*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
5*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
6*5113495bSYour Name  * above copyright notice and this permission notice appear in all
7*5113495bSYour Name  * copies.
8*5113495bSYour Name  *
9*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
17*5113495bSYour Name  */
18*5113495bSYour Name 
19*5113495bSYour Name /**
20*5113495bSYour Name  * DOC: This file contains fw offload south bound interface definitions
21*5113495bSYour Name  */
22*5113495bSYour Name 
23*5113495bSYour Name #include "scheduler_api.h"
24*5113495bSYour Name #include "wlan_objmgr_psoc_obj.h"
25*5113495bSYour Name #include "wlan_objmgr_global_obj.h"
26*5113495bSYour Name #include "wlan_objmgr_pdev_obj.h"
27*5113495bSYour Name #include "wlan_fwol_public_structs.h"
28*5113495bSYour Name #include "wlan_fwol_ucfg_api.h"
29*5113495bSYour Name #include "wlan_fwol_tgt_api.h"
30*5113495bSYour Name #include "wlan_fw_offload_main.h"
31*5113495bSYour Name #include "target_if.h"
32*5113495bSYour Name 
tgt_fwol_register_ev_handler(struct wlan_objmgr_psoc * psoc)33*5113495bSYour Name QDF_STATUS tgt_fwol_register_ev_handler(struct wlan_objmgr_psoc *psoc)
34*5113495bSYour Name {
35*5113495bSYour Name 	struct wlan_fwol_psoc_obj *fwol_obj;
36*5113495bSYour Name 	struct wlan_fwol_tx_ops *tx_ops;
37*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
38*5113495bSYour Name 
39*5113495bSYour Name 	if (!psoc) {
40*5113495bSYour Name 		fwol_err("NULL psoc handle");
41*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
42*5113495bSYour Name 	}
43*5113495bSYour Name 
44*5113495bSYour Name 	fwol_obj = fwol_get_psoc_obj(psoc);
45*5113495bSYour Name 	if (!fwol_obj) {
46*5113495bSYour Name 		fwol_err("Failed to get FWOL Obj");
47*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
48*5113495bSYour Name 	}
49*5113495bSYour Name 
50*5113495bSYour Name 	tx_ops = &fwol_obj->tx_ops;
51*5113495bSYour Name 	if (tx_ops->reg_evt_handler) {
52*5113495bSYour Name 		status = tx_ops->reg_evt_handler(psoc, NULL);
53*5113495bSYour Name 		fwol_debug("reg_evt_handler, status:%d", status);
54*5113495bSYour Name 	} else {
55*5113495bSYour Name 		fwol_alert("No reg_evt_handler");
56*5113495bSYour Name 	}
57*5113495bSYour Name 
58*5113495bSYour Name 	return status;
59*5113495bSYour Name }
60*5113495bSYour Name 
tgt_fwol_unregister_ev_handler(struct wlan_objmgr_psoc * psoc)61*5113495bSYour Name QDF_STATUS tgt_fwol_unregister_ev_handler(struct wlan_objmgr_psoc *psoc)
62*5113495bSYour Name {
63*5113495bSYour Name 	struct wlan_fwol_psoc_obj *fwol_obj;
64*5113495bSYour Name 	struct wlan_fwol_tx_ops *tx_ops;
65*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
66*5113495bSYour Name 
67*5113495bSYour Name 	if (!psoc) {
68*5113495bSYour Name 		fwol_err("NNULL psoc handle");
69*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
70*5113495bSYour Name 	}
71*5113495bSYour Name 
72*5113495bSYour Name 	fwol_obj = fwol_get_psoc_obj(psoc);
73*5113495bSYour Name 	if (!fwol_obj) {
74*5113495bSYour Name 		fwol_err("Failed to get FWOL Obj");
75*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
76*5113495bSYour Name 	}
77*5113495bSYour Name 
78*5113495bSYour Name 	tx_ops = &fwol_obj->tx_ops;
79*5113495bSYour Name 	if (tx_ops->unreg_evt_handler) {
80*5113495bSYour Name 		status = tx_ops->unreg_evt_handler(psoc, NULL);
81*5113495bSYour Name 		fwol_debug("unreg_evt_handler, status:%d", status);
82*5113495bSYour Name 	} else {
83*5113495bSYour Name 		fwol_alert("No unreg_evt_handler");
84*5113495bSYour Name 	}
85*5113495bSYour Name 
86*5113495bSYour Name 	return status;
87*5113495bSYour Name }
88*5113495bSYour Name 
89*5113495bSYour Name /**
90*5113495bSYour Name  * fwol_flush_callback() - fw offload message flush callback
91*5113495bSYour Name  * @msg: fw offload message
92*5113495bSYour Name  *
93*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success.
94*5113495bSYour Name  */
95*5113495bSYour Name __attribute__((unused))
fwol_flush_callback(struct scheduler_msg * msg)96*5113495bSYour Name static QDF_STATUS fwol_flush_callback(struct scheduler_msg *msg)
97*5113495bSYour Name {
98*5113495bSYour Name 	struct wlan_fwol_rx_event *event;
99*5113495bSYour Name 
100*5113495bSYour Name 	if (!msg) {
101*5113495bSYour Name 		fwol_err("NULL pointer for eLNA message");
102*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
103*5113495bSYour Name 	}
104*5113495bSYour Name 
105*5113495bSYour Name 	event = msg->bodyptr;
106*5113495bSYour Name 	msg->bodyptr = NULL;
107*5113495bSYour Name 	fwol_release_rx_event(event);
108*5113495bSYour Name 
109*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
110*5113495bSYour Name }
111*5113495bSYour Name 
112*5113495bSYour Name #ifdef WLAN_FEATURE_ELNA
113*5113495bSYour Name /**
114*5113495bSYour Name  * tgt_fwol_get_elna_bypass_resp() - handler for get eLNA bypass response
115*5113495bSYour Name  * @psoc: psoc handle
116*5113495bSYour Name  * @resp: status for last channel config
117*5113495bSYour Name  *
118*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success
119*5113495bSYour Name  */
120*5113495bSYour Name static QDF_STATUS
tgt_fwol_get_elna_bypass_resp(struct wlan_objmgr_psoc * psoc,struct get_elna_bypass_response * resp)121*5113495bSYour Name tgt_fwol_get_elna_bypass_resp(struct wlan_objmgr_psoc *psoc,
122*5113495bSYour Name 			      struct get_elna_bypass_response *resp)
123*5113495bSYour Name {
124*5113495bSYour Name 	QDF_STATUS status;
125*5113495bSYour Name 	struct scheduler_msg msg = {0};
126*5113495bSYour Name 	struct wlan_fwol_rx_event *event;
127*5113495bSYour Name 
128*5113495bSYour Name 	event = qdf_mem_malloc(sizeof(*event));
129*5113495bSYour Name 	if (!event)
130*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
131*5113495bSYour Name 
132*5113495bSYour Name 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_FWOL_SB_ID);
133*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
134*5113495bSYour Name 		fwol_err("Failed to get psoc ref");
135*5113495bSYour Name 		fwol_release_rx_event(event);
136*5113495bSYour Name 		return status;
137*5113495bSYour Name 	}
138*5113495bSYour Name 
139*5113495bSYour Name 	event->psoc = psoc;
140*5113495bSYour Name 	event->event_id = WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE;
141*5113495bSYour Name 	event->get_elna_bypass_response = *resp;
142*5113495bSYour Name 	msg.type = WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE;
143*5113495bSYour Name 	msg.bodyptr = event;
144*5113495bSYour Name 	msg.callback = fwol_process_event;
145*5113495bSYour Name 	msg.flush_callback = fwol_flush_callback;
146*5113495bSYour Name 	status = scheduler_post_message(QDF_MODULE_ID_FWOL,
147*5113495bSYour Name 					QDF_MODULE_ID_FWOL,
148*5113495bSYour Name 					QDF_MODULE_ID_TARGET_IF, &msg);
149*5113495bSYour Name 
150*5113495bSYour Name 	if (QDF_IS_STATUS_SUCCESS(status))
151*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
152*5113495bSYour Name 
153*5113495bSYour Name 	fwol_err("failed to send WLAN_FWOL_GET_ELNA_BYPASS_RESPONSE msg");
154*5113495bSYour Name 	fwol_flush_callback(&msg);
155*5113495bSYour Name 
156*5113495bSYour Name 	return status;
157*5113495bSYour Name }
158*5113495bSYour Name 
tgt_fwol_register_elna_rx_ops(struct wlan_fwol_rx_ops * rx_ops)159*5113495bSYour Name static void tgt_fwol_register_elna_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
160*5113495bSYour Name {
161*5113495bSYour Name 	rx_ops->get_elna_bypass_resp = tgt_fwol_get_elna_bypass_resp;
162*5113495bSYour Name }
163*5113495bSYour Name #else
tgt_fwol_register_elna_rx_ops(struct wlan_fwol_rx_ops * rx_ops)164*5113495bSYour Name static void tgt_fwol_register_elna_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
165*5113495bSYour Name {
166*5113495bSYour Name }
167*5113495bSYour Name #endif /* WLAN_FEATURE_ELNA */
168*5113495bSYour Name 
169*5113495bSYour Name #ifdef FW_THERMAL_THROTTLE_SUPPORT
170*5113495bSYour Name /**
171*5113495bSYour Name  * notify_thermal_throttle_handler() - Thermal throttle stats event handler
172*5113495bSYour Name  * @psoc: psoc object
173*5113495bSYour Name  * @info: thermal throttle stats info from target if layer
174*5113495bSYour Name  *
175*5113495bSYour Name  * The handle will be registered to target if layer. Target if layer
176*5113495bSYour Name  * will notify the new level from firmware thermal stats event.
177*5113495bSYour Name  *
178*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success
179*5113495bSYour Name  */
180*5113495bSYour Name static QDF_STATUS
notify_thermal_throttle_handler(struct wlan_objmgr_psoc * psoc,struct thermal_throttle_info * info)181*5113495bSYour Name notify_thermal_throttle_handler(struct wlan_objmgr_psoc *psoc,
182*5113495bSYour Name 				struct thermal_throttle_info *info)
183*5113495bSYour Name {
184*5113495bSYour Name 	struct wlan_fwol_psoc_obj *fwol_obj;
185*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
186*5113495bSYour Name 	struct fwol_thermal_callbacks *thermal_cbs;
187*5113495bSYour Name 
188*5113495bSYour Name 	if (!psoc) {
189*5113495bSYour Name 		fwol_err("NULL psoc handle");
190*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
191*5113495bSYour Name 	}
192*5113495bSYour Name 
193*5113495bSYour Name 	fwol_obj = fwol_get_psoc_obj(psoc);
194*5113495bSYour Name 	if (!fwol_obj) {
195*5113495bSYour Name 		fwol_err("Failed to get FWOL Obj");
196*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
197*5113495bSYour Name 	}
198*5113495bSYour Name 	thermal_cbs = &fwol_obj->thermal_cbs;
199*5113495bSYour Name 	fwol_nofl_debug("thermal evt: pdev %d lvl %d",
200*5113495bSYour Name 			info->pdev_id, info->level);
201*5113495bSYour Name 	if (info->pdev_id <= fwol_obj->thermal_throttle.pdev_id ||
202*5113495bSYour Name 	    fwol_obj->thermal_throttle.pdev_id == WLAN_INVALID_PDEV_ID) {
203*5113495bSYour Name 		fwol_obj->thermal_throttle.level = info->level;
204*5113495bSYour Name 		fwol_obj->thermal_throttle.pdev_id = info->pdev_id;
205*5113495bSYour Name 		if (thermal_cbs->notify_thermal_throttle_handler)
206*5113495bSYour Name 			status =
207*5113495bSYour Name 			thermal_cbs->notify_thermal_throttle_handler(psoc,
208*5113495bSYour Name 								     info);
209*5113495bSYour Name 		else
210*5113495bSYour Name 			fwol_debug("no thermal throttle handler");
211*5113495bSYour Name 	}
212*5113495bSYour Name 
213*5113495bSYour Name 	return status;
214*5113495bSYour Name }
215*5113495bSYour Name #endif
216*5113495bSYour Name 
217*5113495bSYour Name #ifdef THERMAL_STATS_SUPPORT
218*5113495bSYour Name static QDF_STATUS
tgt_fwol_get_thermal_stats_resp(struct wlan_objmgr_psoc * psoc,struct thermal_throttle_info * resp)219*5113495bSYour Name tgt_fwol_get_thermal_stats_resp(struct wlan_objmgr_psoc *psoc,
220*5113495bSYour Name 				struct thermal_throttle_info *resp)
221*5113495bSYour Name {
222*5113495bSYour Name 	QDF_STATUS status;
223*5113495bSYour Name 	struct scheduler_msg msg = {0};
224*5113495bSYour Name 	struct wlan_fwol_rx_event *event;
225*5113495bSYour Name 
226*5113495bSYour Name 	event = qdf_mem_malloc(sizeof(*event));
227*5113495bSYour Name 	if (!event)
228*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
229*5113495bSYour Name 
230*5113495bSYour Name 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_FWOL_SB_ID);
231*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
232*5113495bSYour Name 		fwol_err("Failed to get psoc ref");
233*5113495bSYour Name 		fwol_release_rx_event(event);
234*5113495bSYour Name 		return status;
235*5113495bSYour Name 	}
236*5113495bSYour Name 
237*5113495bSYour Name 	event->psoc = psoc;
238*5113495bSYour Name 	event->event_id = WLAN_FWOL_EVT_GET_THERMAL_STATS_RESPONSE;
239*5113495bSYour Name 	event->get_thermal_stats_response = *resp;
240*5113495bSYour Name 	msg.type = WLAN_FWOL_EVT_GET_THERMAL_STATS_RESPONSE;
241*5113495bSYour Name 	msg.bodyptr = event;
242*5113495bSYour Name 	msg.callback = fwol_process_event;
243*5113495bSYour Name 	msg.flush_callback = fwol_flush_callback;
244*5113495bSYour Name 	status = scheduler_post_message(QDF_MODULE_ID_FWOL,
245*5113495bSYour Name 					QDF_MODULE_ID_FWOL,
246*5113495bSYour Name 					QDF_MODULE_ID_TARGET_IF, &msg);
247*5113495bSYour Name 
248*5113495bSYour Name 	if (QDF_IS_STATUS_SUCCESS(status))
249*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
250*5113495bSYour Name 
251*5113495bSYour Name 	fwol_err("failed to send WLAN_FWOL_EVT_GET_THERMAL_STATS_RESPONSE msg");
252*5113495bSYour Name 	fwol_flush_callback(&msg);
253*5113495bSYour Name 
254*5113495bSYour Name 	return status;
255*5113495bSYour Name 
256*5113495bSYour Name }
257*5113495bSYour Name #endif
258*5113495bSYour Name 
259*5113495bSYour Name #ifdef THERMAL_STATS_SUPPORT
260*5113495bSYour Name static void
tgt_fwol_register_thermal_stats_resp(struct wlan_fwol_rx_ops * rx_ops)261*5113495bSYour Name tgt_fwol_register_thermal_stats_resp(struct wlan_fwol_rx_ops *rx_ops)
262*5113495bSYour Name {
263*5113495bSYour Name 	rx_ops->get_thermal_stats_resp = tgt_fwol_get_thermal_stats_resp;
264*5113495bSYour Name }
265*5113495bSYour Name #else
266*5113495bSYour Name static void
tgt_fwol_register_thermal_stats_resp(struct wlan_fwol_rx_ops * rx_ops)267*5113495bSYour Name tgt_fwol_register_thermal_stats_resp(struct wlan_fwol_rx_ops *rx_ops)
268*5113495bSYour Name {
269*5113495bSYour Name }
270*5113495bSYour Name #endif
271*5113495bSYour Name #ifdef FW_THERMAL_THROTTLE_SUPPORT
272*5113495bSYour Name static void
tgt_fwol_register_notify_thermal_throttle_evt(struct wlan_fwol_rx_ops * rx_ops)273*5113495bSYour Name tgt_fwol_register_notify_thermal_throttle_evt(struct wlan_fwol_rx_ops *rx_ops)
274*5113495bSYour Name {
275*5113495bSYour Name 	rx_ops->notify_thermal_throttle_handler =
276*5113495bSYour Name 					notify_thermal_throttle_handler;
277*5113495bSYour Name }
278*5113495bSYour Name #else
279*5113495bSYour Name static void
tgt_fwol_register_notify_thermal_throttle_evt(struct wlan_fwol_rx_ops * rx_ops)280*5113495bSYour Name tgt_fwol_register_notify_thermal_throttle_evt(struct wlan_fwol_rx_ops *rx_ops)
281*5113495bSYour Name {
282*5113495bSYour Name }
283*5113495bSYour Name #endif
284*5113495bSYour Name 
tgt_fwol_register_thermal_rx_ops(struct wlan_fwol_rx_ops * rx_ops)285*5113495bSYour Name static void tgt_fwol_register_thermal_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
286*5113495bSYour Name {
287*5113495bSYour Name 	tgt_fwol_register_notify_thermal_throttle_evt(rx_ops);
288*5113495bSYour Name 	tgt_fwol_register_thermal_stats_resp(rx_ops);
289*5113495bSYour Name }
290*5113495bSYour Name 
tgt_fwol_register_rx_ops(struct wlan_fwol_rx_ops * rx_ops)291*5113495bSYour Name QDF_STATUS tgt_fwol_register_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
292*5113495bSYour Name {
293*5113495bSYour Name 	tgt_fwol_register_elna_rx_ops(rx_ops);
294*5113495bSYour Name 	tgt_fwol_register_thermal_rx_ops(rx_ops);
295*5113495bSYour Name 
296*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
297*5113495bSYour Name }
298*5113495bSYour Name 
tgt_fwol_pdev_param_send(struct wlan_objmgr_pdev * pdev,struct pdev_params pdev_param)299*5113495bSYour Name QDF_STATUS tgt_fwol_pdev_param_send(struct wlan_objmgr_pdev *pdev,
300*5113495bSYour Name 				    struct pdev_params pdev_param)
301*5113495bSYour Name {
302*5113495bSYour Name 	struct wmi_unified *wmi_handle = get_wmi_unified_hdl_from_pdev(pdev);
303*5113495bSYour Name 
304*5113495bSYour Name 	if (!wmi_handle)
305*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
306*5113495bSYour Name 
307*5113495bSYour Name 	return wmi_unified_pdev_param_send(wmi_handle, &pdev_param,
308*5113495bSYour Name 					   FWOL_WILDCARD_PDEV_ID);
309*5113495bSYour Name }
310*5113495bSYour Name 
tgt_fwol_vdev_param_send(struct wlan_objmgr_psoc * psoc,struct vdev_set_params vdev_param)311*5113495bSYour Name QDF_STATUS tgt_fwol_vdev_param_send(struct wlan_objmgr_psoc *psoc,
312*5113495bSYour Name 				    struct vdev_set_params vdev_param)
313*5113495bSYour Name {
314*5113495bSYour Name 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
315*5113495bSYour Name 
316*5113495bSYour Name 	if (!wmi_handle)
317*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
318*5113495bSYour Name 
319*5113495bSYour Name 	return wmi_unified_vdev_set_param_send(wmi_handle, &vdev_param);
320*5113495bSYour Name }
321