154912308SNavdeep Parhar /*- 254912308SNavdeep Parhar * Copyright (c) 2011 Chelsio Communications, Inc. 354912308SNavdeep Parhar * All rights reserved. 454912308SNavdeep Parhar * Written by: Navdeep Parhar <np@FreeBSD.org> 554912308SNavdeep Parhar * 654912308SNavdeep Parhar * Redistribution and use in source and binary forms, with or without 754912308SNavdeep Parhar * modification, are permitted provided that the following conditions 854912308SNavdeep Parhar * are met: 954912308SNavdeep Parhar * 1. Redistributions of source code must retain the above copyright 1054912308SNavdeep Parhar * notice, this list of conditions and the following disclaimer. 1154912308SNavdeep Parhar * 2. Redistributions in binary form must reproduce the above copyright 1254912308SNavdeep Parhar * notice, this list of conditions and the following disclaimer in the 1354912308SNavdeep Parhar * documentation and/or other materials provided with the distribution. 1454912308SNavdeep Parhar * 1554912308SNavdeep Parhar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1654912308SNavdeep Parhar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1754912308SNavdeep Parhar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1854912308SNavdeep Parhar * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1954912308SNavdeep Parhar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2054912308SNavdeep Parhar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2154912308SNavdeep Parhar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2254912308SNavdeep Parhar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2354912308SNavdeep Parhar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2454912308SNavdeep Parhar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2554912308SNavdeep Parhar * SUCH DAMAGE. 2654912308SNavdeep Parhar */ 2754912308SNavdeep Parhar 2854912308SNavdeep Parhar #include <sys/cdefs.h> 2954912308SNavdeep Parhar __FBSDID("$FreeBSD$"); 3054912308SNavdeep Parhar 3154912308SNavdeep Parhar #include <sys/param.h> 3254912308SNavdeep Parhar #include <sys/ioctl.h> 3354912308SNavdeep Parhar #include <sys/mman.h> 3454912308SNavdeep Parhar #include <sys/socket.h> 3554912308SNavdeep Parhar #include <sys/stat.h> 3654912308SNavdeep Parhar 3754912308SNavdeep Parhar #include <arpa/inet.h> 3854912308SNavdeep Parhar #include <net/ethernet.h> 3954912308SNavdeep Parhar #include <net/sff8472.h> 4054912308SNavdeep Parhar #include <netinet/in.h> 4154912308SNavdeep Parhar 4254912308SNavdeep Parhar #include <ctype.h> 4354912308SNavdeep Parhar #include <err.h> 4454912308SNavdeep Parhar #include <errno.h> 4554912308SNavdeep Parhar #include <fcntl.h> 4654912308SNavdeep Parhar #include <limits.h> 4754912308SNavdeep Parhar #include <stdint.h> 4854912308SNavdeep Parhar #include <stdio.h> 4954912308SNavdeep Parhar #include <stdlib.h> 5054912308SNavdeep Parhar #include <string.h> 5154912308SNavdeep Parhar #include <unistd.h> 5254912308SNavdeep Parhar 5354912308SNavdeep Parhar #include "t4_ioctl.h" 54*ae9b4017SNavdeep Parhar #include "tcb_common.h" 5554912308SNavdeep Parhar 5654912308SNavdeep Parhar #define in_range(val, lo, hi) ( val < 0 || (val <= hi && val >= lo)) 5754912308SNavdeep Parhar #define max(x, y) ((x) > (y) ? (x) : (y)) 5854912308SNavdeep Parhar 5954912308SNavdeep Parhar static const char *progname, *nexus; 6054912308SNavdeep Parhar static int chip_id; /* 4 for T4, 5 for T5 */ 6154912308SNavdeep Parhar 6254912308SNavdeep Parhar struct reg_info { 6354912308SNavdeep Parhar const char *name; 6454912308SNavdeep Parhar uint32_t addr; 6554912308SNavdeep Parhar uint32_t len; 6654912308SNavdeep Parhar }; 6754912308SNavdeep Parhar 6854912308SNavdeep Parhar struct mod_regs { 6954912308SNavdeep Parhar const char *name; 7054912308SNavdeep Parhar const struct reg_info *ri; 7154912308SNavdeep Parhar }; 7254912308SNavdeep Parhar 7354912308SNavdeep Parhar struct field_desc { 7454912308SNavdeep Parhar const char *name; /* Field name */ 7554912308SNavdeep Parhar unsigned short start; /* Start bit position */ 7654912308SNavdeep Parhar unsigned short end; /* End bit position */ 7754912308SNavdeep Parhar unsigned char shift; /* # of low order bits omitted and implicitly 0 */ 7854912308SNavdeep Parhar unsigned char hex; /* Print field in hex instead of decimal */ 7954912308SNavdeep Parhar unsigned char islog2; /* Field contains the base-2 log of the value */ 8054912308SNavdeep Parhar }; 8154912308SNavdeep Parhar 8254912308SNavdeep Parhar #include "reg_defs_t4.c" 8354912308SNavdeep Parhar #include "reg_defs_t5.c" 8454912308SNavdeep Parhar #include "reg_defs_t6.c" 8554912308SNavdeep Parhar #include "reg_defs_t4vf.c" 8654912308SNavdeep Parhar 8754912308SNavdeep Parhar static void 8854912308SNavdeep Parhar usage(FILE *fp) 8954912308SNavdeep Parhar { 9054912308SNavdeep Parhar fprintf(fp, "Usage: %s <nexus> [operation]\n", progname); 9154912308SNavdeep Parhar fprintf(fp, 9254912308SNavdeep Parhar "\tclearstats <port> clear port statistics\n" 9354912308SNavdeep Parhar "\tcontext <type> <id> show an SGE context\n" 94f856f099SNavdeep Parhar "\tdumpstate <dump.bin> dump chip state\n" 9554912308SNavdeep Parhar "\tfilter <idx> [<param> <val>] ... set a filter\n" 9654912308SNavdeep Parhar "\tfilter <idx> delete|clear delete a filter\n" 9754912308SNavdeep Parhar "\tfilter list list all filters\n" 9854912308SNavdeep Parhar "\tfilter mode [<match>] ... get/set global filter mode\n" 9954912308SNavdeep Parhar "\ti2c <port> <devaddr> <addr> [<len>] read from i2c device\n" 1008f82718fSNavdeep Parhar "\tloadboot <bi.bin> [pf|offset <val>] install boot image\n" 1018f82718fSNavdeep Parhar "\tloadboot clear [pf|offset <val>] remove boot image\n" 1028f82718fSNavdeep Parhar "\tloadboot-cfg <bc.bin> install boot config\n" 1038f82718fSNavdeep Parhar "\tloadboot-cfg clear remove boot config\n" 10454912308SNavdeep Parhar "\tloadcfg <fw-config.txt> install configuration file\n" 10554912308SNavdeep Parhar "\tloadcfg clear remove configuration file\n" 10654912308SNavdeep Parhar "\tloadfw <fw-image.bin> install firmware\n" 10754912308SNavdeep Parhar "\tmemdump <addr> <len> dump a memory range\n" 10854912308SNavdeep Parhar "\tmodinfo <port> [raw] optics/cable information\n" 10954912308SNavdeep Parhar "\treg <address>[=<val>] read/write register\n" 11054912308SNavdeep Parhar "\treg64 <address>[=<val>] read/write 64 bit register\n" 11154912308SNavdeep Parhar "\tregdump [<module>] ... dump registers\n" 11254912308SNavdeep Parhar "\tsched-class params <param> <val> .. configure TX scheduler class\n" 11354912308SNavdeep Parhar "\tsched-queue <port> <queue> <class> bind NIC queues to TX Scheduling class\n" 11454912308SNavdeep Parhar "\tstdio interactive mode\n" 11554912308SNavdeep Parhar "\ttcb <tid> read TCB\n" 11654912308SNavdeep Parhar "\ttracer <idx> tx<n>|rx<n> set and enable a tracer\n" 11754912308SNavdeep Parhar "\ttracer <idx> disable|enable disable or enable a tracer\n" 11854912308SNavdeep Parhar "\ttracer list list all tracers\n" 11954912308SNavdeep Parhar ); 12054912308SNavdeep Parhar } 12154912308SNavdeep Parhar 12254912308SNavdeep Parhar static inline unsigned int 12354912308SNavdeep Parhar get_card_vers(unsigned int version) 12454912308SNavdeep Parhar { 12554912308SNavdeep Parhar return (version & 0x3ff); 12654912308SNavdeep Parhar } 12754912308SNavdeep Parhar 12854912308SNavdeep Parhar static int 12954912308SNavdeep Parhar real_doit(unsigned long cmd, void *data, const char *cmdstr) 13054912308SNavdeep Parhar { 13154912308SNavdeep Parhar static int fd = -1; 13254912308SNavdeep Parhar int rc = 0; 13354912308SNavdeep Parhar 13454912308SNavdeep Parhar if (fd == -1) { 13554912308SNavdeep Parhar char buf[64]; 13654912308SNavdeep Parhar 13754912308SNavdeep Parhar snprintf(buf, sizeof(buf), "/dev/%s", nexus); 13854912308SNavdeep Parhar if ((fd = open(buf, O_RDWR)) < 0) { 13954912308SNavdeep Parhar warn("open(%s)", nexus); 14054912308SNavdeep Parhar rc = errno; 14154912308SNavdeep Parhar return (rc); 14254912308SNavdeep Parhar } 14354912308SNavdeep Parhar chip_id = nexus[1] - '0'; 14454912308SNavdeep Parhar } 14554912308SNavdeep Parhar 14654912308SNavdeep Parhar rc = ioctl(fd, cmd, data); 14754912308SNavdeep Parhar if (rc < 0) { 14854912308SNavdeep Parhar warn("%s", cmdstr); 14954912308SNavdeep Parhar rc = errno; 15054912308SNavdeep Parhar } 15154912308SNavdeep Parhar 15254912308SNavdeep Parhar return (rc); 15354912308SNavdeep Parhar } 15454912308SNavdeep Parhar #define doit(x, y) real_doit(x, y, #x) 15554912308SNavdeep Parhar 15654912308SNavdeep Parhar static char * 15754912308SNavdeep Parhar str_to_number(const char *s, long *val, long long *vall) 15854912308SNavdeep Parhar { 15954912308SNavdeep Parhar char *p; 16054912308SNavdeep Parhar 16154912308SNavdeep Parhar if (vall) 16254912308SNavdeep Parhar *vall = strtoll(s, &p, 0); 16354912308SNavdeep Parhar else if (val) 16454912308SNavdeep Parhar *val = strtol(s, &p, 0); 16554912308SNavdeep Parhar else 16654912308SNavdeep Parhar p = NULL; 16754912308SNavdeep Parhar 16854912308SNavdeep Parhar return (p); 16954912308SNavdeep Parhar } 17054912308SNavdeep Parhar 17154912308SNavdeep Parhar static int 17254912308SNavdeep Parhar read_reg(long addr, int size, long long *val) 17354912308SNavdeep Parhar { 17454912308SNavdeep Parhar struct t4_reg reg; 17554912308SNavdeep Parhar int rc; 17654912308SNavdeep Parhar 17754912308SNavdeep Parhar reg.addr = (uint32_t) addr; 17854912308SNavdeep Parhar reg.size = (uint32_t) size; 17954912308SNavdeep Parhar reg.val = 0; 18054912308SNavdeep Parhar 18154912308SNavdeep Parhar rc = doit(CHELSIO_T4_GETREG, ®); 18254912308SNavdeep Parhar 18354912308SNavdeep Parhar *val = reg.val; 18454912308SNavdeep Parhar 18554912308SNavdeep Parhar return (rc); 18654912308SNavdeep Parhar } 18754912308SNavdeep Parhar 18854912308SNavdeep Parhar static int 18954912308SNavdeep Parhar write_reg(long addr, int size, long long val) 19054912308SNavdeep Parhar { 19154912308SNavdeep Parhar struct t4_reg reg; 19254912308SNavdeep Parhar 19354912308SNavdeep Parhar reg.addr = (uint32_t) addr; 19454912308SNavdeep Parhar reg.size = (uint32_t) size; 19554912308SNavdeep Parhar reg.val = (uint64_t) val; 19654912308SNavdeep Parhar 19754912308SNavdeep Parhar return doit(CHELSIO_T4_SETREG, ®); 19854912308SNavdeep Parhar } 19954912308SNavdeep Parhar 20054912308SNavdeep Parhar static int 20154912308SNavdeep Parhar register_io(int argc, const char *argv[], int size) 20254912308SNavdeep Parhar { 20354912308SNavdeep Parhar char *p, *v; 20454912308SNavdeep Parhar long addr; 20554912308SNavdeep Parhar long long val; 20654912308SNavdeep Parhar int w = 0, rc; 20754912308SNavdeep Parhar 20854912308SNavdeep Parhar if (argc == 1) { 20954912308SNavdeep Parhar /* <reg> OR <reg>=<value> */ 21054912308SNavdeep Parhar 21154912308SNavdeep Parhar p = str_to_number(argv[0], &addr, NULL); 21254912308SNavdeep Parhar if (*p) { 21354912308SNavdeep Parhar if (*p != '=') { 21454912308SNavdeep Parhar warnx("invalid register \"%s\"", argv[0]); 21554912308SNavdeep Parhar return (EINVAL); 21654912308SNavdeep Parhar } 21754912308SNavdeep Parhar 21854912308SNavdeep Parhar w = 1; 21954912308SNavdeep Parhar v = p + 1; 22054912308SNavdeep Parhar p = str_to_number(v, NULL, &val); 22154912308SNavdeep Parhar 22254912308SNavdeep Parhar if (*p) { 22354912308SNavdeep Parhar warnx("invalid value \"%s\"", v); 22454912308SNavdeep Parhar return (EINVAL); 22554912308SNavdeep Parhar } 22654912308SNavdeep Parhar } 22754912308SNavdeep Parhar 22854912308SNavdeep Parhar } else if (argc == 2) { 22954912308SNavdeep Parhar /* <reg> <value> */ 23054912308SNavdeep Parhar 23154912308SNavdeep Parhar w = 1; 23254912308SNavdeep Parhar 23354912308SNavdeep Parhar p = str_to_number(argv[0], &addr, NULL); 23454912308SNavdeep Parhar if (*p) { 23554912308SNavdeep Parhar warnx("invalid register \"%s\"", argv[0]); 23654912308SNavdeep Parhar return (EINVAL); 23754912308SNavdeep Parhar } 23854912308SNavdeep Parhar 23954912308SNavdeep Parhar p = str_to_number(argv[1], NULL, &val); 24054912308SNavdeep Parhar if (*p) { 24154912308SNavdeep Parhar warnx("invalid value \"%s\"", argv[1]); 24254912308SNavdeep Parhar return (EINVAL); 24354912308SNavdeep Parhar } 24454912308SNavdeep Parhar } else { 24554912308SNavdeep Parhar warnx("reg: invalid number of arguments (%d)", argc); 24654912308SNavdeep Parhar return (EINVAL); 24754912308SNavdeep Parhar } 24854912308SNavdeep Parhar 24954912308SNavdeep Parhar if (w) 25054912308SNavdeep Parhar rc = write_reg(addr, size, val); 25154912308SNavdeep Parhar else { 25254912308SNavdeep Parhar rc = read_reg(addr, size, &val); 25354912308SNavdeep Parhar if (rc == 0) 25454912308SNavdeep Parhar printf("0x%llx [%llu]\n", val, val); 25554912308SNavdeep Parhar } 25654912308SNavdeep Parhar 25754912308SNavdeep Parhar return (rc); 25854912308SNavdeep Parhar } 25954912308SNavdeep Parhar 26054912308SNavdeep Parhar static inline uint32_t 26154912308SNavdeep Parhar xtract(uint32_t val, int shift, int len) 26254912308SNavdeep Parhar { 26354912308SNavdeep Parhar return (val >> shift) & ((1 << len) - 1); 26454912308SNavdeep Parhar } 26554912308SNavdeep Parhar 26654912308SNavdeep Parhar static int 26754912308SNavdeep Parhar dump_block_regs(const struct reg_info *reg_array, const uint32_t *regs) 26854912308SNavdeep Parhar { 26954912308SNavdeep Parhar uint32_t reg_val = 0; 27054912308SNavdeep Parhar 27154912308SNavdeep Parhar for ( ; reg_array->name; ++reg_array) 27254912308SNavdeep Parhar if (!reg_array->len) { 27354912308SNavdeep Parhar reg_val = regs[reg_array->addr / 4]; 27454912308SNavdeep Parhar printf("[%#7x] %-47s %#-10x %u\n", reg_array->addr, 27554912308SNavdeep Parhar reg_array->name, reg_val, reg_val); 27654912308SNavdeep Parhar } else { 27754912308SNavdeep Parhar uint32_t v = xtract(reg_val, reg_array->addr, 27854912308SNavdeep Parhar reg_array->len); 27954912308SNavdeep Parhar 28054912308SNavdeep Parhar printf(" %*u:%u %-47s %#-10x %u\n", 28154912308SNavdeep Parhar reg_array->addr < 10 ? 3 : 2, 28254912308SNavdeep Parhar reg_array->addr + reg_array->len - 1, 28354912308SNavdeep Parhar reg_array->addr, reg_array->name, v, v); 28454912308SNavdeep Parhar } 28554912308SNavdeep Parhar 28654912308SNavdeep Parhar return (1); 28754912308SNavdeep Parhar } 28854912308SNavdeep Parhar 28954912308SNavdeep Parhar static int 29054912308SNavdeep Parhar dump_regs_table(int argc, const char *argv[], const uint32_t *regs, 29154912308SNavdeep Parhar const struct mod_regs *modtab, int nmodules) 29254912308SNavdeep Parhar { 29354912308SNavdeep Parhar int i, j, match; 29454912308SNavdeep Parhar 29554912308SNavdeep Parhar for (i = 0; i < argc; i++) { 29654912308SNavdeep Parhar for (j = 0; j < nmodules; j++) { 29754912308SNavdeep Parhar if (!strcmp(argv[i], modtab[j].name)) 29854912308SNavdeep Parhar break; 29954912308SNavdeep Parhar } 30054912308SNavdeep Parhar 30154912308SNavdeep Parhar if (j == nmodules) { 30254912308SNavdeep Parhar warnx("invalid register block \"%s\"", argv[i]); 30354912308SNavdeep Parhar fprintf(stderr, "\nAvailable blocks:"); 30454912308SNavdeep Parhar for ( ; nmodules; nmodules--, modtab++) 30554912308SNavdeep Parhar fprintf(stderr, " %s", modtab->name); 30654912308SNavdeep Parhar fprintf(stderr, "\n"); 30754912308SNavdeep Parhar return (EINVAL); 30854912308SNavdeep Parhar } 30954912308SNavdeep Parhar } 31054912308SNavdeep Parhar 31154912308SNavdeep Parhar for ( ; nmodules; nmodules--, modtab++) { 31254912308SNavdeep Parhar 31354912308SNavdeep Parhar match = argc == 0 ? 1 : 0; 31454912308SNavdeep Parhar for (i = 0; !match && i < argc; i++) { 31554912308SNavdeep Parhar if (!strcmp(argv[i], modtab->name)) 31654912308SNavdeep Parhar match = 1; 31754912308SNavdeep Parhar } 31854912308SNavdeep Parhar 31954912308SNavdeep Parhar if (match) 32054912308SNavdeep Parhar dump_block_regs(modtab->ri, regs); 32154912308SNavdeep Parhar } 32254912308SNavdeep Parhar 32354912308SNavdeep Parhar return (0); 32454912308SNavdeep Parhar } 32554912308SNavdeep Parhar 32654912308SNavdeep Parhar #define T4_MODREGS(name) { #name, t4_##name##_regs } 32754912308SNavdeep Parhar static int 32854912308SNavdeep Parhar dump_regs_t4(int argc, const char *argv[], const uint32_t *regs) 32954912308SNavdeep Parhar { 33054912308SNavdeep Parhar static struct mod_regs t4_mod[] = { 33154912308SNavdeep Parhar T4_MODREGS(sge), 33254912308SNavdeep Parhar { "pci", t4_pcie_regs }, 33354912308SNavdeep Parhar T4_MODREGS(dbg), 33454912308SNavdeep Parhar T4_MODREGS(mc), 33554912308SNavdeep Parhar T4_MODREGS(ma), 33654912308SNavdeep Parhar { "edc0", t4_edc_0_regs }, 33754912308SNavdeep Parhar { "edc1", t4_edc_1_regs }, 33854912308SNavdeep Parhar T4_MODREGS(cim), 33954912308SNavdeep Parhar T4_MODREGS(tp), 34054912308SNavdeep Parhar T4_MODREGS(ulp_rx), 34154912308SNavdeep Parhar T4_MODREGS(ulp_tx), 34254912308SNavdeep Parhar { "pmrx", t4_pm_rx_regs }, 34354912308SNavdeep Parhar { "pmtx", t4_pm_tx_regs }, 34454912308SNavdeep Parhar T4_MODREGS(mps), 34554912308SNavdeep Parhar { "cplsw", t4_cpl_switch_regs }, 34654912308SNavdeep Parhar T4_MODREGS(smb), 34754912308SNavdeep Parhar { "i2c", t4_i2cm_regs }, 34854912308SNavdeep Parhar T4_MODREGS(mi), 34954912308SNavdeep Parhar T4_MODREGS(uart), 35054912308SNavdeep Parhar T4_MODREGS(pmu), 35154912308SNavdeep Parhar T4_MODREGS(sf), 35254912308SNavdeep Parhar T4_MODREGS(pl), 35354912308SNavdeep Parhar T4_MODREGS(le), 35454912308SNavdeep Parhar T4_MODREGS(ncsi), 35554912308SNavdeep Parhar T4_MODREGS(xgmac) 35654912308SNavdeep Parhar }; 35754912308SNavdeep Parhar 35854912308SNavdeep Parhar return dump_regs_table(argc, argv, regs, t4_mod, nitems(t4_mod)); 35954912308SNavdeep Parhar } 36054912308SNavdeep Parhar #undef T4_MODREGS 36154912308SNavdeep Parhar 36254912308SNavdeep Parhar #define T5_MODREGS(name) { #name, t5_##name##_regs } 36354912308SNavdeep Parhar static int 36454912308SNavdeep Parhar dump_regs_t5(int argc, const char *argv[], const uint32_t *regs) 36554912308SNavdeep Parhar { 36654912308SNavdeep Parhar static struct mod_regs t5_mod[] = { 36754912308SNavdeep Parhar T5_MODREGS(sge), 36854912308SNavdeep Parhar { "pci", t5_pcie_regs }, 36954912308SNavdeep Parhar T5_MODREGS(dbg), 37054912308SNavdeep Parhar { "mc0", t5_mc_0_regs }, 37154912308SNavdeep Parhar { "mc1", t5_mc_1_regs }, 37254912308SNavdeep Parhar T5_MODREGS(ma), 37354912308SNavdeep Parhar { "edc0", t5_edc_t50_regs }, 37454912308SNavdeep Parhar { "edc1", t5_edc_t51_regs }, 37554912308SNavdeep Parhar T5_MODREGS(cim), 37654912308SNavdeep Parhar T5_MODREGS(tp), 37754912308SNavdeep Parhar { "ulprx", t5_ulp_rx_regs }, 37854912308SNavdeep Parhar { "ulptx", t5_ulp_tx_regs }, 37954912308SNavdeep Parhar { "pmrx", t5_pm_rx_regs }, 38054912308SNavdeep Parhar { "pmtx", t5_pm_tx_regs }, 38154912308SNavdeep Parhar T5_MODREGS(mps), 38254912308SNavdeep Parhar { "cplsw", t5_cpl_switch_regs }, 38354912308SNavdeep Parhar T5_MODREGS(smb), 38454912308SNavdeep Parhar { "i2c", t5_i2cm_regs }, 38554912308SNavdeep Parhar T5_MODREGS(mi), 38654912308SNavdeep Parhar T5_MODREGS(uart), 38754912308SNavdeep Parhar T5_MODREGS(pmu), 38854912308SNavdeep Parhar T5_MODREGS(sf), 38954912308SNavdeep Parhar T5_MODREGS(pl), 39054912308SNavdeep Parhar T5_MODREGS(le), 39154912308SNavdeep Parhar T5_MODREGS(ncsi), 39254912308SNavdeep Parhar T5_MODREGS(mac), 39354912308SNavdeep Parhar { "hma", t5_hma_t5_regs } 39454912308SNavdeep Parhar }; 39554912308SNavdeep Parhar 39654912308SNavdeep Parhar return dump_regs_table(argc, argv, regs, t5_mod, nitems(t5_mod)); 39754912308SNavdeep Parhar } 39854912308SNavdeep Parhar #undef T5_MODREGS 39954912308SNavdeep Parhar 40054912308SNavdeep Parhar #define T6_MODREGS(name) { #name, t6_##name##_regs } 40154912308SNavdeep Parhar static int 40254912308SNavdeep Parhar dump_regs_t6(int argc, const char *argv[], const uint32_t *regs) 40354912308SNavdeep Parhar { 40454912308SNavdeep Parhar static struct mod_regs t6_mod[] = { 40554912308SNavdeep Parhar T6_MODREGS(sge), 40654912308SNavdeep Parhar { "pci", t6_pcie_regs }, 40754912308SNavdeep Parhar T6_MODREGS(dbg), 40854912308SNavdeep Parhar { "mc0", t6_mc_0_regs }, 40954912308SNavdeep Parhar T6_MODREGS(ma), 41054912308SNavdeep Parhar { "edc0", t6_edc_t60_regs }, 41154912308SNavdeep Parhar { "edc1", t6_edc_t61_regs }, 41254912308SNavdeep Parhar T6_MODREGS(cim), 41354912308SNavdeep Parhar T6_MODREGS(tp), 41454912308SNavdeep Parhar { "ulprx", t6_ulp_rx_regs }, 41554912308SNavdeep Parhar { "ulptx", t6_ulp_tx_regs }, 41654912308SNavdeep Parhar { "pmrx", t6_pm_rx_regs }, 41754912308SNavdeep Parhar { "pmtx", t6_pm_tx_regs }, 41854912308SNavdeep Parhar T6_MODREGS(mps), 41954912308SNavdeep Parhar { "cplsw", t6_cpl_switch_regs }, 42054912308SNavdeep Parhar T6_MODREGS(smb), 42154912308SNavdeep Parhar { "i2c", t6_i2cm_regs }, 42254912308SNavdeep Parhar T6_MODREGS(mi), 42354912308SNavdeep Parhar T6_MODREGS(uart), 42454912308SNavdeep Parhar T6_MODREGS(pmu), 42554912308SNavdeep Parhar T6_MODREGS(sf), 42654912308SNavdeep Parhar T6_MODREGS(pl), 42754912308SNavdeep Parhar T6_MODREGS(le), 42854912308SNavdeep Parhar T6_MODREGS(ncsi), 42954912308SNavdeep Parhar T6_MODREGS(mac), 43054912308SNavdeep Parhar { "hma", t6_hma_t6_regs } 43154912308SNavdeep Parhar }; 43254912308SNavdeep Parhar 43354912308SNavdeep Parhar return dump_regs_table(argc, argv, regs, t6_mod, nitems(t6_mod)); 43454912308SNavdeep Parhar } 43554912308SNavdeep Parhar #undef T6_MODREGS 43654912308SNavdeep Parhar 43754912308SNavdeep Parhar static int 43854912308SNavdeep Parhar dump_regs_t4vf(int argc, const char *argv[], const uint32_t *regs) 43954912308SNavdeep Parhar { 44054912308SNavdeep Parhar static struct mod_regs t4vf_mod[] = { 44154912308SNavdeep Parhar { "sge", t4vf_sge_regs }, 44254912308SNavdeep Parhar { "mps", t4vf_mps_regs }, 44354912308SNavdeep Parhar { "pl", t4vf_pl_regs }, 44454912308SNavdeep Parhar { "mbdata", t4vf_mbdata_regs }, 44554912308SNavdeep Parhar { "cim", t4vf_cim_regs }, 44654912308SNavdeep Parhar }; 44754912308SNavdeep Parhar 44854912308SNavdeep Parhar return dump_regs_table(argc, argv, regs, t4vf_mod, nitems(t4vf_mod)); 44954912308SNavdeep Parhar } 45054912308SNavdeep Parhar 45154912308SNavdeep Parhar static int 45254912308SNavdeep Parhar dump_regs_t5vf(int argc, const char *argv[], const uint32_t *regs) 45354912308SNavdeep Parhar { 45454912308SNavdeep Parhar static struct mod_regs t5vf_mod[] = { 45554912308SNavdeep Parhar { "sge", t5vf_sge_regs }, 45654912308SNavdeep Parhar { "mps", t4vf_mps_regs }, 45754912308SNavdeep Parhar { "pl", t5vf_pl_regs }, 45854912308SNavdeep Parhar { "mbdata", t4vf_mbdata_regs }, 45954912308SNavdeep Parhar { "cim", t4vf_cim_regs }, 46054912308SNavdeep Parhar }; 46154912308SNavdeep Parhar 46254912308SNavdeep Parhar return dump_regs_table(argc, argv, regs, t5vf_mod, nitems(t5vf_mod)); 46354912308SNavdeep Parhar } 46454912308SNavdeep Parhar 46554912308SNavdeep Parhar static int 46654912308SNavdeep Parhar dump_regs_t6vf(int argc, const char *argv[], const uint32_t *regs) 46754912308SNavdeep Parhar { 46854912308SNavdeep Parhar static struct mod_regs t6vf_mod[] = { 46954912308SNavdeep Parhar { "sge", t5vf_sge_regs }, 47054912308SNavdeep Parhar { "mps", t4vf_mps_regs }, 47154912308SNavdeep Parhar { "pl", t6vf_pl_regs }, 47254912308SNavdeep Parhar { "mbdata", t4vf_mbdata_regs }, 47354912308SNavdeep Parhar { "cim", t4vf_cim_regs }, 47454912308SNavdeep Parhar }; 47554912308SNavdeep Parhar 47654912308SNavdeep Parhar return dump_regs_table(argc, argv, regs, t6vf_mod, nitems(t6vf_mod)); 47754912308SNavdeep Parhar } 47854912308SNavdeep Parhar 47954912308SNavdeep Parhar static int 48054912308SNavdeep Parhar dump_regs(int argc, const char *argv[]) 48154912308SNavdeep Parhar { 48254912308SNavdeep Parhar int vers, revision, rc; 48354912308SNavdeep Parhar struct t4_regdump regs; 48454912308SNavdeep Parhar uint32_t len; 48554912308SNavdeep Parhar 48654912308SNavdeep Parhar len = max(T4_REGDUMP_SIZE, T5_REGDUMP_SIZE); 48754912308SNavdeep Parhar regs.data = calloc(1, len); 48854912308SNavdeep Parhar if (regs.data == NULL) { 48954912308SNavdeep Parhar warnc(ENOMEM, "regdump"); 49054912308SNavdeep Parhar return (ENOMEM); 49154912308SNavdeep Parhar } 49254912308SNavdeep Parhar 49354912308SNavdeep Parhar regs.len = len; 49454912308SNavdeep Parhar rc = doit(CHELSIO_T4_REGDUMP, ®s); 49554912308SNavdeep Parhar if (rc != 0) 49654912308SNavdeep Parhar return (rc); 49754912308SNavdeep Parhar 49854912308SNavdeep Parhar vers = get_card_vers(regs.version); 49954912308SNavdeep Parhar revision = (regs.version >> 10) & 0x3f; 50054912308SNavdeep Parhar 50154912308SNavdeep Parhar if (vers == 4) { 50254912308SNavdeep Parhar if (revision == 0x3f) 50354912308SNavdeep Parhar rc = dump_regs_t4vf(argc, argv, regs.data); 50454912308SNavdeep Parhar else 50554912308SNavdeep Parhar rc = dump_regs_t4(argc, argv, regs.data); 50654912308SNavdeep Parhar } else if (vers == 5) { 50754912308SNavdeep Parhar if (revision == 0x3f) 50854912308SNavdeep Parhar rc = dump_regs_t5vf(argc, argv, regs.data); 50954912308SNavdeep Parhar else 51054912308SNavdeep Parhar rc = dump_regs_t5(argc, argv, regs.data); 51154912308SNavdeep Parhar } else if (vers == 6) { 51254912308SNavdeep Parhar if (revision == 0x3f) 51354912308SNavdeep Parhar rc = dump_regs_t6vf(argc, argv, regs.data); 51454912308SNavdeep Parhar else 51554912308SNavdeep Parhar rc = dump_regs_t6(argc, argv, regs.data); 51654912308SNavdeep Parhar } else { 51754912308SNavdeep Parhar warnx("%s (type %d, rev %d) is not a known card.", 51854912308SNavdeep Parhar nexus, vers, revision); 51954912308SNavdeep Parhar return (ENOTSUP); 52054912308SNavdeep Parhar } 52154912308SNavdeep Parhar 52254912308SNavdeep Parhar free(regs.data); 52354912308SNavdeep Parhar return (rc); 52454912308SNavdeep Parhar } 52554912308SNavdeep Parhar 52654912308SNavdeep Parhar static void 52754912308SNavdeep Parhar do_show_info_header(uint32_t mode) 52854912308SNavdeep Parhar { 52954912308SNavdeep Parhar uint32_t i; 53054912308SNavdeep Parhar 53154912308SNavdeep Parhar printf("%4s %8s", "Idx", "Hits"); 53254912308SNavdeep Parhar for (i = T4_FILTER_FCoE; i <= T4_FILTER_IP_FRAGMENT; i <<= 1) { 53354912308SNavdeep Parhar switch (mode & i) { 53454912308SNavdeep Parhar case T4_FILTER_FCoE: 53554912308SNavdeep Parhar printf(" FCoE"); 53654912308SNavdeep Parhar break; 53754912308SNavdeep Parhar 53854912308SNavdeep Parhar case T4_FILTER_PORT: 53954912308SNavdeep Parhar printf(" Port"); 54054912308SNavdeep Parhar break; 54154912308SNavdeep Parhar 54254912308SNavdeep Parhar case T4_FILTER_VNIC: 54354912308SNavdeep Parhar if (mode & T4_FILTER_IC_VNIC) 54454912308SNavdeep Parhar printf(" VFvld:PF:VF"); 54554912308SNavdeep Parhar else 54654912308SNavdeep Parhar printf(" vld:oVLAN"); 54754912308SNavdeep Parhar break; 54854912308SNavdeep Parhar 54954912308SNavdeep Parhar case T4_FILTER_VLAN: 55054912308SNavdeep Parhar printf(" vld:VLAN"); 55154912308SNavdeep Parhar break; 55254912308SNavdeep Parhar 55354912308SNavdeep Parhar case T4_FILTER_IP_TOS: 55454912308SNavdeep Parhar printf(" TOS"); 55554912308SNavdeep Parhar break; 55654912308SNavdeep Parhar 55754912308SNavdeep Parhar case T4_FILTER_IP_PROTO: 55854912308SNavdeep Parhar printf(" Prot"); 55954912308SNavdeep Parhar break; 56054912308SNavdeep Parhar 56154912308SNavdeep Parhar case T4_FILTER_ETH_TYPE: 56254912308SNavdeep Parhar printf(" EthType"); 56354912308SNavdeep Parhar break; 56454912308SNavdeep Parhar 56554912308SNavdeep Parhar case T4_FILTER_MAC_IDX: 56654912308SNavdeep Parhar printf(" MACIdx"); 56754912308SNavdeep Parhar break; 56854912308SNavdeep Parhar 56954912308SNavdeep Parhar case T4_FILTER_MPS_HIT_TYPE: 57054912308SNavdeep Parhar printf(" MPS"); 57154912308SNavdeep Parhar break; 57254912308SNavdeep Parhar 57354912308SNavdeep Parhar case T4_FILTER_IP_FRAGMENT: 57454912308SNavdeep Parhar printf(" Frag"); 57554912308SNavdeep Parhar break; 57654912308SNavdeep Parhar 57754912308SNavdeep Parhar default: 57854912308SNavdeep Parhar /* compressed filter field not enabled */ 57954912308SNavdeep Parhar break; 58054912308SNavdeep Parhar } 58154912308SNavdeep Parhar } 58254912308SNavdeep Parhar printf(" %20s %20s %9s %9s %s\n", 58354912308SNavdeep Parhar "DIP", "SIP", "DPORT", "SPORT", "Action"); 58454912308SNavdeep Parhar } 58554912308SNavdeep Parhar 58654912308SNavdeep Parhar /* 58754912308SNavdeep Parhar * Parse an argument sub-vector as a { <parameter name> <value>[:<mask>] } 58854912308SNavdeep Parhar * ordered tuple. If the parameter name in the argument sub-vector does not 58954912308SNavdeep Parhar * match the passed in parameter name, then a zero is returned for the 59054912308SNavdeep Parhar * function and no parsing is performed. If there is a match, then the value 59154912308SNavdeep Parhar * and optional mask are parsed and returned in the provided return value 59254912308SNavdeep Parhar * pointers. If no optional mask is specified, then a default mask of all 1s 59354912308SNavdeep Parhar * will be returned. 59454912308SNavdeep Parhar * 59554912308SNavdeep Parhar * An error in parsing the value[:mask] will result in an error message and 59654912308SNavdeep Parhar * program termination. 59754912308SNavdeep Parhar */ 59854912308SNavdeep Parhar static int 59954912308SNavdeep Parhar parse_val_mask(const char *param, const char *args[], uint32_t *val, 60054912308SNavdeep Parhar uint32_t *mask) 60154912308SNavdeep Parhar { 60254912308SNavdeep Parhar char *p; 60354912308SNavdeep Parhar 60454912308SNavdeep Parhar if (strcmp(param, args[0]) != 0) 60554912308SNavdeep Parhar return (EINVAL); 60654912308SNavdeep Parhar 60754912308SNavdeep Parhar *val = strtoul(args[1], &p, 0); 60854912308SNavdeep Parhar if (p > args[1]) { 60954912308SNavdeep Parhar if (p[0] == 0) { 61054912308SNavdeep Parhar *mask = ~0; 61154912308SNavdeep Parhar return (0); 61254912308SNavdeep Parhar } 61354912308SNavdeep Parhar 61454912308SNavdeep Parhar if (p[0] == ':' && p[1] != 0) { 61554912308SNavdeep Parhar *mask = strtoul(p+1, &p, 0); 61654912308SNavdeep Parhar if (p[0] == 0) 61754912308SNavdeep Parhar return (0); 61854912308SNavdeep Parhar } 61954912308SNavdeep Parhar } 62054912308SNavdeep Parhar 62154912308SNavdeep Parhar warnx("parameter \"%s\" has bad \"value[:mask]\" %s", 62254912308SNavdeep Parhar args[0], args[1]); 62354912308SNavdeep Parhar 62454912308SNavdeep Parhar return (EINVAL); 62554912308SNavdeep Parhar } 62654912308SNavdeep Parhar 62754912308SNavdeep Parhar /* 62854912308SNavdeep Parhar * Parse an argument sub-vector as a { <parameter name> <addr>[/<mask>] } 62954912308SNavdeep Parhar * ordered tuple. If the parameter name in the argument sub-vector does not 63054912308SNavdeep Parhar * match the passed in parameter name, then a zero is returned for the 63154912308SNavdeep Parhar * function and no parsing is performed. If there is a match, then the value 63254912308SNavdeep Parhar * and optional mask are parsed and returned in the provided return value 63354912308SNavdeep Parhar * pointers. If no optional mask is specified, then a default mask of all 1s 63454912308SNavdeep Parhar * will be returned. 63554912308SNavdeep Parhar * 63654912308SNavdeep Parhar * The value return parameter "afp" is used to specify the expected address 63754912308SNavdeep Parhar * family -- IPv4 or IPv6 -- of the address[/mask] and return its actual 63854912308SNavdeep Parhar * format. A passed in value of AF_UNSPEC indicates that either IPv4 or IPv6 63954912308SNavdeep Parhar * is acceptable; AF_INET means that only IPv4 addresses are acceptable; and 64054912308SNavdeep Parhar * AF_INET6 means that only IPv6 are acceptable. AF_INET is returned for IPv4 64154912308SNavdeep Parhar * and AF_INET6 for IPv6 addresses, respectively. IPv4 address/mask pairs are 64254912308SNavdeep Parhar * returned in the first four bytes of the address and mask return values with 64354912308SNavdeep Parhar * the address A.B.C.D returned with { A, B, C, D } returned in addresses { 0, 64454912308SNavdeep Parhar * 1, 2, 3}, respectively. 64554912308SNavdeep Parhar * 64654912308SNavdeep Parhar * An error in parsing the value[:mask] will result in an error message and 64754912308SNavdeep Parhar * program termination. 64854912308SNavdeep Parhar */ 64954912308SNavdeep Parhar static int 65054912308SNavdeep Parhar parse_ipaddr(const char *param, const char *args[], int *afp, uint8_t addr[], 65154912308SNavdeep Parhar uint8_t mask[]) 65254912308SNavdeep Parhar { 65354912308SNavdeep Parhar const char *colon, *afn; 65454912308SNavdeep Parhar char *slash; 65554912308SNavdeep Parhar uint8_t *m; 65654912308SNavdeep Parhar int af, ret; 65754912308SNavdeep Parhar unsigned int masksize; 65854912308SNavdeep Parhar 65954912308SNavdeep Parhar /* 66054912308SNavdeep Parhar * Is this our parameter? 66154912308SNavdeep Parhar */ 66254912308SNavdeep Parhar if (strcmp(param, args[0]) != 0) 66354912308SNavdeep Parhar return (EINVAL); 66454912308SNavdeep Parhar 66554912308SNavdeep Parhar /* 66654912308SNavdeep Parhar * Fundamental IPv4 versus IPv6 selection. 66754912308SNavdeep Parhar */ 66854912308SNavdeep Parhar colon = strchr(args[1], ':'); 66954912308SNavdeep Parhar if (!colon) { 67054912308SNavdeep Parhar afn = "IPv4"; 67154912308SNavdeep Parhar af = AF_INET; 67254912308SNavdeep Parhar masksize = 32; 67354912308SNavdeep Parhar } else { 67454912308SNavdeep Parhar afn = "IPv6"; 67554912308SNavdeep Parhar af = AF_INET6; 67654912308SNavdeep Parhar masksize = 128; 67754912308SNavdeep Parhar } 67854912308SNavdeep Parhar if (*afp == AF_UNSPEC) 67954912308SNavdeep Parhar *afp = af; 68054912308SNavdeep Parhar else if (*afp != af) { 68154912308SNavdeep Parhar warnx("address %s is not of expected family %s", 68254912308SNavdeep Parhar args[1], *afp == AF_INET ? "IP" : "IPv6"); 68354912308SNavdeep Parhar return (EINVAL); 68454912308SNavdeep Parhar } 68554912308SNavdeep Parhar 68654912308SNavdeep Parhar /* 68754912308SNavdeep Parhar * Parse address (temporarily stripping off any "/mask" 68854912308SNavdeep Parhar * specification). 68954912308SNavdeep Parhar */ 69054912308SNavdeep Parhar slash = strchr(args[1], '/'); 69154912308SNavdeep Parhar if (slash) 69254912308SNavdeep Parhar *slash = 0; 69354912308SNavdeep Parhar ret = inet_pton(af, args[1], addr); 69454912308SNavdeep Parhar if (slash) 69554912308SNavdeep Parhar *slash = '/'; 69654912308SNavdeep Parhar if (ret <= 0) { 69754912308SNavdeep Parhar warnx("Cannot parse %s %s address %s", param, afn, args[1]); 69854912308SNavdeep Parhar return (EINVAL); 69954912308SNavdeep Parhar } 70054912308SNavdeep Parhar 70154912308SNavdeep Parhar /* 70254912308SNavdeep Parhar * Parse optional mask specification. 70354912308SNavdeep Parhar */ 70454912308SNavdeep Parhar if (slash) { 70554912308SNavdeep Parhar char *p; 70654912308SNavdeep Parhar unsigned int prefix = strtoul(slash + 1, &p, 10); 70754912308SNavdeep Parhar 70854912308SNavdeep Parhar if (p == slash + 1) { 70954912308SNavdeep Parhar warnx("missing address prefix for %s", param); 71054912308SNavdeep Parhar return (EINVAL); 71154912308SNavdeep Parhar } 71254912308SNavdeep Parhar if (*p) { 71354912308SNavdeep Parhar warnx("%s is not a valid address prefix", slash + 1); 71454912308SNavdeep Parhar return (EINVAL); 71554912308SNavdeep Parhar } 71654912308SNavdeep Parhar if (prefix > masksize) { 71754912308SNavdeep Parhar warnx("prefix %u is too long for an %s address", 71854912308SNavdeep Parhar prefix, afn); 71954912308SNavdeep Parhar return (EINVAL); 72054912308SNavdeep Parhar } 72154912308SNavdeep Parhar memset(mask, 0, masksize / 8); 72254912308SNavdeep Parhar masksize = prefix; 72354912308SNavdeep Parhar } 72454912308SNavdeep Parhar 72554912308SNavdeep Parhar /* 72654912308SNavdeep Parhar * Fill in mask. 72754912308SNavdeep Parhar */ 72854912308SNavdeep Parhar for (m = mask; masksize >= 8; m++, masksize -= 8) 72954912308SNavdeep Parhar *m = ~0; 73054912308SNavdeep Parhar if (masksize) 73154912308SNavdeep Parhar *m = ~0 << (8 - masksize); 73254912308SNavdeep Parhar 73354912308SNavdeep Parhar return (0); 73454912308SNavdeep Parhar } 73554912308SNavdeep Parhar 73654912308SNavdeep Parhar /* 73754912308SNavdeep Parhar * Parse an argument sub-vector as a { <parameter name> <value> } ordered 73854912308SNavdeep Parhar * tuple. If the parameter name in the argument sub-vector does not match the 73954912308SNavdeep Parhar * passed in parameter name, then a zero is returned for the function and no 74054912308SNavdeep Parhar * parsing is performed. If there is a match, then the value is parsed and 74154912308SNavdeep Parhar * returned in the provided return value pointer. 74254912308SNavdeep Parhar */ 74354912308SNavdeep Parhar static int 74454912308SNavdeep Parhar parse_val(const char *param, const char *args[], uint32_t *val) 74554912308SNavdeep Parhar { 74654912308SNavdeep Parhar char *p; 74754912308SNavdeep Parhar 74854912308SNavdeep Parhar if (strcmp(param, args[0]) != 0) 74954912308SNavdeep Parhar return (EINVAL); 75054912308SNavdeep Parhar 75154912308SNavdeep Parhar *val = strtoul(args[1], &p, 0); 75254912308SNavdeep Parhar if (p > args[1] && p[0] == 0) 75354912308SNavdeep Parhar return (0); 75454912308SNavdeep Parhar 75554912308SNavdeep Parhar warnx("parameter \"%s\" has bad \"value\" %s", args[0], args[1]); 75654912308SNavdeep Parhar return (EINVAL); 75754912308SNavdeep Parhar } 75854912308SNavdeep Parhar 75954912308SNavdeep Parhar static void 76054912308SNavdeep Parhar filters_show_ipaddr(int type, uint8_t *addr, uint8_t *addrm) 76154912308SNavdeep Parhar { 76254912308SNavdeep Parhar int noctets, octet; 76354912308SNavdeep Parhar 76454912308SNavdeep Parhar printf(" "); 76554912308SNavdeep Parhar if (type == 0) { 76654912308SNavdeep Parhar noctets = 4; 76754912308SNavdeep Parhar printf("%3s", " "); 76854912308SNavdeep Parhar } else 76954912308SNavdeep Parhar noctets = 16; 77054912308SNavdeep Parhar 77154912308SNavdeep Parhar for (octet = 0; octet < noctets; octet++) 77254912308SNavdeep Parhar printf("%02x", addr[octet]); 77354912308SNavdeep Parhar printf("/"); 77454912308SNavdeep Parhar for (octet = 0; octet < noctets; octet++) 77554912308SNavdeep Parhar printf("%02x", addrm[octet]); 77654912308SNavdeep Parhar } 77754912308SNavdeep Parhar 77854912308SNavdeep Parhar static void 77954912308SNavdeep Parhar do_show_one_filter_info(struct t4_filter *t, uint32_t mode) 78054912308SNavdeep Parhar { 78154912308SNavdeep Parhar uint32_t i; 78254912308SNavdeep Parhar 78354912308SNavdeep Parhar printf("%4d", t->idx); 78454912308SNavdeep Parhar if (t->hits == UINT64_MAX) 78554912308SNavdeep Parhar printf(" %8s", "-"); 78654912308SNavdeep Parhar else 78754912308SNavdeep Parhar printf(" %8ju", t->hits); 78854912308SNavdeep Parhar 78954912308SNavdeep Parhar /* 79054912308SNavdeep Parhar * Compressed header portion of filter. 79154912308SNavdeep Parhar */ 79254912308SNavdeep Parhar for (i = T4_FILTER_FCoE; i <= T4_FILTER_IP_FRAGMENT; i <<= 1) { 79354912308SNavdeep Parhar switch (mode & i) { 79454912308SNavdeep Parhar case T4_FILTER_FCoE: 79554912308SNavdeep Parhar printf(" %1d/%1d", t->fs.val.fcoe, t->fs.mask.fcoe); 79654912308SNavdeep Parhar break; 79754912308SNavdeep Parhar 79854912308SNavdeep Parhar case T4_FILTER_PORT: 79954912308SNavdeep Parhar printf(" %1d/%1d", t->fs.val.iport, t->fs.mask.iport); 80054912308SNavdeep Parhar break; 80154912308SNavdeep Parhar 80254912308SNavdeep Parhar case T4_FILTER_VNIC: 80354912308SNavdeep Parhar if (mode & T4_FILTER_IC_VNIC) { 80454912308SNavdeep Parhar printf(" %1d:%1x:%02x/%1d:%1x:%02x", 80554912308SNavdeep Parhar t->fs.val.pfvf_vld, 80654912308SNavdeep Parhar (t->fs.val.vnic >> 13) & 0x7, 80754912308SNavdeep Parhar t->fs.val.vnic & 0x1fff, 80854912308SNavdeep Parhar t->fs.mask.pfvf_vld, 80954912308SNavdeep Parhar (t->fs.mask.vnic >> 13) & 0x7, 81054912308SNavdeep Parhar t->fs.mask.vnic & 0x1fff); 81154912308SNavdeep Parhar } else { 81254912308SNavdeep Parhar printf(" %1d:%04x/%1d:%04x", 81354912308SNavdeep Parhar t->fs.val.ovlan_vld, t->fs.val.vnic, 81454912308SNavdeep Parhar t->fs.mask.ovlan_vld, t->fs.mask.vnic); 81554912308SNavdeep Parhar } 81654912308SNavdeep Parhar break; 81754912308SNavdeep Parhar 81854912308SNavdeep Parhar case T4_FILTER_VLAN: 81954912308SNavdeep Parhar printf(" %1d:%04x/%1d:%04x", 82054912308SNavdeep Parhar t->fs.val.vlan_vld, t->fs.val.vlan, 82154912308SNavdeep Parhar t->fs.mask.vlan_vld, t->fs.mask.vlan); 82254912308SNavdeep Parhar break; 82354912308SNavdeep Parhar 82454912308SNavdeep Parhar case T4_FILTER_IP_TOS: 82554912308SNavdeep Parhar printf(" %02x/%02x", t->fs.val.tos, t->fs.mask.tos); 82654912308SNavdeep Parhar break; 82754912308SNavdeep Parhar 82854912308SNavdeep Parhar case T4_FILTER_IP_PROTO: 82954912308SNavdeep Parhar printf(" %02x/%02x", t->fs.val.proto, t->fs.mask.proto); 83054912308SNavdeep Parhar break; 83154912308SNavdeep Parhar 83254912308SNavdeep Parhar case T4_FILTER_ETH_TYPE: 83354912308SNavdeep Parhar printf(" %04x/%04x", t->fs.val.ethtype, 83454912308SNavdeep Parhar t->fs.mask.ethtype); 83554912308SNavdeep Parhar break; 83654912308SNavdeep Parhar 83754912308SNavdeep Parhar case T4_FILTER_MAC_IDX: 83854912308SNavdeep Parhar printf(" %03x/%03x", t->fs.val.macidx, 83954912308SNavdeep Parhar t->fs.mask.macidx); 84054912308SNavdeep Parhar break; 84154912308SNavdeep Parhar 84254912308SNavdeep Parhar case T4_FILTER_MPS_HIT_TYPE: 84354912308SNavdeep Parhar printf(" %1x/%1x", t->fs.val.matchtype, 84454912308SNavdeep Parhar t->fs.mask.matchtype); 84554912308SNavdeep Parhar break; 84654912308SNavdeep Parhar 84754912308SNavdeep Parhar case T4_FILTER_IP_FRAGMENT: 84854912308SNavdeep Parhar printf(" %1d/%1d", t->fs.val.frag, t->fs.mask.frag); 84954912308SNavdeep Parhar break; 85054912308SNavdeep Parhar 85154912308SNavdeep Parhar default: 85254912308SNavdeep Parhar /* compressed filter field not enabled */ 85354912308SNavdeep Parhar break; 85454912308SNavdeep Parhar } 85554912308SNavdeep Parhar } 85654912308SNavdeep Parhar 85754912308SNavdeep Parhar /* 85854912308SNavdeep Parhar * Fixed portion of filter. 85954912308SNavdeep Parhar */ 86054912308SNavdeep Parhar filters_show_ipaddr(t->fs.type, t->fs.val.dip, t->fs.mask.dip); 86154912308SNavdeep Parhar filters_show_ipaddr(t->fs.type, t->fs.val.sip, t->fs.mask.sip); 86254912308SNavdeep Parhar printf(" %04x/%04x %04x/%04x", 86354912308SNavdeep Parhar t->fs.val.dport, t->fs.mask.dport, 86454912308SNavdeep Parhar t->fs.val.sport, t->fs.mask.sport); 86554912308SNavdeep Parhar 86654912308SNavdeep Parhar /* 86754912308SNavdeep Parhar * Variable length filter action. 86854912308SNavdeep Parhar */ 86954912308SNavdeep Parhar if (t->fs.action == FILTER_DROP) 87054912308SNavdeep Parhar printf(" Drop"); 87154912308SNavdeep Parhar else if (t->fs.action == FILTER_SWITCH) { 87254912308SNavdeep Parhar printf(" Switch: port=%d", t->fs.eport); 87354912308SNavdeep Parhar if (t->fs.newdmac) 87454912308SNavdeep Parhar printf( 87554912308SNavdeep Parhar ", dmac=%02x:%02x:%02x:%02x:%02x:%02x " 87654912308SNavdeep Parhar ", l2tidx=%d", 87754912308SNavdeep Parhar t->fs.dmac[0], t->fs.dmac[1], 87854912308SNavdeep Parhar t->fs.dmac[2], t->fs.dmac[3], 87954912308SNavdeep Parhar t->fs.dmac[4], t->fs.dmac[5], 88054912308SNavdeep Parhar t->l2tidx); 88154912308SNavdeep Parhar if (t->fs.newsmac) 88254912308SNavdeep Parhar printf( 88354912308SNavdeep Parhar ", smac=%02x:%02x:%02x:%02x:%02x:%02x " 88454912308SNavdeep Parhar ", smtidx=%d", 88554912308SNavdeep Parhar t->fs.smac[0], t->fs.smac[1], 88654912308SNavdeep Parhar t->fs.smac[2], t->fs.smac[3], 88754912308SNavdeep Parhar t->fs.smac[4], t->fs.smac[5], 88854912308SNavdeep Parhar t->smtidx); 88954912308SNavdeep Parhar if (t->fs.newvlan == VLAN_REMOVE) 89054912308SNavdeep Parhar printf(", vlan=none"); 89154912308SNavdeep Parhar else if (t->fs.newvlan == VLAN_INSERT) 89254912308SNavdeep Parhar printf(", vlan=insert(%x)", t->fs.vlan); 89354912308SNavdeep Parhar else if (t->fs.newvlan == VLAN_REWRITE) 89454912308SNavdeep Parhar printf(", vlan=rewrite(%x)", t->fs.vlan); 89554912308SNavdeep Parhar } else { 89654912308SNavdeep Parhar printf(" Pass: Q="); 89754912308SNavdeep Parhar if (t->fs.dirsteer == 0) { 89854912308SNavdeep Parhar printf("RSS"); 89954912308SNavdeep Parhar if (t->fs.maskhash) 90054912308SNavdeep Parhar printf("(TCB=hash)"); 90154912308SNavdeep Parhar } else { 90254912308SNavdeep Parhar printf("%d", t->fs.iq); 90354912308SNavdeep Parhar if (t->fs.dirsteerhash == 0) 90454912308SNavdeep Parhar printf("(QID)"); 90554912308SNavdeep Parhar else 90654912308SNavdeep Parhar printf("(hash)"); 90754912308SNavdeep Parhar } 90854912308SNavdeep Parhar } 90954912308SNavdeep Parhar if (t->fs.prio) 91054912308SNavdeep Parhar printf(" Prio"); 91154912308SNavdeep Parhar if (t->fs.rpttid) 91254912308SNavdeep Parhar printf(" RptTID"); 91354912308SNavdeep Parhar printf("\n"); 91454912308SNavdeep Parhar } 91554912308SNavdeep Parhar 91654912308SNavdeep Parhar static int 91754912308SNavdeep Parhar show_filters(void) 91854912308SNavdeep Parhar { 91954912308SNavdeep Parhar uint32_t mode = 0, header = 0; 92054912308SNavdeep Parhar struct t4_filter t; 92154912308SNavdeep Parhar int rc; 92254912308SNavdeep Parhar 92354912308SNavdeep Parhar /* Get the global filter mode first */ 92454912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_FILTER_MODE, &mode); 92554912308SNavdeep Parhar if (rc != 0) 92654912308SNavdeep Parhar return (rc); 92754912308SNavdeep Parhar 92854912308SNavdeep Parhar t.idx = 0; 92954912308SNavdeep Parhar for (t.idx = 0; ; t.idx++) { 93054912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_FILTER, &t); 93154912308SNavdeep Parhar if (rc != 0 || t.idx == 0xffffffff) 93254912308SNavdeep Parhar break; 93354912308SNavdeep Parhar 93454912308SNavdeep Parhar if (!header) { 93554912308SNavdeep Parhar do_show_info_header(mode); 93654912308SNavdeep Parhar header = 1; 93754912308SNavdeep Parhar } 93854912308SNavdeep Parhar do_show_one_filter_info(&t, mode); 93954912308SNavdeep Parhar }; 94054912308SNavdeep Parhar 94154912308SNavdeep Parhar return (rc); 94254912308SNavdeep Parhar } 94354912308SNavdeep Parhar 94454912308SNavdeep Parhar static int 94554912308SNavdeep Parhar get_filter_mode(void) 94654912308SNavdeep Parhar { 94754912308SNavdeep Parhar uint32_t mode = 0; 94854912308SNavdeep Parhar int rc; 94954912308SNavdeep Parhar 95054912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_FILTER_MODE, &mode); 95154912308SNavdeep Parhar if (rc != 0) 95254912308SNavdeep Parhar return (rc); 95354912308SNavdeep Parhar 95454912308SNavdeep Parhar if (mode & T4_FILTER_IPv4) 95554912308SNavdeep Parhar printf("ipv4 "); 95654912308SNavdeep Parhar 95754912308SNavdeep Parhar if (mode & T4_FILTER_IPv6) 95854912308SNavdeep Parhar printf("ipv6 "); 95954912308SNavdeep Parhar 96054912308SNavdeep Parhar if (mode & T4_FILTER_IP_SADDR) 96154912308SNavdeep Parhar printf("sip "); 96254912308SNavdeep Parhar 96354912308SNavdeep Parhar if (mode & T4_FILTER_IP_DADDR) 96454912308SNavdeep Parhar printf("dip "); 96554912308SNavdeep Parhar 96654912308SNavdeep Parhar if (mode & T4_FILTER_IP_SPORT) 96754912308SNavdeep Parhar printf("sport "); 96854912308SNavdeep Parhar 96954912308SNavdeep Parhar if (mode & T4_FILTER_IP_DPORT) 97054912308SNavdeep Parhar printf("dport "); 97154912308SNavdeep Parhar 97254912308SNavdeep Parhar if (mode & T4_FILTER_IP_FRAGMENT) 97354912308SNavdeep Parhar printf("frag "); 97454912308SNavdeep Parhar 97554912308SNavdeep Parhar if (mode & T4_FILTER_MPS_HIT_TYPE) 97654912308SNavdeep Parhar printf("matchtype "); 97754912308SNavdeep Parhar 97854912308SNavdeep Parhar if (mode & T4_FILTER_MAC_IDX) 97954912308SNavdeep Parhar printf("macidx "); 98054912308SNavdeep Parhar 98154912308SNavdeep Parhar if (mode & T4_FILTER_ETH_TYPE) 98254912308SNavdeep Parhar printf("ethtype "); 98354912308SNavdeep Parhar 98454912308SNavdeep Parhar if (mode & T4_FILTER_IP_PROTO) 98554912308SNavdeep Parhar printf("proto "); 98654912308SNavdeep Parhar 98754912308SNavdeep Parhar if (mode & T4_FILTER_IP_TOS) 98854912308SNavdeep Parhar printf("tos "); 98954912308SNavdeep Parhar 99054912308SNavdeep Parhar if (mode & T4_FILTER_VLAN) 99154912308SNavdeep Parhar printf("vlan "); 99254912308SNavdeep Parhar 99354912308SNavdeep Parhar if (mode & T4_FILTER_VNIC) { 99454912308SNavdeep Parhar if (mode & T4_FILTER_IC_VNIC) 99554912308SNavdeep Parhar printf("vnic_id "); 99654912308SNavdeep Parhar else 99754912308SNavdeep Parhar printf("ovlan "); 99854912308SNavdeep Parhar } 99954912308SNavdeep Parhar 100054912308SNavdeep Parhar if (mode & T4_FILTER_PORT) 100154912308SNavdeep Parhar printf("iport "); 100254912308SNavdeep Parhar 100354912308SNavdeep Parhar if (mode & T4_FILTER_FCoE) 100454912308SNavdeep Parhar printf("fcoe "); 100554912308SNavdeep Parhar 100654912308SNavdeep Parhar printf("\n"); 100754912308SNavdeep Parhar 100854912308SNavdeep Parhar return (0); 100954912308SNavdeep Parhar } 101054912308SNavdeep Parhar 101154912308SNavdeep Parhar static int 101254912308SNavdeep Parhar set_filter_mode(int argc, const char *argv[]) 101354912308SNavdeep Parhar { 101454912308SNavdeep Parhar uint32_t mode = 0; 101554912308SNavdeep Parhar int vnic = 0, ovlan = 0; 101654912308SNavdeep Parhar 101754912308SNavdeep Parhar for (; argc; argc--, argv++) { 101854912308SNavdeep Parhar if (!strcmp(argv[0], "frag")) 101954912308SNavdeep Parhar mode |= T4_FILTER_IP_FRAGMENT; 102054912308SNavdeep Parhar 102154912308SNavdeep Parhar if (!strcmp(argv[0], "matchtype")) 102254912308SNavdeep Parhar mode |= T4_FILTER_MPS_HIT_TYPE; 102354912308SNavdeep Parhar 102454912308SNavdeep Parhar if (!strcmp(argv[0], "macidx")) 102554912308SNavdeep Parhar mode |= T4_FILTER_MAC_IDX; 102654912308SNavdeep Parhar 102754912308SNavdeep Parhar if (!strcmp(argv[0], "ethtype")) 102854912308SNavdeep Parhar mode |= T4_FILTER_ETH_TYPE; 102954912308SNavdeep Parhar 103054912308SNavdeep Parhar if (!strcmp(argv[0], "proto")) 103154912308SNavdeep Parhar mode |= T4_FILTER_IP_PROTO; 103254912308SNavdeep Parhar 103354912308SNavdeep Parhar if (!strcmp(argv[0], "tos")) 103454912308SNavdeep Parhar mode |= T4_FILTER_IP_TOS; 103554912308SNavdeep Parhar 103654912308SNavdeep Parhar if (!strcmp(argv[0], "vlan")) 103754912308SNavdeep Parhar mode |= T4_FILTER_VLAN; 103854912308SNavdeep Parhar 103954912308SNavdeep Parhar if (!strcmp(argv[0], "ovlan")) { 104054912308SNavdeep Parhar mode |= T4_FILTER_VNIC; 104154912308SNavdeep Parhar ovlan++; 104254912308SNavdeep Parhar } 104354912308SNavdeep Parhar 104454912308SNavdeep Parhar if (!strcmp(argv[0], "vnic_id")) { 104554912308SNavdeep Parhar mode |= T4_FILTER_VNIC; 104654912308SNavdeep Parhar mode |= T4_FILTER_IC_VNIC; 104754912308SNavdeep Parhar vnic++; 104854912308SNavdeep Parhar } 104954912308SNavdeep Parhar 105054912308SNavdeep Parhar if (!strcmp(argv[0], "iport")) 105154912308SNavdeep Parhar mode |= T4_FILTER_PORT; 105254912308SNavdeep Parhar 105354912308SNavdeep Parhar if (!strcmp(argv[0], "fcoe")) 105454912308SNavdeep Parhar mode |= T4_FILTER_FCoE; 105554912308SNavdeep Parhar } 105654912308SNavdeep Parhar 105754912308SNavdeep Parhar if (vnic > 0 && ovlan > 0) { 105854912308SNavdeep Parhar warnx("\"vnic_id\" and \"ovlan\" are mutually exclusive."); 105954912308SNavdeep Parhar return (EINVAL); 106054912308SNavdeep Parhar } 106154912308SNavdeep Parhar 106254912308SNavdeep Parhar return doit(CHELSIO_T4_SET_FILTER_MODE, &mode); 106354912308SNavdeep Parhar } 106454912308SNavdeep Parhar 106554912308SNavdeep Parhar static int 106654912308SNavdeep Parhar del_filter(uint32_t idx) 106754912308SNavdeep Parhar { 106854912308SNavdeep Parhar struct t4_filter t; 106954912308SNavdeep Parhar 107054912308SNavdeep Parhar t.idx = idx; 107154912308SNavdeep Parhar 107254912308SNavdeep Parhar return doit(CHELSIO_T4_DEL_FILTER, &t); 107354912308SNavdeep Parhar } 107454912308SNavdeep Parhar 107554912308SNavdeep Parhar static int 107654912308SNavdeep Parhar set_filter(uint32_t idx, int argc, const char *argv[]) 107754912308SNavdeep Parhar { 107854912308SNavdeep Parhar int af = AF_UNSPEC, start_arg = 0; 107954912308SNavdeep Parhar struct t4_filter t; 108054912308SNavdeep Parhar 108154912308SNavdeep Parhar if (argc < 2) { 108254912308SNavdeep Parhar warnc(EINVAL, "%s", __func__); 108354912308SNavdeep Parhar return (EINVAL); 108454912308SNavdeep Parhar }; 108554912308SNavdeep Parhar bzero(&t, sizeof (t)); 108654912308SNavdeep Parhar t.idx = idx; 108754912308SNavdeep Parhar t.fs.hitcnts = 1; 108854912308SNavdeep Parhar 108954912308SNavdeep Parhar for (start_arg = 0; start_arg + 2 <= argc; start_arg += 2) { 109054912308SNavdeep Parhar const char **args = &argv[start_arg]; 109154912308SNavdeep Parhar uint32_t val, mask; 109254912308SNavdeep Parhar 109354912308SNavdeep Parhar if (!strcmp(argv[start_arg], "type")) { 109454912308SNavdeep Parhar int newaf; 109554912308SNavdeep Parhar if (!strcasecmp(argv[start_arg + 1], "ipv4")) 109654912308SNavdeep Parhar newaf = AF_INET; 109754912308SNavdeep Parhar else if (!strcasecmp(argv[start_arg + 1], "ipv6")) 109854912308SNavdeep Parhar newaf = AF_INET6; 109954912308SNavdeep Parhar else { 110054912308SNavdeep Parhar warnx("invalid type \"%s\"; " 110154912308SNavdeep Parhar "must be one of \"ipv4\" or \"ipv6\"", 110254912308SNavdeep Parhar argv[start_arg + 1]); 110354912308SNavdeep Parhar return (EINVAL); 110454912308SNavdeep Parhar } 110554912308SNavdeep Parhar 110654912308SNavdeep Parhar if (af != AF_UNSPEC && af != newaf) { 110754912308SNavdeep Parhar warnx("conflicting IPv4/IPv6 specifications."); 110854912308SNavdeep Parhar return (EINVAL); 110954912308SNavdeep Parhar } 111054912308SNavdeep Parhar af = newaf; 111154912308SNavdeep Parhar } else if (!parse_val_mask("fcoe", args, &val, &mask)) { 111254912308SNavdeep Parhar t.fs.val.fcoe = val; 111354912308SNavdeep Parhar t.fs.mask.fcoe = mask; 111454912308SNavdeep Parhar } else if (!parse_val_mask("iport", args, &val, &mask)) { 111554912308SNavdeep Parhar t.fs.val.iport = val; 111654912308SNavdeep Parhar t.fs.mask.iport = mask; 111754912308SNavdeep Parhar } else if (!parse_val_mask("ovlan", args, &val, &mask)) { 111854912308SNavdeep Parhar t.fs.val.vnic = val; 111954912308SNavdeep Parhar t.fs.mask.vnic = mask; 112054912308SNavdeep Parhar t.fs.val.ovlan_vld = 1; 112154912308SNavdeep Parhar t.fs.mask.ovlan_vld = 1; 112254912308SNavdeep Parhar } else if (!parse_val_mask("ivlan", args, &val, &mask)) { 112354912308SNavdeep Parhar t.fs.val.vlan = val; 112454912308SNavdeep Parhar t.fs.mask.vlan = mask; 112554912308SNavdeep Parhar t.fs.val.vlan_vld = 1; 112654912308SNavdeep Parhar t.fs.mask.vlan_vld = 1; 112754912308SNavdeep Parhar } else if (!parse_val_mask("pf", args, &val, &mask)) { 112854912308SNavdeep Parhar t.fs.val.vnic &= 0x1fff; 112954912308SNavdeep Parhar t.fs.val.vnic |= (val & 0x7) << 13; 113054912308SNavdeep Parhar t.fs.mask.vnic &= 0x1fff; 113154912308SNavdeep Parhar t.fs.mask.vnic |= (mask & 0x7) << 13; 113254912308SNavdeep Parhar t.fs.val.pfvf_vld = 1; 113354912308SNavdeep Parhar t.fs.mask.pfvf_vld = 1; 113454912308SNavdeep Parhar } else if (!parse_val_mask("vf", args, &val, &mask)) { 113554912308SNavdeep Parhar t.fs.val.vnic &= 0xe000; 113654912308SNavdeep Parhar t.fs.val.vnic |= val & 0x1fff; 113754912308SNavdeep Parhar t.fs.mask.vnic &= 0xe000; 113854912308SNavdeep Parhar t.fs.mask.vnic |= mask & 0x1fff; 113954912308SNavdeep Parhar t.fs.val.pfvf_vld = 1; 114054912308SNavdeep Parhar t.fs.mask.pfvf_vld = 1; 114154912308SNavdeep Parhar } else if (!parse_val_mask("tos", args, &val, &mask)) { 114254912308SNavdeep Parhar t.fs.val.tos = val; 114354912308SNavdeep Parhar t.fs.mask.tos = mask; 114454912308SNavdeep Parhar } else if (!parse_val_mask("proto", args, &val, &mask)) { 114554912308SNavdeep Parhar t.fs.val.proto = val; 114654912308SNavdeep Parhar t.fs.mask.proto = mask; 114754912308SNavdeep Parhar } else if (!parse_val_mask("ethtype", args, &val, &mask)) { 114854912308SNavdeep Parhar t.fs.val.ethtype = val; 114954912308SNavdeep Parhar t.fs.mask.ethtype = mask; 115054912308SNavdeep Parhar } else if (!parse_val_mask("macidx", args, &val, &mask)) { 115154912308SNavdeep Parhar t.fs.val.macidx = val; 115254912308SNavdeep Parhar t.fs.mask.macidx = mask; 115354912308SNavdeep Parhar } else if (!parse_val_mask("matchtype", args, &val, &mask)) { 115454912308SNavdeep Parhar t.fs.val.matchtype = val; 115554912308SNavdeep Parhar t.fs.mask.matchtype = mask; 115654912308SNavdeep Parhar } else if (!parse_val_mask("frag", args, &val, &mask)) { 115754912308SNavdeep Parhar t.fs.val.frag = val; 115854912308SNavdeep Parhar t.fs.mask.frag = mask; 115954912308SNavdeep Parhar } else if (!parse_val_mask("dport", args, &val, &mask)) { 116054912308SNavdeep Parhar t.fs.val.dport = val; 116154912308SNavdeep Parhar t.fs.mask.dport = mask; 116254912308SNavdeep Parhar } else if (!parse_val_mask("sport", args, &val, &mask)) { 116354912308SNavdeep Parhar t.fs.val.sport = val; 116454912308SNavdeep Parhar t.fs.mask.sport = mask; 116554912308SNavdeep Parhar } else if (!parse_ipaddr("dip", args, &af, t.fs.val.dip, 116654912308SNavdeep Parhar t.fs.mask.dip)) { 116754912308SNavdeep Parhar /* nada */; 116854912308SNavdeep Parhar } else if (!parse_ipaddr("sip", args, &af, t.fs.val.sip, 116954912308SNavdeep Parhar t.fs.mask.sip)) { 117054912308SNavdeep Parhar /* nada */; 117154912308SNavdeep Parhar } else if (!strcmp(argv[start_arg], "action")) { 117254912308SNavdeep Parhar if (!strcmp(argv[start_arg + 1], "pass")) 117354912308SNavdeep Parhar t.fs.action = FILTER_PASS; 117454912308SNavdeep Parhar else if (!strcmp(argv[start_arg + 1], "drop")) 117554912308SNavdeep Parhar t.fs.action = FILTER_DROP; 117654912308SNavdeep Parhar else if (!strcmp(argv[start_arg + 1], "switch")) 117754912308SNavdeep Parhar t.fs.action = FILTER_SWITCH; 117854912308SNavdeep Parhar else { 117954912308SNavdeep Parhar warnx("invalid action \"%s\"; must be one of" 118054912308SNavdeep Parhar " \"pass\", \"drop\" or \"switch\"", 118154912308SNavdeep Parhar argv[start_arg + 1]); 118254912308SNavdeep Parhar return (EINVAL); 118354912308SNavdeep Parhar } 118454912308SNavdeep Parhar } else if (!parse_val("hitcnts", args, &val)) { 118554912308SNavdeep Parhar t.fs.hitcnts = val; 118654912308SNavdeep Parhar } else if (!parse_val("prio", args, &val)) { 118754912308SNavdeep Parhar t.fs.prio = val; 118854912308SNavdeep Parhar } else if (!parse_val("rpttid", args, &val)) { 118954912308SNavdeep Parhar t.fs.rpttid = 1; 119054912308SNavdeep Parhar } else if (!parse_val("queue", args, &val)) { 119154912308SNavdeep Parhar t.fs.dirsteer = 1; 119254912308SNavdeep Parhar t.fs.iq = val; 119354912308SNavdeep Parhar } else if (!parse_val("tcbhash", args, &val)) { 119454912308SNavdeep Parhar t.fs.maskhash = 1; 119554912308SNavdeep Parhar t.fs.dirsteerhash = 1; 119654912308SNavdeep Parhar } else if (!parse_val("eport", args, &val)) { 119754912308SNavdeep Parhar t.fs.eport = val; 119854912308SNavdeep Parhar } else if (!strcmp(argv[start_arg], "dmac")) { 119954912308SNavdeep Parhar struct ether_addr *daddr; 120054912308SNavdeep Parhar 120154912308SNavdeep Parhar daddr = ether_aton(argv[start_arg + 1]); 120254912308SNavdeep Parhar if (daddr == NULL) { 120354912308SNavdeep Parhar warnx("invalid dmac address \"%s\"", 120454912308SNavdeep Parhar argv[start_arg + 1]); 120554912308SNavdeep Parhar return (EINVAL); 120654912308SNavdeep Parhar } 120754912308SNavdeep Parhar memcpy(t.fs.dmac, daddr, ETHER_ADDR_LEN); 120854912308SNavdeep Parhar t.fs.newdmac = 1; 120954912308SNavdeep Parhar } else if (!strcmp(argv[start_arg], "smac")) { 121054912308SNavdeep Parhar struct ether_addr *saddr; 121154912308SNavdeep Parhar 121254912308SNavdeep Parhar saddr = ether_aton(argv[start_arg + 1]); 121354912308SNavdeep Parhar if (saddr == NULL) { 121454912308SNavdeep Parhar warnx("invalid smac address \"%s\"", 121554912308SNavdeep Parhar argv[start_arg + 1]); 121654912308SNavdeep Parhar return (EINVAL); 121754912308SNavdeep Parhar } 121854912308SNavdeep Parhar memcpy(t.fs.smac, saddr, ETHER_ADDR_LEN); 121954912308SNavdeep Parhar t.fs.newsmac = 1; 122054912308SNavdeep Parhar } else if (!strcmp(argv[start_arg], "vlan")) { 122154912308SNavdeep Parhar char *p; 122254912308SNavdeep Parhar if (!strcmp(argv[start_arg + 1], "none")) { 122354912308SNavdeep Parhar t.fs.newvlan = VLAN_REMOVE; 122454912308SNavdeep Parhar } else if (argv[start_arg + 1][0] == '=') { 122554912308SNavdeep Parhar t.fs.newvlan = VLAN_REWRITE; 122654912308SNavdeep Parhar } else if (argv[start_arg + 1][0] == '+') { 122754912308SNavdeep Parhar t.fs.newvlan = VLAN_INSERT; 122854912308SNavdeep Parhar } else if (isdigit(argv[start_arg + 1][0]) && 122954912308SNavdeep Parhar !parse_val_mask("vlan", args, &val, &mask)) { 123054912308SNavdeep Parhar t.fs.val.vlan = val; 123154912308SNavdeep Parhar t.fs.mask.vlan = mask; 123254912308SNavdeep Parhar t.fs.val.vlan_vld = 1; 123354912308SNavdeep Parhar t.fs.mask.vlan_vld = 1; 123454912308SNavdeep Parhar } else { 123554912308SNavdeep Parhar warnx("unknown vlan parameter \"%s\"; must" 123654912308SNavdeep Parhar " be one of \"none\", \"=<vlan>\", " 123754912308SNavdeep Parhar " \"+<vlan>\", or \"<vlan>\"", 123854912308SNavdeep Parhar argv[start_arg + 1]); 123954912308SNavdeep Parhar return (EINVAL); 124054912308SNavdeep Parhar } 124154912308SNavdeep Parhar if (t.fs.newvlan == VLAN_REWRITE || 124254912308SNavdeep Parhar t.fs.newvlan == VLAN_INSERT) { 124354912308SNavdeep Parhar t.fs.vlan = strtoul(argv[start_arg + 1] + 1, 124454912308SNavdeep Parhar &p, 0); 124554912308SNavdeep Parhar if (p == argv[start_arg + 1] + 1 || p[0] != 0) { 124654912308SNavdeep Parhar warnx("invalid vlan \"%s\"", 124754912308SNavdeep Parhar argv[start_arg + 1]); 124854912308SNavdeep Parhar return (EINVAL); 124954912308SNavdeep Parhar } 125054912308SNavdeep Parhar } 125154912308SNavdeep Parhar } else { 125254912308SNavdeep Parhar warnx("invalid parameter \"%s\"", argv[start_arg]); 125354912308SNavdeep Parhar return (EINVAL); 125454912308SNavdeep Parhar } 125554912308SNavdeep Parhar } 125654912308SNavdeep Parhar if (start_arg != argc) { 125754912308SNavdeep Parhar warnx("no value for \"%s\"", argv[start_arg]); 125854912308SNavdeep Parhar return (EINVAL); 125954912308SNavdeep Parhar } 126054912308SNavdeep Parhar 126154912308SNavdeep Parhar /* 126254912308SNavdeep Parhar * Check basic sanity of option combinations. 126354912308SNavdeep Parhar */ 126454912308SNavdeep Parhar if (t.fs.action != FILTER_SWITCH && 126554912308SNavdeep Parhar (t.fs.eport || t.fs.newdmac || t.fs.newsmac || t.fs.newvlan)) { 126654912308SNavdeep Parhar warnx("prio, port dmac, smac and vlan only make sense with" 126754912308SNavdeep Parhar " \"action switch\""); 126854912308SNavdeep Parhar return (EINVAL); 126954912308SNavdeep Parhar } 127054912308SNavdeep Parhar if (t.fs.action != FILTER_PASS && 127154912308SNavdeep Parhar (t.fs.rpttid || t.fs.dirsteer || t.fs.maskhash)) { 127254912308SNavdeep Parhar warnx("rpttid, queue and tcbhash don't make sense with" 127354912308SNavdeep Parhar " action \"drop\" or \"switch\""); 127454912308SNavdeep Parhar return (EINVAL); 127554912308SNavdeep Parhar } 127654912308SNavdeep Parhar if (t.fs.val.ovlan_vld && t.fs.val.pfvf_vld) { 127754912308SNavdeep Parhar warnx("ovlan and vnic_id (pf/vf) are mutually exclusive"); 127854912308SNavdeep Parhar return (EINVAL); 127954912308SNavdeep Parhar } 128054912308SNavdeep Parhar 128154912308SNavdeep Parhar t.fs.type = (af == AF_INET6 ? 1 : 0); /* default IPv4 */ 128254912308SNavdeep Parhar return doit(CHELSIO_T4_SET_FILTER, &t); 128354912308SNavdeep Parhar } 128454912308SNavdeep Parhar 128554912308SNavdeep Parhar static int 128654912308SNavdeep Parhar filter_cmd(int argc, const char *argv[]) 128754912308SNavdeep Parhar { 128854912308SNavdeep Parhar long long val; 128954912308SNavdeep Parhar uint32_t idx; 129054912308SNavdeep Parhar char *s; 129154912308SNavdeep Parhar 129254912308SNavdeep Parhar if (argc == 0) { 129354912308SNavdeep Parhar warnx("filter: no arguments."); 129454912308SNavdeep Parhar return (EINVAL); 129554912308SNavdeep Parhar }; 129654912308SNavdeep Parhar 129754912308SNavdeep Parhar /* list */ 129854912308SNavdeep Parhar if (strcmp(argv[0], "list") == 0) { 129954912308SNavdeep Parhar if (argc != 1) 130054912308SNavdeep Parhar warnx("trailing arguments after \"list\" ignored."); 130154912308SNavdeep Parhar 130254912308SNavdeep Parhar return show_filters(); 130354912308SNavdeep Parhar } 130454912308SNavdeep Parhar 130554912308SNavdeep Parhar /* mode */ 130654912308SNavdeep Parhar if (argc == 1 && strcmp(argv[0], "mode") == 0) 130754912308SNavdeep Parhar return get_filter_mode(); 130854912308SNavdeep Parhar 130954912308SNavdeep Parhar /* mode <mode> */ 131054912308SNavdeep Parhar if (strcmp(argv[0], "mode") == 0) 131154912308SNavdeep Parhar return set_filter_mode(argc - 1, argv + 1); 131254912308SNavdeep Parhar 131354912308SNavdeep Parhar /* <idx> ... */ 131454912308SNavdeep Parhar s = str_to_number(argv[0], NULL, &val); 131554912308SNavdeep Parhar if (*s || val > 0xffffffffU) { 131654912308SNavdeep Parhar warnx("\"%s\" is neither an index nor a filter subcommand.", 131754912308SNavdeep Parhar argv[0]); 131854912308SNavdeep Parhar return (EINVAL); 131954912308SNavdeep Parhar } 132054912308SNavdeep Parhar idx = (uint32_t) val; 132154912308SNavdeep Parhar 132254912308SNavdeep Parhar /* <idx> delete|clear */ 132354912308SNavdeep Parhar if (argc == 2 && 132454912308SNavdeep Parhar (strcmp(argv[1], "delete") == 0 || strcmp(argv[1], "clear") == 0)) { 132554912308SNavdeep Parhar return del_filter(idx); 132654912308SNavdeep Parhar } 132754912308SNavdeep Parhar 132854912308SNavdeep Parhar /* <idx> [<param> <val>] ... */ 132954912308SNavdeep Parhar return set_filter(idx, argc - 1, argv + 1); 133054912308SNavdeep Parhar } 133154912308SNavdeep Parhar 133254912308SNavdeep Parhar /* 133354912308SNavdeep Parhar * Shows the fields of a multi-word structure. The structure is considered to 133454912308SNavdeep Parhar * consist of @nwords 32-bit words (i.e, it's an (@nwords * 32)-bit structure) 133554912308SNavdeep Parhar * whose fields are described by @fd. The 32-bit words are given in @words 133654912308SNavdeep Parhar * starting with the least significant 32-bit word. 133754912308SNavdeep Parhar */ 133854912308SNavdeep Parhar static void 133954912308SNavdeep Parhar show_struct(const uint32_t *words, int nwords, const struct field_desc *fd) 134054912308SNavdeep Parhar { 134154912308SNavdeep Parhar unsigned int w = 0; 134254912308SNavdeep Parhar const struct field_desc *p; 134354912308SNavdeep Parhar 134454912308SNavdeep Parhar for (p = fd; p->name; p++) 134554912308SNavdeep Parhar w = max(w, strlen(p->name)); 134654912308SNavdeep Parhar 134754912308SNavdeep Parhar while (fd->name) { 134854912308SNavdeep Parhar unsigned long long data; 134954912308SNavdeep Parhar int first_word = fd->start / 32; 135054912308SNavdeep Parhar int shift = fd->start % 32; 135154912308SNavdeep Parhar int width = fd->end - fd->start + 1; 135254912308SNavdeep Parhar unsigned long long mask = (1ULL << width) - 1; 135354912308SNavdeep Parhar 135454912308SNavdeep Parhar data = (words[first_word] >> shift) | 135554912308SNavdeep Parhar ((uint64_t)words[first_word + 1] << (32 - shift)); 135654912308SNavdeep Parhar if (shift) 135754912308SNavdeep Parhar data |= ((uint64_t)words[first_word + 2] << (64 - shift)); 135854912308SNavdeep Parhar data &= mask; 135954912308SNavdeep Parhar if (fd->islog2) 136054912308SNavdeep Parhar data = 1 << data; 136154912308SNavdeep Parhar printf("%-*s ", w, fd->name); 136254912308SNavdeep Parhar printf(fd->hex ? "%#llx\n" : "%llu\n", data << fd->shift); 136354912308SNavdeep Parhar fd++; 136454912308SNavdeep Parhar } 136554912308SNavdeep Parhar } 136654912308SNavdeep Parhar 136754912308SNavdeep Parhar #define FIELD(name, start, end) { name, start, end, 0, 0, 0 } 136854912308SNavdeep Parhar #define FIELD1(name, start) FIELD(name, start, start) 136954912308SNavdeep Parhar 137054912308SNavdeep Parhar static void 137154912308SNavdeep Parhar show_t5t6_ctxt(const struct t4_sge_context *p, int vers) 137254912308SNavdeep Parhar { 137354912308SNavdeep Parhar static struct field_desc egress_t5[] = { 137454912308SNavdeep Parhar FIELD("DCA_ST:", 181, 191), 137554912308SNavdeep Parhar FIELD1("StatusPgNS:", 180), 137654912308SNavdeep Parhar FIELD1("StatusPgRO:", 179), 137754912308SNavdeep Parhar FIELD1("FetchNS:", 178), 137854912308SNavdeep Parhar FIELD1("FetchRO:", 177), 137954912308SNavdeep Parhar FIELD1("Valid:", 176), 138054912308SNavdeep Parhar FIELD("PCIeDataChannel:", 174, 175), 138154912308SNavdeep Parhar FIELD1("StatusPgTPHintEn:", 173), 138254912308SNavdeep Parhar FIELD("StatusPgTPHint:", 171, 172), 138354912308SNavdeep Parhar FIELD1("FetchTPHintEn:", 170), 138454912308SNavdeep Parhar FIELD("FetchTPHint:", 168, 169), 138554912308SNavdeep Parhar FIELD1("FCThreshOverride:", 167), 138654912308SNavdeep Parhar { "WRLength:", 162, 166, 9, 0, 1 }, 138754912308SNavdeep Parhar FIELD1("WRLengthKnown:", 161), 138854912308SNavdeep Parhar FIELD1("ReschedulePending:", 160), 138954912308SNavdeep Parhar FIELD1("OnChipQueue:", 159), 139054912308SNavdeep Parhar FIELD1("FetchSizeMode:", 158), 139154912308SNavdeep Parhar { "FetchBurstMin:", 156, 157, 4, 0, 1 }, 139254912308SNavdeep Parhar FIELD1("FLMPacking:", 155), 139354912308SNavdeep Parhar FIELD("FetchBurstMax:", 153, 154), 139454912308SNavdeep Parhar FIELD("uPToken:", 133, 152), 139554912308SNavdeep Parhar FIELD1("uPTokenEn:", 132), 139654912308SNavdeep Parhar FIELD1("UserModeIO:", 131), 139754912308SNavdeep Parhar FIELD("uPFLCredits:", 123, 130), 139854912308SNavdeep Parhar FIELD1("uPFLCreditEn:", 122), 139954912308SNavdeep Parhar FIELD("FID:", 111, 121), 140054912308SNavdeep Parhar FIELD("HostFCMode:", 109, 110), 140154912308SNavdeep Parhar FIELD1("HostFCOwner:", 108), 140254912308SNavdeep Parhar { "CIDXFlushThresh:", 105, 107, 0, 0, 1 }, 140354912308SNavdeep Parhar FIELD("CIDX:", 89, 104), 140454912308SNavdeep Parhar FIELD("PIDX:", 73, 88), 140554912308SNavdeep Parhar { "BaseAddress:", 18, 72, 9, 1 }, 140654912308SNavdeep Parhar FIELD("QueueSize:", 2, 17), 140754912308SNavdeep Parhar FIELD1("QueueType:", 1), 140854912308SNavdeep Parhar FIELD1("CachePriority:", 0), 140954912308SNavdeep Parhar { NULL } 141054912308SNavdeep Parhar }; 141154912308SNavdeep Parhar static struct field_desc egress_t6[] = { 141254912308SNavdeep Parhar FIELD("DCA_ST:", 181, 191), 141354912308SNavdeep Parhar FIELD1("StatusPgNS:", 180), 141454912308SNavdeep Parhar FIELD1("StatusPgRO:", 179), 141554912308SNavdeep Parhar FIELD1("FetchNS:", 178), 141654912308SNavdeep Parhar FIELD1("FetchRO:", 177), 141754912308SNavdeep Parhar FIELD1("Valid:", 176), 141854912308SNavdeep Parhar FIELD1("ReschedulePending_1:", 175), 141954912308SNavdeep Parhar FIELD1("PCIeDataChannel:", 174), 142054912308SNavdeep Parhar FIELD1("StatusPgTPHintEn:", 173), 142154912308SNavdeep Parhar FIELD("StatusPgTPHint:", 171, 172), 142254912308SNavdeep Parhar FIELD1("FetchTPHintEn:", 170), 142354912308SNavdeep Parhar FIELD("FetchTPHint:", 168, 169), 142454912308SNavdeep Parhar FIELD1("FCThreshOverride:", 167), 142554912308SNavdeep Parhar { "WRLength:", 162, 166, 9, 0, 1 }, 142654912308SNavdeep Parhar FIELD1("WRLengthKnown:", 161), 142754912308SNavdeep Parhar FIELD1("ReschedulePending:", 160), 142854912308SNavdeep Parhar FIELD("TimerIx:", 157, 159), 142954912308SNavdeep Parhar FIELD1("FetchBurstMin:", 156), 143054912308SNavdeep Parhar FIELD1("FLMPacking:", 155), 143154912308SNavdeep Parhar FIELD("FetchBurstMax:", 153, 154), 143254912308SNavdeep Parhar FIELD("uPToken:", 133, 152), 143354912308SNavdeep Parhar FIELD1("uPTokenEn:", 132), 143454912308SNavdeep Parhar FIELD1("UserModeIO:", 131), 143554912308SNavdeep Parhar FIELD("uPFLCredits:", 123, 130), 143654912308SNavdeep Parhar FIELD1("uPFLCreditEn:", 122), 143754912308SNavdeep Parhar FIELD("FID:", 111, 121), 143854912308SNavdeep Parhar FIELD("HostFCMode:", 109, 110), 143954912308SNavdeep Parhar FIELD1("HostFCOwner:", 108), 144054912308SNavdeep Parhar { "CIDXFlushThresh:", 105, 107, 0, 0, 1 }, 144154912308SNavdeep Parhar FIELD("CIDX:", 89, 104), 144254912308SNavdeep Parhar FIELD("PIDX:", 73, 88), 144354912308SNavdeep Parhar { "BaseAddress:", 18, 72, 9, 1 }, 144454912308SNavdeep Parhar FIELD("QueueSize:", 2, 17), 144554912308SNavdeep Parhar FIELD1("QueueType:", 1), 144654912308SNavdeep Parhar FIELD1("FetchSizeMode:", 0), 144754912308SNavdeep Parhar { NULL } 144854912308SNavdeep Parhar }; 144954912308SNavdeep Parhar static struct field_desc fl_t5[] = { 145054912308SNavdeep Parhar FIELD("DCA_ST:", 181, 191), 145154912308SNavdeep Parhar FIELD1("StatusPgNS:", 180), 145254912308SNavdeep Parhar FIELD1("StatusPgRO:", 179), 145354912308SNavdeep Parhar FIELD1("FetchNS:", 178), 145454912308SNavdeep Parhar FIELD1("FetchRO:", 177), 145554912308SNavdeep Parhar FIELD1("Valid:", 176), 145654912308SNavdeep Parhar FIELD("PCIeDataChannel:", 174, 175), 145754912308SNavdeep Parhar FIELD1("StatusPgTPHintEn:", 173), 145854912308SNavdeep Parhar FIELD("StatusPgTPHint:", 171, 172), 145954912308SNavdeep Parhar FIELD1("FetchTPHintEn:", 170), 146054912308SNavdeep Parhar FIELD("FetchTPHint:", 168, 169), 146154912308SNavdeep Parhar FIELD1("FCThreshOverride:", 167), 146254912308SNavdeep Parhar FIELD1("ReschedulePending:", 160), 146354912308SNavdeep Parhar FIELD1("OnChipQueue:", 159), 146454912308SNavdeep Parhar FIELD1("FetchSizeMode:", 158), 146554912308SNavdeep Parhar { "FetchBurstMin:", 156, 157, 4, 0, 1 }, 146654912308SNavdeep Parhar FIELD1("FLMPacking:", 155), 146754912308SNavdeep Parhar FIELD("FetchBurstMax:", 153, 154), 146854912308SNavdeep Parhar FIELD1("FLMcongMode:", 152), 146954912308SNavdeep Parhar FIELD("MaxuPFLCredits:", 144, 151), 147054912308SNavdeep Parhar FIELD("FLMcontextID:", 133, 143), 147154912308SNavdeep Parhar FIELD1("uPTokenEn:", 132), 147254912308SNavdeep Parhar FIELD1("UserModeIO:", 131), 147354912308SNavdeep Parhar FIELD("uPFLCredits:", 123, 130), 147454912308SNavdeep Parhar FIELD1("uPFLCreditEn:", 122), 147554912308SNavdeep Parhar FIELD("FID:", 111, 121), 147654912308SNavdeep Parhar FIELD("HostFCMode:", 109, 110), 147754912308SNavdeep Parhar FIELD1("HostFCOwner:", 108), 147854912308SNavdeep Parhar { "CIDXFlushThresh:", 105, 107, 0, 0, 1 }, 147954912308SNavdeep Parhar FIELD("CIDX:", 89, 104), 148054912308SNavdeep Parhar FIELD("PIDX:", 73, 88), 148154912308SNavdeep Parhar { "BaseAddress:", 18, 72, 9, 1 }, 148254912308SNavdeep Parhar FIELD("QueueSize:", 2, 17), 148354912308SNavdeep Parhar FIELD1("QueueType:", 1), 148454912308SNavdeep Parhar FIELD1("CachePriority:", 0), 148554912308SNavdeep Parhar { NULL } 148654912308SNavdeep Parhar }; 148754912308SNavdeep Parhar static struct field_desc ingress_t5[] = { 148854912308SNavdeep Parhar FIELD("DCA_ST:", 143, 153), 148954912308SNavdeep Parhar FIELD1("ISCSICoalescing:", 142), 149054912308SNavdeep Parhar FIELD1("Queue_Valid:", 141), 149154912308SNavdeep Parhar FIELD1("TimerPending:", 140), 149254912308SNavdeep Parhar FIELD1("DropRSS:", 139), 149354912308SNavdeep Parhar FIELD("PCIeChannel:", 137, 138), 149454912308SNavdeep Parhar FIELD1("SEInterruptArmed:", 136), 149554912308SNavdeep Parhar FIELD1("CongestionMgtEnable:", 135), 149654912308SNavdeep Parhar FIELD1("NoSnoop:", 134), 149754912308SNavdeep Parhar FIELD1("RelaxedOrdering:", 133), 149854912308SNavdeep Parhar FIELD1("GTSmode:", 132), 149954912308SNavdeep Parhar FIELD1("TPHintEn:", 131), 150054912308SNavdeep Parhar FIELD("TPHint:", 129, 130), 150154912308SNavdeep Parhar FIELD1("UpdateScheduling:", 128), 150254912308SNavdeep Parhar FIELD("UpdateDelivery:", 126, 127), 150354912308SNavdeep Parhar FIELD1("InterruptSent:", 125), 150454912308SNavdeep Parhar FIELD("InterruptIDX:", 114, 124), 150554912308SNavdeep Parhar FIELD1("InterruptDestination:", 113), 150654912308SNavdeep Parhar FIELD1("InterruptArmed:", 112), 150754912308SNavdeep Parhar FIELD("RxIntCounter:", 106, 111), 150854912308SNavdeep Parhar FIELD("RxIntCounterThreshold:", 104, 105), 150954912308SNavdeep Parhar FIELD1("Generation:", 103), 151054912308SNavdeep Parhar { "BaseAddress:", 48, 102, 9, 1 }, 151154912308SNavdeep Parhar FIELD("PIDX:", 32, 47), 151254912308SNavdeep Parhar FIELD("CIDX:", 16, 31), 151354912308SNavdeep Parhar { "QueueSize:", 4, 15, 4, 0 }, 151454912308SNavdeep Parhar { "QueueEntrySize:", 2, 3, 4, 0, 1 }, 151554912308SNavdeep Parhar FIELD1("QueueEntryOverride:", 1), 151654912308SNavdeep Parhar FIELD1("CachePriority:", 0), 151754912308SNavdeep Parhar { NULL } 151854912308SNavdeep Parhar }; 151954912308SNavdeep Parhar static struct field_desc ingress_t6[] = { 152054912308SNavdeep Parhar FIELD1("SP_NS:", 158), 152154912308SNavdeep Parhar FIELD1("SP_RO:", 157), 152254912308SNavdeep Parhar FIELD1("SP_TPHintEn:", 156), 152354912308SNavdeep Parhar FIELD("SP_TPHint:", 154, 155), 152454912308SNavdeep Parhar FIELD("DCA_ST:", 143, 153), 152554912308SNavdeep Parhar FIELD1("ISCSICoalescing:", 142), 152654912308SNavdeep Parhar FIELD1("Queue_Valid:", 141), 152754912308SNavdeep Parhar FIELD1("TimerPending:", 140), 152854912308SNavdeep Parhar FIELD1("DropRSS:", 139), 152954912308SNavdeep Parhar FIELD("PCIeChannel:", 137, 138), 153054912308SNavdeep Parhar FIELD1("SEInterruptArmed:", 136), 153154912308SNavdeep Parhar FIELD1("CongestionMgtEnable:", 135), 153254912308SNavdeep Parhar FIELD1("NoSnoop:", 134), 153354912308SNavdeep Parhar FIELD1("RelaxedOrdering:", 133), 153454912308SNavdeep Parhar FIELD1("GTSmode:", 132), 153554912308SNavdeep Parhar FIELD1("TPHintEn:", 131), 153654912308SNavdeep Parhar FIELD("TPHint:", 129, 130), 153754912308SNavdeep Parhar FIELD1("UpdateScheduling:", 128), 153854912308SNavdeep Parhar FIELD("UpdateDelivery:", 126, 127), 153954912308SNavdeep Parhar FIELD1("InterruptSent:", 125), 154054912308SNavdeep Parhar FIELD("InterruptIDX:", 114, 124), 154154912308SNavdeep Parhar FIELD1("InterruptDestination:", 113), 154254912308SNavdeep Parhar FIELD1("InterruptArmed:", 112), 154354912308SNavdeep Parhar FIELD("RxIntCounter:", 106, 111), 154454912308SNavdeep Parhar FIELD("RxIntCounterThreshold:", 104, 105), 154554912308SNavdeep Parhar FIELD1("Generation:", 103), 154654912308SNavdeep Parhar { "BaseAddress:", 48, 102, 9, 1 }, 154754912308SNavdeep Parhar FIELD("PIDX:", 32, 47), 154854912308SNavdeep Parhar FIELD("CIDX:", 16, 31), 154954912308SNavdeep Parhar { "QueueSize:", 4, 15, 4, 0 }, 155054912308SNavdeep Parhar { "QueueEntrySize:", 2, 3, 4, 0, 1 }, 155154912308SNavdeep Parhar FIELD1("QueueEntryOverride:", 1), 155254912308SNavdeep Parhar FIELD1("CachePriority:", 0), 155354912308SNavdeep Parhar { NULL } 155454912308SNavdeep Parhar }; 155554912308SNavdeep Parhar static struct field_desc flm_t5[] = { 155654912308SNavdeep Parhar FIELD1("Valid:", 89), 155754912308SNavdeep Parhar FIELD("SplitLenMode:", 87, 88), 155854912308SNavdeep Parhar FIELD1("TPHintEn:", 86), 155954912308SNavdeep Parhar FIELD("TPHint:", 84, 85), 156054912308SNavdeep Parhar FIELD1("NoSnoop:", 83), 156154912308SNavdeep Parhar FIELD1("RelaxedOrdering:", 82), 156254912308SNavdeep Parhar FIELD("DCA_ST:", 71, 81), 156354912308SNavdeep Parhar FIELD("EQid:", 54, 70), 156454912308SNavdeep Parhar FIELD("SplitEn:", 52, 53), 156554912308SNavdeep Parhar FIELD1("PadEn:", 51), 156654912308SNavdeep Parhar FIELD1("PackEn:", 50), 156754912308SNavdeep Parhar FIELD1("Cache_Lock :", 49), 156854912308SNavdeep Parhar FIELD1("CongDrop:", 48), 156954912308SNavdeep Parhar FIELD("PackOffset:", 16, 47), 157054912308SNavdeep Parhar FIELD("CIDX:", 8, 15), 157154912308SNavdeep Parhar FIELD("PIDX:", 0, 7), 157254912308SNavdeep Parhar { NULL } 157354912308SNavdeep Parhar }; 157454912308SNavdeep Parhar static struct field_desc flm_t6[] = { 157554912308SNavdeep Parhar FIELD1("Valid:", 89), 157654912308SNavdeep Parhar FIELD("SplitLenMode:", 87, 88), 157754912308SNavdeep Parhar FIELD1("TPHintEn:", 86), 157854912308SNavdeep Parhar FIELD("TPHint:", 84, 85), 157954912308SNavdeep Parhar FIELD1("NoSnoop:", 83), 158054912308SNavdeep Parhar FIELD1("RelaxedOrdering:", 82), 158154912308SNavdeep Parhar FIELD("DCA_ST:", 71, 81), 158254912308SNavdeep Parhar FIELD("EQid:", 54, 70), 158354912308SNavdeep Parhar FIELD("SplitEn:", 52, 53), 158454912308SNavdeep Parhar FIELD1("PadEn:", 51), 158554912308SNavdeep Parhar FIELD1("PackEn:", 50), 158654912308SNavdeep Parhar FIELD1("Cache_Lock :", 49), 158754912308SNavdeep Parhar FIELD1("CongDrop:", 48), 158854912308SNavdeep Parhar FIELD1("Inflight:", 47), 158954912308SNavdeep Parhar FIELD1("CongEn:", 46), 159054912308SNavdeep Parhar FIELD1("CongMode:", 45), 159154912308SNavdeep Parhar FIELD("PackOffset:", 20, 39), 159254912308SNavdeep Parhar FIELD("CIDX:", 8, 15), 159354912308SNavdeep Parhar FIELD("PIDX:", 0, 7), 159454912308SNavdeep Parhar { NULL } 159554912308SNavdeep Parhar }; 159654912308SNavdeep Parhar static struct field_desc conm_t5[] = { 159754912308SNavdeep Parhar FIELD1("CngMPSEnable:", 21), 159854912308SNavdeep Parhar FIELD("CngTPMode:", 19, 20), 159954912308SNavdeep Parhar FIELD1("CngDBPHdr:", 18), 160054912308SNavdeep Parhar FIELD1("CngDBPData:", 17), 160154912308SNavdeep Parhar FIELD1("CngIMSG:", 16), 160254912308SNavdeep Parhar { "CngChMap:", 0, 15, 0, 1, 0 }, 160354912308SNavdeep Parhar { NULL } 160454912308SNavdeep Parhar }; 160554912308SNavdeep Parhar 160654912308SNavdeep Parhar if (p->mem_id == SGE_CONTEXT_EGRESS) { 160754912308SNavdeep Parhar if (p->data[0] & 2) 160854912308SNavdeep Parhar show_struct(p->data, 6, fl_t5); 160954912308SNavdeep Parhar else if (vers == 5) 161054912308SNavdeep Parhar show_struct(p->data, 6, egress_t5); 161154912308SNavdeep Parhar else 161254912308SNavdeep Parhar show_struct(p->data, 6, egress_t6); 161354912308SNavdeep Parhar } else if (p->mem_id == SGE_CONTEXT_FLM) 161454912308SNavdeep Parhar show_struct(p->data, 3, vers == 5 ? flm_t5 : flm_t6); 161554912308SNavdeep Parhar else if (p->mem_id == SGE_CONTEXT_INGRESS) 161654912308SNavdeep Parhar show_struct(p->data, 5, vers == 5 ? ingress_t5 : ingress_t6); 161754912308SNavdeep Parhar else if (p->mem_id == SGE_CONTEXT_CNM) 161854912308SNavdeep Parhar show_struct(p->data, 1, conm_t5); 161954912308SNavdeep Parhar } 162054912308SNavdeep Parhar 162154912308SNavdeep Parhar static void 162254912308SNavdeep Parhar show_t4_ctxt(const struct t4_sge_context *p) 162354912308SNavdeep Parhar { 162454912308SNavdeep Parhar static struct field_desc egress_t4[] = { 162554912308SNavdeep Parhar FIELD1("StatusPgNS:", 180), 162654912308SNavdeep Parhar FIELD1("StatusPgRO:", 179), 162754912308SNavdeep Parhar FIELD1("FetchNS:", 178), 162854912308SNavdeep Parhar FIELD1("FetchRO:", 177), 162954912308SNavdeep Parhar FIELD1("Valid:", 176), 163054912308SNavdeep Parhar FIELD("PCIeDataChannel:", 174, 175), 163154912308SNavdeep Parhar FIELD1("DCAEgrQEn:", 173), 163254912308SNavdeep Parhar FIELD("DCACPUID:", 168, 172), 163354912308SNavdeep Parhar FIELD1("FCThreshOverride:", 167), 163454912308SNavdeep Parhar FIELD("WRLength:", 162, 166), 163554912308SNavdeep Parhar FIELD1("WRLengthKnown:", 161), 163654912308SNavdeep Parhar FIELD1("ReschedulePending:", 160), 163754912308SNavdeep Parhar FIELD1("OnChipQueue:", 159), 163854912308SNavdeep Parhar FIELD1("FetchSizeMode", 158), 163954912308SNavdeep Parhar { "FetchBurstMin:", 156, 157, 4, 0, 1 }, 164054912308SNavdeep Parhar { "FetchBurstMax:", 153, 154, 6, 0, 1 }, 164154912308SNavdeep Parhar FIELD("uPToken:", 133, 152), 164254912308SNavdeep Parhar FIELD1("uPTokenEn:", 132), 164354912308SNavdeep Parhar FIELD1("UserModeIO:", 131), 164454912308SNavdeep Parhar FIELD("uPFLCredits:", 123, 130), 164554912308SNavdeep Parhar FIELD1("uPFLCreditEn:", 122), 164654912308SNavdeep Parhar FIELD("FID:", 111, 121), 164754912308SNavdeep Parhar FIELD("HostFCMode:", 109, 110), 164854912308SNavdeep Parhar FIELD1("HostFCOwner:", 108), 164954912308SNavdeep Parhar { "CIDXFlushThresh:", 105, 107, 0, 0, 1 }, 165054912308SNavdeep Parhar FIELD("CIDX:", 89, 104), 165154912308SNavdeep Parhar FIELD("PIDX:", 73, 88), 165254912308SNavdeep Parhar { "BaseAddress:", 18, 72, 9, 1 }, 165354912308SNavdeep Parhar FIELD("QueueSize:", 2, 17), 165454912308SNavdeep Parhar FIELD1("QueueType:", 1), 165554912308SNavdeep Parhar FIELD1("CachePriority:", 0), 165654912308SNavdeep Parhar { NULL } 165754912308SNavdeep Parhar }; 165854912308SNavdeep Parhar static struct field_desc fl_t4[] = { 165954912308SNavdeep Parhar FIELD1("StatusPgNS:", 180), 166054912308SNavdeep Parhar FIELD1("StatusPgRO:", 179), 166154912308SNavdeep Parhar FIELD1("FetchNS:", 178), 166254912308SNavdeep Parhar FIELD1("FetchRO:", 177), 166354912308SNavdeep Parhar FIELD1("Valid:", 176), 166454912308SNavdeep Parhar FIELD("PCIeDataChannel:", 174, 175), 166554912308SNavdeep Parhar FIELD1("DCAEgrQEn:", 173), 166654912308SNavdeep Parhar FIELD("DCACPUID:", 168, 172), 166754912308SNavdeep Parhar FIELD1("FCThreshOverride:", 167), 166854912308SNavdeep Parhar FIELD1("ReschedulePending:", 160), 166954912308SNavdeep Parhar FIELD1("OnChipQueue:", 159), 167054912308SNavdeep Parhar FIELD1("FetchSizeMode", 158), 167154912308SNavdeep Parhar { "FetchBurstMin:", 156, 157, 4, 0, 1 }, 167254912308SNavdeep Parhar { "FetchBurstMax:", 153, 154, 6, 0, 1 }, 167354912308SNavdeep Parhar FIELD1("FLMcongMode:", 152), 167454912308SNavdeep Parhar FIELD("MaxuPFLCredits:", 144, 151), 167554912308SNavdeep Parhar FIELD("FLMcontextID:", 133, 143), 167654912308SNavdeep Parhar FIELD1("uPTokenEn:", 132), 167754912308SNavdeep Parhar FIELD1("UserModeIO:", 131), 167854912308SNavdeep Parhar FIELD("uPFLCredits:", 123, 130), 167954912308SNavdeep Parhar FIELD1("uPFLCreditEn:", 122), 168054912308SNavdeep Parhar FIELD("FID:", 111, 121), 168154912308SNavdeep Parhar FIELD("HostFCMode:", 109, 110), 168254912308SNavdeep Parhar FIELD1("HostFCOwner:", 108), 168354912308SNavdeep Parhar { "CIDXFlushThresh:", 105, 107, 0, 0, 1 }, 168454912308SNavdeep Parhar FIELD("CIDX:", 89, 104), 168554912308SNavdeep Parhar FIELD("PIDX:", 73, 88), 168654912308SNavdeep Parhar { "BaseAddress:", 18, 72, 9, 1 }, 168754912308SNavdeep Parhar FIELD("QueueSize:", 2, 17), 168854912308SNavdeep Parhar FIELD1("QueueType:", 1), 168954912308SNavdeep Parhar FIELD1("CachePriority:", 0), 169054912308SNavdeep Parhar { NULL } 169154912308SNavdeep Parhar }; 169254912308SNavdeep Parhar static struct field_desc ingress_t4[] = { 169354912308SNavdeep Parhar FIELD1("NoSnoop:", 145), 169454912308SNavdeep Parhar FIELD1("RelaxedOrdering:", 144), 169554912308SNavdeep Parhar FIELD1("GTSmode:", 143), 169654912308SNavdeep Parhar FIELD1("ISCSICoalescing:", 142), 169754912308SNavdeep Parhar FIELD1("Valid:", 141), 169854912308SNavdeep Parhar FIELD1("TimerPending:", 140), 169954912308SNavdeep Parhar FIELD1("DropRSS:", 139), 170054912308SNavdeep Parhar FIELD("PCIeChannel:", 137, 138), 170154912308SNavdeep Parhar FIELD1("SEInterruptArmed:", 136), 170254912308SNavdeep Parhar FIELD1("CongestionMgtEnable:", 135), 170354912308SNavdeep Parhar FIELD1("DCAIngQEnable:", 134), 170454912308SNavdeep Parhar FIELD("DCACPUID:", 129, 133), 170554912308SNavdeep Parhar FIELD1("UpdateScheduling:", 128), 170654912308SNavdeep Parhar FIELD("UpdateDelivery:", 126, 127), 170754912308SNavdeep Parhar FIELD1("InterruptSent:", 125), 170854912308SNavdeep Parhar FIELD("InterruptIDX:", 114, 124), 170954912308SNavdeep Parhar FIELD1("InterruptDestination:", 113), 171054912308SNavdeep Parhar FIELD1("InterruptArmed:", 112), 171154912308SNavdeep Parhar FIELD("RxIntCounter:", 106, 111), 171254912308SNavdeep Parhar FIELD("RxIntCounterThreshold:", 104, 105), 171354912308SNavdeep Parhar FIELD1("Generation:", 103), 171454912308SNavdeep Parhar { "BaseAddress:", 48, 102, 9, 1 }, 171554912308SNavdeep Parhar FIELD("PIDX:", 32, 47), 171654912308SNavdeep Parhar FIELD("CIDX:", 16, 31), 171754912308SNavdeep Parhar { "QueueSize:", 4, 15, 4, 0 }, 171854912308SNavdeep Parhar { "QueueEntrySize:", 2, 3, 4, 0, 1 }, 171954912308SNavdeep Parhar FIELD1("QueueEntryOverride:", 1), 172054912308SNavdeep Parhar FIELD1("CachePriority:", 0), 172154912308SNavdeep Parhar { NULL } 172254912308SNavdeep Parhar }; 172354912308SNavdeep Parhar static struct field_desc flm_t4[] = { 172454912308SNavdeep Parhar FIELD1("NoSnoop:", 79), 172554912308SNavdeep Parhar FIELD1("RelaxedOrdering:", 78), 172654912308SNavdeep Parhar FIELD1("Valid:", 77), 172754912308SNavdeep Parhar FIELD("DCACPUID:", 72, 76), 172854912308SNavdeep Parhar FIELD1("DCAFLEn:", 71), 172954912308SNavdeep Parhar FIELD("EQid:", 54, 70), 173054912308SNavdeep Parhar FIELD("SplitEn:", 52, 53), 173154912308SNavdeep Parhar FIELD1("PadEn:", 51), 173254912308SNavdeep Parhar FIELD1("PackEn:", 50), 173354912308SNavdeep Parhar FIELD1("DBpriority:", 48), 173454912308SNavdeep Parhar FIELD("PackOffset:", 16, 47), 173554912308SNavdeep Parhar FIELD("CIDX:", 8, 15), 173654912308SNavdeep Parhar FIELD("PIDX:", 0, 7), 173754912308SNavdeep Parhar { NULL } 173854912308SNavdeep Parhar }; 173954912308SNavdeep Parhar static struct field_desc conm_t4[] = { 174054912308SNavdeep Parhar FIELD1("CngDBPHdr:", 6), 174154912308SNavdeep Parhar FIELD1("CngDBPData:", 5), 174254912308SNavdeep Parhar FIELD1("CngIMSG:", 4), 174354912308SNavdeep Parhar { "CngChMap:", 0, 3, 0, 1, 0}, 174454912308SNavdeep Parhar { NULL } 174554912308SNavdeep Parhar }; 174654912308SNavdeep Parhar 174754912308SNavdeep Parhar if (p->mem_id == SGE_CONTEXT_EGRESS) 174854912308SNavdeep Parhar show_struct(p->data, 6, (p->data[0] & 2) ? fl_t4 : egress_t4); 174954912308SNavdeep Parhar else if (p->mem_id == SGE_CONTEXT_FLM) 175054912308SNavdeep Parhar show_struct(p->data, 3, flm_t4); 175154912308SNavdeep Parhar else if (p->mem_id == SGE_CONTEXT_INGRESS) 175254912308SNavdeep Parhar show_struct(p->data, 5, ingress_t4); 175354912308SNavdeep Parhar else if (p->mem_id == SGE_CONTEXT_CNM) 175454912308SNavdeep Parhar show_struct(p->data, 1, conm_t4); 175554912308SNavdeep Parhar } 175654912308SNavdeep Parhar 175754912308SNavdeep Parhar #undef FIELD 175854912308SNavdeep Parhar #undef FIELD1 175954912308SNavdeep Parhar 176054912308SNavdeep Parhar static int 176154912308SNavdeep Parhar get_sge_context(int argc, const char *argv[]) 176254912308SNavdeep Parhar { 176354912308SNavdeep Parhar int rc; 176454912308SNavdeep Parhar char *p; 176554912308SNavdeep Parhar long cid; 176654912308SNavdeep Parhar struct t4_sge_context cntxt = {0}; 176754912308SNavdeep Parhar 176854912308SNavdeep Parhar if (argc != 2) { 176954912308SNavdeep Parhar warnx("sge_context: incorrect number of arguments."); 177054912308SNavdeep Parhar return (EINVAL); 177154912308SNavdeep Parhar } 177254912308SNavdeep Parhar 177354912308SNavdeep Parhar if (!strcmp(argv[0], "egress")) 177454912308SNavdeep Parhar cntxt.mem_id = SGE_CONTEXT_EGRESS; 177554912308SNavdeep Parhar else if (!strcmp(argv[0], "ingress")) 177654912308SNavdeep Parhar cntxt.mem_id = SGE_CONTEXT_INGRESS; 177754912308SNavdeep Parhar else if (!strcmp(argv[0], "fl")) 177854912308SNavdeep Parhar cntxt.mem_id = SGE_CONTEXT_FLM; 177954912308SNavdeep Parhar else if (!strcmp(argv[0], "cong")) 178054912308SNavdeep Parhar cntxt.mem_id = SGE_CONTEXT_CNM; 178154912308SNavdeep Parhar else { 178254912308SNavdeep Parhar warnx("unknown context type \"%s\"; known types are egress, " 178354912308SNavdeep Parhar "ingress, fl, and cong.", argv[0]); 178454912308SNavdeep Parhar return (EINVAL); 178554912308SNavdeep Parhar } 178654912308SNavdeep Parhar 178754912308SNavdeep Parhar p = str_to_number(argv[1], &cid, NULL); 178854912308SNavdeep Parhar if (*p) { 178954912308SNavdeep Parhar warnx("invalid context id \"%s\"", argv[1]); 179054912308SNavdeep Parhar return (EINVAL); 179154912308SNavdeep Parhar } 179254912308SNavdeep Parhar cntxt.cid = cid; 179354912308SNavdeep Parhar 179454912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_SGE_CONTEXT, &cntxt); 179554912308SNavdeep Parhar if (rc != 0) 179654912308SNavdeep Parhar return (rc); 179754912308SNavdeep Parhar 179854912308SNavdeep Parhar if (chip_id == 4) 179954912308SNavdeep Parhar show_t4_ctxt(&cntxt); 180054912308SNavdeep Parhar else 180154912308SNavdeep Parhar show_t5t6_ctxt(&cntxt, chip_id); 180254912308SNavdeep Parhar 180354912308SNavdeep Parhar return (0); 180454912308SNavdeep Parhar } 180554912308SNavdeep Parhar 180654912308SNavdeep Parhar static int 180754912308SNavdeep Parhar loadfw(int argc, const char *argv[]) 180854912308SNavdeep Parhar { 180954912308SNavdeep Parhar int rc, fd; 181054912308SNavdeep Parhar struct t4_data data = {0}; 181154912308SNavdeep Parhar const char *fname = argv[0]; 181254912308SNavdeep Parhar struct stat st = {0}; 181354912308SNavdeep Parhar 181454912308SNavdeep Parhar if (argc != 1) { 181554912308SNavdeep Parhar warnx("loadfw: incorrect number of arguments."); 181654912308SNavdeep Parhar return (EINVAL); 181754912308SNavdeep Parhar } 181854912308SNavdeep Parhar 181954912308SNavdeep Parhar fd = open(fname, O_RDONLY); 182054912308SNavdeep Parhar if (fd < 0) { 182154912308SNavdeep Parhar warn("open(%s)", fname); 182254912308SNavdeep Parhar return (errno); 182354912308SNavdeep Parhar } 182454912308SNavdeep Parhar 182554912308SNavdeep Parhar if (fstat(fd, &st) < 0) { 182654912308SNavdeep Parhar warn("fstat"); 182754912308SNavdeep Parhar close(fd); 182854912308SNavdeep Parhar return (errno); 182954912308SNavdeep Parhar } 183054912308SNavdeep Parhar 183154912308SNavdeep Parhar data.len = st.st_size; 183254912308SNavdeep Parhar data.data = mmap(0, data.len, PROT_READ, MAP_PRIVATE, fd, 0); 183354912308SNavdeep Parhar if (data.data == MAP_FAILED) { 183454912308SNavdeep Parhar warn("mmap"); 183554912308SNavdeep Parhar close(fd); 183654912308SNavdeep Parhar return (errno); 183754912308SNavdeep Parhar } 183854912308SNavdeep Parhar 183954912308SNavdeep Parhar rc = doit(CHELSIO_T4_LOAD_FW, &data); 184054912308SNavdeep Parhar munmap(data.data, data.len); 184154912308SNavdeep Parhar close(fd); 184254912308SNavdeep Parhar return (rc); 184354912308SNavdeep Parhar } 184454912308SNavdeep Parhar 184554912308SNavdeep Parhar static int 184654912308SNavdeep Parhar loadcfg(int argc, const char *argv[]) 184754912308SNavdeep Parhar { 184854912308SNavdeep Parhar int rc, fd; 184954912308SNavdeep Parhar struct t4_data data = {0}; 185054912308SNavdeep Parhar const char *fname = argv[0]; 185154912308SNavdeep Parhar struct stat st = {0}; 185254912308SNavdeep Parhar 185354912308SNavdeep Parhar if (argc != 1) { 185454912308SNavdeep Parhar warnx("loadcfg: incorrect number of arguments."); 185554912308SNavdeep Parhar return (EINVAL); 185654912308SNavdeep Parhar } 185754912308SNavdeep Parhar 185854912308SNavdeep Parhar if (strcmp(fname, "clear") == 0) 185954912308SNavdeep Parhar return (doit(CHELSIO_T4_LOAD_CFG, &data)); 186054912308SNavdeep Parhar 186154912308SNavdeep Parhar fd = open(fname, O_RDONLY); 186254912308SNavdeep Parhar if (fd < 0) { 186354912308SNavdeep Parhar warn("open(%s)", fname); 186454912308SNavdeep Parhar return (errno); 186554912308SNavdeep Parhar } 186654912308SNavdeep Parhar 186754912308SNavdeep Parhar if (fstat(fd, &st) < 0) { 186854912308SNavdeep Parhar warn("fstat"); 186954912308SNavdeep Parhar close(fd); 187054912308SNavdeep Parhar return (errno); 187154912308SNavdeep Parhar } 187254912308SNavdeep Parhar 187354912308SNavdeep Parhar data.len = st.st_size; 187454912308SNavdeep Parhar data.len &= ~3; /* Clip off to make it a multiple of 4 */ 187554912308SNavdeep Parhar data.data = mmap(0, data.len, PROT_READ, MAP_PRIVATE, fd, 0); 187654912308SNavdeep Parhar if (data.data == MAP_FAILED) { 187754912308SNavdeep Parhar warn("mmap"); 187854912308SNavdeep Parhar close(fd); 187954912308SNavdeep Parhar return (errno); 188054912308SNavdeep Parhar } 188154912308SNavdeep Parhar 188254912308SNavdeep Parhar rc = doit(CHELSIO_T4_LOAD_CFG, &data); 188354912308SNavdeep Parhar munmap(data.data, data.len); 188454912308SNavdeep Parhar close(fd); 188554912308SNavdeep Parhar return (rc); 188654912308SNavdeep Parhar } 188754912308SNavdeep Parhar 188854912308SNavdeep Parhar static int 1889f856f099SNavdeep Parhar dumpstate(int argc, const char *argv[]) 1890f856f099SNavdeep Parhar { 1891f856f099SNavdeep Parhar int rc, fd; 1892f856f099SNavdeep Parhar struct t4_cudbg_dump dump = {0}; 1893f856f099SNavdeep Parhar const char *fname = argv[0]; 1894f856f099SNavdeep Parhar 1895f856f099SNavdeep Parhar if (argc != 1) { 1896f856f099SNavdeep Parhar warnx("dumpstate: incorrect number of arguments."); 1897f856f099SNavdeep Parhar return (EINVAL); 1898f856f099SNavdeep Parhar } 1899f856f099SNavdeep Parhar 1900f856f099SNavdeep Parhar dump.wr_flash = 0; 1901f856f099SNavdeep Parhar memset(&dump.bitmap, 0xff, sizeof(dump.bitmap)); 1902f856f099SNavdeep Parhar dump.len = 8 * 1024 * 1024; 1903f856f099SNavdeep Parhar dump.data = malloc(dump.len); 1904f856f099SNavdeep Parhar if (dump.data == NULL) { 1905f856f099SNavdeep Parhar return (ENOMEM); 1906f856f099SNavdeep Parhar } 1907f856f099SNavdeep Parhar 1908f856f099SNavdeep Parhar rc = doit(CHELSIO_T4_CUDBG_DUMP, &dump); 1909313a6435SNavdeep Parhar if (rc != 0) 1910313a6435SNavdeep Parhar goto done; 1911313a6435SNavdeep Parhar 1912313a6435SNavdeep Parhar fd = open(fname, O_CREAT | O_TRUNC | O_EXCL | O_WRONLY, 1913313a6435SNavdeep Parhar S_IRUSR | S_IRGRP | S_IROTH); 1914313a6435SNavdeep Parhar if (fd < 0) { 1915313a6435SNavdeep Parhar warn("open(%s)", fname); 1916313a6435SNavdeep Parhar rc = errno; 1917313a6435SNavdeep Parhar goto done; 1918313a6435SNavdeep Parhar } 1919f856f099SNavdeep Parhar write(fd, dump.data, dump.len); 1920f856f099SNavdeep Parhar close(fd); 1921313a6435SNavdeep Parhar done: 1922313a6435SNavdeep Parhar free(dump.data); 1923f856f099SNavdeep Parhar return (rc); 1924f856f099SNavdeep Parhar } 1925f856f099SNavdeep Parhar 1926f856f099SNavdeep Parhar static int 192754912308SNavdeep Parhar read_mem(uint32_t addr, uint32_t len, void (*output)(uint32_t *, uint32_t)) 192854912308SNavdeep Parhar { 192954912308SNavdeep Parhar int rc; 193054912308SNavdeep Parhar struct t4_mem_range mr; 193154912308SNavdeep Parhar 193254912308SNavdeep Parhar mr.addr = addr; 193354912308SNavdeep Parhar mr.len = len; 193454912308SNavdeep Parhar mr.data = malloc(mr.len); 193554912308SNavdeep Parhar 193654912308SNavdeep Parhar if (mr.data == 0) { 193754912308SNavdeep Parhar warn("read_mem: malloc"); 193854912308SNavdeep Parhar return (errno); 193954912308SNavdeep Parhar } 194054912308SNavdeep Parhar 194154912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_MEM, &mr); 194254912308SNavdeep Parhar if (rc != 0) 194354912308SNavdeep Parhar goto done; 194454912308SNavdeep Parhar 194554912308SNavdeep Parhar if (output) 194654912308SNavdeep Parhar (*output)(mr.data, mr.len); 194754912308SNavdeep Parhar done: 194854912308SNavdeep Parhar free(mr.data); 194954912308SNavdeep Parhar return (rc); 195054912308SNavdeep Parhar } 195154912308SNavdeep Parhar 19528f82718fSNavdeep Parhar static int 19538f82718fSNavdeep Parhar loadboot(int argc, const char *argv[]) 19548f82718fSNavdeep Parhar { 19558f82718fSNavdeep Parhar int rc, fd; 19568f82718fSNavdeep Parhar long l; 19578f82718fSNavdeep Parhar char *p; 19588f82718fSNavdeep Parhar struct t4_bootrom br = {0}; 19598f82718fSNavdeep Parhar const char *fname = argv[0]; 19608f82718fSNavdeep Parhar struct stat st = {0}; 19618f82718fSNavdeep Parhar 19628f82718fSNavdeep Parhar if (argc == 1) { 19638f82718fSNavdeep Parhar br.pf_offset = 0; 19648f82718fSNavdeep Parhar br.pfidx_addr = 0; 19658f82718fSNavdeep Parhar } else if (argc == 3) { 19668f82718fSNavdeep Parhar if (!strcmp(argv[1], "pf")) 19678f82718fSNavdeep Parhar br.pf_offset = 0; 19688f82718fSNavdeep Parhar else if (!strcmp(argv[1], "offset")) 19698f82718fSNavdeep Parhar br.pf_offset = 1; 19708f82718fSNavdeep Parhar else 19718f82718fSNavdeep Parhar return (EINVAL); 19728f82718fSNavdeep Parhar 19738f82718fSNavdeep Parhar p = str_to_number(argv[2], &l, NULL); 19748f82718fSNavdeep Parhar if (*p) 19758f82718fSNavdeep Parhar return (EINVAL); 19768f82718fSNavdeep Parhar br.pfidx_addr = l; 19778f82718fSNavdeep Parhar } else { 19788f82718fSNavdeep Parhar warnx("loadboot: incorrect number of arguments."); 19798f82718fSNavdeep Parhar return (EINVAL); 19808f82718fSNavdeep Parhar } 19818f82718fSNavdeep Parhar 19828f82718fSNavdeep Parhar if (strcmp(fname, "clear") == 0) 19838f82718fSNavdeep Parhar return (doit(CHELSIO_T4_LOAD_BOOT, &br)); 19848f82718fSNavdeep Parhar 19858f82718fSNavdeep Parhar fd = open(fname, O_RDONLY); 19868f82718fSNavdeep Parhar if (fd < 0) { 19878f82718fSNavdeep Parhar warn("open(%s)", fname); 19888f82718fSNavdeep Parhar return (errno); 19898f82718fSNavdeep Parhar } 19908f82718fSNavdeep Parhar 19918f82718fSNavdeep Parhar if (fstat(fd, &st) < 0) { 19928f82718fSNavdeep Parhar warn("fstat"); 19938f82718fSNavdeep Parhar close(fd); 19948f82718fSNavdeep Parhar return (errno); 19958f82718fSNavdeep Parhar } 19968f82718fSNavdeep Parhar 19978f82718fSNavdeep Parhar br.len = st.st_size; 19988f82718fSNavdeep Parhar br.data = mmap(0, br.len, PROT_READ, MAP_PRIVATE, fd, 0); 19998f82718fSNavdeep Parhar if (br.data == MAP_FAILED) { 20008f82718fSNavdeep Parhar warn("mmap"); 20018f82718fSNavdeep Parhar close(fd); 20028f82718fSNavdeep Parhar return (errno); 20038f82718fSNavdeep Parhar } 20048f82718fSNavdeep Parhar 20058f82718fSNavdeep Parhar rc = doit(CHELSIO_T4_LOAD_BOOT, &br); 20068f82718fSNavdeep Parhar munmap(br.data, br.len); 20078f82718fSNavdeep Parhar close(fd); 20088f82718fSNavdeep Parhar return (rc); 20098f82718fSNavdeep Parhar } 20108f82718fSNavdeep Parhar 20118f82718fSNavdeep Parhar static int 20128f82718fSNavdeep Parhar loadbootcfg(int argc, const char *argv[]) 20138f82718fSNavdeep Parhar { 20148f82718fSNavdeep Parhar int rc, fd; 20158f82718fSNavdeep Parhar struct t4_data bc = {0}; 20168f82718fSNavdeep Parhar const char *fname = argv[0]; 20178f82718fSNavdeep Parhar struct stat st = {0}; 20188f82718fSNavdeep Parhar 20198f82718fSNavdeep Parhar if (argc != 1) { 20208f82718fSNavdeep Parhar warnx("loadbootcfg: incorrect number of arguments."); 20218f82718fSNavdeep Parhar return (EINVAL); 20228f82718fSNavdeep Parhar } 20238f82718fSNavdeep Parhar 20248f82718fSNavdeep Parhar if (strcmp(fname, "clear") == 0) 20258f82718fSNavdeep Parhar return (doit(CHELSIO_T4_LOAD_BOOTCFG, &bc)); 20268f82718fSNavdeep Parhar 20278f82718fSNavdeep Parhar fd = open(fname, O_RDONLY); 20288f82718fSNavdeep Parhar if (fd < 0) { 20298f82718fSNavdeep Parhar warn("open(%s)", fname); 20308f82718fSNavdeep Parhar return (errno); 20318f82718fSNavdeep Parhar } 20328f82718fSNavdeep Parhar 20338f82718fSNavdeep Parhar if (fstat(fd, &st) < 0) { 20348f82718fSNavdeep Parhar warn("fstat"); 20358f82718fSNavdeep Parhar close(fd); 20368f82718fSNavdeep Parhar return (errno); 20378f82718fSNavdeep Parhar } 20388f82718fSNavdeep Parhar 20398f82718fSNavdeep Parhar bc.len = st.st_size; 20408f82718fSNavdeep Parhar bc.data = mmap(0, bc.len, PROT_READ, MAP_PRIVATE, fd, 0); 20418f82718fSNavdeep Parhar if (bc.data == MAP_FAILED) { 20428f82718fSNavdeep Parhar warn("mmap"); 20438f82718fSNavdeep Parhar close(fd); 20448f82718fSNavdeep Parhar return (errno); 20458f82718fSNavdeep Parhar } 20468f82718fSNavdeep Parhar 20478f82718fSNavdeep Parhar rc = doit(CHELSIO_T4_LOAD_BOOTCFG, &bc); 20488f82718fSNavdeep Parhar munmap(bc.data, bc.len); 20498f82718fSNavdeep Parhar close(fd); 20508f82718fSNavdeep Parhar return (rc); 20518f82718fSNavdeep Parhar } 20528f82718fSNavdeep Parhar 205354912308SNavdeep Parhar /* 205454912308SNavdeep Parhar * Display memory as list of 'n' 4-byte values per line. 205554912308SNavdeep Parhar */ 205654912308SNavdeep Parhar static void 205754912308SNavdeep Parhar show_mem(uint32_t *buf, uint32_t len) 205854912308SNavdeep Parhar { 205954912308SNavdeep Parhar const char *s; 206054912308SNavdeep Parhar int i, n = 8; 206154912308SNavdeep Parhar 206254912308SNavdeep Parhar while (len) { 206354912308SNavdeep Parhar for (i = 0; len && i < n; i++, buf++, len -= 4) { 206454912308SNavdeep Parhar s = i ? " " : ""; 206554912308SNavdeep Parhar printf("%s%08x", s, htonl(*buf)); 206654912308SNavdeep Parhar } 206754912308SNavdeep Parhar printf("\n"); 206854912308SNavdeep Parhar } 206954912308SNavdeep Parhar } 207054912308SNavdeep Parhar 207154912308SNavdeep Parhar static int 207254912308SNavdeep Parhar memdump(int argc, const char *argv[]) 207354912308SNavdeep Parhar { 207454912308SNavdeep Parhar char *p; 207554912308SNavdeep Parhar long l; 207654912308SNavdeep Parhar uint32_t addr, len; 207754912308SNavdeep Parhar 207854912308SNavdeep Parhar if (argc != 2) { 207954912308SNavdeep Parhar warnx("incorrect number of arguments."); 208054912308SNavdeep Parhar return (EINVAL); 208154912308SNavdeep Parhar } 208254912308SNavdeep Parhar 208354912308SNavdeep Parhar p = str_to_number(argv[0], &l, NULL); 208454912308SNavdeep Parhar if (*p) { 208554912308SNavdeep Parhar warnx("invalid address \"%s\"", argv[0]); 208654912308SNavdeep Parhar return (EINVAL); 208754912308SNavdeep Parhar } 208854912308SNavdeep Parhar addr = l; 208954912308SNavdeep Parhar 209054912308SNavdeep Parhar p = str_to_number(argv[1], &l, NULL); 209154912308SNavdeep Parhar if (*p) { 209254912308SNavdeep Parhar warnx("memdump: invalid length \"%s\"", argv[1]); 209354912308SNavdeep Parhar return (EINVAL); 209454912308SNavdeep Parhar } 209554912308SNavdeep Parhar len = l; 209654912308SNavdeep Parhar 209754912308SNavdeep Parhar return (read_mem(addr, len, show_mem)); 209854912308SNavdeep Parhar } 209954912308SNavdeep Parhar 210054912308SNavdeep Parhar /* 210154912308SNavdeep Parhar * Display TCB as list of 'n' 4-byte values per line. 210254912308SNavdeep Parhar */ 210354912308SNavdeep Parhar static void 210454912308SNavdeep Parhar show_tcb(uint32_t *buf, uint32_t len) 210554912308SNavdeep Parhar { 2106*ae9b4017SNavdeep Parhar unsigned char *tcb = (unsigned char *)buf; 210754912308SNavdeep Parhar const char *s; 210854912308SNavdeep Parhar int i, n = 8; 210954912308SNavdeep Parhar 211054912308SNavdeep Parhar while (len) { 211154912308SNavdeep Parhar for (i = 0; len && i < n; i++, buf++, len -= 4) { 211254912308SNavdeep Parhar s = i ? " " : ""; 211354912308SNavdeep Parhar printf("%s%08x", s, htonl(*buf)); 211454912308SNavdeep Parhar } 211554912308SNavdeep Parhar printf("\n"); 211654912308SNavdeep Parhar } 2117*ae9b4017SNavdeep Parhar set_tcb_info(TIDTYPE_TCB, chip_id); 2118*ae9b4017SNavdeep Parhar set_print_style(PRNTSTYL_COMP); 2119*ae9b4017SNavdeep Parhar swizzle_tcb(tcb); 2120*ae9b4017SNavdeep Parhar parse_n_display_xcb(tcb); 212154912308SNavdeep Parhar } 212254912308SNavdeep Parhar 212354912308SNavdeep Parhar #define A_TP_CMM_TCB_BASE 0x7d10 212454912308SNavdeep Parhar #define TCB_SIZE 128 212554912308SNavdeep Parhar static int 212654912308SNavdeep Parhar read_tcb(int argc, const char *argv[]) 212754912308SNavdeep Parhar { 212854912308SNavdeep Parhar char *p; 212954912308SNavdeep Parhar long l; 213054912308SNavdeep Parhar long long val; 213154912308SNavdeep Parhar unsigned int tid; 213254912308SNavdeep Parhar uint32_t addr; 213354912308SNavdeep Parhar int rc; 213454912308SNavdeep Parhar 213554912308SNavdeep Parhar if (argc != 1) { 213654912308SNavdeep Parhar warnx("incorrect number of arguments."); 213754912308SNavdeep Parhar return (EINVAL); 213854912308SNavdeep Parhar } 213954912308SNavdeep Parhar 214054912308SNavdeep Parhar p = str_to_number(argv[0], &l, NULL); 214154912308SNavdeep Parhar if (*p) { 214254912308SNavdeep Parhar warnx("invalid tid \"%s\"", argv[0]); 214354912308SNavdeep Parhar return (EINVAL); 214454912308SNavdeep Parhar } 214554912308SNavdeep Parhar tid = l; 214654912308SNavdeep Parhar 214754912308SNavdeep Parhar rc = read_reg(A_TP_CMM_TCB_BASE, 4, &val); 214854912308SNavdeep Parhar if (rc != 0) 214954912308SNavdeep Parhar return (rc); 215054912308SNavdeep Parhar 215154912308SNavdeep Parhar addr = val + tid * TCB_SIZE; 215254912308SNavdeep Parhar 215354912308SNavdeep Parhar return (read_mem(addr, TCB_SIZE, show_tcb)); 215454912308SNavdeep Parhar } 215554912308SNavdeep Parhar 215654912308SNavdeep Parhar static int 215754912308SNavdeep Parhar read_i2c(int argc, const char *argv[]) 215854912308SNavdeep Parhar { 215954912308SNavdeep Parhar char *p; 216054912308SNavdeep Parhar long l; 216154912308SNavdeep Parhar struct t4_i2c_data i2cd; 216254912308SNavdeep Parhar int rc, i; 216354912308SNavdeep Parhar 216454912308SNavdeep Parhar if (argc < 3 || argc > 4) { 216554912308SNavdeep Parhar warnx("incorrect number of arguments."); 216654912308SNavdeep Parhar return (EINVAL); 216754912308SNavdeep Parhar } 216854912308SNavdeep Parhar 216954912308SNavdeep Parhar p = str_to_number(argv[0], &l, NULL); 217054912308SNavdeep Parhar if (*p || l > UCHAR_MAX) { 217154912308SNavdeep Parhar warnx("invalid port id \"%s\"", argv[0]); 217254912308SNavdeep Parhar return (EINVAL); 217354912308SNavdeep Parhar } 217454912308SNavdeep Parhar i2cd.port_id = l; 217554912308SNavdeep Parhar 217654912308SNavdeep Parhar p = str_to_number(argv[1], &l, NULL); 217754912308SNavdeep Parhar if (*p || l > UCHAR_MAX) { 217854912308SNavdeep Parhar warnx("invalid i2c device address \"%s\"", argv[1]); 217954912308SNavdeep Parhar return (EINVAL); 218054912308SNavdeep Parhar } 218154912308SNavdeep Parhar i2cd.dev_addr = l; 218254912308SNavdeep Parhar 218354912308SNavdeep Parhar p = str_to_number(argv[2], &l, NULL); 218454912308SNavdeep Parhar if (*p || l > UCHAR_MAX) { 218554912308SNavdeep Parhar warnx("invalid byte offset \"%s\"", argv[2]); 218654912308SNavdeep Parhar return (EINVAL); 218754912308SNavdeep Parhar } 218854912308SNavdeep Parhar i2cd.offset = l; 218954912308SNavdeep Parhar 219054912308SNavdeep Parhar if (argc == 4) { 219154912308SNavdeep Parhar p = str_to_number(argv[3], &l, NULL); 219254912308SNavdeep Parhar if (*p || l > sizeof(i2cd.data)) { 219354912308SNavdeep Parhar warnx("invalid number of bytes \"%s\"", argv[3]); 219454912308SNavdeep Parhar return (EINVAL); 219554912308SNavdeep Parhar } 219654912308SNavdeep Parhar i2cd.len = l; 219754912308SNavdeep Parhar } else 219854912308SNavdeep Parhar i2cd.len = 1; 219954912308SNavdeep Parhar 220054912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_I2C, &i2cd); 220154912308SNavdeep Parhar if (rc != 0) 220254912308SNavdeep Parhar return (rc); 220354912308SNavdeep Parhar 220454912308SNavdeep Parhar for (i = 0; i < i2cd.len; i++) 220554912308SNavdeep Parhar printf("0x%x [%u]\n", i2cd.data[i], i2cd.data[i]); 220654912308SNavdeep Parhar 220754912308SNavdeep Parhar return (0); 220854912308SNavdeep Parhar } 220954912308SNavdeep Parhar 221054912308SNavdeep Parhar static int 221154912308SNavdeep Parhar clearstats(int argc, const char *argv[]) 221254912308SNavdeep Parhar { 221354912308SNavdeep Parhar char *p; 221454912308SNavdeep Parhar long l; 221554912308SNavdeep Parhar uint32_t port; 221654912308SNavdeep Parhar 221754912308SNavdeep Parhar if (argc != 1) { 221854912308SNavdeep Parhar warnx("incorrect number of arguments."); 221954912308SNavdeep Parhar return (EINVAL); 222054912308SNavdeep Parhar } 222154912308SNavdeep Parhar 222254912308SNavdeep Parhar p = str_to_number(argv[0], &l, NULL); 222354912308SNavdeep Parhar if (*p) { 222454912308SNavdeep Parhar warnx("invalid port id \"%s\"", argv[0]); 222554912308SNavdeep Parhar return (EINVAL); 222654912308SNavdeep Parhar } 222754912308SNavdeep Parhar port = l; 222854912308SNavdeep Parhar 222954912308SNavdeep Parhar return doit(CHELSIO_T4_CLEAR_STATS, &port); 223054912308SNavdeep Parhar } 223154912308SNavdeep Parhar 223254912308SNavdeep Parhar static int 223354912308SNavdeep Parhar show_tracers(void) 223454912308SNavdeep Parhar { 223554912308SNavdeep Parhar struct t4_tracer t; 223654912308SNavdeep Parhar char *s; 223754912308SNavdeep Parhar int rc, port_idx, i; 223854912308SNavdeep Parhar long long val; 223954912308SNavdeep Parhar 224054912308SNavdeep Parhar /* Magic values: MPS_TRC_CFG = 0x9800. MPS_TRC_CFG[1:1] = TrcEn */ 224154912308SNavdeep Parhar rc = read_reg(0x9800, 4, &val); 224254912308SNavdeep Parhar if (rc != 0) 224354912308SNavdeep Parhar return (rc); 224454912308SNavdeep Parhar printf("tracing is %s\n", val & 2 ? "ENABLED" : "DISABLED"); 224554912308SNavdeep Parhar 224654912308SNavdeep Parhar t.idx = 0; 224754912308SNavdeep Parhar for (t.idx = 0; ; t.idx++) { 224854912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_TRACER, &t); 224954912308SNavdeep Parhar if (rc != 0 || t.idx == 0xff) 225054912308SNavdeep Parhar break; 225154912308SNavdeep Parhar 225254912308SNavdeep Parhar if (t.tp.port < 4) { 225354912308SNavdeep Parhar s = "Rx"; 225454912308SNavdeep Parhar port_idx = t.tp.port; 225554912308SNavdeep Parhar } else if (t.tp.port < 8) { 225654912308SNavdeep Parhar s = "Tx"; 225754912308SNavdeep Parhar port_idx = t.tp.port - 4; 225854912308SNavdeep Parhar } else if (t.tp.port < 12) { 225954912308SNavdeep Parhar s = "loopback"; 226054912308SNavdeep Parhar port_idx = t.tp.port - 8; 226154912308SNavdeep Parhar } else if (t.tp.port < 16) { 226254912308SNavdeep Parhar s = "MPS Rx"; 226354912308SNavdeep Parhar port_idx = t.tp.port - 12; 226454912308SNavdeep Parhar } else if (t.tp.port < 20) { 226554912308SNavdeep Parhar s = "MPS Tx"; 226654912308SNavdeep Parhar port_idx = t.tp.port - 16; 226754912308SNavdeep Parhar } else { 226854912308SNavdeep Parhar s = "unknown"; 226954912308SNavdeep Parhar port_idx = t.tp.port; 227054912308SNavdeep Parhar } 227154912308SNavdeep Parhar 227254912308SNavdeep Parhar printf("\ntracer %u (currently %s) captures ", t.idx, 227354912308SNavdeep Parhar t.enabled ? "ENABLED" : "DISABLED"); 227454912308SNavdeep Parhar if (t.tp.port < 8) 227554912308SNavdeep Parhar printf("port %u %s, ", port_idx, s); 227654912308SNavdeep Parhar else 227754912308SNavdeep Parhar printf("%s %u, ", s, port_idx); 227854912308SNavdeep Parhar printf("snap length: %u, min length: %u\n", t.tp.snap_len, 227954912308SNavdeep Parhar t.tp.min_len); 228054912308SNavdeep Parhar printf("packets captured %smatch filter\n", 228154912308SNavdeep Parhar t.tp.invert ? "do not " : ""); 228254912308SNavdeep Parhar if (t.tp.skip_ofst) { 228354912308SNavdeep Parhar printf("filter pattern: "); 228454912308SNavdeep Parhar for (i = 0; i < t.tp.skip_ofst * 2; i += 2) 228554912308SNavdeep Parhar printf("%08x%08x", t.tp.data[i], 228654912308SNavdeep Parhar t.tp.data[i + 1]); 228754912308SNavdeep Parhar printf("/"); 228854912308SNavdeep Parhar for (i = 0; i < t.tp.skip_ofst * 2; i += 2) 228954912308SNavdeep Parhar printf("%08x%08x", t.tp.mask[i], 229054912308SNavdeep Parhar t.tp.mask[i + 1]); 229154912308SNavdeep Parhar printf("@0\n"); 229254912308SNavdeep Parhar } 229354912308SNavdeep Parhar printf("filter pattern: "); 229454912308SNavdeep Parhar for (i = t.tp.skip_ofst * 2; i < T4_TRACE_LEN / 4; i += 2) 229554912308SNavdeep Parhar printf("%08x%08x", t.tp.data[i], t.tp.data[i + 1]); 229654912308SNavdeep Parhar printf("/"); 229754912308SNavdeep Parhar for (i = t.tp.skip_ofst * 2; i < T4_TRACE_LEN / 4; i += 2) 229854912308SNavdeep Parhar printf("%08x%08x", t.tp.mask[i], t.tp.mask[i + 1]); 229954912308SNavdeep Parhar printf("@%u\n", (t.tp.skip_ofst + t.tp.skip_len) * 8); 230054912308SNavdeep Parhar } 230154912308SNavdeep Parhar 230254912308SNavdeep Parhar return (rc); 230354912308SNavdeep Parhar } 230454912308SNavdeep Parhar 230554912308SNavdeep Parhar static int 230654912308SNavdeep Parhar tracer_onoff(uint8_t idx, int enabled) 230754912308SNavdeep Parhar { 230854912308SNavdeep Parhar struct t4_tracer t; 230954912308SNavdeep Parhar 231054912308SNavdeep Parhar t.idx = idx; 231154912308SNavdeep Parhar t.enabled = enabled; 231254912308SNavdeep Parhar t.valid = 0; 231354912308SNavdeep Parhar 231454912308SNavdeep Parhar return doit(CHELSIO_T4_SET_TRACER, &t); 231554912308SNavdeep Parhar } 231654912308SNavdeep Parhar 231754912308SNavdeep Parhar static void 231854912308SNavdeep Parhar create_tracing_ifnet() 231954912308SNavdeep Parhar { 232054912308SNavdeep Parhar char *cmd[] = { 232154912308SNavdeep Parhar "/sbin/ifconfig", __DECONST(char *, nexus), "create", NULL 232254912308SNavdeep Parhar }; 232354912308SNavdeep Parhar char *env[] = {NULL}; 232454912308SNavdeep Parhar 232554912308SNavdeep Parhar if (vfork() == 0) { 232654912308SNavdeep Parhar close(STDERR_FILENO); 232754912308SNavdeep Parhar execve(cmd[0], cmd, env); 232854912308SNavdeep Parhar _exit(0); 232954912308SNavdeep Parhar } 233054912308SNavdeep Parhar } 233154912308SNavdeep Parhar 233254912308SNavdeep Parhar /* 233354912308SNavdeep Parhar * XXX: Allow user to specify snaplen, minlen, and pattern (including inverted 233454912308SNavdeep Parhar * matching). Right now this is a quick-n-dirty implementation that traces the 233554912308SNavdeep Parhar * first 128B of all tx or rx on a port 233654912308SNavdeep Parhar */ 233754912308SNavdeep Parhar static int 233854912308SNavdeep Parhar set_tracer(uint8_t idx, int argc, const char *argv[]) 233954912308SNavdeep Parhar { 234054912308SNavdeep Parhar struct t4_tracer t; 234154912308SNavdeep Parhar int len, port; 234254912308SNavdeep Parhar 234354912308SNavdeep Parhar bzero(&t, sizeof (t)); 234454912308SNavdeep Parhar t.idx = idx; 234554912308SNavdeep Parhar t.enabled = 1; 234654912308SNavdeep Parhar t.valid = 1; 234754912308SNavdeep Parhar 234854912308SNavdeep Parhar if (argc != 1) { 234954912308SNavdeep Parhar warnx("must specify tx<n> or rx<n>."); 235054912308SNavdeep Parhar return (EINVAL); 235154912308SNavdeep Parhar } 235254912308SNavdeep Parhar 235354912308SNavdeep Parhar len = strlen(argv[0]); 235454912308SNavdeep Parhar if (len != 3) { 235554912308SNavdeep Parhar warnx("argument must be 3 characters (tx<n> or rx<n>)"); 235654912308SNavdeep Parhar return (EINVAL); 235754912308SNavdeep Parhar } 235854912308SNavdeep Parhar 235954912308SNavdeep Parhar if (strncmp(argv[0], "tx", 2) == 0) { 236054912308SNavdeep Parhar port = argv[0][2] - '0'; 236154912308SNavdeep Parhar if (port < 0 || port > 3) { 236254912308SNavdeep Parhar warnx("'%c' in %s is invalid", argv[0][2], argv[0]); 236354912308SNavdeep Parhar return (EINVAL); 236454912308SNavdeep Parhar } 236554912308SNavdeep Parhar port += 4; 236654912308SNavdeep Parhar } else if (strncmp(argv[0], "rx", 2) == 0) { 236754912308SNavdeep Parhar port = argv[0][2] - '0'; 236854912308SNavdeep Parhar if (port < 0 || port > 3) { 236954912308SNavdeep Parhar warnx("'%c' in %s is invalid", argv[0][2], argv[0]); 237054912308SNavdeep Parhar return (EINVAL); 237154912308SNavdeep Parhar } 237254912308SNavdeep Parhar } else { 237354912308SNavdeep Parhar warnx("argument '%s' isn't tx<n> or rx<n>", argv[0]); 237454912308SNavdeep Parhar return (EINVAL); 237554912308SNavdeep Parhar } 237654912308SNavdeep Parhar 237754912308SNavdeep Parhar t.tp.snap_len = 128; 237854912308SNavdeep Parhar t.tp.min_len = 0; 237954912308SNavdeep Parhar t.tp.skip_ofst = 0; 238054912308SNavdeep Parhar t.tp.skip_len = 0; 238154912308SNavdeep Parhar t.tp.invert = 0; 238254912308SNavdeep Parhar t.tp.port = port; 238354912308SNavdeep Parhar 238454912308SNavdeep Parhar create_tracing_ifnet(); 238554912308SNavdeep Parhar return doit(CHELSIO_T4_SET_TRACER, &t); 238654912308SNavdeep Parhar } 238754912308SNavdeep Parhar 238854912308SNavdeep Parhar static int 238954912308SNavdeep Parhar tracer_cmd(int argc, const char *argv[]) 239054912308SNavdeep Parhar { 239154912308SNavdeep Parhar long long val; 239254912308SNavdeep Parhar uint8_t idx; 239354912308SNavdeep Parhar char *s; 239454912308SNavdeep Parhar 239554912308SNavdeep Parhar if (argc == 0) { 239654912308SNavdeep Parhar warnx("tracer: no arguments."); 239754912308SNavdeep Parhar return (EINVAL); 239854912308SNavdeep Parhar }; 239954912308SNavdeep Parhar 240054912308SNavdeep Parhar /* list */ 240154912308SNavdeep Parhar if (strcmp(argv[0], "list") == 0) { 240254912308SNavdeep Parhar if (argc != 1) 240354912308SNavdeep Parhar warnx("trailing arguments after \"list\" ignored."); 240454912308SNavdeep Parhar 240554912308SNavdeep Parhar return show_tracers(); 240654912308SNavdeep Parhar } 240754912308SNavdeep Parhar 240854912308SNavdeep Parhar /* <idx> ... */ 240954912308SNavdeep Parhar s = str_to_number(argv[0], NULL, &val); 241054912308SNavdeep Parhar if (*s || val > 0xff) { 241154912308SNavdeep Parhar warnx("\"%s\" is neither an index nor a tracer subcommand.", 241254912308SNavdeep Parhar argv[0]); 241354912308SNavdeep Parhar return (EINVAL); 241454912308SNavdeep Parhar } 241554912308SNavdeep Parhar idx = (int8_t)val; 241654912308SNavdeep Parhar 241754912308SNavdeep Parhar /* <idx> disable */ 241854912308SNavdeep Parhar if (argc == 2 && strcmp(argv[1], "disable") == 0) 241954912308SNavdeep Parhar return tracer_onoff(idx, 0); 242054912308SNavdeep Parhar 242154912308SNavdeep Parhar /* <idx> enable */ 242254912308SNavdeep Parhar if (argc == 2 && strcmp(argv[1], "enable") == 0) 242354912308SNavdeep Parhar return tracer_onoff(idx, 1); 242454912308SNavdeep Parhar 242554912308SNavdeep Parhar /* <idx> ... */ 242654912308SNavdeep Parhar return set_tracer(idx, argc - 1, argv + 1); 242754912308SNavdeep Parhar } 242854912308SNavdeep Parhar 242954912308SNavdeep Parhar static int 243054912308SNavdeep Parhar modinfo_raw(int port_id) 243154912308SNavdeep Parhar { 243254912308SNavdeep Parhar uint8_t offset; 243354912308SNavdeep Parhar struct t4_i2c_data i2cd; 243454912308SNavdeep Parhar int rc; 243554912308SNavdeep Parhar 243654912308SNavdeep Parhar for (offset = 0; offset < 96; offset += sizeof(i2cd.data)) { 243754912308SNavdeep Parhar bzero(&i2cd, sizeof(i2cd)); 243854912308SNavdeep Parhar i2cd.port_id = port_id; 243954912308SNavdeep Parhar i2cd.dev_addr = 0xa0; 244054912308SNavdeep Parhar i2cd.offset = offset; 244154912308SNavdeep Parhar i2cd.len = sizeof(i2cd.data); 244254912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_I2C, &i2cd); 244354912308SNavdeep Parhar if (rc != 0) 244454912308SNavdeep Parhar return (rc); 244554912308SNavdeep Parhar printf("%02x: %02x %02x %02x %02x %02x %02x %02x %02x", 244654912308SNavdeep Parhar offset, i2cd.data[0], i2cd.data[1], i2cd.data[2], 244754912308SNavdeep Parhar i2cd.data[3], i2cd.data[4], i2cd.data[5], i2cd.data[6], 244854912308SNavdeep Parhar i2cd.data[7]); 244954912308SNavdeep Parhar 245054912308SNavdeep Parhar printf(" %c%c%c%c %c%c%c%c\n", 245154912308SNavdeep Parhar isprint(i2cd.data[0]) ? i2cd.data[0] : '.', 245254912308SNavdeep Parhar isprint(i2cd.data[1]) ? i2cd.data[1] : '.', 245354912308SNavdeep Parhar isprint(i2cd.data[2]) ? i2cd.data[2] : '.', 245454912308SNavdeep Parhar isprint(i2cd.data[3]) ? i2cd.data[3] : '.', 245554912308SNavdeep Parhar isprint(i2cd.data[4]) ? i2cd.data[4] : '.', 245654912308SNavdeep Parhar isprint(i2cd.data[5]) ? i2cd.data[5] : '.', 245754912308SNavdeep Parhar isprint(i2cd.data[6]) ? i2cd.data[6] : '.', 245854912308SNavdeep Parhar isprint(i2cd.data[7]) ? i2cd.data[7] : '.'); 245954912308SNavdeep Parhar } 246054912308SNavdeep Parhar 246154912308SNavdeep Parhar return (0); 246254912308SNavdeep Parhar } 246354912308SNavdeep Parhar 246454912308SNavdeep Parhar static int 246554912308SNavdeep Parhar modinfo(int argc, const char *argv[]) 246654912308SNavdeep Parhar { 246754912308SNavdeep Parhar long port; 246854912308SNavdeep Parhar char string[16], *p; 246954912308SNavdeep Parhar struct t4_i2c_data i2cd; 247054912308SNavdeep Parhar int rc, i; 247154912308SNavdeep Parhar uint16_t temp, vcc, tx_bias, tx_power, rx_power; 247254912308SNavdeep Parhar 247354912308SNavdeep Parhar if (argc < 1) { 247454912308SNavdeep Parhar warnx("must supply a port"); 247554912308SNavdeep Parhar return (EINVAL); 247654912308SNavdeep Parhar } 247754912308SNavdeep Parhar 247854912308SNavdeep Parhar if (argc > 2) { 247954912308SNavdeep Parhar warnx("too many arguments"); 248054912308SNavdeep Parhar return (EINVAL); 248154912308SNavdeep Parhar } 248254912308SNavdeep Parhar 248354912308SNavdeep Parhar p = str_to_number(argv[0], &port, NULL); 248454912308SNavdeep Parhar if (*p || port > UCHAR_MAX) { 248554912308SNavdeep Parhar warnx("invalid port id \"%s\"", argv[0]); 248654912308SNavdeep Parhar return (EINVAL); 248754912308SNavdeep Parhar } 248854912308SNavdeep Parhar 248954912308SNavdeep Parhar if (argc == 2) { 249054912308SNavdeep Parhar if (!strcmp(argv[1], "raw")) 249154912308SNavdeep Parhar return (modinfo_raw(port)); 249254912308SNavdeep Parhar else { 249354912308SNavdeep Parhar warnx("second argument can only be \"raw\""); 249454912308SNavdeep Parhar return (EINVAL); 249554912308SNavdeep Parhar } 249654912308SNavdeep Parhar } 249754912308SNavdeep Parhar 249854912308SNavdeep Parhar bzero(&i2cd, sizeof(i2cd)); 249954912308SNavdeep Parhar i2cd.len = 1; 250054912308SNavdeep Parhar i2cd.port_id = port; 250154912308SNavdeep Parhar i2cd.dev_addr = SFF_8472_BASE; 250254912308SNavdeep Parhar 250354912308SNavdeep Parhar i2cd.offset = SFF_8472_ID; 250454912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 250554912308SNavdeep Parhar goto fail; 250654912308SNavdeep Parhar 250754912308SNavdeep Parhar if (i2cd.data[0] > SFF_8472_ID_LAST) 250854912308SNavdeep Parhar printf("Unknown ID\n"); 250954912308SNavdeep Parhar else 251054912308SNavdeep Parhar printf("ID: %s\n", sff_8472_id[i2cd.data[0]]); 251154912308SNavdeep Parhar 251254912308SNavdeep Parhar bzero(&string, sizeof(string)); 251354912308SNavdeep Parhar for (i = SFF_8472_VENDOR_START; i < SFF_8472_VENDOR_END; i++) { 251454912308SNavdeep Parhar i2cd.offset = i; 251554912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 251654912308SNavdeep Parhar goto fail; 251754912308SNavdeep Parhar string[i - SFF_8472_VENDOR_START] = i2cd.data[0]; 251854912308SNavdeep Parhar } 251954912308SNavdeep Parhar printf("Vendor %s\n", string); 252054912308SNavdeep Parhar 252154912308SNavdeep Parhar bzero(&string, sizeof(string)); 252254912308SNavdeep Parhar for (i = SFF_8472_SN_START; i < SFF_8472_SN_END; i++) { 252354912308SNavdeep Parhar i2cd.offset = i; 252454912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 252554912308SNavdeep Parhar goto fail; 252654912308SNavdeep Parhar string[i - SFF_8472_SN_START] = i2cd.data[0]; 252754912308SNavdeep Parhar } 252854912308SNavdeep Parhar printf("SN %s\n", string); 252954912308SNavdeep Parhar 253054912308SNavdeep Parhar bzero(&string, sizeof(string)); 253154912308SNavdeep Parhar for (i = SFF_8472_PN_START; i < SFF_8472_PN_END; i++) { 253254912308SNavdeep Parhar i2cd.offset = i; 253354912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 253454912308SNavdeep Parhar goto fail; 253554912308SNavdeep Parhar string[i - SFF_8472_PN_START] = i2cd.data[0]; 253654912308SNavdeep Parhar } 253754912308SNavdeep Parhar printf("PN %s\n", string); 253854912308SNavdeep Parhar 253954912308SNavdeep Parhar bzero(&string, sizeof(string)); 254054912308SNavdeep Parhar for (i = SFF_8472_REV_START; i < SFF_8472_REV_END; i++) { 254154912308SNavdeep Parhar i2cd.offset = i; 254254912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 254354912308SNavdeep Parhar goto fail; 254454912308SNavdeep Parhar string[i - SFF_8472_REV_START] = i2cd.data[0]; 254554912308SNavdeep Parhar } 254654912308SNavdeep Parhar printf("Rev %s\n", string); 254754912308SNavdeep Parhar 254854912308SNavdeep Parhar i2cd.offset = SFF_8472_DIAG_TYPE; 254954912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 255054912308SNavdeep Parhar goto fail; 255154912308SNavdeep Parhar 255254912308SNavdeep Parhar if ((char )i2cd.data[0] & (SFF_8472_DIAG_IMPL | 255354912308SNavdeep Parhar SFF_8472_DIAG_INTERNAL)) { 255454912308SNavdeep Parhar 255554912308SNavdeep Parhar /* Switch to reading from the Diagnostic address. */ 255654912308SNavdeep Parhar i2cd.dev_addr = SFF_8472_DIAG; 255754912308SNavdeep Parhar i2cd.len = 1; 255854912308SNavdeep Parhar 255954912308SNavdeep Parhar i2cd.offset = SFF_8472_TEMP; 256054912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 256154912308SNavdeep Parhar goto fail; 256254912308SNavdeep Parhar temp = i2cd.data[0] << 8; 256354912308SNavdeep Parhar printf("Temp: "); 256454912308SNavdeep Parhar if ((temp & SFF_8472_TEMP_SIGN) == SFF_8472_TEMP_SIGN) 256554912308SNavdeep Parhar printf("-"); 256654912308SNavdeep Parhar else 256754912308SNavdeep Parhar printf("+"); 256854912308SNavdeep Parhar printf("%dC\n", (temp & SFF_8472_TEMP_MSK) >> 256954912308SNavdeep Parhar SFF_8472_TEMP_SHIFT); 257054912308SNavdeep Parhar 257154912308SNavdeep Parhar i2cd.offset = SFF_8472_VCC; 257254912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 257354912308SNavdeep Parhar goto fail; 257454912308SNavdeep Parhar vcc = i2cd.data[0] << 8; 257554912308SNavdeep Parhar printf("Vcc %fV\n", vcc / SFF_8472_VCC_FACTOR); 257654912308SNavdeep Parhar 257754912308SNavdeep Parhar i2cd.offset = SFF_8472_TX_BIAS; 257854912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 257954912308SNavdeep Parhar goto fail; 258054912308SNavdeep Parhar tx_bias = i2cd.data[0] << 8; 258154912308SNavdeep Parhar printf("TX Bias %fuA\n", tx_bias / SFF_8472_BIAS_FACTOR); 258254912308SNavdeep Parhar 258354912308SNavdeep Parhar i2cd.offset = SFF_8472_TX_POWER; 258454912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 258554912308SNavdeep Parhar goto fail; 258654912308SNavdeep Parhar tx_power = i2cd.data[0] << 8; 258754912308SNavdeep Parhar printf("TX Power %fmW\n", tx_power / SFF_8472_POWER_FACTOR); 258854912308SNavdeep Parhar 258954912308SNavdeep Parhar i2cd.offset = SFF_8472_RX_POWER; 259054912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 259154912308SNavdeep Parhar goto fail; 259254912308SNavdeep Parhar rx_power = i2cd.data[0] << 8; 259354912308SNavdeep Parhar printf("RX Power %fmW\n", rx_power / SFF_8472_POWER_FACTOR); 259454912308SNavdeep Parhar 259554912308SNavdeep Parhar } else 259654912308SNavdeep Parhar printf("Diagnostics not supported.\n"); 259754912308SNavdeep Parhar 259854912308SNavdeep Parhar return(0); 259954912308SNavdeep Parhar 260054912308SNavdeep Parhar fail: 260154912308SNavdeep Parhar if (rc == EPERM) 260254912308SNavdeep Parhar warnx("No module/cable in port %ld", port); 260354912308SNavdeep Parhar return (rc); 260454912308SNavdeep Parhar 260554912308SNavdeep Parhar } 260654912308SNavdeep Parhar 260754912308SNavdeep Parhar /* XXX: pass in a low/high and do range checks as well */ 260854912308SNavdeep Parhar static int 260954912308SNavdeep Parhar get_sched_param(const char *param, const char *args[], long *val) 261054912308SNavdeep Parhar { 261154912308SNavdeep Parhar char *p; 261254912308SNavdeep Parhar 261354912308SNavdeep Parhar if (strcmp(param, args[0]) != 0) 261454912308SNavdeep Parhar return (EINVAL); 261554912308SNavdeep Parhar 261654912308SNavdeep Parhar p = str_to_number(args[1], val, NULL); 261754912308SNavdeep Parhar if (*p) { 261854912308SNavdeep Parhar warnx("parameter \"%s\" has bad value \"%s\"", args[0], 261954912308SNavdeep Parhar args[1]); 262054912308SNavdeep Parhar return (EINVAL); 262154912308SNavdeep Parhar } 262254912308SNavdeep Parhar 262354912308SNavdeep Parhar return (0); 262454912308SNavdeep Parhar } 262554912308SNavdeep Parhar 262654912308SNavdeep Parhar static int 262754912308SNavdeep Parhar sched_class(int argc, const char *argv[]) 262854912308SNavdeep Parhar { 262954912308SNavdeep Parhar struct t4_sched_params op; 263054912308SNavdeep Parhar int errs, i; 263154912308SNavdeep Parhar 263254912308SNavdeep Parhar memset(&op, 0xff, sizeof(op)); 263354912308SNavdeep Parhar op.subcmd = -1; 263454912308SNavdeep Parhar op.type = -1; 263554912308SNavdeep Parhar if (argc == 0) { 263654912308SNavdeep Parhar warnx("missing scheduling sub-command"); 263754912308SNavdeep Parhar return (EINVAL); 263854912308SNavdeep Parhar } 263954912308SNavdeep Parhar if (!strcmp(argv[0], "config")) { 264054912308SNavdeep Parhar op.subcmd = SCHED_CLASS_SUBCMD_CONFIG; 264154912308SNavdeep Parhar op.u.config.minmax = -1; 264254912308SNavdeep Parhar } else if (!strcmp(argv[0], "params")) { 264354912308SNavdeep Parhar op.subcmd = SCHED_CLASS_SUBCMD_PARAMS; 264454912308SNavdeep Parhar op.u.params.level = op.u.params.mode = op.u.params.rateunit = 264554912308SNavdeep Parhar op.u.params.ratemode = op.u.params.channel = 264654912308SNavdeep Parhar op.u.params.cl = op.u.params.minrate = op.u.params.maxrate = 264754912308SNavdeep Parhar op.u.params.weight = op.u.params.pktsize = -1; 264854912308SNavdeep Parhar } else { 264954912308SNavdeep Parhar warnx("invalid scheduling sub-command \"%s\"", argv[0]); 265054912308SNavdeep Parhar return (EINVAL); 265154912308SNavdeep Parhar } 265254912308SNavdeep Parhar 265354912308SNavdeep Parhar /* Decode remaining arguments ... */ 265454912308SNavdeep Parhar errs = 0; 265554912308SNavdeep Parhar for (i = 1; i < argc; i += 2) { 265654912308SNavdeep Parhar const char **args = &argv[i]; 265754912308SNavdeep Parhar long l; 265854912308SNavdeep Parhar 265954912308SNavdeep Parhar if (i + 1 == argc) { 266054912308SNavdeep Parhar warnx("missing argument for \"%s\"", args[0]); 266154912308SNavdeep Parhar errs++; 266254912308SNavdeep Parhar break; 266354912308SNavdeep Parhar } 266454912308SNavdeep Parhar 266554912308SNavdeep Parhar if (!strcmp(args[0], "type")) { 266654912308SNavdeep Parhar if (!strcmp(args[1], "packet")) 266754912308SNavdeep Parhar op.type = SCHED_CLASS_TYPE_PACKET; 266854912308SNavdeep Parhar else { 266954912308SNavdeep Parhar warnx("invalid type parameter \"%s\"", args[1]); 267054912308SNavdeep Parhar errs++; 267154912308SNavdeep Parhar } 267254912308SNavdeep Parhar 267354912308SNavdeep Parhar continue; 267454912308SNavdeep Parhar } 267554912308SNavdeep Parhar 267654912308SNavdeep Parhar if (op.subcmd == SCHED_CLASS_SUBCMD_CONFIG) { 267754912308SNavdeep Parhar if(!get_sched_param("minmax", args, &l)) 267854912308SNavdeep Parhar op.u.config.minmax = (int8_t)l; 267954912308SNavdeep Parhar else { 268054912308SNavdeep Parhar warnx("unknown scheduler config parameter " 268154912308SNavdeep Parhar "\"%s\"", args[0]); 268254912308SNavdeep Parhar errs++; 268354912308SNavdeep Parhar } 268454912308SNavdeep Parhar 268554912308SNavdeep Parhar continue; 268654912308SNavdeep Parhar } 268754912308SNavdeep Parhar 268854912308SNavdeep Parhar /* Rest applies only to SUBCMD_PARAMS */ 268954912308SNavdeep Parhar if (op.subcmd != SCHED_CLASS_SUBCMD_PARAMS) 269054912308SNavdeep Parhar continue; 269154912308SNavdeep Parhar 269254912308SNavdeep Parhar if (!strcmp(args[0], "level")) { 269354912308SNavdeep Parhar if (!strcmp(args[1], "cl-rl")) 269454912308SNavdeep Parhar op.u.params.level = SCHED_CLASS_LEVEL_CL_RL; 269554912308SNavdeep Parhar else if (!strcmp(args[1], "cl-wrr")) 269654912308SNavdeep Parhar op.u.params.level = SCHED_CLASS_LEVEL_CL_WRR; 269754912308SNavdeep Parhar else if (!strcmp(args[1], "ch-rl")) 269854912308SNavdeep Parhar op.u.params.level = SCHED_CLASS_LEVEL_CH_RL; 269954912308SNavdeep Parhar else { 270054912308SNavdeep Parhar warnx("invalid level parameter \"%s\"", 270154912308SNavdeep Parhar args[1]); 270254912308SNavdeep Parhar errs++; 270354912308SNavdeep Parhar } 270454912308SNavdeep Parhar } else if (!strcmp(args[0], "mode")) { 270554912308SNavdeep Parhar if (!strcmp(args[1], "class")) 270654912308SNavdeep Parhar op.u.params.mode = SCHED_CLASS_MODE_CLASS; 270754912308SNavdeep Parhar else if (!strcmp(args[1], "flow")) 270854912308SNavdeep Parhar op.u.params.mode = SCHED_CLASS_MODE_FLOW; 270954912308SNavdeep Parhar else { 271054912308SNavdeep Parhar warnx("invalid mode parameter \"%s\"", args[1]); 271154912308SNavdeep Parhar errs++; 271254912308SNavdeep Parhar } 271354912308SNavdeep Parhar } else if (!strcmp(args[0], "rate-unit")) { 271454912308SNavdeep Parhar if (!strcmp(args[1], "bits")) 271554912308SNavdeep Parhar op.u.params.rateunit = SCHED_CLASS_RATEUNIT_BITS; 271654912308SNavdeep Parhar else if (!strcmp(args[1], "pkts")) 271754912308SNavdeep Parhar op.u.params.rateunit = SCHED_CLASS_RATEUNIT_PKTS; 271854912308SNavdeep Parhar else { 271954912308SNavdeep Parhar warnx("invalid rate-unit parameter \"%s\"", 272054912308SNavdeep Parhar args[1]); 272154912308SNavdeep Parhar errs++; 272254912308SNavdeep Parhar } 272354912308SNavdeep Parhar } else if (!strcmp(args[0], "rate-mode")) { 272454912308SNavdeep Parhar if (!strcmp(args[1], "relative")) 272554912308SNavdeep Parhar op.u.params.ratemode = SCHED_CLASS_RATEMODE_REL; 272654912308SNavdeep Parhar else if (!strcmp(args[1], "absolute")) 272754912308SNavdeep Parhar op.u.params.ratemode = SCHED_CLASS_RATEMODE_ABS; 272854912308SNavdeep Parhar else { 272954912308SNavdeep Parhar warnx("invalid rate-mode parameter \"%s\"", 273054912308SNavdeep Parhar args[1]); 273154912308SNavdeep Parhar errs++; 273254912308SNavdeep Parhar } 273354912308SNavdeep Parhar } else if (!get_sched_param("channel", args, &l)) 273454912308SNavdeep Parhar op.u.params.channel = (int8_t)l; 273554912308SNavdeep Parhar else if (!get_sched_param("class", args, &l)) 273654912308SNavdeep Parhar op.u.params.cl = (int8_t)l; 273754912308SNavdeep Parhar else if (!get_sched_param("min-rate", args, &l)) 273854912308SNavdeep Parhar op.u.params.minrate = (int32_t)l; 273954912308SNavdeep Parhar else if (!get_sched_param("max-rate", args, &l)) 274054912308SNavdeep Parhar op.u.params.maxrate = (int32_t)l; 274154912308SNavdeep Parhar else if (!get_sched_param("weight", args, &l)) 274254912308SNavdeep Parhar op.u.params.weight = (int16_t)l; 274354912308SNavdeep Parhar else if (!get_sched_param("pkt-size", args, &l)) 274454912308SNavdeep Parhar op.u.params.pktsize = (int16_t)l; 274554912308SNavdeep Parhar else { 274654912308SNavdeep Parhar warnx("unknown scheduler parameter \"%s\"", args[0]); 274754912308SNavdeep Parhar errs++; 274854912308SNavdeep Parhar } 274954912308SNavdeep Parhar } 275054912308SNavdeep Parhar 275154912308SNavdeep Parhar /* 275254912308SNavdeep Parhar * Catch some logical fallacies in terms of argument combinations here 275354912308SNavdeep Parhar * so we can offer more than just the EINVAL return from the driver. 275454912308SNavdeep Parhar * The driver will be able to catch a lot more issues since it knows 275554912308SNavdeep Parhar * the specifics of the device hardware capabilities like how many 275654912308SNavdeep Parhar * channels, classes, etc. the device supports. 275754912308SNavdeep Parhar */ 275854912308SNavdeep Parhar if (op.type < 0) { 275954912308SNavdeep Parhar warnx("sched \"type\" parameter missing"); 276054912308SNavdeep Parhar errs++; 276154912308SNavdeep Parhar } 276254912308SNavdeep Parhar if (op.subcmd == SCHED_CLASS_SUBCMD_CONFIG) { 276354912308SNavdeep Parhar if (op.u.config.minmax < 0) { 276454912308SNavdeep Parhar warnx("sched config \"minmax\" parameter missing"); 276554912308SNavdeep Parhar errs++; 276654912308SNavdeep Parhar } 276754912308SNavdeep Parhar } 276854912308SNavdeep Parhar if (op.subcmd == SCHED_CLASS_SUBCMD_PARAMS) { 276954912308SNavdeep Parhar if (op.u.params.level < 0) { 277054912308SNavdeep Parhar warnx("sched params \"level\" parameter missing"); 277154912308SNavdeep Parhar errs++; 277254912308SNavdeep Parhar } 277354912308SNavdeep Parhar if (op.u.params.mode < 0) { 277454912308SNavdeep Parhar warnx("sched params \"mode\" parameter missing"); 277554912308SNavdeep Parhar errs++; 277654912308SNavdeep Parhar } 277754912308SNavdeep Parhar if (op.u.params.rateunit < 0) { 277854912308SNavdeep Parhar warnx("sched params \"rate-unit\" parameter missing"); 277954912308SNavdeep Parhar errs++; 278054912308SNavdeep Parhar } 278154912308SNavdeep Parhar if (op.u.params.ratemode < 0) { 278254912308SNavdeep Parhar warnx("sched params \"rate-mode\" parameter missing"); 278354912308SNavdeep Parhar errs++; 278454912308SNavdeep Parhar } 278554912308SNavdeep Parhar if (op.u.params.channel < 0) { 278654912308SNavdeep Parhar warnx("sched params \"channel\" missing"); 278754912308SNavdeep Parhar errs++; 278854912308SNavdeep Parhar } 278954912308SNavdeep Parhar if (op.u.params.cl < 0) { 279054912308SNavdeep Parhar warnx("sched params \"class\" missing"); 279154912308SNavdeep Parhar errs++; 279254912308SNavdeep Parhar } 279354912308SNavdeep Parhar if (op.u.params.maxrate < 0 && 279454912308SNavdeep Parhar (op.u.params.level == SCHED_CLASS_LEVEL_CL_RL || 279554912308SNavdeep Parhar op.u.params.level == SCHED_CLASS_LEVEL_CH_RL)) { 279654912308SNavdeep Parhar warnx("sched params \"max-rate\" missing for " 279754912308SNavdeep Parhar "rate-limit level"); 279854912308SNavdeep Parhar errs++; 279954912308SNavdeep Parhar } 280054912308SNavdeep Parhar if (op.u.params.weight < 0 && 280154912308SNavdeep Parhar op.u.params.level == SCHED_CLASS_LEVEL_CL_WRR) { 280254912308SNavdeep Parhar warnx("sched params \"weight\" missing for " 280354912308SNavdeep Parhar "weighted-round-robin level"); 280454912308SNavdeep Parhar errs++; 280554912308SNavdeep Parhar } 280654912308SNavdeep Parhar if (op.u.params.pktsize < 0 && 280754912308SNavdeep Parhar (op.u.params.level == SCHED_CLASS_LEVEL_CL_RL || 280854912308SNavdeep Parhar op.u.params.level == SCHED_CLASS_LEVEL_CH_RL)) { 280954912308SNavdeep Parhar warnx("sched params \"pkt-size\" missing for " 281054912308SNavdeep Parhar "rate-limit level"); 281154912308SNavdeep Parhar errs++; 281254912308SNavdeep Parhar } 281354912308SNavdeep Parhar if (op.u.params.mode == SCHED_CLASS_MODE_FLOW && 281454912308SNavdeep Parhar op.u.params.ratemode != SCHED_CLASS_RATEMODE_ABS) { 281554912308SNavdeep Parhar warnx("sched params mode flow needs rate-mode absolute"); 281654912308SNavdeep Parhar errs++; 281754912308SNavdeep Parhar } 281854912308SNavdeep Parhar if (op.u.params.ratemode == SCHED_CLASS_RATEMODE_REL && 281954912308SNavdeep Parhar !in_range(op.u.params.maxrate, 1, 100)) { 282054912308SNavdeep Parhar warnx("sched params \"max-rate\" takes " 282154912308SNavdeep Parhar "percentage value(1-100) for rate-mode relative"); 282254912308SNavdeep Parhar errs++; 282354912308SNavdeep Parhar } 282454912308SNavdeep Parhar if (op.u.params.ratemode == SCHED_CLASS_RATEMODE_ABS && 282554912308SNavdeep Parhar !in_range(op.u.params.maxrate, 1, 100000000)) { 282654912308SNavdeep Parhar warnx("sched params \"max-rate\" takes " 282754912308SNavdeep Parhar "value(1-100000000) for rate-mode absolute"); 282854912308SNavdeep Parhar errs++; 282954912308SNavdeep Parhar } 283054912308SNavdeep Parhar if (op.u.params.maxrate > 0 && 283154912308SNavdeep Parhar op.u.params.maxrate < op.u.params.minrate) { 283254912308SNavdeep Parhar warnx("sched params \"max-rate\" is less than " 283354912308SNavdeep Parhar "\"min-rate\""); 283454912308SNavdeep Parhar errs++; 283554912308SNavdeep Parhar } 283654912308SNavdeep Parhar } 283754912308SNavdeep Parhar 283854912308SNavdeep Parhar if (errs > 0) { 283954912308SNavdeep Parhar warnx("%d error%s in sched-class command", errs, 284054912308SNavdeep Parhar errs == 1 ? "" : "s"); 284154912308SNavdeep Parhar return (EINVAL); 284254912308SNavdeep Parhar } 284354912308SNavdeep Parhar 284454912308SNavdeep Parhar return doit(CHELSIO_T4_SCHED_CLASS, &op); 284554912308SNavdeep Parhar } 284654912308SNavdeep Parhar 284754912308SNavdeep Parhar static int 284854912308SNavdeep Parhar sched_queue(int argc, const char *argv[]) 284954912308SNavdeep Parhar { 285054912308SNavdeep Parhar struct t4_sched_queue op = {0}; 285154912308SNavdeep Parhar char *p; 285254912308SNavdeep Parhar long val; 285354912308SNavdeep Parhar 285454912308SNavdeep Parhar if (argc != 3) { 285554912308SNavdeep Parhar /* need "<port> <queue> <class> */ 285654912308SNavdeep Parhar warnx("incorrect number of arguments."); 285754912308SNavdeep Parhar return (EINVAL); 285854912308SNavdeep Parhar } 285954912308SNavdeep Parhar 286054912308SNavdeep Parhar p = str_to_number(argv[0], &val, NULL); 286154912308SNavdeep Parhar if (*p || val > UCHAR_MAX) { 286254912308SNavdeep Parhar warnx("invalid port id \"%s\"", argv[0]); 286354912308SNavdeep Parhar return (EINVAL); 286454912308SNavdeep Parhar } 286554912308SNavdeep Parhar op.port = (uint8_t)val; 286654912308SNavdeep Parhar 286754912308SNavdeep Parhar if (!strcmp(argv[1], "all") || !strcmp(argv[1], "*")) 286854912308SNavdeep Parhar op.queue = -1; 286954912308SNavdeep Parhar else { 287054912308SNavdeep Parhar p = str_to_number(argv[1], &val, NULL); 287154912308SNavdeep Parhar if (*p || val < -1) { 287254912308SNavdeep Parhar warnx("invalid queue \"%s\"", argv[1]); 287354912308SNavdeep Parhar return (EINVAL); 287454912308SNavdeep Parhar } 287554912308SNavdeep Parhar op.queue = (int8_t)val; 287654912308SNavdeep Parhar } 287754912308SNavdeep Parhar 287854912308SNavdeep Parhar if (!strcmp(argv[2], "unbind") || !strcmp(argv[2], "clear")) 287954912308SNavdeep Parhar op.cl = -1; 288054912308SNavdeep Parhar else { 288154912308SNavdeep Parhar p = str_to_number(argv[2], &val, NULL); 288254912308SNavdeep Parhar if (*p || val < -1) { 288354912308SNavdeep Parhar warnx("invalid class \"%s\"", argv[2]); 288454912308SNavdeep Parhar return (EINVAL); 288554912308SNavdeep Parhar } 288654912308SNavdeep Parhar op.cl = (int8_t)val; 288754912308SNavdeep Parhar } 288854912308SNavdeep Parhar 288954912308SNavdeep Parhar return doit(CHELSIO_T4_SCHED_QUEUE, &op); 289054912308SNavdeep Parhar } 289154912308SNavdeep Parhar 289254912308SNavdeep Parhar static int 289354912308SNavdeep Parhar run_cmd(int argc, const char *argv[]) 289454912308SNavdeep Parhar { 289554912308SNavdeep Parhar int rc = -1; 289654912308SNavdeep Parhar const char *cmd = argv[0]; 289754912308SNavdeep Parhar 289854912308SNavdeep Parhar /* command */ 289954912308SNavdeep Parhar argc--; 290054912308SNavdeep Parhar argv++; 290154912308SNavdeep Parhar 290254912308SNavdeep Parhar if (!strcmp(cmd, "reg") || !strcmp(cmd, "reg32")) 290354912308SNavdeep Parhar rc = register_io(argc, argv, 4); 290454912308SNavdeep Parhar else if (!strcmp(cmd, "reg64")) 290554912308SNavdeep Parhar rc = register_io(argc, argv, 8); 290654912308SNavdeep Parhar else if (!strcmp(cmd, "regdump")) 290754912308SNavdeep Parhar rc = dump_regs(argc, argv); 290854912308SNavdeep Parhar else if (!strcmp(cmd, "filter")) 290954912308SNavdeep Parhar rc = filter_cmd(argc, argv); 291054912308SNavdeep Parhar else if (!strcmp(cmd, "context")) 291154912308SNavdeep Parhar rc = get_sge_context(argc, argv); 291254912308SNavdeep Parhar else if (!strcmp(cmd, "loadfw")) 291354912308SNavdeep Parhar rc = loadfw(argc, argv); 291454912308SNavdeep Parhar else if (!strcmp(cmd, "memdump")) 291554912308SNavdeep Parhar rc = memdump(argc, argv); 291654912308SNavdeep Parhar else if (!strcmp(cmd, "tcb")) 291754912308SNavdeep Parhar rc = read_tcb(argc, argv); 291854912308SNavdeep Parhar else if (!strcmp(cmd, "i2c")) 291954912308SNavdeep Parhar rc = read_i2c(argc, argv); 292054912308SNavdeep Parhar else if (!strcmp(cmd, "clearstats")) 292154912308SNavdeep Parhar rc = clearstats(argc, argv); 292254912308SNavdeep Parhar else if (!strcmp(cmd, "tracer")) 292354912308SNavdeep Parhar rc = tracer_cmd(argc, argv); 292454912308SNavdeep Parhar else if (!strcmp(cmd, "modinfo")) 292554912308SNavdeep Parhar rc = modinfo(argc, argv); 292654912308SNavdeep Parhar else if (!strcmp(cmd, "sched-class")) 292754912308SNavdeep Parhar rc = sched_class(argc, argv); 292854912308SNavdeep Parhar else if (!strcmp(cmd, "sched-queue")) 292954912308SNavdeep Parhar rc = sched_queue(argc, argv); 293054912308SNavdeep Parhar else if (!strcmp(cmd, "loadcfg")) 293154912308SNavdeep Parhar rc = loadcfg(argc, argv); 29328f82718fSNavdeep Parhar else if (!strcmp(cmd, "loadboot")) 29338f82718fSNavdeep Parhar rc = loadboot(argc, argv); 29348f82718fSNavdeep Parhar else if (!strcmp(cmd, "loadboot-cfg")) 29358f82718fSNavdeep Parhar rc = loadbootcfg(argc, argv); 2936f856f099SNavdeep Parhar else if (!strcmp(cmd, "dumpstate")) 2937f856f099SNavdeep Parhar rc = dumpstate(argc, argv); 293854912308SNavdeep Parhar else { 293954912308SNavdeep Parhar rc = EINVAL; 294054912308SNavdeep Parhar warnx("invalid command \"%s\"", cmd); 294154912308SNavdeep Parhar } 294254912308SNavdeep Parhar 294354912308SNavdeep Parhar return (rc); 294454912308SNavdeep Parhar } 294554912308SNavdeep Parhar 294654912308SNavdeep Parhar #define MAX_ARGS 15 294754912308SNavdeep Parhar static int 294854912308SNavdeep Parhar run_cmd_loop(void) 294954912308SNavdeep Parhar { 295054912308SNavdeep Parhar int i, rc = 0; 295154912308SNavdeep Parhar char buffer[128], *buf; 295254912308SNavdeep Parhar const char *args[MAX_ARGS + 1]; 295354912308SNavdeep Parhar 295454912308SNavdeep Parhar /* 295554912308SNavdeep Parhar * Simple loop: displays a "> " prompt and processes any input as a 295654912308SNavdeep Parhar * cxgbetool command. You're supposed to enter only the part after 295754912308SNavdeep Parhar * "cxgbetool t4nexX". Use "quit" or "exit" to exit. 295854912308SNavdeep Parhar */ 295954912308SNavdeep Parhar for (;;) { 296054912308SNavdeep Parhar fprintf(stdout, "> "); 296154912308SNavdeep Parhar fflush(stdout); 296254912308SNavdeep Parhar buf = fgets(buffer, sizeof(buffer), stdin); 296354912308SNavdeep Parhar if (buf == NULL) { 296454912308SNavdeep Parhar if (ferror(stdin)) { 296554912308SNavdeep Parhar warn("stdin error"); 296654912308SNavdeep Parhar rc = errno; /* errno from fgets */ 296754912308SNavdeep Parhar } 296854912308SNavdeep Parhar break; 296954912308SNavdeep Parhar } 297054912308SNavdeep Parhar 297154912308SNavdeep Parhar i = 0; 297254912308SNavdeep Parhar while ((args[i] = strsep(&buf, " \t\n")) != NULL) { 297354912308SNavdeep Parhar if (args[i][0] != 0 && ++i == MAX_ARGS) 297454912308SNavdeep Parhar break; 297554912308SNavdeep Parhar } 297654912308SNavdeep Parhar args[i] = 0; 297754912308SNavdeep Parhar 297854912308SNavdeep Parhar if (i == 0) 297954912308SNavdeep Parhar continue; /* skip empty line */ 298054912308SNavdeep Parhar 298154912308SNavdeep Parhar if (!strcmp(args[0], "quit") || !strcmp(args[0], "exit")) 298254912308SNavdeep Parhar break; 298354912308SNavdeep Parhar 298454912308SNavdeep Parhar rc = run_cmd(i, args); 298554912308SNavdeep Parhar } 298654912308SNavdeep Parhar 298754912308SNavdeep Parhar /* rc normally comes from the last command (not including quit/exit) */ 298854912308SNavdeep Parhar return (rc); 298954912308SNavdeep Parhar } 299054912308SNavdeep Parhar 299154912308SNavdeep Parhar int 299254912308SNavdeep Parhar main(int argc, const char *argv[]) 299354912308SNavdeep Parhar { 299454912308SNavdeep Parhar int rc = -1; 299554912308SNavdeep Parhar 299654912308SNavdeep Parhar progname = argv[0]; 299754912308SNavdeep Parhar 299854912308SNavdeep Parhar if (argc == 2) { 299954912308SNavdeep Parhar if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { 300054912308SNavdeep Parhar usage(stdout); 300154912308SNavdeep Parhar exit(0); 300254912308SNavdeep Parhar } 300354912308SNavdeep Parhar } 300454912308SNavdeep Parhar 300554912308SNavdeep Parhar if (argc < 3) { 300654912308SNavdeep Parhar usage(stderr); 300754912308SNavdeep Parhar exit(EINVAL); 300854912308SNavdeep Parhar } 300954912308SNavdeep Parhar 301054912308SNavdeep Parhar nexus = argv[1]; 301154912308SNavdeep Parhar 301254912308SNavdeep Parhar /* progname and nexus */ 301354912308SNavdeep Parhar argc -= 2; 301454912308SNavdeep Parhar argv += 2; 301554912308SNavdeep Parhar 301654912308SNavdeep Parhar if (argc == 1 && !strcmp(argv[0], "stdio")) 301754912308SNavdeep Parhar rc = run_cmd_loop(); 301854912308SNavdeep Parhar else 301954912308SNavdeep Parhar rc = run_cmd(argc, argv); 302054912308SNavdeep Parhar 302154912308SNavdeep Parhar return (rc); 302254912308SNavdeep Parhar } 3023