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 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 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 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 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 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 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 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 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 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 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 138 void qdf_register_recovering_state_query_callback( 139 qdf_is_recovering_callback is_recovering) 140 { 141 is_recovering_cb = is_recovering; 142 } 143 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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