xref: /wlan-dirver/qca-wifi-host-cmn/qdf/src/qdf_platform.c (revision 97f44cd39e4ff816eaa1710279d28cf6b9e65ad9)
1 /*
2  * Copyright (c) 2018-2020 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_recovering_callback	is_recovering_cb;
31 static qdf_is_drv_connected_callback    is_drv_connected_cb;
32 static qdf_wmi_send_over_qmi_callback _wmi_send_recv_qmi_cb;
33 static qdf_is_drv_supported_callback    is_drv_supported_cb;
34 static qdf_recovery_reason_update_callback   update_recovery_reason_cb;
35 static qdf_bus_reg_dump   get_bus_reg_dump;
36 
37 
38 
39 void qdf_register_fw_down_callback(qdf_is_fw_down_callback is_fw_down)
40 {
41 	is_fw_down_cb = is_fw_down;
42 }
43 
44 qdf_export_symbol(qdf_register_fw_down_callback);
45 
46 bool qdf_is_fw_down(void)
47 {
48 	if (!is_fw_down_cb) {
49 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
50 			"fw down callback is not registered");
51 			return false;
52 	}
53 
54 	return is_fw_down_cb();
55 }
56 qdf_export_symbol(qdf_is_fw_down);
57 
58 void qdf_register_wmi_send_recv_qmi_callback(qdf_wmi_send_over_qmi_callback
59 					     wmi_send_recv_qmi_cb)
60 {
61 	_wmi_send_recv_qmi_cb = wmi_send_recv_qmi_cb;
62 }
63 
64 qdf_export_symbol(qdf_register_wmi_send_recv_qmi_callback);
65 
66 QDF_STATUS qdf_wmi_send_recv_qmi(void *buf, uint32_t len, void *cb_ctx,
67 				 qdf_wmi_recv_qmi_cb wmi_recv_qmi_cb)
68 {
69 	if (!_wmi_send_recv_qmi_cb) {
70 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
71 			  "Platform callback for WMI over QMI not registered");
72 			return QDF_STATUS_E_INVAL;
73 	}
74 
75 	return _wmi_send_recv_qmi_cb(buf, len, cb_ctx, wmi_recv_qmi_cb);
76 }
77 
78 qdf_export_symbol(qdf_wmi_send_recv_qmi);
79 
80 void qdf_register_is_driver_unloading_callback(
81 				qdf_is_driver_unloading_callback callback)
82 {
83 	is_driver_unloading_cb = callback;
84 }
85 
86 qdf_export_symbol(qdf_register_is_driver_unloading_callback);
87 
88 void qdf_register_self_recovery_callback(qdf_self_recovery_callback callback)
89 {
90 	self_recovery_cb = callback;
91 }
92 
93 qdf_export_symbol(qdf_register_self_recovery_callback);
94 
95 void __qdf_trigger_self_recovery(void *psoc, enum qdf_hang_reason reason,
96 				 const char *func, const uint32_t line)
97 {
98 	if (self_recovery_cb)
99 		self_recovery_cb(psoc, reason, func, line);
100 	else
101 		QDF_DEBUG_PANIC_FL(func, line, "");
102 }
103 
104 qdf_export_symbol(__qdf_trigger_self_recovery);
105 
106 void qdf_register_recovering_state_query_callback(
107 			qdf_is_recovering_callback is_recovering)
108 {
109 	is_recovering_cb = is_recovering;
110 }
111 
112 bool qdf_is_driver_unloading(void)
113 {
114 	if (is_driver_unloading_cb)
115 		return is_driver_unloading_cb();
116 	return false;
117 }
118 
119 qdf_export_symbol(qdf_is_driver_unloading);
120 
121 bool qdf_is_recovering(void)
122 {
123 	if (is_recovering_cb)
124 		return is_recovering_cb();
125 	return false;
126 }
127 
128 qdf_export_symbol(qdf_is_recovering);
129 
130 static qdf_op_protect_cb __on_op_protect;
131 static qdf_op_unprotect_cb __on_op_unprotect;
132 
133 void qdf_op_callbacks_register(qdf_op_protect_cb on_protect,
134 			       qdf_op_unprotect_cb on_unprotect)
135 {
136 	__on_op_protect = on_protect;
137 	__on_op_unprotect = on_unprotect;
138 }
139 qdf_export_symbol(qdf_op_callbacks_register);
140 
141 int __qdf_op_protect(struct qdf_op_sync **out_sync, const char *func)
142 {
143 	if (!__on_op_protect)
144 		return 0;
145 
146 	return __on_op_protect((void **)out_sync, func);
147 }
148 qdf_export_symbol(__qdf_op_protect);
149 
150 void __qdf_op_unprotect(struct qdf_op_sync *sync, const char *func)
151 {
152 	if (__on_op_unprotect)
153 		__on_op_unprotect(sync, func);
154 }
155 qdf_export_symbol(__qdf_op_unprotect);
156 
157 void qdf_register_drv_connected_callback(qdf_is_drv_connected_callback
158 					 is_drv_connected)
159 {
160 	is_drv_connected_cb = is_drv_connected;
161 }
162 qdf_export_symbol(qdf_register_drv_connected_callback);
163 
164 bool qdf_is_drv_connected(void)
165 {
166 	if (!is_drv_connected_cb) {
167 		qdf_err("drv connected callback is not registered");
168 		return false;
169 	}
170 
171 	return is_drv_connected_cb();
172 }
173 qdf_export_symbol(qdf_is_drv_connected);
174 
175 void qdf_check_state_before_panic(void)
176 {
177 	if (!qdf_is_recovering() && !qdf_is_fw_down())
178 		QDF_BUG(0);
179 }
180 
181 qdf_export_symbol(qdf_check_state_before_panic);
182 
183 void qdf_register_drv_supported_callback(qdf_is_drv_supported_callback
184 					 is_drv_supported)
185 {
186 	is_drv_supported_cb = is_drv_supported;
187 }
188 
189 qdf_export_symbol(qdf_register_drv_supported_callback);
190 
191 bool qdf_is_drv_supported(void)
192 {
193 	if (!is_drv_supported_cb) {
194 		qdf_err("drv supported callback is not registered");
195 		return false;
196 	}
197 
198 	return is_drv_supported_cb();
199 }
200 
201 qdf_export_symbol(qdf_is_drv_supported);
202 
203 void qdf_register_recovery_reason_update(qdf_recovery_reason_update_callback
204 					 callback)
205 {
206 	update_recovery_reason_cb = callback;
207 }
208 
209 qdf_export_symbol(qdf_register_recovery_reason_update);
210 
211 void qdf_recovery_reason_update(enum qdf_hang_reason reason)
212 {
213 	if (!update_recovery_reason_cb)
214 		return;
215 
216 	update_recovery_reason_cb(reason);
217 }
218 
219 qdf_export_symbol(qdf_recovery_reason_update);
220 
221 void qdf_register_get_bus_reg_dump(qdf_bus_reg_dump callback)
222 {
223 	get_bus_reg_dump = callback;
224 }
225 
226 qdf_export_symbol(qdf_register_get_bus_reg_dump);
227 
228 void qdf_get_bus_reg_dump(struct device *dev, uint8_t *buf, uint32_t len)
229 {
230 	if (!get_bus_reg_dump)
231 		return;
232 
233 	get_bus_reg_dump(dev, buf, len);
234 }
235 
236 qdf_export_symbol(qdf_get_bus_reg_dump);
237