xref: /titanic_44/usr/src/cmd/mdb/intel/modules/i40e/i40e.c (revision 5ca90d72bb15ab4b88b7497504cdd4408d82faab)
113fc00e0SRobert Mustacchi /*
213fc00e0SRobert Mustacchi  * This file and its contents are supplied under the terms of the
313fc00e0SRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
413fc00e0SRobert Mustacchi  * You may only use this file in accordance with the terms of version
513fc00e0SRobert Mustacchi  * 1.0 of the CDDL.
613fc00e0SRobert Mustacchi  *
713fc00e0SRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
813fc00e0SRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
913fc00e0SRobert Mustacchi  * http://www.illumos.org/license/CDDL.
1013fc00e0SRobert Mustacchi  */
1113fc00e0SRobert Mustacchi 
1213fc00e0SRobert Mustacchi /*
13*5ca90d72SRyan Zezeski  * Copyright 2018 Joyent, Inc.
1413fc00e0SRobert Mustacchi  */
1513fc00e0SRobert Mustacchi 
16*5ca90d72SRyan Zezeski #include <mdb/mdb_ctf.h>
1713fc00e0SRobert Mustacchi #include <sys/mdb_modapi.h>
1813fc00e0SRobert Mustacchi #include "i40e_sw.h"
1913fc00e0SRobert Mustacchi 
2013fc00e0SRobert Mustacchi #define	RSRC_MAX	0x13
2113fc00e0SRobert Mustacchi static const char *i40e_switch_rsrc_names[] = {
2213fc00e0SRobert Mustacchi 	"VEBs",
2313fc00e0SRobert Mustacchi 	"VSIs",
2413fc00e0SRobert Mustacchi 	"Perfect Match MAC Addresses",
2513fc00e0SRobert Mustacchi 	"S-Tags",
2613fc00e0SRobert Mustacchi 	"Reserved",
2713fc00e0SRobert Mustacchi 	"Multicast Hash Entries",
2813fc00e0SRobert Mustacchi 	"Reserved",
2913fc00e0SRobert Mustacchi 	"VLANs",
3013fc00e0SRobert Mustacchi 	"VSI Lists",
3113fc00e0SRobert Mustacchi 	"Reserved",
3213fc00e0SRobert Mustacchi 	"VLAN Stat pools",
3313fc00e0SRobert Mustacchi 	"Mirror rules",
3413fc00e0SRobert Mustacchi 	"Queue sets",
3513fc00e0SRobert Mustacchi 	"Inner VLAN Forwarding",
3613fc00e0SRobert Mustacchi 	"Reserved",
3713fc00e0SRobert Mustacchi 	"Inner MACs",
3813fc00e0SRobert Mustacchi 	"IPs",
3913fc00e0SRobert Mustacchi 	"GRE/VN1 Keys",
4013fc00e0SRobert Mustacchi 	"VN2 Keys",
4113fc00e0SRobert Mustacchi 	"Tunnelling Ports"
4213fc00e0SRobert Mustacchi };
4313fc00e0SRobert Mustacchi 
4413fc00e0SRobert Mustacchi /*
4513fc00e0SRobert Mustacchi  * i40e mdb dcmds
4613fc00e0SRobert Mustacchi  */
4713fc00e0SRobert Mustacchi /* ARGSUSED */
4813fc00e0SRobert Mustacchi static int
i40e_switch_rsrcs_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)4913fc00e0SRobert Mustacchi i40e_switch_rsrcs_dcmd(uintptr_t addr, uint_t flags, int argc,
5013fc00e0SRobert Mustacchi     const mdb_arg_t *argv)
5113fc00e0SRobert Mustacchi {
5213fc00e0SRobert Mustacchi 	i40e_t i40e;
5313fc00e0SRobert Mustacchi 	int i;
5413fc00e0SRobert Mustacchi 
5513fc00e0SRobert Mustacchi 	if (!(flags & DCMD_ADDRSPEC)) {
5613fc00e0SRobert Mustacchi 		mdb_warn("::i40e_switch_rsrcs does not operate globally\n");
5713fc00e0SRobert Mustacchi 		return (DCMD_USAGE);
5813fc00e0SRobert Mustacchi 	}
5913fc00e0SRobert Mustacchi 
6013fc00e0SRobert Mustacchi 	if (mdb_vread(&i40e, sizeof (i40e_t), addr) != sizeof (i40e_t)) {
6113fc00e0SRobert Mustacchi 		mdb_warn("failed to read i40e_t at %p", addr);
6213fc00e0SRobert Mustacchi 		return (DCMD_ERR);
6313fc00e0SRobert Mustacchi 	}
6413fc00e0SRobert Mustacchi 
6513fc00e0SRobert Mustacchi 	mdb_printf("%-28s %-12s %-8s %-8s %s\n", "TYPE", "GUARANTEE",
6613fc00e0SRobert Mustacchi 	    "TOTAL", "USED", "UNALLOCED");
6713fc00e0SRobert Mustacchi 
6813fc00e0SRobert Mustacchi 	for (i = 0; i < i40e.i40e_switch_rsrc_actual; i++) {
6913fc00e0SRobert Mustacchi 		i40e_switch_rsrc_t rsrc;
7013fc00e0SRobert Mustacchi 		uintptr_t raddr = (uintptr_t)i40e.i40e_switch_rsrcs +
7113fc00e0SRobert Mustacchi 		    i * sizeof (i40e_switch_rsrc_t);
7213fc00e0SRobert Mustacchi 		const char *name;
7313fc00e0SRobert Mustacchi 
7413fc00e0SRobert Mustacchi 		if (mdb_vread(&rsrc, sizeof (i40e_switch_rsrc_t), raddr) !=
7513fc00e0SRobert Mustacchi 		    sizeof (i40e_switch_rsrc_t)) {
7613fc00e0SRobert Mustacchi 			mdb_warn("failed to read i40e_switch_rsrc_t %d at %p",
7713fc00e0SRobert Mustacchi 			    i, raddr);
7813fc00e0SRobert Mustacchi 			return (DCMD_ERR);
7913fc00e0SRobert Mustacchi 		}
8013fc00e0SRobert Mustacchi 
8113fc00e0SRobert Mustacchi 		if (rsrc.resource_type <= RSRC_MAX) {
8213fc00e0SRobert Mustacchi 			name = i40e_switch_rsrc_names[rsrc.resource_type];
8313fc00e0SRobert Mustacchi 		} else {
8413fc00e0SRobert Mustacchi 			char *buf;
8513fc00e0SRobert Mustacchi 			size_t s = mdb_snprintf(NULL, 0, "Unknown type (%d)",
8613fc00e0SRobert Mustacchi 			    rsrc.resource_type);
8713fc00e0SRobert Mustacchi 			buf = mdb_alloc(s + 1, UM_GC | UM_SLEEP);
8813fc00e0SRobert Mustacchi 			(void) mdb_snprintf(buf, s + 1, "Unknown type (%d)",
8913fc00e0SRobert Mustacchi 			    rsrc.resource_type);
9013fc00e0SRobert Mustacchi 			name = buf;
9113fc00e0SRobert Mustacchi 		}
9213fc00e0SRobert Mustacchi 
9313fc00e0SRobert Mustacchi 		mdb_printf("%-28s %-12d %-8d %-8d %d\n", name,
9413fc00e0SRobert Mustacchi 		    LE_16(rsrc.guaranteed), LE_16(rsrc.total), LE_16(rsrc.used),
9513fc00e0SRobert Mustacchi 		    LE_16(rsrc.total_unalloced));
9613fc00e0SRobert Mustacchi 	}
9713fc00e0SRobert Mustacchi 
9813fc00e0SRobert Mustacchi 	return (DCMD_OK);
9913fc00e0SRobert Mustacchi }
10013fc00e0SRobert Mustacchi 
101*5ca90d72SRyan Zezeski typedef struct mdb_i40e_trqpair {
102*5ca90d72SRyan Zezeski 	uint32_t		itrq_tx_ring_size;
103*5ca90d72SRyan Zezeski 	uint32_t		itrq_desc_free;
104*5ca90d72SRyan Zezeski 	uint32_t 		*itrq_desc_wbhead;
105*5ca90d72SRyan Zezeski 	uint32_t		itrq_desc_head;
106*5ca90d72SRyan Zezeski 	uint32_t		itrq_desc_tail;
107*5ca90d72SRyan Zezeski 	i40e_tx_desc_t		*itrq_desc_ring;
108*5ca90d72SRyan Zezeski 	i40e_tx_control_block_t	**itrq_tcb_work_list;
109*5ca90d72SRyan Zezeski } mdb_i40e_trqpair_t;
110*5ca90d72SRyan Zezeski 
111*5ca90d72SRyan Zezeski static void
i40e_tx_ring_help()112*5ca90d72SRyan Zezeski i40e_tx_ring_help()
113*5ca90d72SRyan Zezeski {
114*5ca90d72SRyan Zezeski 	mdb_printf(
115*5ca90d72SRyan Zezeski 	    "\t -a dump all ring entries\n"
116*5ca90d72SRyan Zezeski 	    "\t or\n"
117*5ca90d72SRyan Zezeski 	    "\t combine -b [start index] with -e [end index] to specify a \n"
118*5ca90d72SRyan Zezeski 	    "\t range of ring entries to print\n");
119*5ca90d72SRyan Zezeski }
120*5ca90d72SRyan Zezeski 
121*5ca90d72SRyan Zezeski static int
i40e_tx_ring_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)122*5ca90d72SRyan Zezeski i40e_tx_ring_dcmd(uintptr_t addr, uint_t flags, int argc,
123*5ca90d72SRyan Zezeski     const mdb_arg_t *argv)
124*5ca90d72SRyan Zezeski {
125*5ca90d72SRyan Zezeski 	mdb_i40e_trqpair_t trq;
126*5ca90d72SRyan Zezeski 	i40e_tx_desc_t *descring;
127*5ca90d72SRyan Zezeski 	i40e_tx_control_block_t **wklist;
128*5ca90d72SRyan Zezeski 	uint32_t wbhead;
129*5ca90d72SRyan Zezeski 	size_t ringsz, wklistsz;
130*5ca90d72SRyan Zezeski 	boolean_t opt_a = B_FALSE;
131*5ca90d72SRyan Zezeski 	char *opt_b = NULL, *opt_e = NULL;
132*5ca90d72SRyan Zezeski 	uint64_t begin = UINT64_MAX, end = UINT64_MAX;
133*5ca90d72SRyan Zezeski 
134*5ca90d72SRyan Zezeski 	if (!(flags & DCMD_ADDRSPEC)) {
135*5ca90d72SRyan Zezeski 		mdb_warn("::i40e_tx_ring does not operate globally\n");
136*5ca90d72SRyan Zezeski 		return (DCMD_USAGE);
137*5ca90d72SRyan Zezeski 	}
138*5ca90d72SRyan Zezeski 
139*5ca90d72SRyan Zezeski 	if (mdb_getopts(argc, argv,
140*5ca90d72SRyan Zezeski 	    'a', MDB_OPT_SETBITS, B_TRUE, &opt_a,
141*5ca90d72SRyan Zezeski 	    'b', MDB_OPT_STR, &opt_b,
142*5ca90d72SRyan Zezeski 	    'e', MDB_OPT_STR, &opt_e, NULL) != argc)
143*5ca90d72SRyan Zezeski 		return (DCMD_USAGE);
144*5ca90d72SRyan Zezeski 
145*5ca90d72SRyan Zezeski 	/*
146*5ca90d72SRyan Zezeski 	 * Verify that a legal combination of -a/-b/-e were used.
147*5ca90d72SRyan Zezeski 	 */
148*5ca90d72SRyan Zezeski 	if (opt_a && (opt_b != NULL || opt_e != NULL)) {
149*5ca90d72SRyan Zezeski 		mdb_warn("-a and -b/-e are mutually exclusive\n");
150*5ca90d72SRyan Zezeski 		return (DCMD_USAGE);
151*5ca90d72SRyan Zezeski 	}
152*5ca90d72SRyan Zezeski 	if (argc > 0 && ! opt_a && (opt_b == NULL || opt_e == NULL)) {
153*5ca90d72SRyan Zezeski 		mdb_warn("-b/-e must both be specified\n");
154*5ca90d72SRyan Zezeski 		return (DCMD_USAGE);
155*5ca90d72SRyan Zezeski 	}
156*5ca90d72SRyan Zezeski 
157*5ca90d72SRyan Zezeski 	if (mdb_ctf_vread(&trq, "i40e_trqpair_t", "mdb_i40e_trqpair_t", addr,
158*5ca90d72SRyan Zezeski 	    0) == -1) {
159*5ca90d72SRyan Zezeski 		mdb_warn("failed to read i40e_trqpair_t at %p", addr);
160*5ca90d72SRyan Zezeski 		return (DCMD_ERR);
161*5ca90d72SRyan Zezeski 	}
162*5ca90d72SRyan Zezeski 
163*5ca90d72SRyan Zezeski 	if (opt_b != NULL)
164*5ca90d72SRyan Zezeski 		begin = mdb_strtoull(opt_b);
165*5ca90d72SRyan Zezeski 	if (opt_e != NULL)
166*5ca90d72SRyan Zezeski 		end = mdb_strtoull(opt_e);
167*5ca90d72SRyan Zezeski 	if (opt_a) {
168*5ca90d72SRyan Zezeski 		begin = 0;
169*5ca90d72SRyan Zezeski 		end = trq.itrq_tx_ring_size - 1;
170*5ca90d72SRyan Zezeski 	}
171*5ca90d72SRyan Zezeski 
172*5ca90d72SRyan Zezeski 	/*
173*5ca90d72SRyan Zezeski 	 * Verify that the requested range of ring entries makes sense.
174*5ca90d72SRyan Zezeski 	 */
175*5ca90d72SRyan Zezeski 	if (argc > 0 && (end < begin || begin >= trq.itrq_tx_ring_size ||
176*5ca90d72SRyan Zezeski 	    end >= trq.itrq_tx_ring_size)) {
177*5ca90d72SRyan Zezeski 		mdb_warn("invalid range specified\n");
178*5ca90d72SRyan Zezeski 		return (DCMD_USAGE);
179*5ca90d72SRyan Zezeski 	}
180*5ca90d72SRyan Zezeski 
181*5ca90d72SRyan Zezeski 	if (mdb_vread(&wbhead, sizeof (uint32_t),
182*5ca90d72SRyan Zezeski 	    (uintptr_t)trq.itrq_desc_wbhead) != sizeof (uint32_t)) {
183*5ca90d72SRyan Zezeski 		mdb_warn("failed to read trq.itrq_desc_wbhead");
184*5ca90d72SRyan Zezeski 		return (DCMD_ERR);
185*5ca90d72SRyan Zezeski 	}
186*5ca90d72SRyan Zezeski 	mdb_printf("%-20s%d\n", "Ring Size:", trq.itrq_tx_ring_size);
187*5ca90d72SRyan Zezeski 	mdb_printf("%-20s%d\n", "Free Descriptors:", trq.itrq_desc_free);
188*5ca90d72SRyan Zezeski 	mdb_printf("%-20s%d\n", "Writeback Head:", wbhead);
189*5ca90d72SRyan Zezeski 	mdb_printf("%-20s%d\n", "Head:", trq.itrq_desc_head);
190*5ca90d72SRyan Zezeski 	mdb_printf("%-20s%d\n", "Tail:", trq.itrq_desc_tail);
191*5ca90d72SRyan Zezeski 
192*5ca90d72SRyan Zezeski 	/*
193*5ca90d72SRyan Zezeski 	 * No arguments were specified, so we're done.
194*5ca90d72SRyan Zezeski 	 */
195*5ca90d72SRyan Zezeski 	if (argc == 0)
196*5ca90d72SRyan Zezeski 		return (DCMD_OK);
197*5ca90d72SRyan Zezeski 
198*5ca90d72SRyan Zezeski 	/*
199*5ca90d72SRyan Zezeski 	 * Allocate memory and read in the entire TX descriptor ring and
200*5ca90d72SRyan Zezeski 	 * TCB work list.
201*5ca90d72SRyan Zezeski 	 */
202*5ca90d72SRyan Zezeski 	ringsz = sizeof (i40e_tx_desc_t) * trq.itrq_tx_ring_size;
203*5ca90d72SRyan Zezeski 	descring = mdb_alloc(ringsz, UM_SLEEP);
204*5ca90d72SRyan Zezeski 	if (mdb_vread(descring, ringsz, (uintptr_t)trq.itrq_desc_ring) !=
205*5ca90d72SRyan Zezeski 	    ringsz) {
206*5ca90d72SRyan Zezeski 		mdb_warn("Failed to read in TX decriptor ring\n");
207*5ca90d72SRyan Zezeski 		mdb_free(descring, ringsz);
208*5ca90d72SRyan Zezeski 		return (DCMD_ERR);
209*5ca90d72SRyan Zezeski 	}
210*5ca90d72SRyan Zezeski 	wklistsz = sizeof (i40e_tx_control_block_t *) * trq.itrq_tx_ring_size;
211*5ca90d72SRyan Zezeski 	wklist = mdb_alloc(wklistsz, UM_SLEEP);
212*5ca90d72SRyan Zezeski 	if (mdb_vread(wklist, wklistsz, (uintptr_t)trq.itrq_tcb_work_list) !=
213*5ca90d72SRyan Zezeski 	    wklistsz) {
214*5ca90d72SRyan Zezeski 		mdb_warn("Failed to read in TX TCB work list\n");
215*5ca90d72SRyan Zezeski 		mdb_free(descring, ringsz);
216*5ca90d72SRyan Zezeski 		mdb_free(wklist, wklistsz);
217*5ca90d72SRyan Zezeski 		return (DCMD_ERR);
218*5ca90d72SRyan Zezeski 	}
219*5ca90d72SRyan Zezeski 
220*5ca90d72SRyan Zezeski 	mdb_printf("\n%-10s %-10s %-16s %-16s %-10s\n", "Index", "Desc Type",
221*5ca90d72SRyan Zezeski 	    "Desc Ptr", "TCB Ptr", "Other");
222*5ca90d72SRyan Zezeski 	for (uint64_t i = begin; i <= end; i++) {
223*5ca90d72SRyan Zezeski 		const char *dtype;
224*5ca90d72SRyan Zezeski 		char dother[17];
225*5ca90d72SRyan Zezeski 		i40e_tx_desc_t *dptr;
226*5ca90d72SRyan Zezeski 		i40e_tx_control_block_t *tcbptr;
227*5ca90d72SRyan Zezeski 		uint64_t ctob;
228*5ca90d72SRyan Zezeski 
229*5ca90d72SRyan Zezeski 		dptr = &descring[i];
230*5ca90d72SRyan Zezeski 		tcbptr = wklist[i];
231*5ca90d72SRyan Zezeski 		ctob = LE_64(dptr->cmd_type_offset_bsz);
232*5ca90d72SRyan Zezeski 		if (ctob == 0) {
233*5ca90d72SRyan Zezeski 			dtype = "FREE";
234*5ca90d72SRyan Zezeski 		} else {
235*5ca90d72SRyan Zezeski 			switch (ctob & I40E_TXD_QW1_DTYPE_MASK) {
236*5ca90d72SRyan Zezeski 			case (I40E_TX_DESC_DTYPE_CONTEXT):
237*5ca90d72SRyan Zezeski 				dtype = "CONTEXT";
238*5ca90d72SRyan Zezeski 				break;
239*5ca90d72SRyan Zezeski 			case (I40E_TX_DESC_DTYPE_DATA):
240*5ca90d72SRyan Zezeski 				dtype = "DATA";
241*5ca90d72SRyan Zezeski 				break;
242*5ca90d72SRyan Zezeski 			case (I40E_TX_DESC_DTYPE_FILTER_PROG):
243*5ca90d72SRyan Zezeski 				dtype = "FILTER";
244*5ca90d72SRyan Zezeski 				break;
245*5ca90d72SRyan Zezeski 			default:
246*5ca90d72SRyan Zezeski 				dtype = "UNKNOWN";
247*5ca90d72SRyan Zezeski 			}
248*5ca90d72SRyan Zezeski 		}
249*5ca90d72SRyan Zezeski 		dother[0] = '\0';
250*5ca90d72SRyan Zezeski 		if (i == wbhead)
251*5ca90d72SRyan Zezeski 			(void) strcat(dother, "WBHEAD");
252*5ca90d72SRyan Zezeski 
253*5ca90d72SRyan Zezeski 		if (i == trq.itrq_desc_head)
254*5ca90d72SRyan Zezeski 			(void) strcat(dother,
255*5ca90d72SRyan Zezeski 			    strlen(dother) > 0 ? " HEAD" : "HEAD");
256*5ca90d72SRyan Zezeski 
257*5ca90d72SRyan Zezeski 		if (i == trq.itrq_desc_tail)
258*5ca90d72SRyan Zezeski 			(void) strcat(dother,
259*5ca90d72SRyan Zezeski 			    strlen(dother) > 0 ? " TAIL" : "TAIL");
260*5ca90d72SRyan Zezeski 
261*5ca90d72SRyan Zezeski 		mdb_printf("%-10d %-10s %-16p %-16p %-10s\n", i, dtype, dptr,
262*5ca90d72SRyan Zezeski 		    tcbptr, dother);
263*5ca90d72SRyan Zezeski 	}
264*5ca90d72SRyan Zezeski 
265*5ca90d72SRyan Zezeski 	mdb_free(descring, ringsz);
266*5ca90d72SRyan Zezeski 	mdb_free(wklist, wklistsz);
267*5ca90d72SRyan Zezeski 	return (DCMD_OK);
268*5ca90d72SRyan Zezeski }
269*5ca90d72SRyan Zezeski 
27013fc00e0SRobert Mustacchi static const mdb_dcmd_t i40e_dcmds[] = {
27113fc00e0SRobert Mustacchi 	{ "i40e_switch_rsrcs", NULL, "print switch resources",
27213fc00e0SRobert Mustacchi 	    i40e_switch_rsrcs_dcmd, NULL },
273*5ca90d72SRyan Zezeski 	{ "i40e_tx_ring", "[-a] -b [start index] -e [end index]\n",
274*5ca90d72SRyan Zezeski 	    "dump TX descriptor ring state", i40e_tx_ring_dcmd,
275*5ca90d72SRyan Zezeski 	    i40e_tx_ring_help },
27613fc00e0SRobert Mustacchi 	{ NULL }
27713fc00e0SRobert Mustacchi };
27813fc00e0SRobert Mustacchi 
27913fc00e0SRobert Mustacchi static const mdb_modinfo_t i40e_modinfo = {
28013fc00e0SRobert Mustacchi 	MDB_API_VERSION, i40e_dcmds, NULL
28113fc00e0SRobert Mustacchi };
28213fc00e0SRobert Mustacchi 
28313fc00e0SRobert Mustacchi const mdb_modinfo_t *
_mdb_init(void)28413fc00e0SRobert Mustacchi _mdb_init(void)
28513fc00e0SRobert Mustacchi {
28613fc00e0SRobert Mustacchi 	return (&i40e_modinfo);
28713fc00e0SRobert Mustacchi }
288