xref: /wlan-driver/qcacld-3.0/components/target_if/fw_offload/src/target_if_fwol.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /**
21*5113495bSYour Name  * DOC: target interface APIs for fw offload
22*5113495bSYour Name  *
23*5113495bSYour Name  */
24*5113495bSYour Name 
25*5113495bSYour Name #include "qdf_mem.h"
26*5113495bSYour Name #include "target_if.h"
27*5113495bSYour Name #include "qdf_status.h"
28*5113495bSYour Name #include "wmi_unified_api.h"
29*5113495bSYour Name #include "wmi_unified_priv.h"
30*5113495bSYour Name #include "wmi_unified_param.h"
31*5113495bSYour Name #include "wlan_objmgr_psoc_obj.h"
32*5113495bSYour Name #include "wlan_utility.h"
33*5113495bSYour Name #include "wlan_defs.h"
34*5113495bSYour Name #include "wlan_fwol_public_structs.h"
35*5113495bSYour Name #include "wlan_fw_offload_main.h"
36*5113495bSYour Name #include "target_if_fwol.h"
37*5113495bSYour Name 
38*5113495bSYour Name #ifdef WLAN_FEATURE_ELNA
39*5113495bSYour Name /**
40*5113495bSYour Name  * target_if_fwol_set_elna_bypass() - send set eLNA bypass request to FW
41*5113495bSYour Name  * @psoc: pointer to PSOC object
42*5113495bSYour Name  * @req: set eLNA bypass request
43*5113495bSYour Name  *
44*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success
45*5113495bSYour Name  */
46*5113495bSYour Name static QDF_STATUS
target_if_fwol_set_elna_bypass(struct wlan_objmgr_psoc * psoc,struct set_elna_bypass_request * req)47*5113495bSYour Name target_if_fwol_set_elna_bypass(struct wlan_objmgr_psoc *psoc,
48*5113495bSYour Name 			       struct set_elna_bypass_request *req)
49*5113495bSYour Name {
50*5113495bSYour Name 	QDF_STATUS status;
51*5113495bSYour Name 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
52*5113495bSYour Name 
53*5113495bSYour Name 	if (!wmi_handle) {
54*5113495bSYour Name 		target_if_err("Invalid wmi_handle");
55*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
56*5113495bSYour Name 	}
57*5113495bSYour Name 
58*5113495bSYour Name 	status = wmi_unified_send_set_elna_bypass_cmd(wmi_handle, req);
59*5113495bSYour Name 	if (status)
60*5113495bSYour Name 		target_if_err("Failed to set eLNA bypass %d", status);
61*5113495bSYour Name 
62*5113495bSYour Name 	return status;
63*5113495bSYour Name }
64*5113495bSYour Name 
65*5113495bSYour Name /**
66*5113495bSYour Name  * target_if_fwol_get_elna_bypass() - send get eLNA bypass request to FW
67*5113495bSYour Name  * @psoc: pointer to PSOC object
68*5113495bSYour Name  * @req: get eLNA bypass request
69*5113495bSYour Name  *
70*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success
71*5113495bSYour Name  */
72*5113495bSYour Name static QDF_STATUS
target_if_fwol_get_elna_bypass(struct wlan_objmgr_psoc * psoc,struct get_elna_bypass_request * req)73*5113495bSYour Name target_if_fwol_get_elna_bypass(struct wlan_objmgr_psoc *psoc,
74*5113495bSYour Name 			       struct get_elna_bypass_request *req)
75*5113495bSYour Name {
76*5113495bSYour Name 	QDF_STATUS status;
77*5113495bSYour Name 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
78*5113495bSYour Name 
79*5113495bSYour Name 	if (!wmi_handle) {
80*5113495bSYour Name 		target_if_err("Invalid wmi_handle");
81*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
82*5113495bSYour Name 	}
83*5113495bSYour Name 
84*5113495bSYour Name 	status = wmi_unified_send_get_elna_bypass_cmd(wmi_handle, req);
85*5113495bSYour Name 	if (status)
86*5113495bSYour Name 		target_if_err("Failed to set eLNA bypass %d", status);
87*5113495bSYour Name 
88*5113495bSYour Name 	return status;
89*5113495bSYour Name }
90*5113495bSYour Name 
91*5113495bSYour Name /**
92*5113495bSYour Name  * target_if_fwol_get_elna_bypass_resp() - handler for get eLNA bypass response
93*5113495bSYour Name  * @scn: scn handle
94*5113495bSYour Name  * @event_buf: pointer to the event buffer
95*5113495bSYour Name  * @len: length of the buffer
96*5113495bSYour Name  *
97*5113495bSYour Name  * Return: 0 on success
98*5113495bSYour Name  */
target_if_fwol_get_elna_bypass_resp(ol_scn_t scn,uint8_t * event_buf,uint32_t len)99*5113495bSYour Name static int target_if_fwol_get_elna_bypass_resp(ol_scn_t scn, uint8_t *event_buf,
100*5113495bSYour Name 					       uint32_t len)
101*5113495bSYour Name {
102*5113495bSYour Name 	QDF_STATUS status;
103*5113495bSYour Name 	struct get_elna_bypass_response resp;
104*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
105*5113495bSYour Name 	wmi_unified_t wmi_handle;
106*5113495bSYour Name 	struct wlan_fwol_psoc_obj *fwol_obj;
107*5113495bSYour Name 	struct wlan_fwol_rx_ops *rx_ops;
108*5113495bSYour Name 
109*5113495bSYour Name 	target_if_debug("scn:%pK, data:%pK, datalen:%d", scn, event_buf, len);
110*5113495bSYour Name 	if (!scn || !event_buf) {
111*5113495bSYour Name 		target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf);
112*5113495bSYour Name 		return -EINVAL;
113*5113495bSYour Name 	}
114*5113495bSYour Name 
115*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
116*5113495bSYour Name 	if (!psoc) {
117*5113495bSYour Name 		target_if_err("null psoc");
118*5113495bSYour Name 		return -EINVAL;
119*5113495bSYour Name 	}
120*5113495bSYour Name 
121*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
122*5113495bSYour Name 	if (!wmi_handle) {
123*5113495bSYour Name 		target_if_err("Invalid wmi_handle");
124*5113495bSYour Name 		return -EINVAL;
125*5113495bSYour Name 	}
126*5113495bSYour Name 
127*5113495bSYour Name 	fwol_obj = fwol_get_psoc_obj(psoc);
128*5113495bSYour Name 	if (!fwol_obj) {
129*5113495bSYour Name 		target_if_err("Failed to get FWOL Obj");
130*5113495bSYour Name 		return -EINVAL;
131*5113495bSYour Name 	}
132*5113495bSYour Name 
133*5113495bSYour Name 	rx_ops = &fwol_obj->rx_ops;
134*5113495bSYour Name 	if (rx_ops->get_elna_bypass_resp) {
135*5113495bSYour Name 		status = wmi_extract_get_elna_bypass_resp(wmi_handle,
136*5113495bSYour Name 							  event_buf, &resp);
137*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
138*5113495bSYour Name 			target_if_err("Failed to extract eLNA bypass");
139*5113495bSYour Name 			return -EINVAL;
140*5113495bSYour Name 		}
141*5113495bSYour Name 		status = rx_ops->get_elna_bypass_resp(psoc, &resp);
142*5113495bSYour Name 		if (status != QDF_STATUS_SUCCESS) {
143*5113495bSYour Name 			target_if_err("get_elna_bypass_resp failed.");
144*5113495bSYour Name 			return -EINVAL;
145*5113495bSYour Name 		}
146*5113495bSYour Name 	} else {
147*5113495bSYour Name 		target_if_fatal("No get_elna_bypass_resp callback");
148*5113495bSYour Name 		return -EINVAL;
149*5113495bSYour Name 	}
150*5113495bSYour Name 
151*5113495bSYour Name 	return 0;
152*5113495bSYour Name };
153*5113495bSYour Name 
154*5113495bSYour Name static void
target_if_fwol_register_elna_event_handler(struct wlan_objmgr_psoc * psoc,void * arg)155*5113495bSYour Name target_if_fwol_register_elna_event_handler(struct wlan_objmgr_psoc *psoc,
156*5113495bSYour Name 					   void *arg)
157*5113495bSYour Name {
158*5113495bSYour Name 	QDF_STATUS rc;
159*5113495bSYour Name 
160*5113495bSYour Name 	rc = wmi_unified_register_event(get_wmi_unified_hdl_from_psoc(psoc),
161*5113495bSYour Name 					wmi_get_elna_bypass_event_id,
162*5113495bSYour Name 					target_if_fwol_get_elna_bypass_resp);
163*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(rc))
164*5113495bSYour Name 		target_if_debug("Failed to register get eLNA bypass event cb");
165*5113495bSYour Name }
166*5113495bSYour Name 
167*5113495bSYour Name static void
target_if_fwol_unregister_elna_event_handler(struct wlan_objmgr_psoc * psoc,void * arg)168*5113495bSYour Name target_if_fwol_unregister_elna_event_handler(struct wlan_objmgr_psoc *psoc,
169*5113495bSYour Name 					     void *arg)
170*5113495bSYour Name {
171*5113495bSYour Name 	QDF_STATUS rc;
172*5113495bSYour Name 
173*5113495bSYour Name 	rc = wmi_unified_unregister_event_handler(
174*5113495bSYour Name 					    get_wmi_unified_hdl_from_psoc(psoc),
175*5113495bSYour Name 					    wmi_get_elna_bypass_event_id);
176*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(rc))
177*5113495bSYour Name 		target_if_debug("Failed to unregister get eLNA bypass event cb");
178*5113495bSYour Name }
179*5113495bSYour Name 
180*5113495bSYour Name static void
target_if_fwol_register_elna_tx_ops(struct wlan_fwol_tx_ops * tx_ops)181*5113495bSYour Name target_if_fwol_register_elna_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
182*5113495bSYour Name {
183*5113495bSYour Name 	tx_ops->set_elna_bypass = target_if_fwol_set_elna_bypass;
184*5113495bSYour Name 	tx_ops->get_elna_bypass = target_if_fwol_get_elna_bypass;
185*5113495bSYour Name }
186*5113495bSYour Name #else
187*5113495bSYour Name static void
target_if_fwol_register_elna_event_handler(struct wlan_objmgr_psoc * psoc,void * arg)188*5113495bSYour Name target_if_fwol_register_elna_event_handler(struct wlan_objmgr_psoc *psoc,
189*5113495bSYour Name 					   void *arg)
190*5113495bSYour Name {
191*5113495bSYour Name }
192*5113495bSYour Name 
193*5113495bSYour Name static void
target_if_fwol_unregister_elna_event_handler(struct wlan_objmgr_psoc * psoc,void * arg)194*5113495bSYour Name target_if_fwol_unregister_elna_event_handler(struct wlan_objmgr_psoc *psoc,
195*5113495bSYour Name 					     void *arg)
196*5113495bSYour Name {
197*5113495bSYour Name }
198*5113495bSYour Name 
199*5113495bSYour Name static void
target_if_fwol_register_elna_tx_ops(struct wlan_fwol_tx_ops * tx_ops)200*5113495bSYour Name target_if_fwol_register_elna_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
201*5113495bSYour Name {
202*5113495bSYour Name }
203*5113495bSYour Name #endif /* WLAN_FEATURE_ELNA */
204*5113495bSYour Name 
205*5113495bSYour Name #ifdef WLAN_SEND_DSCP_UP_MAP_TO_FW
206*5113495bSYour Name /**
207*5113495bSYour Name  * target_if_fwol_send_dscp_up_map_to_fw() - send dscp up map to FW
208*5113495bSYour Name  * @psoc: pointer to PSOC object
209*5113495bSYour Name  * @dscp_to_up_map: DSCP to UP map array
210*5113495bSYour Name  *
211*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success
212*5113495bSYour Name  */
213*5113495bSYour Name static QDF_STATUS
target_if_fwol_send_dscp_up_map_to_fw(struct wlan_objmgr_psoc * psoc,uint32_t * dscp_to_up_map)214*5113495bSYour Name target_if_fwol_send_dscp_up_map_to_fw(struct wlan_objmgr_psoc *psoc,
215*5113495bSYour Name 				     uint32_t *dscp_to_up_map)
216*5113495bSYour Name {
217*5113495bSYour Name 	QDF_STATUS status;
218*5113495bSYour Name 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
219*5113495bSYour Name 
220*5113495bSYour Name 	if (!wmi_handle) {
221*5113495bSYour Name 		target_if_err("Invalid wmi_handle");
222*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
223*5113495bSYour Name 	}
224*5113495bSYour Name 
225*5113495bSYour Name 	status = wmi_unified_send_dscp_tip_map_cmd(wmi_handle, dscp_to_up_map);
226*5113495bSYour Name 	if (status)
227*5113495bSYour Name 		target_if_err("Failed to send dscp_up_map_to_fw %d", status);
228*5113495bSYour Name 
229*5113495bSYour Name 	return status;
230*5113495bSYour Name }
231*5113495bSYour Name 
232*5113495bSYour Name static void
target_if_fwol_register_dscp_up_tx_ops(struct wlan_fwol_tx_ops * tx_ops)233*5113495bSYour Name target_if_fwol_register_dscp_up_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
234*5113495bSYour Name {
235*5113495bSYour Name 	tx_ops->send_dscp_up_map_to_fw = target_if_fwol_send_dscp_up_map_to_fw;
236*5113495bSYour Name }
237*5113495bSYour Name #else
238*5113495bSYour Name static void
target_if_fwol_register_dscp_up_tx_ops(struct wlan_fwol_tx_ops * tx_ops)239*5113495bSYour Name target_if_fwol_register_dscp_up_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
240*5113495bSYour Name {
241*5113495bSYour Name }
242*5113495bSYour Name #endif
243*5113495bSYour Name 
244*5113495bSYour Name #ifdef THERMAL_STATS_SUPPORT
245*5113495bSYour Name /**
246*5113495bSYour Name  * target_if_fwol_get_thermal_stats() - send get thermal stats request to FW
247*5113495bSYour Name  * @psoc: pointer to PSOC object
248*5113495bSYour Name  * @req_type: get thermal stats request type
249*5113495bSYour Name  * @therm_stats_offset: thermal temp stats offset for each temp range
250*5113495bSYour Name  *
251*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success
252*5113495bSYour Name  */
253*5113495bSYour Name static QDF_STATUS
target_if_fwol_get_thermal_stats(struct wlan_objmgr_psoc * psoc,enum thermal_stats_request_type req_type,uint8_t therm_stats_offset)254*5113495bSYour Name target_if_fwol_get_thermal_stats(struct wlan_objmgr_psoc *psoc,
255*5113495bSYour Name 				 enum thermal_stats_request_type req_type,
256*5113495bSYour Name 				 uint8_t therm_stats_offset)
257*5113495bSYour Name {
258*5113495bSYour Name 	QDF_STATUS status;
259*5113495bSYour Name 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
260*5113495bSYour Name 
261*5113495bSYour Name 	if (!wmi_handle) {
262*5113495bSYour Name 		target_if_err("Invalid wmi_handle");
263*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
264*5113495bSYour Name 	}
265*5113495bSYour Name 
266*5113495bSYour Name 	status = wmi_unified_send_get_thermal_stats_cmd(wmi_handle, req_type,
267*5113495bSYour Name 							therm_stats_offset);
268*5113495bSYour Name 	if (status)
269*5113495bSYour Name 		target_if_err("Failed to send get thermal stats cmd %d",
270*5113495bSYour Name 			      status);
271*5113495bSYour Name 
272*5113495bSYour Name 	return status;
273*5113495bSYour Name }
274*5113495bSYour Name 
275*5113495bSYour Name static void
target_if_fwol_register_thermal_stats_tx_ops(struct wlan_fwol_tx_ops * tx_ops)276*5113495bSYour Name target_if_fwol_register_thermal_stats_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
277*5113495bSYour Name {
278*5113495bSYour Name 	tx_ops->get_thermal_stats = target_if_fwol_get_thermal_stats;
279*5113495bSYour Name }
280*5113495bSYour Name 
281*5113495bSYour Name static QDF_STATUS
target_if_fwol_handle_thermal_lvl_stats_evt(struct wlan_objmgr_psoc * psoc,struct wlan_fwol_rx_ops * rx_ops,struct thermal_throttle_info * info)282*5113495bSYour Name target_if_fwol_handle_thermal_lvl_stats_evt(struct wlan_objmgr_psoc *psoc,
283*5113495bSYour Name 					    struct wlan_fwol_rx_ops *rx_ops,
284*5113495bSYour Name 					    struct thermal_throttle_info *info)
285*5113495bSYour Name {
286*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
287*5113495bSYour Name 
288*5113495bSYour Name 	if (rx_ops->get_thermal_stats_resp && info->therm_throt_levels)
289*5113495bSYour Name 		status = rx_ops->get_thermal_stats_resp(psoc, info);
290*5113495bSYour Name 
291*5113495bSYour Name 	return status;
292*5113495bSYour Name }
293*5113495bSYour Name 
294*5113495bSYour Name static bool
target_if_fwol_is_thermal_stats_enable(struct wlan_fwol_psoc_obj * fwol_obj)295*5113495bSYour Name target_if_fwol_is_thermal_stats_enable(struct wlan_fwol_psoc_obj *fwol_obj)
296*5113495bSYour Name {
297*5113495bSYour Name 	return (fwol_obj->capability_info.fw_thermal_stats_cap &&
298*5113495bSYour Name 		fwol_obj->cfg.thermal_temp_cfg.therm_stats_offset);
299*5113495bSYour Name }
300*5113495bSYour Name #else
301*5113495bSYour Name static void
target_if_fwol_register_thermal_stats_tx_ops(struct wlan_fwol_tx_ops * tx_ops)302*5113495bSYour Name target_if_fwol_register_thermal_stats_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
303*5113495bSYour Name {
304*5113495bSYour Name }
305*5113495bSYour Name 
306*5113495bSYour Name #ifdef FW_THERMAL_THROTTLE_SUPPORT
307*5113495bSYour Name static QDF_STATUS
target_if_fwol_handle_thermal_lvl_stats_evt(struct wlan_objmgr_psoc * psoc,struct wlan_fwol_rx_ops * rx_ops,struct thermal_throttle_info * info)308*5113495bSYour Name target_if_fwol_handle_thermal_lvl_stats_evt(struct wlan_objmgr_psoc *psoc,
309*5113495bSYour Name 					    struct wlan_fwol_rx_ops *rx_ops,
310*5113495bSYour Name 					    struct thermal_throttle_info *info)
311*5113495bSYour Name {
312*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
313*5113495bSYour Name }
314*5113495bSYour Name 
315*5113495bSYour Name static bool
target_if_fwol_is_thermal_stats_enable(struct wlan_fwol_psoc_obj * fwol_obj)316*5113495bSYour Name target_if_fwol_is_thermal_stats_enable(struct wlan_fwol_psoc_obj *fwol_obj)
317*5113495bSYour Name {
318*5113495bSYour Name 	return false;
319*5113495bSYour Name }
320*5113495bSYour Name #endif
321*5113495bSYour Name #endif
322*5113495bSYour Name 
323*5113495bSYour Name #if defined FW_THERMAL_THROTTLE_SUPPORT || defined THERMAL_STATS_SUPPORT
324*5113495bSYour Name QDF_STATUS
target_if_fwol_notify_thermal_throttle(struct wlan_objmgr_psoc * psoc,struct thermal_throttle_info * info)325*5113495bSYour Name target_if_fwol_notify_thermal_throttle(struct wlan_objmgr_psoc *psoc,
326*5113495bSYour Name 				       struct thermal_throttle_info *info)
327*5113495bSYour Name {
328*5113495bSYour Name 	struct wlan_fwol_psoc_obj *fwol_obj;
329*5113495bSYour Name 	struct wlan_fwol_rx_ops *rx_ops;
330*5113495bSYour Name 	QDF_STATUS status;
331*5113495bSYour Name 
332*5113495bSYour Name 	fwol_obj = fwol_get_psoc_obj(psoc);
333*5113495bSYour Name 	if (!fwol_obj) {
334*5113495bSYour Name 		target_if_err("Failed to get FWOL Obj");
335*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
336*5113495bSYour Name 	}
337*5113495bSYour Name 
338*5113495bSYour Name 	rx_ops = &fwol_obj->rx_ops;
339*5113495bSYour Name 	if (!rx_ops) {
340*5113495bSYour Name 		target_if_err("rx_ops Null");
341*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
342*5113495bSYour Name 	}
343*5113495bSYour Name 
344*5113495bSYour Name 	if (!info) {
345*5113495bSYour Name 		target_if_err("info Null");
346*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
347*5113495bSYour Name 	}
348*5113495bSYour Name 
349*5113495bSYour Name 	if (rx_ops->notify_thermal_throttle_handler) {
350*5113495bSYour Name 		if (info->level == THERMAL_UNKNOWN) {
351*5113495bSYour Name 			target_if_debug("Invalid thermal target lvl");
352*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
353*5113495bSYour Name 		}
354*5113495bSYour Name 		status = rx_ops->notify_thermal_throttle_handler(psoc, info);
355*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
356*5113495bSYour Name 			target_if_debug("notify thermal_throttle failed.");
357*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
358*5113495bSYour Name 		}
359*5113495bSYour Name 	} else {
360*5113495bSYour Name 		target_if_debug("No notify thermal_throttle callback");
361*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
362*5113495bSYour Name 	}
363*5113495bSYour Name 
364*5113495bSYour Name 	return status;
365*5113495bSYour Name }
366*5113495bSYour Name 
367*5113495bSYour Name /**
368*5113495bSYour Name  * target_if_fwol_thermal_throttle_event_handler() - handler for thermal
369*5113495bSYour Name  *  throttle event
370*5113495bSYour Name  * @scn: scn handle
371*5113495bSYour Name  * @event_buf: pointer to the event buffer
372*5113495bSYour Name  * @len: length of the buffer
373*5113495bSYour Name  *
374*5113495bSYour Name  * Return: 0 on success
375*5113495bSYour Name  */
376*5113495bSYour Name static int
target_if_fwol_thermal_throttle_event_handler(ol_scn_t scn,uint8_t * event_buf,uint32_t len)377*5113495bSYour Name target_if_fwol_thermal_throttle_event_handler(ol_scn_t scn, uint8_t *event_buf,
378*5113495bSYour Name 					      uint32_t len)
379*5113495bSYour Name {
380*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
381*5113495bSYour Name 	struct thermal_throttle_info info = {0};
382*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
383*5113495bSYour Name 	wmi_unified_t wmi_handle;
384*5113495bSYour Name 	struct wlan_fwol_psoc_obj *fwol_obj;
385*5113495bSYour Name 	struct wlan_fwol_rx_ops *rx_ops;
386*5113495bSYour Name 
387*5113495bSYour Name 	target_if_debug("scn:%pK, data:%pK, datalen:%d", scn, event_buf, len);
388*5113495bSYour Name 	if (!scn || !event_buf) {
389*5113495bSYour Name 		target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf);
390*5113495bSYour Name 		return -EINVAL;
391*5113495bSYour Name 	}
392*5113495bSYour Name 
393*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
394*5113495bSYour Name 	if (!psoc) {
395*5113495bSYour Name 		target_if_err("null psoc");
396*5113495bSYour Name 		return -EINVAL;
397*5113495bSYour Name 	}
398*5113495bSYour Name 
399*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
400*5113495bSYour Name 	if (!wmi_handle) {
401*5113495bSYour Name 		target_if_err("Invalid wmi_handle");
402*5113495bSYour Name 		return -EINVAL;
403*5113495bSYour Name 	}
404*5113495bSYour Name 
405*5113495bSYour Name 	fwol_obj = fwol_get_psoc_obj(psoc);
406*5113495bSYour Name 	if (!fwol_obj) {
407*5113495bSYour Name 		target_if_err("Failed to get FWOL Obj");
408*5113495bSYour Name 		return -EINVAL;
409*5113495bSYour Name 	}
410*5113495bSYour Name 
411*5113495bSYour Name 	status = wmi_extract_thermal_stats(wmi_handle,
412*5113495bSYour Name 					   event_buf,
413*5113495bSYour Name 					   &info.temperature,
414*5113495bSYour Name 					   &info.level,
415*5113495bSYour Name 					   &info.therm_throt_levels,
416*5113495bSYour Name 					   info.level_info,
417*5113495bSYour Name 					   &info.pdev_id);
418*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
419*5113495bSYour Name 		target_if_debug("Failed to convert thermal target level");
420*5113495bSYour Name 		return -EINVAL;
421*5113495bSYour Name 	}
422*5113495bSYour Name 	rx_ops = &fwol_obj->rx_ops;
423*5113495bSYour Name 	if (!rx_ops) {
424*5113495bSYour Name 		target_if_debug("rx_ops Null");
425*5113495bSYour Name 		return -EINVAL;
426*5113495bSYour Name 	}
427*5113495bSYour Name 
428*5113495bSYour Name 	status = target_if_fwol_handle_thermal_lvl_stats_evt(psoc, rx_ops,
429*5113495bSYour Name 							     &info);
430*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
431*5113495bSYour Name 		target_if_debug("thermal stats level response failed.");
432*5113495bSYour Name 
433*5113495bSYour Name 	if (rx_ops->notify_thermal_throttle_handler)
434*5113495bSYour Name 	{
435*5113495bSYour Name 		if (info.level == THERMAL_UNKNOWN) {
436*5113495bSYour Name 			target_if_debug("Failed to convert thermal target lvl");
437*5113495bSYour Name 			return -EINVAL;
438*5113495bSYour Name 		}
439*5113495bSYour Name 		status = rx_ops->notify_thermal_throttle_handler(psoc, &info);
440*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
441*5113495bSYour Name 			target_if_debug("notify thermal_throttle failed.");
442*5113495bSYour Name 			return -EINVAL;
443*5113495bSYour Name 		}
444*5113495bSYour Name 	} else {
445*5113495bSYour Name 		target_if_debug("No notify thermal_throttle callback");
446*5113495bSYour Name 		return -EINVAL;
447*5113495bSYour Name 	}
448*5113495bSYour Name 	return 0;
449*5113495bSYour Name }
450*5113495bSYour Name 
451*5113495bSYour Name /**
452*5113495bSYour Name  * target_if_fwol_register_thermal_throttle_handler() - Register handler for
453*5113495bSYour Name  * thermal throttle stats firmware event
454*5113495bSYour Name  * @psoc: psoc object
455*5113495bSYour Name  *
456*5113495bSYour Name  * Return: void
457*5113495bSYour Name  */
458*5113495bSYour Name static void
target_if_fwol_register_thermal_throttle_handler(struct wlan_objmgr_psoc * psoc)459*5113495bSYour Name target_if_fwol_register_thermal_throttle_handler(struct wlan_objmgr_psoc *psoc)
460*5113495bSYour Name {
461*5113495bSYour Name 	QDF_STATUS status;
462*5113495bSYour Name 	struct wlan_fwol_psoc_obj *fwol_obj;
463*5113495bSYour Name 
464*5113495bSYour Name 	fwol_obj = fwol_get_psoc_obj(psoc);
465*5113495bSYour Name 	if (!fwol_obj) {
466*5113495bSYour Name 		target_if_err("Failed to get FWOL Obj");
467*5113495bSYour Name 		return;
468*5113495bSYour Name 	}
469*5113495bSYour Name 	if (!fwol_obj->cfg.thermal_temp_cfg.thermal_mitigation_enable &&
470*5113495bSYour Name 	    !target_if_fwol_is_thermal_stats_enable(fwol_obj)) {
471*5113495bSYour Name 		target_if_debug("thermal mitigation or stats offload not enabled");
472*5113495bSYour Name 		return;
473*5113495bSYour Name 	}
474*5113495bSYour Name 	status = wmi_unified_register_event_handler(
475*5113495bSYour Name 				get_wmi_unified_hdl_from_psoc(psoc),
476*5113495bSYour Name 				wmi_tt_stats_event_id,
477*5113495bSYour Name 				target_if_fwol_thermal_throttle_event_handler,
478*5113495bSYour Name 				WMI_RX_SERIALIZER_CTX);
479*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
480*5113495bSYour Name 		target_if_debug("Failed to register thermal stats event cb");
481*5113495bSYour Name }
482*5113495bSYour Name 
483*5113495bSYour Name /**
484*5113495bSYour Name  * target_if_fwol_unregister_thermal_throttle_handler() - Unregister handler for
485*5113495bSYour Name  * thermal throttle stats firmware event
486*5113495bSYour Name  * @psoc: psoc object
487*5113495bSYour Name  *
488*5113495bSYour Name  * Return: void
489*5113495bSYour Name  */
490*5113495bSYour Name static void
target_if_fwol_unregister_thermal_throttle_handler(struct wlan_objmgr_psoc * psoc)491*5113495bSYour Name target_if_fwol_unregister_thermal_throttle_handler(
492*5113495bSYour Name 					struct wlan_objmgr_psoc *psoc)
493*5113495bSYour Name {
494*5113495bSYour Name 	QDF_STATUS status;
495*5113495bSYour Name 
496*5113495bSYour Name 	status = wmi_unified_unregister_event_handler(
497*5113495bSYour Name 				get_wmi_unified_hdl_from_psoc(psoc),
498*5113495bSYour Name 				wmi_tt_stats_event_id);
499*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
500*5113495bSYour Name 		target_if_debug("Failed to unregister thermal stats event cb");
501*5113495bSYour Name }
502*5113495bSYour Name #else
503*5113495bSYour Name static void
target_if_fwol_register_thermal_throttle_handler(struct wlan_objmgr_psoc * psoc)504*5113495bSYour Name target_if_fwol_register_thermal_throttle_handler(struct wlan_objmgr_psoc *psoc)
505*5113495bSYour Name {
506*5113495bSYour Name }
507*5113495bSYour Name 
508*5113495bSYour Name static void
target_if_fwol_unregister_thermal_throttle_handler(struct wlan_objmgr_psoc * psoc)509*5113495bSYour Name target_if_fwol_unregister_thermal_throttle_handler(
510*5113495bSYour Name 					struct wlan_objmgr_psoc *psoc)
511*5113495bSYour Name {
512*5113495bSYour Name }
513*5113495bSYour Name #endif
514*5113495bSYour Name 
515*5113495bSYour Name #ifdef WLAN_FEATURE_MDNS_OFFLOAD
516*5113495bSYour Name /**
517*5113495bSYour Name  * target_if_fwol_set_mdns_config() - Set mdns Config to FW
518*5113495bSYour Name  * @psoc: pointer to PSOC object
519*5113495bSYour Name  * @mdns_info: pointer to mdns config info
520*5113495bSYour Name  *
521*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success
522*5113495bSYour Name  */
523*5113495bSYour Name static QDF_STATUS
target_if_fwol_set_mdns_config(struct wlan_objmgr_psoc * psoc,struct mdns_config_info * mdns_info)524*5113495bSYour Name target_if_fwol_set_mdns_config(struct wlan_objmgr_psoc *psoc,
525*5113495bSYour Name 			       struct mdns_config_info *mdns_info)
526*5113495bSYour Name {
527*5113495bSYour Name 	QDF_STATUS status;
528*5113495bSYour Name 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
529*5113495bSYour Name 
530*5113495bSYour Name 	if (!wmi_handle) {
531*5113495bSYour Name 		target_if_err("Invalid wmi_handle");
532*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
533*5113495bSYour Name 	}
534*5113495bSYour Name 
535*5113495bSYour Name 	status = wmi_unified_send_set_mdns_config_cmd(wmi_handle,
536*5113495bSYour Name 						      mdns_info);
537*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
538*5113495bSYour Name 		target_if_err("Failed to set mDNS Config %d", status);
539*5113495bSYour Name 
540*5113495bSYour Name 	return status;
541*5113495bSYour Name }
542*5113495bSYour Name 
543*5113495bSYour Name static void
target_if_fwol_register_mdns_tx_ops(struct wlan_fwol_tx_ops * tx_ops)544*5113495bSYour Name target_if_fwol_register_mdns_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
545*5113495bSYour Name {
546*5113495bSYour Name 	tx_ops->set_mdns_config = target_if_fwol_set_mdns_config;
547*5113495bSYour Name }
548*5113495bSYour Name #else
549*5113495bSYour Name static void
target_if_fwol_register_mdns_tx_ops(struct wlan_fwol_tx_ops * tx_ops)550*5113495bSYour Name target_if_fwol_register_mdns_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
551*5113495bSYour Name {
552*5113495bSYour Name }
553*5113495bSYour Name #endif /* WLAN_FEATURE_MDNS_OFFLOAD */
554*5113495bSYour Name 
555*5113495bSYour Name QDF_STATUS
target_if_fwol_register_event_handler(struct wlan_objmgr_psoc * psoc,void * arg)556*5113495bSYour Name target_if_fwol_register_event_handler(struct wlan_objmgr_psoc *psoc,
557*5113495bSYour Name 				      void *arg)
558*5113495bSYour Name {
559*5113495bSYour Name 	target_if_fwol_register_elna_event_handler(psoc, arg);
560*5113495bSYour Name 	target_if_fwol_register_thermal_throttle_handler(psoc);
561*5113495bSYour Name 
562*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
563*5113495bSYour Name }
564*5113495bSYour Name 
565*5113495bSYour Name QDF_STATUS
target_if_fwol_unregister_event_handler(struct wlan_objmgr_psoc * psoc,void * arg)566*5113495bSYour Name target_if_fwol_unregister_event_handler(struct wlan_objmgr_psoc *psoc,
567*5113495bSYour Name 					void *arg)
568*5113495bSYour Name {
569*5113495bSYour Name 	target_if_fwol_unregister_thermal_throttle_handler(psoc);
570*5113495bSYour Name 	target_if_fwol_unregister_elna_event_handler(psoc, arg);
571*5113495bSYour Name 
572*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
573*5113495bSYour Name }
574*5113495bSYour Name 
target_if_fwol_register_tx_ops(struct wlan_fwol_tx_ops * tx_ops)575*5113495bSYour Name QDF_STATUS target_if_fwol_register_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
576*5113495bSYour Name {
577*5113495bSYour Name 	target_if_fwol_register_elna_tx_ops(tx_ops);
578*5113495bSYour Name 	target_if_fwol_register_dscp_up_tx_ops(tx_ops);
579*5113495bSYour Name 	target_if_fwol_register_mdns_tx_ops(tx_ops);
580*5113495bSYour Name 	target_if_fwol_register_thermal_stats_tx_ops(tx_ops);
581*5113495bSYour Name 
582*5113495bSYour Name 	tx_ops->reg_evt_handler = target_if_fwol_register_event_handler;
583*5113495bSYour Name 	tx_ops->unreg_evt_handler = target_if_fwol_unregister_event_handler;
584*5113495bSYour Name 
585*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
586*5113495bSYour Name }
587*5113495bSYour Name 
588