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