1 /* 2 * Copyright (c) 2018-2019 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_recovering_callback is_recovering_cb; 30 static qdf_is_drv_connected_callback is_drv_connected_cb; 31 static qdf_wmi_send_over_qmi_callback _wmi_send_recv_qmi_cb; 32 33 void qdf_register_fw_down_callback(qdf_is_fw_down_callback is_fw_down) 34 { 35 is_fw_down_cb = is_fw_down; 36 } 37 38 qdf_export_symbol(qdf_register_fw_down_callback); 39 40 bool qdf_is_fw_down(void) 41 { 42 if (!is_fw_down_cb) { 43 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, 44 "fw down callback is not registered"); 45 return false; 46 } 47 48 return is_fw_down_cb(); 49 } 50 qdf_export_symbol(qdf_is_fw_down); 51 52 void qdf_register_wmi_send_recv_qmi_callback(qdf_wmi_send_over_qmi_callback 53 wmi_send_recv_qmi_cb) 54 { 55 _wmi_send_recv_qmi_cb = wmi_send_recv_qmi_cb; 56 } 57 58 qdf_export_symbol(qdf_register_wmi_send_recv_qmi_callback); 59 60 QDF_STATUS qdf_wmi_send_recv_qmi(void *buf, uint32_t len, void *cb_ctx, 61 qdf_wmi_recv_qmi_cb wmi_recv_qmi_cb) 62 { 63 if (!_wmi_send_recv_qmi_cb) { 64 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, 65 "Platform callback for WMI over QMI not registered"); 66 return QDF_STATUS_E_INVAL; 67 } 68 69 return _wmi_send_recv_qmi_cb(buf, len, cb_ctx, wmi_recv_qmi_cb); 70 } 71 72 qdf_export_symbol(qdf_wmi_send_recv_qmi); 73 74 void qdf_register_self_recovery_callback(qdf_self_recovery_callback callback) 75 { 76 self_recovery_cb = callback; 77 } 78 79 qdf_export_symbol(qdf_register_self_recovery_callback); 80 81 void __qdf_trigger_self_recovery(enum qdf_hang_reason reason, 82 const char *func, const uint32_t line) 83 { 84 if (self_recovery_cb) 85 self_recovery_cb(reason, func, line); 86 else 87 QDF_DEBUG_PANIC_FL(func, line, ""); 88 } 89 90 qdf_export_symbol(__qdf_trigger_self_recovery); 91 92 void qdf_register_recovering_state_query_callback( 93 qdf_is_recovering_callback is_recovering) 94 { 95 is_recovering_cb = is_recovering; 96 } 97 98 bool qdf_is_recovering(void) 99 { 100 if (is_recovering_cb) 101 return is_recovering_cb(); 102 return false; 103 } 104 105 qdf_export_symbol(qdf_is_recovering); 106 107 static qdf_op_protect_cb __on_op_protect; 108 static qdf_op_unprotect_cb __on_op_unprotect; 109 110 void qdf_op_callbacks_register(qdf_op_protect_cb on_protect, 111 qdf_op_unprotect_cb on_unprotect) 112 { 113 __on_op_protect = on_protect; 114 __on_op_unprotect = on_unprotect; 115 } 116 qdf_export_symbol(qdf_op_callbacks_register); 117 118 int __qdf_op_protect(struct qdf_op_sync **out_sync, const char *func) 119 { 120 if (!__on_op_protect) 121 return 0; 122 123 return __on_op_protect((void **)out_sync, func); 124 } 125 qdf_export_symbol(__qdf_op_protect); 126 127 void __qdf_op_unprotect(struct qdf_op_sync *sync, const char *func) 128 { 129 if (__on_op_unprotect) 130 __on_op_unprotect(sync, func); 131 } 132 qdf_export_symbol(__qdf_op_unprotect); 133 134 void qdf_register_drv_connected_callback(qdf_is_drv_connected_callback 135 is_drv_connected) 136 { 137 is_drv_connected_cb = is_drv_connected; 138 } 139 qdf_export_symbol(qdf_register_drv_connected_callback); 140 141 bool qdf_is_drv_connected(void) 142 { 143 if (!is_drv_connected_cb) { 144 qdf_err("drv connected callback is not registered"); 145 return false; 146 } 147 148 return is_drv_connected_cb(); 149 } 150 qdf_export_symbol(qdf_is_drv_connected); 151