1 /*
2 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. 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 "qdf_module.h"
21 #include "qdf_trace.h"
22 #include "qdf_platform.h"
23
24 /*
25 * The following callbacks should be defined static to make sure they are
26 * initialized to NULL
27 */
28 static qdf_self_recovery_callback self_recovery_cb;
29 static qdf_is_fw_down_callback is_fw_down_cb;
30 static qdf_is_driver_unloading_callback is_driver_unloading_cb;
31 static qdf_is_driver_state_module_stop_callback is_driver_state_module_stop_cb;
32 static qdf_is_recovering_callback is_recovering_cb;
33 static qdf_is_drv_connected_callback is_drv_connected_cb;
34 static qdf_wmi_send_over_qmi_callback _wmi_send_recv_qmi_cb;
35 static qdf_send_ind_over_qmi_callback _qmi_indication_cb;
36 static qdf_is_drv_supported_callback is_drv_supported_cb;
37 static qdf_recovery_reason_update_callback update_recovery_reason_cb;
38 static qdf_bus_reg_dump get_bus_reg_dump;
39
40
41
qdf_register_fw_down_callback(qdf_is_fw_down_callback is_fw_down)42 void qdf_register_fw_down_callback(qdf_is_fw_down_callback is_fw_down)
43 {
44 is_fw_down_cb = is_fw_down;
45 }
46
47 qdf_export_symbol(qdf_register_fw_down_callback);
48
qdf_is_fw_down(void)49 bool qdf_is_fw_down(void)
50 {
51 if (!is_fw_down_cb) {
52 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
53 "fw down callback is not registered");
54 return false;
55 }
56
57 return is_fw_down_cb();
58 }
59 qdf_export_symbol(qdf_is_fw_down);
60
qdf_register_wmi_send_recv_qmi_callback(qdf_wmi_send_over_qmi_callback wmi_send_recv_qmi_cb)61 void qdf_register_wmi_send_recv_qmi_callback(qdf_wmi_send_over_qmi_callback
62 wmi_send_recv_qmi_cb)
63 {
64 _wmi_send_recv_qmi_cb = wmi_send_recv_qmi_cb;
65 }
66
67 qdf_export_symbol(qdf_register_wmi_send_recv_qmi_callback);
68
qdf_register_qmi_indication_callback(qdf_send_ind_over_qmi_callback cds_qmi_indication)69 void qdf_register_qmi_indication_callback(qdf_send_ind_over_qmi_callback
70 cds_qmi_indication)
71 {
72 _qmi_indication_cb = cds_qmi_indication;
73 }
74
75 qdf_export_symbol(qdf_register_qmi_indication_callback);
76
qdf_wmi_send_recv_qmi(void * buf,uint32_t len,void * cb_ctx,qdf_wmi_recv_qmi_cb wmi_recv_qmi_cb)77 QDF_STATUS qdf_wmi_send_recv_qmi(void *buf, uint32_t len, void *cb_ctx,
78 qdf_wmi_recv_qmi_cb wmi_recv_qmi_cb)
79 {
80 if (!_wmi_send_recv_qmi_cb) {
81 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
82 "Platform callback for WMI over QMI not registered");
83 return QDF_STATUS_E_INVAL;
84 }
85
86 return _wmi_send_recv_qmi_cb(buf, len, cb_ctx, wmi_recv_qmi_cb);
87 }
88
89 qdf_export_symbol(qdf_wmi_send_recv_qmi);
90
qdf_reg_qmi_indication(void * cb_ctx,qdf_qmi_ind_cb qmi_ind_cb)91 QDF_STATUS qdf_reg_qmi_indication(void *cb_ctx, qdf_qmi_ind_cb qmi_ind_cb)
92 {
93 if (!_qmi_indication_cb) {
94 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
95 "Platform callback for QMI indication not registered");
96 return QDF_STATUS_E_INVAL;
97 }
98
99 return _qmi_indication_cb(cb_ctx, qmi_ind_cb);
100 }
101
102 qdf_export_symbol(qdf_reg_qmi_indication);
103
qdf_register_is_driver_unloading_callback(qdf_is_driver_unloading_callback callback)104 void qdf_register_is_driver_unloading_callback(
105 qdf_is_driver_unloading_callback callback)
106 {
107 is_driver_unloading_cb = callback;
108 }
109
110 qdf_export_symbol(qdf_register_is_driver_unloading_callback);
111
qdf_register_is_driver_state_module_stop_callback(qdf_is_driver_state_module_stop_callback callback)112 void qdf_register_is_driver_state_module_stop_callback(
113 qdf_is_driver_state_module_stop_callback callback)
114 {
115 is_driver_state_module_stop_cb = callback;
116 }
117
118 qdf_export_symbol(qdf_register_is_driver_state_module_stop_callback);
119
qdf_register_self_recovery_callback(qdf_self_recovery_callback callback)120 void qdf_register_self_recovery_callback(qdf_self_recovery_callback callback)
121 {
122 self_recovery_cb = callback;
123 }
124
125 qdf_export_symbol(qdf_register_self_recovery_callback);
126
__qdf_trigger_self_recovery(void * psoc,enum qdf_hang_reason reason,const char * func,const uint32_t line)127 void __qdf_trigger_self_recovery(void *psoc, enum qdf_hang_reason reason,
128 const char *func, const uint32_t line)
129 {
130 if (self_recovery_cb)
131 self_recovery_cb(psoc, reason, func, line);
132 else
133 QDF_DEBUG_PANIC_FL(func, line, "");
134 }
135
136 qdf_export_symbol(__qdf_trigger_self_recovery);
137
qdf_register_recovering_state_query_callback(qdf_is_recovering_callback is_recovering)138 void qdf_register_recovering_state_query_callback(
139 qdf_is_recovering_callback is_recovering)
140 {
141 is_recovering_cb = is_recovering;
142 }
143
qdf_is_driver_unloading(void)144 bool qdf_is_driver_unloading(void)
145 {
146 if (is_driver_unloading_cb)
147 return is_driver_unloading_cb();
148 return false;
149 }
150
151 qdf_export_symbol(qdf_is_driver_unloading);
152
qdf_is_driver_state_module_stop(void)153 bool qdf_is_driver_state_module_stop(void)
154 {
155 if (is_driver_state_module_stop_cb)
156 return is_driver_state_module_stop_cb();
157 return false;
158 }
159
160 qdf_export_symbol(qdf_is_driver_state_module_stop);
161
qdf_is_recovering(void)162 bool qdf_is_recovering(void)
163 {
164 if (is_recovering_cb)
165 return is_recovering_cb();
166 return false;
167 }
168
169 qdf_export_symbol(qdf_is_recovering);
170
171 static qdf_op_protect_cb __on_op_protect;
172 static qdf_op_unprotect_cb __on_op_unprotect;
173
qdf_op_callbacks_register(qdf_op_protect_cb on_protect,qdf_op_unprotect_cb on_unprotect)174 void qdf_op_callbacks_register(qdf_op_protect_cb on_protect,
175 qdf_op_unprotect_cb on_unprotect)
176 {
177 __on_op_protect = on_protect;
178 __on_op_unprotect = on_unprotect;
179 }
180 qdf_export_symbol(qdf_op_callbacks_register);
181
__qdf_op_protect(struct qdf_op_sync ** out_sync,const char * func)182 int __qdf_op_protect(struct qdf_op_sync **out_sync, const char *func)
183 {
184 if (!__on_op_protect)
185 return 0;
186
187 return __on_op_protect((void **)out_sync, func);
188 }
189 qdf_export_symbol(__qdf_op_protect);
190
__qdf_op_unprotect(struct qdf_op_sync * sync,const char * func)191 void __qdf_op_unprotect(struct qdf_op_sync *sync, const char *func)
192 {
193 if (__on_op_unprotect)
194 __on_op_unprotect(sync, func);
195 }
196 qdf_export_symbol(__qdf_op_unprotect);
197
qdf_register_drv_connected_callback(qdf_is_drv_connected_callback is_drv_connected)198 void qdf_register_drv_connected_callback(qdf_is_drv_connected_callback
199 is_drv_connected)
200 {
201 is_drv_connected_cb = is_drv_connected;
202 }
203 qdf_export_symbol(qdf_register_drv_connected_callback);
204
qdf_is_drv_connected(void)205 bool qdf_is_drv_connected(void)
206 {
207 if (!is_drv_connected_cb) {
208 qdf_err("drv connected callback is not registered");
209 return false;
210 }
211
212 return is_drv_connected_cb();
213 }
214 qdf_export_symbol(qdf_is_drv_connected);
215
qdf_check_state_before_panic(const char * func,const uint32_t line)216 void qdf_check_state_before_panic(const char *func, const uint32_t line)
217 {
218 if (!qdf_is_recovering() && !qdf_is_fw_down())
219 QDF_DEBUG_PANIC_FL(func, line, "");
220 }
221
222 qdf_export_symbol(qdf_check_state_before_panic);
223
qdf_register_drv_supported_callback(qdf_is_drv_supported_callback is_drv_supported)224 void qdf_register_drv_supported_callback(qdf_is_drv_supported_callback
225 is_drv_supported)
226 {
227 is_drv_supported_cb = is_drv_supported;
228 }
229
230 qdf_export_symbol(qdf_register_drv_supported_callback);
231
qdf_is_drv_supported(void)232 bool qdf_is_drv_supported(void)
233 {
234 if (!is_drv_supported_cb) {
235 qdf_err("drv supported callback is not registered");
236 return false;
237 }
238
239 return is_drv_supported_cb();
240 }
241
242 qdf_export_symbol(qdf_is_drv_supported);
243
qdf_register_recovery_reason_update(qdf_recovery_reason_update_callback callback)244 void qdf_register_recovery_reason_update(qdf_recovery_reason_update_callback
245 callback)
246 {
247 update_recovery_reason_cb = callback;
248 }
249
250 qdf_export_symbol(qdf_register_recovery_reason_update);
251
qdf_recovery_reason_update(enum qdf_hang_reason reason)252 void qdf_recovery_reason_update(enum qdf_hang_reason reason)
253 {
254 if (!update_recovery_reason_cb)
255 return;
256
257 update_recovery_reason_cb(reason);
258 }
259
260 qdf_export_symbol(qdf_recovery_reason_update);
261
qdf_register_get_bus_reg_dump(qdf_bus_reg_dump callback)262 void qdf_register_get_bus_reg_dump(qdf_bus_reg_dump callback)
263 {
264 get_bus_reg_dump = callback;
265 }
266
267 qdf_export_symbol(qdf_register_get_bus_reg_dump);
268
qdf_get_bus_reg_dump(struct device * dev,uint8_t * buf,uint32_t len)269 void qdf_get_bus_reg_dump(struct device *dev, uint8_t *buf, uint32_t len)
270 {
271 if (!get_bus_reg_dump)
272 return;
273
274 get_bus_reg_dump(dev, buf, len);
275 }
276
277 qdf_export_symbol(qdf_get_bus_reg_dump);
278
279 #ifdef WLAN_SUPPORT_DPDK
qdf_uio_register_device(struct device * parent,qdf_uio_info_t * info)280 int qdf_uio_register_device(struct device *parent, qdf_uio_info_t *info)
281 {
282 return uio_register_device(parent, (struct uio_info *)info);
283 }
284
285 qdf_export_symbol(qdf_uio_register_device);
286
qdf_uio_unregister_device(qdf_uio_info_t * info)287 void qdf_uio_unregister_device(qdf_uio_info_t *info)
288 {
289 uio_unregister_device(info);
290 }
291
292 qdf_export_symbol(qdf_uio_unregister_device);
293 #endif
294