xref: /freebsd/sys/dev/iwx/if_iwx_debug.c (revision f8ed8382daf4b9a97056b1dba4fe4e5cb4f7485c)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2015 Adrian Chadd <adrian@FreeBSD.org>
5  * Copyright (c) 2025 The FreeBSD Foundation
6  *
7  * Portions of this software were developed by Tom Jones <thj@FreeBSD.org>
8  * under sponsorship from the FreeBSD Foundation.
9  */
10 
11 #include <sys/param.h>
12 #include <sys/systm.h>
13 #include <net/ethernet.h>
14 
15 #include <net80211/ieee80211.h>
16 
17 #define le32_to_cpup(_a_) (le32toh(*(const uint32_t *)(_a_)))
18 
19 #include <dev/iwx/if_iwxreg.h>
20 #include <dev/iwx/if_iwx_debug.h>
21 
22 static uint16_t bbl_idx = 0;
23 static uint32_t bbl_seq = 0;
24 static uint8_t bbl_compress = 1;
25 
26 static const char *
27 iwx_bbl_to_str(int type)
28 {
29 	switch(type) {
30 	case IWX_BBL_PKT_TX:
31 		return ("IWX_BBL_PKT_TX");
32 	case IWX_BBL_PKT_RX:
33 		return ("IWX_BBL_PKT_RX");
34 	case IWX_BBL_PKT_DUP:
35 		return ("IWX_BBL_PKT_DUP");
36 	case IWX_BBL_CMD_TX:
37 		return ("IWX_BBL_CMD_TX");
38 	case IWX_BBL_CMD_RX:
39 		return ("IWX_BBL_CMD_RX");
40 	case IWX_BBL_ANY:
41 		return ("IWX_BBL_ANY");
42 	default:
43 		return ("ERROR");
44 	}
45 }
46 
47 static const char *
48 get_label(struct opcode_label *table, uint8_t opcode)
49 {
50 	struct opcode_label *op = table;
51 	while(op->label != NULL) {
52 		if (op->opcode == opcode)
53 			return op->label;
54 		op++;
55 	}
56 	return "NOT FOUND IN TABLE";
57 }
58 
59 static struct opcode_label *
60 get_table(uint8_t group)
61 {
62 	switch (group)
63 	{
64 	case IWX_LEGACY_GROUP:
65 	case IWX_LONG_GROUP:
66 		return legacy_opcodes;
67 		break;
68 	case IWX_SYSTEM_GROUP:
69 		return system_opcodes;
70 		break;
71 	case IWX_MAC_CONF_GROUP:
72 		return macconf_opcodes;
73 		break;
74 	case IWX_DATA_PATH_GROUP:
75 		return data_opcodes;
76 		break;
77 	case IWX_REGULATORY_AND_NVM_GROUP:
78 		return reg_opcodes;
79 		break;
80 	case IWX_PHY_OPS_GROUP:
81 		return phyops_opcodes;
82 		break;
83 	case IWX_PROT_OFFLOAD_GROUP:
84 		break;
85 	}
86 	return NULL;
87 }
88 
89 void
90 print_opcode(const char *func, int line, int type, uint32_t code)
91 {
92 	int print = print_mask & type;
93 	uint8_t opcode = iwx_cmd_opcode(code);
94 	uint8_t group = iwx_cmd_groupid(code);
95 
96 	struct opcode_label *table = get_table(group);
97 	if (table == NULL) {
98 		printf("Couldn't find opcode table for 0x%08x", code);
99 		return;
100 	}
101 
102 	for (int i = 0; i < nitems(print_codes); i++)
103 		if (print_codes[i][0] == group && print_codes[i][1] == opcode)
104 			print = 1;
105 
106 	if (print) {
107 		printf("%s:%d %s\t%s\t%s\t(0x%08x)\n", func, line,
108 		    iwx_bbl_to_str(type), get_label(command_group, group),
109 		    get_label(table, opcode), code);
110 	}
111 }
112 
113 void
114 iwx_dump_cmd(uint32_t id, void *data, uint16_t len, const char *str, int type)
115 {
116 	int dump = dump_mask & type;
117 	uint8_t opcode = iwx_cmd_opcode(id);
118 	uint8_t group = iwx_cmd_groupid(id);
119 
120 	for (int i = 0; i < nitems(dump_codes); i++)
121 		if (dump_codes[i][0] == group && dump_codes[i][1] == opcode)
122 			dump = 1;
123 
124 	if (dump)
125 		hexdump(data, len, str, 0);
126 }
127 
128 void
129 iwx_bbl_add_entry(uint32_t code, int type, int ticks)
130 {
131 	/*
132 	 * Compress together repeated notifications, but increment the sequence
133 	 * number so we can track things processing.
134 	 */
135 	if (bbl_compress && (iwx_bb_log[bbl_idx].code == code &&
136 	    iwx_bb_log[bbl_idx].type == type)) {
137 		iwx_bb_log[bbl_idx].count++;
138 		iwx_bb_log[bbl_idx].seq = bbl_seq++;
139 		iwx_bb_log[bbl_idx].ticks = ticks;
140 		return;
141 	}
142 
143 	if (bbl_idx++ > IWX_BBL_ENTRIES) {
144 #if 0
145 		printf("iwx bbl roll over: type %d (%lu)\n", type, code);
146 #endif
147 		bbl_idx = 0;
148 	}
149 	iwx_bb_log[bbl_idx].code = code;
150 	iwx_bb_log[bbl_idx].type = type;
151 	iwx_bb_log[bbl_idx].seq = bbl_seq++;
152 	iwx_bb_log[bbl_idx].ticks = ticks;
153 	iwx_bb_log[bbl_idx].count = 1;
154 }
155 
156 static void
157 iwx_bbl_print_entry(struct iwx_bbl_entry *e)
158 {
159 	uint8_t opcode = iwx_cmd_opcode(e->code);
160 	uint8_t group = iwx_cmd_groupid(e->code);
161 
162 	switch(e->type) {
163 	case IWX_BBL_PKT_TX:
164 		printf("pkt     ");
165 		printf("seq %08d\t pkt len %u",
166 			e->seq, e->code);
167 		break;
168 		printf("pkt dup ");
169 		printf("seq %08d\t dup count %u",
170 			e->seq, e->code);
171 		break;
172 	case IWX_BBL_CMD_TX:
173 		printf("tx ->   ");
174 		printf("seq %08d\tcode 0x%08x (%s:%s)",
175 			e->seq, e->code, get_label(command_group, group),
176 			get_label(get_table(group), opcode));
177 		break;
178 	case IWX_BBL_CMD_RX:
179 		printf("rx      ");
180 		printf("seq %08d\tcode 0x%08x (%s:%s)",
181 			e->seq, e->code, get_label(command_group, group),
182 			get_label(get_table(group), opcode));
183 		break;
184 	}
185 	if (e->count > 1)
186 		printf(" (count %d)", e->count);
187 	printf("\n");
188 }
189 
190 void
191 iwx_bbl_print_log(void)
192 {
193 	int start = -1;
194 
195 	start = bbl_idx+1;
196 	if (start > IWX_BBL_ENTRIES-1)
197 		start = 0;
198 
199 	for (int i = start; i < IWX_BBL_ENTRIES; i++) {
200 		struct iwx_bbl_entry *e = &iwx_bb_log[i];
201 		printf("bbl entry %05d %05d: ", i, e->ticks);
202 		iwx_bbl_print_entry(e);
203 	}
204 	for (int i = 0; i < start; i++) {
205 		struct iwx_bbl_entry *e = &iwx_bb_log[i];
206 		printf("bbl entry %05d %05d: ", i, e->ticks);
207 		iwx_bbl_print_entry(e);
208 	}
209 	printf("iwx bblog index %d seq %d\n", bbl_idx, bbl_seq);
210 }
211 
212 void
213 print_ratenflags(const char *func, int line, uint32_t flags, int ver)
214 {
215 	printf("%s:%d\n\t flags 0x%08x ", func, line, flags);
216 
217 	if (ver >= 2) {
218 		printf(" rate_n_flags version 2\n");
219 
220 		uint32_t type = (flags & IWX_RATE_MCS_MOD_TYPE_MSK) >> IWX_RATE_MCS_MOD_TYPE_POS;
221 
222 		switch(type)
223 		{
224 		case 0:
225 			printf("\t(0) Legacy CCK: ");
226 			switch (flags & IWX_RATE_LEGACY_RATE_MSK)
227 			{
228 			case 0:
229 				printf("(0) 0xa - 1 Mbps\n");
230 				break;
231 			case 1:
232 				printf("(1) 0x14 - 2 Mbps\n");
233 				break;
234 			case 2:
235 				printf("(2) 0x37 - 5.5 Mbps\n");
236 				break;
237 			case 3:
238 				printf("(3) 0x6e - 11 nbps\n");
239 				break;
240 			}
241 			break;
242 		case 1:
243 			printf("\t(1) Legacy OFDM \n");
244 			switch (flags & IWX_RATE_LEGACY_RATE_MSK)
245 			{
246 			case 0:
247 				printf("(0) 6 Mbps\n");
248 				break;
249 			case 1:
250 				printf("(1) 9 Mbps\n");
251 				break;
252 			case 2:
253 				printf("(2) 12 Mbps\n");
254 				break;
255 			case 3:
256 				printf("(3) 18 Mbps\n");
257 				break;
258 			case 4:
259 				printf("(4) 24 Mbps\n");
260 				break;
261 			case 5:
262 				printf("(5) 36 Mbps\n");
263 				break;
264 			case 6:
265 				printf("(6) 48 Mbps\n");
266 				break;
267 			case 7:
268 				printf("(7) 54 Mbps\n");
269 				break;
270 			}
271 			break;
272 		case 2:
273 			printf("\t(2) High-throughput (HT)\n");
274 			break;
275 		case 3:
276 			printf("\t(3) Very High-throughput (VHT) \n");
277 			break;
278 		case 4:
279 			printf("\t(4) High-efficiency (HE)\n");
280 			break;
281 		case 5:
282 			printf("\t(5) Extremely High-throughput (EHT)\n");
283 			break;
284 		default:
285 			printf("invalid\n");
286 		}
287 
288 		/* Not a legacy rate. */
289 		if (type > 1) {
290 			printf("\tMCS %d ", IWX_RATE_HT_MCS_INDEX(flags));
291 			switch((flags & IWX_RATE_MCS_CHAN_WIDTH_MSK) >> IWX_RATE_MCS_CHAN_WIDTH_POS)
292 			{
293 			case 0:
294 				printf("20MHz ");
295 				break;
296 			case 1:
297 				printf("40MHz ");
298 				break;
299 			case 2:
300 				printf("80MHz ");
301 				break;
302 			case 3:
303 				printf("160MHz ");
304 				break;
305 			case 4:
306 				printf("320MHz ");
307 				break;
308 
309 			}
310 			printf("antennas: (%s|%s) ",
311 				flags & (1 << 14) ? "A" : " ",
312 				flags & (1 << 15) ? "B" : " ");
313 			if (flags & (1 << 16))
314 				printf("ldpc ");
315 			printf("\n");
316 		}
317 	} else {
318 		printf("%s:%d rate_n_flags versions other than < 2 not implemented",
319 		    __func__, __LINE__);
320 	}
321 }
322