1167518Skmacy/************************************************************************** 2167518Skmacy 3207643SnpCopyright (c) 2007-2010, Chelsio Inc. 4167518SkmacyAll rights reserved. 5167518Skmacy 6167518SkmacyRedistribution and use in source and binary forms, with or without 7167518Skmacymodification, are permitted provided that the following conditions are met: 8167518Skmacy 9167518Skmacy 1. Redistributions of source code must retain the above copyright notice, 10167518Skmacy this list of conditions and the following disclaimer. 11167518Skmacy 12167518Skmacy 2. Redistributions in binary form must reproduce the above copyright 13167518Skmacy notice, this list of conditions and the following disclaimer in the 14167518Skmacy documentation and/or other materials provided with the distribution. 15167518Skmacy 16167518Skmacy 3. Neither the name of the Chelsio Corporation nor the names of its 17167518Skmacy contributors may be used to endorse or promote products derived from 18167518Skmacy this software without specific prior written permission. 19167518Skmacy 20167518SkmacyTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21167518SkmacyAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22167518SkmacyIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23167518SkmacyARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24167518SkmacyLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25167518SkmacyCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26167518SkmacySUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27167518SkmacyINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28167518SkmacyCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29167518SkmacyARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30167518SkmacyPOSSIBILITY OF SUCH DAMAGE. 31167518Skmacy 32167518Skmacy 33167518Skmacy***************************************************************************/ 34167518Skmacy#include <sys/cdefs.h> 35167518Skmacy__FBSDID("$FreeBSD$"); 36167518Skmacy 37167518Skmacy#include <stdlib.h> 38167518Skmacy#include <stdio.h> 39167518Skmacy#include <stdint.h> 40167518Skmacy#include <string.h> 41167518Skmacy#include <unistd.h> 42167518Skmacy#include <fcntl.h> 43167518Skmacy#include <err.h> 44167518Skmacy#include <errno.h> 45167518Skmacy#include <inttypes.h> 46167518Skmacy#include <sys/param.h> 47167518Skmacy#include <sys/time.h> 48167518Skmacy#include <sys/ioctl.h> 49167518Skmacy#include <sys/socket.h> 50167518Skmacy 51167518Skmacy#include <netinet/in.h> 52167518Skmacy#include <arpa/inet.h> 53167518Skmacy 54167518Skmacy#include <net/if.h> 55167518Skmacy#include <net/if_var.h> 56167518Skmacy#include <net/if_types.h> 57182899Skmacy#include <sys/endian.h> 58167518Skmacy 59167518Skmacy#define NMTUS 16 60167518Skmacy#define TCB_SIZE 128 61167518Skmacy#define TCB_WORDS (TCB_SIZE / 4) 62167518Skmacy#define PROTO_SRAM_LINES 128 63167518Skmacy#define PROTO_SRAM_LINE_BITS 132 64167518Skmacy#define PROTO_SRAM_LINE_NIBBLES (132 / 4) 65167518Skmacy#define PROTO_SRAM_SIZE (PROTO_SRAM_LINE_NIBBLES * PROTO_SRAM_LINES / 2) 66167518Skmacy#define PROTO_SRAM_EEPROM_ADDR 4096 67167518Skmacy 68167589Skmacy#include <cxgb_ioctl.h> 69167589Skmacy#include <common/cxgb_regs.h> 70167518Skmacy#include "version.h" 71167518Skmacy 72167518Skmacystruct reg_info { 73167518Skmacy const char *name; 74167518Skmacy uint16_t addr; 75167518Skmacy uint16_t len; 76167518Skmacy}; 77167518Skmacy 78167518Skmacy 79167518Skmacy#include "reg_defs.c" 80167518Skmacy#if defined(CONFIG_T3_REGS) 81167518Skmacy# include "reg_defs_t3.c" 82167518Skmacy# include "reg_defs_t3b.c" 83182594Skmacy# include "reg_defs_t3c.c" 84167518Skmacy#endif 85167518Skmacy 86167518Skmacystatic const char *progname; 87167518Skmacy 88204267Snpstatic void 89204267Snpusage(FILE *fp) 90167518Skmacy{ 91167518Skmacy fprintf(fp, "Usage: %s <interface> [operation]\n", progname); 92167518Skmacy fprintf(fp, 93182594Skmacy "\tclearstats clear MAC statistics\n" 94182594Skmacy "\tcontext <type> <id> show an SGE context\n" 95182594Skmacy "\tdesc <qset> <queue> <idx> [<cnt>] dump SGE descriptors\n" 96207643Snp "\tfilter <idx> [<param> <val>] ... set a filter\n" 97207643Snp "\tfilter <idx> delete|clear delete a filter\n" 98207643Snp "\tfilter list list all filters\n" 99189643Sgnn "\tioqs dump uP IOQs\n" 100189643Sgnn "\tla dump uP logic analyzer info\n" 101182594Skmacy "\tloadboot <boot image> download boot image\n" 102182594Skmacy "\tloadfw <FW image> download firmware\n" 103167518Skmacy "\tmdio <phy_addr> <mmd_addr>\n" 104167518Skmacy "\t <reg_addr> [<val>] read/write MDIO register\n" 105182594Skmacy "\tmemdump cm|tx|rx <addr> <len> dump a mem range\n" 106182594Skmacy "\tmeminfo show memory info\n" 107167518Skmacy "\tmtus [<mtu0>...<mtuN>] read/write MTU table\n" 108182594Skmacy "\tpktsched port <idx> <min> <max> set TX port scheduler params\n" 109182594Skmacy "\tpktsched tunnelq <idx> <max>\n" 110182594Skmacy "\t <binding> set TX tunnelq scheduler params\n" 111182594Skmacy "\tpktsched tx <idx>\n" 112182594Skmacy "\t [<param> <val>] ... set Tx HW scheduler\n" 113167518Skmacy "\tpm [<TX page spec> <RX page spec>] read/write PM config\n" 114182594Skmacy "\tproto read proto SRAM\n" 115182594Skmacy "\tqset read qset parameters\n" 116182594Skmacy "\tqsets read # of qsets\n" 117182594Skmacy "\treg <address>[=<val>] read/write register\n" 118167518Skmacy "\tregdump [<module>] dump registers\n" 119167518Skmacy "\ttcamdump <address> <count> show TCAM contents\n" 120182594Skmacy "\ttcb <index> read TCB\n" 121167518Skmacy "\ttrace tx|rx|all on|off [not]\n" 122167518Skmacy "\t [<param> <val>[:<mask>]] ... write trace parameters\n" 123167518Skmacy ); 124167518Skmacy exit(fp == stderr ? 1 : 0); 125167518Skmacy} 126167518Skmacy 127167518Skmacystatic int 128167518Skmacydoit(const char *iff_name, unsigned long cmd, void *data) 129167518Skmacy{ 130167518Skmacy static int fd = 0; 131167518Skmacy 132167518Skmacy if (fd == 0) { 133167518Skmacy char buf[64]; 134167518Skmacy snprintf(buf, 64, "/dev/%s", iff_name); 135167518Skmacy 136167518Skmacy if ((fd = open(buf, O_RDWR)) < 0) 137182594Skmacy return -1; 138167518Skmacy } 139167518Skmacy 140167518Skmacy return ioctl(fd, cmd, data) < 0 ? -1 : 0; 141167518Skmacy} 142167518Skmacy 143204267Snpstatic int 144204267Snpget_int_arg(const char *s, uint32_t *valp) 145167518Skmacy{ 146167518Skmacy char *p; 147167518Skmacy 148167518Skmacy *valp = strtoul(s, &p, 0); 149167518Skmacy if (*p) { 150167518Skmacy warnx("bad parameter \"%s\"", s); 151167518Skmacy return -1; 152167518Skmacy } 153167518Skmacy return 0; 154167518Skmacy} 155167518Skmacy 156167518Skmacystatic uint32_t 157167518Skmacyread_reg(const char *iff_name, uint32_t addr) 158167518Skmacy{ 159167518Skmacy struct ch_reg reg; 160167518Skmacy 161167518Skmacy reg.addr = addr; 162167518Skmacy 163167518Skmacy if (doit(iff_name, CHELSIO_GETREG, ®) < 0) 164167518Skmacy err(1, "register read"); 165167518Skmacy return reg.val; 166167518Skmacy} 167167518Skmacy 168167518Skmacystatic void 169167518Skmacywrite_reg(const char *iff_name, uint32_t addr, uint32_t val) 170167518Skmacy{ 171167518Skmacy struct ch_reg ch_reg; 172167518Skmacy 173167518Skmacy ch_reg.addr = addr; 174167518Skmacy ch_reg.val = val; 175167518Skmacy 176167518Skmacy if (doit(iff_name, CHELSIO_SETREG, &ch_reg) < 0) 177167518Skmacy err(1, "register write"); 178167518Skmacy} 179167518Skmacy 180204267Snpstatic int 181204267Snpregister_io(int argc, char *argv[], int start_arg, 182167518Skmacy const char *iff_name) 183167518Skmacy{ 184167518Skmacy char *p; 185204267Snp uint32_t addr, val = 0, w = 0; 186167518Skmacy 187167518Skmacy if (argc != start_arg + 1) return -1; 188167518Skmacy 189167518Skmacy addr = strtoul(argv[start_arg], &p, 0); 190167518Skmacy if (p == argv[start_arg]) return -1; 191167518Skmacy if (*p == '=' && p[1]) { 192167518Skmacy val = strtoul(p + 1, &p, 0); 193204267Snp w = 1; 194167518Skmacy } 195167518Skmacy if (*p) { 196167518Skmacy warnx("bad parameter \"%s\"", argv[start_arg]); 197167518Skmacy return -1; 198167518Skmacy } 199167518Skmacy 200204267Snp if (w) 201167518Skmacy write_reg(iff_name, addr, val); 202167518Skmacy else { 203167518Skmacy val = read_reg(iff_name, addr); 204167518Skmacy printf("%#x [%u]\n", val, val); 205167518Skmacy } 206167518Skmacy return 0; 207167518Skmacy} 208167518Skmacy 209204267Snpstatic int 210204267Snpmdio_io(int argc, char *argv[], int start_arg, const char *iff_name) 211167518Skmacy{ 212182594Skmacy struct ch_mii_data p; 213167518Skmacy unsigned int cmd, phy_addr, reg, mmd, val; 214167518Skmacy 215167518Skmacy if (argc == start_arg + 3) 216182594Skmacy cmd = CHELSIO_GET_MIIREG; 217167518Skmacy else if (argc == start_arg + 4) 218182594Skmacy cmd = CHELSIO_SET_MIIREG; 219167518Skmacy else 220167518Skmacy return -1; 221167518Skmacy 222167518Skmacy if (get_int_arg(argv[start_arg], &phy_addr) || 223167518Skmacy get_int_arg(argv[start_arg + 1], &mmd) || 224167518Skmacy get_int_arg(argv[start_arg + 2], ®) || 225182594Skmacy (cmd == CHELSIO_SET_MIIREG && get_int_arg(argv[start_arg + 3], &val))) 226167518Skmacy return -1; 227167518Skmacy 228167518Skmacy p.phy_id = phy_addr | (mmd << 8); 229167518Skmacy p.reg_num = reg; 230167518Skmacy p.val_in = val; 231167518Skmacy 232167518Skmacy if (doit(iff_name, cmd, &p) < 0) 233182594Skmacy err(1, "MDIO %s", cmd == CHELSIO_GET_MIIREG ? "read" : "write"); 234182594Skmacy if (cmd == CHELSIO_GET_MIIREG) 235167518Skmacy printf("%#x [%u]\n", p.val_out, p.val_out); 236167518Skmacy return 0; 237167518Skmacy} 238167518Skmacy 239204267Snpstatic inline 240204267Snpuint32_t xtract(uint32_t val, int shift, int len) 241167518Skmacy{ 242167518Skmacy return (val >> shift) & ((1 << len) - 1); 243167518Skmacy} 244167518Skmacy 245204267Snpstatic int 246204267Snpdump_block_regs(const struct reg_info *reg_array, uint32_t *regs) 247167518Skmacy{ 248167518Skmacy uint32_t reg_val = 0; // silence compiler warning 249167518Skmacy 250167518Skmacy for ( ; reg_array->name; ++reg_array) 251167518Skmacy if (!reg_array->len) { 252167518Skmacy reg_val = regs[reg_array->addr / 4]; 253167518Skmacy printf("[%#5x] %-40s %#-10x [%u]\n", reg_array->addr, 254167518Skmacy reg_array->name, reg_val, reg_val); 255167518Skmacy } else { 256167518Skmacy uint32_t v = xtract(reg_val, reg_array->addr, 257167518Skmacy reg_array->len); 258167518Skmacy 259167518Skmacy printf(" %-40s %#-10x [%u]\n", reg_array->name, 260167518Skmacy v, v); 261167518Skmacy } 262167518Skmacy return 1; 263167518Skmacy} 264167518Skmacy 265204267Snpstatic int 266204267Snpdump_regs_t2(int argc, char *argv[], int start_arg, uint32_t *regs) 267167518Skmacy{ 268167518Skmacy int match = 0; 269167518Skmacy char *block_name = NULL; 270167518Skmacy 271167518Skmacy if (argc == start_arg + 1) 272167518Skmacy block_name = argv[start_arg]; 273167518Skmacy else if (argc != start_arg) 274167518Skmacy return -1; 275167518Skmacy 276167518Skmacy if (!block_name || !strcmp(block_name, "sge")) 277167518Skmacy match += dump_block_regs(sge_regs, regs); 278167518Skmacy if (!block_name || !strcmp(block_name, "mc3")) 279167518Skmacy match += dump_block_regs(mc3_regs, regs); 280167518Skmacy if (!block_name || !strcmp(block_name, "mc4")) 281167518Skmacy match += dump_block_regs(mc4_regs, regs); 282167518Skmacy if (!block_name || !strcmp(block_name, "tpi")) 283167518Skmacy match += dump_block_regs(tpi_regs, regs); 284167518Skmacy if (!block_name || !strcmp(block_name, "tp")) 285167518Skmacy match += dump_block_regs(tp_regs, regs); 286167518Skmacy if (!block_name || !strcmp(block_name, "rat")) 287167518Skmacy match += dump_block_regs(rat_regs, regs); 288167518Skmacy if (!block_name || !strcmp(block_name, "cspi")) 289167518Skmacy match += dump_block_regs(cspi_regs, regs); 290167518Skmacy if (!block_name || !strcmp(block_name, "espi")) 291167518Skmacy match += dump_block_regs(espi_regs, regs); 292167518Skmacy if (!block_name || !strcmp(block_name, "ulp")) 293167518Skmacy match += dump_block_regs(ulp_regs, regs); 294167518Skmacy if (!block_name || !strcmp(block_name, "pl")) 295167518Skmacy match += dump_block_regs(pl_regs, regs); 296167518Skmacy if (!block_name || !strcmp(block_name, "mc5")) 297167518Skmacy match += dump_block_regs(mc5_regs, regs); 298167518Skmacy if (!match) 299167518Skmacy errx(1, "unknown block \"%s\"", block_name); 300167518Skmacy return 0; 301167518Skmacy} 302167518Skmacy 303167518Skmacy#if defined(CONFIG_T3_REGS) 304204267Snpstatic int 305204267Snpdump_regs_t3(int argc, char *argv[], int start_arg, uint32_t *regs, int is_pcie) 306167518Skmacy{ 307167518Skmacy int match = 0; 308167518Skmacy char *block_name = NULL; 309167518Skmacy 310167518Skmacy if (argc == start_arg + 1) 311167518Skmacy block_name = argv[start_arg]; 312167518Skmacy else if (argc != start_arg) 313167518Skmacy return -1; 314167518Skmacy 315167518Skmacy if (!block_name || !strcmp(block_name, "sge")) 316167518Skmacy match += dump_block_regs(sge3_regs, regs); 317167518Skmacy if (!block_name || !strcmp(block_name, "pci")) 318167518Skmacy match += dump_block_regs(is_pcie ? pcie0_regs : pcix1_regs, 319167518Skmacy regs); 320167518Skmacy if (!block_name || !strcmp(block_name, "t3dbg")) 321167518Skmacy match += dump_block_regs(t3dbg_regs, regs); 322167518Skmacy if (!block_name || !strcmp(block_name, "pmrx")) 323167518Skmacy match += dump_block_regs(mc7_pmrx_regs, regs); 324167518Skmacy if (!block_name || !strcmp(block_name, "pmtx")) 325167518Skmacy match += dump_block_regs(mc7_pmtx_regs, regs); 326167518Skmacy if (!block_name || !strcmp(block_name, "cm")) 327167518Skmacy match += dump_block_regs(mc7_cm_regs, regs); 328167518Skmacy if (!block_name || !strcmp(block_name, "cim")) 329167518Skmacy match += dump_block_regs(cim_regs, regs); 330167518Skmacy if (!block_name || !strcmp(block_name, "tp")) 331167518Skmacy match += dump_block_regs(tp1_regs, regs); 332167518Skmacy if (!block_name || !strcmp(block_name, "ulp_rx")) 333167518Skmacy match += dump_block_regs(ulp2_rx_regs, regs); 334167518Skmacy if (!block_name || !strcmp(block_name, "ulp_tx")) 335167518Skmacy match += dump_block_regs(ulp2_tx_regs, regs); 336167518Skmacy if (!block_name || !strcmp(block_name, "pmrx")) 337167518Skmacy match += dump_block_regs(pm1_rx_regs, regs); 338167518Skmacy if (!block_name || !strcmp(block_name, "pmtx")) 339167518Skmacy match += dump_block_regs(pm1_tx_regs, regs); 340167518Skmacy if (!block_name || !strcmp(block_name, "mps")) 341167518Skmacy match += dump_block_regs(mps0_regs, regs); 342167518Skmacy if (!block_name || !strcmp(block_name, "cplsw")) 343167518Skmacy match += dump_block_regs(cpl_switch_regs, regs); 344167518Skmacy if (!block_name || !strcmp(block_name, "smb")) 345167518Skmacy match += dump_block_regs(smb0_regs, regs); 346167518Skmacy if (!block_name || !strcmp(block_name, "i2c")) 347167518Skmacy match += dump_block_regs(i2cm0_regs, regs); 348167518Skmacy if (!block_name || !strcmp(block_name, "mi1")) 349167518Skmacy match += dump_block_regs(mi1_regs, regs); 350167518Skmacy if (!block_name || !strcmp(block_name, "sf")) 351167518Skmacy match += dump_block_regs(sf1_regs, regs); 352167518Skmacy if (!block_name || !strcmp(block_name, "pl")) 353167518Skmacy match += dump_block_regs(pl3_regs, regs); 354167518Skmacy if (!block_name || !strcmp(block_name, "mc5")) 355167518Skmacy match += dump_block_regs(mc5a_regs, regs); 356167518Skmacy if (!block_name || !strcmp(block_name, "xgmac0")) 357167518Skmacy match += dump_block_regs(xgmac0_0_regs, regs); 358167518Skmacy if (!block_name || !strcmp(block_name, "xgmac1")) 359167518Skmacy match += dump_block_regs(xgmac0_1_regs, regs); 360167518Skmacy if (!match) 361167518Skmacy errx(1, "unknown block \"%s\"", block_name); 362167518Skmacy return 0; 363167518Skmacy} 364167518Skmacy 365204267Snpstatic int 366204267Snpdump_regs_t3b(int argc, char *argv[], int start_arg, uint32_t *regs, 367204267Snp int is_pcie) 368167518Skmacy{ 369167518Skmacy int match = 0; 370167518Skmacy char *block_name = NULL; 371167518Skmacy 372167518Skmacy if (argc == start_arg + 1) 373167518Skmacy block_name = argv[start_arg]; 374167518Skmacy else if (argc != start_arg) 375167518Skmacy return -1; 376167518Skmacy 377167518Skmacy if (!block_name || !strcmp(block_name, "sge")) 378167518Skmacy match += dump_block_regs(t3b_sge3_regs, regs); 379167518Skmacy if (!block_name || !strcmp(block_name, "pci")) 380167518Skmacy match += dump_block_regs(is_pcie ? t3b_pcie0_regs : 381167518Skmacy t3b_pcix1_regs, regs); 382167518Skmacy if (!block_name || !strcmp(block_name, "t3dbg")) 383167518Skmacy match += dump_block_regs(t3b_t3dbg_regs, regs); 384167518Skmacy if (!block_name || !strcmp(block_name, "pmrx")) 385167518Skmacy match += dump_block_regs(t3b_mc7_pmrx_regs, regs); 386167518Skmacy if (!block_name || !strcmp(block_name, "pmtx")) 387167518Skmacy match += dump_block_regs(t3b_mc7_pmtx_regs, regs); 388167518Skmacy if (!block_name || !strcmp(block_name, "cm")) 389167518Skmacy match += dump_block_regs(t3b_mc7_cm_regs, regs); 390167518Skmacy if (!block_name || !strcmp(block_name, "cim")) 391167518Skmacy match += dump_block_regs(t3b_cim_regs, regs); 392167518Skmacy if (!block_name || !strcmp(block_name, "tp")) 393167518Skmacy match += dump_block_regs(t3b_tp1_regs, regs); 394167518Skmacy if (!block_name || !strcmp(block_name, "ulp_rx")) 395167518Skmacy match += dump_block_regs(t3b_ulp2_rx_regs, regs); 396167518Skmacy if (!block_name || !strcmp(block_name, "ulp_tx")) 397167518Skmacy match += dump_block_regs(t3b_ulp2_tx_regs, regs); 398167518Skmacy if (!block_name || !strcmp(block_name, "pmrx")) 399167518Skmacy match += dump_block_regs(t3b_pm1_rx_regs, regs); 400167518Skmacy if (!block_name || !strcmp(block_name, "pmtx")) 401167518Skmacy match += dump_block_regs(t3b_pm1_tx_regs, regs); 402167518Skmacy if (!block_name || !strcmp(block_name, "mps")) 403167518Skmacy match += dump_block_regs(t3b_mps0_regs, regs); 404167518Skmacy if (!block_name || !strcmp(block_name, "cplsw")) 405167518Skmacy match += dump_block_regs(t3b_cpl_switch_regs, regs); 406167518Skmacy if (!block_name || !strcmp(block_name, "smb")) 407167518Skmacy match += dump_block_regs(t3b_smb0_regs, regs); 408167518Skmacy if (!block_name || !strcmp(block_name, "i2c")) 409167518Skmacy match += dump_block_regs(t3b_i2cm0_regs, regs); 410167518Skmacy if (!block_name || !strcmp(block_name, "mi1")) 411167518Skmacy match += dump_block_regs(t3b_mi1_regs, regs); 412167518Skmacy if (!block_name || !strcmp(block_name, "sf")) 413167518Skmacy match += dump_block_regs(t3b_sf1_regs, regs); 414167518Skmacy if (!block_name || !strcmp(block_name, "pl")) 415167518Skmacy match += dump_block_regs(t3b_pl3_regs, regs); 416167518Skmacy if (!block_name || !strcmp(block_name, "mc5")) 417167518Skmacy match += dump_block_regs(t3b_mc5a_regs, regs); 418167518Skmacy if (!block_name || !strcmp(block_name, "xgmac0")) 419167518Skmacy match += dump_block_regs(t3b_xgmac0_0_regs, regs); 420167518Skmacy if (!block_name || !strcmp(block_name, "xgmac1")) 421167518Skmacy match += dump_block_regs(t3b_xgmac0_1_regs, regs); 422167518Skmacy if (!match) 423167518Skmacy errx(1, "unknown block \"%s\"", block_name); 424167518Skmacy return 0; 425167518Skmacy} 426182594Skmacy 427204267Snpstatic int 428204267Snpdump_regs_t3c(int argc, char *argv[], int start_arg, uint32_t *regs, 429204267Snp int is_pcie) 430182594Skmacy{ 431182594Skmacy int match = 0; 432182594Skmacy char *block_name = NULL; 433182594Skmacy 434182594Skmacy if (argc == start_arg + 1) 435182594Skmacy block_name = argv[start_arg]; 436182594Skmacy else if (argc != start_arg) 437182594Skmacy return -1; 438182594Skmacy 439182594Skmacy if (!block_name || !strcmp(block_name, "sge")) 440182594Skmacy match += dump_block_regs(t3c_sge3_regs, regs); 441182594Skmacy if (!block_name || !strcmp(block_name, "pci")) 442182594Skmacy match += dump_block_regs(is_pcie ? t3c_pcie0_regs : 443182594Skmacy t3c_pcix1_regs, regs); 444182594Skmacy if (!block_name || !strcmp(block_name, "t3dbg")) 445182594Skmacy match += dump_block_regs(t3c_t3dbg_regs, regs); 446182594Skmacy if (!block_name || !strcmp(block_name, "pmrx")) 447182594Skmacy match += dump_block_regs(t3c_mc7_pmrx_regs, regs); 448182594Skmacy if (!block_name || !strcmp(block_name, "pmtx")) 449182594Skmacy match += dump_block_regs(t3c_mc7_pmtx_regs, regs); 450182594Skmacy if (!block_name || !strcmp(block_name, "cm")) 451182594Skmacy match += dump_block_regs(t3c_mc7_cm_regs, regs); 452182594Skmacy if (!block_name || !strcmp(block_name, "cim")) 453182594Skmacy match += dump_block_regs(t3c_cim_regs, regs); 454182594Skmacy if (!block_name || !strcmp(block_name, "tp")) 455182594Skmacy match += dump_block_regs(t3c_tp1_regs, regs); 456182594Skmacy if (!block_name || !strcmp(block_name, "ulp_rx")) 457182594Skmacy match += dump_block_regs(t3c_ulp2_rx_regs, regs); 458182594Skmacy if (!block_name || !strcmp(block_name, "ulp_tx")) 459182594Skmacy match += dump_block_regs(t3c_ulp2_tx_regs, regs); 460182594Skmacy if (!block_name || !strcmp(block_name, "pmrx")) 461182594Skmacy match += dump_block_regs(t3c_pm1_rx_regs, regs); 462182594Skmacy if (!block_name || !strcmp(block_name, "pmtx")) 463182594Skmacy match += dump_block_regs(t3c_pm1_tx_regs, regs); 464182594Skmacy if (!block_name || !strcmp(block_name, "mps")) 465182594Skmacy match += dump_block_regs(t3c_mps0_regs, regs); 466182594Skmacy if (!block_name || !strcmp(block_name, "cplsw")) 467182594Skmacy match += dump_block_regs(t3c_cpl_switch_regs, regs); 468182594Skmacy if (!block_name || !strcmp(block_name, "smb")) 469182594Skmacy match += dump_block_regs(t3c_smb0_regs, regs); 470182594Skmacy if (!block_name || !strcmp(block_name, "i2c")) 471182594Skmacy match += dump_block_regs(t3c_i2cm0_regs, regs); 472182594Skmacy if (!block_name || !strcmp(block_name, "mi1")) 473182594Skmacy match += dump_block_regs(t3c_mi1_regs, regs); 474182594Skmacy if (!block_name || !strcmp(block_name, "sf")) 475182594Skmacy match += dump_block_regs(t3c_sf1_regs, regs); 476182594Skmacy if (!block_name || !strcmp(block_name, "pl")) 477182594Skmacy match += dump_block_regs(t3c_pl3_regs, regs); 478182594Skmacy if (!block_name || !strcmp(block_name, "mc5")) 479182594Skmacy match += dump_block_regs(t3c_mc5a_regs, regs); 480182594Skmacy if (!block_name || !strcmp(block_name, "xgmac0")) 481182594Skmacy match += dump_block_regs(t3c_xgmac0_0_regs, regs); 482182594Skmacy if (!block_name || !strcmp(block_name, "xgmac1")) 483182594Skmacy match += dump_block_regs(t3c_xgmac0_1_regs, regs); 484182594Skmacy if (!match) 485182594Skmacy errx(1, "unknown block \"%s\"", block_name); 486182594Skmacy return 0; 487182594Skmacy} 488167518Skmacy#endif 489167518Skmacy 490167518Skmacystatic int 491167518Skmacydump_regs(int argc, char *argv[], int start_arg, const char *iff_name) 492167518Skmacy{ 493204267Snp int vers, revision, is_pcie; 494182594Skmacy struct ch_ifconf_regs regs; 495167518Skmacy 496167518Skmacy regs.len = REGDUMP_SIZE; 497167518Skmacy 498182594Skmacy /* XXX: This is never freed. Looks like we don't care. */ 499182594Skmacy if ((regs.data = malloc(regs.len)) == NULL) 500167518Skmacy err(1, "can't malloc"); 501167518Skmacy 502167518Skmacy if (doit(iff_name, CHELSIO_IFCONF_GETREGS, ®s)) 503167518Skmacy err(1, "can't read registers"); 504167518Skmacy 505167518Skmacy vers = regs.version & 0x3ff; 506167518Skmacy revision = (regs.version >> 10) & 0x3f; 507167518Skmacy is_pcie = (regs.version & 0x80000000) != 0; 508167518Skmacy 509167518Skmacy if (vers <= 2) 510167518Skmacy return dump_regs_t2(argc, argv, start_arg, (uint32_t *)regs.data); 511167518Skmacy#if defined(CONFIG_T3_REGS) 512167518Skmacy if (vers == 3) { 513167518Skmacy if (revision == 0) 514167518Skmacy return dump_regs_t3(argc, argv, start_arg, 515167518Skmacy (uint32_t *)regs.data, is_pcie); 516182899Skmacy if (revision == 2 || revision == 3) 517167518Skmacy return dump_regs_t3b(argc, argv, start_arg, 518167518Skmacy (uint32_t *)regs.data, is_pcie); 519182594Skmacy if (revision == 4) 520182594Skmacy return dump_regs_t3c(argc, argv, start_arg, 521182594Skmacy (uint32_t *)regs.data, is_pcie); 522167518Skmacy } 523167518Skmacy#endif 524182594Skmacy errx(1, "unknown card type %d.%d", vers, revision); 525167518Skmacy return 0; 526167518Skmacy} 527167518Skmacy 528204267Snpstatic int 529204267Snpt3_meminfo(const uint32_t *regs) 530167518Skmacy{ 531167518Skmacy enum { 532167518Skmacy SG_EGR_CNTX_BADDR = 0x58, 533167518Skmacy SG_CQ_CONTEXT_BADDR = 0x6c, 534167518Skmacy CIM_SDRAM_BASE_ADDR = 0x28c, 535167518Skmacy CIM_SDRAM_ADDR_SIZE = 0x290, 536167518Skmacy TP_CMM_MM_BASE = 0x314, 537167518Skmacy TP_CMM_TIMER_BASE = 0x318, 538167518Skmacy TP_CMM_MM_RX_FLST_BASE = 0x460, 539167518Skmacy TP_CMM_MM_TX_FLST_BASE = 0x464, 540167518Skmacy TP_CMM_MM_PS_FLST_BASE = 0x468, 541167518Skmacy ULPRX_ISCSI_LLIMIT = 0x50c, 542167518Skmacy ULPRX_ISCSI_ULIMIT = 0x510, 543167518Skmacy ULPRX_TDDP_LLIMIT = 0x51c, 544167518Skmacy ULPRX_TDDP_ULIMIT = 0x520, 545167518Skmacy ULPRX_STAG_LLIMIT = 0x52c, 546167518Skmacy ULPRX_STAG_ULIMIT = 0x530, 547167518Skmacy ULPRX_RQ_LLIMIT = 0x534, 548167518Skmacy ULPRX_RQ_ULIMIT = 0x538, 549167518Skmacy ULPRX_PBL_LLIMIT = 0x53c, 550167518Skmacy ULPRX_PBL_ULIMIT = 0x540, 551167518Skmacy }; 552167518Skmacy 553167518Skmacy unsigned int egr_cntxt = regs[SG_EGR_CNTX_BADDR / 4], 554167518Skmacy cq_cntxt = regs[SG_CQ_CONTEXT_BADDR / 4], 555167518Skmacy timers = regs[TP_CMM_TIMER_BASE / 4] & 0xfffffff, 556167518Skmacy pstructs = regs[TP_CMM_MM_BASE / 4], 557167518Skmacy pstruct_fl = regs[TP_CMM_MM_PS_FLST_BASE / 4], 558167518Skmacy rx_fl = regs[TP_CMM_MM_RX_FLST_BASE / 4], 559167518Skmacy tx_fl = regs[TP_CMM_MM_TX_FLST_BASE / 4], 560167518Skmacy cim_base = regs[CIM_SDRAM_BASE_ADDR / 4], 561167518Skmacy cim_size = regs[CIM_SDRAM_ADDR_SIZE / 4]; 562167518Skmacy unsigned int iscsi_ll = regs[ULPRX_ISCSI_LLIMIT / 4], 563167518Skmacy iscsi_ul = regs[ULPRX_ISCSI_ULIMIT / 4], 564167518Skmacy tddp_ll = regs[ULPRX_TDDP_LLIMIT / 4], 565167518Skmacy tddp_ul = regs[ULPRX_TDDP_ULIMIT / 4], 566167518Skmacy stag_ll = regs[ULPRX_STAG_LLIMIT / 4], 567167518Skmacy stag_ul = regs[ULPRX_STAG_ULIMIT / 4], 568167518Skmacy rq_ll = regs[ULPRX_RQ_LLIMIT / 4], 569167518Skmacy rq_ul = regs[ULPRX_RQ_ULIMIT / 4], 570167518Skmacy pbl_ll = regs[ULPRX_PBL_LLIMIT / 4], 571167518Skmacy pbl_ul = regs[ULPRX_PBL_ULIMIT / 4]; 572167518Skmacy 573167518Skmacy printf("CM memory map:\n"); 574167518Skmacy printf(" TCB region: 0x%08x - 0x%08x [%u]\n", 0, egr_cntxt - 1, 575167518Skmacy egr_cntxt); 576167518Skmacy printf(" Egress contexts: 0x%08x - 0x%08x [%u]\n", egr_cntxt, 577167518Skmacy cq_cntxt - 1, cq_cntxt - egr_cntxt); 578167518Skmacy printf(" CQ contexts: 0x%08x - 0x%08x [%u]\n", cq_cntxt, 579167518Skmacy timers - 1, timers - cq_cntxt); 580167518Skmacy printf(" Timers: 0x%08x - 0x%08x [%u]\n", timers, 581167518Skmacy pstructs - 1, pstructs - timers); 582167518Skmacy printf(" Pstructs: 0x%08x - 0x%08x [%u]\n", pstructs, 583167518Skmacy pstruct_fl - 1, pstruct_fl - pstructs); 584167518Skmacy printf(" Pstruct FL: 0x%08x - 0x%08x [%u]\n", pstruct_fl, 585167518Skmacy rx_fl - 1, rx_fl - pstruct_fl); 586167518Skmacy printf(" Rx FL: 0x%08x - 0x%08x [%u]\n", rx_fl, tx_fl - 1, 587167518Skmacy tx_fl - rx_fl); 588167518Skmacy printf(" Tx FL: 0x%08x - 0x%08x [%u]\n", tx_fl, cim_base - 1, 589167518Skmacy cim_base - tx_fl); 590167518Skmacy printf(" uP RAM: 0x%08x - 0x%08x [%u]\n", cim_base, 591167518Skmacy cim_base + cim_size - 1, cim_size); 592167518Skmacy 593167518Skmacy printf("\nPMRX memory map:\n"); 594167518Skmacy printf(" iSCSI region: 0x%08x - 0x%08x [%u]\n", iscsi_ll, iscsi_ul, 595167518Skmacy iscsi_ul - iscsi_ll + 1); 596167518Skmacy printf(" TCP DDP region: 0x%08x - 0x%08x [%u]\n", tddp_ll, tddp_ul, 597167518Skmacy tddp_ul - tddp_ll + 1); 598167518Skmacy printf(" TPT region: 0x%08x - 0x%08x [%u]\n", stag_ll, stag_ul, 599167518Skmacy stag_ul - stag_ll + 1); 600167518Skmacy printf(" RQ region: 0x%08x - 0x%08x [%u]\n", rq_ll, rq_ul, 601167518Skmacy rq_ul - rq_ll + 1); 602167518Skmacy printf(" PBL region: 0x%08x - 0x%08x [%u]\n", pbl_ll, pbl_ul, 603167518Skmacy pbl_ul - pbl_ll + 1); 604167518Skmacy return 0; 605167518Skmacy} 606167518Skmacy 607204267Snpstatic int 608204267Snpmeminfo(int argc, char *argv[], int start_arg, const char *iff_name) 609167518Skmacy{ 610167518Skmacy int vers; 611182594Skmacy struct ch_ifconf_regs regs; 612167518Skmacy 613204267Snp (void) argc; 614204267Snp (void) argv; 615204267Snp (void) start_arg; 616204267Snp 617182594Skmacy regs.len = REGDUMP_SIZE; 618182594Skmacy if ((regs.data = malloc(regs.len)) == NULL) 619167518Skmacy err(1, "can't malloc"); 620167518Skmacy 621167518Skmacy if (doit(iff_name, CHELSIO_IFCONF_GETREGS, ®s)) 622167518Skmacy err(1, "can't read registers"); 623167518Skmacy 624167518Skmacy vers = regs.version & 0x3ff; 625167518Skmacy if (vers == 3) 626167518Skmacy return t3_meminfo((uint32_t *)regs.data); 627167518Skmacy 628167518Skmacy errx(1, "unknown card type %d", vers); 629167518Skmacy return 0; 630167518Skmacy} 631167518Skmacy 632204267Snpstatic int 633204267Snpmtu_tab_op(int argc, char *argv[], int start_arg, const char *iff_name) 634167518Skmacy{ 635182594Skmacy struct ch_mtus m; 636204267Snp unsigned int i; 637167518Skmacy 638167518Skmacy if (argc == start_arg) { 639182594Skmacy if (doit(iff_name, CHELSIO_GETMTUTAB, &m) < 0) 640167518Skmacy err(1, "get MTU table"); 641182594Skmacy for (i = 0; i < m.nmtus; ++i) 642182594Skmacy printf("%u ", m.mtus[i]); 643167518Skmacy printf("\n"); 644182594Skmacy } else if (argc <= start_arg + NMTUS) { 645182594Skmacy m.nmtus = argc - start_arg; 646167518Skmacy 647182594Skmacy for (i = 0; i < m.nmtus; ++i) { 648167518Skmacy char *p; 649182594Skmacy unsigned long mt = strtoul(argv[start_arg + i], &p, 0); 650167518Skmacy 651182594Skmacy if (*p || mt > 9600) { 652167518Skmacy warnx("bad parameter \"%s\"", 653167518Skmacy argv[start_arg + i]); 654167518Skmacy return -1; 655167518Skmacy } 656182594Skmacy if (i && mt < m.mtus[i - 1]) 657167518Skmacy errx(1, "MTUs must be in ascending order"); 658182594Skmacy m.mtus[i] = mt; 659167518Skmacy } 660182594Skmacy if (doit(iff_name, CHELSIO_SETMTUTAB, &m) < 0) 661167518Skmacy err(1, "set MTU table"); 662167518Skmacy } else 663167518Skmacy return -1; 664167518Skmacy 665167518Skmacy return 0; 666167518Skmacy} 667167518Skmacy 668167518Skmacy#ifdef CHELSIO_INTERNAL 669204267Snpstatic void 670204267Snpshow_egress_cntxt(uint32_t data[]) 671167518Skmacy{ 672167518Skmacy printf("credits: %u\n", data[0] & 0x7fff); 673167518Skmacy printf("GTS: %u\n", (data[0] >> 15) & 1); 674167518Skmacy printf("index: %u\n", data[0] >> 16); 675167518Skmacy printf("queue size: %u\n", data[1] & 0xffff); 676204267Snp printf("base address: 0x%" PRIx64 "\n", 677167518Skmacy ((data[1] >> 16) | ((uint64_t)data[2] << 16) | 678167518Skmacy (((uint64_t)data[3] & 0xf) << 48)) << 12); 679167518Skmacy printf("rsp queue #: %u\n", (data[3] >> 4) & 7); 680167518Skmacy printf("cmd queue #: %u\n", (data[3] >> 7) & 1); 681167518Skmacy printf("TUN: %u\n", (data[3] >> 8) & 1); 682167518Skmacy printf("TOE: %u\n", (data[3] >> 9) & 1); 683167518Skmacy printf("generation: %u\n", (data[3] >> 10) & 1); 684167518Skmacy printf("uP token: %u\n", (data[3] >> 11) & 0xfffff); 685167518Skmacy printf("valid: %u\n", (data[3] >> 31) & 1); 686167518Skmacy} 687167518Skmacy 688204267Snpstatic void 689204267Snpshow_fl_cntxt(uint32_t data[]) 690167518Skmacy{ 691204267Snp printf("base address: 0x%" PRIx64 "\n", 692167518Skmacy ((uint64_t)data[0] | ((uint64_t)data[1] & 0xfffff) << 32) << 12); 693167518Skmacy printf("index: %u\n", (data[1] >> 20) | ((data[2] & 0xf) << 12)); 694167518Skmacy printf("queue size: %u\n", (data[2] >> 4) & 0xffff); 695167518Skmacy printf("generation: %u\n", (data[2] >> 20) & 1); 696167518Skmacy printf("entry size: %u\n", 697189643Sgnn (data[2] >> 21) | (data[3] & 0x1fffff) << 11); 698167518Skmacy printf("congest thr: %u\n", (data[3] >> 21) & 0x3ff); 699167518Skmacy printf("GTS: %u\n", (data[3] >> 31) & 1); 700167518Skmacy} 701167518Skmacy 702204267Snpstatic void 703204267Snpshow_response_cntxt(uint32_t data[]) 704167518Skmacy{ 705167518Skmacy printf("index: %u\n", data[0] & 0xffff); 706167518Skmacy printf("size: %u\n", data[0] >> 16); 707204267Snp printf("base address: 0x%" PRIx64 "\n", 708167518Skmacy ((uint64_t)data[1] | ((uint64_t)data[2] & 0xfffff) << 32) << 12); 709167518Skmacy printf("MSI-X/RspQ: %u\n", (data[2] >> 20) & 0x3f); 710167518Skmacy printf("intr enable: %u\n", (data[2] >> 26) & 1); 711167518Skmacy printf("intr armed: %u\n", (data[2] >> 27) & 1); 712167518Skmacy printf("generation: %u\n", (data[2] >> 28) & 1); 713167518Skmacy printf("CQ mode: %u\n", (data[2] >> 31) & 1); 714167518Skmacy printf("FL threshold: %u\n", data[3]); 715167518Skmacy} 716167518Skmacy 717204267Snpstatic void 718204267Snpshow_cq_cntxt(uint32_t data[]) 719167518Skmacy{ 720167518Skmacy printf("index: %u\n", data[0] & 0xffff); 721167518Skmacy printf("size: %u\n", data[0] >> 16); 722204267Snp printf("base address: 0x%" PRIx64 "\n", 723167518Skmacy ((uint64_t)data[1] | ((uint64_t)data[2] & 0xfffff) << 32) << 12); 724167518Skmacy printf("rsp queue #: %u\n", (data[2] >> 20) & 0x3f); 725167518Skmacy printf("AN: %u\n", (data[2] >> 26) & 1); 726167518Skmacy printf("armed: %u\n", (data[2] >> 27) & 1); 727167518Skmacy printf("ANS: %u\n", (data[2] >> 28) & 1); 728167518Skmacy printf("generation: %u\n", (data[2] >> 29) & 1); 729167518Skmacy printf("overflow mode: %u\n", (data[2] >> 31) & 1); 730167518Skmacy printf("credits: %u\n", data[3] & 0xffff); 731167518Skmacy printf("credit threshold: %u\n", data[3] >> 16); 732167518Skmacy} 733167518Skmacy 734204267Snpstatic int 735204267Snpget_sge_context(int argc, char *argv[], int start_arg, const char *iff_name) 736167518Skmacy{ 737167518Skmacy struct ch_cntxt ctx; 738167518Skmacy 739167518Skmacy if (argc != start_arg + 2) return -1; 740167518Skmacy 741167518Skmacy if (!strcmp(argv[start_arg], "egress")) 742167518Skmacy ctx.cntxt_type = CNTXT_TYPE_EGRESS; 743167518Skmacy else if (!strcmp(argv[start_arg], "fl")) 744167518Skmacy ctx.cntxt_type = CNTXT_TYPE_FL; 745167518Skmacy else if (!strcmp(argv[start_arg], "response")) 746167518Skmacy ctx.cntxt_type = CNTXT_TYPE_RSP; 747167518Skmacy else if (!strcmp(argv[start_arg], "cq")) 748167518Skmacy ctx.cntxt_type = CNTXT_TYPE_CQ; 749167518Skmacy else { 750167518Skmacy warnx("unknown context type \"%s\"; known types are egress, " 751167518Skmacy "fl, cq, and response", argv[start_arg]); 752167518Skmacy return -1; 753167518Skmacy } 754167518Skmacy 755167518Skmacy if (get_int_arg(argv[start_arg + 1], &ctx.cntxt_id)) 756167518Skmacy return -1; 757167518Skmacy 758167518Skmacy if (doit(iff_name, CHELSIO_GET_SGE_CONTEXT, &ctx) < 0) 759167518Skmacy err(1, "get SGE context"); 760167518Skmacy 761167518Skmacy if (!strcmp(argv[start_arg], "egress")) 762167518Skmacy show_egress_cntxt(ctx.data); 763167518Skmacy else if (!strcmp(argv[start_arg], "fl")) 764167518Skmacy show_fl_cntxt(ctx.data); 765167518Skmacy else if (!strcmp(argv[start_arg], "response")) 766167518Skmacy show_response_cntxt(ctx.data); 767167518Skmacy else if (!strcmp(argv[start_arg], "cq")) 768167518Skmacy show_cq_cntxt(ctx.data); 769167518Skmacy return 0; 770167518Skmacy} 771167518Skmacy 772182899Skmacy#define ntohll(x) be64toh((x)) 773167518Skmacy 774204267Snpstatic int 775204267Snpget_sge_desc(int argc, char *argv[], int start_arg, const char *iff_name) 776167518Skmacy{ 777167518Skmacy uint64_t *p, wr_hdr; 778167518Skmacy unsigned int n = 1, qset, qnum; 779167518Skmacy struct ch_desc desc; 780167518Skmacy 781167518Skmacy if (argc != start_arg + 3 && argc != start_arg + 4) 782167518Skmacy return -1; 783167518Skmacy 784167518Skmacy if (get_int_arg(argv[start_arg], &qset) || 785167518Skmacy get_int_arg(argv[start_arg + 1], &qnum) || 786167518Skmacy get_int_arg(argv[start_arg + 2], &desc.idx)) 787167518Skmacy return -1; 788167518Skmacy 789167518Skmacy if (argc == start_arg + 4 && get_int_arg(argv[start_arg + 3], &n)) 790167518Skmacy return -1; 791167518Skmacy 792167518Skmacy if (qnum > 5) 793167518Skmacy errx(1, "invalid queue number %d, range is 0..5", qnum); 794167518Skmacy 795167518Skmacy desc.queue_num = qset * 6 + qnum; 796167518Skmacy 797167518Skmacy for (; n--; desc.idx++) { 798167518Skmacy if (doit(iff_name, CHELSIO_GET_SGE_DESC, &desc) < 0) 799167518Skmacy err(1, "get SGE descriptor"); 800167518Skmacy 801167518Skmacy p = (uint64_t *)desc.data; 802167518Skmacy wr_hdr = ntohll(*p); 803167518Skmacy printf("Descriptor %u: cmd %u, TID %u, %s%s%s%s%u flits\n", 804167518Skmacy desc.idx, (unsigned int)(wr_hdr >> 56), 805167518Skmacy ((unsigned int)wr_hdr >> 8) & 0xfffff, 806167518Skmacy ((wr_hdr >> 55) & 1) ? "SOP, " : "", 807167518Skmacy ((wr_hdr >> 54) & 1) ? "EOP, " : "", 808167518Skmacy ((wr_hdr >> 53) & 1) ? "COMPL, " : "", 809167518Skmacy ((wr_hdr >> 52) & 1) ? "SGL, " : "", 810167518Skmacy (unsigned int)wr_hdr & 0xff); 811167518Skmacy 812167518Skmacy for (; desc.size; p++, desc.size -= sizeof(uint64_t)) 813167518Skmacy printf("%016" PRIx64 "%c", ntohll(*p), 814167518Skmacy desc.size % 32 == 8 ? '\n' : ' '); 815167518Skmacy } 816167518Skmacy return 0; 817167518Skmacy} 818167518Skmacy#endif 819167518Skmacy 820204267Snpstatic int 821204267Snpget_tcb2(int argc, char *argv[], int start_arg, const char *iff_name) 822167518Skmacy{ 823167518Skmacy uint64_t *d; 824167518Skmacy unsigned int i; 825182594Skmacy unsigned int tcb_idx; 826182594Skmacy struct ch_mem_range mr; 827167518Skmacy 828182594Skmacy if (argc != start_arg + 1) 829182594Skmacy return -1; 830182594Skmacy 831182594Skmacy if (get_int_arg(argv[start_arg], &tcb_idx)) 832182594Skmacy return -1; 833182594Skmacy 834182594Skmacy mr.buf = calloc(1, TCB_SIZE); 835182594Skmacy if (!mr.buf) 836167518Skmacy err(1, "get TCB"); 837167518Skmacy 838182594Skmacy mr.mem_id = MEM_CM; 839182594Skmacy mr.addr = tcb_idx * TCB_SIZE; 840182594Skmacy mr.len = TCB_SIZE; 841167518Skmacy 842182594Skmacy if (doit(iff_name, CHELSIO_GET_MEM, &mr) < 0) 843167518Skmacy err(1, "get TCB"); 844167518Skmacy 845182899Skmacy for (d = (uint64_t *)mr.buf, i = 0; i < TCB_SIZE / 32; i++) { 846167518Skmacy printf("%2u:", i); 847167518Skmacy printf(" %08x %08x %08x %08x", (uint32_t)d[1], 848167518Skmacy (uint32_t)(d[1] >> 32), (uint32_t)d[0], 849167518Skmacy (uint32_t)(d[0] >> 32)); 850167518Skmacy d += 2; 851167518Skmacy printf(" %08x %08x %08x %08x\n", (uint32_t)d[1], 852167518Skmacy (uint32_t)(d[1] >> 32), (uint32_t)d[0], 853167518Skmacy (uint32_t)(d[0] >> 32)); 854167518Skmacy d += 2; 855167518Skmacy } 856182594Skmacy free(mr.buf); 857167518Skmacy return 0; 858167518Skmacy} 859167518Skmacy 860204267Snpstatic int 861204267Snpget_pm_page_spec(const char *s, unsigned int *page_size, 862204267Snp unsigned int *num_pages) 863167518Skmacy{ 864167518Skmacy char *p; 865167518Skmacy unsigned long val; 866167518Skmacy 867167518Skmacy val = strtoul(s, &p, 0); 868167518Skmacy if (p == s) return -1; 869167518Skmacy if (*p == 'x' && p[1]) { 870167518Skmacy *num_pages = val; 871167518Skmacy *page_size = strtoul(p + 1, &p, 0); 872167518Skmacy } else { 873167518Skmacy *num_pages = -1; 874167518Skmacy *page_size = val; 875167518Skmacy } 876167518Skmacy *page_size <<= 10; // KB -> bytes 877167518Skmacy return *p; 878167518Skmacy} 879167518Skmacy 880204267Snpstatic int 881204267Snpconf_pm(int argc, char *argv[], int start_arg, const char *iff_name) 882167518Skmacy{ 883182594Skmacy struct ch_pm pm; 884167518Skmacy 885167518Skmacy if (argc == start_arg) { 886182594Skmacy if (doit(iff_name, CHELSIO_GET_PM, &pm) < 0) 887167518Skmacy err(1, "read pm config"); 888167518Skmacy printf("%ux%uKB TX pages, %ux%uKB RX pages, %uKB total memory\n", 889182594Skmacy pm.tx_num_pg, pm.tx_pg_sz >> 10, pm.rx_num_pg, 890182594Skmacy pm.rx_pg_sz >> 10, pm.pm_total >> 10); 891167518Skmacy return 0; 892167518Skmacy } 893167518Skmacy 894167518Skmacy if (argc != start_arg + 2) return -1; 895167518Skmacy 896182594Skmacy if (get_pm_page_spec(argv[start_arg], &pm.tx_pg_sz, &pm.tx_num_pg)) { 897167518Skmacy warnx("bad parameter \"%s\"", argv[start_arg]); 898167518Skmacy return -1; 899167518Skmacy } 900182594Skmacy if (get_pm_page_spec(argv[start_arg + 1], &pm.rx_pg_sz, 901182594Skmacy &pm.rx_num_pg)) { 902167518Skmacy warnx("bad parameter \"%s\"", argv[start_arg + 1]); 903167518Skmacy return -1; 904167518Skmacy } 905182594Skmacy if (doit(iff_name, CHELSIO_SET_PM, &pm) < 0) 906167518Skmacy err(1, "pm config"); 907167518Skmacy return 0; 908167518Skmacy} 909167518Skmacy 910167518Skmacy#ifdef CHELSIO_INTERNAL 911204267Snpstatic int 912204267Snpdump_tcam(int argc, char *argv[], int start_arg, const char *iff_name) 913167518Skmacy{ 914167518Skmacy unsigned int nwords; 915182594Skmacy struct ch_tcam_word op; 916167518Skmacy 917167518Skmacy if (argc != start_arg + 2) return -1; 918167518Skmacy 919167518Skmacy if (get_int_arg(argv[start_arg], &op.addr) || 920167518Skmacy get_int_arg(argv[start_arg + 1], &nwords)) 921167518Skmacy return -1; 922167518Skmacy 923167518Skmacy while (nwords--) { 924182594Skmacy if (doit(iff_name, CHELSIO_READ_TCAM_WORD, &op) < 0) 925167518Skmacy err(1, "tcam dump"); 926167518Skmacy 927167518Skmacy printf("0x%08x: 0x%02x 0x%08x 0x%08x\n", op.addr, 928167518Skmacy op.buf[0] & 0xff, op.buf[1], op.buf[2]); 929167518Skmacy op.addr++; 930167518Skmacy } 931167518Skmacy return 0; 932167518Skmacy} 933182594Skmacy 934204267Snpstatic void 935204267Snphexdump_8b(unsigned int start, uint64_t *data, unsigned int len) 936167518Skmacy{ 937167518Skmacy int i; 938167518Skmacy 939167518Skmacy while (len) { 940167518Skmacy printf("0x%08x:", start); 941167518Skmacy for (i = 0; i < 4 && len; ++i, --len) 942167518Skmacy printf(" %016llx", (unsigned long long)*data++); 943167518Skmacy printf("\n"); 944167518Skmacy start += 32; 945167518Skmacy } 946167518Skmacy} 947167518Skmacy 948204267Snpstatic int 949204267Snpdump_mc7(int argc, char *argv[], int start_arg, const char *iff_name) 950167518Skmacy{ 951167518Skmacy struct ch_mem_range mem; 952167518Skmacy unsigned int mem_id, addr, len; 953167518Skmacy 954167518Skmacy if (argc != start_arg + 3) return -1; 955167518Skmacy 956167518Skmacy if (!strcmp(argv[start_arg], "cm")) 957167518Skmacy mem_id = MEM_CM; 958167518Skmacy else if (!strcmp(argv[start_arg], "rx")) 959167518Skmacy mem_id = MEM_PMRX; 960167518Skmacy else if (!strcmp(argv[start_arg], "tx")) 961167518Skmacy mem_id = MEM_PMTX; 962167518Skmacy else 963167518Skmacy errx(1, "unknown memory \"%s\"; must be one of \"cm\", \"tx\"," 964167518Skmacy " or \"rx\"", argv[start_arg]); 965167518Skmacy 966167518Skmacy if (get_int_arg(argv[start_arg + 1], &addr) || 967167518Skmacy get_int_arg(argv[start_arg + 2], &len)) 968167518Skmacy return -1; 969167518Skmacy 970167518Skmacy mem.buf = malloc(len); 971167518Skmacy if (!mem.buf) 972167518Skmacy err(1, "memory dump"); 973167518Skmacy 974167518Skmacy mem.mem_id = mem_id; 975167518Skmacy mem.addr = addr; 976167518Skmacy mem.len = len; 977167518Skmacy 978167518Skmacy if (doit(iff_name, CHELSIO_GET_MEM, &mem) < 0) 979167518Skmacy err(1, "memory dump"); 980167518Skmacy 981167518Skmacy hexdump_8b(mem.addr, (uint64_t *)mem.buf, mem.len >> 3); 982167518Skmacy free(mem.buf); 983167518Skmacy return 0; 984167518Skmacy} 985167518Skmacy#endif 986167518Skmacy 987204267Snp/* Max FW size is 64K including version, +4 bytes for the checksum. */ 988189643Sgnn#define MAX_FW_IMAGE_SIZE (64 * 1024) 989167518Skmacy 990204267Snpstatic int 991204267Snpload_fw(int argc, char *argv[], int start_arg, const char *iff_name) 992167518Skmacy{ 993167518Skmacy int fd, len; 994182594Skmacy struct ch_mem_range op; 995167518Skmacy const char *fname = argv[start_arg]; 996167518Skmacy 997167518Skmacy if (argc != start_arg + 1) return -1; 998167518Skmacy 999167518Skmacy fd = open(fname, O_RDONLY); 1000167518Skmacy if (fd < 0) 1001167518Skmacy err(1, "load firmware"); 1002167518Skmacy 1003182594Skmacy bzero(&op, sizeof(op)); 1004182594Skmacy op.buf = malloc(MAX_FW_IMAGE_SIZE + 1); 1005182594Skmacy if (!op.buf) 1006167518Skmacy err(1, "load firmware"); 1007167518Skmacy 1008204267Snp len = read(fd, op.buf, MAX_FW_IMAGE_SIZE + 1); 1009204267Snp if (len < 0) 1010167518Skmacy err(1, "load firmware"); 1011204267Snp if (len > MAX_FW_IMAGE_SIZE) 1012167518Skmacy errx(1, "FW image too large"); 1013167518Skmacy 1014204267Snp op.len = len; 1015182594Skmacy if (doit(iff_name, CHELSIO_LOAD_FW, &op) < 0) 1016167518Skmacy err(1, "load firmware"); 1017216285Skevlo 1018216285Skevlo close(fd); 1019167518Skmacy return 0; 1020167518Skmacy} 1021167518Skmacy 1022182594Skmacy/* Max BOOT size is 255*512 bytes including the BIOS boot ROM basic header */ 1023182594Skmacy#define MAX_BOOT_IMAGE_SIZE (0xff * 512) 1024167518Skmacy 1025204267Snpstatic int 1026204267Snpload_boot(int argc, char *argv[], int start_arg, const char *iff_name) 1027167518Skmacy{ 1028182594Skmacy int fd, len; 1029182594Skmacy struct ch_mem_range op; 1030182594Skmacy const char *fname = argv[start_arg]; 1031167518Skmacy 1032182594Skmacy if (argc != start_arg + 1) return -1; 1033167518Skmacy 1034182594Skmacy fd = open(fname, O_RDONLY); 1035182594Skmacy if (fd < 0) 1036182594Skmacy err(1, "load boot image"); 1037167518Skmacy 1038182594Skmacy op.buf = malloc(MAX_BOOT_IMAGE_SIZE + 1); 1039182594Skmacy if (!op.buf) 1040182594Skmacy err(1, "load boot image"); 1041182594Skmacy 1042182594Skmacy len = read(fd, op.buf, MAX_BOOT_IMAGE_SIZE + 1); 1043182594Skmacy if (len < 0) 1044182594Skmacy err(1, "load boot image"); 1045182594Skmacy if (len > MAX_BOOT_IMAGE_SIZE) 1046182594Skmacy errx(1, "boot image too large"); 1047182594Skmacy 1048182594Skmacy op.len = len; 1049182594Skmacy 1050182594Skmacy if (doit(iff_name, CHELSIO_LOAD_BOOT, &op) < 0) 1051182594Skmacy err(1, "load boot image"); 1052182594Skmacy 1053216285Skevlo close(fd); 1054167518Skmacy return 0; 1055167518Skmacy} 1056167518Skmacy 1057204267Snpstatic int 1058204267Snpdump_proto_sram(const char *iff_name) 1059167518Skmacy{ 1060167518Skmacy int i, j; 1061182594Skmacy uint8_t buf[PROTO_SRAM_SIZE]; 1062182594Skmacy struct ch_eeprom ee; 1063182594Skmacy uint8_t *p = buf; 1064167518Skmacy 1065182594Skmacy bzero(buf, sizeof(buf)); 1066182594Skmacy ee.offset = PROTO_SRAM_EEPROM_ADDR; 1067182594Skmacy ee.data = p; 1068182594Skmacy ee.len = sizeof(buf); 1069182594Skmacy if (doit(iff_name, CHELSIO_GET_EEPROM, &ee)) 1070167518Skmacy err(1, "show protocol sram"); 1071167518Skmacy 1072167518Skmacy for (i = 0; i < PROTO_SRAM_LINES; i++) { 1073167518Skmacy for (j = PROTO_SRAM_LINE_NIBBLES - 1; j >= 0; j--) { 1074167518Skmacy int nibble_idx = i * PROTO_SRAM_LINE_NIBBLES + j; 1075182594Skmacy uint8_t nibble = p[nibble_idx / 2]; 1076167518Skmacy 1077167518Skmacy if (nibble_idx & 1) 1078167518Skmacy nibble >>= 4; 1079167518Skmacy else 1080167518Skmacy nibble &= 0xf; 1081167518Skmacy printf("%x", nibble); 1082167518Skmacy } 1083167518Skmacy putchar('\n'); 1084167518Skmacy } 1085167518Skmacy return 0; 1086167518Skmacy} 1087167518Skmacy 1088204267Snpstatic int 1089204267Snpproto_sram_op(int argc, char *argv[], int start_arg, 1090167518Skmacy const char *iff_name) 1091167518Skmacy{ 1092204267Snp (void) argv; 1093204267Snp (void) start_arg; 1094204267Snp 1095167518Skmacy if (argc == start_arg) 1096167518Skmacy return dump_proto_sram(iff_name); 1097167518Skmacy return -1; 1098167518Skmacy} 1099167518Skmacy 1100204267Snpstatic int 1101204267Snpdump_qset_params(const char *iff_name) 1102167518Skmacy{ 1103167518Skmacy struct ch_qset_params qp; 1104167518Skmacy 1105167518Skmacy qp.qset_idx = 0; 1106167518Skmacy 1107167518Skmacy while (doit(iff_name, CHELSIO_GET_QSET_PARAMS, &qp) == 0) { 1108167518Skmacy if (!qp.qset_idx) 1109182594Skmacy printf("Qset TxQ0 TxQ1 TxQ2 RspQ RxQ0 RxQ1" 1110182594Skmacy " Cong Lat IRQ\n"); 1111182594Skmacy printf("%4u %6u %6u %6u %6u %6u %6u %5u %4u %5d\n", 1112182594Skmacy qp.qnum, 1113167518Skmacy qp.txq_size[0], qp.txq_size[1], qp.txq_size[2], 1114167518Skmacy qp.rspq_size, qp.fl_size[0], qp.fl_size[1], 1115182594Skmacy qp.cong_thres, qp.intr_lat, qp.vector); 1116167518Skmacy qp.qset_idx++; 1117167518Skmacy } 1118167518Skmacy if (!qp.qset_idx || (errno && errno != EINVAL)) 1119167518Skmacy err(1, "get qset parameters"); 1120167518Skmacy return 0; 1121167518Skmacy} 1122167518Skmacy 1123204267Snpstatic int 1124204267Snpqset_config(int argc, char *argv[], int start_arg, const char *iff_name) 1125167518Skmacy{ 1126204267Snp (void) argv; 1127167518Skmacy 1128167518Skmacy if (argc == start_arg) 1129167518Skmacy return dump_qset_params(iff_name); 1130167518Skmacy 1131182594Skmacy return -1; 1132167518Skmacy} 1133167518Skmacy 1134204267Snpstatic int 1135204267Snpqset_num_config(int argc, char *argv[], int start_arg, const char *iff_name) 1136167518Skmacy{ 1137167518Skmacy struct ch_reg reg; 1138167518Skmacy 1139204267Snp (void) argv; 1140204267Snp 1141167518Skmacy if (argc == start_arg) { 1142167518Skmacy if (doit(iff_name, CHELSIO_GET_QSET_NUM, ®) < 0) 1143167518Skmacy err(1, "get qsets"); 1144167518Skmacy printf("%u\n", reg.val); 1145167518Skmacy return 0; 1146167518Skmacy } 1147167518Skmacy 1148182594Skmacy return -1; 1149167518Skmacy} 1150167518Skmacy 1151167518Skmacy/* 1152167518Skmacy * Parse a string containing an IP address with an optional network prefix. 1153167518Skmacy */ 1154204267Snpstatic int 1155204267Snpparse_ipaddr(const char *s, uint32_t *addr, uint32_t *mask) 1156167518Skmacy{ 1157167518Skmacy char *p, *slash; 1158167518Skmacy struct in_addr ia; 1159167518Skmacy 1160167518Skmacy *mask = 0xffffffffU; 1161167518Skmacy slash = strchr(s, '/'); 1162167518Skmacy if (slash) 1163167518Skmacy *slash = 0; 1164167518Skmacy if (!inet_aton(s, &ia)) { 1165167518Skmacy if (slash) 1166167518Skmacy *slash = '/'; 1167167518Skmacy *addr = 0; 1168167518Skmacy return -1; 1169167518Skmacy } 1170167518Skmacy *addr = ntohl(ia.s_addr); 1171167518Skmacy if (slash) { 1172167518Skmacy unsigned int prefix = strtoul(slash + 1, &p, 10); 1173167518Skmacy 1174167518Skmacy *slash = '/'; 1175167518Skmacy if (p == slash + 1 || *p || prefix > 32) 1176167518Skmacy return -1; 1177167518Skmacy *mask <<= (32 - prefix); 1178167518Skmacy } 1179167518Skmacy return 0; 1180167518Skmacy} 1181167518Skmacy 1182167518Skmacy/* 1183167518Skmacy * Parse a string containing a value and an optional colon separated mask. 1184167518Skmacy */ 1185204267Snpstatic int 1186207643Snpparse_val_mask_param(const char *s, uint32_t *val, uint32_t *mask, 1187207643Snp uint32_t default_mask) 1188167518Skmacy{ 1189167518Skmacy char *p; 1190167518Skmacy 1191207643Snp *mask = default_mask; 1192167518Skmacy *val = strtoul(s, &p, 0); 1193207643Snp if (p == s || *val > default_mask) 1194167518Skmacy return -1; 1195167518Skmacy if (*p == ':' && p[1]) 1196167518Skmacy *mask = strtoul(p + 1, &p, 0); 1197207643Snp return *p || *mask > default_mask ? -1 : 0; 1198167518Skmacy} 1199167518Skmacy 1200204267Snpstatic int 1201204267Snpparse_trace_param(const char *s, uint32_t *val, uint32_t *mask) 1202167518Skmacy{ 1203167518Skmacy return strchr(s, '.') ? parse_ipaddr(s, val, mask) : 1204207643Snp parse_val_mask_param(s, val, mask, 0xffffffffU); 1205167518Skmacy} 1206167518Skmacy 1207204267Snpstatic int 1208204267Snptrace_config(int argc, char *argv[], int start_arg, const char *iff_name) 1209167518Skmacy{ 1210167518Skmacy uint32_t val, mask; 1211167518Skmacy struct ch_trace trace; 1212167518Skmacy 1213167518Skmacy if (argc == start_arg) 1214167518Skmacy return -1; 1215167518Skmacy 1216167518Skmacy memset(&trace, 0, sizeof(trace)); 1217167518Skmacy if (!strcmp(argv[start_arg], "tx")) 1218167518Skmacy trace.config_tx = 1; 1219167518Skmacy else if (!strcmp(argv[start_arg], "rx")) 1220167518Skmacy trace.config_rx = 1; 1221167518Skmacy else if (!strcmp(argv[start_arg], "all")) 1222167518Skmacy trace.config_tx = trace.config_rx = 1; 1223167518Skmacy else 1224167518Skmacy errx(1, "bad trace filter \"%s\"; must be one of \"rx\", " 1225167518Skmacy "\"tx\" or \"all\"", argv[start_arg]); 1226167518Skmacy 1227167518Skmacy if (argc == ++start_arg) 1228167518Skmacy return -1; 1229167518Skmacy if (!strcmp(argv[start_arg], "on")) { 1230167518Skmacy trace.trace_tx = trace.config_tx; 1231167518Skmacy trace.trace_rx = trace.config_rx; 1232167518Skmacy } else if (strcmp(argv[start_arg], "off")) 1233167518Skmacy errx(1, "bad argument \"%s\"; must be \"on\" or \"off\"", 1234167518Skmacy argv[start_arg]); 1235167518Skmacy 1236167518Skmacy start_arg++; 1237167518Skmacy if (start_arg < argc && !strcmp(argv[start_arg], "not")) { 1238167518Skmacy trace.invert_match = 1; 1239167518Skmacy start_arg++; 1240167518Skmacy } 1241167518Skmacy 1242167518Skmacy while (start_arg + 2 <= argc) { 1243167518Skmacy int ret = parse_trace_param(argv[start_arg + 1], &val, &mask); 1244167518Skmacy 1245167518Skmacy if (!strcmp(argv[start_arg], "interface")) { 1246167518Skmacy trace.intf = val; 1247167518Skmacy trace.intf_mask = mask; 1248167518Skmacy } else if (!strcmp(argv[start_arg], "sip")) { 1249167518Skmacy trace.sip = val; 1250167518Skmacy trace.sip_mask = mask; 1251167518Skmacy } else if (!strcmp(argv[start_arg], "dip")) { 1252167518Skmacy trace.dip = val; 1253167518Skmacy trace.dip_mask = mask; 1254167518Skmacy } else if (!strcmp(argv[start_arg], "sport")) { 1255167518Skmacy trace.sport = val; 1256167518Skmacy trace.sport_mask = mask; 1257167518Skmacy } else if (!strcmp(argv[start_arg], "dport")) { 1258167518Skmacy trace.dport = val; 1259167518Skmacy trace.dport_mask = mask; 1260167518Skmacy } else if (!strcmp(argv[start_arg], "vlan")) { 1261167518Skmacy trace.vlan = val; 1262167518Skmacy trace.vlan_mask = mask; 1263167518Skmacy } else if (!strcmp(argv[start_arg], "proto")) { 1264167518Skmacy trace.proto = val; 1265167518Skmacy trace.proto_mask = mask; 1266167518Skmacy } else 1267167518Skmacy errx(1, "unknown trace parameter \"%s\"\n" 1268167518Skmacy "known parameters are \"interface\", \"sip\", " 1269167518Skmacy "\"dip\", \"sport\", \"dport\", \"vlan\", " 1270167518Skmacy "\"proto\"", argv[start_arg]); 1271167518Skmacy if (ret < 0) 1272167518Skmacy errx(1, "bad parameter \"%s\"", argv[start_arg + 1]); 1273167518Skmacy start_arg += 2; 1274167518Skmacy } 1275167518Skmacy if (start_arg != argc) 1276167518Skmacy errx(1, "unknown parameter \"%s\"", argv[start_arg]); 1277167518Skmacy 1278167518Skmacy if (doit(iff_name, CHELSIO_SET_TRACE_FILTER, &trace) < 0) 1279167518Skmacy err(1, "trace"); 1280167518Skmacy return 0; 1281167518Skmacy} 1282167518Skmacy 1283207643Snpstatic void 1284207643Snpshow_filters(const char *iff_name) 1285207643Snp{ 1286207643Snp static const char *pkt_type[] = { "*", "tcp", "udp", "frag" }; 1287207643Snp struct ch_filter op; 1288207643Snp union { 1289207643Snp uint32_t nip; 1290207643Snp uint8_t octet[4]; 1291207643Snp } nsip, ndip; 1292207643Snp char sip[20], dip[20]; 1293207643Snp int header = 0; 1294207643Snp 1295207643Snp bzero(&op, sizeof(op)); 1296207643Snp op.filter_id = 0xffffffff; 1297207643Snp 1298207643Snp do { 1299207643Snp if (doit(iff_name, CHELSIO_GET_FILTER, &op) < 0) 1300207643Snp err(1, "list filters"); 1301207643Snp 1302207643Snp if (op.filter_id == 0xffffffff) 1303207643Snp break; 1304207643Snp 1305207643Snp if (!header) { 1306207643Snp printf("index SIP DIP sport " 1307207643Snp "dport VLAN PRI P/MAC type Q\n"); 1308207643Snp header = 1; 1309207643Snp } 1310207643Snp 1311207643Snp nsip.nip = htonl(op.val.sip); 1312207643Snp ndip.nip = htonl(op.val.dip); 1313207643Snp 1314207643Snp sprintf(sip, "%u.%u.%u.%u/%-2u", nsip.octet[0], nsip.octet[1], 1315207643Snp nsip.octet[2], nsip.octet[3], 1316207643Snp op.mask.sip ? 33 - ffs(op.mask.sip) : 0); 1317207643Snp sprintf(dip, "%u.%u.%u.%u", ndip.octet[0], ndip.octet[1], 1318207643Snp ndip.octet[2], ndip.octet[3]); 1319207643Snp printf("%5zu %18s %15s ", (size_t)op.filter_id, sip, dip); 1320207643Snp printf(op.val.sport ? "%5u " : " * ", op.val.sport); 1321207643Snp printf(op.val.dport ? "%5u " : " * ", op.val.dport); 1322207643Snp printf(op.val.vlan != 0xfff ? "%4u " : " * ", op.val.vlan); 1323207643Snp printf(op.val.vlan_prio == 7 ? " * " : 1324207643Snp "%1u/%1u ", op.val.vlan_prio, op.val.vlan_prio | 1); 1325207643Snp if (op.mac_addr_idx == 0xffff) 1326207643Snp printf("*/* "); 1327207643Snp else if (op.mac_hit) 1328207643Snp printf("%1u/%3u ", (op.mac_addr_idx >> 3) & 0x1, 1329207643Snp (op.mac_addr_idx) & 0x7); 1330207643Snp else 1331207643Snp printf("%1u/ * ", (op.mac_addr_idx >> 3) & 0x1); 1332207643Snp printf("%4s ", pkt_type[op.proto]); 1333207643Snp if (!op.pass) 1334207643Snp printf("-\n"); 1335207643Snp else if (op.rss) 1336207643Snp printf("*\n"); 1337207643Snp else 1338207643Snp printf("%1u\n", op.qset); 1339207643Snp } while (1); 1340207643Snp} 1341207643Snp 1342204267Snpstatic int 1343207643Snpfilter_config(int argc, char *argv[], int start_arg, const char *iff_name) 1344207643Snp{ 1345207643Snp int ret = 0; 1346207643Snp uint32_t val, mask; 1347207643Snp struct ch_filter op; 1348207643Snp 1349207643Snp if (argc < start_arg + 1) 1350207643Snp return -1; 1351207643Snp 1352207643Snp memset(&op, 0, sizeof(op)); 1353207643Snp op.mac_addr_idx = 0xffff; 1354207643Snp op.rss = 1; 1355207643Snp 1356207643Snp if (argc == start_arg + 1 && !strcmp(argv[start_arg], "list")) { 1357207643Snp show_filters(iff_name); 1358207643Snp return 0; 1359207643Snp } 1360207643Snp 1361207643Snp if (get_int_arg(argv[start_arg++], &op.filter_id)) 1362207643Snp return -1; 1363207643Snp if (argc == start_arg + 1 && (!strcmp(argv[start_arg], "delete") || 1364207643Snp !strcmp(argv[start_arg], "clear"))) { 1365207643Snp if (doit(iff_name, CHELSIO_DEL_FILTER, &op) < 0) { 1366207643Snp if (errno == EBUSY) 1367207643Snp err(1, "no filter support when offload in use"); 1368207643Snp err(1, "delete filter"); 1369207643Snp } 1370207643Snp return 0; 1371207643Snp } 1372207643Snp 1373207643Snp while (start_arg + 2 <= argc) { 1374207643Snp if (!strcmp(argv[start_arg], "sip")) { 1375207643Snp ret = parse_ipaddr(argv[start_arg + 1], &op.val.sip, 1376207643Snp &op.mask.sip); 1377207643Snp } else if (!strcmp(argv[start_arg], "dip")) { 1378207643Snp ret = parse_ipaddr(argv[start_arg + 1], &op.val.dip, 1379207643Snp &op.mask.dip); 1380207643Snp } else if (!strcmp(argv[start_arg], "sport")) { 1381207643Snp ret = parse_val_mask_param(argv[start_arg + 1], 1382207643Snp &val, &mask, 0xffff); 1383207643Snp op.val.sport = val; 1384207643Snp op.mask.sport = mask; 1385207643Snp } else if (!strcmp(argv[start_arg], "dport")) { 1386207643Snp ret = parse_val_mask_param(argv[start_arg + 1], 1387207643Snp &val, &mask, 0xffff); 1388207643Snp op.val.dport = val; 1389207643Snp op.mask.dport = mask; 1390207643Snp } else if (!strcmp(argv[start_arg], "vlan")) { 1391207643Snp ret = parse_val_mask_param(argv[start_arg + 1], 1392207643Snp &val, &mask, 0xfff); 1393207643Snp op.val.vlan = val; 1394207643Snp op.mask.vlan = mask; 1395207643Snp } else if (!strcmp(argv[start_arg], "prio")) { 1396207643Snp ret = parse_val_mask_param(argv[start_arg + 1], 1397207643Snp &val, &mask, 7); 1398207643Snp op.val.vlan_prio = val; 1399207643Snp op.mask.vlan_prio = mask; 1400207643Snp } else if (!strcmp(argv[start_arg], "mac")) { 1401207643Snp if (!strcmp(argv[start_arg + 1], "none")) 1402207643Snp val = -1; 1403207643Snp else 1404207643Snp ret = get_int_arg(argv[start_arg + 1], &val); 1405207643Snp op.mac_hit = val != (uint32_t)-1; 1406207643Snp op.mac_addr_idx = op.mac_hit ? val : 0; 1407207643Snp } else if (!strcmp(argv[start_arg], "type")) { 1408207643Snp if (!strcmp(argv[start_arg + 1], "tcp")) 1409207643Snp op.proto = 1; 1410207643Snp else if (!strcmp(argv[start_arg + 1], "udp")) 1411207643Snp op.proto = 2; 1412207643Snp else if (!strcmp(argv[start_arg + 1], "frag")) 1413207643Snp op.proto = 3; 1414207643Snp else 1415207643Snp errx(1, "unknown type \"%s\"; must be one of " 1416207643Snp "\"tcp\", \"udp\", or \"frag\"", 1417207643Snp argv[start_arg + 1]); 1418207643Snp } else if (!strcmp(argv[start_arg], "queue")) { 1419207643Snp ret = get_int_arg(argv[start_arg + 1], &val); 1420207643Snp op.qset = val; 1421207643Snp op.rss = 0; 1422207643Snp } else if (!strcmp(argv[start_arg], "action")) { 1423207643Snp if (!strcmp(argv[start_arg + 1], "pass")) 1424207643Snp op.pass = 1; 1425207643Snp else if (strcmp(argv[start_arg + 1], "drop")) 1426207643Snp errx(1, "unknown action \"%s\"; must be one of " 1427207643Snp "\"pass\" or \"drop\"", 1428207643Snp argv[start_arg + 1]); 1429207643Snp } else 1430207643Snp errx(1, "unknown filter parameter \"%s\"\n" 1431207643Snp "known parameters are \"mac\", \"sip\", " 1432207643Snp "\"dip\", \"sport\", \"dport\", \"vlan\", " 1433207643Snp "\"prio\", \"type\", \"queue\", and \"action\"", 1434207643Snp argv[start_arg]); 1435207643Snp if (ret < 0) 1436207643Snp errx(1, "bad value \"%s\" for parameter \"%s\"", 1437207643Snp argv[start_arg + 1], argv[start_arg]); 1438207643Snp start_arg += 2; 1439207643Snp } 1440207643Snp if (start_arg != argc) 1441207643Snp errx(1, "no value for \"%s\"", argv[start_arg]); 1442207643Snp 1443207643Snp if (doit(iff_name, CHELSIO_SET_FILTER, &op) < 0) { 1444207643Snp if (errno == EBUSY) 1445207643Snp err(1, "no filter support when offload in use"); 1446207643Snp err(1, "set filter"); 1447207643Snp } 1448207643Snp 1449207643Snp return 0; 1450207643Snp} 1451207643Snpstatic int 1452204267Snpget_sched_param(int argc, char *argv[], int pos, unsigned int *valp) 1453167518Skmacy{ 1454182594Skmacy if (pos + 1 >= argc) 1455182594Skmacy errx(1, "missing value for %s", argv[pos]); 1456182594Skmacy if (get_int_arg(argv[pos + 1], valp)) 1457182594Skmacy exit(1); 1458182594Skmacy return 0; 1459182594Skmacy} 1460167518Skmacy 1461204267Snpstatic int 1462204267Snptx_sched(int argc, char *argv[], int start_arg, const char *iff_name) 1463182594Skmacy{ 1464182594Skmacy struct ch_hw_sched op; 1465182594Skmacy unsigned int idx, val; 1466167518Skmacy 1467182594Skmacy if (argc < 5 || get_int_arg(argv[start_arg++], &idx)) 1468167518Skmacy return -1; 1469182594Skmacy 1470182594Skmacy op.sched = idx; 1471182594Skmacy op.mode = op.channel = -1; 1472182594Skmacy op.kbps = op.class_ipg = op.flow_ipg = -1; 1473182594Skmacy 1474182594Skmacy while (argc > start_arg) { 1475182594Skmacy if (!strcmp(argv[start_arg], "mode")) { 1476182594Skmacy if (start_arg + 1 >= argc) 1477182594Skmacy errx(1, "missing value for mode"); 1478182594Skmacy if (!strcmp(argv[start_arg + 1], "class")) 1479182594Skmacy op.mode = 0; 1480182594Skmacy else if (!strcmp(argv[start_arg + 1], "flow")) 1481182594Skmacy op.mode = 1; 1482182594Skmacy else 1483182594Skmacy errx(1, "bad mode \"%s\"", argv[start_arg + 1]); 1484182594Skmacy } else if (!strcmp(argv[start_arg], "channel") && 1485182594Skmacy !get_sched_param(argc, argv, start_arg, &val)) 1486182594Skmacy op.channel = val; 1487182594Skmacy else if (!strcmp(argv[start_arg], "rate") && 1488182594Skmacy !get_sched_param(argc, argv, start_arg, &val)) 1489182594Skmacy op.kbps = val; 1490182594Skmacy else if (!strcmp(argv[start_arg], "ipg") && 1491182594Skmacy !get_sched_param(argc, argv, start_arg, &val)) 1492182594Skmacy op.class_ipg = val; 1493182594Skmacy else if (!strcmp(argv[start_arg], "flowipg") && 1494182594Skmacy !get_sched_param(argc, argv, start_arg, &val)) 1495182594Skmacy op.flow_ipg = val; 1496182594Skmacy else 1497182594Skmacy errx(1, "unknown scheduler parameter \"%s\"", 1498182594Skmacy argv[start_arg]); 1499182594Skmacy start_arg += 2; 1500167518Skmacy } 1501167518Skmacy 1502182594Skmacy if (doit(iff_name, CHELSIO_SET_HW_SCHED, &op) < 0) 1503182594Skmacy err(1, "pktsched"); 1504167518Skmacy 1505167518Skmacy return 0; 1506167518Skmacy} 1507167518Skmacy 1508204267Snpstatic int 1509204267Snppktsched(int argc, char *argv[], int start_arg, const char *iff_name) 1510167518Skmacy{ 1511182594Skmacy struct ch_pktsched_params op; 1512167518Skmacy unsigned int idx, min = -1, max, binding = -1; 1513167518Skmacy 1514182594Skmacy if (argc < 4) 1515182594Skmacy errx(1, "no scheduler specified"); 1516182594Skmacy 1517167518Skmacy if (!strcmp(argv[start_arg], "port")) { 1518167518Skmacy if (argc != start_arg + 4) 1519167518Skmacy return -1; 1520167518Skmacy if (get_int_arg(argv[start_arg + 1], &idx) || 1521167518Skmacy get_int_arg(argv[start_arg + 2], &min) || 1522167518Skmacy get_int_arg(argv[start_arg + 3], &max)) 1523167518Skmacy return -1; 1524182594Skmacy op.sched = 0; 1525167518Skmacy } else if (!strcmp(argv[start_arg], "tunnelq")) { 1526167518Skmacy if (argc != start_arg + 4) 1527167518Skmacy return -1; 1528167518Skmacy if (get_int_arg(argv[start_arg + 1], &idx) || 1529167518Skmacy get_int_arg(argv[start_arg + 2], &max) || 1530167518Skmacy get_int_arg(argv[start_arg + 3], &binding)) 1531167518Skmacy return -1; 1532182594Skmacy op.sched = 1; 1533182594Skmacy } else if (!strcmp(argv[start_arg], "tx")) 1534182594Skmacy return tx_sched(argc, argv, start_arg + 1, iff_name); 1535182594Skmacy else 1536182594Skmacy errx(1, "unknown scheduler \"%s\"; must be one of \"port\", " 1537182594Skmacy "\"tunnelq\" or \"tx\"", argv[start_arg]); 1538182594Skmacy 1539182594Skmacy op.idx = idx; 1540182594Skmacy op.min = min; 1541182594Skmacy op.max = max; 1542182594Skmacy op.binding = binding; 1543182594Skmacy if (doit(iff_name, CHELSIO_SET_PKTSCHED, &op) < 0) 1544167518Skmacy err(1, "pktsched"); 1545167518Skmacy 1546167518Skmacy return 0; 1547167518Skmacy} 1548189643Sgnn 1549204267Snpstatic int 1550204267Snpclear_stats(int argc, char *argv[], int start_arg, const char *iff_name) 1551182594Skmacy{ 1552204267Snp (void) argc; 1553204267Snp (void) argv; 1554204267Snp (void) start_arg; 1555204267Snp 1556182594Skmacy if (doit(iff_name, CHELSIO_CLEAR_STATS, NULL) < 0) 1557182594Skmacy err(1, "clearstats"); 1558167518Skmacy 1559182594Skmacy return 0; 1560182594Skmacy} 1561182594Skmacy 1562204267Snpstatic int 1563204267Snpget_up_la(int argc, char *argv[], int start_arg, const char *iff_name) 1564189643Sgnn{ 1565189643Sgnn struct ch_up_la la; 1566189643Sgnn int i, idx, max_idx, entries; 1567189643Sgnn 1568204267Snp (void) argc; 1569204267Snp (void) argv; 1570204267Snp (void) start_arg; 1571204267Snp 1572189643Sgnn la.stopped = 0; 1573189643Sgnn la.idx = -1; 1574189643Sgnn la.bufsize = LA_BUFSIZE; 1575189643Sgnn la.data = malloc(la.bufsize); 1576189643Sgnn if (!la.data) 1577189643Sgnn err(1, "uP_LA malloc"); 1578189643Sgnn 1579189643Sgnn if (doit(iff_name, CHELSIO_GET_UP_LA, &la) < 0) 1580189643Sgnn err(1, "uP_LA"); 1581189643Sgnn 1582189643Sgnn if (la.stopped) 1583189643Sgnn printf("LA is not running\n"); 1584189643Sgnn 1585189643Sgnn entries = la.bufsize / 4; 1586189643Sgnn idx = (int)la.idx; 1587189643Sgnn max_idx = (entries / 4) - 1; 1588189643Sgnn for (i = 0; i < max_idx; i++) { 1589189643Sgnn printf("%04x %08x %08x\n", 1590189643Sgnn la.data[idx], la.data[idx+2], la.data[idx+1]); 1591189643Sgnn idx = (idx + 4) & (entries - 1); 1592189643Sgnn } 1593189643Sgnn 1594189643Sgnn return 0; 1595189643Sgnn} 1596189643Sgnn 1597204267Snpstatic int 1598204267Snpget_up_ioqs(int argc, char *argv[], int start_arg, const char *iff_name) 1599189643Sgnn{ 1600189643Sgnn struct ch_up_ioqs ioqs; 1601189643Sgnn int i, entries; 1602189643Sgnn 1603204267Snp (void) argc; 1604204267Snp (void) argv; 1605204267Snp (void) start_arg; 1606204267Snp 1607189643Sgnn bzero(&ioqs, sizeof(ioqs)); 1608189643Sgnn ioqs.bufsize = IOQS_BUFSIZE; 1609189643Sgnn ioqs.data = malloc(IOQS_BUFSIZE); 1610189643Sgnn if (!ioqs.data) 1611189643Sgnn err(1, "uP_IOQs malloc"); 1612189643Sgnn 1613189643Sgnn if (doit(iff_name, CHELSIO_GET_UP_IOQS, &ioqs) < 0) 1614189643Sgnn err(1, "uP_IOQs"); 1615189643Sgnn 1616189643Sgnn printf("ioq_rx_enable : 0x%08x\n", ioqs.ioq_rx_enable); 1617189643Sgnn printf("ioq_tx_enable : 0x%08x\n", ioqs.ioq_tx_enable); 1618189643Sgnn printf("ioq_rx_status : 0x%08x\n", ioqs.ioq_rx_status); 1619189643Sgnn printf("ioq_tx_status : 0x%08x\n", ioqs.ioq_tx_status); 1620189643Sgnn 1621189643Sgnn entries = ioqs.bufsize / sizeof(struct t3_ioq_entry); 1622189643Sgnn for (i = 0; i < entries; i++) { 1623189643Sgnn printf("\nioq[%d].cp : 0x%08x\n", i, 1624189643Sgnn ioqs.data[i].ioq_cp); 1625189643Sgnn printf("ioq[%d].pp : 0x%08x\n", i, 1626189643Sgnn ioqs.data[i].ioq_pp); 1627189643Sgnn printf("ioq[%d].alen : 0x%08x\n", i, 1628189643Sgnn ioqs.data[i].ioq_alen); 1629189643Sgnn printf("ioq[%d].stats : 0x%08x\n", i, 1630189643Sgnn ioqs.data[i].ioq_stats); 1631189643Sgnn printf(" sop %u\n", ioqs.data[i].ioq_stats >> 16); 1632189643Sgnn printf(" eop %u\n", ioqs.data[i].ioq_stats & 0xFFFF); 1633189643Sgnn } 1634189643Sgnn 1635189643Sgnn return 0; 1636189643Sgnn} 1637189643Sgnn 1638194928Snpstatic int 1639194928Snprun_cmd(int argc, char *argv[], const char *iff_name) 1640167518Skmacy{ 1641167518Skmacy int r = -1; 1642167518Skmacy 1643167518Skmacy if (!strcmp(argv[2], "reg")) 1644167518Skmacy r = register_io(argc, argv, 3, iff_name); 1645167518Skmacy else if (!strcmp(argv[2], "mdio")) 1646167518Skmacy r = mdio_io(argc, argv, 3, iff_name); 1647167518Skmacy else if (!strcmp(argv[2], "mtus")) 1648167518Skmacy r = mtu_tab_op(argc, argv, 3, iff_name); 1649167518Skmacy else if (!strcmp(argv[2], "pm")) 1650167518Skmacy r = conf_pm(argc, argv, 3, iff_name); 1651167518Skmacy else if (!strcmp(argv[2], "regdump")) 1652167518Skmacy r = dump_regs(argc, argv, 3, iff_name); 1653182594Skmacy else if (!strcmp(argv[2], "tcamdump")) 1654182594Skmacy r = dump_tcam(argc, argv, 3, iff_name); 1655167518Skmacy else if (!strcmp(argv[2], "memdump")) 1656167518Skmacy r = dump_mc7(argc, argv, 3, iff_name); 1657167518Skmacy else if (!strcmp(argv[2], "meminfo")) 1658167518Skmacy r = meminfo(argc, argv, 3, iff_name); 1659167518Skmacy else if (!strcmp(argv[2], "context")) 1660167518Skmacy r = get_sge_context(argc, argv, 3, iff_name); 1661167518Skmacy else if (!strcmp(argv[2], "desc")) 1662167518Skmacy r = get_sge_desc(argc, argv, 3, iff_name); 1663182594Skmacy else if (!strcmp(argv[2], "loadfw")) 1664182594Skmacy r = load_fw(argc, argv, 3, iff_name); 1665182594Skmacy else if (!strcmp(argv[2], "loadboot")) 1666182594Skmacy r = load_boot(argc, argv, 3, iff_name); 1667182594Skmacy else if (!strcmp(argv[2], "proto")) 1668182594Skmacy r = proto_sram_op(argc, argv, 3, iff_name); 1669167518Skmacy else if (!strcmp(argv[2], "qset")) 1670167518Skmacy r = qset_config(argc, argv, 3, iff_name); 1671167518Skmacy else if (!strcmp(argv[2], "qsets")) 1672167518Skmacy r = qset_num_config(argc, argv, 3, iff_name); 1673167518Skmacy else if (!strcmp(argv[2], "trace")) 1674167518Skmacy r = trace_config(argc, argv, 3, iff_name); 1675167518Skmacy else if (!strcmp(argv[2], "pktsched")) 1676167518Skmacy r = pktsched(argc, argv, 3, iff_name); 1677182594Skmacy else if (!strcmp(argv[2], "tcb")) 1678182594Skmacy r = get_tcb2(argc, argv, 3, iff_name); 1679207643Snp else if (!strcmp(argv[2], "filter")) 1680207643Snp r = filter_config(argc, argv, 3, iff_name); 1681182594Skmacy else if (!strcmp(argv[2], "clearstats")) 1682182594Skmacy r = clear_stats(argc, argv, 3, iff_name); 1683189643Sgnn else if (!strcmp(argv[2], "la")) 1684189643Sgnn r = get_up_la(argc, argv, 3, iff_name); 1685189643Sgnn else if (!strcmp(argv[2], "ioqs")) 1686189643Sgnn r = get_up_ioqs(argc, argv, 3, iff_name); 1687182594Skmacy 1688167518Skmacy if (r == -1) 1689167518Skmacy usage(stderr); 1690182594Skmacy 1691194928Snp return (0); 1692167518Skmacy} 1693194928Snp 1694194928Snpstatic int 1695194928Snprun_cmd_loop(int argc, char *argv[], const char *iff_name) 1696194928Snp{ 1697204267Snp int n; 1698204267Snp unsigned int i; 1699194928Snp char buf[64]; 1700194928Snp char *args[8], *s; 1701194928Snp 1702204267Snp (void) argc; 1703194928Snp args[0] = argv[0]; 1704194928Snp args[1] = argv[1]; 1705194928Snp 1706194928Snp /* 1707194928Snp * Fairly simplistic loop. Displays a "> " prompt and processes any 1708194928Snp * input as a cxgbtool command. You're supposed to enter only the part 1709194928Snp * after "cxgbtool cxgbX". Use "quit" or "exit" to exit. Any error in 1710194928Snp * the command will also terminate cxgbtool. 1711194928Snp */ 1712194928Snp for (;;) { 1713194928Snp fprintf(stdout, "> "); 1714194928Snp fflush(stdout); 1715204267Snp n = read(STDIN_FILENO, buf, sizeof(buf) - 1); 1716204267Snp if (n <= 0) 1717194928Snp return (0); 1718194928Snp 1719194928Snp if (buf[--n] != '\n') 1720194928Snp continue; 1721194928Snp else 1722194928Snp buf[n] = 0; 1723194928Snp 1724194928Snp s = &buf[0]; 1725194928Snp for (i = 2; i < sizeof(args)/sizeof(args[0]) - 1; i++) { 1726194928Snp while (s && (*s == ' ' || *s == '\t')) 1727194928Snp s++; 1728194928Snp if ((args[i] = strsep(&s, " \t")) == NULL) 1729194928Snp break; 1730194928Snp } 1731194928Snp args[sizeof(args)/sizeof(args[0]) - 1] = 0; 1732194928Snp 1733194928Snp if (!strcmp(args[2], "quit") || !strcmp(args[2], "exit")) 1734194928Snp return (0); 1735194928Snp 1736194928Snp (void) run_cmd(i, args, iff_name); 1737194928Snp } 1738194928Snp 1739194928Snp /* Can't really get here */ 1740194928Snp return (0); 1741194928Snp} 1742194928Snp 1743194928Snpint 1744194928Snpmain(int argc, char *argv[]) 1745194928Snp{ 1746194928Snp int r = -1; 1747194928Snp const char *iff_name; 1748194928Snp 1749194928Snp progname = argv[0]; 1750194928Snp 1751194928Snp if (argc == 2) { 1752194928Snp if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) 1753194928Snp usage(stdout); 1754194928Snp if (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version")) { 1755194928Snp printf("%s version %s\n", PROGNAME, VERSION); 1756194928Snp printf("%s\n", COPYRIGHT); 1757194928Snp exit(0); 1758194928Snp } 1759194928Snp } 1760194928Snp 1761194928Snp if (argc < 3) usage(stderr); 1762194928Snp 1763194928Snp iff_name = argv[1]; 1764194928Snp 1765194928Snp if (argc == 3 && !strcmp(argv[2], "stdio")) 1766194928Snp r = run_cmd_loop(argc, argv, iff_name); 1767194928Snp else 1768194928Snp r = run_cmd(argc, argv, iff_name); 1769194928Snp 1770194928Snp return (r); 1771194928Snp} 1772