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