19d26e4fcSRobert Mustacchi /*
29d26e4fcSRobert Mustacchi * This file and its contents are supplied under the terms of the
39d26e4fcSRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0.
49d26e4fcSRobert Mustacchi * You may only use this file in accordance with the terms of version
59d26e4fcSRobert Mustacchi * 1.0 of the CDDL.
69d26e4fcSRobert Mustacchi *
79d26e4fcSRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this
89d26e4fcSRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at
99d26e4fcSRobert Mustacchi * http://www.illumos.org/license/CDDL.
109d26e4fcSRobert Mustacchi */
119d26e4fcSRobert Mustacchi
129d26e4fcSRobert Mustacchi /*
13*09aee612SRyan Zezeski * Copyright 2018 Joyent, Inc.
149d26e4fcSRobert Mustacchi */
159d26e4fcSRobert Mustacchi
16*09aee612SRyan Zezeski #include <mdb/mdb_ctf.h>
179d26e4fcSRobert Mustacchi #include <sys/mdb_modapi.h>
189d26e4fcSRobert Mustacchi #include "i40e_sw.h"
199d26e4fcSRobert Mustacchi
209d26e4fcSRobert Mustacchi #define RSRC_MAX 0x13
219d26e4fcSRobert Mustacchi static const char *i40e_switch_rsrc_names[] = {
229d26e4fcSRobert Mustacchi "VEBs",
239d26e4fcSRobert Mustacchi "VSIs",
249d26e4fcSRobert Mustacchi "Perfect Match MAC Addresses",
259d26e4fcSRobert Mustacchi "S-Tags",
269d26e4fcSRobert Mustacchi "Reserved",
279d26e4fcSRobert Mustacchi "Multicast Hash Entries",
289d26e4fcSRobert Mustacchi "Reserved",
299d26e4fcSRobert Mustacchi "VLANs",
309d26e4fcSRobert Mustacchi "VSI Lists",
319d26e4fcSRobert Mustacchi "Reserved",
329d26e4fcSRobert Mustacchi "VLAN Stat pools",
339d26e4fcSRobert Mustacchi "Mirror rules",
349d26e4fcSRobert Mustacchi "Queue sets",
359d26e4fcSRobert Mustacchi "Inner VLAN Forwarding",
369d26e4fcSRobert Mustacchi "Reserved",
379d26e4fcSRobert Mustacchi "Inner MACs",
389d26e4fcSRobert Mustacchi "IPs",
399d26e4fcSRobert Mustacchi "GRE/VN1 Keys",
409d26e4fcSRobert Mustacchi "VN2 Keys",
419d26e4fcSRobert Mustacchi "Tunnelling Ports"
429d26e4fcSRobert Mustacchi };
439d26e4fcSRobert Mustacchi
449d26e4fcSRobert Mustacchi /*
459d26e4fcSRobert Mustacchi * i40e mdb dcmds
469d26e4fcSRobert Mustacchi */
479d26e4fcSRobert Mustacchi /* ARGSUSED */
489d26e4fcSRobert Mustacchi static int
i40e_switch_rsrcs_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)499d26e4fcSRobert Mustacchi i40e_switch_rsrcs_dcmd(uintptr_t addr, uint_t flags, int argc,
509d26e4fcSRobert Mustacchi const mdb_arg_t *argv)
519d26e4fcSRobert Mustacchi {
529d26e4fcSRobert Mustacchi i40e_t i40e;
539d26e4fcSRobert Mustacchi int i;
549d26e4fcSRobert Mustacchi
559d26e4fcSRobert Mustacchi if (!(flags & DCMD_ADDRSPEC)) {
569d26e4fcSRobert Mustacchi mdb_warn("::i40e_switch_rsrcs does not operate globally\n");
579d26e4fcSRobert Mustacchi return (DCMD_USAGE);
589d26e4fcSRobert Mustacchi }
599d26e4fcSRobert Mustacchi
609d26e4fcSRobert Mustacchi if (mdb_vread(&i40e, sizeof (i40e_t), addr) != sizeof (i40e_t)) {
619d26e4fcSRobert Mustacchi mdb_warn("failed to read i40e_t at %p", addr);
629d26e4fcSRobert Mustacchi return (DCMD_ERR);
639d26e4fcSRobert Mustacchi }
649d26e4fcSRobert Mustacchi
659d26e4fcSRobert Mustacchi mdb_printf("%-28s %-12s %-8s %-8s %s\n", "TYPE", "GUARANTEE",
669d26e4fcSRobert Mustacchi "TOTAL", "USED", "UNALLOCED");
679d26e4fcSRobert Mustacchi
689d26e4fcSRobert Mustacchi for (i = 0; i < i40e.i40e_switch_rsrc_actual; i++) {
699d26e4fcSRobert Mustacchi i40e_switch_rsrc_t rsrc;
709d26e4fcSRobert Mustacchi uintptr_t raddr = (uintptr_t)i40e.i40e_switch_rsrcs +
719d26e4fcSRobert Mustacchi i * sizeof (i40e_switch_rsrc_t);
729d26e4fcSRobert Mustacchi const char *name;
739d26e4fcSRobert Mustacchi
749d26e4fcSRobert Mustacchi if (mdb_vread(&rsrc, sizeof (i40e_switch_rsrc_t), raddr) !=
759d26e4fcSRobert Mustacchi sizeof (i40e_switch_rsrc_t)) {
769d26e4fcSRobert Mustacchi mdb_warn("failed to read i40e_switch_rsrc_t %d at %p",
779d26e4fcSRobert Mustacchi i, raddr);
789d26e4fcSRobert Mustacchi return (DCMD_ERR);
799d26e4fcSRobert Mustacchi }
809d26e4fcSRobert Mustacchi
819d26e4fcSRobert Mustacchi if (rsrc.resource_type <= RSRC_MAX) {
829d26e4fcSRobert Mustacchi name = i40e_switch_rsrc_names[rsrc.resource_type];
839d26e4fcSRobert Mustacchi } else {
849d26e4fcSRobert Mustacchi char *buf;
859d26e4fcSRobert Mustacchi size_t s = mdb_snprintf(NULL, 0, "Unknown type (%d)",
869d26e4fcSRobert Mustacchi rsrc.resource_type);
879d26e4fcSRobert Mustacchi buf = mdb_alloc(s + 1, UM_GC | UM_SLEEP);
889d26e4fcSRobert Mustacchi (void) mdb_snprintf(buf, s + 1, "Unknown type (%d)",
899d26e4fcSRobert Mustacchi rsrc.resource_type);
909d26e4fcSRobert Mustacchi name = buf;
919d26e4fcSRobert Mustacchi }
929d26e4fcSRobert Mustacchi
939d26e4fcSRobert Mustacchi mdb_printf("%-28s %-12d %-8d %-8d %d\n", name,
949d26e4fcSRobert Mustacchi LE_16(rsrc.guaranteed), LE_16(rsrc.total), LE_16(rsrc.used),
959d26e4fcSRobert Mustacchi LE_16(rsrc.total_unalloced));
969d26e4fcSRobert Mustacchi }
979d26e4fcSRobert Mustacchi
989d26e4fcSRobert Mustacchi return (DCMD_OK);
999d26e4fcSRobert Mustacchi }
1009d26e4fcSRobert Mustacchi
101*09aee612SRyan Zezeski typedef struct mdb_i40e_trqpair {
102*09aee612SRyan Zezeski uint32_t itrq_tx_ring_size;
103*09aee612SRyan Zezeski uint32_t itrq_desc_free;
104*09aee612SRyan Zezeski uint32_t *itrq_desc_wbhead;
105*09aee612SRyan Zezeski uint32_t itrq_desc_head;
106*09aee612SRyan Zezeski uint32_t itrq_desc_tail;
107*09aee612SRyan Zezeski i40e_tx_desc_t *itrq_desc_ring;
108*09aee612SRyan Zezeski i40e_tx_control_block_t **itrq_tcb_work_list;
109*09aee612SRyan Zezeski } mdb_i40e_trqpair_t;
110*09aee612SRyan Zezeski
111*09aee612SRyan Zezeski static void
i40e_tx_ring_help()112*09aee612SRyan Zezeski i40e_tx_ring_help()
113*09aee612SRyan Zezeski {
114*09aee612SRyan Zezeski mdb_printf(
115*09aee612SRyan Zezeski "\t -a dump all ring entries\n"
116*09aee612SRyan Zezeski "\t or\n"
117*09aee612SRyan Zezeski "\t combine -b [start index] with -e [end index] to specify a \n"
118*09aee612SRyan Zezeski "\t range of ring entries to print\n");
119*09aee612SRyan Zezeski }
120*09aee612SRyan Zezeski
121*09aee612SRyan Zezeski static int
i40e_tx_ring_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)122*09aee612SRyan Zezeski i40e_tx_ring_dcmd(uintptr_t addr, uint_t flags, int argc,
123*09aee612SRyan Zezeski const mdb_arg_t *argv)
124*09aee612SRyan Zezeski {
125*09aee612SRyan Zezeski mdb_i40e_trqpair_t trq;
126*09aee612SRyan Zezeski i40e_tx_desc_t *descring;
127*09aee612SRyan Zezeski i40e_tx_control_block_t **wklist;
128*09aee612SRyan Zezeski uint32_t wbhead;
129*09aee612SRyan Zezeski size_t ringsz, wklistsz;
130*09aee612SRyan Zezeski boolean_t opt_a = B_FALSE;
131*09aee612SRyan Zezeski char *opt_b = NULL, *opt_e = NULL;
132*09aee612SRyan Zezeski uint64_t begin = UINT64_MAX, end = UINT64_MAX;
133*09aee612SRyan Zezeski
134*09aee612SRyan Zezeski if (!(flags & DCMD_ADDRSPEC)) {
135*09aee612SRyan Zezeski mdb_warn("::i40e_tx_ring does not operate globally\n");
136*09aee612SRyan Zezeski return (DCMD_USAGE);
137*09aee612SRyan Zezeski }
138*09aee612SRyan Zezeski
139*09aee612SRyan Zezeski if (mdb_getopts(argc, argv,
140*09aee612SRyan Zezeski 'a', MDB_OPT_SETBITS, B_TRUE, &opt_a,
141*09aee612SRyan Zezeski 'b', MDB_OPT_STR, &opt_b,
142*09aee612SRyan Zezeski 'e', MDB_OPT_STR, &opt_e, NULL) != argc)
143*09aee612SRyan Zezeski return (DCMD_USAGE);
144*09aee612SRyan Zezeski
145*09aee612SRyan Zezeski /*
146*09aee612SRyan Zezeski * Verify that a legal combination of -a/-b/-e were used.
147*09aee612SRyan Zezeski */
148*09aee612SRyan Zezeski if (opt_a && (opt_b != NULL || opt_e != NULL)) {
149*09aee612SRyan Zezeski mdb_warn("-a and -b/-e are mutually exclusive\n");
150*09aee612SRyan Zezeski return (DCMD_USAGE);
151*09aee612SRyan Zezeski }
152*09aee612SRyan Zezeski if (argc > 0 && ! opt_a && (opt_b == NULL || opt_e == NULL)) {
153*09aee612SRyan Zezeski mdb_warn("-b/-e must both be specified\n");
154*09aee612SRyan Zezeski return (DCMD_USAGE);
155*09aee612SRyan Zezeski }
156*09aee612SRyan Zezeski
157*09aee612SRyan Zezeski if (mdb_ctf_vread(&trq, "i40e_trqpair_t", "mdb_i40e_trqpair_t", addr,
158*09aee612SRyan Zezeski 0) == -1) {
159*09aee612SRyan Zezeski mdb_warn("failed to read i40e_trqpair_t at %p", addr);
160*09aee612SRyan Zezeski return (DCMD_ERR);
161*09aee612SRyan Zezeski }
162*09aee612SRyan Zezeski
163*09aee612SRyan Zezeski if (opt_b != NULL)
164*09aee612SRyan Zezeski begin = mdb_strtoull(opt_b);
165*09aee612SRyan Zezeski if (opt_e != NULL)
166*09aee612SRyan Zezeski end = mdb_strtoull(opt_e);
167*09aee612SRyan Zezeski if (opt_a) {
168*09aee612SRyan Zezeski begin = 0;
169*09aee612SRyan Zezeski end = trq.itrq_tx_ring_size - 1;
170*09aee612SRyan Zezeski }
171*09aee612SRyan Zezeski
172*09aee612SRyan Zezeski /*
173*09aee612SRyan Zezeski * Verify that the requested range of ring entries makes sense.
174*09aee612SRyan Zezeski */
175*09aee612SRyan Zezeski if (argc > 0 && (end < begin || begin >= trq.itrq_tx_ring_size ||
176*09aee612SRyan Zezeski end >= trq.itrq_tx_ring_size)) {
177*09aee612SRyan Zezeski mdb_warn("invalid range specified\n");
178*09aee612SRyan Zezeski return (DCMD_USAGE);
179*09aee612SRyan Zezeski }
180*09aee612SRyan Zezeski
181*09aee612SRyan Zezeski if (mdb_vread(&wbhead, sizeof (uint32_t),
182*09aee612SRyan Zezeski (uintptr_t)trq.itrq_desc_wbhead) != sizeof (uint32_t)) {
183*09aee612SRyan Zezeski mdb_warn("failed to read trq.itrq_desc_wbhead");
184*09aee612SRyan Zezeski return (DCMD_ERR);
185*09aee612SRyan Zezeski }
186*09aee612SRyan Zezeski mdb_printf("%-20s%d\n", "Ring Size:", trq.itrq_tx_ring_size);
187*09aee612SRyan Zezeski mdb_printf("%-20s%d\n", "Free Descriptors:", trq.itrq_desc_free);
188*09aee612SRyan Zezeski mdb_printf("%-20s%d\n", "Writeback Head:", wbhead);
189*09aee612SRyan Zezeski mdb_printf("%-20s%d\n", "Head:", trq.itrq_desc_head);
190*09aee612SRyan Zezeski mdb_printf("%-20s%d\n", "Tail:", trq.itrq_desc_tail);
191*09aee612SRyan Zezeski
192*09aee612SRyan Zezeski /*
193*09aee612SRyan Zezeski * No arguments were specified, so we're done.
194*09aee612SRyan Zezeski */
195*09aee612SRyan Zezeski if (argc == 0)
196*09aee612SRyan Zezeski return (DCMD_OK);
197*09aee612SRyan Zezeski
198*09aee612SRyan Zezeski /*
199*09aee612SRyan Zezeski * Allocate memory and read in the entire TX descriptor ring and
200*09aee612SRyan Zezeski * TCB work list.
201*09aee612SRyan Zezeski */
202*09aee612SRyan Zezeski ringsz = sizeof (i40e_tx_desc_t) * trq.itrq_tx_ring_size;
203*09aee612SRyan Zezeski descring = mdb_alloc(ringsz, UM_SLEEP);
204*09aee612SRyan Zezeski if (mdb_vread(descring, ringsz, (uintptr_t)trq.itrq_desc_ring) !=
205*09aee612SRyan Zezeski ringsz) {
206*09aee612SRyan Zezeski mdb_warn("Failed to read in TX decriptor ring\n");
207*09aee612SRyan Zezeski mdb_free(descring, ringsz);
208*09aee612SRyan Zezeski return (DCMD_ERR);
209*09aee612SRyan Zezeski }
210*09aee612SRyan Zezeski wklistsz = sizeof (i40e_tx_control_block_t *) * trq.itrq_tx_ring_size;
211*09aee612SRyan Zezeski wklist = mdb_alloc(wklistsz, UM_SLEEP);
212*09aee612SRyan Zezeski if (mdb_vread(wklist, wklistsz, (uintptr_t)trq.itrq_tcb_work_list) !=
213*09aee612SRyan Zezeski wklistsz) {
214*09aee612SRyan Zezeski mdb_warn("Failed to read in TX TCB work list\n");
215*09aee612SRyan Zezeski mdb_free(descring, ringsz);
216*09aee612SRyan Zezeski mdb_free(wklist, wklistsz);
217*09aee612SRyan Zezeski return (DCMD_ERR);
218*09aee612SRyan Zezeski }
219*09aee612SRyan Zezeski
220*09aee612SRyan Zezeski mdb_printf("\n%-10s %-10s %-16s %-16s %-10s\n", "Index", "Desc Type",
221*09aee612SRyan Zezeski "Desc Ptr", "TCB Ptr", "Other");
222*09aee612SRyan Zezeski for (uint64_t i = begin; i <= end; i++) {
223*09aee612SRyan Zezeski const char *dtype;
224*09aee612SRyan Zezeski char dother[17];
225*09aee612SRyan Zezeski i40e_tx_desc_t *dptr;
226*09aee612SRyan Zezeski i40e_tx_control_block_t *tcbptr;
227*09aee612SRyan Zezeski uint64_t ctob;
228*09aee612SRyan Zezeski
229*09aee612SRyan Zezeski dptr = &descring[i];
230*09aee612SRyan Zezeski tcbptr = wklist[i];
231*09aee612SRyan Zezeski ctob = LE_64(dptr->cmd_type_offset_bsz);
232*09aee612SRyan Zezeski if (ctob == 0) {
233*09aee612SRyan Zezeski dtype = "FREE";
234*09aee612SRyan Zezeski } else {
235*09aee612SRyan Zezeski switch (ctob & I40E_TXD_QW1_DTYPE_MASK) {
236*09aee612SRyan Zezeski case (I40E_TX_DESC_DTYPE_CONTEXT):
237*09aee612SRyan Zezeski dtype = "CONTEXT";
238*09aee612SRyan Zezeski break;
239*09aee612SRyan Zezeski case (I40E_TX_DESC_DTYPE_DATA):
240*09aee612SRyan Zezeski dtype = "DATA";
241*09aee612SRyan Zezeski break;
242*09aee612SRyan Zezeski case (I40E_TX_DESC_DTYPE_FILTER_PROG):
243*09aee612SRyan Zezeski dtype = "FILTER";
244*09aee612SRyan Zezeski break;
245*09aee612SRyan Zezeski default:
246*09aee612SRyan Zezeski dtype = "UNKNOWN";
247*09aee612SRyan Zezeski }
248*09aee612SRyan Zezeski }
249*09aee612SRyan Zezeski dother[0] = '\0';
250*09aee612SRyan Zezeski if (i == wbhead)
251*09aee612SRyan Zezeski (void) strcat(dother, "WBHEAD");
252*09aee612SRyan Zezeski
253*09aee612SRyan Zezeski if (i == trq.itrq_desc_head)
254*09aee612SRyan Zezeski (void) strcat(dother,
255*09aee612SRyan Zezeski strlen(dother) > 0 ? " HEAD" : "HEAD");
256*09aee612SRyan Zezeski
257*09aee612SRyan Zezeski if (i == trq.itrq_desc_tail)
258*09aee612SRyan Zezeski (void) strcat(dother,
259*09aee612SRyan Zezeski strlen(dother) > 0 ? " TAIL" : "TAIL");
260*09aee612SRyan Zezeski
261*09aee612SRyan Zezeski mdb_printf("%-10d %-10s %-16p %-16p %-10s\n", i, dtype, dptr,
262*09aee612SRyan Zezeski tcbptr, dother);
263*09aee612SRyan Zezeski }
264*09aee612SRyan Zezeski
265*09aee612SRyan Zezeski mdb_free(descring, ringsz);
266*09aee612SRyan Zezeski mdb_free(wklist, wklistsz);
267*09aee612SRyan Zezeski return (DCMD_OK);
268*09aee612SRyan Zezeski }
269*09aee612SRyan Zezeski
2709d26e4fcSRobert Mustacchi static const mdb_dcmd_t i40e_dcmds[] = {
2719d26e4fcSRobert Mustacchi { "i40e_switch_rsrcs", NULL, "print switch resources",
2729d26e4fcSRobert Mustacchi i40e_switch_rsrcs_dcmd, NULL },
273*09aee612SRyan Zezeski { "i40e_tx_ring", "[-a] -b [start index] -e [end index]\n",
274*09aee612SRyan Zezeski "dump TX descriptor ring state", i40e_tx_ring_dcmd,
275*09aee612SRyan Zezeski i40e_tx_ring_help },
2769d26e4fcSRobert Mustacchi { NULL }
2779d26e4fcSRobert Mustacchi };
2789d26e4fcSRobert Mustacchi
2799d26e4fcSRobert Mustacchi static const mdb_modinfo_t i40e_modinfo = {
2809d26e4fcSRobert Mustacchi MDB_API_VERSION, i40e_dcmds, NULL
2819d26e4fcSRobert Mustacchi };
2829d26e4fcSRobert Mustacchi
2839d26e4fcSRobert Mustacchi const mdb_modinfo_t *
_mdb_init(void)2849d26e4fcSRobert Mustacchi _mdb_init(void)
2859d26e4fcSRobert Mustacchi {
2869d26e4fcSRobert Mustacchi return (&i40e_modinfo);
2879d26e4fcSRobert Mustacchi }
288