14f60ed91SVivek /* 280a5429aSVivek * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. 331864b63SHimanshu Batra * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 44f60ed91SVivek * 54f60ed91SVivek * Permission to use, copy, modify, and/or distribute this software for 64f60ed91SVivek * any purpose with or without fee is hereby granted, provided that the 74f60ed91SVivek * above copyright notice and this permission notice appear in all 84f60ed91SVivek * copies. 94f60ed91SVivek * 104f60ed91SVivek * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 114f60ed91SVivek * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 124f60ed91SVivek * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 134f60ed91SVivek * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 144f60ed91SVivek * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 154f60ed91SVivek * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 164f60ed91SVivek * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 174f60ed91SVivek * PERFORMANCE OF THIS SOFTWARE. 184f60ed91SVivek */ 194f60ed91SVivek /** 204f60ed91SVivek * DOC: wlan_serialization_debug.c 214f60ed91SVivek * This file defines the debug functions for serialization component. 224f60ed91SVivek */ 234f60ed91SVivek 244f60ed91SVivek #include <wlan_objmgr_vdev_obj.h> 254f60ed91SVivek #include <wlan_objmgr_pdev_obj.h> 264f60ed91SVivek #include <wlan_utility.h> 274f60ed91SVivek #include "wlan_serialization_utils_i.h" 284f60ed91SVivek #include "wlan_serialization_main_i.h" 294f60ed91SVivek #include "wlan_serialization_queue_i.h" 304f60ed91SVivek #include "wlan_serialization_debug_i.h" 314f60ed91SVivek 324f60ed91SVivek #ifdef WLAN_SER_DEBUG 334f60ed91SVivek const char *ser_reason_string[SER_QUEUE_ACTION_MAX] = { 344f60ed91SVivek "REQUEST", 354f60ed91SVivek "REMOVE", 364f60ed91SVivek "CANCEL", 374f60ed91SVivek "TIMEOUT", 384f60ed91SVivek "ACTIVATION_FAILED", 394f60ed91SVivek "PENDING_TO_ACTIVE", 404f60ed91SVivek }; 414f60ed91SVivek 424f60ed91SVivek static void wlan_ser_print_queues( 434f60ed91SVivek qdf_list_t *queue, 444f60ed91SVivek enum wlan_serialization_node node_type, 454f60ed91SVivek bool is_active_queue) 464f60ed91SVivek { 474f60ed91SVivek struct wlan_serialization_command_list *cmd_list = NULL; 484f60ed91SVivek uint32_t queuelen; 494f60ed91SVivek QDF_STATUS status = QDF_STATUS_E_FAILURE; 504f60ed91SVivek qdf_list_node_t *nnode = NULL; 514f60ed91SVivek bool is_pdev_queue = false; 524f60ed91SVivek 534f60ed91SVivek if (node_type == WLAN_SER_PDEV_NODE) 544f60ed91SVivek is_pdev_queue = true; 554f60ed91SVivek 56c4eabce9SVivek ser_err_no_fl(WLAN_SER_LINE); 57c4eabce9SVivek ser_err_no_fl("%s %s Queue", (is_pdev_queue) ? "PDEV" : "VDEV", 584f60ed91SVivek (is_active_queue ? "Active" : "Pending")); 594f60ed91SVivek 60c4eabce9SVivek ser_err_no_fl(WLAN_SER_LINE); 6180a5429aSVivek ser_err_no_fl("|CMD_TYPE|CMD_ID|VDEV_ID|BLOCKING|PRIORITY|"); 62c4eabce9SVivek ser_err_no_fl(WLAN_SER_LINE); 634f60ed91SVivek 644f60ed91SVivek queuelen = wlan_serialization_list_size(queue); 654f60ed91SVivek while (queuelen--) { 664f60ed91SVivek status = wlan_serialization_get_cmd_from_queue(queue, &nnode); 674f60ed91SVivek if (status != QDF_STATUS_SUCCESS) 684f60ed91SVivek break; 694f60ed91SVivek 704f60ed91SVivek if (node_type == WLAN_SER_PDEV_NODE) 714f60ed91SVivek cmd_list = qdf_container_of( 724f60ed91SVivek nnode, 734f60ed91SVivek struct wlan_serialization_command_list, 744f60ed91SVivek pdev_node); 754f60ed91SVivek else 764f60ed91SVivek cmd_list = qdf_container_of( 774f60ed91SVivek nnode, 784f60ed91SVivek struct wlan_serialization_command_list, 794f60ed91SVivek vdev_node); 804f60ed91SVivek 8180a5429aSVivek ser_err_no_fl("|%8u|%6u|%6u|%8u|%8u|", 824f60ed91SVivek cmd_list->cmd.cmd_type, 834f60ed91SVivek cmd_list->cmd.cmd_id, 8480a5429aSVivek wlan_vdev_get_id(cmd_list->cmd.vdev), 854f60ed91SVivek cmd_list->cmd.is_blocking, 864f60ed91SVivek cmd_list->cmd.is_high_priority); 874f60ed91SVivek } 884f60ed91SVivek } 894f60ed91SVivek 904f60ed91SVivek static void wlan_ser_print_pdev_queue( 914f60ed91SVivek struct wlan_serialization_pdev_queue *ser_pdev_q_obj, 924f60ed91SVivek enum wlan_serialization_node node_type) 934f60ed91SVivek { 944f60ed91SVivek /*Dump the active queue*/ 954f60ed91SVivek wlan_ser_print_queues(&ser_pdev_q_obj->active_list, 964f60ed91SVivek node_type, true); 974f60ed91SVivek 984f60ed91SVivek /*Dump the pending queue*/ 994f60ed91SVivek wlan_ser_print_queues(&ser_pdev_q_obj->pending_list, 1004f60ed91SVivek node_type, false); 1014f60ed91SVivek } 1024f60ed91SVivek 1034f60ed91SVivek static void wlan_ser_print_vdev_queue( 1044f60ed91SVivek struct wlan_serialization_vdev_queue *ser_vdev_q_obj, 1054f60ed91SVivek enum wlan_serialization_node node_type) 1064f60ed91SVivek { 1074f60ed91SVivek /*Dump the active queue*/ 1084f60ed91SVivek wlan_ser_print_queues(&ser_vdev_q_obj->active_list, 1094f60ed91SVivek node_type, true); 1104f60ed91SVivek 1114f60ed91SVivek /*Dump the pending queue*/ 1124f60ed91SVivek wlan_ser_print_queues(&ser_vdev_q_obj->pending_list, 1134f60ed91SVivek node_type, false); 1144f60ed91SVivek } 1154f60ed91SVivek 1164f60ed91SVivek static void wlan_ser_print_all_history( 1174f60ed91SVivek struct wlan_serialization_pdev_queue *pdev_queue, 1184f60ed91SVivek bool for_vdev_queue, 1194f60ed91SVivek uint32_t vdev_id) 1204f60ed91SVivek { 1214f60ed91SVivek uint8_t idx; 122445a3a58SVivek uint8_t data_idx; 1234f60ed91SVivek struct ser_history *history_info; 1244f60ed91SVivek struct ser_data *data; 1254f60ed91SVivek 1264f60ed91SVivek history_info = &pdev_queue->history; 1274f60ed91SVivek 128c4eabce9SVivek ser_err_no_fl(WLAN_SER_LINE WLAN_SER_LINE); 129c4eabce9SVivek ser_err_no_fl("Queue Commands History"); 130c4eabce9SVivek ser_err_no_fl(WLAN_SER_LINE WLAN_SER_LINE); 131c4eabce9SVivek ser_err_no_fl(WLAN_SER_HISTORY_HEADER); 132c4eabce9SVivek ser_err_no_fl(WLAN_SER_LINE WLAN_SER_LINE); 1334f60ed91SVivek 134445a3a58SVivek for (idx = 0; idx < SER_MAX_HISTORY_CMDS; idx++) { 135445a3a58SVivek data_idx = (history_info->index + idx) % SER_MAX_HISTORY_CMDS; 136445a3a58SVivek 137445a3a58SVivek data = &history_info->data[data_idx]; 1384f60ed91SVivek 1394f60ed91SVivek if (data->ser_reason >= SER_QUEUE_ACTION_MAX) { 140445a3a58SVivek ser_debug("Invalid Serialization Reason"); 1414f60ed91SVivek continue; 1424f60ed91SVivek } 1434f60ed91SVivek 144445a3a58SVivek if (!data->data_updated) 145445a3a58SVivek continue; 146445a3a58SVivek 1474f60ed91SVivek if (for_vdev_queue) { 1484f60ed91SVivek if (vdev_id != data->vdev_id) 1494f60ed91SVivek continue; 1504f60ed91SVivek } 151c4eabce9SVivek ser_err_no_fl( 15231864b63SHimanshu Batra "|0x%016llx|%8d|%6d|%7d|%8d|%8d|%6s|%7s|%17s|", 15331864b63SHimanshu Batra data->time, 1544f60ed91SVivek data->cmd_type, 1554f60ed91SVivek data->cmd_id, 1564f60ed91SVivek data->vdev_id, 1574f60ed91SVivek data->is_blocking, 1584f60ed91SVivek data->is_high_priority, 1594f60ed91SVivek data->add_remove ? "ADD" : "REMOVE", 1604f60ed91SVivek data->active_pending ? "ACTIVE" : "PENDING", 1614f60ed91SVivek ser_reason_string[data->ser_reason]); 1624f60ed91SVivek } 1634f60ed91SVivek } 1644f60ed91SVivek 1654f60ed91SVivek QDF_STATUS wlan_ser_print_history( 1664f60ed91SVivek struct wlan_objmgr_vdev *vdev, uint8_t val, 1674f60ed91SVivek uint32_t sub_val) 1684f60ed91SVivek { 1694f60ed91SVivek struct wlan_ser_pdev_obj *ser_pdev; 1704f60ed91SVivek struct wlan_ser_vdev_obj *ser_vdev; 1714f60ed91SVivek struct wlan_serialization_pdev_queue *pdev_q; 1724f60ed91SVivek struct wlan_serialization_vdev_queue *vdev_q; 1734f60ed91SVivek bool for_vdev_queue = false; 174963b9daaSVivek uint32_t vdev_id = WLAN_INVALID_VDEV_ID; 1754f60ed91SVivek 1764f60ed91SVivek ser_pdev = wlan_serialization_get_pdev_obj( 1774f60ed91SVivek wlan_vdev_get_pdev(vdev)); 1784f60ed91SVivek 1794f60ed91SVivek ser_vdev = wlan_serialization_get_vdev_obj(vdev); 1804f60ed91SVivek 1814f60ed91SVivek switch (val) { 1824f60ed91SVivek /* 1834f60ed91SVivek * Print scan pdev queues 1844f60ed91SVivek */ 1854f60ed91SVivek case SER_PDEV_QUEUE_COMP_SCAN: 186c4eabce9SVivek ser_err_no_fl("Serialization SCAN Queues(LIVE)"); 1874f60ed91SVivek pdev_q = &ser_pdev->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 1884f60ed91SVivek wlan_ser_print_pdev_queue(pdev_q, WLAN_SER_PDEV_NODE); 1894f60ed91SVivek break; 1904f60ed91SVivek /* 1914f60ed91SVivek * Print non scan queues 1924f60ed91SVivek */ 1934f60ed91SVivek case SER_PDEV_QUEUE_COMP_NON_SCAN: 1944f60ed91SVivek pdev_q = &ser_pdev->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; 195c4eabce9SVivek ser_err_no_fl("Serialization NON SCAN Queues(LIVE)"); 1964f60ed91SVivek switch (sub_val) { 1974f60ed91SVivek /* 1984f60ed91SVivek * Print non scan pdev queues 1994f60ed91SVivek */ 2004f60ed91SVivek case SER_PDEV_QUEUE_TYPE: 2014f60ed91SVivek wlan_ser_print_pdev_queue(pdev_q, WLAN_SER_PDEV_NODE); 2024f60ed91SVivek break; 2034f60ed91SVivek /* 2044f60ed91SVivek * Print non scan pdev queues 2054f60ed91SVivek */ 2064f60ed91SVivek case SER_VDEV_QUEUE_TYPE: 2074f60ed91SVivek vdev_q = 2084f60ed91SVivek &ser_vdev->vdev_q[SER_VDEV_QUEUE_COMP_NON_SCAN]; 2094f60ed91SVivek for_vdev_queue = true; 2104f60ed91SVivek vdev_id = wlan_vdev_get_id(vdev); 2114f60ed91SVivek wlan_ser_print_vdev_queue(vdev_q, WLAN_SER_VDEV_NODE); 2124f60ed91SVivek break; 2134f60ed91SVivek default: 2144f60ed91SVivek ser_err("Invalid parameter for queue type(pdev/vdev)"); 2154f60ed91SVivek } 2164f60ed91SVivek break; 2174f60ed91SVivek default: 218*ed240b1dSJeff Johnson ser_err("Invalid parameter for queue type(scan/non_scan"); 2194f60ed91SVivek goto error; 2204f60ed91SVivek } 2214f60ed91SVivek 2224f60ed91SVivek wlan_ser_print_all_history(pdev_q, for_vdev_queue, vdev_id); 2234f60ed91SVivek error: 2244f60ed91SVivek return QDF_STATUS_SUCCESS; 2254f60ed91SVivek } 2264f60ed91SVivek 2270a46a191SSantosh Anbu qdf_export_symbol(wlan_ser_print_history); 2280a46a191SSantosh Anbu 2294f60ed91SVivek void wlan_ser_update_cmd_history( 2304f60ed91SVivek struct wlan_serialization_pdev_queue *pdev_queue, 2314f60ed91SVivek struct wlan_serialization_command *cmd, 2324f60ed91SVivek enum ser_queue_reason ser_reason, 2334f60ed91SVivek bool add_remove, 2344f60ed91SVivek bool active_queue) 2354f60ed91SVivek { 2364f60ed91SVivek struct ser_data *ser_data_info; 2374f60ed91SVivek struct ser_history *ser_history_info; 2384f60ed91SVivek 2394f60ed91SVivek ser_history_info = &pdev_queue->history; 2404f60ed91SVivek ser_history_info->index %= SER_MAX_HISTORY_CMDS; 2414f60ed91SVivek 2424f60ed91SVivek ser_data_info = &ser_history_info->data[ser_history_info->index]; 2434f60ed91SVivek 2444f60ed91SVivek ser_data_info->cmd_type = cmd->cmd_type; 2454f60ed91SVivek ser_data_info->cmd_id = cmd->cmd_id; 2464f60ed91SVivek ser_data_info->is_blocking = cmd->is_blocking; 2474f60ed91SVivek ser_data_info->is_high_priority = cmd->is_high_priority; 2484f60ed91SVivek ser_data_info->add_remove = add_remove; 2494f60ed91SVivek ser_data_info->active_pending = active_queue; 2504f60ed91SVivek ser_data_info->ser_reason = ser_reason; 2514f60ed91SVivek ser_data_info->vdev_id = wlan_vdev_get_id(cmd->vdev); 252445a3a58SVivek ser_data_info->data_updated = true; 25331864b63SHimanshu Batra ser_data_info->time = qdf_get_log_timestamp(); 2544f60ed91SVivek 2554f60ed91SVivek ser_history_info->index++; 2564f60ed91SVivek } 2574f60ed91SVivek #endif 258