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