xref: /wlan-dirver/qca-wifi-host-cmn/qdf/src/qdf_platform.c (revision 2f4b444fb7e689b83a4ab0e7b3b38f0bf4def8e0)
1 /*
2  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include "qdf_module.h"
20 #include "qdf_trace.h"
21 #include "qdf_platform.h"
22 
23 /**
24  * The following callbacks should be defined static to make sure they are
25  * initialized to NULL
26  */
27 static qdf_self_recovery_callback	self_recovery_cb;
28 static qdf_is_fw_down_callback		is_fw_down_cb;
29 static qdf_is_driver_unloading_callback is_driver_unloading_cb;
30 static qdf_is_driver_state_module_stop_callback is_driver_state_module_stop_cb;
31 static qdf_is_recovering_callback	is_recovering_cb;
32 static qdf_is_drv_connected_callback    is_drv_connected_cb;
33 static qdf_wmi_send_over_qmi_callback _wmi_send_recv_qmi_cb;
34 static qdf_is_drv_supported_callback    is_drv_supported_cb;
35 static qdf_recovery_reason_update_callback   update_recovery_reason_cb;
36 static qdf_bus_reg_dump   get_bus_reg_dump;
37 
38 
39 
40 void qdf_register_fw_down_callback(qdf_is_fw_down_callback is_fw_down)
41 {
42 	is_fw_down_cb = is_fw_down;
43 }
44 
45 qdf_export_symbol(qdf_register_fw_down_callback);
46 
47 bool qdf_is_fw_down(void)
48 {
49 	if (!is_fw_down_cb) {
50 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
51 			"fw down callback is not registered");
52 			return false;
53 	}
54 
55 	return is_fw_down_cb();
56 }
57 qdf_export_symbol(qdf_is_fw_down);
58 
59 void qdf_register_wmi_send_recv_qmi_callback(qdf_wmi_send_over_qmi_callback
60 					     wmi_send_recv_qmi_cb)
61 {
62 	_wmi_send_recv_qmi_cb = wmi_send_recv_qmi_cb;
63 }
64 
65 qdf_export_symbol(qdf_register_wmi_send_recv_qmi_callback);
66 
67 QDF_STATUS qdf_wmi_send_recv_qmi(void *buf, uint32_t len, void *cb_ctx,
68 				 qdf_wmi_recv_qmi_cb wmi_recv_qmi_cb)
69 {
70 	if (!_wmi_send_recv_qmi_cb) {
71 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
72 			  "Platform callback for WMI over QMI not registered");
73 			return QDF_STATUS_E_INVAL;
74 	}
75 
76 	return _wmi_send_recv_qmi_cb(buf, len, cb_ctx, wmi_recv_qmi_cb);
77 }
78 
79 qdf_export_symbol(qdf_wmi_send_recv_qmi);
80 
81 void qdf_register_is_driver_unloading_callback(
82 				qdf_is_driver_unloading_callback callback)
83 {
84 	is_driver_unloading_cb = callback;
85 }
86 
87 qdf_export_symbol(qdf_register_is_driver_unloading_callback);
88 
89 void qdf_register_is_driver_state_module_stop_callback(
90 			qdf_is_driver_state_module_stop_callback callback)
91 {
92 	is_driver_state_module_stop_cb = callback;
93 }
94 
95 qdf_export_symbol(qdf_register_is_driver_state_module_stop_callback);
96 
97 void qdf_register_self_recovery_callback(qdf_self_recovery_callback callback)
98 {
99 	self_recovery_cb = callback;
100 }
101 
102 qdf_export_symbol(qdf_register_self_recovery_callback);
103 
104 void __qdf_trigger_self_recovery(void *psoc, enum qdf_hang_reason reason,
105 				 const char *func, const uint32_t line)
106 {
107 	if (self_recovery_cb)
108 		self_recovery_cb(psoc, reason, func, line);
109 	else
110 		QDF_DEBUG_PANIC_FL(func, line, "");
111 }
112 
113 qdf_export_symbol(__qdf_trigger_self_recovery);
114 
115 void qdf_register_recovering_state_query_callback(
116 			qdf_is_recovering_callback is_recovering)
117 {
118 	is_recovering_cb = is_recovering;
119 }
120 
121 bool qdf_is_driver_unloading(void)
122 {
123 	if (is_driver_unloading_cb)
124 		return is_driver_unloading_cb();
125 	return false;
126 }
127 
128 qdf_export_symbol(qdf_is_driver_unloading);
129 
130 bool qdf_is_driver_state_module_stop(void)
131 {
132 	if (is_driver_state_module_stop_cb)
133 		return is_driver_state_module_stop_cb();
134 	return false;
135 }
136 
137 qdf_export_symbol(qdf_is_driver_state_module_stop);
138 
139 bool qdf_is_recovering(void)
140 {
141 	if (is_recovering_cb)
142 		return is_recovering_cb();
143 	return false;
144 }
145 
146 qdf_export_symbol(qdf_is_recovering);
147 
148 static qdf_op_protect_cb __on_op_protect;
149 static qdf_op_unprotect_cb __on_op_unprotect;
150 
151 void qdf_op_callbacks_register(qdf_op_protect_cb on_protect,
152 			       qdf_op_unprotect_cb on_unprotect)
153 {
154 	__on_op_protect = on_protect;
155 	__on_op_unprotect = on_unprotect;
156 }
157 qdf_export_symbol(qdf_op_callbacks_register);
158 
159 int __qdf_op_protect(struct qdf_op_sync **out_sync, const char *func)
160 {
161 	if (!__on_op_protect)
162 		return 0;
163 
164 	return __on_op_protect((void **)out_sync, func);
165 }
166 qdf_export_symbol(__qdf_op_protect);
167 
168 void __qdf_op_unprotect(struct qdf_op_sync *sync, const char *func)
169 {
170 	if (__on_op_unprotect)
171 		__on_op_unprotect(sync, func);
172 }
173 qdf_export_symbol(__qdf_op_unprotect);
174 
175 void qdf_register_drv_connected_callback(qdf_is_drv_connected_callback
176 					 is_drv_connected)
177 {
178 	is_drv_connected_cb = is_drv_connected;
179 }
180 qdf_export_symbol(qdf_register_drv_connected_callback);
181 
182 bool qdf_is_drv_connected(void)
183 {
184 	if (!is_drv_connected_cb) {
185 		qdf_err("drv connected callback is not registered");
186 		return false;
187 	}
188 
189 	return is_drv_connected_cb();
190 }
191 qdf_export_symbol(qdf_is_drv_connected);
192 
193 void qdf_check_state_before_panic(const char *func, const uint32_t line)
194 {
195 	if (!qdf_is_recovering() && !qdf_is_fw_down())
196 		QDF_DEBUG_PANIC_FL(func, line, "");
197 }
198 
199 qdf_export_symbol(qdf_check_state_before_panic);
200 
201 void qdf_register_drv_supported_callback(qdf_is_drv_supported_callback
202 					 is_drv_supported)
203 {
204 	is_drv_supported_cb = is_drv_supported;
205 }
206 
207 qdf_export_symbol(qdf_register_drv_supported_callback);
208 
209 bool qdf_is_drv_supported(void)
210 {
211 	if (!is_drv_supported_cb) {
212 		qdf_err("drv supported callback is not registered");
213 		return false;
214 	}
215 
216 	return is_drv_supported_cb();
217 }
218 
219 qdf_export_symbol(qdf_is_drv_supported);
220 
221 void qdf_register_recovery_reason_update(qdf_recovery_reason_update_callback
222 					 callback)
223 {
224 	update_recovery_reason_cb = callback;
225 }
226 
227 qdf_export_symbol(qdf_register_recovery_reason_update);
228 
229 void qdf_recovery_reason_update(enum qdf_hang_reason reason)
230 {
231 	if (!update_recovery_reason_cb)
232 		return;
233 
234 	update_recovery_reason_cb(reason);
235 }
236 
237 qdf_export_symbol(qdf_recovery_reason_update);
238 
239 void qdf_register_get_bus_reg_dump(qdf_bus_reg_dump callback)
240 {
241 	get_bus_reg_dump = callback;
242 }
243 
244 qdf_export_symbol(qdf_register_get_bus_reg_dump);
245 
246 void qdf_get_bus_reg_dump(struct device *dev, uint8_t *buf, uint32_t len)
247 {
248 	if (!get_bus_reg_dump)
249 		return;
250 
251 	get_bus_reg_dump(dev, buf, len);
252 }
253 
254 qdf_export_symbol(qdf_get_bus_reg_dump);
255