1 /* 2 * Copyright (c) 2018 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 * DOC: wlan_serialization_debug.c 20 * This file defines the debug functions for serialization component. 21 */ 22 23 #include <wlan_objmgr_vdev_obj.h> 24 #include <wlan_objmgr_pdev_obj.h> 25 #include <wlan_utility.h> 26 #include "wlan_serialization_utils_i.h" 27 #include "wlan_serialization_main_i.h" 28 #include "wlan_serialization_queue_i.h" 29 #include "wlan_serialization_debug_i.h" 30 31 #ifdef WLAN_SER_DEBUG 32 const char *ser_reason_string[SER_QUEUE_ACTION_MAX] = { 33 "REQUEST", 34 "REMOVE", 35 "CANCEL", 36 "TIMEOUT", 37 "ACTIVATION_FAILED", 38 "PENDING_TO_ACTIVE", 39 }; 40 41 static void wlan_ser_print_queues( 42 qdf_list_t *queue, 43 enum wlan_serialization_node node_type, 44 bool is_active_queue) 45 { 46 struct wlan_serialization_command_list *cmd_list = NULL; 47 uint32_t queuelen; 48 QDF_STATUS status = QDF_STATUS_E_FAILURE; 49 qdf_list_node_t *nnode = NULL; 50 bool is_pdev_queue = false; 51 52 if (node_type == WLAN_SER_PDEV_NODE) 53 is_pdev_queue = true; 54 55 ser_err(WLAN_SER_LINE); 56 ser_err("%s %s Queue", (is_pdev_queue) ? "PDEV" : "VDEV", 57 (is_active_queue ? "Active" : "Pending")); 58 59 ser_err(WLAN_SER_LINE); 60 ser_err("|CMD_TYPE|CMD_ID|BLOCKING|PRIORITY|"); 61 ser_err(WLAN_SER_LINE); 62 63 queuelen = wlan_serialization_list_size(queue); 64 while (queuelen--) { 65 status = wlan_serialization_get_cmd_from_queue(queue, &nnode); 66 if (status != QDF_STATUS_SUCCESS) 67 break; 68 69 if (node_type == WLAN_SER_PDEV_NODE) 70 cmd_list = qdf_container_of( 71 nnode, 72 struct wlan_serialization_command_list, 73 pdev_node); 74 else 75 cmd_list = qdf_container_of( 76 nnode, 77 struct wlan_serialization_command_list, 78 vdev_node); 79 80 ser_err("|%8u|%6u|%8u|%8u|", 81 cmd_list->cmd.cmd_type, 82 cmd_list->cmd.cmd_id, 83 cmd_list->cmd.is_blocking, 84 cmd_list->cmd.is_high_priority); 85 } 86 } 87 88 static void wlan_ser_print_pdev_queue( 89 struct wlan_serialization_pdev_queue *ser_pdev_q_obj, 90 enum wlan_serialization_node node_type) 91 { 92 /*Dump the active queue*/ 93 wlan_ser_print_queues(&ser_pdev_q_obj->active_list, 94 node_type, true); 95 96 /*Dump the pending queue*/ 97 wlan_ser_print_queues(&ser_pdev_q_obj->pending_list, 98 node_type, false); 99 } 100 101 static void wlan_ser_print_vdev_queue( 102 struct wlan_serialization_vdev_queue *ser_vdev_q_obj, 103 enum wlan_serialization_node node_type) 104 { 105 /*Dump the active queue*/ 106 wlan_ser_print_queues(&ser_vdev_q_obj->active_list, 107 node_type, true); 108 109 /*Dump the pending queue*/ 110 wlan_ser_print_queues(&ser_vdev_q_obj->pending_list, 111 node_type, false); 112 } 113 114 static void wlan_ser_print_all_history( 115 struct wlan_serialization_pdev_queue *pdev_queue, 116 bool for_vdev_queue, 117 uint32_t vdev_id) 118 { 119 uint8_t idx; 120 struct ser_history *history_info; 121 struct ser_data *data; 122 123 history_info = &pdev_queue->history; 124 125 if (!history_info->index) 126 return; 127 128 ser_err(WLAN_SER_LINE WLAN_SER_LINE); 129 ser_err("Queue Commands History"); 130 ser_err(WLAN_SER_LINE WLAN_SER_LINE); 131 ser_err(WLAN_SER_HISTORY_HEADER); 132 ser_err(WLAN_SER_LINE WLAN_SER_LINE); 133 134 for (idx = 0; idx < history_info->index; idx++) { 135 data = &history_info->data[idx]; 136 137 if (data->ser_reason >= SER_QUEUE_ACTION_MAX) { 138 ser_err("Invalid Serialization Reason"); 139 continue; 140 } 141 142 if (for_vdev_queue) { 143 if (vdev_id != data->vdev_id) 144 continue; 145 } 146 ser_err("%8d|%6d|%7d|%8d|%8d|%6s|%7s|%17s|", 147 data->cmd_type, 148 data->cmd_id, 149 data->vdev_id, 150 data->is_blocking, 151 data->is_high_priority, 152 data->add_remove ? "ADD" : "REMOVE", 153 data->active_pending ? "ACTIVE" : "PENDING", 154 ser_reason_string[data->ser_reason]); 155 } 156 } 157 158 QDF_STATUS wlan_ser_print_history( 159 struct wlan_objmgr_vdev *vdev, uint8_t val, 160 uint32_t sub_val) 161 { 162 struct wlan_ser_pdev_obj *ser_pdev; 163 struct wlan_ser_vdev_obj *ser_vdev; 164 struct wlan_serialization_pdev_queue *pdev_q; 165 struct wlan_serialization_vdev_queue *vdev_q; 166 bool for_vdev_queue = false; 167 uint32_t vdev_id; 168 169 ser_pdev = wlan_serialization_get_pdev_obj( 170 wlan_vdev_get_pdev(vdev)); 171 172 ser_vdev = wlan_serialization_get_vdev_obj(vdev); 173 174 switch (val) { 175 /* 176 * Print scan pdev queues 177 */ 178 case SER_PDEV_QUEUE_COMP_SCAN: 179 ser_err("Serialization SCAN Queues(LIVE)"); 180 pdev_q = &ser_pdev->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 181 wlan_ser_print_pdev_queue(pdev_q, WLAN_SER_PDEV_NODE); 182 break; 183 /* 184 * Print non scan queues 185 */ 186 case SER_PDEV_QUEUE_COMP_NON_SCAN: 187 pdev_q = &ser_pdev->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; 188 ser_err("Serialization NON SCAN Queues(LIVE)"); 189 switch (sub_val) { 190 /* 191 * Print non scan pdev queues 192 */ 193 case SER_PDEV_QUEUE_TYPE: 194 wlan_ser_print_pdev_queue(pdev_q, WLAN_SER_PDEV_NODE); 195 break; 196 /* 197 * Print non scan pdev queues 198 */ 199 case SER_VDEV_QUEUE_TYPE: 200 vdev_q = 201 &ser_vdev->vdev_q[SER_VDEV_QUEUE_COMP_NON_SCAN]; 202 for_vdev_queue = true; 203 vdev_id = wlan_vdev_get_id(vdev); 204 wlan_ser_print_vdev_queue(vdev_q, WLAN_SER_VDEV_NODE); 205 break; 206 default: 207 ser_err("Invalid parameter for queue type(pdev/vdev)"); 208 } 209 break; 210 default: 211 ser_err("Invalid pramater for queue type(scan/non_scan"); 212 goto error; 213 } 214 215 wlan_ser_print_all_history(pdev_q, for_vdev_queue, vdev_id); 216 error: 217 return QDF_STATUS_SUCCESS; 218 } 219 220 void wlan_ser_update_cmd_history( 221 struct wlan_serialization_pdev_queue *pdev_queue, 222 struct wlan_serialization_command *cmd, 223 enum ser_queue_reason ser_reason, 224 bool add_remove, 225 bool active_queue) 226 { 227 struct ser_data *ser_data_info; 228 struct ser_history *ser_history_info; 229 230 ser_history_info = &pdev_queue->history; 231 ser_history_info->index %= SER_MAX_HISTORY_CMDS; 232 233 ser_data_info = &ser_history_info->data[ser_history_info->index]; 234 235 ser_data_info->cmd_type = cmd->cmd_type; 236 ser_data_info->cmd_id = cmd->cmd_id; 237 ser_data_info->is_blocking = cmd->is_blocking; 238 ser_data_info->is_high_priority = cmd->is_high_priority; 239 ser_data_info->add_remove = add_remove; 240 ser_data_info->active_pending = active_queue; 241 ser_data_info->ser_reason = ser_reason; 242 ser_data_info->vdev_id = wlan_vdev_get_id(cmd->vdev); 243 244 ser_history_info->index++; 245 } 246 #endif 247