/* * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /** * DOC: wlan_hdd_data_stall_detection.c * * WLAN Host Device Driver Data Stall detection API implementation */ #include #include #include "wlan_hdd_data_stall_detection.h" #include "wlan_hdd_main.h" #include "cdp_txrx_cmn.h" #include "cdp_txrx_misc.h" #include "ol_txrx_types.h" #include "ol_defines.h" #ifdef FEATURE_WLAN_DIAG_SUPPORT #include "host_diag_core_event.h" #include "host_diag_core_log.h" #endif /* FEATURE_WLAN_DIAG_SUPPORT */ #ifdef FEATURE_WLAN_DIAG_SUPPORT /** * hdd_data_stall_send_event()- send data stall information * @reason: data stall event subtype * This Function sends data stall status diag event * * Return: void. */ static void hdd_data_stall_send_event(uint32_t reason) { WLAN_HOST_DIAG_EVENT_DEF(sta_data_stall, struct host_event_wlan_datastall); qdf_mem_zero(&sta_data_stall, sizeof(sta_data_stall)); sta_data_stall.reason = reason; hdd_debug("Posting data stall event %x", reason); WLAN_HOST_DIAG_EVENT_REPORT(&sta_data_stall, EVENT_WLAN_STA_DATASTALL); cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC), CDP_TXRX_PATH_STATS, QDF_STATS_VERBOSITY_LEVEL_LOW); } #else static inline void hdd_data_stall_send_event(uint32_t reason) { } #endif /** * hdd_data_stall_process_event() - Process data stall event * @msg: data stall message * * Process data stall message * * Return: QDF_STATUS */ static QDF_STATUS hdd_data_stall_process_event(struct scheduler_msg *msg) { struct data_stall_event_info *data_stall_info; if (!msg) return QDF_STATUS_E_FAILURE; data_stall_info = msg->bodyptr; hdd_data_stall_send_event(data_stall_info->data_stall_type); return QDF_STATUS_SUCCESS; } /** * hdd_data_stall_process_cb() - Process data stall message * @info: data stall message * * Process data stall message * * Return: void */ static void hdd_data_stall_process_cb( struct data_stall_event_info *info) { struct scheduler_msg msg = {0}; struct data_stall_event_info *data_stall_event_info; QDF_STATUS status; data_stall_event_info = qdf_mem_malloc(sizeof(*data_stall_event_info)); if (!data_stall_event_info) return; data_stall_event_info->data_stall_type = info->data_stall_type; data_stall_event_info->indicator = info->indicator; data_stall_event_info->pdev_id = info->pdev_id; data_stall_event_info->recovery_type = info->recovery_type; data_stall_event_info->vdev_id_bitmap = info->vdev_id_bitmap; sys_build_message_header(SYS_MSG_ID_DATA_STALL_MSG, &msg); /* Save callback and data */ msg.callback = hdd_data_stall_process_event; msg.bodyptr = data_stall_event_info; msg.bodyval = 0; status = scheduler_post_message(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, QDF_MODULE_ID_SYS, &msg); if (status != QDF_STATUS_SUCCESS) qdf_mem_free(data_stall_event_info); } int hdd_register_data_stall_detect_cb(void) { QDF_STATUS status; void *soc = cds_get_context(QDF_MODULE_ID_SOC); /* Register the data stall callback */ hdd_debug("Register data stall detect callback"); status = cdp_data_stall_cb_register(soc, OL_TXRX_PDEV_ID, hdd_data_stall_process_cb); return qdf_status_to_os_return(status); } int hdd_deregister_data_stall_detect_cb(void) { QDF_STATUS status; void *soc = cds_get_context(QDF_MODULE_ID_SOC); /* De-Register the data stall callback */ hdd_debug("De-Register data stall detect callback"); status = cdp_data_stall_cb_deregister(soc, OL_TXRX_PDEV_ID, hdd_data_stall_process_cb); return qdf_status_to_os_return(status); }