xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_debug.c (revision a86b23ee68a2491aede2e03991f3fb37046f4e41)
1 /*
2  * Copyright (c) 2018-2020 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_no_fl(WLAN_SER_LINE);
56 	ser_err_no_fl("%s %s Queue", (is_pdev_queue) ? "PDEV" : "VDEV",
57 		      (is_active_queue ? "Active" : "Pending"));
58 
59 	ser_err_no_fl(WLAN_SER_LINE);
60 	ser_err_no_fl("|CMD_TYPE|CMD_ID|VDEV_ID|BLOCKING|PRIORITY|");
61 	ser_err_no_fl(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_no_fl("|%8u|%6u|%6u|%8u|%8u|",
81 		      cmd_list->cmd.cmd_type,
82 		cmd_list->cmd.cmd_id,
83 		wlan_vdev_get_id(cmd_list->cmd.vdev),
84 		cmd_list->cmd.is_blocking,
85 		cmd_list->cmd.is_high_priority);
86 	}
87 }
88 
89 static void wlan_ser_print_pdev_queue(
90 		struct wlan_serialization_pdev_queue *ser_pdev_q_obj,
91 		enum wlan_serialization_node node_type)
92 {
93 	/*Dump the active queue*/
94 	wlan_ser_print_queues(&ser_pdev_q_obj->active_list,
95 			      node_type, true);
96 
97 	/*Dump the pending queue*/
98 	wlan_ser_print_queues(&ser_pdev_q_obj->pending_list,
99 			      node_type, false);
100 }
101 
102 static void wlan_ser_print_vdev_queue(
103 		struct wlan_serialization_vdev_queue *ser_vdev_q_obj,
104 		enum wlan_serialization_node node_type)
105 {
106 	/*Dump the active queue*/
107 	wlan_ser_print_queues(&ser_vdev_q_obj->active_list,
108 			      node_type, true);
109 
110 	/*Dump the pending queue*/
111 	wlan_ser_print_queues(&ser_vdev_q_obj->pending_list,
112 			      node_type, false);
113 }
114 
115 static void wlan_ser_print_all_history(
116 		struct wlan_serialization_pdev_queue *pdev_queue,
117 		bool for_vdev_queue,
118 		uint32_t vdev_id)
119 {
120 	uint8_t idx;
121 	uint8_t data_idx;
122 	struct ser_history *history_info;
123 	struct ser_data *data;
124 
125 	history_info = &pdev_queue->history;
126 
127 	ser_err_no_fl(WLAN_SER_LINE WLAN_SER_LINE);
128 	ser_err_no_fl("Queue Commands History");
129 	ser_err_no_fl(WLAN_SER_LINE WLAN_SER_LINE);
130 	ser_err_no_fl(WLAN_SER_HISTORY_HEADER);
131 	ser_err_no_fl(WLAN_SER_LINE WLAN_SER_LINE);
132 
133 	for (idx = 0; idx < SER_MAX_HISTORY_CMDS; idx++) {
134 		data_idx = (history_info->index + idx) % SER_MAX_HISTORY_CMDS;
135 
136 		data = &history_info->data[data_idx];
137 
138 		if (data->ser_reason >= SER_QUEUE_ACTION_MAX) {
139 			ser_debug("Invalid Serialization Reason");
140 			continue;
141 		}
142 
143 		if (!data->data_updated)
144 			continue;
145 
146 		if (for_vdev_queue) {
147 			if (vdev_id != data->vdev_id)
148 				continue;
149 		}
150 		ser_err_no_fl(
151 			"%8d|%6d|%7d|%8d|%8d|%6s|%7s|%17s|",
152 			data->cmd_type,
153 			data->cmd_id,
154 			data->vdev_id,
155 			data->is_blocking,
156 			data->is_high_priority,
157 			data->add_remove ? "ADD" : "REMOVE",
158 			data->active_pending ? "ACTIVE" : "PENDING",
159 			ser_reason_string[data->ser_reason]);
160 	}
161 }
162 
163 QDF_STATUS wlan_ser_print_history(
164 		struct wlan_objmgr_vdev *vdev, uint8_t val,
165 		uint32_t sub_val)
166 {
167 	struct wlan_ser_pdev_obj *ser_pdev;
168 	struct wlan_ser_vdev_obj *ser_vdev;
169 	struct wlan_serialization_pdev_queue *pdev_q;
170 	struct wlan_serialization_vdev_queue *vdev_q;
171 	bool for_vdev_queue = false;
172 	uint32_t vdev_id = WLAN_INVALID_VDEV_ID;
173 
174 	ser_pdev = wlan_serialization_get_pdev_obj(
175 			wlan_vdev_get_pdev(vdev));
176 
177 	ser_vdev = wlan_serialization_get_vdev_obj(vdev);
178 
179 	switch (val) {
180 	/*
181 	 * Print scan pdev queues
182 	 */
183 	case SER_PDEV_QUEUE_COMP_SCAN:
184 		ser_err_no_fl("Serialization SCAN Queues(LIVE)");
185 		pdev_q = &ser_pdev->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
186 		wlan_ser_print_pdev_queue(pdev_q, WLAN_SER_PDEV_NODE);
187 		break;
188 	/*
189 	 * Print non scan queues
190 	 */
191 	case SER_PDEV_QUEUE_COMP_NON_SCAN:
192 		pdev_q = &ser_pdev->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN];
193 		ser_err_no_fl("Serialization NON SCAN Queues(LIVE)");
194 		switch (sub_val) {
195 		/*
196 		 * Print non scan pdev queues
197 		 */
198 		case SER_PDEV_QUEUE_TYPE:
199 			wlan_ser_print_pdev_queue(pdev_q, WLAN_SER_PDEV_NODE);
200 			break;
201 		/*
202 		 * Print non scan pdev queues
203 		 */
204 		case SER_VDEV_QUEUE_TYPE:
205 			vdev_q =
206 			    &ser_vdev->vdev_q[SER_VDEV_QUEUE_COMP_NON_SCAN];
207 			for_vdev_queue = true;
208 			vdev_id = wlan_vdev_get_id(vdev);
209 			wlan_ser_print_vdev_queue(vdev_q, WLAN_SER_VDEV_NODE);
210 			break;
211 		default:
212 			ser_err("Invalid parameter for queue type(pdev/vdev)");
213 		}
214 		break;
215 	default:
216 		ser_err("Invalid pramater for queue type(scan/non_scan");
217 		goto error;
218 	}
219 
220 	wlan_ser_print_all_history(pdev_q, for_vdev_queue, vdev_id);
221 error:
222 	return QDF_STATUS_SUCCESS;
223 }
224 
225 qdf_export_symbol(wlan_ser_print_history);
226 
227 void wlan_ser_update_cmd_history(
228 		struct wlan_serialization_pdev_queue *pdev_queue,
229 		struct wlan_serialization_command *cmd,
230 		enum ser_queue_reason ser_reason,
231 		bool add_remove,
232 		bool active_queue)
233 {
234 	struct ser_data *ser_data_info;
235 	struct ser_history *ser_history_info;
236 
237 	ser_history_info = &pdev_queue->history;
238 	ser_history_info->index %= SER_MAX_HISTORY_CMDS;
239 
240 	ser_data_info = &ser_history_info->data[ser_history_info->index];
241 
242 	ser_data_info->cmd_type = cmd->cmd_type;
243 	ser_data_info->cmd_id = cmd->cmd_id;
244 	ser_data_info->is_blocking = cmd->is_blocking;
245 	ser_data_info->is_high_priority = cmd->is_high_priority;
246 	ser_data_info->add_remove = add_remove;
247 	ser_data_info->active_pending = active_queue;
248 	ser_data_info->ser_reason = ser_reason;
249 	ser_data_info->vdev_id = wlan_vdev_get_id(cmd->vdev);
250 	ser_data_info->data_updated = true;
251 
252 	ser_history_info->index++;
253 }
254 #endif
255