xref: /titanic_52/usr/src/cmd/mdb/intel/modules/i40e/i40e.c (revision 8d5069bc751f57c7f5fe5ef63afce1daa8ce219f)
1eab22797SRobert Mustacchi /*
2eab22797SRobert Mustacchi  * This file and its contents are supplied under the terms of the
3eab22797SRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4eab22797SRobert Mustacchi  * You may only use this file in accordance with the terms of version
5eab22797SRobert Mustacchi  * 1.0 of the CDDL.
6eab22797SRobert Mustacchi  *
7eab22797SRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8eab22797SRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9eab22797SRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10eab22797SRobert Mustacchi  */
11eab22797SRobert Mustacchi 
12eab22797SRobert Mustacchi /*
13*8d5069bcSRyan Zezeski  * Copyright 2018 Joyent, Inc.
14eab22797SRobert Mustacchi  */
15eab22797SRobert Mustacchi 
16*8d5069bcSRyan Zezeski #include <mdb/mdb_ctf.h>
17eab22797SRobert Mustacchi #include <sys/mdb_modapi.h>
18eab22797SRobert Mustacchi #include "i40e_sw.h"
19eab22797SRobert Mustacchi 
20eab22797SRobert Mustacchi #define	RSRC_MAX	0x13
21eab22797SRobert Mustacchi static const char *i40e_switch_rsrc_names[] = {
22eab22797SRobert Mustacchi 	"VEBs",
23eab22797SRobert Mustacchi 	"VSIs",
24eab22797SRobert Mustacchi 	"Perfect Match MAC Addresses",
25eab22797SRobert Mustacchi 	"S-Tags",
26eab22797SRobert Mustacchi 	"Reserved",
27eab22797SRobert Mustacchi 	"Multicast Hash Entries",
28eab22797SRobert Mustacchi 	"Reserved",
29eab22797SRobert Mustacchi 	"VLANs",
30eab22797SRobert Mustacchi 	"VSI Lists",
31eab22797SRobert Mustacchi 	"Reserved",
32eab22797SRobert Mustacchi 	"VLAN Stat pools",
33eab22797SRobert Mustacchi 	"Mirror rules",
34eab22797SRobert Mustacchi 	"Queue sets",
35eab22797SRobert Mustacchi 	"Inner VLAN Forwarding",
36eab22797SRobert Mustacchi 	"Reserved",
37eab22797SRobert Mustacchi 	"Inner MACs",
38eab22797SRobert Mustacchi 	"IPs",
39eab22797SRobert Mustacchi 	"GRE/VN1 Keys",
40eab22797SRobert Mustacchi 	"VN2 Keys",
41eab22797SRobert Mustacchi 	"Tunnelling Ports"
42eab22797SRobert Mustacchi };
43eab22797SRobert Mustacchi 
44eab22797SRobert Mustacchi /*
45eab22797SRobert Mustacchi  * i40e mdb dcmds
46eab22797SRobert Mustacchi  */
47eab22797SRobert Mustacchi /* ARGSUSED */
48eab22797SRobert Mustacchi static int
49eab22797SRobert Mustacchi i40e_switch_rsrcs_dcmd(uintptr_t addr, uint_t flags, int argc,
50eab22797SRobert Mustacchi     const mdb_arg_t *argv)
51eab22797SRobert Mustacchi {
52eab22797SRobert Mustacchi 	i40e_t i40e;
53eab22797SRobert Mustacchi 	int i;
54eab22797SRobert Mustacchi 
55eab22797SRobert Mustacchi 	if (!(flags & DCMD_ADDRSPEC)) {
56eab22797SRobert Mustacchi 		mdb_warn("::i40e_switch_rsrcs does not operate globally\n");
57eab22797SRobert Mustacchi 		return (DCMD_USAGE);
58eab22797SRobert Mustacchi 	}
59eab22797SRobert Mustacchi 
60eab22797SRobert Mustacchi 	if (mdb_vread(&i40e, sizeof (i40e_t), addr) != sizeof (i40e_t)) {
61eab22797SRobert Mustacchi 		mdb_warn("failed to read i40e_t at %p", addr);
62eab22797SRobert Mustacchi 		return (DCMD_ERR);
63eab22797SRobert Mustacchi 	}
64eab22797SRobert Mustacchi 
65eab22797SRobert Mustacchi 	mdb_printf("%-28s %-12s %-8s %-8s %s\n", "TYPE", "GUARANTEE",
66eab22797SRobert Mustacchi 	    "TOTAL", "USED", "UNALLOCED");
67eab22797SRobert Mustacchi 
68eab22797SRobert Mustacchi 	for (i = 0; i < i40e.i40e_switch_rsrc_actual; i++) {
69eab22797SRobert Mustacchi 		i40e_switch_rsrc_t rsrc;
70eab22797SRobert Mustacchi 		uintptr_t raddr = (uintptr_t)i40e.i40e_switch_rsrcs +
71eab22797SRobert Mustacchi 		    i * sizeof (i40e_switch_rsrc_t);
72eab22797SRobert Mustacchi 		const char *name;
73eab22797SRobert Mustacchi 
74eab22797SRobert Mustacchi 		if (mdb_vread(&rsrc, sizeof (i40e_switch_rsrc_t), raddr) !=
75eab22797SRobert Mustacchi 		    sizeof (i40e_switch_rsrc_t)) {
76eab22797SRobert Mustacchi 			mdb_warn("failed to read i40e_switch_rsrc_t %d at %p",
77eab22797SRobert Mustacchi 			    i, raddr);
78eab22797SRobert Mustacchi 			return (DCMD_ERR);
79eab22797SRobert Mustacchi 		}
80eab22797SRobert Mustacchi 
81eab22797SRobert Mustacchi 		if (rsrc.resource_type <= RSRC_MAX) {
82eab22797SRobert Mustacchi 			name = i40e_switch_rsrc_names[rsrc.resource_type];
83eab22797SRobert Mustacchi 		} else {
84eab22797SRobert Mustacchi 			char *buf;
85eab22797SRobert Mustacchi 			size_t s = mdb_snprintf(NULL, 0, "Unknown type (%d)",
86eab22797SRobert Mustacchi 			    rsrc.resource_type);
87eab22797SRobert Mustacchi 			buf = mdb_alloc(s + 1, UM_GC | UM_SLEEP);
88eab22797SRobert Mustacchi 			(void) mdb_snprintf(buf, s + 1, "Unknown type (%d)",
89eab22797SRobert Mustacchi 			    rsrc.resource_type);
90eab22797SRobert Mustacchi 			name = buf;
91eab22797SRobert Mustacchi 		}
92eab22797SRobert Mustacchi 
93eab22797SRobert Mustacchi 		mdb_printf("%-28s %-12d %-8d %-8d %d\n", name,
94eab22797SRobert Mustacchi 		    LE_16(rsrc.guaranteed), LE_16(rsrc.total), LE_16(rsrc.used),
95eab22797SRobert Mustacchi 		    LE_16(rsrc.total_unalloced));
96eab22797SRobert Mustacchi 	}
97eab22797SRobert Mustacchi 
98eab22797SRobert Mustacchi 	return (DCMD_OK);
99eab22797SRobert Mustacchi }
100eab22797SRobert Mustacchi 
101*8d5069bcSRyan Zezeski typedef struct mdb_i40e_trqpair {
102*8d5069bcSRyan Zezeski 	uint32_t		itrq_tx_ring_size;
103*8d5069bcSRyan Zezeski 	uint32_t		itrq_desc_free;
104*8d5069bcSRyan Zezeski 	uint32_t 		*itrq_desc_wbhead;
105*8d5069bcSRyan Zezeski 	uint32_t		itrq_desc_head;
106*8d5069bcSRyan Zezeski 	uint32_t		itrq_desc_tail;
107*8d5069bcSRyan Zezeski 	i40e_tx_desc_t		*itrq_desc_ring;
108*8d5069bcSRyan Zezeski 	i40e_tx_control_block_t	**itrq_tcb_work_list;
109*8d5069bcSRyan Zezeski } mdb_i40e_trqpair_t;
110*8d5069bcSRyan Zezeski 
111*8d5069bcSRyan Zezeski static void
112*8d5069bcSRyan Zezeski i40e_tx_ring_help()
113*8d5069bcSRyan Zezeski {
114*8d5069bcSRyan Zezeski 	mdb_printf(
115*8d5069bcSRyan Zezeski 	    "\t -a dump all ring entries\n"
116*8d5069bcSRyan Zezeski 	    "\t or\n"
117*8d5069bcSRyan Zezeski 	    "\t combine -b [start index] with -e [end index] to specify a \n"
118*8d5069bcSRyan Zezeski 	    "\t range of ring entries to print\n");
119*8d5069bcSRyan Zezeski }
120*8d5069bcSRyan Zezeski 
121*8d5069bcSRyan Zezeski static int
122*8d5069bcSRyan Zezeski i40e_tx_ring_dcmd(uintptr_t addr, uint_t flags, int argc,
123*8d5069bcSRyan Zezeski     const mdb_arg_t *argv)
124*8d5069bcSRyan Zezeski {
125*8d5069bcSRyan Zezeski 	mdb_i40e_trqpair_t trq;
126*8d5069bcSRyan Zezeski 	i40e_tx_desc_t *descring;
127*8d5069bcSRyan Zezeski 	i40e_tx_control_block_t **wklist;
128*8d5069bcSRyan Zezeski 	uint32_t wbhead;
129*8d5069bcSRyan Zezeski 	size_t ringsz, wklistsz;
130*8d5069bcSRyan Zezeski 	boolean_t opt_a = B_FALSE;
131*8d5069bcSRyan Zezeski 	char *opt_b = NULL, *opt_e = NULL;
132*8d5069bcSRyan Zezeski 	uint64_t begin = UINT64_MAX, end = UINT64_MAX;
133*8d5069bcSRyan Zezeski 
134*8d5069bcSRyan Zezeski 	if (!(flags & DCMD_ADDRSPEC)) {
135*8d5069bcSRyan Zezeski 		mdb_warn("::i40e_tx_ring does not operate globally\n");
136*8d5069bcSRyan Zezeski 		return (DCMD_USAGE);
137*8d5069bcSRyan Zezeski 	}
138*8d5069bcSRyan Zezeski 
139*8d5069bcSRyan Zezeski 	if (mdb_getopts(argc, argv,
140*8d5069bcSRyan Zezeski 	    'a', MDB_OPT_SETBITS, B_TRUE, &opt_a,
141*8d5069bcSRyan Zezeski 	    'b', MDB_OPT_STR, &opt_b,
142*8d5069bcSRyan Zezeski 	    'e', MDB_OPT_STR, &opt_e, NULL) != argc)
143*8d5069bcSRyan Zezeski 		return (DCMD_USAGE);
144*8d5069bcSRyan Zezeski 
145*8d5069bcSRyan Zezeski 	/*
146*8d5069bcSRyan Zezeski 	 * Verify that a legal combination of -a/-b/-e were used.
147*8d5069bcSRyan Zezeski 	 */
148*8d5069bcSRyan Zezeski 	if (opt_a && (opt_b != NULL || opt_e != NULL)) {
149*8d5069bcSRyan Zezeski 		mdb_warn("-a and -b/-e are mutually exclusive\n");
150*8d5069bcSRyan Zezeski 		return (DCMD_USAGE);
151*8d5069bcSRyan Zezeski 	}
152*8d5069bcSRyan Zezeski 	if (argc > 0 && ! opt_a && (opt_b == NULL || opt_e == NULL)) {
153*8d5069bcSRyan Zezeski 		mdb_warn("-b/-e must both be specified\n");
154*8d5069bcSRyan Zezeski 		return (DCMD_USAGE);
155*8d5069bcSRyan Zezeski 	}
156*8d5069bcSRyan Zezeski 
157*8d5069bcSRyan Zezeski 	if (mdb_ctf_vread(&trq, "i40e_trqpair_t", "mdb_i40e_trqpair_t", addr,
158*8d5069bcSRyan Zezeski 	    0) == -1) {
159*8d5069bcSRyan Zezeski 		mdb_warn("failed to read i40e_trqpair_t at %p", addr);
160*8d5069bcSRyan Zezeski 		return (DCMD_ERR);
161*8d5069bcSRyan Zezeski 	}
162*8d5069bcSRyan Zezeski 
163*8d5069bcSRyan Zezeski 	if (opt_b != NULL)
164*8d5069bcSRyan Zezeski 		begin = mdb_strtoull(opt_b);
165*8d5069bcSRyan Zezeski 	if (opt_e != NULL)
166*8d5069bcSRyan Zezeski 		end = mdb_strtoull(opt_e);
167*8d5069bcSRyan Zezeski 	if (opt_a) {
168*8d5069bcSRyan Zezeski 		begin = 0;
169*8d5069bcSRyan Zezeski 		end = trq.itrq_tx_ring_size - 1;
170*8d5069bcSRyan Zezeski 	}
171*8d5069bcSRyan Zezeski 
172*8d5069bcSRyan Zezeski 	/*
173*8d5069bcSRyan Zezeski 	 * Verify that the requested range of ring entries makes sense.
174*8d5069bcSRyan Zezeski 	 */
175*8d5069bcSRyan Zezeski 	if (argc > 0 && (end < begin || begin >= trq.itrq_tx_ring_size ||
176*8d5069bcSRyan Zezeski 	    end >= trq.itrq_tx_ring_size)) {
177*8d5069bcSRyan Zezeski 		mdb_warn("invalid range specified\n");
178*8d5069bcSRyan Zezeski 		return (DCMD_USAGE);
179*8d5069bcSRyan Zezeski 	}
180*8d5069bcSRyan Zezeski 
181*8d5069bcSRyan Zezeski 	if (mdb_vread(&wbhead, sizeof (uint32_t),
182*8d5069bcSRyan Zezeski 	    (uintptr_t)trq.itrq_desc_wbhead) != sizeof (uint32_t)) {
183*8d5069bcSRyan Zezeski 		mdb_warn("failed to read trq.itrq_desc_wbhead");
184*8d5069bcSRyan Zezeski 		return (DCMD_ERR);
185*8d5069bcSRyan Zezeski 	}
186*8d5069bcSRyan Zezeski 	mdb_printf("%-20s%d\n", "Ring Size:", trq.itrq_tx_ring_size);
187*8d5069bcSRyan Zezeski 	mdb_printf("%-20s%d\n", "Free Descriptors:", trq.itrq_desc_free);
188*8d5069bcSRyan Zezeski 	mdb_printf("%-20s%d\n", "Writeback Head:", wbhead);
189*8d5069bcSRyan Zezeski 	mdb_printf("%-20s%d\n", "Head:", trq.itrq_desc_head);
190*8d5069bcSRyan Zezeski 	mdb_printf("%-20s%d\n", "Tail:", trq.itrq_desc_tail);
191*8d5069bcSRyan Zezeski 
192*8d5069bcSRyan Zezeski 	/*
193*8d5069bcSRyan Zezeski 	 * No arguments were specified, so we're done.
194*8d5069bcSRyan Zezeski 	 */
195*8d5069bcSRyan Zezeski 	if (argc == 0)
196*8d5069bcSRyan Zezeski 		return (DCMD_OK);
197*8d5069bcSRyan Zezeski 
198*8d5069bcSRyan Zezeski 	/*
199*8d5069bcSRyan Zezeski 	 * Allocate memory and read in the entire TX descriptor ring and
200*8d5069bcSRyan Zezeski 	 * TCB work list.
201*8d5069bcSRyan Zezeski 	 */
202*8d5069bcSRyan Zezeski 	ringsz = sizeof (i40e_tx_desc_t) * trq.itrq_tx_ring_size;
203*8d5069bcSRyan Zezeski 	descring = mdb_alloc(ringsz, UM_SLEEP);
204*8d5069bcSRyan Zezeski 	if (mdb_vread(descring, ringsz, (uintptr_t)trq.itrq_desc_ring) !=
205*8d5069bcSRyan Zezeski 	    ringsz) {
206*8d5069bcSRyan Zezeski 		mdb_warn("Failed to read in TX decriptor ring\n");
207*8d5069bcSRyan Zezeski 		mdb_free(descring, ringsz);
208*8d5069bcSRyan Zezeski 		return (DCMD_ERR);
209*8d5069bcSRyan Zezeski 	}
210*8d5069bcSRyan Zezeski 	wklistsz = sizeof (i40e_tx_control_block_t *) * trq.itrq_tx_ring_size;
211*8d5069bcSRyan Zezeski 	wklist = mdb_alloc(wklistsz, UM_SLEEP);
212*8d5069bcSRyan Zezeski 	if (mdb_vread(wklist, wklistsz, (uintptr_t)trq.itrq_tcb_work_list) !=
213*8d5069bcSRyan Zezeski 	    wklistsz) {
214*8d5069bcSRyan Zezeski 		mdb_warn("Failed to read in TX TCB work list\n");
215*8d5069bcSRyan Zezeski 		mdb_free(descring, ringsz);
216*8d5069bcSRyan Zezeski 		mdb_free(wklist, wklistsz);
217*8d5069bcSRyan Zezeski 		return (DCMD_ERR);
218*8d5069bcSRyan Zezeski 	}
219*8d5069bcSRyan Zezeski 
220*8d5069bcSRyan Zezeski 	mdb_printf("\n%-10s %-10s %-16s %-16s %-10s\n", "Index", "Desc Type",
221*8d5069bcSRyan Zezeski 	    "Desc Ptr", "TCB Ptr", "Other");
222*8d5069bcSRyan Zezeski 	for (uint64_t i = begin; i <= end; i++) {
223*8d5069bcSRyan Zezeski 		const char *dtype;
224*8d5069bcSRyan Zezeski 		char dother[17];
225*8d5069bcSRyan Zezeski 		i40e_tx_desc_t *dptr;
226*8d5069bcSRyan Zezeski 		i40e_tx_control_block_t *tcbptr;
227*8d5069bcSRyan Zezeski 		uint64_t ctob;
228*8d5069bcSRyan Zezeski 
229*8d5069bcSRyan Zezeski 		dptr = &descring[i];
230*8d5069bcSRyan Zezeski 		tcbptr = wklist[i];
231*8d5069bcSRyan Zezeski 		ctob = LE_64(dptr->cmd_type_offset_bsz);
232*8d5069bcSRyan Zezeski 		if (ctob == 0) {
233*8d5069bcSRyan Zezeski 			dtype = "FREE";
234*8d5069bcSRyan Zezeski 		} else {
235*8d5069bcSRyan Zezeski 			switch (ctob & I40E_TXD_QW1_DTYPE_MASK) {
236*8d5069bcSRyan Zezeski 			case (I40E_TX_DESC_DTYPE_CONTEXT):
237*8d5069bcSRyan Zezeski 				dtype = "CONTEXT";
238*8d5069bcSRyan Zezeski 				break;
239*8d5069bcSRyan Zezeski 			case (I40E_TX_DESC_DTYPE_DATA):
240*8d5069bcSRyan Zezeski 				dtype = "DATA";
241*8d5069bcSRyan Zezeski 				break;
242*8d5069bcSRyan Zezeski 			case (I40E_TX_DESC_DTYPE_FILTER_PROG):
243*8d5069bcSRyan Zezeski 				dtype = "FILTER";
244*8d5069bcSRyan Zezeski 				break;
245*8d5069bcSRyan Zezeski 			default:
246*8d5069bcSRyan Zezeski 				dtype = "UNKNOWN";
247*8d5069bcSRyan Zezeski 			}
248*8d5069bcSRyan Zezeski 		}
249*8d5069bcSRyan Zezeski 		dother[0] = '\0';
250*8d5069bcSRyan Zezeski 		if (i == wbhead)
251*8d5069bcSRyan Zezeski 			(void) strcat(dother, "WBHEAD");
252*8d5069bcSRyan Zezeski 
253*8d5069bcSRyan Zezeski 		if (i == trq.itrq_desc_head)
254*8d5069bcSRyan Zezeski 			(void) strcat(dother,
255*8d5069bcSRyan Zezeski 			    strlen(dother) > 0 ? " HEAD" : "HEAD");
256*8d5069bcSRyan Zezeski 
257*8d5069bcSRyan Zezeski 		if (i == trq.itrq_desc_tail)
258*8d5069bcSRyan Zezeski 			(void) strcat(dother,
259*8d5069bcSRyan Zezeski 			    strlen(dother) > 0 ? " TAIL" : "TAIL");
260*8d5069bcSRyan Zezeski 
261*8d5069bcSRyan Zezeski 		mdb_printf("%-10d %-10s %-16p %-16p %-10s\n", i, dtype, dptr,
262*8d5069bcSRyan Zezeski 		    tcbptr, dother);
263*8d5069bcSRyan Zezeski 	}
264*8d5069bcSRyan Zezeski 
265*8d5069bcSRyan Zezeski 	mdb_free(descring, ringsz);
266*8d5069bcSRyan Zezeski 	mdb_free(wklist, wklistsz);
267*8d5069bcSRyan Zezeski 	return (DCMD_OK);
268*8d5069bcSRyan Zezeski }
269*8d5069bcSRyan Zezeski 
270eab22797SRobert Mustacchi static const mdb_dcmd_t i40e_dcmds[] = {
271eab22797SRobert Mustacchi 	{ "i40e_switch_rsrcs", NULL, "print switch resources",
272eab22797SRobert Mustacchi 	    i40e_switch_rsrcs_dcmd, NULL },
273*8d5069bcSRyan Zezeski 	{ "i40e_tx_ring", "[-a] -b [start index] -e [end index]\n",
274*8d5069bcSRyan Zezeski 	    "dump TX descriptor ring state", i40e_tx_ring_dcmd,
275*8d5069bcSRyan Zezeski 	    i40e_tx_ring_help },
276eab22797SRobert Mustacchi 	{ NULL }
277eab22797SRobert Mustacchi };
278eab22797SRobert Mustacchi 
279eab22797SRobert Mustacchi static const mdb_modinfo_t i40e_modinfo = {
280eab22797SRobert Mustacchi 	MDB_API_VERSION, i40e_dcmds, NULL
281eab22797SRobert Mustacchi };
282eab22797SRobert Mustacchi 
283eab22797SRobert Mustacchi const mdb_modinfo_t *
284eab22797SRobert Mustacchi _mdb_init(void)
285eab22797SRobert Mustacchi {
286eab22797SRobert Mustacchi 	return (&i40e_modinfo);
287eab22797SRobert Mustacchi }
288