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> 521131c927SNavdeep Parhar #include <pcap.h> 5354912308SNavdeep Parhar 5454912308SNavdeep Parhar #include "t4_ioctl.h" 55ae9b4017SNavdeep Parhar #include "tcb_common.h" 5654912308SNavdeep Parhar 5754912308SNavdeep Parhar #define in_range(val, lo, hi) ( val < 0 || (val <= hi && val >= lo)) 5854912308SNavdeep Parhar #define max(x, y) ((x) > (y) ? (x) : (y)) 5954912308SNavdeep Parhar 6054912308SNavdeep Parhar static const char *progname, *nexus; 6154912308SNavdeep Parhar static int chip_id; /* 4 for T4, 5 for T5 */ 6254912308SNavdeep Parhar 6354912308SNavdeep Parhar struct reg_info { 6454912308SNavdeep Parhar const char *name; 6554912308SNavdeep Parhar uint32_t addr; 6654912308SNavdeep Parhar uint32_t len; 6754912308SNavdeep Parhar }; 6854912308SNavdeep Parhar 6954912308SNavdeep Parhar struct mod_regs { 7054912308SNavdeep Parhar const char *name; 7154912308SNavdeep Parhar const struct reg_info *ri; 7254912308SNavdeep Parhar }; 7354912308SNavdeep Parhar 7454912308SNavdeep Parhar struct field_desc { 7554912308SNavdeep Parhar const char *name; /* Field name */ 7654912308SNavdeep Parhar unsigned short start; /* Start bit position */ 7754912308SNavdeep Parhar unsigned short end; /* End bit position */ 7854912308SNavdeep Parhar unsigned char shift; /* # of low order bits omitted and implicitly 0 */ 7954912308SNavdeep Parhar unsigned char hex; /* Print field in hex instead of decimal */ 8054912308SNavdeep Parhar unsigned char islog2; /* Field contains the base-2 log of the value */ 8154912308SNavdeep Parhar }; 8254912308SNavdeep Parhar 8354912308SNavdeep Parhar #include "reg_defs_t4.c" 8454912308SNavdeep Parhar #include "reg_defs_t5.c" 8554912308SNavdeep Parhar #include "reg_defs_t6.c" 8654912308SNavdeep Parhar #include "reg_defs_t4vf.c" 8754912308SNavdeep Parhar 8854912308SNavdeep Parhar static void 8954912308SNavdeep Parhar usage(FILE *fp) 9054912308SNavdeep Parhar { 9154912308SNavdeep Parhar fprintf(fp, "Usage: %s <nexus> [operation]\n", progname); 9254912308SNavdeep Parhar fprintf(fp, 9354912308SNavdeep Parhar "\tclearstats <port> clear port statistics\n" 9454912308SNavdeep Parhar "\tcontext <type> <id> show an SGE context\n" 95f856f099SNavdeep Parhar "\tdumpstate <dump.bin> dump chip state\n" 9654912308SNavdeep Parhar "\tfilter <idx> [<param> <val>] ... set a filter\n" 9754912308SNavdeep Parhar "\tfilter <idx> delete|clear delete a filter\n" 9854912308SNavdeep Parhar "\tfilter list list all filters\n" 9954912308SNavdeep Parhar "\tfilter mode [<match>] ... get/set global filter mode\n" 10036ea2fe3SNavdeep Parhar "\thashfilter [<param> <val>] ... set a hashfilter\n" 10136ea2fe3SNavdeep Parhar "\thashfilter <idx> delete|clear delete a hashfilter\n" 10236ea2fe3SNavdeep Parhar "\thashfilter list list all hashfilters\n" 10336ea2fe3SNavdeep Parhar "\thashfilter mode get global hashfilter mode\n" 10454912308SNavdeep Parhar "\ti2c <port> <devaddr> <addr> [<len>] read from i2c device\n" 1058f82718fSNavdeep Parhar "\tloadboot <bi.bin> [pf|offset <val>] install boot image\n" 1068f82718fSNavdeep Parhar "\tloadboot clear [pf|offset <val>] remove boot image\n" 1078f82718fSNavdeep Parhar "\tloadboot-cfg <bc.bin> install boot config\n" 1088f82718fSNavdeep Parhar "\tloadboot-cfg clear remove boot config\n" 10954912308SNavdeep Parhar "\tloadcfg <fw-config.txt> install configuration file\n" 11054912308SNavdeep Parhar "\tloadcfg clear remove configuration file\n" 11154912308SNavdeep Parhar "\tloadfw <fw-image.bin> install firmware\n" 11254912308SNavdeep Parhar "\tmemdump <addr> <len> dump a memory range\n" 11354912308SNavdeep Parhar "\tmodinfo <port> [raw] optics/cable information\n" 1141131c927SNavdeep Parhar "\tpolicy <policy.txt> install offload policy\n" 1151131c927SNavdeep Parhar "\tpolicy clear remove offload policy\n" 11654912308SNavdeep Parhar "\treg <address>[=<val>] read/write register\n" 11754912308SNavdeep Parhar "\treg64 <address>[=<val>] read/write 64 bit register\n" 11854912308SNavdeep Parhar "\tregdump [<module>] ... dump registers\n" 11954912308SNavdeep Parhar "\tsched-class params <param> <val> .. configure TX scheduler class\n" 12054912308SNavdeep Parhar "\tsched-queue <port> <queue> <class> bind NIC queues to TX Scheduling class\n" 12154912308SNavdeep Parhar "\tstdio interactive mode\n" 12254912308SNavdeep Parhar "\ttcb <tid> read TCB\n" 12354912308SNavdeep Parhar "\ttracer <idx> tx<n>|rx<n> set and enable a tracer\n" 12454912308SNavdeep Parhar "\ttracer <idx> disable|enable disable or enable a tracer\n" 12554912308SNavdeep Parhar "\ttracer list list all tracers\n" 12654912308SNavdeep Parhar ); 12754912308SNavdeep Parhar } 12854912308SNavdeep Parhar 12954912308SNavdeep Parhar static inline unsigned int 13054912308SNavdeep Parhar get_card_vers(unsigned int version) 13154912308SNavdeep Parhar { 13254912308SNavdeep Parhar return (version & 0x3ff); 13354912308SNavdeep Parhar } 13454912308SNavdeep Parhar 13554912308SNavdeep Parhar static int 13654912308SNavdeep Parhar real_doit(unsigned long cmd, void *data, const char *cmdstr) 13754912308SNavdeep Parhar { 13854912308SNavdeep Parhar static int fd = -1; 13954912308SNavdeep Parhar int rc = 0; 14054912308SNavdeep Parhar 14154912308SNavdeep Parhar if (fd == -1) { 14254912308SNavdeep Parhar char buf[64]; 14354912308SNavdeep Parhar 14454912308SNavdeep Parhar snprintf(buf, sizeof(buf), "/dev/%s", nexus); 14554912308SNavdeep Parhar if ((fd = open(buf, O_RDWR)) < 0) { 14654912308SNavdeep Parhar warn("open(%s)", nexus); 14754912308SNavdeep Parhar rc = errno; 14854912308SNavdeep Parhar return (rc); 14954912308SNavdeep Parhar } 15054912308SNavdeep Parhar chip_id = nexus[1] - '0'; 15154912308SNavdeep Parhar } 15254912308SNavdeep Parhar 15354912308SNavdeep Parhar rc = ioctl(fd, cmd, data); 15454912308SNavdeep Parhar if (rc < 0) { 15554912308SNavdeep Parhar warn("%s", cmdstr); 15654912308SNavdeep Parhar rc = errno; 15754912308SNavdeep Parhar } 15854912308SNavdeep Parhar 15954912308SNavdeep Parhar return (rc); 16054912308SNavdeep Parhar } 16154912308SNavdeep Parhar #define doit(x, y) real_doit(x, y, #x) 16254912308SNavdeep Parhar 16354912308SNavdeep Parhar static char * 16454912308SNavdeep Parhar str_to_number(const char *s, long *val, long long *vall) 16554912308SNavdeep Parhar { 16654912308SNavdeep Parhar char *p; 16754912308SNavdeep Parhar 16854912308SNavdeep Parhar if (vall) 16954912308SNavdeep Parhar *vall = strtoll(s, &p, 0); 17054912308SNavdeep Parhar else if (val) 17154912308SNavdeep Parhar *val = strtol(s, &p, 0); 17254912308SNavdeep Parhar else 17354912308SNavdeep Parhar p = NULL; 17454912308SNavdeep Parhar 17554912308SNavdeep Parhar return (p); 17654912308SNavdeep Parhar } 17754912308SNavdeep Parhar 17854912308SNavdeep Parhar static int 17954912308SNavdeep Parhar read_reg(long addr, int size, long long *val) 18054912308SNavdeep Parhar { 18154912308SNavdeep Parhar struct t4_reg reg; 18254912308SNavdeep Parhar int rc; 18354912308SNavdeep Parhar 18454912308SNavdeep Parhar reg.addr = (uint32_t) addr; 18554912308SNavdeep Parhar reg.size = (uint32_t) size; 18654912308SNavdeep Parhar reg.val = 0; 18754912308SNavdeep Parhar 18854912308SNavdeep Parhar rc = doit(CHELSIO_T4_GETREG, ®); 18954912308SNavdeep Parhar 19054912308SNavdeep Parhar *val = reg.val; 19154912308SNavdeep Parhar 19254912308SNavdeep Parhar return (rc); 19354912308SNavdeep Parhar } 19454912308SNavdeep Parhar 19554912308SNavdeep Parhar static int 19654912308SNavdeep Parhar write_reg(long addr, int size, long long val) 19754912308SNavdeep Parhar { 19854912308SNavdeep Parhar struct t4_reg reg; 19954912308SNavdeep Parhar 20054912308SNavdeep Parhar reg.addr = (uint32_t) addr; 20154912308SNavdeep Parhar reg.size = (uint32_t) size; 20254912308SNavdeep Parhar reg.val = (uint64_t) val; 20354912308SNavdeep Parhar 20454912308SNavdeep Parhar return doit(CHELSIO_T4_SETREG, ®); 20554912308SNavdeep Parhar } 20654912308SNavdeep Parhar 20754912308SNavdeep Parhar static int 20854912308SNavdeep Parhar register_io(int argc, const char *argv[], int size) 20954912308SNavdeep Parhar { 21054912308SNavdeep Parhar char *p, *v; 21154912308SNavdeep Parhar long addr; 21254912308SNavdeep Parhar long long val; 21354912308SNavdeep Parhar int w = 0, rc; 21454912308SNavdeep Parhar 21554912308SNavdeep Parhar if (argc == 1) { 21654912308SNavdeep Parhar /* <reg> OR <reg>=<value> */ 21754912308SNavdeep Parhar 21854912308SNavdeep Parhar p = str_to_number(argv[0], &addr, NULL); 21954912308SNavdeep Parhar if (*p) { 22054912308SNavdeep Parhar if (*p != '=') { 22154912308SNavdeep Parhar warnx("invalid register \"%s\"", argv[0]); 22254912308SNavdeep Parhar return (EINVAL); 22354912308SNavdeep Parhar } 22454912308SNavdeep Parhar 22554912308SNavdeep Parhar w = 1; 22654912308SNavdeep Parhar v = p + 1; 22754912308SNavdeep Parhar p = str_to_number(v, NULL, &val); 22854912308SNavdeep Parhar 22954912308SNavdeep Parhar if (*p) { 23054912308SNavdeep Parhar warnx("invalid value \"%s\"", v); 23154912308SNavdeep Parhar return (EINVAL); 23254912308SNavdeep Parhar } 23354912308SNavdeep Parhar } 23454912308SNavdeep Parhar 23554912308SNavdeep Parhar } else if (argc == 2) { 23654912308SNavdeep Parhar /* <reg> <value> */ 23754912308SNavdeep Parhar 23854912308SNavdeep Parhar w = 1; 23954912308SNavdeep Parhar 24054912308SNavdeep Parhar p = str_to_number(argv[0], &addr, NULL); 24154912308SNavdeep Parhar if (*p) { 24254912308SNavdeep Parhar warnx("invalid register \"%s\"", argv[0]); 24354912308SNavdeep Parhar return (EINVAL); 24454912308SNavdeep Parhar } 24554912308SNavdeep Parhar 24654912308SNavdeep Parhar p = str_to_number(argv[1], NULL, &val); 24754912308SNavdeep Parhar if (*p) { 24854912308SNavdeep Parhar warnx("invalid value \"%s\"", argv[1]); 24954912308SNavdeep Parhar return (EINVAL); 25054912308SNavdeep Parhar } 25154912308SNavdeep Parhar } else { 25254912308SNavdeep Parhar warnx("reg: invalid number of arguments (%d)", argc); 25354912308SNavdeep Parhar return (EINVAL); 25454912308SNavdeep Parhar } 25554912308SNavdeep Parhar 25654912308SNavdeep Parhar if (w) 25754912308SNavdeep Parhar rc = write_reg(addr, size, val); 25854912308SNavdeep Parhar else { 25954912308SNavdeep Parhar rc = read_reg(addr, size, &val); 26054912308SNavdeep Parhar if (rc == 0) 26154912308SNavdeep Parhar printf("0x%llx [%llu]\n", val, val); 26254912308SNavdeep Parhar } 26354912308SNavdeep Parhar 26454912308SNavdeep Parhar return (rc); 26554912308SNavdeep Parhar } 26654912308SNavdeep Parhar 26754912308SNavdeep Parhar static inline uint32_t 26854912308SNavdeep Parhar xtract(uint32_t val, int shift, int len) 26954912308SNavdeep Parhar { 27054912308SNavdeep Parhar return (val >> shift) & ((1 << len) - 1); 27154912308SNavdeep Parhar } 27254912308SNavdeep Parhar 27354912308SNavdeep Parhar static int 27454912308SNavdeep Parhar dump_block_regs(const struct reg_info *reg_array, const uint32_t *regs) 27554912308SNavdeep Parhar { 27654912308SNavdeep Parhar uint32_t reg_val = 0; 27754912308SNavdeep Parhar 27854912308SNavdeep Parhar for ( ; reg_array->name; ++reg_array) 27954912308SNavdeep Parhar if (!reg_array->len) { 28054912308SNavdeep Parhar reg_val = regs[reg_array->addr / 4]; 28154912308SNavdeep Parhar printf("[%#7x] %-47s %#-10x %u\n", reg_array->addr, 28254912308SNavdeep Parhar reg_array->name, reg_val, reg_val); 28354912308SNavdeep Parhar } else { 28454912308SNavdeep Parhar uint32_t v = xtract(reg_val, reg_array->addr, 28554912308SNavdeep Parhar reg_array->len); 28654912308SNavdeep Parhar 28754912308SNavdeep Parhar printf(" %*u:%u %-47s %#-10x %u\n", 28854912308SNavdeep Parhar reg_array->addr < 10 ? 3 : 2, 28954912308SNavdeep Parhar reg_array->addr + reg_array->len - 1, 29054912308SNavdeep Parhar reg_array->addr, reg_array->name, v, v); 29154912308SNavdeep Parhar } 29254912308SNavdeep Parhar 29354912308SNavdeep Parhar return (1); 29454912308SNavdeep Parhar } 29554912308SNavdeep Parhar 29654912308SNavdeep Parhar static int 29754912308SNavdeep Parhar dump_regs_table(int argc, const char *argv[], const uint32_t *regs, 29854912308SNavdeep Parhar const struct mod_regs *modtab, int nmodules) 29954912308SNavdeep Parhar { 30054912308SNavdeep Parhar int i, j, match; 30154912308SNavdeep Parhar 30254912308SNavdeep Parhar for (i = 0; i < argc; i++) { 30354912308SNavdeep Parhar for (j = 0; j < nmodules; j++) { 30454912308SNavdeep Parhar if (!strcmp(argv[i], modtab[j].name)) 30554912308SNavdeep Parhar break; 30654912308SNavdeep Parhar } 30754912308SNavdeep Parhar 30854912308SNavdeep Parhar if (j == nmodules) { 30954912308SNavdeep Parhar warnx("invalid register block \"%s\"", argv[i]); 31054912308SNavdeep Parhar fprintf(stderr, "\nAvailable blocks:"); 31154912308SNavdeep Parhar for ( ; nmodules; nmodules--, modtab++) 31254912308SNavdeep Parhar fprintf(stderr, " %s", modtab->name); 31354912308SNavdeep Parhar fprintf(stderr, "\n"); 31454912308SNavdeep Parhar return (EINVAL); 31554912308SNavdeep Parhar } 31654912308SNavdeep Parhar } 31754912308SNavdeep Parhar 31854912308SNavdeep Parhar for ( ; nmodules; nmodules--, modtab++) { 31954912308SNavdeep Parhar 32054912308SNavdeep Parhar match = argc == 0 ? 1 : 0; 32154912308SNavdeep Parhar for (i = 0; !match && i < argc; i++) { 32254912308SNavdeep Parhar if (!strcmp(argv[i], modtab->name)) 32354912308SNavdeep Parhar match = 1; 32454912308SNavdeep Parhar } 32554912308SNavdeep Parhar 32654912308SNavdeep Parhar if (match) 32754912308SNavdeep Parhar dump_block_regs(modtab->ri, regs); 32854912308SNavdeep Parhar } 32954912308SNavdeep Parhar 33054912308SNavdeep Parhar return (0); 33154912308SNavdeep Parhar } 33254912308SNavdeep Parhar 33354912308SNavdeep Parhar #define T4_MODREGS(name) { #name, t4_##name##_regs } 33454912308SNavdeep Parhar static int 33554912308SNavdeep Parhar dump_regs_t4(int argc, const char *argv[], const uint32_t *regs) 33654912308SNavdeep Parhar { 33754912308SNavdeep Parhar static struct mod_regs t4_mod[] = { 33854912308SNavdeep Parhar T4_MODREGS(sge), 33954912308SNavdeep Parhar { "pci", t4_pcie_regs }, 34054912308SNavdeep Parhar T4_MODREGS(dbg), 34154912308SNavdeep Parhar T4_MODREGS(mc), 34254912308SNavdeep Parhar T4_MODREGS(ma), 34354912308SNavdeep Parhar { "edc0", t4_edc_0_regs }, 34454912308SNavdeep Parhar { "edc1", t4_edc_1_regs }, 34554912308SNavdeep Parhar T4_MODREGS(cim), 34654912308SNavdeep Parhar T4_MODREGS(tp), 34754912308SNavdeep Parhar T4_MODREGS(ulp_rx), 34854912308SNavdeep Parhar T4_MODREGS(ulp_tx), 34954912308SNavdeep Parhar { "pmrx", t4_pm_rx_regs }, 35054912308SNavdeep Parhar { "pmtx", t4_pm_tx_regs }, 35154912308SNavdeep Parhar T4_MODREGS(mps), 35254912308SNavdeep Parhar { "cplsw", t4_cpl_switch_regs }, 35354912308SNavdeep Parhar T4_MODREGS(smb), 35454912308SNavdeep Parhar { "i2c", t4_i2cm_regs }, 35554912308SNavdeep Parhar T4_MODREGS(mi), 35654912308SNavdeep Parhar T4_MODREGS(uart), 35754912308SNavdeep Parhar T4_MODREGS(pmu), 35854912308SNavdeep Parhar T4_MODREGS(sf), 35954912308SNavdeep Parhar T4_MODREGS(pl), 36054912308SNavdeep Parhar T4_MODREGS(le), 36154912308SNavdeep Parhar T4_MODREGS(ncsi), 36254912308SNavdeep Parhar T4_MODREGS(xgmac) 36354912308SNavdeep Parhar }; 36454912308SNavdeep Parhar 36554912308SNavdeep Parhar return dump_regs_table(argc, argv, regs, t4_mod, nitems(t4_mod)); 36654912308SNavdeep Parhar } 36754912308SNavdeep Parhar #undef T4_MODREGS 36854912308SNavdeep Parhar 36954912308SNavdeep Parhar #define T5_MODREGS(name) { #name, t5_##name##_regs } 37054912308SNavdeep Parhar static int 37154912308SNavdeep Parhar dump_regs_t5(int argc, const char *argv[], const uint32_t *regs) 37254912308SNavdeep Parhar { 37354912308SNavdeep Parhar static struct mod_regs t5_mod[] = { 37454912308SNavdeep Parhar T5_MODREGS(sge), 37554912308SNavdeep Parhar { "pci", t5_pcie_regs }, 37654912308SNavdeep Parhar T5_MODREGS(dbg), 37754912308SNavdeep Parhar { "mc0", t5_mc_0_regs }, 37854912308SNavdeep Parhar { "mc1", t5_mc_1_regs }, 37954912308SNavdeep Parhar T5_MODREGS(ma), 38054912308SNavdeep Parhar { "edc0", t5_edc_t50_regs }, 38154912308SNavdeep Parhar { "edc1", t5_edc_t51_regs }, 38254912308SNavdeep Parhar T5_MODREGS(cim), 38354912308SNavdeep Parhar T5_MODREGS(tp), 38454912308SNavdeep Parhar { "ulprx", t5_ulp_rx_regs }, 38554912308SNavdeep Parhar { "ulptx", t5_ulp_tx_regs }, 38654912308SNavdeep Parhar { "pmrx", t5_pm_rx_regs }, 38754912308SNavdeep Parhar { "pmtx", t5_pm_tx_regs }, 38854912308SNavdeep Parhar T5_MODREGS(mps), 38954912308SNavdeep Parhar { "cplsw", t5_cpl_switch_regs }, 39054912308SNavdeep Parhar T5_MODREGS(smb), 39154912308SNavdeep Parhar { "i2c", t5_i2cm_regs }, 39254912308SNavdeep Parhar T5_MODREGS(mi), 39354912308SNavdeep Parhar T5_MODREGS(uart), 39454912308SNavdeep Parhar T5_MODREGS(pmu), 39554912308SNavdeep Parhar T5_MODREGS(sf), 39654912308SNavdeep Parhar T5_MODREGS(pl), 39754912308SNavdeep Parhar T5_MODREGS(le), 39854912308SNavdeep Parhar T5_MODREGS(ncsi), 39954912308SNavdeep Parhar T5_MODREGS(mac), 40054912308SNavdeep Parhar { "hma", t5_hma_t5_regs } 40154912308SNavdeep Parhar }; 40254912308SNavdeep Parhar 40354912308SNavdeep Parhar return dump_regs_table(argc, argv, regs, t5_mod, nitems(t5_mod)); 40454912308SNavdeep Parhar } 40554912308SNavdeep Parhar #undef T5_MODREGS 40654912308SNavdeep Parhar 40754912308SNavdeep Parhar #define T6_MODREGS(name) { #name, t6_##name##_regs } 40854912308SNavdeep Parhar static int 40954912308SNavdeep Parhar dump_regs_t6(int argc, const char *argv[], const uint32_t *regs) 41054912308SNavdeep Parhar { 41154912308SNavdeep Parhar static struct mod_regs t6_mod[] = { 41254912308SNavdeep Parhar T6_MODREGS(sge), 41354912308SNavdeep Parhar { "pci", t6_pcie_regs }, 41454912308SNavdeep Parhar T6_MODREGS(dbg), 41554912308SNavdeep Parhar { "mc0", t6_mc_0_regs }, 41654912308SNavdeep Parhar T6_MODREGS(ma), 41754912308SNavdeep Parhar { "edc0", t6_edc_t60_regs }, 41854912308SNavdeep Parhar { "edc1", t6_edc_t61_regs }, 41954912308SNavdeep Parhar T6_MODREGS(cim), 42054912308SNavdeep Parhar T6_MODREGS(tp), 42154912308SNavdeep Parhar { "ulprx", t6_ulp_rx_regs }, 42254912308SNavdeep Parhar { "ulptx", t6_ulp_tx_regs }, 42354912308SNavdeep Parhar { "pmrx", t6_pm_rx_regs }, 42454912308SNavdeep Parhar { "pmtx", t6_pm_tx_regs }, 42554912308SNavdeep Parhar T6_MODREGS(mps), 42654912308SNavdeep Parhar { "cplsw", t6_cpl_switch_regs }, 42754912308SNavdeep Parhar T6_MODREGS(smb), 42854912308SNavdeep Parhar { "i2c", t6_i2cm_regs }, 42954912308SNavdeep Parhar T6_MODREGS(mi), 43054912308SNavdeep Parhar T6_MODREGS(uart), 43154912308SNavdeep Parhar T6_MODREGS(pmu), 43254912308SNavdeep Parhar T6_MODREGS(sf), 43354912308SNavdeep Parhar T6_MODREGS(pl), 43454912308SNavdeep Parhar T6_MODREGS(le), 43554912308SNavdeep Parhar T6_MODREGS(ncsi), 43654912308SNavdeep Parhar T6_MODREGS(mac), 43754912308SNavdeep Parhar { "hma", t6_hma_t6_regs } 43854912308SNavdeep Parhar }; 43954912308SNavdeep Parhar 44054912308SNavdeep Parhar return dump_regs_table(argc, argv, regs, t6_mod, nitems(t6_mod)); 44154912308SNavdeep Parhar } 44254912308SNavdeep Parhar #undef T6_MODREGS 44354912308SNavdeep Parhar 44454912308SNavdeep Parhar static int 44554912308SNavdeep Parhar dump_regs_t4vf(int argc, const char *argv[], const uint32_t *regs) 44654912308SNavdeep Parhar { 44754912308SNavdeep Parhar static struct mod_regs t4vf_mod[] = { 44854912308SNavdeep Parhar { "sge", t4vf_sge_regs }, 44954912308SNavdeep Parhar { "mps", t4vf_mps_regs }, 45054912308SNavdeep Parhar { "pl", t4vf_pl_regs }, 45154912308SNavdeep Parhar { "mbdata", t4vf_mbdata_regs }, 45254912308SNavdeep Parhar { "cim", t4vf_cim_regs }, 45354912308SNavdeep Parhar }; 45454912308SNavdeep Parhar 45554912308SNavdeep Parhar return dump_regs_table(argc, argv, regs, t4vf_mod, nitems(t4vf_mod)); 45654912308SNavdeep Parhar } 45754912308SNavdeep Parhar 45854912308SNavdeep Parhar static int 45954912308SNavdeep Parhar dump_regs_t5vf(int argc, const char *argv[], const uint32_t *regs) 46054912308SNavdeep Parhar { 46154912308SNavdeep Parhar static struct mod_regs t5vf_mod[] = { 46254912308SNavdeep Parhar { "sge", t5vf_sge_regs }, 46354912308SNavdeep Parhar { "mps", t4vf_mps_regs }, 46454912308SNavdeep Parhar { "pl", t5vf_pl_regs }, 46554912308SNavdeep Parhar { "mbdata", t4vf_mbdata_regs }, 46654912308SNavdeep Parhar { "cim", t4vf_cim_regs }, 46754912308SNavdeep Parhar }; 46854912308SNavdeep Parhar 46954912308SNavdeep Parhar return dump_regs_table(argc, argv, regs, t5vf_mod, nitems(t5vf_mod)); 47054912308SNavdeep Parhar } 47154912308SNavdeep Parhar 47254912308SNavdeep Parhar static int 47354912308SNavdeep Parhar dump_regs_t6vf(int argc, const char *argv[], const uint32_t *regs) 47454912308SNavdeep Parhar { 47554912308SNavdeep Parhar static struct mod_regs t6vf_mod[] = { 47654912308SNavdeep Parhar { "sge", t5vf_sge_regs }, 47754912308SNavdeep Parhar { "mps", t4vf_mps_regs }, 47854912308SNavdeep Parhar { "pl", t6vf_pl_regs }, 47954912308SNavdeep Parhar { "mbdata", t4vf_mbdata_regs }, 48054912308SNavdeep Parhar { "cim", t4vf_cim_regs }, 48154912308SNavdeep Parhar }; 48254912308SNavdeep Parhar 48354912308SNavdeep Parhar return dump_regs_table(argc, argv, regs, t6vf_mod, nitems(t6vf_mod)); 48454912308SNavdeep Parhar } 48554912308SNavdeep Parhar 48654912308SNavdeep Parhar static int 48754912308SNavdeep Parhar dump_regs(int argc, const char *argv[]) 48854912308SNavdeep Parhar { 48954912308SNavdeep Parhar int vers, revision, rc; 49054912308SNavdeep Parhar struct t4_regdump regs; 49154912308SNavdeep Parhar uint32_t len; 49254912308SNavdeep Parhar 49354912308SNavdeep Parhar len = max(T4_REGDUMP_SIZE, T5_REGDUMP_SIZE); 49454912308SNavdeep Parhar regs.data = calloc(1, len); 49554912308SNavdeep Parhar if (regs.data == NULL) { 49654912308SNavdeep Parhar warnc(ENOMEM, "regdump"); 49754912308SNavdeep Parhar return (ENOMEM); 49854912308SNavdeep Parhar } 49954912308SNavdeep Parhar 50054912308SNavdeep Parhar regs.len = len; 50154912308SNavdeep Parhar rc = doit(CHELSIO_T4_REGDUMP, ®s); 50254912308SNavdeep Parhar if (rc != 0) 50354912308SNavdeep Parhar return (rc); 50454912308SNavdeep Parhar 50554912308SNavdeep Parhar vers = get_card_vers(regs.version); 50654912308SNavdeep Parhar revision = (regs.version >> 10) & 0x3f; 50754912308SNavdeep Parhar 50854912308SNavdeep Parhar if (vers == 4) { 50954912308SNavdeep Parhar if (revision == 0x3f) 51054912308SNavdeep Parhar rc = dump_regs_t4vf(argc, argv, regs.data); 51154912308SNavdeep Parhar else 51254912308SNavdeep Parhar rc = dump_regs_t4(argc, argv, regs.data); 51354912308SNavdeep Parhar } else if (vers == 5) { 51454912308SNavdeep Parhar if (revision == 0x3f) 51554912308SNavdeep Parhar rc = dump_regs_t5vf(argc, argv, regs.data); 51654912308SNavdeep Parhar else 51754912308SNavdeep Parhar rc = dump_regs_t5(argc, argv, regs.data); 51854912308SNavdeep Parhar } else if (vers == 6) { 51954912308SNavdeep Parhar if (revision == 0x3f) 52054912308SNavdeep Parhar rc = dump_regs_t6vf(argc, argv, regs.data); 52154912308SNavdeep Parhar else 52254912308SNavdeep Parhar rc = dump_regs_t6(argc, argv, regs.data); 52354912308SNavdeep Parhar } else { 52454912308SNavdeep Parhar warnx("%s (type %d, rev %d) is not a known card.", 52554912308SNavdeep Parhar nexus, vers, revision); 52654912308SNavdeep Parhar return (ENOTSUP); 52754912308SNavdeep Parhar } 52854912308SNavdeep Parhar 52954912308SNavdeep Parhar free(regs.data); 53054912308SNavdeep Parhar return (rc); 53154912308SNavdeep Parhar } 53254912308SNavdeep Parhar 53354912308SNavdeep Parhar static void 53454912308SNavdeep Parhar do_show_info_header(uint32_t mode) 53554912308SNavdeep Parhar { 53654912308SNavdeep Parhar uint32_t i; 53754912308SNavdeep Parhar 53854912308SNavdeep Parhar printf("%4s %8s", "Idx", "Hits"); 53954912308SNavdeep Parhar for (i = T4_FILTER_FCoE; i <= T4_FILTER_IP_FRAGMENT; i <<= 1) { 54054912308SNavdeep Parhar switch (mode & i) { 54154912308SNavdeep Parhar case T4_FILTER_FCoE: 54254912308SNavdeep Parhar printf(" FCoE"); 54354912308SNavdeep Parhar break; 54454912308SNavdeep Parhar 54554912308SNavdeep Parhar case T4_FILTER_PORT: 54654912308SNavdeep Parhar printf(" Port"); 54754912308SNavdeep Parhar break; 54854912308SNavdeep Parhar 54954912308SNavdeep Parhar case T4_FILTER_VNIC: 55054912308SNavdeep Parhar if (mode & T4_FILTER_IC_VNIC) 55154912308SNavdeep Parhar printf(" VFvld:PF:VF"); 55254912308SNavdeep Parhar else 55354912308SNavdeep Parhar printf(" vld:oVLAN"); 55454912308SNavdeep Parhar break; 55554912308SNavdeep Parhar 55654912308SNavdeep Parhar case T4_FILTER_VLAN: 55754912308SNavdeep Parhar printf(" vld:VLAN"); 55854912308SNavdeep Parhar break; 55954912308SNavdeep Parhar 56054912308SNavdeep Parhar case T4_FILTER_IP_TOS: 56154912308SNavdeep Parhar printf(" TOS"); 56254912308SNavdeep Parhar break; 56354912308SNavdeep Parhar 56454912308SNavdeep Parhar case T4_FILTER_IP_PROTO: 56554912308SNavdeep Parhar printf(" Prot"); 56654912308SNavdeep Parhar break; 56754912308SNavdeep Parhar 56854912308SNavdeep Parhar case T4_FILTER_ETH_TYPE: 56954912308SNavdeep Parhar printf(" EthType"); 57054912308SNavdeep Parhar break; 57154912308SNavdeep Parhar 57254912308SNavdeep Parhar case T4_FILTER_MAC_IDX: 57354912308SNavdeep Parhar printf(" MACIdx"); 57454912308SNavdeep Parhar break; 57554912308SNavdeep Parhar 57654912308SNavdeep Parhar case T4_FILTER_MPS_HIT_TYPE: 57754912308SNavdeep Parhar printf(" MPS"); 57854912308SNavdeep Parhar break; 57954912308SNavdeep Parhar 58054912308SNavdeep Parhar case T4_FILTER_IP_FRAGMENT: 58154912308SNavdeep Parhar printf(" Frag"); 58254912308SNavdeep Parhar break; 58354912308SNavdeep Parhar 58454912308SNavdeep Parhar default: 58554912308SNavdeep Parhar /* compressed filter field not enabled */ 58654912308SNavdeep Parhar break; 58754912308SNavdeep Parhar } 58854912308SNavdeep Parhar } 58954912308SNavdeep Parhar printf(" %20s %20s %9s %9s %s\n", 59054912308SNavdeep Parhar "DIP", "SIP", "DPORT", "SPORT", "Action"); 59154912308SNavdeep Parhar } 59254912308SNavdeep Parhar 59354912308SNavdeep Parhar /* 59454912308SNavdeep Parhar * Parse an argument sub-vector as a { <parameter name> <value>[:<mask>] } 59554912308SNavdeep Parhar * ordered tuple. If the parameter name in the argument sub-vector does not 59654912308SNavdeep Parhar * match the passed in parameter name, then a zero is returned for the 59754912308SNavdeep Parhar * function and no parsing is performed. If there is a match, then the value 59854912308SNavdeep Parhar * and optional mask are parsed and returned in the provided return value 59954912308SNavdeep Parhar * pointers. If no optional mask is specified, then a default mask of all 1s 60054912308SNavdeep Parhar * will be returned. 60154912308SNavdeep Parhar * 60254912308SNavdeep Parhar * An error in parsing the value[:mask] will result in an error message and 60354912308SNavdeep Parhar * program termination. 60454912308SNavdeep Parhar */ 60554912308SNavdeep Parhar static int 60654912308SNavdeep Parhar parse_val_mask(const char *param, const char *args[], uint32_t *val, 60736ea2fe3SNavdeep Parhar uint32_t *mask, int hashfilter) 60854912308SNavdeep Parhar { 609a12a06faSNavdeep Parhar long l; 61054912308SNavdeep Parhar char *p; 61154912308SNavdeep Parhar 61254912308SNavdeep Parhar if (strcmp(param, args[0]) != 0) 61354912308SNavdeep Parhar return (EINVAL); 61454912308SNavdeep Parhar 615a12a06faSNavdeep Parhar p = str_to_number(args[1], &l, NULL); 616a12a06faSNavdeep Parhar if (l >= 0 && l <= UINT32_MAX) { 617a12a06faSNavdeep Parhar *val = (uint32_t)l; 61854912308SNavdeep Parhar if (p > args[1]) { 61954912308SNavdeep Parhar if (p[0] == 0) { 62054912308SNavdeep Parhar *mask = ~0; 62154912308SNavdeep Parhar return (0); 62254912308SNavdeep Parhar } 62354912308SNavdeep Parhar 62454912308SNavdeep Parhar if (p[0] == ':' && p[1] != 0) { 62536ea2fe3SNavdeep Parhar if (hashfilter) { 62636ea2fe3SNavdeep Parhar warnx("param %s: mask not allowed for " 62736ea2fe3SNavdeep Parhar "hashfilter or nat params", param); 62836ea2fe3SNavdeep Parhar return (EINVAL); 62936ea2fe3SNavdeep Parhar } 630a12a06faSNavdeep Parhar p = str_to_number(p + 1, &l, NULL); 631a12a06faSNavdeep Parhar if (l >= 0 && l <= UINT32_MAX && p[0] == 0) { 632a12a06faSNavdeep Parhar *mask = (uint32_t)l; 63354912308SNavdeep Parhar return (0); 634a12a06faSNavdeep Parhar } 635a12a06faSNavdeep Parhar } 63654912308SNavdeep Parhar } 63754912308SNavdeep Parhar } 63854912308SNavdeep Parhar 63954912308SNavdeep Parhar warnx("parameter \"%s\" has bad \"value[:mask]\" %s", 64054912308SNavdeep Parhar args[0], args[1]); 64154912308SNavdeep Parhar 64254912308SNavdeep Parhar return (EINVAL); 64354912308SNavdeep Parhar } 64454912308SNavdeep Parhar 64554912308SNavdeep Parhar /* 64654912308SNavdeep Parhar * Parse an argument sub-vector as a { <parameter name> <addr>[/<mask>] } 64754912308SNavdeep Parhar * ordered tuple. If the parameter name in the argument sub-vector does not 64854912308SNavdeep Parhar * match the passed in parameter name, then a zero is returned for the 64954912308SNavdeep Parhar * function and no parsing is performed. If there is a match, then the value 65054912308SNavdeep Parhar * and optional mask are parsed and returned in the provided return value 65154912308SNavdeep Parhar * pointers. If no optional mask is specified, then a default mask of all 1s 65254912308SNavdeep Parhar * will be returned. 65354912308SNavdeep Parhar * 65454912308SNavdeep Parhar * The value return parameter "afp" is used to specify the expected address 65554912308SNavdeep Parhar * family -- IPv4 or IPv6 -- of the address[/mask] and return its actual 65654912308SNavdeep Parhar * format. A passed in value of AF_UNSPEC indicates that either IPv4 or IPv6 65754912308SNavdeep Parhar * is acceptable; AF_INET means that only IPv4 addresses are acceptable; and 65854912308SNavdeep Parhar * AF_INET6 means that only IPv6 are acceptable. AF_INET is returned for IPv4 65954912308SNavdeep Parhar * and AF_INET6 for IPv6 addresses, respectively. IPv4 address/mask pairs are 66054912308SNavdeep Parhar * returned in the first four bytes of the address and mask return values with 66154912308SNavdeep Parhar * the address A.B.C.D returned with { A, B, C, D } returned in addresses { 0, 66254912308SNavdeep Parhar * 1, 2, 3}, respectively. 66354912308SNavdeep Parhar * 66454912308SNavdeep Parhar * An error in parsing the value[:mask] will result in an error message and 66554912308SNavdeep Parhar * program termination. 66654912308SNavdeep Parhar */ 66754912308SNavdeep Parhar static int 66854912308SNavdeep Parhar parse_ipaddr(const char *param, const char *args[], int *afp, uint8_t addr[], 66936ea2fe3SNavdeep Parhar uint8_t mask[], int maskless) 67054912308SNavdeep Parhar { 67154912308SNavdeep Parhar const char *colon, *afn; 67254912308SNavdeep Parhar char *slash; 67354912308SNavdeep Parhar uint8_t *m; 67454912308SNavdeep Parhar int af, ret; 67554912308SNavdeep Parhar unsigned int masksize; 67654912308SNavdeep Parhar 67754912308SNavdeep Parhar /* 67854912308SNavdeep Parhar * Is this our parameter? 67954912308SNavdeep Parhar */ 68054912308SNavdeep Parhar if (strcmp(param, args[0]) != 0) 68154912308SNavdeep Parhar return (EINVAL); 68254912308SNavdeep Parhar 68354912308SNavdeep Parhar /* 68454912308SNavdeep Parhar * Fundamental IPv4 versus IPv6 selection. 68554912308SNavdeep Parhar */ 68654912308SNavdeep Parhar colon = strchr(args[1], ':'); 68754912308SNavdeep Parhar if (!colon) { 68854912308SNavdeep Parhar afn = "IPv4"; 68954912308SNavdeep Parhar af = AF_INET; 69054912308SNavdeep Parhar masksize = 32; 69154912308SNavdeep Parhar } else { 69254912308SNavdeep Parhar afn = "IPv6"; 69354912308SNavdeep Parhar af = AF_INET6; 69454912308SNavdeep Parhar masksize = 128; 69554912308SNavdeep Parhar } 69654912308SNavdeep Parhar if (*afp == AF_UNSPEC) 69754912308SNavdeep Parhar *afp = af; 69854912308SNavdeep Parhar else if (*afp != af) { 69954912308SNavdeep Parhar warnx("address %s is not of expected family %s", 70054912308SNavdeep Parhar args[1], *afp == AF_INET ? "IP" : "IPv6"); 70154912308SNavdeep Parhar return (EINVAL); 70254912308SNavdeep Parhar } 70354912308SNavdeep Parhar 70454912308SNavdeep Parhar /* 70554912308SNavdeep Parhar * Parse address (temporarily stripping off any "/mask" 70654912308SNavdeep Parhar * specification). 70754912308SNavdeep Parhar */ 70854912308SNavdeep Parhar slash = strchr(args[1], '/'); 70954912308SNavdeep Parhar if (slash) 71054912308SNavdeep Parhar *slash = 0; 71154912308SNavdeep Parhar ret = inet_pton(af, args[1], addr); 71254912308SNavdeep Parhar if (slash) 71354912308SNavdeep Parhar *slash = '/'; 71454912308SNavdeep Parhar if (ret <= 0) { 71554912308SNavdeep Parhar warnx("Cannot parse %s %s address %s", param, afn, args[1]); 71654912308SNavdeep Parhar return (EINVAL); 71754912308SNavdeep Parhar } 71854912308SNavdeep Parhar 71954912308SNavdeep Parhar /* 72054912308SNavdeep Parhar * Parse optional mask specification. 72154912308SNavdeep Parhar */ 72254912308SNavdeep Parhar if (slash) { 72354912308SNavdeep Parhar char *p; 72454912308SNavdeep Parhar unsigned int prefix = strtoul(slash + 1, &p, 10); 72554912308SNavdeep Parhar 72636ea2fe3SNavdeep Parhar if (maskless) { 72736ea2fe3SNavdeep Parhar warnx("mask cannot be provided for maskless specification"); 72836ea2fe3SNavdeep Parhar return (EINVAL); 72936ea2fe3SNavdeep Parhar } 73036ea2fe3SNavdeep Parhar 73154912308SNavdeep Parhar if (p == slash + 1) { 73254912308SNavdeep Parhar warnx("missing address prefix for %s", param); 73354912308SNavdeep Parhar return (EINVAL); 73454912308SNavdeep Parhar } 73554912308SNavdeep Parhar if (*p) { 73654912308SNavdeep Parhar warnx("%s is not a valid address prefix", slash + 1); 73754912308SNavdeep Parhar return (EINVAL); 73854912308SNavdeep Parhar } 73954912308SNavdeep Parhar if (prefix > masksize) { 74054912308SNavdeep Parhar warnx("prefix %u is too long for an %s address", 74154912308SNavdeep Parhar prefix, afn); 74254912308SNavdeep Parhar return (EINVAL); 74354912308SNavdeep Parhar } 74454912308SNavdeep Parhar memset(mask, 0, masksize / 8); 74554912308SNavdeep Parhar masksize = prefix; 74654912308SNavdeep Parhar } 74754912308SNavdeep Parhar 74836ea2fe3SNavdeep Parhar if (mask != NULL) { 74954912308SNavdeep Parhar /* 75054912308SNavdeep Parhar * Fill in mask. 75154912308SNavdeep Parhar */ 75254912308SNavdeep Parhar for (m = mask; masksize >= 8; m++, masksize -= 8) 75354912308SNavdeep Parhar *m = ~0; 75454912308SNavdeep Parhar if (masksize) 75554912308SNavdeep Parhar *m = ~0 << (8 - masksize); 75636ea2fe3SNavdeep Parhar } 75754912308SNavdeep Parhar 75854912308SNavdeep Parhar return (0); 75954912308SNavdeep Parhar } 76054912308SNavdeep Parhar 76154912308SNavdeep Parhar /* 76254912308SNavdeep Parhar * Parse an argument sub-vector as a { <parameter name> <value> } ordered 76354912308SNavdeep Parhar * tuple. If the parameter name in the argument sub-vector does not match the 76454912308SNavdeep Parhar * passed in parameter name, then a zero is returned for the function and no 76554912308SNavdeep Parhar * parsing is performed. If there is a match, then the value is parsed and 76654912308SNavdeep Parhar * returned in the provided return value pointer. 76754912308SNavdeep Parhar */ 76854912308SNavdeep Parhar static int 76954912308SNavdeep Parhar parse_val(const char *param, const char *args[], uint32_t *val) 77054912308SNavdeep Parhar { 77154912308SNavdeep Parhar char *p; 772a12a06faSNavdeep Parhar long l; 77354912308SNavdeep Parhar 77454912308SNavdeep Parhar if (strcmp(param, args[0]) != 0) 77554912308SNavdeep Parhar return (EINVAL); 77654912308SNavdeep Parhar 777a12a06faSNavdeep Parhar p = str_to_number(args[1], &l, NULL); 778a12a06faSNavdeep Parhar if (*p || l < 0 || l > UINT32_MAX) { 77954912308SNavdeep Parhar warnx("parameter \"%s\" has bad \"value\" %s", args[0], args[1]); 78054912308SNavdeep Parhar return (EINVAL); 78154912308SNavdeep Parhar } 78254912308SNavdeep Parhar 783a12a06faSNavdeep Parhar *val = (uint32_t)l; 784a12a06faSNavdeep Parhar return (0); 785a12a06faSNavdeep Parhar } 786a12a06faSNavdeep Parhar 78754912308SNavdeep Parhar static void 78854912308SNavdeep Parhar filters_show_ipaddr(int type, uint8_t *addr, uint8_t *addrm) 78954912308SNavdeep Parhar { 79054912308SNavdeep Parhar int noctets, octet; 79154912308SNavdeep Parhar 79254912308SNavdeep Parhar printf(" "); 79354912308SNavdeep Parhar if (type == 0) { 79454912308SNavdeep Parhar noctets = 4; 79554912308SNavdeep Parhar printf("%3s", " "); 79654912308SNavdeep Parhar } else 79754912308SNavdeep Parhar noctets = 16; 79854912308SNavdeep Parhar 79954912308SNavdeep Parhar for (octet = 0; octet < noctets; octet++) 80054912308SNavdeep Parhar printf("%02x", addr[octet]); 80154912308SNavdeep Parhar printf("/"); 80254912308SNavdeep Parhar for (octet = 0; octet < noctets; octet++) 80354912308SNavdeep Parhar printf("%02x", addrm[octet]); 80454912308SNavdeep Parhar } 80554912308SNavdeep Parhar 80654912308SNavdeep Parhar static void 80754912308SNavdeep Parhar do_show_one_filter_info(struct t4_filter *t, uint32_t mode) 80854912308SNavdeep Parhar { 80954912308SNavdeep Parhar uint32_t i; 81054912308SNavdeep Parhar 81154912308SNavdeep Parhar printf("%4d", t->idx); 81254912308SNavdeep Parhar if (t->hits == UINT64_MAX) 81354912308SNavdeep Parhar printf(" %8s", "-"); 81454912308SNavdeep Parhar else 81554912308SNavdeep Parhar printf(" %8ju", t->hits); 81654912308SNavdeep Parhar 81754912308SNavdeep Parhar /* 81854912308SNavdeep Parhar * Compressed header portion of filter. 81954912308SNavdeep Parhar */ 82054912308SNavdeep Parhar for (i = T4_FILTER_FCoE; i <= T4_FILTER_IP_FRAGMENT; i <<= 1) { 82154912308SNavdeep Parhar switch (mode & i) { 82254912308SNavdeep Parhar case T4_FILTER_FCoE: 82354912308SNavdeep Parhar printf(" %1d/%1d", t->fs.val.fcoe, t->fs.mask.fcoe); 82454912308SNavdeep Parhar break; 82554912308SNavdeep Parhar 82654912308SNavdeep Parhar case T4_FILTER_PORT: 82754912308SNavdeep Parhar printf(" %1d/%1d", t->fs.val.iport, t->fs.mask.iport); 82854912308SNavdeep Parhar break; 82954912308SNavdeep Parhar 83054912308SNavdeep Parhar case T4_FILTER_VNIC: 83154912308SNavdeep Parhar if (mode & T4_FILTER_IC_VNIC) { 83254912308SNavdeep Parhar printf(" %1d:%1x:%02x/%1d:%1x:%02x", 83354912308SNavdeep Parhar t->fs.val.pfvf_vld, 83454912308SNavdeep Parhar (t->fs.val.vnic >> 13) & 0x7, 83554912308SNavdeep Parhar t->fs.val.vnic & 0x1fff, 83654912308SNavdeep Parhar t->fs.mask.pfvf_vld, 83754912308SNavdeep Parhar (t->fs.mask.vnic >> 13) & 0x7, 83854912308SNavdeep Parhar t->fs.mask.vnic & 0x1fff); 83954912308SNavdeep Parhar } else { 84054912308SNavdeep Parhar printf(" %1d:%04x/%1d:%04x", 84154912308SNavdeep Parhar t->fs.val.ovlan_vld, t->fs.val.vnic, 84254912308SNavdeep Parhar t->fs.mask.ovlan_vld, t->fs.mask.vnic); 84354912308SNavdeep Parhar } 84454912308SNavdeep Parhar break; 84554912308SNavdeep Parhar 84654912308SNavdeep Parhar case T4_FILTER_VLAN: 84754912308SNavdeep Parhar printf(" %1d:%04x/%1d:%04x", 84854912308SNavdeep Parhar t->fs.val.vlan_vld, t->fs.val.vlan, 84954912308SNavdeep Parhar t->fs.mask.vlan_vld, t->fs.mask.vlan); 85054912308SNavdeep Parhar break; 85154912308SNavdeep Parhar 85254912308SNavdeep Parhar case T4_FILTER_IP_TOS: 85354912308SNavdeep Parhar printf(" %02x/%02x", t->fs.val.tos, t->fs.mask.tos); 85454912308SNavdeep Parhar break; 85554912308SNavdeep Parhar 85654912308SNavdeep Parhar case T4_FILTER_IP_PROTO: 85754912308SNavdeep Parhar printf(" %02x/%02x", t->fs.val.proto, t->fs.mask.proto); 85854912308SNavdeep Parhar break; 85954912308SNavdeep Parhar 86054912308SNavdeep Parhar case T4_FILTER_ETH_TYPE: 86154912308SNavdeep Parhar printf(" %04x/%04x", t->fs.val.ethtype, 86254912308SNavdeep Parhar t->fs.mask.ethtype); 86354912308SNavdeep Parhar break; 86454912308SNavdeep Parhar 86554912308SNavdeep Parhar case T4_FILTER_MAC_IDX: 86654912308SNavdeep Parhar printf(" %03x/%03x", t->fs.val.macidx, 86754912308SNavdeep Parhar t->fs.mask.macidx); 86854912308SNavdeep Parhar break; 86954912308SNavdeep Parhar 87054912308SNavdeep Parhar case T4_FILTER_MPS_HIT_TYPE: 87154912308SNavdeep Parhar printf(" %1x/%1x", t->fs.val.matchtype, 87254912308SNavdeep Parhar t->fs.mask.matchtype); 87354912308SNavdeep Parhar break; 87454912308SNavdeep Parhar 87554912308SNavdeep Parhar case T4_FILTER_IP_FRAGMENT: 87654912308SNavdeep Parhar printf(" %1d/%1d", t->fs.val.frag, t->fs.mask.frag); 87754912308SNavdeep Parhar break; 87854912308SNavdeep Parhar 87954912308SNavdeep Parhar default: 88054912308SNavdeep Parhar /* compressed filter field not enabled */ 88154912308SNavdeep Parhar break; 88254912308SNavdeep Parhar } 88354912308SNavdeep Parhar } 88454912308SNavdeep Parhar 88554912308SNavdeep Parhar /* 88654912308SNavdeep Parhar * Fixed portion of filter. 88754912308SNavdeep Parhar */ 88854912308SNavdeep Parhar filters_show_ipaddr(t->fs.type, t->fs.val.dip, t->fs.mask.dip); 88954912308SNavdeep Parhar filters_show_ipaddr(t->fs.type, t->fs.val.sip, t->fs.mask.sip); 89054912308SNavdeep Parhar printf(" %04x/%04x %04x/%04x", 89154912308SNavdeep Parhar t->fs.val.dport, t->fs.mask.dport, 89254912308SNavdeep Parhar t->fs.val.sport, t->fs.mask.sport); 89354912308SNavdeep Parhar 89454912308SNavdeep Parhar /* 89554912308SNavdeep Parhar * Variable length filter action. 89654912308SNavdeep Parhar */ 89754912308SNavdeep Parhar if (t->fs.action == FILTER_DROP) 89854912308SNavdeep Parhar printf(" Drop"); 89954912308SNavdeep Parhar else if (t->fs.action == FILTER_SWITCH) { 90054912308SNavdeep Parhar printf(" Switch: port=%d", t->fs.eport); 90154912308SNavdeep Parhar if (t->fs.newdmac) 90254912308SNavdeep Parhar printf( 90354912308SNavdeep Parhar ", dmac=%02x:%02x:%02x:%02x:%02x:%02x " 90454912308SNavdeep Parhar ", l2tidx=%d", 90554912308SNavdeep Parhar t->fs.dmac[0], t->fs.dmac[1], 90654912308SNavdeep Parhar t->fs.dmac[2], t->fs.dmac[3], 90754912308SNavdeep Parhar t->fs.dmac[4], t->fs.dmac[5], 90854912308SNavdeep Parhar t->l2tidx); 90954912308SNavdeep Parhar if (t->fs.newsmac) 91054912308SNavdeep Parhar printf( 91154912308SNavdeep Parhar ", smac=%02x:%02x:%02x:%02x:%02x:%02x " 91254912308SNavdeep Parhar ", smtidx=%d", 91354912308SNavdeep Parhar t->fs.smac[0], t->fs.smac[1], 91454912308SNavdeep Parhar t->fs.smac[2], t->fs.smac[3], 91554912308SNavdeep Parhar t->fs.smac[4], t->fs.smac[5], 91654912308SNavdeep Parhar t->smtidx); 91754912308SNavdeep Parhar if (t->fs.newvlan == VLAN_REMOVE) 91854912308SNavdeep Parhar printf(", vlan=none"); 91954912308SNavdeep Parhar else if (t->fs.newvlan == VLAN_INSERT) 92054912308SNavdeep Parhar printf(", vlan=insert(%x)", t->fs.vlan); 92154912308SNavdeep Parhar else if (t->fs.newvlan == VLAN_REWRITE) 92254912308SNavdeep Parhar printf(", vlan=rewrite(%x)", t->fs.vlan); 92354912308SNavdeep Parhar } else { 92454912308SNavdeep Parhar printf(" Pass: Q="); 92554912308SNavdeep Parhar if (t->fs.dirsteer == 0) { 92654912308SNavdeep Parhar printf("RSS"); 92754912308SNavdeep Parhar if (t->fs.maskhash) 92854912308SNavdeep Parhar printf("(TCB=hash)"); 92954912308SNavdeep Parhar } else { 93054912308SNavdeep Parhar printf("%d", t->fs.iq); 93154912308SNavdeep Parhar if (t->fs.dirsteerhash == 0) 93254912308SNavdeep Parhar printf("(QID)"); 93354912308SNavdeep Parhar else 93454912308SNavdeep Parhar printf("(hash)"); 93554912308SNavdeep Parhar } 93654912308SNavdeep Parhar } 93754912308SNavdeep Parhar if (t->fs.prio) 93854912308SNavdeep Parhar printf(" Prio"); 93954912308SNavdeep Parhar if (t->fs.rpttid) 94054912308SNavdeep Parhar printf(" RptTID"); 94154912308SNavdeep Parhar printf("\n"); 94254912308SNavdeep Parhar } 94354912308SNavdeep Parhar 94454912308SNavdeep Parhar static int 94536ea2fe3SNavdeep Parhar show_filters(int hash) 94654912308SNavdeep Parhar { 94754912308SNavdeep Parhar uint32_t mode = 0, header = 0; 94854912308SNavdeep Parhar struct t4_filter t; 94954912308SNavdeep Parhar int rc; 95054912308SNavdeep Parhar 95154912308SNavdeep Parhar /* Get the global filter mode first */ 95254912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_FILTER_MODE, &mode); 95354912308SNavdeep Parhar if (rc != 0) 95454912308SNavdeep Parhar return (rc); 95554912308SNavdeep Parhar 95654912308SNavdeep Parhar t.idx = 0; 95736ea2fe3SNavdeep Parhar t.fs.hash = hash; 95854912308SNavdeep Parhar for (t.idx = 0; ; t.idx++) { 95954912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_FILTER, &t); 96054912308SNavdeep Parhar if (rc != 0 || t.idx == 0xffffffff) 96154912308SNavdeep Parhar break; 96254912308SNavdeep Parhar 96354912308SNavdeep Parhar if (!header) { 96454912308SNavdeep Parhar do_show_info_header(mode); 96554912308SNavdeep Parhar header = 1; 96654912308SNavdeep Parhar } 96754912308SNavdeep Parhar do_show_one_filter_info(&t, mode); 96854912308SNavdeep Parhar }; 96954912308SNavdeep Parhar 97054912308SNavdeep Parhar return (rc); 97154912308SNavdeep Parhar } 97254912308SNavdeep Parhar 97354912308SNavdeep Parhar static int 97436ea2fe3SNavdeep Parhar get_filter_mode(int hashfilter) 97554912308SNavdeep Parhar { 97636ea2fe3SNavdeep Parhar uint32_t mode = hashfilter; 97754912308SNavdeep Parhar int rc; 97854912308SNavdeep Parhar 97954912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_FILTER_MODE, &mode); 98054912308SNavdeep Parhar if (rc != 0) 98154912308SNavdeep Parhar return (rc); 98254912308SNavdeep Parhar 98354912308SNavdeep Parhar if (mode & T4_FILTER_IPv4) 98454912308SNavdeep Parhar printf("ipv4 "); 98554912308SNavdeep Parhar 98654912308SNavdeep Parhar if (mode & T4_FILTER_IPv6) 98754912308SNavdeep Parhar printf("ipv6 "); 98854912308SNavdeep Parhar 98954912308SNavdeep Parhar if (mode & T4_FILTER_IP_SADDR) 99054912308SNavdeep Parhar printf("sip "); 99154912308SNavdeep Parhar 99254912308SNavdeep Parhar if (mode & T4_FILTER_IP_DADDR) 99354912308SNavdeep Parhar printf("dip "); 99454912308SNavdeep Parhar 99554912308SNavdeep Parhar if (mode & T4_FILTER_IP_SPORT) 99654912308SNavdeep Parhar printf("sport "); 99754912308SNavdeep Parhar 99854912308SNavdeep Parhar if (mode & T4_FILTER_IP_DPORT) 99954912308SNavdeep Parhar printf("dport "); 100054912308SNavdeep Parhar 100154912308SNavdeep Parhar if (mode & T4_FILTER_IP_FRAGMENT) 100254912308SNavdeep Parhar printf("frag "); 100354912308SNavdeep Parhar 100454912308SNavdeep Parhar if (mode & T4_FILTER_MPS_HIT_TYPE) 100554912308SNavdeep Parhar printf("matchtype "); 100654912308SNavdeep Parhar 100754912308SNavdeep Parhar if (mode & T4_FILTER_MAC_IDX) 100854912308SNavdeep Parhar printf("macidx "); 100954912308SNavdeep Parhar 101054912308SNavdeep Parhar if (mode & T4_FILTER_ETH_TYPE) 101154912308SNavdeep Parhar printf("ethtype "); 101254912308SNavdeep Parhar 101354912308SNavdeep Parhar if (mode & T4_FILTER_IP_PROTO) 101454912308SNavdeep Parhar printf("proto "); 101554912308SNavdeep Parhar 101654912308SNavdeep Parhar if (mode & T4_FILTER_IP_TOS) 101754912308SNavdeep Parhar printf("tos "); 101854912308SNavdeep Parhar 101954912308SNavdeep Parhar if (mode & T4_FILTER_VLAN) 102054912308SNavdeep Parhar printf("vlan "); 102154912308SNavdeep Parhar 102254912308SNavdeep Parhar if (mode & T4_FILTER_VNIC) { 102354912308SNavdeep Parhar if (mode & T4_FILTER_IC_VNIC) 102454912308SNavdeep Parhar printf("vnic_id "); 102554912308SNavdeep Parhar else 102654912308SNavdeep Parhar printf("ovlan "); 102754912308SNavdeep Parhar } 102854912308SNavdeep Parhar 102954912308SNavdeep Parhar if (mode & T4_FILTER_PORT) 103054912308SNavdeep Parhar printf("iport "); 103154912308SNavdeep Parhar 103254912308SNavdeep Parhar if (mode & T4_FILTER_FCoE) 103354912308SNavdeep Parhar printf("fcoe "); 103454912308SNavdeep Parhar 103554912308SNavdeep Parhar printf("\n"); 103654912308SNavdeep Parhar 103754912308SNavdeep Parhar return (0); 103854912308SNavdeep Parhar } 103954912308SNavdeep Parhar 104054912308SNavdeep Parhar static int 104154912308SNavdeep Parhar set_filter_mode(int argc, const char *argv[]) 104254912308SNavdeep Parhar { 104354912308SNavdeep Parhar uint32_t mode = 0; 104454912308SNavdeep Parhar int vnic = 0, ovlan = 0; 104554912308SNavdeep Parhar 104654912308SNavdeep Parhar for (; argc; argc--, argv++) { 104754912308SNavdeep Parhar if (!strcmp(argv[0], "frag")) 104854912308SNavdeep Parhar mode |= T4_FILTER_IP_FRAGMENT; 104954912308SNavdeep Parhar 105054912308SNavdeep Parhar if (!strcmp(argv[0], "matchtype")) 105154912308SNavdeep Parhar mode |= T4_FILTER_MPS_HIT_TYPE; 105254912308SNavdeep Parhar 105354912308SNavdeep Parhar if (!strcmp(argv[0], "macidx")) 105454912308SNavdeep Parhar mode |= T4_FILTER_MAC_IDX; 105554912308SNavdeep Parhar 105654912308SNavdeep Parhar if (!strcmp(argv[0], "ethtype")) 105754912308SNavdeep Parhar mode |= T4_FILTER_ETH_TYPE; 105854912308SNavdeep Parhar 105954912308SNavdeep Parhar if (!strcmp(argv[0], "proto")) 106054912308SNavdeep Parhar mode |= T4_FILTER_IP_PROTO; 106154912308SNavdeep Parhar 106254912308SNavdeep Parhar if (!strcmp(argv[0], "tos")) 106354912308SNavdeep Parhar mode |= T4_FILTER_IP_TOS; 106454912308SNavdeep Parhar 106554912308SNavdeep Parhar if (!strcmp(argv[0], "vlan")) 106654912308SNavdeep Parhar mode |= T4_FILTER_VLAN; 106754912308SNavdeep Parhar 106854912308SNavdeep Parhar if (!strcmp(argv[0], "ovlan")) { 106954912308SNavdeep Parhar mode |= T4_FILTER_VNIC; 107054912308SNavdeep Parhar ovlan++; 107154912308SNavdeep Parhar } 107254912308SNavdeep Parhar 107354912308SNavdeep Parhar if (!strcmp(argv[0], "vnic_id")) { 107454912308SNavdeep Parhar mode |= T4_FILTER_VNIC; 107554912308SNavdeep Parhar mode |= T4_FILTER_IC_VNIC; 107654912308SNavdeep Parhar vnic++; 107754912308SNavdeep Parhar } 107854912308SNavdeep Parhar 107954912308SNavdeep Parhar if (!strcmp(argv[0], "iport")) 108054912308SNavdeep Parhar mode |= T4_FILTER_PORT; 108154912308SNavdeep Parhar 108254912308SNavdeep Parhar if (!strcmp(argv[0], "fcoe")) 108354912308SNavdeep Parhar mode |= T4_FILTER_FCoE; 108454912308SNavdeep Parhar } 108554912308SNavdeep Parhar 108654912308SNavdeep Parhar if (vnic > 0 && ovlan > 0) { 108754912308SNavdeep Parhar warnx("\"vnic_id\" and \"ovlan\" are mutually exclusive."); 108854912308SNavdeep Parhar return (EINVAL); 108954912308SNavdeep Parhar } 109054912308SNavdeep Parhar 109154912308SNavdeep Parhar return doit(CHELSIO_T4_SET_FILTER_MODE, &mode); 109254912308SNavdeep Parhar } 109354912308SNavdeep Parhar 109454912308SNavdeep Parhar static int 109536ea2fe3SNavdeep Parhar del_filter(uint32_t idx, int hashfilter) 109654912308SNavdeep Parhar { 109754912308SNavdeep Parhar struct t4_filter t; 109854912308SNavdeep Parhar 109936ea2fe3SNavdeep Parhar t.fs.hash = hashfilter; 110054912308SNavdeep Parhar t.idx = idx; 110154912308SNavdeep Parhar 110254912308SNavdeep Parhar return doit(CHELSIO_T4_DEL_FILTER, &t); 110354912308SNavdeep Parhar } 110454912308SNavdeep Parhar 11052293e221SNavdeep Parhar #define MAX_VLANID (4095) 11062293e221SNavdeep Parhar 110754912308SNavdeep Parhar static int 110836ea2fe3SNavdeep Parhar set_filter(uint32_t idx, int argc, const char *argv[], int hash) 110954912308SNavdeep Parhar { 111036ea2fe3SNavdeep Parhar int rc, af = AF_UNSPEC, start_arg = 0; 111154912308SNavdeep Parhar struct t4_filter t; 111254912308SNavdeep Parhar 111354912308SNavdeep Parhar if (argc < 2) { 111454912308SNavdeep Parhar warnc(EINVAL, "%s", __func__); 111554912308SNavdeep Parhar return (EINVAL); 111654912308SNavdeep Parhar }; 111754912308SNavdeep Parhar bzero(&t, sizeof (t)); 111854912308SNavdeep Parhar t.idx = idx; 111954912308SNavdeep Parhar t.fs.hitcnts = 1; 112036ea2fe3SNavdeep Parhar t.fs.hash = hash; 112154912308SNavdeep Parhar 112254912308SNavdeep Parhar for (start_arg = 0; start_arg + 2 <= argc; start_arg += 2) { 112354912308SNavdeep Parhar const char **args = &argv[start_arg]; 112454912308SNavdeep Parhar uint32_t val, mask; 112554912308SNavdeep Parhar 112654912308SNavdeep Parhar if (!strcmp(argv[start_arg], "type")) { 112754912308SNavdeep Parhar int newaf; 112854912308SNavdeep Parhar if (!strcasecmp(argv[start_arg + 1], "ipv4")) 112954912308SNavdeep Parhar newaf = AF_INET; 113054912308SNavdeep Parhar else if (!strcasecmp(argv[start_arg + 1], "ipv6")) 113154912308SNavdeep Parhar newaf = AF_INET6; 113254912308SNavdeep Parhar else { 113354912308SNavdeep Parhar warnx("invalid type \"%s\"; " 113454912308SNavdeep Parhar "must be one of \"ipv4\" or \"ipv6\"", 113554912308SNavdeep Parhar argv[start_arg + 1]); 113654912308SNavdeep Parhar return (EINVAL); 113754912308SNavdeep Parhar } 113854912308SNavdeep Parhar 113954912308SNavdeep Parhar if (af != AF_UNSPEC && af != newaf) { 114054912308SNavdeep Parhar warnx("conflicting IPv4/IPv6 specifications."); 114154912308SNavdeep Parhar return (EINVAL); 114254912308SNavdeep Parhar } 114354912308SNavdeep Parhar af = newaf; 114436ea2fe3SNavdeep Parhar } else if (!parse_val_mask("fcoe", args, &val, &mask, hash)) { 114554912308SNavdeep Parhar t.fs.val.fcoe = val; 114654912308SNavdeep Parhar t.fs.mask.fcoe = mask; 114736ea2fe3SNavdeep Parhar } else if (!parse_val_mask("iport", args, &val, &mask, hash)) { 114854912308SNavdeep Parhar t.fs.val.iport = val; 114954912308SNavdeep Parhar t.fs.mask.iport = mask; 115036ea2fe3SNavdeep Parhar } else if (!parse_val_mask("ovlan", args, &val, &mask, hash)) { 115154912308SNavdeep Parhar t.fs.val.vnic = val; 115254912308SNavdeep Parhar t.fs.mask.vnic = mask; 115354912308SNavdeep Parhar t.fs.val.ovlan_vld = 1; 115454912308SNavdeep Parhar t.fs.mask.ovlan_vld = 1; 115536ea2fe3SNavdeep Parhar } else if (!parse_val_mask("ivlan", args, &val, &mask, hash)) { 115654912308SNavdeep Parhar t.fs.val.vlan = val; 115754912308SNavdeep Parhar t.fs.mask.vlan = mask; 115854912308SNavdeep Parhar t.fs.val.vlan_vld = 1; 115954912308SNavdeep Parhar t.fs.mask.vlan_vld = 1; 116036ea2fe3SNavdeep Parhar } else if (!parse_val_mask("pf", args, &val, &mask, hash)) { 116154912308SNavdeep Parhar t.fs.val.vnic &= 0x1fff; 116254912308SNavdeep Parhar t.fs.val.vnic |= (val & 0x7) << 13; 116354912308SNavdeep Parhar t.fs.mask.vnic &= 0x1fff; 116454912308SNavdeep Parhar t.fs.mask.vnic |= (mask & 0x7) << 13; 116554912308SNavdeep Parhar t.fs.val.pfvf_vld = 1; 116654912308SNavdeep Parhar t.fs.mask.pfvf_vld = 1; 116736ea2fe3SNavdeep Parhar } else if (!parse_val_mask("vf", args, &val, &mask, hash)) { 116854912308SNavdeep Parhar t.fs.val.vnic &= 0xe000; 116954912308SNavdeep Parhar t.fs.val.vnic |= val & 0x1fff; 117054912308SNavdeep Parhar t.fs.mask.vnic &= 0xe000; 117154912308SNavdeep Parhar t.fs.mask.vnic |= mask & 0x1fff; 117254912308SNavdeep Parhar t.fs.val.pfvf_vld = 1; 117354912308SNavdeep Parhar t.fs.mask.pfvf_vld = 1; 117436ea2fe3SNavdeep Parhar } else if (!parse_val_mask("tos", args, &val, &mask, hash)) { 117554912308SNavdeep Parhar t.fs.val.tos = val; 117654912308SNavdeep Parhar t.fs.mask.tos = mask; 117736ea2fe3SNavdeep Parhar } else if (!parse_val_mask("proto", args, &val, &mask, hash)) { 117854912308SNavdeep Parhar t.fs.val.proto = val; 117954912308SNavdeep Parhar t.fs.mask.proto = mask; 118036ea2fe3SNavdeep Parhar } else if (!parse_val_mask("ethtype", args, &val, &mask, hash)) { 118154912308SNavdeep Parhar t.fs.val.ethtype = val; 118254912308SNavdeep Parhar t.fs.mask.ethtype = mask; 118336ea2fe3SNavdeep Parhar } else if (!parse_val_mask("macidx", args, &val, &mask, hash)) { 118454912308SNavdeep Parhar t.fs.val.macidx = val; 118554912308SNavdeep Parhar t.fs.mask.macidx = mask; 118636ea2fe3SNavdeep Parhar } else if (!parse_val_mask("matchtype", args, &val, &mask, hash)) { 118754912308SNavdeep Parhar t.fs.val.matchtype = val; 118854912308SNavdeep Parhar t.fs.mask.matchtype = mask; 118936ea2fe3SNavdeep Parhar } else if (!parse_val_mask("frag", args, &val, &mask, hash)) { 119054912308SNavdeep Parhar t.fs.val.frag = val; 119154912308SNavdeep Parhar t.fs.mask.frag = mask; 119236ea2fe3SNavdeep Parhar } else if (!parse_val_mask("dport", args, &val, &mask, hash)) { 119354912308SNavdeep Parhar t.fs.val.dport = val; 119454912308SNavdeep Parhar t.fs.mask.dport = mask; 119536ea2fe3SNavdeep Parhar } else if (!parse_val_mask("sport", args, &val, &mask, hash)) { 119654912308SNavdeep Parhar t.fs.val.sport = val; 119754912308SNavdeep Parhar t.fs.mask.sport = mask; 119854912308SNavdeep Parhar } else if (!parse_ipaddr("dip", args, &af, t.fs.val.dip, 119936ea2fe3SNavdeep Parhar t.fs.mask.dip, hash)) { 120054912308SNavdeep Parhar /* nada */; 120154912308SNavdeep Parhar } else if (!parse_ipaddr("sip", args, &af, t.fs.val.sip, 120236ea2fe3SNavdeep Parhar t.fs.mask.sip, hash)) { 120354912308SNavdeep Parhar /* nada */; 120436ea2fe3SNavdeep Parhar } else if (!parse_ipaddr("nat_dip", args, &af, t.fs.nat_dip, NULL, 1)) { 120536ea2fe3SNavdeep Parhar /*nada*/; 120636ea2fe3SNavdeep Parhar } else if (!parse_ipaddr("nat_sip", args, &af, t.fs.nat_sip, NULL, 1)) { 120736ea2fe3SNavdeep Parhar /*nada*/ 120836ea2fe3SNavdeep Parhar } else if (!parse_val_mask("nat_dport", args, &val, &mask, 1)) { 120936ea2fe3SNavdeep Parhar t.fs.nat_dport = val; 121036ea2fe3SNavdeep Parhar } else if (!parse_val_mask("nat_sport", args, &val, &mask, 1)) { 121136ea2fe3SNavdeep Parhar t.fs.nat_sport = val; 121254912308SNavdeep Parhar } else if (!strcmp(argv[start_arg], "action")) { 121354912308SNavdeep Parhar if (!strcmp(argv[start_arg + 1], "pass")) 121454912308SNavdeep Parhar t.fs.action = FILTER_PASS; 121554912308SNavdeep Parhar else if (!strcmp(argv[start_arg + 1], "drop")) 121654912308SNavdeep Parhar t.fs.action = FILTER_DROP; 121754912308SNavdeep Parhar else if (!strcmp(argv[start_arg + 1], "switch")) 121854912308SNavdeep Parhar t.fs.action = FILTER_SWITCH; 121954912308SNavdeep Parhar else { 122054912308SNavdeep Parhar warnx("invalid action \"%s\"; must be one of" 122154912308SNavdeep Parhar " \"pass\", \"drop\" or \"switch\"", 122254912308SNavdeep Parhar argv[start_arg + 1]); 122354912308SNavdeep Parhar return (EINVAL); 122454912308SNavdeep Parhar } 122554912308SNavdeep Parhar } else if (!parse_val("hitcnts", args, &val)) { 122654912308SNavdeep Parhar t.fs.hitcnts = val; 122754912308SNavdeep Parhar } else if (!parse_val("prio", args, &val)) { 122854912308SNavdeep Parhar t.fs.prio = val; 122954912308SNavdeep Parhar } else if (!parse_val("rpttid", args, &val)) { 123054912308SNavdeep Parhar t.fs.rpttid = 1; 123154912308SNavdeep Parhar } else if (!parse_val("queue", args, &val)) { 123254912308SNavdeep Parhar t.fs.dirsteer = 1; 123354912308SNavdeep Parhar t.fs.iq = val; 123454912308SNavdeep Parhar } else if (!parse_val("tcbhash", args, &val)) { 123554912308SNavdeep Parhar t.fs.maskhash = 1; 123654912308SNavdeep Parhar t.fs.dirsteerhash = 1; 123754912308SNavdeep Parhar } else if (!parse_val("eport", args, &val)) { 123854912308SNavdeep Parhar t.fs.eport = val; 123936ea2fe3SNavdeep Parhar } else if (!parse_val("swapmac", args, &val)) { 124036ea2fe3SNavdeep Parhar t.fs.swapmac = 1; 124136ea2fe3SNavdeep Parhar } else if (!strcmp(argv[start_arg], "nat")) { 124236ea2fe3SNavdeep Parhar if (!strcmp(argv[start_arg + 1], "dip")) 124336ea2fe3SNavdeep Parhar t.fs.nat_mode = NAT_MODE_DIP; 124436ea2fe3SNavdeep Parhar else if (!strcmp(argv[start_arg + 1], "dip-dp")) 124536ea2fe3SNavdeep Parhar t.fs.nat_mode = NAT_MODE_DIP_DP; 124636ea2fe3SNavdeep Parhar else if (!strcmp(argv[start_arg + 1], "dip-dp-sip")) 124736ea2fe3SNavdeep Parhar t.fs.nat_mode = NAT_MODE_DIP_DP_SIP; 124836ea2fe3SNavdeep Parhar else if (!strcmp(argv[start_arg + 1], "dip-dp-sp")) 124936ea2fe3SNavdeep Parhar t.fs.nat_mode = NAT_MODE_DIP_DP_SP; 125036ea2fe3SNavdeep Parhar else if (!strcmp(argv[start_arg + 1], "sip-sp")) 125136ea2fe3SNavdeep Parhar t.fs.nat_mode = NAT_MODE_SIP_SP; 125236ea2fe3SNavdeep Parhar else if (!strcmp(argv[start_arg + 1], "dip-sip-sp")) 125336ea2fe3SNavdeep Parhar t.fs.nat_mode = NAT_MODE_DIP_SIP_SP; 125436ea2fe3SNavdeep Parhar else if (!strcmp(argv[start_arg + 1], "all")) 125536ea2fe3SNavdeep Parhar t.fs.nat_mode = NAT_MODE_ALL; 125636ea2fe3SNavdeep Parhar else { 125736ea2fe3SNavdeep Parhar warnx("unknown nat type \"%s\"; known types are dip, " 125836ea2fe3SNavdeep Parhar "dip-dp, dip-dp-sip, dip-dp-sp, sip-sp, " 125936ea2fe3SNavdeep Parhar "dip-sip-sp, and all", argv[start_arg + 1]); 126036ea2fe3SNavdeep Parhar return (EINVAL); 126136ea2fe3SNavdeep Parhar } 126236ea2fe3SNavdeep Parhar } else if (!parse_val("natseq", args, &val)) { 126336ea2fe3SNavdeep Parhar t.fs.nat_seq_chk = val; 126436ea2fe3SNavdeep Parhar } else if (!parse_val("natflag", args, &val)) { 126536ea2fe3SNavdeep Parhar t.fs.nat_flag_chk = 1; 126654912308SNavdeep Parhar } else if (!strcmp(argv[start_arg], "dmac")) { 126754912308SNavdeep Parhar struct ether_addr *daddr; 126854912308SNavdeep Parhar 126954912308SNavdeep Parhar daddr = ether_aton(argv[start_arg + 1]); 127054912308SNavdeep Parhar if (daddr == NULL) { 127154912308SNavdeep Parhar warnx("invalid dmac address \"%s\"", 127254912308SNavdeep Parhar argv[start_arg + 1]); 127354912308SNavdeep Parhar return (EINVAL); 127454912308SNavdeep Parhar } 127554912308SNavdeep Parhar memcpy(t.fs.dmac, daddr, ETHER_ADDR_LEN); 127654912308SNavdeep Parhar t.fs.newdmac = 1; 127754912308SNavdeep Parhar } else if (!strcmp(argv[start_arg], "smac")) { 127854912308SNavdeep Parhar struct ether_addr *saddr; 127954912308SNavdeep Parhar 128054912308SNavdeep Parhar saddr = ether_aton(argv[start_arg + 1]); 128154912308SNavdeep Parhar if (saddr == NULL) { 128254912308SNavdeep Parhar warnx("invalid smac address \"%s\"", 128354912308SNavdeep Parhar argv[start_arg + 1]); 128454912308SNavdeep Parhar return (EINVAL); 128554912308SNavdeep Parhar } 128654912308SNavdeep Parhar memcpy(t.fs.smac, saddr, ETHER_ADDR_LEN); 128754912308SNavdeep Parhar t.fs.newsmac = 1; 128854912308SNavdeep Parhar } else if (!strcmp(argv[start_arg], "vlan")) { 128954912308SNavdeep Parhar char *p; 129054912308SNavdeep Parhar if (!strcmp(argv[start_arg + 1], "none")) { 129154912308SNavdeep Parhar t.fs.newvlan = VLAN_REMOVE; 129254912308SNavdeep Parhar } else if (argv[start_arg + 1][0] == '=') { 129354912308SNavdeep Parhar t.fs.newvlan = VLAN_REWRITE; 129454912308SNavdeep Parhar } else if (argv[start_arg + 1][0] == '+') { 129554912308SNavdeep Parhar t.fs.newvlan = VLAN_INSERT; 129654912308SNavdeep Parhar } else if (isdigit(argv[start_arg + 1][0]) && 129736ea2fe3SNavdeep Parhar !parse_val_mask("vlan", args, &val, &mask, hash)) { 129854912308SNavdeep Parhar t.fs.val.vlan = val; 129954912308SNavdeep Parhar t.fs.mask.vlan = mask; 130054912308SNavdeep Parhar t.fs.val.vlan_vld = 1; 130154912308SNavdeep Parhar t.fs.mask.vlan_vld = 1; 130254912308SNavdeep Parhar } else { 130354912308SNavdeep Parhar warnx("unknown vlan parameter \"%s\"; must" 130454912308SNavdeep Parhar " be one of \"none\", \"=<vlan>\", " 130554912308SNavdeep Parhar " \"+<vlan>\", or \"<vlan>\"", 130654912308SNavdeep Parhar argv[start_arg + 1]); 130754912308SNavdeep Parhar return (EINVAL); 130854912308SNavdeep Parhar } 130954912308SNavdeep Parhar if (t.fs.newvlan == VLAN_REWRITE || 131054912308SNavdeep Parhar t.fs.newvlan == VLAN_INSERT) { 131154912308SNavdeep Parhar t.fs.vlan = strtoul(argv[start_arg + 1] + 1, 131254912308SNavdeep Parhar &p, 0); 13132293e221SNavdeep Parhar if (p == argv[start_arg + 1] + 1 || p[0] != 0 || 13142293e221SNavdeep Parhar t.fs.vlan > MAX_VLANID) { 131554912308SNavdeep Parhar warnx("invalid vlan \"%s\"", 131654912308SNavdeep Parhar argv[start_arg + 1]); 131754912308SNavdeep Parhar return (EINVAL); 131854912308SNavdeep Parhar } 131954912308SNavdeep Parhar } 132054912308SNavdeep Parhar } else { 132154912308SNavdeep Parhar warnx("invalid parameter \"%s\"", argv[start_arg]); 132254912308SNavdeep Parhar return (EINVAL); 132354912308SNavdeep Parhar } 132454912308SNavdeep Parhar } 132554912308SNavdeep Parhar if (start_arg != argc) { 132654912308SNavdeep Parhar warnx("no value for \"%s\"", argv[start_arg]); 132754912308SNavdeep Parhar return (EINVAL); 132854912308SNavdeep Parhar } 132954912308SNavdeep Parhar 133054912308SNavdeep Parhar /* 133154912308SNavdeep Parhar * Check basic sanity of option combinations. 133254912308SNavdeep Parhar */ 133354912308SNavdeep Parhar if (t.fs.action != FILTER_SWITCH && 133436ea2fe3SNavdeep Parhar (t.fs.eport || t.fs.newdmac || t.fs.newsmac || t.fs.newvlan || 133536ea2fe3SNavdeep Parhar t.fs.swapmac || t.fs.nat_mode)) { 133636ea2fe3SNavdeep Parhar warnx("port, dmac, smac, vlan, and nat only make sense with" 133754912308SNavdeep Parhar " \"action switch\""); 133854912308SNavdeep Parhar return (EINVAL); 133954912308SNavdeep Parhar } 134036ea2fe3SNavdeep Parhar if (!t.fs.nat_mode && (t.fs.nat_seq_chk || t.fs.nat_flag_chk || 134136ea2fe3SNavdeep Parhar *t.fs.nat_dip || *t.fs.nat_sip || t.fs.nat_dport || t.fs.nat_sport)) { 134236ea2fe3SNavdeep Parhar warnx("nat params only make sense with valid nat mode"); 134336ea2fe3SNavdeep Parhar return (EINVAL); 134436ea2fe3SNavdeep Parhar } 134554912308SNavdeep Parhar if (t.fs.action != FILTER_PASS && 134654912308SNavdeep Parhar (t.fs.rpttid || t.fs.dirsteer || t.fs.maskhash)) { 134754912308SNavdeep Parhar warnx("rpttid, queue and tcbhash don't make sense with" 134854912308SNavdeep Parhar " action \"drop\" or \"switch\""); 134954912308SNavdeep Parhar return (EINVAL); 135054912308SNavdeep Parhar } 135154912308SNavdeep Parhar if (t.fs.val.ovlan_vld && t.fs.val.pfvf_vld) { 135254912308SNavdeep Parhar warnx("ovlan and vnic_id (pf/vf) are mutually exclusive"); 135354912308SNavdeep Parhar return (EINVAL); 135454912308SNavdeep Parhar } 135554912308SNavdeep Parhar 135654912308SNavdeep Parhar t.fs.type = (af == AF_INET6 ? 1 : 0); /* default IPv4 */ 135736ea2fe3SNavdeep Parhar rc = doit(CHELSIO_T4_SET_FILTER, &t); 135836ea2fe3SNavdeep Parhar if (hash && rc == 0) 135936ea2fe3SNavdeep Parhar printf("%d\n", t.idx); 136036ea2fe3SNavdeep Parhar return (rc); 136154912308SNavdeep Parhar } 136254912308SNavdeep Parhar 136354912308SNavdeep Parhar static int 136436ea2fe3SNavdeep Parhar filter_cmd(int argc, const char *argv[], int hashfilter) 136554912308SNavdeep Parhar { 136654912308SNavdeep Parhar long long val; 136754912308SNavdeep Parhar uint32_t idx; 136854912308SNavdeep Parhar char *s; 136954912308SNavdeep Parhar 137054912308SNavdeep Parhar if (argc == 0) { 137136ea2fe3SNavdeep Parhar warnx("%sfilter: no arguments.", hashfilter ? "hash" : ""); 137254912308SNavdeep Parhar return (EINVAL); 137354912308SNavdeep Parhar }; 137454912308SNavdeep Parhar 137554912308SNavdeep Parhar /* list */ 137654912308SNavdeep Parhar if (strcmp(argv[0], "list") == 0) { 137754912308SNavdeep Parhar if (argc != 1) 137854912308SNavdeep Parhar warnx("trailing arguments after \"list\" ignored."); 137954912308SNavdeep Parhar 138036ea2fe3SNavdeep Parhar return show_filters(hashfilter); 138154912308SNavdeep Parhar } 138254912308SNavdeep Parhar 138354912308SNavdeep Parhar /* mode */ 138454912308SNavdeep Parhar if (argc == 1 && strcmp(argv[0], "mode") == 0) 138536ea2fe3SNavdeep Parhar return get_filter_mode(hashfilter); 138654912308SNavdeep Parhar 138754912308SNavdeep Parhar /* mode <mode> */ 138836ea2fe3SNavdeep Parhar if (!hashfilter && strcmp(argv[0], "mode") == 0) 138954912308SNavdeep Parhar return set_filter_mode(argc - 1, argv + 1); 139054912308SNavdeep Parhar 139154912308SNavdeep Parhar /* <idx> ... */ 139254912308SNavdeep Parhar s = str_to_number(argv[0], NULL, &val); 139336ea2fe3SNavdeep Parhar if (*s || val < 0 || val > 0xffffffffU) { 139436ea2fe3SNavdeep Parhar if (hashfilter) { 139536ea2fe3SNavdeep Parhar /* 139636ea2fe3SNavdeep Parhar * No numeric index means this must be a request to 139736ea2fe3SNavdeep Parhar * create a new hashfilter and we are already at the 139836ea2fe3SNavdeep Parhar * paramter/value list. 139936ea2fe3SNavdeep Parhar */ 140036ea2fe3SNavdeep Parhar idx = (uint32_t) -1; 140136ea2fe3SNavdeep Parhar goto setf; 140236ea2fe3SNavdeep Parhar } 140354912308SNavdeep Parhar warnx("\"%s\" is neither an index nor a filter subcommand.", 140454912308SNavdeep Parhar argv[0]); 140554912308SNavdeep Parhar return (EINVAL); 140654912308SNavdeep Parhar } 140754912308SNavdeep Parhar idx = (uint32_t) val; 140854912308SNavdeep Parhar 140954912308SNavdeep Parhar /* <idx> delete|clear */ 141054912308SNavdeep Parhar if (argc == 2 && 141154912308SNavdeep Parhar (strcmp(argv[1], "delete") == 0 || strcmp(argv[1], "clear") == 0)) { 141236ea2fe3SNavdeep Parhar return del_filter(idx, hashfilter); 141354912308SNavdeep Parhar } 141454912308SNavdeep Parhar 141536ea2fe3SNavdeep Parhar /* skip <idx> */ 141636ea2fe3SNavdeep Parhar argc--; 141736ea2fe3SNavdeep Parhar argv++; 141836ea2fe3SNavdeep Parhar 141936ea2fe3SNavdeep Parhar setf: 142036ea2fe3SNavdeep Parhar /* [<param> <val>] ... */ 142136ea2fe3SNavdeep Parhar return set_filter(idx, argc, argv, hashfilter); 142254912308SNavdeep Parhar } 142354912308SNavdeep Parhar 142454912308SNavdeep Parhar /* 142554912308SNavdeep Parhar * Shows the fields of a multi-word structure. The structure is considered to 142654912308SNavdeep Parhar * consist of @nwords 32-bit words (i.e, it's an (@nwords * 32)-bit structure) 142754912308SNavdeep Parhar * whose fields are described by @fd. The 32-bit words are given in @words 142854912308SNavdeep Parhar * starting with the least significant 32-bit word. 142954912308SNavdeep Parhar */ 143054912308SNavdeep Parhar static void 143154912308SNavdeep Parhar show_struct(const uint32_t *words, int nwords, const struct field_desc *fd) 143254912308SNavdeep Parhar { 143354912308SNavdeep Parhar unsigned int w = 0; 143454912308SNavdeep Parhar const struct field_desc *p; 143554912308SNavdeep Parhar 143654912308SNavdeep Parhar for (p = fd; p->name; p++) 143754912308SNavdeep Parhar w = max(w, strlen(p->name)); 143854912308SNavdeep Parhar 143954912308SNavdeep Parhar while (fd->name) { 144054912308SNavdeep Parhar unsigned long long data; 144154912308SNavdeep Parhar int first_word = fd->start / 32; 144254912308SNavdeep Parhar int shift = fd->start % 32; 144354912308SNavdeep Parhar int width = fd->end - fd->start + 1; 144454912308SNavdeep Parhar unsigned long long mask = (1ULL << width) - 1; 144554912308SNavdeep Parhar 144654912308SNavdeep Parhar data = (words[first_word] >> shift) | 144754912308SNavdeep Parhar ((uint64_t)words[first_word + 1] << (32 - shift)); 144854912308SNavdeep Parhar if (shift) 144954912308SNavdeep Parhar data |= ((uint64_t)words[first_word + 2] << (64 - shift)); 145054912308SNavdeep Parhar data &= mask; 145154912308SNavdeep Parhar if (fd->islog2) 145254912308SNavdeep Parhar data = 1 << data; 145354912308SNavdeep Parhar printf("%-*s ", w, fd->name); 145454912308SNavdeep Parhar printf(fd->hex ? "%#llx\n" : "%llu\n", data << fd->shift); 145554912308SNavdeep Parhar fd++; 145654912308SNavdeep Parhar } 145754912308SNavdeep Parhar } 145854912308SNavdeep Parhar 145954912308SNavdeep Parhar #define FIELD(name, start, end) { name, start, end, 0, 0, 0 } 146054912308SNavdeep Parhar #define FIELD1(name, start) FIELD(name, start, start) 146154912308SNavdeep Parhar 146254912308SNavdeep Parhar static void 146354912308SNavdeep Parhar show_t5t6_ctxt(const struct t4_sge_context *p, int vers) 146454912308SNavdeep Parhar { 146554912308SNavdeep Parhar static struct field_desc egress_t5[] = { 146654912308SNavdeep Parhar FIELD("DCA_ST:", 181, 191), 146754912308SNavdeep Parhar FIELD1("StatusPgNS:", 180), 146854912308SNavdeep Parhar FIELD1("StatusPgRO:", 179), 146954912308SNavdeep Parhar FIELD1("FetchNS:", 178), 147054912308SNavdeep Parhar FIELD1("FetchRO:", 177), 147154912308SNavdeep Parhar FIELD1("Valid:", 176), 147254912308SNavdeep Parhar FIELD("PCIeDataChannel:", 174, 175), 147354912308SNavdeep Parhar FIELD1("StatusPgTPHintEn:", 173), 147454912308SNavdeep Parhar FIELD("StatusPgTPHint:", 171, 172), 147554912308SNavdeep Parhar FIELD1("FetchTPHintEn:", 170), 147654912308SNavdeep Parhar FIELD("FetchTPHint:", 168, 169), 147754912308SNavdeep Parhar FIELD1("FCThreshOverride:", 167), 147854912308SNavdeep Parhar { "WRLength:", 162, 166, 9, 0, 1 }, 147954912308SNavdeep Parhar FIELD1("WRLengthKnown:", 161), 148054912308SNavdeep Parhar FIELD1("ReschedulePending:", 160), 148154912308SNavdeep Parhar FIELD1("OnChipQueue:", 159), 148254912308SNavdeep Parhar FIELD1("FetchSizeMode:", 158), 148354912308SNavdeep Parhar { "FetchBurstMin:", 156, 157, 4, 0, 1 }, 148454912308SNavdeep Parhar FIELD1("FLMPacking:", 155), 148554912308SNavdeep Parhar FIELD("FetchBurstMax:", 153, 154), 148654912308SNavdeep Parhar FIELD("uPToken:", 133, 152), 148754912308SNavdeep Parhar FIELD1("uPTokenEn:", 132), 148854912308SNavdeep Parhar FIELD1("UserModeIO:", 131), 148954912308SNavdeep Parhar FIELD("uPFLCredits:", 123, 130), 149054912308SNavdeep Parhar FIELD1("uPFLCreditEn:", 122), 149154912308SNavdeep Parhar FIELD("FID:", 111, 121), 149254912308SNavdeep Parhar FIELD("HostFCMode:", 109, 110), 149354912308SNavdeep Parhar FIELD1("HostFCOwner:", 108), 149454912308SNavdeep Parhar { "CIDXFlushThresh:", 105, 107, 0, 0, 1 }, 149554912308SNavdeep Parhar FIELD("CIDX:", 89, 104), 149654912308SNavdeep Parhar FIELD("PIDX:", 73, 88), 149754912308SNavdeep Parhar { "BaseAddress:", 18, 72, 9, 1 }, 149854912308SNavdeep Parhar FIELD("QueueSize:", 2, 17), 149954912308SNavdeep Parhar FIELD1("QueueType:", 1), 150054912308SNavdeep Parhar FIELD1("CachePriority:", 0), 150154912308SNavdeep Parhar { NULL } 150254912308SNavdeep Parhar }; 150354912308SNavdeep Parhar static struct field_desc egress_t6[] = { 150454912308SNavdeep Parhar FIELD("DCA_ST:", 181, 191), 150554912308SNavdeep Parhar FIELD1("StatusPgNS:", 180), 150654912308SNavdeep Parhar FIELD1("StatusPgRO:", 179), 150754912308SNavdeep Parhar FIELD1("FetchNS:", 178), 150854912308SNavdeep Parhar FIELD1("FetchRO:", 177), 150954912308SNavdeep Parhar FIELD1("Valid:", 176), 151054912308SNavdeep Parhar FIELD1("ReschedulePending_1:", 175), 151154912308SNavdeep Parhar FIELD1("PCIeDataChannel:", 174), 151254912308SNavdeep Parhar FIELD1("StatusPgTPHintEn:", 173), 151354912308SNavdeep Parhar FIELD("StatusPgTPHint:", 171, 172), 151454912308SNavdeep Parhar FIELD1("FetchTPHintEn:", 170), 151554912308SNavdeep Parhar FIELD("FetchTPHint:", 168, 169), 151654912308SNavdeep Parhar FIELD1("FCThreshOverride:", 167), 151754912308SNavdeep Parhar { "WRLength:", 162, 166, 9, 0, 1 }, 151854912308SNavdeep Parhar FIELD1("WRLengthKnown:", 161), 151954912308SNavdeep Parhar FIELD1("ReschedulePending:", 160), 152054912308SNavdeep Parhar FIELD("TimerIx:", 157, 159), 152154912308SNavdeep Parhar FIELD1("FetchBurstMin:", 156), 152254912308SNavdeep Parhar FIELD1("FLMPacking:", 155), 152354912308SNavdeep Parhar FIELD("FetchBurstMax:", 153, 154), 152454912308SNavdeep Parhar FIELD("uPToken:", 133, 152), 152554912308SNavdeep Parhar FIELD1("uPTokenEn:", 132), 152654912308SNavdeep Parhar FIELD1("UserModeIO:", 131), 152754912308SNavdeep Parhar FIELD("uPFLCredits:", 123, 130), 152854912308SNavdeep Parhar FIELD1("uPFLCreditEn:", 122), 152954912308SNavdeep Parhar FIELD("FID:", 111, 121), 153054912308SNavdeep Parhar FIELD("HostFCMode:", 109, 110), 153154912308SNavdeep Parhar FIELD1("HostFCOwner:", 108), 153254912308SNavdeep Parhar { "CIDXFlushThresh:", 105, 107, 0, 0, 1 }, 153354912308SNavdeep Parhar FIELD("CIDX:", 89, 104), 153454912308SNavdeep Parhar FIELD("PIDX:", 73, 88), 153554912308SNavdeep Parhar { "BaseAddress:", 18, 72, 9, 1 }, 153654912308SNavdeep Parhar FIELD("QueueSize:", 2, 17), 153754912308SNavdeep Parhar FIELD1("QueueType:", 1), 153854912308SNavdeep Parhar FIELD1("FetchSizeMode:", 0), 153954912308SNavdeep Parhar { NULL } 154054912308SNavdeep Parhar }; 154154912308SNavdeep Parhar static struct field_desc fl_t5[] = { 154254912308SNavdeep Parhar FIELD("DCA_ST:", 181, 191), 154354912308SNavdeep Parhar FIELD1("StatusPgNS:", 180), 154454912308SNavdeep Parhar FIELD1("StatusPgRO:", 179), 154554912308SNavdeep Parhar FIELD1("FetchNS:", 178), 154654912308SNavdeep Parhar FIELD1("FetchRO:", 177), 154754912308SNavdeep Parhar FIELD1("Valid:", 176), 154854912308SNavdeep Parhar FIELD("PCIeDataChannel:", 174, 175), 154954912308SNavdeep Parhar FIELD1("StatusPgTPHintEn:", 173), 155054912308SNavdeep Parhar FIELD("StatusPgTPHint:", 171, 172), 155154912308SNavdeep Parhar FIELD1("FetchTPHintEn:", 170), 155254912308SNavdeep Parhar FIELD("FetchTPHint:", 168, 169), 155354912308SNavdeep Parhar FIELD1("FCThreshOverride:", 167), 155454912308SNavdeep Parhar FIELD1("ReschedulePending:", 160), 155554912308SNavdeep Parhar FIELD1("OnChipQueue:", 159), 155654912308SNavdeep Parhar FIELD1("FetchSizeMode:", 158), 155754912308SNavdeep Parhar { "FetchBurstMin:", 156, 157, 4, 0, 1 }, 155854912308SNavdeep Parhar FIELD1("FLMPacking:", 155), 155954912308SNavdeep Parhar FIELD("FetchBurstMax:", 153, 154), 156054912308SNavdeep Parhar FIELD1("FLMcongMode:", 152), 156154912308SNavdeep Parhar FIELD("MaxuPFLCredits:", 144, 151), 156254912308SNavdeep Parhar FIELD("FLMcontextID:", 133, 143), 156354912308SNavdeep Parhar FIELD1("uPTokenEn:", 132), 156454912308SNavdeep Parhar FIELD1("UserModeIO:", 131), 156554912308SNavdeep Parhar FIELD("uPFLCredits:", 123, 130), 156654912308SNavdeep Parhar FIELD1("uPFLCreditEn:", 122), 156754912308SNavdeep Parhar FIELD("FID:", 111, 121), 156854912308SNavdeep Parhar FIELD("HostFCMode:", 109, 110), 156954912308SNavdeep Parhar FIELD1("HostFCOwner:", 108), 157054912308SNavdeep Parhar { "CIDXFlushThresh:", 105, 107, 0, 0, 1 }, 157154912308SNavdeep Parhar FIELD("CIDX:", 89, 104), 157254912308SNavdeep Parhar FIELD("PIDX:", 73, 88), 157354912308SNavdeep Parhar { "BaseAddress:", 18, 72, 9, 1 }, 157454912308SNavdeep Parhar FIELD("QueueSize:", 2, 17), 157554912308SNavdeep Parhar FIELD1("QueueType:", 1), 157654912308SNavdeep Parhar FIELD1("CachePriority:", 0), 157754912308SNavdeep Parhar { NULL } 157854912308SNavdeep Parhar }; 157954912308SNavdeep Parhar static struct field_desc ingress_t5[] = { 158054912308SNavdeep Parhar FIELD("DCA_ST:", 143, 153), 158154912308SNavdeep Parhar FIELD1("ISCSICoalescing:", 142), 158254912308SNavdeep Parhar FIELD1("Queue_Valid:", 141), 158354912308SNavdeep Parhar FIELD1("TimerPending:", 140), 158454912308SNavdeep Parhar FIELD1("DropRSS:", 139), 158554912308SNavdeep Parhar FIELD("PCIeChannel:", 137, 138), 158654912308SNavdeep Parhar FIELD1("SEInterruptArmed:", 136), 158754912308SNavdeep Parhar FIELD1("CongestionMgtEnable:", 135), 158854912308SNavdeep Parhar FIELD1("NoSnoop:", 134), 158954912308SNavdeep Parhar FIELD1("RelaxedOrdering:", 133), 159054912308SNavdeep Parhar FIELD1("GTSmode:", 132), 159154912308SNavdeep Parhar FIELD1("TPHintEn:", 131), 159254912308SNavdeep Parhar FIELD("TPHint:", 129, 130), 159354912308SNavdeep Parhar FIELD1("UpdateScheduling:", 128), 159454912308SNavdeep Parhar FIELD("UpdateDelivery:", 126, 127), 159554912308SNavdeep Parhar FIELD1("InterruptSent:", 125), 159654912308SNavdeep Parhar FIELD("InterruptIDX:", 114, 124), 159754912308SNavdeep Parhar FIELD1("InterruptDestination:", 113), 159854912308SNavdeep Parhar FIELD1("InterruptArmed:", 112), 159954912308SNavdeep Parhar FIELD("RxIntCounter:", 106, 111), 160054912308SNavdeep Parhar FIELD("RxIntCounterThreshold:", 104, 105), 160154912308SNavdeep Parhar FIELD1("Generation:", 103), 160254912308SNavdeep Parhar { "BaseAddress:", 48, 102, 9, 1 }, 160354912308SNavdeep Parhar FIELD("PIDX:", 32, 47), 160454912308SNavdeep Parhar FIELD("CIDX:", 16, 31), 160554912308SNavdeep Parhar { "QueueSize:", 4, 15, 4, 0 }, 160654912308SNavdeep Parhar { "QueueEntrySize:", 2, 3, 4, 0, 1 }, 160754912308SNavdeep Parhar FIELD1("QueueEntryOverride:", 1), 160854912308SNavdeep Parhar FIELD1("CachePriority:", 0), 160954912308SNavdeep Parhar { NULL } 161054912308SNavdeep Parhar }; 161154912308SNavdeep Parhar static struct field_desc ingress_t6[] = { 161254912308SNavdeep Parhar FIELD1("SP_NS:", 158), 161354912308SNavdeep Parhar FIELD1("SP_RO:", 157), 161454912308SNavdeep Parhar FIELD1("SP_TPHintEn:", 156), 161554912308SNavdeep Parhar FIELD("SP_TPHint:", 154, 155), 161654912308SNavdeep Parhar FIELD("DCA_ST:", 143, 153), 161754912308SNavdeep Parhar FIELD1("ISCSICoalescing:", 142), 161854912308SNavdeep Parhar FIELD1("Queue_Valid:", 141), 161954912308SNavdeep Parhar FIELD1("TimerPending:", 140), 162054912308SNavdeep Parhar FIELD1("DropRSS:", 139), 162154912308SNavdeep Parhar FIELD("PCIeChannel:", 137, 138), 162254912308SNavdeep Parhar FIELD1("SEInterruptArmed:", 136), 162354912308SNavdeep Parhar FIELD1("CongestionMgtEnable:", 135), 162454912308SNavdeep Parhar FIELD1("NoSnoop:", 134), 162554912308SNavdeep Parhar FIELD1("RelaxedOrdering:", 133), 162654912308SNavdeep Parhar FIELD1("GTSmode:", 132), 162754912308SNavdeep Parhar FIELD1("TPHintEn:", 131), 162854912308SNavdeep Parhar FIELD("TPHint:", 129, 130), 162954912308SNavdeep Parhar FIELD1("UpdateScheduling:", 128), 163054912308SNavdeep Parhar FIELD("UpdateDelivery:", 126, 127), 163154912308SNavdeep Parhar FIELD1("InterruptSent:", 125), 163254912308SNavdeep Parhar FIELD("InterruptIDX:", 114, 124), 163354912308SNavdeep Parhar FIELD1("InterruptDestination:", 113), 163454912308SNavdeep Parhar FIELD1("InterruptArmed:", 112), 163554912308SNavdeep Parhar FIELD("RxIntCounter:", 106, 111), 163654912308SNavdeep Parhar FIELD("RxIntCounterThreshold:", 104, 105), 163754912308SNavdeep Parhar FIELD1("Generation:", 103), 163854912308SNavdeep Parhar { "BaseAddress:", 48, 102, 9, 1 }, 163954912308SNavdeep Parhar FIELD("PIDX:", 32, 47), 164054912308SNavdeep Parhar FIELD("CIDX:", 16, 31), 164154912308SNavdeep Parhar { "QueueSize:", 4, 15, 4, 0 }, 164254912308SNavdeep Parhar { "QueueEntrySize:", 2, 3, 4, 0, 1 }, 164354912308SNavdeep Parhar FIELD1("QueueEntryOverride:", 1), 164454912308SNavdeep Parhar FIELD1("CachePriority:", 0), 164554912308SNavdeep Parhar { NULL } 164654912308SNavdeep Parhar }; 164754912308SNavdeep Parhar static struct field_desc flm_t5[] = { 164854912308SNavdeep Parhar FIELD1("Valid:", 89), 164954912308SNavdeep Parhar FIELD("SplitLenMode:", 87, 88), 165054912308SNavdeep Parhar FIELD1("TPHintEn:", 86), 165154912308SNavdeep Parhar FIELD("TPHint:", 84, 85), 165254912308SNavdeep Parhar FIELD1("NoSnoop:", 83), 165354912308SNavdeep Parhar FIELD1("RelaxedOrdering:", 82), 165454912308SNavdeep Parhar FIELD("DCA_ST:", 71, 81), 165554912308SNavdeep Parhar FIELD("EQid:", 54, 70), 165654912308SNavdeep Parhar FIELD("SplitEn:", 52, 53), 165754912308SNavdeep Parhar FIELD1("PadEn:", 51), 165854912308SNavdeep Parhar FIELD1("PackEn:", 50), 165954912308SNavdeep Parhar FIELD1("Cache_Lock :", 49), 166054912308SNavdeep Parhar FIELD1("CongDrop:", 48), 166154912308SNavdeep Parhar FIELD("PackOffset:", 16, 47), 166254912308SNavdeep Parhar FIELD("CIDX:", 8, 15), 166354912308SNavdeep Parhar FIELD("PIDX:", 0, 7), 166454912308SNavdeep Parhar { NULL } 166554912308SNavdeep Parhar }; 166654912308SNavdeep Parhar static struct field_desc flm_t6[] = { 166754912308SNavdeep Parhar FIELD1("Valid:", 89), 166854912308SNavdeep Parhar FIELD("SplitLenMode:", 87, 88), 166954912308SNavdeep Parhar FIELD1("TPHintEn:", 86), 167054912308SNavdeep Parhar FIELD("TPHint:", 84, 85), 167154912308SNavdeep Parhar FIELD1("NoSnoop:", 83), 167254912308SNavdeep Parhar FIELD1("RelaxedOrdering:", 82), 167354912308SNavdeep Parhar FIELD("DCA_ST:", 71, 81), 167454912308SNavdeep Parhar FIELD("EQid:", 54, 70), 167554912308SNavdeep Parhar FIELD("SplitEn:", 52, 53), 167654912308SNavdeep Parhar FIELD1("PadEn:", 51), 167754912308SNavdeep Parhar FIELD1("PackEn:", 50), 167854912308SNavdeep Parhar FIELD1("Cache_Lock :", 49), 167954912308SNavdeep Parhar FIELD1("CongDrop:", 48), 168054912308SNavdeep Parhar FIELD1("Inflight:", 47), 168154912308SNavdeep Parhar FIELD1("CongEn:", 46), 168254912308SNavdeep Parhar FIELD1("CongMode:", 45), 168354912308SNavdeep Parhar FIELD("PackOffset:", 20, 39), 168454912308SNavdeep Parhar FIELD("CIDX:", 8, 15), 168554912308SNavdeep Parhar FIELD("PIDX:", 0, 7), 168654912308SNavdeep Parhar { NULL } 168754912308SNavdeep Parhar }; 168854912308SNavdeep Parhar static struct field_desc conm_t5[] = { 168954912308SNavdeep Parhar FIELD1("CngMPSEnable:", 21), 169054912308SNavdeep Parhar FIELD("CngTPMode:", 19, 20), 169154912308SNavdeep Parhar FIELD1("CngDBPHdr:", 18), 169254912308SNavdeep Parhar FIELD1("CngDBPData:", 17), 169354912308SNavdeep Parhar FIELD1("CngIMSG:", 16), 169454912308SNavdeep Parhar { "CngChMap:", 0, 15, 0, 1, 0 }, 169554912308SNavdeep Parhar { NULL } 169654912308SNavdeep Parhar }; 169754912308SNavdeep Parhar 169854912308SNavdeep Parhar if (p->mem_id == SGE_CONTEXT_EGRESS) { 169954912308SNavdeep Parhar if (p->data[0] & 2) 170054912308SNavdeep Parhar show_struct(p->data, 6, fl_t5); 170154912308SNavdeep Parhar else if (vers == 5) 170254912308SNavdeep Parhar show_struct(p->data, 6, egress_t5); 170354912308SNavdeep Parhar else 170454912308SNavdeep Parhar show_struct(p->data, 6, egress_t6); 170554912308SNavdeep Parhar } else if (p->mem_id == SGE_CONTEXT_FLM) 170654912308SNavdeep Parhar show_struct(p->data, 3, vers == 5 ? flm_t5 : flm_t6); 170754912308SNavdeep Parhar else if (p->mem_id == SGE_CONTEXT_INGRESS) 170854912308SNavdeep Parhar show_struct(p->data, 5, vers == 5 ? ingress_t5 : ingress_t6); 170954912308SNavdeep Parhar else if (p->mem_id == SGE_CONTEXT_CNM) 171054912308SNavdeep Parhar show_struct(p->data, 1, conm_t5); 171154912308SNavdeep Parhar } 171254912308SNavdeep Parhar 171354912308SNavdeep Parhar static void 171454912308SNavdeep Parhar show_t4_ctxt(const struct t4_sge_context *p) 171554912308SNavdeep Parhar { 171654912308SNavdeep Parhar static struct field_desc egress_t4[] = { 171754912308SNavdeep Parhar FIELD1("StatusPgNS:", 180), 171854912308SNavdeep Parhar FIELD1("StatusPgRO:", 179), 171954912308SNavdeep Parhar FIELD1("FetchNS:", 178), 172054912308SNavdeep Parhar FIELD1("FetchRO:", 177), 172154912308SNavdeep Parhar FIELD1("Valid:", 176), 172254912308SNavdeep Parhar FIELD("PCIeDataChannel:", 174, 175), 172354912308SNavdeep Parhar FIELD1("DCAEgrQEn:", 173), 172454912308SNavdeep Parhar FIELD("DCACPUID:", 168, 172), 172554912308SNavdeep Parhar FIELD1("FCThreshOverride:", 167), 172654912308SNavdeep Parhar FIELD("WRLength:", 162, 166), 172754912308SNavdeep Parhar FIELD1("WRLengthKnown:", 161), 172854912308SNavdeep Parhar FIELD1("ReschedulePending:", 160), 172954912308SNavdeep Parhar FIELD1("OnChipQueue:", 159), 173054912308SNavdeep Parhar FIELD1("FetchSizeMode", 158), 173154912308SNavdeep Parhar { "FetchBurstMin:", 156, 157, 4, 0, 1 }, 173254912308SNavdeep Parhar { "FetchBurstMax:", 153, 154, 6, 0, 1 }, 173354912308SNavdeep Parhar FIELD("uPToken:", 133, 152), 173454912308SNavdeep Parhar FIELD1("uPTokenEn:", 132), 173554912308SNavdeep Parhar FIELD1("UserModeIO:", 131), 173654912308SNavdeep Parhar FIELD("uPFLCredits:", 123, 130), 173754912308SNavdeep Parhar FIELD1("uPFLCreditEn:", 122), 173854912308SNavdeep Parhar FIELD("FID:", 111, 121), 173954912308SNavdeep Parhar FIELD("HostFCMode:", 109, 110), 174054912308SNavdeep Parhar FIELD1("HostFCOwner:", 108), 174154912308SNavdeep Parhar { "CIDXFlushThresh:", 105, 107, 0, 0, 1 }, 174254912308SNavdeep Parhar FIELD("CIDX:", 89, 104), 174354912308SNavdeep Parhar FIELD("PIDX:", 73, 88), 174454912308SNavdeep Parhar { "BaseAddress:", 18, 72, 9, 1 }, 174554912308SNavdeep Parhar FIELD("QueueSize:", 2, 17), 174654912308SNavdeep Parhar FIELD1("QueueType:", 1), 174754912308SNavdeep Parhar FIELD1("CachePriority:", 0), 174854912308SNavdeep Parhar { NULL } 174954912308SNavdeep Parhar }; 175054912308SNavdeep Parhar static struct field_desc fl_t4[] = { 175154912308SNavdeep Parhar FIELD1("StatusPgNS:", 180), 175254912308SNavdeep Parhar FIELD1("StatusPgRO:", 179), 175354912308SNavdeep Parhar FIELD1("FetchNS:", 178), 175454912308SNavdeep Parhar FIELD1("FetchRO:", 177), 175554912308SNavdeep Parhar FIELD1("Valid:", 176), 175654912308SNavdeep Parhar FIELD("PCIeDataChannel:", 174, 175), 175754912308SNavdeep Parhar FIELD1("DCAEgrQEn:", 173), 175854912308SNavdeep Parhar FIELD("DCACPUID:", 168, 172), 175954912308SNavdeep Parhar FIELD1("FCThreshOverride:", 167), 176054912308SNavdeep Parhar FIELD1("ReschedulePending:", 160), 176154912308SNavdeep Parhar FIELD1("OnChipQueue:", 159), 176254912308SNavdeep Parhar FIELD1("FetchSizeMode", 158), 176354912308SNavdeep Parhar { "FetchBurstMin:", 156, 157, 4, 0, 1 }, 176454912308SNavdeep Parhar { "FetchBurstMax:", 153, 154, 6, 0, 1 }, 176554912308SNavdeep Parhar FIELD1("FLMcongMode:", 152), 176654912308SNavdeep Parhar FIELD("MaxuPFLCredits:", 144, 151), 176754912308SNavdeep Parhar FIELD("FLMcontextID:", 133, 143), 176854912308SNavdeep Parhar FIELD1("uPTokenEn:", 132), 176954912308SNavdeep Parhar FIELD1("UserModeIO:", 131), 177054912308SNavdeep Parhar FIELD("uPFLCredits:", 123, 130), 177154912308SNavdeep Parhar FIELD1("uPFLCreditEn:", 122), 177254912308SNavdeep Parhar FIELD("FID:", 111, 121), 177354912308SNavdeep Parhar FIELD("HostFCMode:", 109, 110), 177454912308SNavdeep Parhar FIELD1("HostFCOwner:", 108), 177554912308SNavdeep Parhar { "CIDXFlushThresh:", 105, 107, 0, 0, 1 }, 177654912308SNavdeep Parhar FIELD("CIDX:", 89, 104), 177754912308SNavdeep Parhar FIELD("PIDX:", 73, 88), 177854912308SNavdeep Parhar { "BaseAddress:", 18, 72, 9, 1 }, 177954912308SNavdeep Parhar FIELD("QueueSize:", 2, 17), 178054912308SNavdeep Parhar FIELD1("QueueType:", 1), 178154912308SNavdeep Parhar FIELD1("CachePriority:", 0), 178254912308SNavdeep Parhar { NULL } 178354912308SNavdeep Parhar }; 178454912308SNavdeep Parhar static struct field_desc ingress_t4[] = { 178554912308SNavdeep Parhar FIELD1("NoSnoop:", 145), 178654912308SNavdeep Parhar FIELD1("RelaxedOrdering:", 144), 178754912308SNavdeep Parhar FIELD1("GTSmode:", 143), 178854912308SNavdeep Parhar FIELD1("ISCSICoalescing:", 142), 178954912308SNavdeep Parhar FIELD1("Valid:", 141), 179054912308SNavdeep Parhar FIELD1("TimerPending:", 140), 179154912308SNavdeep Parhar FIELD1("DropRSS:", 139), 179254912308SNavdeep Parhar FIELD("PCIeChannel:", 137, 138), 179354912308SNavdeep Parhar FIELD1("SEInterruptArmed:", 136), 179454912308SNavdeep Parhar FIELD1("CongestionMgtEnable:", 135), 179554912308SNavdeep Parhar FIELD1("DCAIngQEnable:", 134), 179654912308SNavdeep Parhar FIELD("DCACPUID:", 129, 133), 179754912308SNavdeep Parhar FIELD1("UpdateScheduling:", 128), 179854912308SNavdeep Parhar FIELD("UpdateDelivery:", 126, 127), 179954912308SNavdeep Parhar FIELD1("InterruptSent:", 125), 180054912308SNavdeep Parhar FIELD("InterruptIDX:", 114, 124), 180154912308SNavdeep Parhar FIELD1("InterruptDestination:", 113), 180254912308SNavdeep Parhar FIELD1("InterruptArmed:", 112), 180354912308SNavdeep Parhar FIELD("RxIntCounter:", 106, 111), 180454912308SNavdeep Parhar FIELD("RxIntCounterThreshold:", 104, 105), 180554912308SNavdeep Parhar FIELD1("Generation:", 103), 180654912308SNavdeep Parhar { "BaseAddress:", 48, 102, 9, 1 }, 180754912308SNavdeep Parhar FIELD("PIDX:", 32, 47), 180854912308SNavdeep Parhar FIELD("CIDX:", 16, 31), 180954912308SNavdeep Parhar { "QueueSize:", 4, 15, 4, 0 }, 181054912308SNavdeep Parhar { "QueueEntrySize:", 2, 3, 4, 0, 1 }, 181154912308SNavdeep Parhar FIELD1("QueueEntryOverride:", 1), 181254912308SNavdeep Parhar FIELD1("CachePriority:", 0), 181354912308SNavdeep Parhar { NULL } 181454912308SNavdeep Parhar }; 181554912308SNavdeep Parhar static struct field_desc flm_t4[] = { 181654912308SNavdeep Parhar FIELD1("NoSnoop:", 79), 181754912308SNavdeep Parhar FIELD1("RelaxedOrdering:", 78), 181854912308SNavdeep Parhar FIELD1("Valid:", 77), 181954912308SNavdeep Parhar FIELD("DCACPUID:", 72, 76), 182054912308SNavdeep Parhar FIELD1("DCAFLEn:", 71), 182154912308SNavdeep Parhar FIELD("EQid:", 54, 70), 182254912308SNavdeep Parhar FIELD("SplitEn:", 52, 53), 182354912308SNavdeep Parhar FIELD1("PadEn:", 51), 182454912308SNavdeep Parhar FIELD1("PackEn:", 50), 182554912308SNavdeep Parhar FIELD1("DBpriority:", 48), 182654912308SNavdeep Parhar FIELD("PackOffset:", 16, 47), 182754912308SNavdeep Parhar FIELD("CIDX:", 8, 15), 182854912308SNavdeep Parhar FIELD("PIDX:", 0, 7), 182954912308SNavdeep Parhar { NULL } 183054912308SNavdeep Parhar }; 183154912308SNavdeep Parhar static struct field_desc conm_t4[] = { 183254912308SNavdeep Parhar FIELD1("CngDBPHdr:", 6), 183354912308SNavdeep Parhar FIELD1("CngDBPData:", 5), 183454912308SNavdeep Parhar FIELD1("CngIMSG:", 4), 183554912308SNavdeep Parhar { "CngChMap:", 0, 3, 0, 1, 0}, 183654912308SNavdeep Parhar { NULL } 183754912308SNavdeep Parhar }; 183854912308SNavdeep Parhar 183954912308SNavdeep Parhar if (p->mem_id == SGE_CONTEXT_EGRESS) 184054912308SNavdeep Parhar show_struct(p->data, 6, (p->data[0] & 2) ? fl_t4 : egress_t4); 184154912308SNavdeep Parhar else if (p->mem_id == SGE_CONTEXT_FLM) 184254912308SNavdeep Parhar show_struct(p->data, 3, flm_t4); 184354912308SNavdeep Parhar else if (p->mem_id == SGE_CONTEXT_INGRESS) 184454912308SNavdeep Parhar show_struct(p->data, 5, ingress_t4); 184554912308SNavdeep Parhar else if (p->mem_id == SGE_CONTEXT_CNM) 184654912308SNavdeep Parhar show_struct(p->data, 1, conm_t4); 184754912308SNavdeep Parhar } 184854912308SNavdeep Parhar 184954912308SNavdeep Parhar #undef FIELD 185054912308SNavdeep Parhar #undef FIELD1 185154912308SNavdeep Parhar 185254912308SNavdeep Parhar static int 185354912308SNavdeep Parhar get_sge_context(int argc, const char *argv[]) 185454912308SNavdeep Parhar { 185554912308SNavdeep Parhar int rc; 185654912308SNavdeep Parhar char *p; 185754912308SNavdeep Parhar long cid; 185854912308SNavdeep Parhar struct t4_sge_context cntxt = {0}; 185954912308SNavdeep Parhar 186054912308SNavdeep Parhar if (argc != 2) { 186154912308SNavdeep Parhar warnx("sge_context: incorrect number of arguments."); 186254912308SNavdeep Parhar return (EINVAL); 186354912308SNavdeep Parhar } 186454912308SNavdeep Parhar 186554912308SNavdeep Parhar if (!strcmp(argv[0], "egress")) 186654912308SNavdeep Parhar cntxt.mem_id = SGE_CONTEXT_EGRESS; 186754912308SNavdeep Parhar else if (!strcmp(argv[0], "ingress")) 186854912308SNavdeep Parhar cntxt.mem_id = SGE_CONTEXT_INGRESS; 186954912308SNavdeep Parhar else if (!strcmp(argv[0], "fl")) 187054912308SNavdeep Parhar cntxt.mem_id = SGE_CONTEXT_FLM; 187154912308SNavdeep Parhar else if (!strcmp(argv[0], "cong")) 187254912308SNavdeep Parhar cntxt.mem_id = SGE_CONTEXT_CNM; 187354912308SNavdeep Parhar else { 187454912308SNavdeep Parhar warnx("unknown context type \"%s\"; known types are egress, " 187554912308SNavdeep Parhar "ingress, fl, and cong.", argv[0]); 187654912308SNavdeep Parhar return (EINVAL); 187754912308SNavdeep Parhar } 187854912308SNavdeep Parhar 187954912308SNavdeep Parhar p = str_to_number(argv[1], &cid, NULL); 188054912308SNavdeep Parhar if (*p) { 188154912308SNavdeep Parhar warnx("invalid context id \"%s\"", argv[1]); 188254912308SNavdeep Parhar return (EINVAL); 188354912308SNavdeep Parhar } 188454912308SNavdeep Parhar cntxt.cid = cid; 188554912308SNavdeep Parhar 188654912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_SGE_CONTEXT, &cntxt); 188754912308SNavdeep Parhar if (rc != 0) 188854912308SNavdeep Parhar return (rc); 188954912308SNavdeep Parhar 189054912308SNavdeep Parhar if (chip_id == 4) 189154912308SNavdeep Parhar show_t4_ctxt(&cntxt); 189254912308SNavdeep Parhar else 189354912308SNavdeep Parhar show_t5t6_ctxt(&cntxt, chip_id); 189454912308SNavdeep Parhar 189554912308SNavdeep Parhar return (0); 189654912308SNavdeep Parhar } 189754912308SNavdeep Parhar 189854912308SNavdeep Parhar static int 189954912308SNavdeep Parhar loadfw(int argc, const char *argv[]) 190054912308SNavdeep Parhar { 190154912308SNavdeep Parhar int rc, fd; 190254912308SNavdeep Parhar struct t4_data data = {0}; 190354912308SNavdeep Parhar const char *fname = argv[0]; 190454912308SNavdeep Parhar struct stat st = {0}; 190554912308SNavdeep Parhar 190654912308SNavdeep Parhar if (argc != 1) { 190754912308SNavdeep Parhar warnx("loadfw: incorrect number of arguments."); 190854912308SNavdeep Parhar return (EINVAL); 190954912308SNavdeep Parhar } 191054912308SNavdeep Parhar 191154912308SNavdeep Parhar fd = open(fname, O_RDONLY); 191254912308SNavdeep Parhar if (fd < 0) { 191354912308SNavdeep Parhar warn("open(%s)", fname); 191454912308SNavdeep Parhar return (errno); 191554912308SNavdeep Parhar } 191654912308SNavdeep Parhar 191754912308SNavdeep Parhar if (fstat(fd, &st) < 0) { 191854912308SNavdeep Parhar warn("fstat"); 191954912308SNavdeep Parhar close(fd); 192054912308SNavdeep Parhar return (errno); 192154912308SNavdeep Parhar } 192254912308SNavdeep Parhar 192354912308SNavdeep Parhar data.len = st.st_size; 192454912308SNavdeep Parhar data.data = mmap(0, data.len, PROT_READ, MAP_PRIVATE, fd, 0); 192554912308SNavdeep Parhar if (data.data == MAP_FAILED) { 192654912308SNavdeep Parhar warn("mmap"); 192754912308SNavdeep Parhar close(fd); 192854912308SNavdeep Parhar return (errno); 192954912308SNavdeep Parhar } 193054912308SNavdeep Parhar 193154912308SNavdeep Parhar rc = doit(CHELSIO_T4_LOAD_FW, &data); 193254912308SNavdeep Parhar munmap(data.data, data.len); 193354912308SNavdeep Parhar close(fd); 193454912308SNavdeep Parhar return (rc); 193554912308SNavdeep Parhar } 193654912308SNavdeep Parhar 193754912308SNavdeep Parhar static int 193854912308SNavdeep Parhar loadcfg(int argc, const char *argv[]) 193954912308SNavdeep Parhar { 194054912308SNavdeep Parhar int rc, fd; 194154912308SNavdeep Parhar struct t4_data data = {0}; 194254912308SNavdeep Parhar const char *fname = argv[0]; 194354912308SNavdeep Parhar struct stat st = {0}; 194454912308SNavdeep Parhar 194554912308SNavdeep Parhar if (argc != 1) { 194654912308SNavdeep Parhar warnx("loadcfg: incorrect number of arguments."); 194754912308SNavdeep Parhar return (EINVAL); 194854912308SNavdeep Parhar } 194954912308SNavdeep Parhar 195054912308SNavdeep Parhar if (strcmp(fname, "clear") == 0) 195154912308SNavdeep Parhar return (doit(CHELSIO_T4_LOAD_CFG, &data)); 195254912308SNavdeep Parhar 195354912308SNavdeep Parhar fd = open(fname, O_RDONLY); 195454912308SNavdeep Parhar if (fd < 0) { 195554912308SNavdeep Parhar warn("open(%s)", fname); 195654912308SNavdeep Parhar return (errno); 195754912308SNavdeep Parhar } 195854912308SNavdeep Parhar 195954912308SNavdeep Parhar if (fstat(fd, &st) < 0) { 196054912308SNavdeep Parhar warn("fstat"); 196154912308SNavdeep Parhar close(fd); 196254912308SNavdeep Parhar return (errno); 196354912308SNavdeep Parhar } 196454912308SNavdeep Parhar 196554912308SNavdeep Parhar data.len = st.st_size; 196654912308SNavdeep Parhar data.len &= ~3; /* Clip off to make it a multiple of 4 */ 196754912308SNavdeep Parhar data.data = mmap(0, data.len, PROT_READ, MAP_PRIVATE, fd, 0); 196854912308SNavdeep Parhar if (data.data == MAP_FAILED) { 196954912308SNavdeep Parhar warn("mmap"); 197054912308SNavdeep Parhar close(fd); 197154912308SNavdeep Parhar return (errno); 197254912308SNavdeep Parhar } 197354912308SNavdeep Parhar 197454912308SNavdeep Parhar rc = doit(CHELSIO_T4_LOAD_CFG, &data); 197554912308SNavdeep Parhar munmap(data.data, data.len); 197654912308SNavdeep Parhar close(fd); 197754912308SNavdeep Parhar return (rc); 197854912308SNavdeep Parhar } 197954912308SNavdeep Parhar 198054912308SNavdeep Parhar static int 1981f856f099SNavdeep Parhar dumpstate(int argc, const char *argv[]) 1982f856f099SNavdeep Parhar { 1983f856f099SNavdeep Parhar int rc, fd; 1984f856f099SNavdeep Parhar struct t4_cudbg_dump dump = {0}; 1985f856f099SNavdeep Parhar const char *fname = argv[0]; 1986f856f099SNavdeep Parhar 1987f856f099SNavdeep Parhar if (argc != 1) { 1988f856f099SNavdeep Parhar warnx("dumpstate: incorrect number of arguments."); 1989f856f099SNavdeep Parhar return (EINVAL); 1990f856f099SNavdeep Parhar } 1991f856f099SNavdeep Parhar 1992f856f099SNavdeep Parhar dump.wr_flash = 0; 1993f856f099SNavdeep Parhar memset(&dump.bitmap, 0xff, sizeof(dump.bitmap)); 1994f856f099SNavdeep Parhar dump.len = 8 * 1024 * 1024; 1995f856f099SNavdeep Parhar dump.data = malloc(dump.len); 1996f856f099SNavdeep Parhar if (dump.data == NULL) { 1997f856f099SNavdeep Parhar return (ENOMEM); 1998f856f099SNavdeep Parhar } 1999f856f099SNavdeep Parhar 2000f856f099SNavdeep Parhar rc = doit(CHELSIO_T4_CUDBG_DUMP, &dump); 2001313a6435SNavdeep Parhar if (rc != 0) 2002313a6435SNavdeep Parhar goto done; 2003313a6435SNavdeep Parhar 2004313a6435SNavdeep Parhar fd = open(fname, O_CREAT | O_TRUNC | O_EXCL | O_WRONLY, 2005313a6435SNavdeep Parhar S_IRUSR | S_IRGRP | S_IROTH); 2006313a6435SNavdeep Parhar if (fd < 0) { 2007313a6435SNavdeep Parhar warn("open(%s)", fname); 2008313a6435SNavdeep Parhar rc = errno; 2009313a6435SNavdeep Parhar goto done; 2010313a6435SNavdeep Parhar } 2011f856f099SNavdeep Parhar write(fd, dump.data, dump.len); 2012f856f099SNavdeep Parhar close(fd); 2013313a6435SNavdeep Parhar done: 2014313a6435SNavdeep Parhar free(dump.data); 2015f856f099SNavdeep Parhar return (rc); 2016f856f099SNavdeep Parhar } 2017f856f099SNavdeep Parhar 2018f856f099SNavdeep Parhar static int 201954912308SNavdeep Parhar read_mem(uint32_t addr, uint32_t len, void (*output)(uint32_t *, uint32_t)) 202054912308SNavdeep Parhar { 202154912308SNavdeep Parhar int rc; 202254912308SNavdeep Parhar struct t4_mem_range mr; 202354912308SNavdeep Parhar 202454912308SNavdeep Parhar mr.addr = addr; 202554912308SNavdeep Parhar mr.len = len; 202654912308SNavdeep Parhar mr.data = malloc(mr.len); 202754912308SNavdeep Parhar 202854912308SNavdeep Parhar if (mr.data == 0) { 202954912308SNavdeep Parhar warn("read_mem: malloc"); 203054912308SNavdeep Parhar return (errno); 203154912308SNavdeep Parhar } 203254912308SNavdeep Parhar 203354912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_MEM, &mr); 203454912308SNavdeep Parhar if (rc != 0) 203554912308SNavdeep Parhar goto done; 203654912308SNavdeep Parhar 203754912308SNavdeep Parhar if (output) 203854912308SNavdeep Parhar (*output)(mr.data, mr.len); 203954912308SNavdeep Parhar done: 204054912308SNavdeep Parhar free(mr.data); 204154912308SNavdeep Parhar return (rc); 204254912308SNavdeep Parhar } 204354912308SNavdeep Parhar 20448f82718fSNavdeep Parhar static int 20458f82718fSNavdeep Parhar loadboot(int argc, const char *argv[]) 20468f82718fSNavdeep Parhar { 20478f82718fSNavdeep Parhar int rc, fd; 20488f82718fSNavdeep Parhar long l; 20498f82718fSNavdeep Parhar char *p; 20508f82718fSNavdeep Parhar struct t4_bootrom br = {0}; 20518f82718fSNavdeep Parhar const char *fname = argv[0]; 20528f82718fSNavdeep Parhar struct stat st = {0}; 20538f82718fSNavdeep Parhar 20548f82718fSNavdeep Parhar if (argc == 1) { 20558f82718fSNavdeep Parhar br.pf_offset = 0; 20568f82718fSNavdeep Parhar br.pfidx_addr = 0; 20578f82718fSNavdeep Parhar } else if (argc == 3) { 20588f82718fSNavdeep Parhar if (!strcmp(argv[1], "pf")) 20598f82718fSNavdeep Parhar br.pf_offset = 0; 20608f82718fSNavdeep Parhar else if (!strcmp(argv[1], "offset")) 20618f82718fSNavdeep Parhar br.pf_offset = 1; 20628f82718fSNavdeep Parhar else 20638f82718fSNavdeep Parhar return (EINVAL); 20648f82718fSNavdeep Parhar 20658f82718fSNavdeep Parhar p = str_to_number(argv[2], &l, NULL); 20668f82718fSNavdeep Parhar if (*p) 20678f82718fSNavdeep Parhar return (EINVAL); 20688f82718fSNavdeep Parhar br.pfidx_addr = l; 20698f82718fSNavdeep Parhar } else { 20708f82718fSNavdeep Parhar warnx("loadboot: incorrect number of arguments."); 20718f82718fSNavdeep Parhar return (EINVAL); 20728f82718fSNavdeep Parhar } 20738f82718fSNavdeep Parhar 20748f82718fSNavdeep Parhar if (strcmp(fname, "clear") == 0) 20758f82718fSNavdeep Parhar return (doit(CHELSIO_T4_LOAD_BOOT, &br)); 20768f82718fSNavdeep Parhar 20778f82718fSNavdeep Parhar fd = open(fname, O_RDONLY); 20788f82718fSNavdeep Parhar if (fd < 0) { 20798f82718fSNavdeep Parhar warn("open(%s)", fname); 20808f82718fSNavdeep Parhar return (errno); 20818f82718fSNavdeep Parhar } 20828f82718fSNavdeep Parhar 20838f82718fSNavdeep Parhar if (fstat(fd, &st) < 0) { 20848f82718fSNavdeep Parhar warn("fstat"); 20858f82718fSNavdeep Parhar close(fd); 20868f82718fSNavdeep Parhar return (errno); 20878f82718fSNavdeep Parhar } 20888f82718fSNavdeep Parhar 20898f82718fSNavdeep Parhar br.len = st.st_size; 20908f82718fSNavdeep Parhar br.data = mmap(0, br.len, PROT_READ, MAP_PRIVATE, fd, 0); 20918f82718fSNavdeep Parhar if (br.data == MAP_FAILED) { 20928f82718fSNavdeep Parhar warn("mmap"); 20938f82718fSNavdeep Parhar close(fd); 20948f82718fSNavdeep Parhar return (errno); 20958f82718fSNavdeep Parhar } 20968f82718fSNavdeep Parhar 20978f82718fSNavdeep Parhar rc = doit(CHELSIO_T4_LOAD_BOOT, &br); 20988f82718fSNavdeep Parhar munmap(br.data, br.len); 20998f82718fSNavdeep Parhar close(fd); 21008f82718fSNavdeep Parhar return (rc); 21018f82718fSNavdeep Parhar } 21028f82718fSNavdeep Parhar 21038f82718fSNavdeep Parhar static int 21048f82718fSNavdeep Parhar loadbootcfg(int argc, const char *argv[]) 21058f82718fSNavdeep Parhar { 21068f82718fSNavdeep Parhar int rc, fd; 21078f82718fSNavdeep Parhar struct t4_data bc = {0}; 21088f82718fSNavdeep Parhar const char *fname = argv[0]; 21098f82718fSNavdeep Parhar struct stat st = {0}; 21108f82718fSNavdeep Parhar 21118f82718fSNavdeep Parhar if (argc != 1) { 21128f82718fSNavdeep Parhar warnx("loadbootcfg: incorrect number of arguments."); 21138f82718fSNavdeep Parhar return (EINVAL); 21148f82718fSNavdeep Parhar } 21158f82718fSNavdeep Parhar 21168f82718fSNavdeep Parhar if (strcmp(fname, "clear") == 0) 21178f82718fSNavdeep Parhar return (doit(CHELSIO_T4_LOAD_BOOTCFG, &bc)); 21188f82718fSNavdeep Parhar 21198f82718fSNavdeep Parhar fd = open(fname, O_RDONLY); 21208f82718fSNavdeep Parhar if (fd < 0) { 21218f82718fSNavdeep Parhar warn("open(%s)", fname); 21228f82718fSNavdeep Parhar return (errno); 21238f82718fSNavdeep Parhar } 21248f82718fSNavdeep Parhar 21258f82718fSNavdeep Parhar if (fstat(fd, &st) < 0) { 21268f82718fSNavdeep Parhar warn("fstat"); 21278f82718fSNavdeep Parhar close(fd); 21288f82718fSNavdeep Parhar return (errno); 21298f82718fSNavdeep Parhar } 21308f82718fSNavdeep Parhar 21318f82718fSNavdeep Parhar bc.len = st.st_size; 21328f82718fSNavdeep Parhar bc.data = mmap(0, bc.len, PROT_READ, MAP_PRIVATE, fd, 0); 21338f82718fSNavdeep Parhar if (bc.data == MAP_FAILED) { 21348f82718fSNavdeep Parhar warn("mmap"); 21358f82718fSNavdeep Parhar close(fd); 21368f82718fSNavdeep Parhar return (errno); 21378f82718fSNavdeep Parhar } 21388f82718fSNavdeep Parhar 21398f82718fSNavdeep Parhar rc = doit(CHELSIO_T4_LOAD_BOOTCFG, &bc); 21408f82718fSNavdeep Parhar munmap(bc.data, bc.len); 21418f82718fSNavdeep Parhar close(fd); 21428f82718fSNavdeep Parhar return (rc); 21438f82718fSNavdeep Parhar } 21448f82718fSNavdeep Parhar 214554912308SNavdeep Parhar /* 214654912308SNavdeep Parhar * Display memory as list of 'n' 4-byte values per line. 214754912308SNavdeep Parhar */ 214854912308SNavdeep Parhar static void 214954912308SNavdeep Parhar show_mem(uint32_t *buf, uint32_t len) 215054912308SNavdeep Parhar { 215154912308SNavdeep Parhar const char *s; 215254912308SNavdeep Parhar int i, n = 8; 215354912308SNavdeep Parhar 215454912308SNavdeep Parhar while (len) { 215554912308SNavdeep Parhar for (i = 0; len && i < n; i++, buf++, len -= 4) { 215654912308SNavdeep Parhar s = i ? " " : ""; 215754912308SNavdeep Parhar printf("%s%08x", s, htonl(*buf)); 215854912308SNavdeep Parhar } 215954912308SNavdeep Parhar printf("\n"); 216054912308SNavdeep Parhar } 216154912308SNavdeep Parhar } 216254912308SNavdeep Parhar 216354912308SNavdeep Parhar static int 216454912308SNavdeep Parhar memdump(int argc, const char *argv[]) 216554912308SNavdeep Parhar { 216654912308SNavdeep Parhar char *p; 216754912308SNavdeep Parhar long l; 216854912308SNavdeep Parhar uint32_t addr, len; 216954912308SNavdeep Parhar 217054912308SNavdeep Parhar if (argc != 2) { 217154912308SNavdeep Parhar warnx("incorrect number of arguments."); 217254912308SNavdeep Parhar return (EINVAL); 217354912308SNavdeep Parhar } 217454912308SNavdeep Parhar 217554912308SNavdeep Parhar p = str_to_number(argv[0], &l, NULL); 217654912308SNavdeep Parhar if (*p) { 217754912308SNavdeep Parhar warnx("invalid address \"%s\"", argv[0]); 217854912308SNavdeep Parhar return (EINVAL); 217954912308SNavdeep Parhar } 218054912308SNavdeep Parhar addr = l; 218154912308SNavdeep Parhar 218254912308SNavdeep Parhar p = str_to_number(argv[1], &l, NULL); 218354912308SNavdeep Parhar if (*p) { 218454912308SNavdeep Parhar warnx("memdump: invalid length \"%s\"", argv[1]); 218554912308SNavdeep Parhar return (EINVAL); 218654912308SNavdeep Parhar } 218754912308SNavdeep Parhar len = l; 218854912308SNavdeep Parhar 218954912308SNavdeep Parhar return (read_mem(addr, len, show_mem)); 219054912308SNavdeep Parhar } 219154912308SNavdeep Parhar 219254912308SNavdeep Parhar /* 219354912308SNavdeep Parhar * Display TCB as list of 'n' 4-byte values per line. 219454912308SNavdeep Parhar */ 219554912308SNavdeep Parhar static void 219654912308SNavdeep Parhar show_tcb(uint32_t *buf, uint32_t len) 219754912308SNavdeep Parhar { 2198ae9b4017SNavdeep Parhar unsigned char *tcb = (unsigned char *)buf; 219954912308SNavdeep Parhar const char *s; 220054912308SNavdeep Parhar int i, n = 8; 220154912308SNavdeep Parhar 220254912308SNavdeep Parhar while (len) { 220354912308SNavdeep Parhar for (i = 0; len && i < n; i++, buf++, len -= 4) { 220454912308SNavdeep Parhar s = i ? " " : ""; 220554912308SNavdeep Parhar printf("%s%08x", s, htonl(*buf)); 220654912308SNavdeep Parhar } 220754912308SNavdeep Parhar printf("\n"); 220854912308SNavdeep Parhar } 2209ae9b4017SNavdeep Parhar set_tcb_info(TIDTYPE_TCB, chip_id); 2210ae9b4017SNavdeep Parhar set_print_style(PRNTSTYL_COMP); 2211ae9b4017SNavdeep Parhar swizzle_tcb(tcb); 2212ae9b4017SNavdeep Parhar parse_n_display_xcb(tcb); 221354912308SNavdeep Parhar } 221454912308SNavdeep Parhar 221554912308SNavdeep Parhar #define A_TP_CMM_TCB_BASE 0x7d10 221654912308SNavdeep Parhar #define TCB_SIZE 128 221754912308SNavdeep Parhar static int 221854912308SNavdeep Parhar read_tcb(int argc, const char *argv[]) 221954912308SNavdeep Parhar { 222054912308SNavdeep Parhar char *p; 222154912308SNavdeep Parhar long l; 222254912308SNavdeep Parhar long long val; 222354912308SNavdeep Parhar unsigned int tid; 222454912308SNavdeep Parhar uint32_t addr; 222554912308SNavdeep Parhar int rc; 222654912308SNavdeep Parhar 222754912308SNavdeep Parhar if (argc != 1) { 222854912308SNavdeep Parhar warnx("incorrect number of arguments."); 222954912308SNavdeep Parhar return (EINVAL); 223054912308SNavdeep Parhar } 223154912308SNavdeep Parhar 223254912308SNavdeep Parhar p = str_to_number(argv[0], &l, NULL); 223354912308SNavdeep Parhar if (*p) { 223454912308SNavdeep Parhar warnx("invalid tid \"%s\"", argv[0]); 223554912308SNavdeep Parhar return (EINVAL); 223654912308SNavdeep Parhar } 223754912308SNavdeep Parhar tid = l; 223854912308SNavdeep Parhar 223954912308SNavdeep Parhar rc = read_reg(A_TP_CMM_TCB_BASE, 4, &val); 224054912308SNavdeep Parhar if (rc != 0) 224154912308SNavdeep Parhar return (rc); 224254912308SNavdeep Parhar 224354912308SNavdeep Parhar addr = val + tid * TCB_SIZE; 224454912308SNavdeep Parhar 224554912308SNavdeep Parhar return (read_mem(addr, TCB_SIZE, show_tcb)); 224654912308SNavdeep Parhar } 224754912308SNavdeep Parhar 224854912308SNavdeep Parhar static int 224954912308SNavdeep Parhar read_i2c(int argc, const char *argv[]) 225054912308SNavdeep Parhar { 225154912308SNavdeep Parhar char *p; 225254912308SNavdeep Parhar long l; 225354912308SNavdeep Parhar struct t4_i2c_data i2cd; 225454912308SNavdeep Parhar int rc, i; 225554912308SNavdeep Parhar 225654912308SNavdeep Parhar if (argc < 3 || argc > 4) { 225754912308SNavdeep Parhar warnx("incorrect number of arguments."); 225854912308SNavdeep Parhar return (EINVAL); 225954912308SNavdeep Parhar } 226054912308SNavdeep Parhar 226154912308SNavdeep Parhar p = str_to_number(argv[0], &l, NULL); 226254912308SNavdeep Parhar if (*p || l > UCHAR_MAX) { 226354912308SNavdeep Parhar warnx("invalid port id \"%s\"", argv[0]); 226454912308SNavdeep Parhar return (EINVAL); 226554912308SNavdeep Parhar } 226654912308SNavdeep Parhar i2cd.port_id = l; 226754912308SNavdeep Parhar 226854912308SNavdeep Parhar p = str_to_number(argv[1], &l, NULL); 226954912308SNavdeep Parhar if (*p || l > UCHAR_MAX) { 227054912308SNavdeep Parhar warnx("invalid i2c device address \"%s\"", argv[1]); 227154912308SNavdeep Parhar return (EINVAL); 227254912308SNavdeep Parhar } 227354912308SNavdeep Parhar i2cd.dev_addr = l; 227454912308SNavdeep Parhar 227554912308SNavdeep Parhar p = str_to_number(argv[2], &l, NULL); 227654912308SNavdeep Parhar if (*p || l > UCHAR_MAX) { 227754912308SNavdeep Parhar warnx("invalid byte offset \"%s\"", argv[2]); 227854912308SNavdeep Parhar return (EINVAL); 227954912308SNavdeep Parhar } 228054912308SNavdeep Parhar i2cd.offset = l; 228154912308SNavdeep Parhar 228254912308SNavdeep Parhar if (argc == 4) { 228354912308SNavdeep Parhar p = str_to_number(argv[3], &l, NULL); 228454912308SNavdeep Parhar if (*p || l > sizeof(i2cd.data)) { 228554912308SNavdeep Parhar warnx("invalid number of bytes \"%s\"", argv[3]); 228654912308SNavdeep Parhar return (EINVAL); 228754912308SNavdeep Parhar } 228854912308SNavdeep Parhar i2cd.len = l; 228954912308SNavdeep Parhar } else 229054912308SNavdeep Parhar i2cd.len = 1; 229154912308SNavdeep Parhar 229254912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_I2C, &i2cd); 229354912308SNavdeep Parhar if (rc != 0) 229454912308SNavdeep Parhar return (rc); 229554912308SNavdeep Parhar 229654912308SNavdeep Parhar for (i = 0; i < i2cd.len; i++) 229754912308SNavdeep Parhar printf("0x%x [%u]\n", i2cd.data[i], i2cd.data[i]); 229854912308SNavdeep Parhar 229954912308SNavdeep Parhar return (0); 230054912308SNavdeep Parhar } 230154912308SNavdeep Parhar 230254912308SNavdeep Parhar static int 230354912308SNavdeep Parhar clearstats(int argc, const char *argv[]) 230454912308SNavdeep Parhar { 230554912308SNavdeep Parhar char *p; 230654912308SNavdeep Parhar long l; 230754912308SNavdeep Parhar uint32_t port; 230854912308SNavdeep Parhar 230954912308SNavdeep Parhar if (argc != 1) { 231054912308SNavdeep Parhar warnx("incorrect number of arguments."); 231154912308SNavdeep Parhar return (EINVAL); 231254912308SNavdeep Parhar } 231354912308SNavdeep Parhar 231454912308SNavdeep Parhar p = str_to_number(argv[0], &l, NULL); 231554912308SNavdeep Parhar if (*p) { 231654912308SNavdeep Parhar warnx("invalid port id \"%s\"", argv[0]); 231754912308SNavdeep Parhar return (EINVAL); 231854912308SNavdeep Parhar } 231954912308SNavdeep Parhar port = l; 232054912308SNavdeep Parhar 232154912308SNavdeep Parhar return doit(CHELSIO_T4_CLEAR_STATS, &port); 232254912308SNavdeep Parhar } 232354912308SNavdeep Parhar 232454912308SNavdeep Parhar static int 232554912308SNavdeep Parhar show_tracers(void) 232654912308SNavdeep Parhar { 232754912308SNavdeep Parhar struct t4_tracer t; 232854912308SNavdeep Parhar char *s; 232954912308SNavdeep Parhar int rc, port_idx, i; 233054912308SNavdeep Parhar long long val; 233154912308SNavdeep Parhar 233254912308SNavdeep Parhar /* Magic values: MPS_TRC_CFG = 0x9800. MPS_TRC_CFG[1:1] = TrcEn */ 233354912308SNavdeep Parhar rc = read_reg(0x9800, 4, &val); 233454912308SNavdeep Parhar if (rc != 0) 233554912308SNavdeep Parhar return (rc); 233654912308SNavdeep Parhar printf("tracing is %s\n", val & 2 ? "ENABLED" : "DISABLED"); 233754912308SNavdeep Parhar 233854912308SNavdeep Parhar t.idx = 0; 233954912308SNavdeep Parhar for (t.idx = 0; ; t.idx++) { 234054912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_TRACER, &t); 234154912308SNavdeep Parhar if (rc != 0 || t.idx == 0xff) 234254912308SNavdeep Parhar break; 234354912308SNavdeep Parhar 234454912308SNavdeep Parhar if (t.tp.port < 4) { 234554912308SNavdeep Parhar s = "Rx"; 234654912308SNavdeep Parhar port_idx = t.tp.port; 234754912308SNavdeep Parhar } else if (t.tp.port < 8) { 234854912308SNavdeep Parhar s = "Tx"; 234954912308SNavdeep Parhar port_idx = t.tp.port - 4; 235054912308SNavdeep Parhar } else if (t.tp.port < 12) { 235154912308SNavdeep Parhar s = "loopback"; 235254912308SNavdeep Parhar port_idx = t.tp.port - 8; 235354912308SNavdeep Parhar } else if (t.tp.port < 16) { 235454912308SNavdeep Parhar s = "MPS Rx"; 235554912308SNavdeep Parhar port_idx = t.tp.port - 12; 235654912308SNavdeep Parhar } else if (t.tp.port < 20) { 235754912308SNavdeep Parhar s = "MPS Tx"; 235854912308SNavdeep Parhar port_idx = t.tp.port - 16; 235954912308SNavdeep Parhar } else { 236054912308SNavdeep Parhar s = "unknown"; 236154912308SNavdeep Parhar port_idx = t.tp.port; 236254912308SNavdeep Parhar } 236354912308SNavdeep Parhar 236454912308SNavdeep Parhar printf("\ntracer %u (currently %s) captures ", t.idx, 236554912308SNavdeep Parhar t.enabled ? "ENABLED" : "DISABLED"); 236654912308SNavdeep Parhar if (t.tp.port < 8) 236754912308SNavdeep Parhar printf("port %u %s, ", port_idx, s); 236854912308SNavdeep Parhar else 236954912308SNavdeep Parhar printf("%s %u, ", s, port_idx); 237054912308SNavdeep Parhar printf("snap length: %u, min length: %u\n", t.tp.snap_len, 237154912308SNavdeep Parhar t.tp.min_len); 237254912308SNavdeep Parhar printf("packets captured %smatch filter\n", 237354912308SNavdeep Parhar t.tp.invert ? "do not " : ""); 237454912308SNavdeep Parhar if (t.tp.skip_ofst) { 237554912308SNavdeep Parhar printf("filter pattern: "); 237654912308SNavdeep Parhar for (i = 0; i < t.tp.skip_ofst * 2; i += 2) 237754912308SNavdeep Parhar printf("%08x%08x", t.tp.data[i], 237854912308SNavdeep Parhar t.tp.data[i + 1]); 237954912308SNavdeep Parhar printf("/"); 238054912308SNavdeep Parhar for (i = 0; i < t.tp.skip_ofst * 2; i += 2) 238154912308SNavdeep Parhar printf("%08x%08x", t.tp.mask[i], 238254912308SNavdeep Parhar t.tp.mask[i + 1]); 238354912308SNavdeep Parhar printf("@0\n"); 238454912308SNavdeep Parhar } 238554912308SNavdeep Parhar printf("filter pattern: "); 238654912308SNavdeep Parhar for (i = t.tp.skip_ofst * 2; i < T4_TRACE_LEN / 4; i += 2) 238754912308SNavdeep Parhar printf("%08x%08x", t.tp.data[i], t.tp.data[i + 1]); 238854912308SNavdeep Parhar printf("/"); 238954912308SNavdeep Parhar for (i = t.tp.skip_ofst * 2; i < T4_TRACE_LEN / 4; i += 2) 239054912308SNavdeep Parhar printf("%08x%08x", t.tp.mask[i], t.tp.mask[i + 1]); 239154912308SNavdeep Parhar printf("@%u\n", (t.tp.skip_ofst + t.tp.skip_len) * 8); 239254912308SNavdeep Parhar } 239354912308SNavdeep Parhar 239454912308SNavdeep Parhar return (rc); 239554912308SNavdeep Parhar } 239654912308SNavdeep Parhar 239754912308SNavdeep Parhar static int 239854912308SNavdeep Parhar tracer_onoff(uint8_t idx, int enabled) 239954912308SNavdeep Parhar { 240054912308SNavdeep Parhar struct t4_tracer t; 240154912308SNavdeep Parhar 240254912308SNavdeep Parhar t.idx = idx; 240354912308SNavdeep Parhar t.enabled = enabled; 240454912308SNavdeep Parhar t.valid = 0; 240554912308SNavdeep Parhar 240654912308SNavdeep Parhar return doit(CHELSIO_T4_SET_TRACER, &t); 240754912308SNavdeep Parhar } 240854912308SNavdeep Parhar 240954912308SNavdeep Parhar static void 241054912308SNavdeep Parhar create_tracing_ifnet() 241154912308SNavdeep Parhar { 241254912308SNavdeep Parhar char *cmd[] = { 241354912308SNavdeep Parhar "/sbin/ifconfig", __DECONST(char *, nexus), "create", NULL 241454912308SNavdeep Parhar }; 241554912308SNavdeep Parhar char *env[] = {NULL}; 241654912308SNavdeep Parhar 241754912308SNavdeep Parhar if (vfork() == 0) { 241854912308SNavdeep Parhar close(STDERR_FILENO); 241954912308SNavdeep Parhar execve(cmd[0], cmd, env); 242054912308SNavdeep Parhar _exit(0); 242154912308SNavdeep Parhar } 242254912308SNavdeep Parhar } 242354912308SNavdeep Parhar 242454912308SNavdeep Parhar /* 242554912308SNavdeep Parhar * XXX: Allow user to specify snaplen, minlen, and pattern (including inverted 242654912308SNavdeep Parhar * matching). Right now this is a quick-n-dirty implementation that traces the 242754912308SNavdeep Parhar * first 128B of all tx or rx on a port 242854912308SNavdeep Parhar */ 242954912308SNavdeep Parhar static int 243054912308SNavdeep Parhar set_tracer(uint8_t idx, int argc, const char *argv[]) 243154912308SNavdeep Parhar { 243254912308SNavdeep Parhar struct t4_tracer t; 243354912308SNavdeep Parhar int len, port; 243454912308SNavdeep Parhar 243554912308SNavdeep Parhar bzero(&t, sizeof (t)); 243654912308SNavdeep Parhar t.idx = idx; 243754912308SNavdeep Parhar t.enabled = 1; 243854912308SNavdeep Parhar t.valid = 1; 243954912308SNavdeep Parhar 244054912308SNavdeep Parhar if (argc != 1) { 244154912308SNavdeep Parhar warnx("must specify tx<n> or rx<n>."); 244254912308SNavdeep Parhar return (EINVAL); 244354912308SNavdeep Parhar } 244454912308SNavdeep Parhar 244554912308SNavdeep Parhar len = strlen(argv[0]); 244654912308SNavdeep Parhar if (len != 3) { 244754912308SNavdeep Parhar warnx("argument must be 3 characters (tx<n> or rx<n>)"); 244854912308SNavdeep Parhar return (EINVAL); 244954912308SNavdeep Parhar } 245054912308SNavdeep Parhar 245154912308SNavdeep Parhar if (strncmp(argv[0], "tx", 2) == 0) { 245254912308SNavdeep Parhar port = argv[0][2] - '0'; 245354912308SNavdeep Parhar if (port < 0 || port > 3) { 245454912308SNavdeep Parhar warnx("'%c' in %s is invalid", argv[0][2], argv[0]); 245554912308SNavdeep Parhar return (EINVAL); 245654912308SNavdeep Parhar } 245754912308SNavdeep Parhar port += 4; 245854912308SNavdeep Parhar } else if (strncmp(argv[0], "rx", 2) == 0) { 245954912308SNavdeep Parhar port = argv[0][2] - '0'; 246054912308SNavdeep Parhar if (port < 0 || port > 3) { 246154912308SNavdeep Parhar warnx("'%c' in %s is invalid", argv[0][2], argv[0]); 246254912308SNavdeep Parhar return (EINVAL); 246354912308SNavdeep Parhar } 246454912308SNavdeep Parhar } else { 246554912308SNavdeep Parhar warnx("argument '%s' isn't tx<n> or rx<n>", argv[0]); 246654912308SNavdeep Parhar return (EINVAL); 246754912308SNavdeep Parhar } 246854912308SNavdeep Parhar 246954912308SNavdeep Parhar t.tp.snap_len = 128; 247054912308SNavdeep Parhar t.tp.min_len = 0; 247154912308SNavdeep Parhar t.tp.skip_ofst = 0; 247254912308SNavdeep Parhar t.tp.skip_len = 0; 247354912308SNavdeep Parhar t.tp.invert = 0; 247454912308SNavdeep Parhar t.tp.port = port; 247554912308SNavdeep Parhar 247654912308SNavdeep Parhar create_tracing_ifnet(); 247754912308SNavdeep Parhar return doit(CHELSIO_T4_SET_TRACER, &t); 247854912308SNavdeep Parhar } 247954912308SNavdeep Parhar 248054912308SNavdeep Parhar static int 248154912308SNavdeep Parhar tracer_cmd(int argc, const char *argv[]) 248254912308SNavdeep Parhar { 248354912308SNavdeep Parhar long long val; 248454912308SNavdeep Parhar uint8_t idx; 248554912308SNavdeep Parhar char *s; 248654912308SNavdeep Parhar 248754912308SNavdeep Parhar if (argc == 0) { 248854912308SNavdeep Parhar warnx("tracer: no arguments."); 248954912308SNavdeep Parhar return (EINVAL); 249054912308SNavdeep Parhar }; 249154912308SNavdeep Parhar 249254912308SNavdeep Parhar /* list */ 249354912308SNavdeep Parhar if (strcmp(argv[0], "list") == 0) { 249454912308SNavdeep Parhar if (argc != 1) 249554912308SNavdeep Parhar warnx("trailing arguments after \"list\" ignored."); 249654912308SNavdeep Parhar 249754912308SNavdeep Parhar return show_tracers(); 249854912308SNavdeep Parhar } 249954912308SNavdeep Parhar 250054912308SNavdeep Parhar /* <idx> ... */ 250154912308SNavdeep Parhar s = str_to_number(argv[0], NULL, &val); 250254912308SNavdeep Parhar if (*s || val > 0xff) { 250354912308SNavdeep Parhar warnx("\"%s\" is neither an index nor a tracer subcommand.", 250454912308SNavdeep Parhar argv[0]); 250554912308SNavdeep Parhar return (EINVAL); 250654912308SNavdeep Parhar } 250754912308SNavdeep Parhar idx = (int8_t)val; 250854912308SNavdeep Parhar 250954912308SNavdeep Parhar /* <idx> disable */ 251054912308SNavdeep Parhar if (argc == 2 && strcmp(argv[1], "disable") == 0) 251154912308SNavdeep Parhar return tracer_onoff(idx, 0); 251254912308SNavdeep Parhar 251354912308SNavdeep Parhar /* <idx> enable */ 251454912308SNavdeep Parhar if (argc == 2 && strcmp(argv[1], "enable") == 0) 251554912308SNavdeep Parhar return tracer_onoff(idx, 1); 251654912308SNavdeep Parhar 251754912308SNavdeep Parhar /* <idx> ... */ 251854912308SNavdeep Parhar return set_tracer(idx, argc - 1, argv + 1); 251954912308SNavdeep Parhar } 252054912308SNavdeep Parhar 252154912308SNavdeep Parhar static int 252254912308SNavdeep Parhar modinfo_raw(int port_id) 252354912308SNavdeep Parhar { 252454912308SNavdeep Parhar uint8_t offset; 252554912308SNavdeep Parhar struct t4_i2c_data i2cd; 252654912308SNavdeep Parhar int rc; 252754912308SNavdeep Parhar 252854912308SNavdeep Parhar for (offset = 0; offset < 96; offset += sizeof(i2cd.data)) { 252954912308SNavdeep Parhar bzero(&i2cd, sizeof(i2cd)); 253054912308SNavdeep Parhar i2cd.port_id = port_id; 253154912308SNavdeep Parhar i2cd.dev_addr = 0xa0; 253254912308SNavdeep Parhar i2cd.offset = offset; 253354912308SNavdeep Parhar i2cd.len = sizeof(i2cd.data); 253454912308SNavdeep Parhar rc = doit(CHELSIO_T4_GET_I2C, &i2cd); 253554912308SNavdeep Parhar if (rc != 0) 253654912308SNavdeep Parhar return (rc); 253754912308SNavdeep Parhar printf("%02x: %02x %02x %02x %02x %02x %02x %02x %02x", 253854912308SNavdeep Parhar offset, i2cd.data[0], i2cd.data[1], i2cd.data[2], 253954912308SNavdeep Parhar i2cd.data[3], i2cd.data[4], i2cd.data[5], i2cd.data[6], 254054912308SNavdeep Parhar i2cd.data[7]); 254154912308SNavdeep Parhar 254254912308SNavdeep Parhar printf(" %c%c%c%c %c%c%c%c\n", 254354912308SNavdeep Parhar isprint(i2cd.data[0]) ? i2cd.data[0] : '.', 254454912308SNavdeep Parhar isprint(i2cd.data[1]) ? i2cd.data[1] : '.', 254554912308SNavdeep Parhar isprint(i2cd.data[2]) ? i2cd.data[2] : '.', 254654912308SNavdeep Parhar isprint(i2cd.data[3]) ? i2cd.data[3] : '.', 254754912308SNavdeep Parhar isprint(i2cd.data[4]) ? i2cd.data[4] : '.', 254854912308SNavdeep Parhar isprint(i2cd.data[5]) ? i2cd.data[5] : '.', 254954912308SNavdeep Parhar isprint(i2cd.data[6]) ? i2cd.data[6] : '.', 255054912308SNavdeep Parhar isprint(i2cd.data[7]) ? i2cd.data[7] : '.'); 255154912308SNavdeep Parhar } 255254912308SNavdeep Parhar 255354912308SNavdeep Parhar return (0); 255454912308SNavdeep Parhar } 255554912308SNavdeep Parhar 255654912308SNavdeep Parhar static int 255754912308SNavdeep Parhar modinfo(int argc, const char *argv[]) 255854912308SNavdeep Parhar { 255954912308SNavdeep Parhar long port; 256054912308SNavdeep Parhar char string[16], *p; 256154912308SNavdeep Parhar struct t4_i2c_data i2cd; 256254912308SNavdeep Parhar int rc, i; 256354912308SNavdeep Parhar uint16_t temp, vcc, tx_bias, tx_power, rx_power; 256454912308SNavdeep Parhar 256554912308SNavdeep Parhar if (argc < 1) { 256654912308SNavdeep Parhar warnx("must supply a port"); 256754912308SNavdeep Parhar return (EINVAL); 256854912308SNavdeep Parhar } 256954912308SNavdeep Parhar 257054912308SNavdeep Parhar if (argc > 2) { 257154912308SNavdeep Parhar warnx("too many arguments"); 257254912308SNavdeep Parhar return (EINVAL); 257354912308SNavdeep Parhar } 257454912308SNavdeep Parhar 257554912308SNavdeep Parhar p = str_to_number(argv[0], &port, NULL); 257654912308SNavdeep Parhar if (*p || port > UCHAR_MAX) { 257754912308SNavdeep Parhar warnx("invalid port id \"%s\"", argv[0]); 257854912308SNavdeep Parhar return (EINVAL); 257954912308SNavdeep Parhar } 258054912308SNavdeep Parhar 258154912308SNavdeep Parhar if (argc == 2) { 258254912308SNavdeep Parhar if (!strcmp(argv[1], "raw")) 258354912308SNavdeep Parhar return (modinfo_raw(port)); 258454912308SNavdeep Parhar else { 258554912308SNavdeep Parhar warnx("second argument can only be \"raw\""); 258654912308SNavdeep Parhar return (EINVAL); 258754912308SNavdeep Parhar } 258854912308SNavdeep Parhar } 258954912308SNavdeep Parhar 259054912308SNavdeep Parhar bzero(&i2cd, sizeof(i2cd)); 259154912308SNavdeep Parhar i2cd.len = 1; 259254912308SNavdeep Parhar i2cd.port_id = port; 259354912308SNavdeep Parhar i2cd.dev_addr = SFF_8472_BASE; 259454912308SNavdeep Parhar 259554912308SNavdeep Parhar i2cd.offset = SFF_8472_ID; 259654912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 259754912308SNavdeep Parhar goto fail; 259854912308SNavdeep Parhar 259954912308SNavdeep Parhar if (i2cd.data[0] > SFF_8472_ID_LAST) 260054912308SNavdeep Parhar printf("Unknown ID\n"); 260154912308SNavdeep Parhar else 260254912308SNavdeep Parhar printf("ID: %s\n", sff_8472_id[i2cd.data[0]]); 260354912308SNavdeep Parhar 260454912308SNavdeep Parhar bzero(&string, sizeof(string)); 260554912308SNavdeep Parhar for (i = SFF_8472_VENDOR_START; i < SFF_8472_VENDOR_END; i++) { 260654912308SNavdeep Parhar i2cd.offset = i; 260754912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 260854912308SNavdeep Parhar goto fail; 260954912308SNavdeep Parhar string[i - SFF_8472_VENDOR_START] = i2cd.data[0]; 261054912308SNavdeep Parhar } 261154912308SNavdeep Parhar printf("Vendor %s\n", string); 261254912308SNavdeep Parhar 261354912308SNavdeep Parhar bzero(&string, sizeof(string)); 261454912308SNavdeep Parhar for (i = SFF_8472_SN_START; i < SFF_8472_SN_END; i++) { 261554912308SNavdeep Parhar i2cd.offset = i; 261654912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 261754912308SNavdeep Parhar goto fail; 261854912308SNavdeep Parhar string[i - SFF_8472_SN_START] = i2cd.data[0]; 261954912308SNavdeep Parhar } 262054912308SNavdeep Parhar printf("SN %s\n", string); 262154912308SNavdeep Parhar 262254912308SNavdeep Parhar bzero(&string, sizeof(string)); 262354912308SNavdeep Parhar for (i = SFF_8472_PN_START; i < SFF_8472_PN_END; i++) { 262454912308SNavdeep Parhar i2cd.offset = i; 262554912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 262654912308SNavdeep Parhar goto fail; 262754912308SNavdeep Parhar string[i - SFF_8472_PN_START] = i2cd.data[0]; 262854912308SNavdeep Parhar } 262954912308SNavdeep Parhar printf("PN %s\n", string); 263054912308SNavdeep Parhar 263154912308SNavdeep Parhar bzero(&string, sizeof(string)); 263254912308SNavdeep Parhar for (i = SFF_8472_REV_START; i < SFF_8472_REV_END; i++) { 263354912308SNavdeep Parhar i2cd.offset = i; 263454912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 263554912308SNavdeep Parhar goto fail; 263654912308SNavdeep Parhar string[i - SFF_8472_REV_START] = i2cd.data[0]; 263754912308SNavdeep Parhar } 263854912308SNavdeep Parhar printf("Rev %s\n", string); 263954912308SNavdeep Parhar 264054912308SNavdeep Parhar i2cd.offset = SFF_8472_DIAG_TYPE; 264154912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 264254912308SNavdeep Parhar goto fail; 264354912308SNavdeep Parhar 264454912308SNavdeep Parhar if ((char )i2cd.data[0] & (SFF_8472_DIAG_IMPL | 264554912308SNavdeep Parhar SFF_8472_DIAG_INTERNAL)) { 264654912308SNavdeep Parhar 264754912308SNavdeep Parhar /* Switch to reading from the Diagnostic address. */ 264854912308SNavdeep Parhar i2cd.dev_addr = SFF_8472_DIAG; 264954912308SNavdeep Parhar i2cd.len = 1; 265054912308SNavdeep Parhar 265154912308SNavdeep Parhar i2cd.offset = SFF_8472_TEMP; 265254912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 265354912308SNavdeep Parhar goto fail; 265454912308SNavdeep Parhar temp = i2cd.data[0] << 8; 265554912308SNavdeep Parhar printf("Temp: "); 265654912308SNavdeep Parhar if ((temp & SFF_8472_TEMP_SIGN) == SFF_8472_TEMP_SIGN) 265754912308SNavdeep Parhar printf("-"); 265854912308SNavdeep Parhar else 265954912308SNavdeep Parhar printf("+"); 266054912308SNavdeep Parhar printf("%dC\n", (temp & SFF_8472_TEMP_MSK) >> 266154912308SNavdeep Parhar SFF_8472_TEMP_SHIFT); 266254912308SNavdeep Parhar 266354912308SNavdeep Parhar i2cd.offset = SFF_8472_VCC; 266454912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 266554912308SNavdeep Parhar goto fail; 266654912308SNavdeep Parhar vcc = i2cd.data[0] << 8; 266754912308SNavdeep Parhar printf("Vcc %fV\n", vcc / SFF_8472_VCC_FACTOR); 266854912308SNavdeep Parhar 266954912308SNavdeep Parhar i2cd.offset = SFF_8472_TX_BIAS; 267054912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 267154912308SNavdeep Parhar goto fail; 267254912308SNavdeep Parhar tx_bias = i2cd.data[0] << 8; 267354912308SNavdeep Parhar printf("TX Bias %fuA\n", tx_bias / SFF_8472_BIAS_FACTOR); 267454912308SNavdeep Parhar 267554912308SNavdeep Parhar i2cd.offset = SFF_8472_TX_POWER; 267654912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 267754912308SNavdeep Parhar goto fail; 267854912308SNavdeep Parhar tx_power = i2cd.data[0] << 8; 267954912308SNavdeep Parhar printf("TX Power %fmW\n", tx_power / SFF_8472_POWER_FACTOR); 268054912308SNavdeep Parhar 268154912308SNavdeep Parhar i2cd.offset = SFF_8472_RX_POWER; 268254912308SNavdeep Parhar if ((rc = doit(CHELSIO_T4_GET_I2C, &i2cd)) != 0) 268354912308SNavdeep Parhar goto fail; 268454912308SNavdeep Parhar rx_power = i2cd.data[0] << 8; 268554912308SNavdeep Parhar printf("RX Power %fmW\n", rx_power / SFF_8472_POWER_FACTOR); 268654912308SNavdeep Parhar 268754912308SNavdeep Parhar } else 268854912308SNavdeep Parhar printf("Diagnostics not supported.\n"); 268954912308SNavdeep Parhar 269054912308SNavdeep Parhar return(0); 269154912308SNavdeep Parhar 269254912308SNavdeep Parhar fail: 269354912308SNavdeep Parhar if (rc == EPERM) 269454912308SNavdeep Parhar warnx("No module/cable in port %ld", port); 269554912308SNavdeep Parhar return (rc); 269654912308SNavdeep Parhar 269754912308SNavdeep Parhar } 269854912308SNavdeep Parhar 269954912308SNavdeep Parhar /* XXX: pass in a low/high and do range checks as well */ 270054912308SNavdeep Parhar static int 270154912308SNavdeep Parhar get_sched_param(const char *param, const char *args[], long *val) 270254912308SNavdeep Parhar { 270354912308SNavdeep Parhar char *p; 270454912308SNavdeep Parhar 270554912308SNavdeep Parhar if (strcmp(param, args[0]) != 0) 270654912308SNavdeep Parhar return (EINVAL); 270754912308SNavdeep Parhar 270854912308SNavdeep Parhar p = str_to_number(args[1], val, NULL); 270954912308SNavdeep Parhar if (*p) { 271054912308SNavdeep Parhar warnx("parameter \"%s\" has bad value \"%s\"", args[0], 271154912308SNavdeep Parhar args[1]); 271254912308SNavdeep Parhar return (EINVAL); 271354912308SNavdeep Parhar } 271454912308SNavdeep Parhar 271554912308SNavdeep Parhar return (0); 271654912308SNavdeep Parhar } 271754912308SNavdeep Parhar 271854912308SNavdeep Parhar static int 271954912308SNavdeep Parhar sched_class(int argc, const char *argv[]) 272054912308SNavdeep Parhar { 272154912308SNavdeep Parhar struct t4_sched_params op; 272254912308SNavdeep Parhar int errs, i; 272354912308SNavdeep Parhar 272454912308SNavdeep Parhar memset(&op, 0xff, sizeof(op)); 272554912308SNavdeep Parhar op.subcmd = -1; 272654912308SNavdeep Parhar op.type = -1; 272754912308SNavdeep Parhar if (argc == 0) { 272854912308SNavdeep Parhar warnx("missing scheduling sub-command"); 272954912308SNavdeep Parhar return (EINVAL); 273054912308SNavdeep Parhar } 273154912308SNavdeep Parhar if (!strcmp(argv[0], "config")) { 273254912308SNavdeep Parhar op.subcmd = SCHED_CLASS_SUBCMD_CONFIG; 273354912308SNavdeep Parhar op.u.config.minmax = -1; 273454912308SNavdeep Parhar } else if (!strcmp(argv[0], "params")) { 273554912308SNavdeep Parhar op.subcmd = SCHED_CLASS_SUBCMD_PARAMS; 273654912308SNavdeep Parhar op.u.params.level = op.u.params.mode = op.u.params.rateunit = 273754912308SNavdeep Parhar op.u.params.ratemode = op.u.params.channel = 273854912308SNavdeep Parhar op.u.params.cl = op.u.params.minrate = op.u.params.maxrate = 273954912308SNavdeep Parhar op.u.params.weight = op.u.params.pktsize = -1; 274054912308SNavdeep Parhar } else { 274154912308SNavdeep Parhar warnx("invalid scheduling sub-command \"%s\"", argv[0]); 274254912308SNavdeep Parhar return (EINVAL); 274354912308SNavdeep Parhar } 274454912308SNavdeep Parhar 274554912308SNavdeep Parhar /* Decode remaining arguments ... */ 274654912308SNavdeep Parhar errs = 0; 274754912308SNavdeep Parhar for (i = 1; i < argc; i += 2) { 274854912308SNavdeep Parhar const char **args = &argv[i]; 274954912308SNavdeep Parhar long l; 275054912308SNavdeep Parhar 275154912308SNavdeep Parhar if (i + 1 == argc) { 275254912308SNavdeep Parhar warnx("missing argument for \"%s\"", args[0]); 275354912308SNavdeep Parhar errs++; 275454912308SNavdeep Parhar break; 275554912308SNavdeep Parhar } 275654912308SNavdeep Parhar 275754912308SNavdeep Parhar if (!strcmp(args[0], "type")) { 275854912308SNavdeep Parhar if (!strcmp(args[1], "packet")) 275954912308SNavdeep Parhar op.type = SCHED_CLASS_TYPE_PACKET; 276054912308SNavdeep Parhar else { 276154912308SNavdeep Parhar warnx("invalid type parameter \"%s\"", args[1]); 276254912308SNavdeep Parhar errs++; 276354912308SNavdeep Parhar } 276454912308SNavdeep Parhar 276554912308SNavdeep Parhar continue; 276654912308SNavdeep Parhar } 276754912308SNavdeep Parhar 276854912308SNavdeep Parhar if (op.subcmd == SCHED_CLASS_SUBCMD_CONFIG) { 276954912308SNavdeep Parhar if(!get_sched_param("minmax", args, &l)) 277054912308SNavdeep Parhar op.u.config.minmax = (int8_t)l; 277154912308SNavdeep Parhar else { 277254912308SNavdeep Parhar warnx("unknown scheduler config parameter " 277354912308SNavdeep Parhar "\"%s\"", args[0]); 277454912308SNavdeep Parhar errs++; 277554912308SNavdeep Parhar } 277654912308SNavdeep Parhar 277754912308SNavdeep Parhar continue; 277854912308SNavdeep Parhar } 277954912308SNavdeep Parhar 278054912308SNavdeep Parhar /* Rest applies only to SUBCMD_PARAMS */ 278154912308SNavdeep Parhar if (op.subcmd != SCHED_CLASS_SUBCMD_PARAMS) 278254912308SNavdeep Parhar continue; 278354912308SNavdeep Parhar 278454912308SNavdeep Parhar if (!strcmp(args[0], "level")) { 278554912308SNavdeep Parhar if (!strcmp(args[1], "cl-rl")) 278654912308SNavdeep Parhar op.u.params.level = SCHED_CLASS_LEVEL_CL_RL; 278754912308SNavdeep Parhar else if (!strcmp(args[1], "cl-wrr")) 278854912308SNavdeep Parhar op.u.params.level = SCHED_CLASS_LEVEL_CL_WRR; 278954912308SNavdeep Parhar else if (!strcmp(args[1], "ch-rl")) 279054912308SNavdeep Parhar op.u.params.level = SCHED_CLASS_LEVEL_CH_RL; 279154912308SNavdeep Parhar else { 279254912308SNavdeep Parhar warnx("invalid level parameter \"%s\"", 279354912308SNavdeep Parhar args[1]); 279454912308SNavdeep Parhar errs++; 279554912308SNavdeep Parhar } 279654912308SNavdeep Parhar } else if (!strcmp(args[0], "mode")) { 279754912308SNavdeep Parhar if (!strcmp(args[1], "class")) 279854912308SNavdeep Parhar op.u.params.mode = SCHED_CLASS_MODE_CLASS; 279954912308SNavdeep Parhar else if (!strcmp(args[1], "flow")) 280054912308SNavdeep Parhar op.u.params.mode = SCHED_CLASS_MODE_FLOW; 280154912308SNavdeep Parhar else { 280254912308SNavdeep Parhar warnx("invalid mode parameter \"%s\"", args[1]); 280354912308SNavdeep Parhar errs++; 280454912308SNavdeep Parhar } 280554912308SNavdeep Parhar } else if (!strcmp(args[0], "rate-unit")) { 280654912308SNavdeep Parhar if (!strcmp(args[1], "bits")) 280754912308SNavdeep Parhar op.u.params.rateunit = SCHED_CLASS_RATEUNIT_BITS; 280854912308SNavdeep Parhar else if (!strcmp(args[1], "pkts")) 280954912308SNavdeep Parhar op.u.params.rateunit = SCHED_CLASS_RATEUNIT_PKTS; 281054912308SNavdeep Parhar else { 281154912308SNavdeep Parhar warnx("invalid rate-unit parameter \"%s\"", 281254912308SNavdeep Parhar args[1]); 281354912308SNavdeep Parhar errs++; 281454912308SNavdeep Parhar } 281554912308SNavdeep Parhar } else if (!strcmp(args[0], "rate-mode")) { 281654912308SNavdeep Parhar if (!strcmp(args[1], "relative")) 281754912308SNavdeep Parhar op.u.params.ratemode = SCHED_CLASS_RATEMODE_REL; 281854912308SNavdeep Parhar else if (!strcmp(args[1], "absolute")) 281954912308SNavdeep Parhar op.u.params.ratemode = SCHED_CLASS_RATEMODE_ABS; 282054912308SNavdeep Parhar else { 282154912308SNavdeep Parhar warnx("invalid rate-mode parameter \"%s\"", 282254912308SNavdeep Parhar args[1]); 282354912308SNavdeep Parhar errs++; 282454912308SNavdeep Parhar } 282554912308SNavdeep Parhar } else if (!get_sched_param("channel", args, &l)) 282654912308SNavdeep Parhar op.u.params.channel = (int8_t)l; 282754912308SNavdeep Parhar else if (!get_sched_param("class", args, &l)) 282854912308SNavdeep Parhar op.u.params.cl = (int8_t)l; 282954912308SNavdeep Parhar else if (!get_sched_param("min-rate", args, &l)) 283054912308SNavdeep Parhar op.u.params.minrate = (int32_t)l; 283154912308SNavdeep Parhar else if (!get_sched_param("max-rate", args, &l)) 283254912308SNavdeep Parhar op.u.params.maxrate = (int32_t)l; 283354912308SNavdeep Parhar else if (!get_sched_param("weight", args, &l)) 283454912308SNavdeep Parhar op.u.params.weight = (int16_t)l; 283554912308SNavdeep Parhar else if (!get_sched_param("pkt-size", args, &l)) 283654912308SNavdeep Parhar op.u.params.pktsize = (int16_t)l; 283754912308SNavdeep Parhar else { 283854912308SNavdeep Parhar warnx("unknown scheduler parameter \"%s\"", args[0]); 283954912308SNavdeep Parhar errs++; 284054912308SNavdeep Parhar } 284154912308SNavdeep Parhar } 284254912308SNavdeep Parhar 284354912308SNavdeep Parhar /* 284454912308SNavdeep Parhar * Catch some logical fallacies in terms of argument combinations here 284554912308SNavdeep Parhar * so we can offer more than just the EINVAL return from the driver. 284654912308SNavdeep Parhar * The driver will be able to catch a lot more issues since it knows 284754912308SNavdeep Parhar * the specifics of the device hardware capabilities like how many 284854912308SNavdeep Parhar * channels, classes, etc. the device supports. 284954912308SNavdeep Parhar */ 285054912308SNavdeep Parhar if (op.type < 0) { 285154912308SNavdeep Parhar warnx("sched \"type\" parameter missing"); 285254912308SNavdeep Parhar errs++; 285354912308SNavdeep Parhar } 285454912308SNavdeep Parhar if (op.subcmd == SCHED_CLASS_SUBCMD_CONFIG) { 285554912308SNavdeep Parhar if (op.u.config.minmax < 0) { 285654912308SNavdeep Parhar warnx("sched config \"minmax\" parameter missing"); 285754912308SNavdeep Parhar errs++; 285854912308SNavdeep Parhar } 285954912308SNavdeep Parhar } 286054912308SNavdeep Parhar if (op.subcmd == SCHED_CLASS_SUBCMD_PARAMS) { 286154912308SNavdeep Parhar if (op.u.params.level < 0) { 286254912308SNavdeep Parhar warnx("sched params \"level\" parameter missing"); 286354912308SNavdeep Parhar errs++; 286454912308SNavdeep Parhar } 2865*ffcf81c9SNavdeep Parhar if (op.u.params.mode < 0 && 2866*ffcf81c9SNavdeep Parhar op.u.params.level == SCHED_CLASS_LEVEL_CL_RL) { 286754912308SNavdeep Parhar warnx("sched params \"mode\" parameter missing"); 286854912308SNavdeep Parhar errs++; 286954912308SNavdeep Parhar } 2870*ffcf81c9SNavdeep Parhar if (op.u.params.rateunit < 0 && 2871*ffcf81c9SNavdeep Parhar (op.u.params.level == SCHED_CLASS_LEVEL_CL_RL || 2872*ffcf81c9SNavdeep Parhar op.u.params.level == SCHED_CLASS_LEVEL_CH_RL)) { 287354912308SNavdeep Parhar warnx("sched params \"rate-unit\" parameter missing"); 287454912308SNavdeep Parhar errs++; 287554912308SNavdeep Parhar } 2876*ffcf81c9SNavdeep Parhar if (op.u.params.ratemode < 0 && 2877*ffcf81c9SNavdeep Parhar (op.u.params.level == SCHED_CLASS_LEVEL_CL_RL || 2878*ffcf81c9SNavdeep Parhar op.u.params.level == SCHED_CLASS_LEVEL_CH_RL)) { 287954912308SNavdeep Parhar warnx("sched params \"rate-mode\" parameter missing"); 288054912308SNavdeep Parhar errs++; 288154912308SNavdeep Parhar } 288254912308SNavdeep Parhar if (op.u.params.channel < 0) { 288354912308SNavdeep Parhar warnx("sched params \"channel\" missing"); 288454912308SNavdeep Parhar errs++; 288554912308SNavdeep Parhar } 2886*ffcf81c9SNavdeep Parhar if (op.u.params.cl < 0 && 2887*ffcf81c9SNavdeep Parhar (op.u.params.level == SCHED_CLASS_LEVEL_CL_RL || 2888*ffcf81c9SNavdeep Parhar op.u.params.level == SCHED_CLASS_LEVEL_CL_WRR)) { 288954912308SNavdeep Parhar warnx("sched params \"class\" missing"); 289054912308SNavdeep Parhar errs++; 289154912308SNavdeep Parhar } 289254912308SNavdeep Parhar if (op.u.params.maxrate < 0 && 289354912308SNavdeep Parhar (op.u.params.level == SCHED_CLASS_LEVEL_CL_RL || 289454912308SNavdeep Parhar op.u.params.level == SCHED_CLASS_LEVEL_CH_RL)) { 289554912308SNavdeep Parhar warnx("sched params \"max-rate\" missing for " 289654912308SNavdeep Parhar "rate-limit level"); 289754912308SNavdeep Parhar errs++; 289854912308SNavdeep Parhar } 2899*ffcf81c9SNavdeep Parhar if (op.u.params.level == SCHED_CLASS_LEVEL_CL_WRR && 2900*ffcf81c9SNavdeep Parhar (op.u.params.weight < 1 || op.u.params.weight > 99)) { 2901*ffcf81c9SNavdeep Parhar warnx("sched params \"weight\" missing or invalid " 2902*ffcf81c9SNavdeep Parhar "(not 1-99) for weighted-round-robin level"); 290354912308SNavdeep Parhar errs++; 290454912308SNavdeep Parhar } 290554912308SNavdeep Parhar if (op.u.params.pktsize < 0 && 2906*ffcf81c9SNavdeep Parhar op.u.params.level == SCHED_CLASS_LEVEL_CL_RL) { 290754912308SNavdeep Parhar warnx("sched params \"pkt-size\" missing for " 290854912308SNavdeep Parhar "rate-limit level"); 290954912308SNavdeep Parhar errs++; 291054912308SNavdeep Parhar } 291154912308SNavdeep Parhar if (op.u.params.mode == SCHED_CLASS_MODE_FLOW && 291254912308SNavdeep Parhar op.u.params.ratemode != SCHED_CLASS_RATEMODE_ABS) { 291354912308SNavdeep Parhar warnx("sched params mode flow needs rate-mode absolute"); 291454912308SNavdeep Parhar errs++; 291554912308SNavdeep Parhar } 291654912308SNavdeep Parhar if (op.u.params.ratemode == SCHED_CLASS_RATEMODE_REL && 291754912308SNavdeep Parhar !in_range(op.u.params.maxrate, 1, 100)) { 291854912308SNavdeep Parhar warnx("sched params \"max-rate\" takes " 291954912308SNavdeep Parhar "percentage value(1-100) for rate-mode relative"); 292054912308SNavdeep Parhar errs++; 292154912308SNavdeep Parhar } 292254912308SNavdeep Parhar if (op.u.params.ratemode == SCHED_CLASS_RATEMODE_ABS && 292354912308SNavdeep Parhar !in_range(op.u.params.maxrate, 1, 100000000)) { 292454912308SNavdeep Parhar warnx("sched params \"max-rate\" takes " 292554912308SNavdeep Parhar "value(1-100000000) for rate-mode absolute"); 292654912308SNavdeep Parhar errs++; 292754912308SNavdeep Parhar } 292854912308SNavdeep Parhar if (op.u.params.maxrate > 0 && 292954912308SNavdeep Parhar op.u.params.maxrate < op.u.params.minrate) { 293054912308SNavdeep Parhar warnx("sched params \"max-rate\" is less than " 293154912308SNavdeep Parhar "\"min-rate\""); 293254912308SNavdeep Parhar errs++; 293354912308SNavdeep Parhar } 293454912308SNavdeep Parhar } 293554912308SNavdeep Parhar 293654912308SNavdeep Parhar if (errs > 0) { 293754912308SNavdeep Parhar warnx("%d error%s in sched-class command", errs, 293854912308SNavdeep Parhar errs == 1 ? "" : "s"); 293954912308SNavdeep Parhar return (EINVAL); 294054912308SNavdeep Parhar } 294154912308SNavdeep Parhar 294254912308SNavdeep Parhar return doit(CHELSIO_T4_SCHED_CLASS, &op); 294354912308SNavdeep Parhar } 294454912308SNavdeep Parhar 294554912308SNavdeep Parhar static int 294654912308SNavdeep Parhar sched_queue(int argc, const char *argv[]) 294754912308SNavdeep Parhar { 294854912308SNavdeep Parhar struct t4_sched_queue op = {0}; 294954912308SNavdeep Parhar char *p; 295054912308SNavdeep Parhar long val; 295154912308SNavdeep Parhar 295254912308SNavdeep Parhar if (argc != 3) { 295354912308SNavdeep Parhar /* need "<port> <queue> <class> */ 295454912308SNavdeep Parhar warnx("incorrect number of arguments."); 295554912308SNavdeep Parhar return (EINVAL); 295654912308SNavdeep Parhar } 295754912308SNavdeep Parhar 295854912308SNavdeep Parhar p = str_to_number(argv[0], &val, NULL); 295954912308SNavdeep Parhar if (*p || val > UCHAR_MAX) { 296054912308SNavdeep Parhar warnx("invalid port id \"%s\"", argv[0]); 296154912308SNavdeep Parhar return (EINVAL); 296254912308SNavdeep Parhar } 296354912308SNavdeep Parhar op.port = (uint8_t)val; 296454912308SNavdeep Parhar 296554912308SNavdeep Parhar if (!strcmp(argv[1], "all") || !strcmp(argv[1], "*")) 296654912308SNavdeep Parhar op.queue = -1; 296754912308SNavdeep Parhar else { 296854912308SNavdeep Parhar p = str_to_number(argv[1], &val, NULL); 296954912308SNavdeep Parhar if (*p || val < -1) { 297054912308SNavdeep Parhar warnx("invalid queue \"%s\"", argv[1]); 297154912308SNavdeep Parhar return (EINVAL); 297254912308SNavdeep Parhar } 297354912308SNavdeep Parhar op.queue = (int8_t)val; 297454912308SNavdeep Parhar } 297554912308SNavdeep Parhar 297654912308SNavdeep Parhar if (!strcmp(argv[2], "unbind") || !strcmp(argv[2], "clear")) 297754912308SNavdeep Parhar op.cl = -1; 297854912308SNavdeep Parhar else { 297954912308SNavdeep Parhar p = str_to_number(argv[2], &val, NULL); 298054912308SNavdeep Parhar if (*p || val < -1) { 298154912308SNavdeep Parhar warnx("invalid class \"%s\"", argv[2]); 298254912308SNavdeep Parhar return (EINVAL); 298354912308SNavdeep Parhar } 298454912308SNavdeep Parhar op.cl = (int8_t)val; 298554912308SNavdeep Parhar } 298654912308SNavdeep Parhar 298754912308SNavdeep Parhar return doit(CHELSIO_T4_SCHED_QUEUE, &op); 298854912308SNavdeep Parhar } 298954912308SNavdeep Parhar 299054912308SNavdeep Parhar static int 29911131c927SNavdeep Parhar parse_offload_settings_word(const char *s, char **pnext, const char *ws, 29921131c927SNavdeep Parhar int *pneg, struct offload_settings *os) 29931131c927SNavdeep Parhar { 29941131c927SNavdeep Parhar 29951131c927SNavdeep Parhar while (*s == '!') { 29961131c927SNavdeep Parhar (*pneg)++; 29971131c927SNavdeep Parhar s++; 29981131c927SNavdeep Parhar } 29991131c927SNavdeep Parhar 30001131c927SNavdeep Parhar if (!strcmp(s, "not")) { 30011131c927SNavdeep Parhar (*pneg)++; 30021131c927SNavdeep Parhar return (0); 30031131c927SNavdeep Parhar } 30041131c927SNavdeep Parhar 30051131c927SNavdeep Parhar if (!strcmp(s, "offload")) { 30061131c927SNavdeep Parhar os->offload = (*pneg + 1) & 1; 30071131c927SNavdeep Parhar *pneg = 0; 30081131c927SNavdeep Parhar } else if (!strcmp(s , "coalesce")) { 30091131c927SNavdeep Parhar os->rx_coalesce = (*pneg + 1) & 1; 30101131c927SNavdeep Parhar *pneg = 0; 30111131c927SNavdeep Parhar } else if (!strcmp(s, "timestamp") || !strcmp(s, "tstamp")) { 30121131c927SNavdeep Parhar os->tstamp = (*pneg + 1) & 1; 30131131c927SNavdeep Parhar *pneg = 0; 30141131c927SNavdeep Parhar } else if (!strcmp(s, "sack")) { 30151131c927SNavdeep Parhar os->sack = (*pneg + 1) & 1; 30161131c927SNavdeep Parhar *pneg = 0; 30171131c927SNavdeep Parhar } else if (!strcmp(s, "nagle")) { 30181131c927SNavdeep Parhar os->nagle = (*pneg + 1) & 1; 30191131c927SNavdeep Parhar *pneg = 0; 30201131c927SNavdeep Parhar } else if (!strcmp(s, "ecn")) { 30211131c927SNavdeep Parhar os->ecn = (*pneg + 1) & 1; 30221131c927SNavdeep Parhar *pneg = 0; 30231131c927SNavdeep Parhar } else if (!strcmp(s, "ddp")) { 30241131c927SNavdeep Parhar os->ddp = (*pneg + 1) & 1; 30251131c927SNavdeep Parhar *pneg = 0; 30261131c927SNavdeep Parhar } else if (!strcmp(s, "tls")) { 30271131c927SNavdeep Parhar os->tls = (*pneg + 1) & 1; 30281131c927SNavdeep Parhar *pneg = 0; 30291131c927SNavdeep Parhar } else { 30301131c927SNavdeep Parhar char *param, *p; 30311131c927SNavdeep Parhar long val; 30321131c927SNavdeep Parhar 30331131c927SNavdeep Parhar /* Settings with additional parameter handled here. */ 30341131c927SNavdeep Parhar 30351131c927SNavdeep Parhar if (*pneg) { 30361131c927SNavdeep Parhar warnx("\"%s\" is not a valid keyword, or it does not " 30371131c927SNavdeep Parhar "support negation.", s); 30381131c927SNavdeep Parhar return (EINVAL); 30391131c927SNavdeep Parhar } 30401131c927SNavdeep Parhar 30411131c927SNavdeep Parhar while ((param = strsep(pnext, ws)) != NULL) { 30421131c927SNavdeep Parhar if (*param != '\0') 30431131c927SNavdeep Parhar break; 30441131c927SNavdeep Parhar } 30451131c927SNavdeep Parhar if (param == NULL) { 30461131c927SNavdeep Parhar warnx("\"%s\" is not a valid keyword, or it requires a " 30471131c927SNavdeep Parhar "parameter that has not been provided.", s); 30481131c927SNavdeep Parhar return (EINVAL); 30491131c927SNavdeep Parhar } 30501131c927SNavdeep Parhar 30511131c927SNavdeep Parhar if (!strcmp(s, "cong")) { 30521131c927SNavdeep Parhar if (!strcmp(param, "reno")) 30531131c927SNavdeep Parhar os->cong_algo = 0; 30541131c927SNavdeep Parhar else if (!strcmp(param, "tahoe")) 30551131c927SNavdeep Parhar os->cong_algo = 1; 30561131c927SNavdeep Parhar else if (!strcmp(param, "newreno")) 30571131c927SNavdeep Parhar os->cong_algo = 2; 30581131c927SNavdeep Parhar else if (!strcmp(param, "highspeed")) 30591131c927SNavdeep Parhar os->cong_algo = 3; 30601131c927SNavdeep Parhar else { 30611131c927SNavdeep Parhar warnx("unknown congestion algorithm \"%s\".", s); 30621131c927SNavdeep Parhar return (EINVAL); 30631131c927SNavdeep Parhar } 30641131c927SNavdeep Parhar } else if (!strcmp(s, "class")) { 30651131c927SNavdeep Parhar val = -1; 30661131c927SNavdeep Parhar p = str_to_number(param, &val, NULL); 30671131c927SNavdeep Parhar /* (nsched_cls - 1) is spelled 15 here. */ 30681131c927SNavdeep Parhar if (*p || val < 0 || val > 15) { 30691131c927SNavdeep Parhar warnx("invalid scheduling class \"%s\". " 30701131c927SNavdeep Parhar "\"class\" needs an integer value where " 30711131c927SNavdeep Parhar "0 <= value <= 15", param); 30721131c927SNavdeep Parhar return (EINVAL); 30731131c927SNavdeep Parhar } 30741131c927SNavdeep Parhar os->sched_class = val; 30751131c927SNavdeep Parhar } else if (!strcmp(s, "bind") || !strcmp(s, "txq") || 30761131c927SNavdeep Parhar !strcmp(s, "rxq")) { 30771131c927SNavdeep Parhar val = -1; 30781131c927SNavdeep Parhar if (strcmp(param, "random")) { 30791131c927SNavdeep Parhar p = str_to_number(param, &val, NULL); 30801131c927SNavdeep Parhar if (*p || val < 0 || val > 0xffff) { 30811131c927SNavdeep Parhar warnx("invalid queue specification " 30821131c927SNavdeep Parhar "\"%s\". \"%s\" needs an integer" 30831131c927SNavdeep Parhar " value, or \"random\".", 30841131c927SNavdeep Parhar param, s); 30851131c927SNavdeep Parhar return (EINVAL); 30861131c927SNavdeep Parhar } 30871131c927SNavdeep Parhar } 30881131c927SNavdeep Parhar if (!strcmp(s, "bind")) { 30891131c927SNavdeep Parhar os->txq = val; 30901131c927SNavdeep Parhar os->rxq = val; 30911131c927SNavdeep Parhar } else if (!strcmp(s, "txq")) { 30921131c927SNavdeep Parhar os->txq = val; 30931131c927SNavdeep Parhar } else if (!strcmp(s, "rxq")) { 30941131c927SNavdeep Parhar os->rxq = val; 30951131c927SNavdeep Parhar } else { 30961131c927SNavdeep Parhar return (EDOOFUS); 30971131c927SNavdeep Parhar } 30981131c927SNavdeep Parhar } else if (!strcmp(s, "mss")) { 30991131c927SNavdeep Parhar val = -1; 31001131c927SNavdeep Parhar p = str_to_number(param, &val, NULL); 31011131c927SNavdeep Parhar if (*p || val <= 0) { 31021131c927SNavdeep Parhar warnx("invalid MSS specification \"%s\". " 31031131c927SNavdeep Parhar "\"mss\" needs a positive integer value", 31041131c927SNavdeep Parhar param); 31051131c927SNavdeep Parhar return (EINVAL); 31061131c927SNavdeep Parhar } 31071131c927SNavdeep Parhar os->mss = val; 31081131c927SNavdeep Parhar } else { 31091131c927SNavdeep Parhar warnx("unknown settings keyword: \"%s\"", s); 31101131c927SNavdeep Parhar return (EINVAL); 31111131c927SNavdeep Parhar } 31121131c927SNavdeep Parhar } 31131131c927SNavdeep Parhar 31141131c927SNavdeep Parhar return (0); 31151131c927SNavdeep Parhar } 31161131c927SNavdeep Parhar 31171131c927SNavdeep Parhar static int 31181131c927SNavdeep Parhar parse_offload_settings(const char *settings_ro, struct offload_settings *os) 31191131c927SNavdeep Parhar { 31201131c927SNavdeep Parhar const char *ws = " \f\n\r\v\t"; 31211131c927SNavdeep Parhar char *settings, *s, *next; 31221131c927SNavdeep Parhar int rc, nsettings, neg; 31231131c927SNavdeep Parhar static const struct offload_settings default_settings = { 31241131c927SNavdeep Parhar .offload = 0, /* No settings imply !offload */ 31251131c927SNavdeep Parhar .rx_coalesce = -1, 31261131c927SNavdeep Parhar .cong_algo = -1, 31271131c927SNavdeep Parhar .sched_class = -1, 31281131c927SNavdeep Parhar .tstamp = -1, 31291131c927SNavdeep Parhar .sack = -1, 31301131c927SNavdeep Parhar .nagle = -1, 31311131c927SNavdeep Parhar .ecn = -1, 31321131c927SNavdeep Parhar .ddp = -1, 31331131c927SNavdeep Parhar .tls = -1, 31341131c927SNavdeep Parhar .txq = -1, 31351131c927SNavdeep Parhar .rxq = -1, 31361131c927SNavdeep Parhar .mss = -1, 31371131c927SNavdeep Parhar }; 31381131c927SNavdeep Parhar 31391131c927SNavdeep Parhar *os = default_settings; 31401131c927SNavdeep Parhar 31411131c927SNavdeep Parhar next = settings = strdup(settings_ro); 31421131c927SNavdeep Parhar if (settings == NULL) { 31431131c927SNavdeep Parhar warn (NULL); 31441131c927SNavdeep Parhar return (errno); 31451131c927SNavdeep Parhar } 31461131c927SNavdeep Parhar 31471131c927SNavdeep Parhar nsettings = 0; 31481131c927SNavdeep Parhar rc = 0; 31491131c927SNavdeep Parhar neg = 0; 31501131c927SNavdeep Parhar while ((s = strsep(&next, ws)) != NULL) { 31511131c927SNavdeep Parhar if (*s == '\0') 31521131c927SNavdeep Parhar continue; 31531131c927SNavdeep Parhar nsettings++; 31541131c927SNavdeep Parhar rc = parse_offload_settings_word(s, &next, ws, &neg, os); 31551131c927SNavdeep Parhar if (rc != 0) 31561131c927SNavdeep Parhar goto done; 31571131c927SNavdeep Parhar } 31581131c927SNavdeep Parhar if (nsettings == 0) { 31591131c927SNavdeep Parhar warnx("no settings provided"); 31601131c927SNavdeep Parhar rc = EINVAL; 31611131c927SNavdeep Parhar goto done; 31621131c927SNavdeep Parhar } 31631131c927SNavdeep Parhar if (neg > 0) { 31641131c927SNavdeep Parhar warnx("%d stray negation(s) at end of offload settings", neg); 31651131c927SNavdeep Parhar rc = EINVAL; 31661131c927SNavdeep Parhar goto done; 31671131c927SNavdeep Parhar } 31681131c927SNavdeep Parhar done: 31691131c927SNavdeep Parhar free(settings); 31701131c927SNavdeep Parhar return (rc); 31711131c927SNavdeep Parhar } 31721131c927SNavdeep Parhar 31731131c927SNavdeep Parhar static int 31741131c927SNavdeep Parhar isempty_line(char *line, size_t llen) 31751131c927SNavdeep Parhar { 31761131c927SNavdeep Parhar 31771131c927SNavdeep Parhar /* skip leading whitespace */ 31781131c927SNavdeep Parhar while (isspace(*line)) { 31791131c927SNavdeep Parhar line++; 31801131c927SNavdeep Parhar llen--; 31811131c927SNavdeep Parhar } 31821131c927SNavdeep Parhar if (llen == 0 || *line == '#' || *line == '\n') 31831131c927SNavdeep Parhar return (1); 31841131c927SNavdeep Parhar 31851131c927SNavdeep Parhar return (0); 31861131c927SNavdeep Parhar } 31871131c927SNavdeep Parhar 31881131c927SNavdeep Parhar static int 31891131c927SNavdeep Parhar special_offload_rule(char *str) 31901131c927SNavdeep Parhar { 31911131c927SNavdeep Parhar 31921131c927SNavdeep Parhar /* skip leading whitespaces */ 31931131c927SNavdeep Parhar while (isspace(*str)) 31941131c927SNavdeep Parhar str++; 31951131c927SNavdeep Parhar 31961131c927SNavdeep Parhar /* check for special strings: "-", "all", "any" */ 31971131c927SNavdeep Parhar if (*str == '-') { 31981131c927SNavdeep Parhar str++; 31991131c927SNavdeep Parhar } else if (!strncmp(str, "all", 3) || !strncmp(str, "any", 3)) { 32001131c927SNavdeep Parhar str += 3; 32011131c927SNavdeep Parhar } else { 32021131c927SNavdeep Parhar return (0); 32031131c927SNavdeep Parhar } 32041131c927SNavdeep Parhar 32051131c927SNavdeep Parhar /* skip trailing whitespaces */ 32061131c927SNavdeep Parhar while (isspace(*str)) 32071131c927SNavdeep Parhar str++; 32081131c927SNavdeep Parhar 32091131c927SNavdeep Parhar return (*str == '\0'); 32101131c927SNavdeep Parhar } 32111131c927SNavdeep Parhar 32121131c927SNavdeep Parhar /* 32131131c927SNavdeep Parhar * A rule has 3 parts: an open-type, a match expression, and offload settings. 32141131c927SNavdeep Parhar * 32151131c927SNavdeep Parhar * [<open-type>] <expr> => <settings> 32161131c927SNavdeep Parhar */ 32171131c927SNavdeep Parhar static int 32181131c927SNavdeep Parhar parse_offload_policy_line(size_t lno, char *line, size_t llen, pcap_t *pd, 32191131c927SNavdeep Parhar struct offload_rule *r) 32201131c927SNavdeep Parhar { 32211131c927SNavdeep Parhar char *expr, *settings, *s; 32221131c927SNavdeep Parhar 32231131c927SNavdeep Parhar bzero(r, sizeof(*r)); 32241131c927SNavdeep Parhar 32251131c927SNavdeep Parhar /* Skip leading whitespace. */ 32261131c927SNavdeep Parhar while (isspace(*line)) 32271131c927SNavdeep Parhar line++; 32281131c927SNavdeep Parhar /* Trim trailing whitespace */ 32291131c927SNavdeep Parhar s = &line[llen - 1]; 32301131c927SNavdeep Parhar while (isspace(*s)) { 32311131c927SNavdeep Parhar *s-- = '\0'; 32321131c927SNavdeep Parhar llen--; 32331131c927SNavdeep Parhar } 32341131c927SNavdeep Parhar 32351131c927SNavdeep Parhar /* 32361131c927SNavdeep Parhar * First part of the rule: '[X]' where X = A/D/L/P 32371131c927SNavdeep Parhar */ 32381131c927SNavdeep Parhar if (*line++ != '[') { 32391131c927SNavdeep Parhar warnx("missing \"[\" on line %zd", lno); 32401131c927SNavdeep Parhar return (EINVAL); 32411131c927SNavdeep Parhar } 32421131c927SNavdeep Parhar switch (*line) { 32431131c927SNavdeep Parhar case 'A': 32441131c927SNavdeep Parhar case 'D': 32451131c927SNavdeep Parhar case 'L': 32461131c927SNavdeep Parhar case 'P': 32471131c927SNavdeep Parhar r->open_type = *line; 32481131c927SNavdeep Parhar break; 32491131c927SNavdeep Parhar default: 32501131c927SNavdeep Parhar warnx("invalid socket-type \"%c\" on line %zd.", *line, lno); 32511131c927SNavdeep Parhar return (EINVAL); 32521131c927SNavdeep Parhar } 32531131c927SNavdeep Parhar line++; 32541131c927SNavdeep Parhar if (*line++ != ']') { 32551131c927SNavdeep Parhar warnx("missing \"]\" after \"[%c\" on line %zd", 32561131c927SNavdeep Parhar r->open_type, lno); 32571131c927SNavdeep Parhar return (EINVAL); 32581131c927SNavdeep Parhar } 32591131c927SNavdeep Parhar 32601131c927SNavdeep Parhar /* Skip whitespace. */ 32611131c927SNavdeep Parhar while (isspace(*line)) 32621131c927SNavdeep Parhar line++; 32631131c927SNavdeep Parhar 32641131c927SNavdeep Parhar /* 32651131c927SNavdeep Parhar * Rest of the rule: <expr> => <settings> 32661131c927SNavdeep Parhar */ 32671131c927SNavdeep Parhar expr = line; 32681131c927SNavdeep Parhar s = strstr(line, "=>"); 32691131c927SNavdeep Parhar if (s == NULL) 32701131c927SNavdeep Parhar return (EINVAL); 32711131c927SNavdeep Parhar settings = s + 2; 32721131c927SNavdeep Parhar while (isspace(*settings)) 32731131c927SNavdeep Parhar settings++; 32741131c927SNavdeep Parhar *s = '\0'; 32751131c927SNavdeep Parhar 32761131c927SNavdeep Parhar /* 32771131c927SNavdeep Parhar * <expr> is either a special name (all, any) or a pcap-filter(7). 32781131c927SNavdeep Parhar * In case of a special name the bpf_prog stays all-zero. 32791131c927SNavdeep Parhar */ 32801131c927SNavdeep Parhar if (!special_offload_rule(expr)) { 32811131c927SNavdeep Parhar if (pcap_compile(pd, &r->bpf_prog, expr, 1, 32821131c927SNavdeep Parhar PCAP_NETMASK_UNKNOWN) < 0) { 32831131c927SNavdeep Parhar warnx("failed to compile \"%s\" on line %zd: %s", expr, 32841131c927SNavdeep Parhar lno, pcap_geterr(pd)); 32851131c927SNavdeep Parhar return (EINVAL); 32861131c927SNavdeep Parhar } 32871131c927SNavdeep Parhar } 32881131c927SNavdeep Parhar 32891131c927SNavdeep Parhar /* settings to apply on a match. */ 32901131c927SNavdeep Parhar if (parse_offload_settings(settings, &r->settings) != 0) { 32911131c927SNavdeep Parhar warnx("failed to parse offload settings \"%s\" on line %zd", 32921131c927SNavdeep Parhar settings, lno); 32931131c927SNavdeep Parhar pcap_freecode(&r->bpf_prog); 32941131c927SNavdeep Parhar return (EINVAL); 32951131c927SNavdeep Parhar } 32961131c927SNavdeep Parhar 32971131c927SNavdeep Parhar return (0); 32981131c927SNavdeep Parhar 32991131c927SNavdeep Parhar } 33001131c927SNavdeep Parhar 33011131c927SNavdeep Parhar /* 33021131c927SNavdeep Parhar * Note that op itself is not dynamically allocated. 33031131c927SNavdeep Parhar */ 33041131c927SNavdeep Parhar static void 33051131c927SNavdeep Parhar free_offload_policy(struct t4_offload_policy *op) 33061131c927SNavdeep Parhar { 33071131c927SNavdeep Parhar int i; 33081131c927SNavdeep Parhar 33091131c927SNavdeep Parhar for (i = 0; i < op->nrules; i++) { 33101131c927SNavdeep Parhar /* 33111131c927SNavdeep Parhar * pcap_freecode can cope with empty bpf_prog, which is the case 33121131c927SNavdeep Parhar * for an rule that matches on 'any/all/-'. 33131131c927SNavdeep Parhar */ 33141131c927SNavdeep Parhar pcap_freecode(&op->rule[i].bpf_prog); 33151131c927SNavdeep Parhar } 33161131c927SNavdeep Parhar free(op->rule); 33171131c927SNavdeep Parhar op->nrules = 0; 33181131c927SNavdeep Parhar op->rule = NULL; 33191131c927SNavdeep Parhar } 33201131c927SNavdeep Parhar 33211131c927SNavdeep Parhar #define REALLOC_STRIDE 32 33221131c927SNavdeep Parhar 33231131c927SNavdeep Parhar /* 33241131c927SNavdeep Parhar * Fills up op->nrules and op->rule. 33251131c927SNavdeep Parhar */ 33261131c927SNavdeep Parhar static int 33271131c927SNavdeep Parhar parse_offload_policy(const char *fname, struct t4_offload_policy *op) 33281131c927SNavdeep Parhar { 33291131c927SNavdeep Parhar FILE *fp; 33301131c927SNavdeep Parhar char *line; 33311131c927SNavdeep Parhar int lno, maxrules, rc; 33321131c927SNavdeep Parhar size_t lcap, llen; 33331131c927SNavdeep Parhar struct offload_rule *r; 33341131c927SNavdeep Parhar pcap_t *pd; 33351131c927SNavdeep Parhar 33361131c927SNavdeep Parhar fp = fopen(fname, "r"); 33371131c927SNavdeep Parhar if (fp == NULL) { 33381131c927SNavdeep Parhar warn("Unable to open file \"%s\"", fname); 33391131c927SNavdeep Parhar return (errno); 33401131c927SNavdeep Parhar } 33411131c927SNavdeep Parhar pd = pcap_open_dead(DLT_EN10MB, 128); 33421131c927SNavdeep Parhar if (pd == NULL) { 33431131c927SNavdeep Parhar warnx("Failed to open pcap device"); 33441131c927SNavdeep Parhar fclose(fp); 33451131c927SNavdeep Parhar return (EIO); 33461131c927SNavdeep Parhar } 33471131c927SNavdeep Parhar 33481131c927SNavdeep Parhar rc = 0; 33491131c927SNavdeep Parhar lno = 0; 33501131c927SNavdeep Parhar lcap = 0; 33511131c927SNavdeep Parhar maxrules = 0; 33521131c927SNavdeep Parhar op->nrules = 0; 33531131c927SNavdeep Parhar op->rule = NULL; 33541131c927SNavdeep Parhar line = NULL; 33551131c927SNavdeep Parhar 33561131c927SNavdeep Parhar while ((llen = getline(&line, &lcap, fp)) != -1) { 33571131c927SNavdeep Parhar lno++; 33581131c927SNavdeep Parhar 33591131c927SNavdeep Parhar /* Skip empty lines. */ 33601131c927SNavdeep Parhar if (isempty_line(line, llen)) 33611131c927SNavdeep Parhar continue; 33621131c927SNavdeep Parhar 33631131c927SNavdeep Parhar if (op->nrules == maxrules) { 33641131c927SNavdeep Parhar maxrules += REALLOC_STRIDE; 33651131c927SNavdeep Parhar r = realloc(op->rule, 33661131c927SNavdeep Parhar maxrules * sizeof(struct offload_rule)); 33671131c927SNavdeep Parhar if (r == NULL) { 33681131c927SNavdeep Parhar warnx("failed to allocate memory for %d rules", 33691131c927SNavdeep Parhar maxrules); 33701131c927SNavdeep Parhar rc = ENOMEM; 33711131c927SNavdeep Parhar goto done; 33721131c927SNavdeep Parhar } 33731131c927SNavdeep Parhar op->rule = r; 33741131c927SNavdeep Parhar } 33751131c927SNavdeep Parhar 33761131c927SNavdeep Parhar r = &op->rule[op->nrules]; 33771131c927SNavdeep Parhar rc = parse_offload_policy_line(lno, line, llen, pd, r); 33781131c927SNavdeep Parhar if (rc != 0) { 33791131c927SNavdeep Parhar warnx("Error parsing line %d of \"%s\"", lno, fname); 33801131c927SNavdeep Parhar goto done; 33811131c927SNavdeep Parhar } 33821131c927SNavdeep Parhar 33831131c927SNavdeep Parhar op->nrules++; 33841131c927SNavdeep Parhar } 33851131c927SNavdeep Parhar free(line); 33861131c927SNavdeep Parhar 33871131c927SNavdeep Parhar if (!feof(fp)) { 33881131c927SNavdeep Parhar warn("Error while reading from file \"%s\" at line %d", 33891131c927SNavdeep Parhar fname, lno); 33901131c927SNavdeep Parhar rc = errno; 33911131c927SNavdeep Parhar goto done; 33921131c927SNavdeep Parhar } 33931131c927SNavdeep Parhar 33941131c927SNavdeep Parhar if (op->nrules == 0) { 33951131c927SNavdeep Parhar warnx("No valid rules found in \"%s\"", fname); 33961131c927SNavdeep Parhar rc = EINVAL; 33971131c927SNavdeep Parhar } 33981131c927SNavdeep Parhar done: 33991131c927SNavdeep Parhar pcap_close(pd); 34001131c927SNavdeep Parhar fclose(fp); 34011131c927SNavdeep Parhar if (rc != 0) { 34021131c927SNavdeep Parhar free_offload_policy(op); 34031131c927SNavdeep Parhar } 34041131c927SNavdeep Parhar 34051131c927SNavdeep Parhar return (rc); 34061131c927SNavdeep Parhar } 34071131c927SNavdeep Parhar 34081131c927SNavdeep Parhar static int 34091131c927SNavdeep Parhar load_offload_policy(int argc, const char *argv[]) 34101131c927SNavdeep Parhar { 34111131c927SNavdeep Parhar int rc = 0; 34121131c927SNavdeep Parhar const char *fname = argv[0]; 34131131c927SNavdeep Parhar struct t4_offload_policy op = {0}; 34141131c927SNavdeep Parhar 34151131c927SNavdeep Parhar if (argc != 1) { 34161131c927SNavdeep Parhar warnx("incorrect number of arguments."); 34171131c927SNavdeep Parhar return (EINVAL); 34181131c927SNavdeep Parhar } 34191131c927SNavdeep Parhar 34201131c927SNavdeep Parhar if (!strcmp(fname, "clear") || !strcmp(fname, "none")) { 34211131c927SNavdeep Parhar /* op.nrules is 0 and that means clear policy */ 34221131c927SNavdeep Parhar return (doit(CHELSIO_T4_SET_OFLD_POLICY, &op)); 34231131c927SNavdeep Parhar } 34241131c927SNavdeep Parhar 34251131c927SNavdeep Parhar rc = parse_offload_policy(fname, &op); 34261131c927SNavdeep Parhar if (rc != 0) { 34271131c927SNavdeep Parhar /* Error message displayed already */ 34281131c927SNavdeep Parhar return (EINVAL); 34291131c927SNavdeep Parhar } 34301131c927SNavdeep Parhar 34311131c927SNavdeep Parhar rc = doit(CHELSIO_T4_SET_OFLD_POLICY, &op); 34321131c927SNavdeep Parhar free_offload_policy(&op); 34331131c927SNavdeep Parhar 34341131c927SNavdeep Parhar return (rc); 34351131c927SNavdeep Parhar } 34361131c927SNavdeep Parhar 34371131c927SNavdeep Parhar static int 343854912308SNavdeep Parhar run_cmd(int argc, const char *argv[]) 343954912308SNavdeep Parhar { 344054912308SNavdeep Parhar int rc = -1; 344154912308SNavdeep Parhar const char *cmd = argv[0]; 344254912308SNavdeep Parhar 344354912308SNavdeep Parhar /* command */ 344454912308SNavdeep Parhar argc--; 344554912308SNavdeep Parhar argv++; 344654912308SNavdeep Parhar 344754912308SNavdeep Parhar if (!strcmp(cmd, "reg") || !strcmp(cmd, "reg32")) 344854912308SNavdeep Parhar rc = register_io(argc, argv, 4); 344954912308SNavdeep Parhar else if (!strcmp(cmd, "reg64")) 345054912308SNavdeep Parhar rc = register_io(argc, argv, 8); 345154912308SNavdeep Parhar else if (!strcmp(cmd, "regdump")) 345254912308SNavdeep Parhar rc = dump_regs(argc, argv); 345354912308SNavdeep Parhar else if (!strcmp(cmd, "filter")) 345436ea2fe3SNavdeep Parhar rc = filter_cmd(argc, argv, 0); 345554912308SNavdeep Parhar else if (!strcmp(cmd, "context")) 345654912308SNavdeep Parhar rc = get_sge_context(argc, argv); 345754912308SNavdeep Parhar else if (!strcmp(cmd, "loadfw")) 345854912308SNavdeep Parhar rc = loadfw(argc, argv); 345954912308SNavdeep Parhar else if (!strcmp(cmd, "memdump")) 346054912308SNavdeep Parhar rc = memdump(argc, argv); 346154912308SNavdeep Parhar else if (!strcmp(cmd, "tcb")) 346254912308SNavdeep Parhar rc = read_tcb(argc, argv); 346354912308SNavdeep Parhar else if (!strcmp(cmd, "i2c")) 346454912308SNavdeep Parhar rc = read_i2c(argc, argv); 346554912308SNavdeep Parhar else if (!strcmp(cmd, "clearstats")) 346654912308SNavdeep Parhar rc = clearstats(argc, argv); 346754912308SNavdeep Parhar else if (!strcmp(cmd, "tracer")) 346854912308SNavdeep Parhar rc = tracer_cmd(argc, argv); 346954912308SNavdeep Parhar else if (!strcmp(cmd, "modinfo")) 347054912308SNavdeep Parhar rc = modinfo(argc, argv); 347154912308SNavdeep Parhar else if (!strcmp(cmd, "sched-class")) 347254912308SNavdeep Parhar rc = sched_class(argc, argv); 347354912308SNavdeep Parhar else if (!strcmp(cmd, "sched-queue")) 347454912308SNavdeep Parhar rc = sched_queue(argc, argv); 347554912308SNavdeep Parhar else if (!strcmp(cmd, "loadcfg")) 347654912308SNavdeep Parhar rc = loadcfg(argc, argv); 34778f82718fSNavdeep Parhar else if (!strcmp(cmd, "loadboot")) 34788f82718fSNavdeep Parhar rc = loadboot(argc, argv); 34798f82718fSNavdeep Parhar else if (!strcmp(cmd, "loadboot-cfg")) 34808f82718fSNavdeep Parhar rc = loadbootcfg(argc, argv); 3481f856f099SNavdeep Parhar else if (!strcmp(cmd, "dumpstate")) 3482f856f099SNavdeep Parhar rc = dumpstate(argc, argv); 34831131c927SNavdeep Parhar else if (!strcmp(cmd, "policy")) 34841131c927SNavdeep Parhar rc = load_offload_policy(argc, argv); 348536ea2fe3SNavdeep Parhar else if (!strcmp(cmd, "hashfilter")) 348636ea2fe3SNavdeep Parhar rc = filter_cmd(argc, argv, 1); 348754912308SNavdeep Parhar else { 348854912308SNavdeep Parhar rc = EINVAL; 348954912308SNavdeep Parhar warnx("invalid command \"%s\"", cmd); 349054912308SNavdeep Parhar } 349154912308SNavdeep Parhar 349254912308SNavdeep Parhar return (rc); 349354912308SNavdeep Parhar } 349454912308SNavdeep Parhar 349554912308SNavdeep Parhar #define MAX_ARGS 15 349654912308SNavdeep Parhar static int 349754912308SNavdeep Parhar run_cmd_loop(void) 349854912308SNavdeep Parhar { 349954912308SNavdeep Parhar int i, rc = 0; 350054912308SNavdeep Parhar char buffer[128], *buf; 350154912308SNavdeep Parhar const char *args[MAX_ARGS + 1]; 350254912308SNavdeep Parhar 350354912308SNavdeep Parhar /* 350454912308SNavdeep Parhar * Simple loop: displays a "> " prompt and processes any input as a 350554912308SNavdeep Parhar * cxgbetool command. You're supposed to enter only the part after 350654912308SNavdeep Parhar * "cxgbetool t4nexX". Use "quit" or "exit" to exit. 350754912308SNavdeep Parhar */ 350854912308SNavdeep Parhar for (;;) { 350954912308SNavdeep Parhar fprintf(stdout, "> "); 351054912308SNavdeep Parhar fflush(stdout); 351154912308SNavdeep Parhar buf = fgets(buffer, sizeof(buffer), stdin); 351254912308SNavdeep Parhar if (buf == NULL) { 351354912308SNavdeep Parhar if (ferror(stdin)) { 351454912308SNavdeep Parhar warn("stdin error"); 351554912308SNavdeep Parhar rc = errno; /* errno from fgets */ 351654912308SNavdeep Parhar } 351754912308SNavdeep Parhar break; 351854912308SNavdeep Parhar } 351954912308SNavdeep Parhar 352054912308SNavdeep Parhar i = 0; 352154912308SNavdeep Parhar while ((args[i] = strsep(&buf, " \t\n")) != NULL) { 352254912308SNavdeep Parhar if (args[i][0] != 0 && ++i == MAX_ARGS) 352354912308SNavdeep Parhar break; 352454912308SNavdeep Parhar } 352554912308SNavdeep Parhar args[i] = 0; 352654912308SNavdeep Parhar 352754912308SNavdeep Parhar if (i == 0) 352854912308SNavdeep Parhar continue; /* skip empty line */ 352954912308SNavdeep Parhar 353054912308SNavdeep Parhar if (!strcmp(args[0], "quit") || !strcmp(args[0], "exit")) 353154912308SNavdeep Parhar break; 353254912308SNavdeep Parhar 353354912308SNavdeep Parhar rc = run_cmd(i, args); 353454912308SNavdeep Parhar } 353554912308SNavdeep Parhar 353654912308SNavdeep Parhar /* rc normally comes from the last command (not including quit/exit) */ 353754912308SNavdeep Parhar return (rc); 353854912308SNavdeep Parhar } 353954912308SNavdeep Parhar 354054912308SNavdeep Parhar int 354154912308SNavdeep Parhar main(int argc, const char *argv[]) 354254912308SNavdeep Parhar { 354354912308SNavdeep Parhar int rc = -1; 354454912308SNavdeep Parhar 354554912308SNavdeep Parhar progname = argv[0]; 354654912308SNavdeep Parhar 354754912308SNavdeep Parhar if (argc == 2) { 354854912308SNavdeep Parhar if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { 354954912308SNavdeep Parhar usage(stdout); 355054912308SNavdeep Parhar exit(0); 355154912308SNavdeep Parhar } 355254912308SNavdeep Parhar } 355354912308SNavdeep Parhar 355454912308SNavdeep Parhar if (argc < 3) { 355554912308SNavdeep Parhar usage(stderr); 355654912308SNavdeep Parhar exit(EINVAL); 355754912308SNavdeep Parhar } 355854912308SNavdeep Parhar 355954912308SNavdeep Parhar nexus = argv[1]; 356054912308SNavdeep Parhar 356154912308SNavdeep Parhar /* progname and nexus */ 356254912308SNavdeep Parhar argc -= 2; 356354912308SNavdeep Parhar argv += 2; 356454912308SNavdeep Parhar 356554912308SNavdeep Parhar if (argc == 1 && !strcmp(argv[0], "stdio")) 356654912308SNavdeep Parhar rc = run_cmd_loop(); 356754912308SNavdeep Parhar else 356854912308SNavdeep Parhar rc = run_cmd(argc, argv); 356954912308SNavdeep Parhar 357054912308SNavdeep Parhar return (rc); 357154912308SNavdeep Parhar } 3572