cxgbtool.c revision 167518
1/************************************************************************** 2 3Copyright (c) 2007, Chelsio Inc. 4All rights reserved. 5 6Redistribution and use in source and binary forms, with or without 7modification, are permitted provided that the following conditions are met: 8 9 1. Redistributions of source code must retain the above copyright notice, 10 this list of conditions and the following disclaimer. 11 12 2. Redistributions in binary form must reproduce the above copyright 13 notice, this list of conditions and the following disclaimer in the 14 documentation and/or other materials provided with the distribution. 15 16 3. Neither the name of the Chelsio Corporation nor the names of its 17 contributors may be used to endorse or promote products derived from 18 this software without specific prior written permission. 19 20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30POSSIBILITY OF SUCH DAMAGE. 31 32 33***************************************************************************/ 34#include <sys/cdefs.h> 35__FBSDID("$FreeBSD: head/usr.sbin/cxgbtool/cxgbtool.c 167518 2007-03-14 02:51:57Z kmacy $"); 36 37#include <stdlib.h> 38#include <stdio.h> 39#include <stdint.h> 40#include <string.h> 41#include <unistd.h> 42#include <fcntl.h> 43#include <err.h> 44#include <errno.h> 45#include <inttypes.h> 46#include <sys/param.h> 47#include <sys/time.h> 48#include <sys/ioctl.h> 49#include <sys/socket.h> 50 51#include <netinet/in.h> 52#include <arpa/inet.h> 53 54#include <net/if.h> 55#include <net/if_var.h> 56#include <net/if_types.h> 57 58#define NMTUS 16 59#define TCB_SIZE 128 60#define TCB_WORDS (TCB_SIZE / 4) 61#define PROTO_SRAM_LINES 128 62#define PROTO_SRAM_LINE_BITS 132 63#define PROTO_SRAM_LINE_NIBBLES (132 / 4) 64#define PROTO_SRAM_SIZE (PROTO_SRAM_LINE_NIBBLES * PROTO_SRAM_LINES / 2) 65#define PROTO_SRAM_EEPROM_ADDR 4096 66 67#include <cxgb3_ioctl.h> 68#include <common/cxgb3_regs.h> 69#include "version.h" 70 71struct reg_info { 72 const char *name; 73 uint16_t addr; 74 uint16_t len; 75}; 76 77 78#include "reg_defs.c" 79#if defined(CONFIG_T3_REGS) 80# include "reg_defs_t3.c" 81# include "reg_defs_t3b.c" 82#endif 83 84static const char *progname; 85 86static void __attribute__((noreturn)) usage(FILE *fp) 87{ 88 fprintf(fp, "Usage: %s <interface> [operation]\n", progname); 89 fprintf(fp, 90#ifdef CHELSIO_INTERNAL 91 "\treg <address>[=<val>] read/write register\n" 92 "\ttpi <address>[=<val>] read/write TPI register\n" 93 "\tmdio <phy_addr> <mmd_addr>\n" 94 "\t <reg_addr> [<val>] read/write MDIO register\n" 95#endif 96 "\tmtus [<mtu0>...<mtuN>] read/write MTU table\n" 97#ifdef CHELSIO_INTERNAL 98 "\tpm [<TX page spec> <RX page spec>] read/write PM config\n" 99 "\ttcam [<#serv> <#routes> <#filters>] read/write TCAM config\n" 100 "\ttcb <index> read TCB\n" 101#endif 102 "\tregdump [<module>] dump registers\n" 103#ifdef CHELSIO_INTERNAL 104 "\ttcamdump <address> <count> show TCAM contents\n" 105 "\tcontext <type> <id> show an SGE context\n" 106 "\tdesc <qset> <queue> <idx> [<cnt>] dump SGE descriptors\n" 107 "\tmemdump cm|tx|rx <addr> <len> dump a mem range\n" 108 "\tmeminfo show memory info\n" 109#endif 110 "\tup activate TOE\n" 111 "\tproto [<protocol image>] read/write proto SRAM\n" 112 "\tloadfw <FW image> download firmware\n" 113 "\tqset [<index> [<param> <val>] ...] read/write qset parameters\n" 114 "\tqsets [<# of qsets>] read/write # of qsets\n" 115 "\ttrace tx|rx|all on|off [not]\n" 116 "\t [<param> <val>[:<mask>]] ... write trace parameters\n" 117 "\tt1powersave [on|off] enable/disable T1xx powersave mode\n" 118 "\tpktsched port <idx> <min> <max> set TX port scheduler params\n" 119 "\tpktsched tunnelq <idx> <max>\n" 120 "\t <binding> set TX tunnelq scheduler params\n" 121 ); 122 exit(fp == stderr ? 1 : 0); 123} 124 125/* 126 * Make a TOETOOL ioctl call. 127 */ 128static int 129doit(const char *iff_name, unsigned long cmd, void *data) 130{ 131 static int fd = 0; 132 133 if (fd == 0) { 134 char buf[64]; 135 snprintf(buf, 64, "/dev/%s", iff_name); 136 137 if ((fd = open(buf, O_RDWR)) < 0) 138 return (EINVAL); 139 } 140 141 return ioctl(fd, cmd, data) < 0 ? -1 : 0; 142} 143 144static int get_int_arg(const char *s, uint32_t *valp) 145{ 146 char *p; 147 148 *valp = strtoul(s, &p, 0); 149 if (*p) { 150 warnx("bad parameter \"%s\"", s); 151 return -1; 152 } 153 return 0; 154} 155 156static uint32_t 157read_reg(const char *iff_name, uint32_t addr) 158{ 159 struct ch_reg reg; 160 161 reg.addr = addr; 162 163 if (doit(iff_name, CHELSIO_GETREG, ®) < 0) 164 err(1, "register read"); 165 return reg.val; 166} 167 168static void 169write_reg(const char *iff_name, uint32_t addr, uint32_t val) 170{ 171 struct ch_reg ch_reg; 172 173 ch_reg.addr = addr; 174 ch_reg.val = val; 175 176 if (doit(iff_name, CHELSIO_SETREG, &ch_reg) < 0) 177 err(1, "register write"); 178} 179 180static int register_io(int argc, char *argv[], int start_arg, 181 const char *iff_name) 182{ 183 char *p; 184 uint32_t addr, val = 0, write = 0; 185 186 if (argc != start_arg + 1) return -1; 187 188 addr = strtoul(argv[start_arg], &p, 0); 189 if (p == argv[start_arg]) return -1; 190 if (*p == '=' && p[1]) { 191 val = strtoul(p + 1, &p, 0); 192 write = 1; 193 } 194 if (*p) { 195 warnx("bad parameter \"%s\"", argv[start_arg]); 196 return -1; 197 } 198 199 if (write) 200 write_reg(iff_name, addr, val); 201 else { 202 val = read_reg(iff_name, addr); 203 printf("%#x [%u]\n", val, val); 204 } 205 return 0; 206} 207 208static int mdio_io(int argc, char *argv[], int start_arg, const char *iff_name) 209{ 210 struct ifreq ifr; 211 struct mii_data p; 212 unsigned int cmd, phy_addr, reg, mmd, val; 213 214 if (argc == start_arg + 3) 215 cmd = SIOCGMIIREG; 216 else if (argc == start_arg + 4) 217 cmd = SIOCSMIIREG; 218 else 219 return -1; 220 221 if (get_int_arg(argv[start_arg], &phy_addr) || 222 get_int_arg(argv[start_arg + 1], &mmd) || 223 get_int_arg(argv[start_arg + 2], ®) || 224 (cmd == SIOCSMIIREG && get_int_arg(argv[start_arg + 3], &val))) 225 return -1; 226 227 p.phy_id = phy_addr | (mmd << 8); 228 p.reg_num = reg; 229 p.val_in = val; 230 231 if (doit(iff_name, cmd, &p) < 0) 232 err(1, "MDIO %s", cmd == SIOCGMIIREG ? "read" : "write"); 233 if (cmd == SIOCGMIIREG) 234 printf("%#x [%u]\n", p.val_out, p.val_out); 235 return 0; 236} 237 238static inline uint32_t xtract(uint32_t val, int shift, int len) 239{ 240 return (val >> shift) & ((1 << len) - 1); 241} 242 243static int dump_block_regs(const struct reg_info *reg_array, uint32_t *regs) 244{ 245 uint32_t reg_val = 0; // silence compiler warning 246 247 for ( ; reg_array->name; ++reg_array) 248 if (!reg_array->len) { 249 reg_val = regs[reg_array->addr / 4]; 250 printf("[%#5x] %-40s %#-10x [%u]\n", reg_array->addr, 251 reg_array->name, reg_val, reg_val); 252 } else { 253 uint32_t v = xtract(reg_val, reg_array->addr, 254 reg_array->len); 255 256 printf(" %-40s %#-10x [%u]\n", reg_array->name, 257 v, v); 258 } 259 return 1; 260} 261 262static int dump_regs_t2(int argc, char *argv[], int start_arg, uint32_t *regs) 263{ 264 int match = 0; 265 char *block_name = NULL; 266 267 if (argc == start_arg + 1) 268 block_name = argv[start_arg]; 269 else if (argc != start_arg) 270 return -1; 271 272 if (!block_name || !strcmp(block_name, "sge")) 273 match += dump_block_regs(sge_regs, regs); 274 if (!block_name || !strcmp(block_name, "mc3")) 275 match += dump_block_regs(mc3_regs, regs); 276 if (!block_name || !strcmp(block_name, "mc4")) 277 match += dump_block_regs(mc4_regs, regs); 278 if (!block_name || !strcmp(block_name, "tpi")) 279 match += dump_block_regs(tpi_regs, regs); 280 if (!block_name || !strcmp(block_name, "tp")) 281 match += dump_block_regs(tp_regs, regs); 282 if (!block_name || !strcmp(block_name, "rat")) 283 match += dump_block_regs(rat_regs, regs); 284 if (!block_name || !strcmp(block_name, "cspi")) 285 match += dump_block_regs(cspi_regs, regs); 286 if (!block_name || !strcmp(block_name, "espi")) 287 match += dump_block_regs(espi_regs, regs); 288 if (!block_name || !strcmp(block_name, "ulp")) 289 match += dump_block_regs(ulp_regs, regs); 290 if (!block_name || !strcmp(block_name, "pl")) 291 match += dump_block_regs(pl_regs, regs); 292 if (!block_name || !strcmp(block_name, "mc5")) 293 match += dump_block_regs(mc5_regs, regs); 294 if (!match) 295 errx(1, "unknown block \"%s\"", block_name); 296 return 0; 297} 298 299#if defined(CONFIG_T3_REGS) 300static int dump_regs_t3(int argc, char *argv[], int start_arg, uint32_t *regs, 301 int is_pcie) 302{ 303 int match = 0; 304 char *block_name = NULL; 305 306 if (argc == start_arg + 1) 307 block_name = argv[start_arg]; 308 else if (argc != start_arg) 309 return -1; 310 311 if (!block_name || !strcmp(block_name, "sge")) 312 match += dump_block_regs(sge3_regs, regs); 313 if (!block_name || !strcmp(block_name, "pci")) 314 match += dump_block_regs(is_pcie ? pcie0_regs : pcix1_regs, 315 regs); 316 if (!block_name || !strcmp(block_name, "t3dbg")) 317 match += dump_block_regs(t3dbg_regs, regs); 318 if (!block_name || !strcmp(block_name, "pmrx")) 319 match += dump_block_regs(mc7_pmrx_regs, regs); 320 if (!block_name || !strcmp(block_name, "pmtx")) 321 match += dump_block_regs(mc7_pmtx_regs, regs); 322 if (!block_name || !strcmp(block_name, "cm")) 323 match += dump_block_regs(mc7_cm_regs, regs); 324 if (!block_name || !strcmp(block_name, "cim")) 325 match += dump_block_regs(cim_regs, regs); 326 if (!block_name || !strcmp(block_name, "tp")) 327 match += dump_block_regs(tp1_regs, regs); 328 if (!block_name || !strcmp(block_name, "ulp_rx")) 329 match += dump_block_regs(ulp2_rx_regs, regs); 330 if (!block_name || !strcmp(block_name, "ulp_tx")) 331 match += dump_block_regs(ulp2_tx_regs, regs); 332 if (!block_name || !strcmp(block_name, "pmrx")) 333 match += dump_block_regs(pm1_rx_regs, regs); 334 if (!block_name || !strcmp(block_name, "pmtx")) 335 match += dump_block_regs(pm1_tx_regs, regs); 336 if (!block_name || !strcmp(block_name, "mps")) 337 match += dump_block_regs(mps0_regs, regs); 338 if (!block_name || !strcmp(block_name, "cplsw")) 339 match += dump_block_regs(cpl_switch_regs, regs); 340 if (!block_name || !strcmp(block_name, "smb")) 341 match += dump_block_regs(smb0_regs, regs); 342 if (!block_name || !strcmp(block_name, "i2c")) 343 match += dump_block_regs(i2cm0_regs, regs); 344 if (!block_name || !strcmp(block_name, "mi1")) 345 match += dump_block_regs(mi1_regs, regs); 346 if (!block_name || !strcmp(block_name, "sf")) 347 match += dump_block_regs(sf1_regs, regs); 348 if (!block_name || !strcmp(block_name, "pl")) 349 match += dump_block_regs(pl3_regs, regs); 350 if (!block_name || !strcmp(block_name, "mc5")) 351 match += dump_block_regs(mc5a_regs, regs); 352 if (!block_name || !strcmp(block_name, "xgmac0")) 353 match += dump_block_regs(xgmac0_0_regs, regs); 354 if (!block_name || !strcmp(block_name, "xgmac1")) 355 match += dump_block_regs(xgmac0_1_regs, regs); 356 if (!match) 357 errx(1, "unknown block \"%s\"", block_name); 358 return 0; 359} 360 361static int dump_regs_t3b(int argc, char *argv[], int start_arg, uint32_t *regs, 362 int is_pcie) 363{ 364 int match = 0; 365 char *block_name = NULL; 366 367 if (argc == start_arg + 1) 368 block_name = argv[start_arg]; 369 else if (argc != start_arg) 370 return -1; 371 372 if (!block_name || !strcmp(block_name, "sge")) 373 match += dump_block_regs(t3b_sge3_regs, regs); 374 if (!block_name || !strcmp(block_name, "pci")) 375 match += dump_block_regs(is_pcie ? t3b_pcie0_regs : 376 t3b_pcix1_regs, regs); 377 if (!block_name || !strcmp(block_name, "t3dbg")) 378 match += dump_block_regs(t3b_t3dbg_regs, regs); 379 if (!block_name || !strcmp(block_name, "pmrx")) 380 match += dump_block_regs(t3b_mc7_pmrx_regs, regs); 381 if (!block_name || !strcmp(block_name, "pmtx")) 382 match += dump_block_regs(t3b_mc7_pmtx_regs, regs); 383 if (!block_name || !strcmp(block_name, "cm")) 384 match += dump_block_regs(t3b_mc7_cm_regs, regs); 385 if (!block_name || !strcmp(block_name, "cim")) 386 match += dump_block_regs(t3b_cim_regs, regs); 387 if (!block_name || !strcmp(block_name, "tp")) 388 match += dump_block_regs(t3b_tp1_regs, regs); 389 if (!block_name || !strcmp(block_name, "ulp_rx")) 390 match += dump_block_regs(t3b_ulp2_rx_regs, regs); 391 if (!block_name || !strcmp(block_name, "ulp_tx")) 392 match += dump_block_regs(t3b_ulp2_tx_regs, regs); 393 if (!block_name || !strcmp(block_name, "pmrx")) 394 match += dump_block_regs(t3b_pm1_rx_regs, regs); 395 if (!block_name || !strcmp(block_name, "pmtx")) 396 match += dump_block_regs(t3b_pm1_tx_regs, regs); 397 if (!block_name || !strcmp(block_name, "mps")) 398 match += dump_block_regs(t3b_mps0_regs, regs); 399 if (!block_name || !strcmp(block_name, "cplsw")) 400 match += dump_block_regs(t3b_cpl_switch_regs, regs); 401 if (!block_name || !strcmp(block_name, "smb")) 402 match += dump_block_regs(t3b_smb0_regs, regs); 403 if (!block_name || !strcmp(block_name, "i2c")) 404 match += dump_block_regs(t3b_i2cm0_regs, regs); 405 if (!block_name || !strcmp(block_name, "mi1")) 406 match += dump_block_regs(t3b_mi1_regs, regs); 407 if (!block_name || !strcmp(block_name, "sf")) 408 match += dump_block_regs(t3b_sf1_regs, regs); 409 if (!block_name || !strcmp(block_name, "pl")) 410 match += dump_block_regs(t3b_pl3_regs, regs); 411 if (!block_name || !strcmp(block_name, "mc5")) 412 match += dump_block_regs(t3b_mc5a_regs, regs); 413 if (!block_name || !strcmp(block_name, "xgmac0")) 414 match += dump_block_regs(t3b_xgmac0_0_regs, regs); 415 if (!block_name || !strcmp(block_name, "xgmac1")) 416 match += dump_block_regs(t3b_xgmac0_1_regs, regs); 417 if (!match) 418 errx(1, "unknown block \"%s\"", block_name); 419 return 0; 420} 421#endif 422 423static int 424dump_regs(int argc, char *argv[], int start_arg, const char *iff_name) 425{ 426 427 428 int i, vers, revision, is_pcie; 429 struct ifconf_regs regs; 430 431 regs.len = REGDUMP_SIZE; 432 433 if ((regs.data = malloc(REGDUMP_SIZE)) == NULL) 434 err(1, "can't malloc"); 435 436 if (doit(iff_name, CHELSIO_IFCONF_GETREGS, ®s)) 437 err(1, "can't read registers"); 438 439 vers = regs.version & 0x3ff; 440 revision = (regs.version >> 10) & 0x3f; 441 is_pcie = (regs.version & 0x80000000) != 0; 442 443 if (vers <= 2) 444 return dump_regs_t2(argc, argv, start_arg, (uint32_t *)regs.data); 445#if defined(CONFIG_T3_REGS) 446 if (vers == 3) { 447 if (revision == 0) 448 return dump_regs_t3(argc, argv, start_arg, 449 (uint32_t *)regs.data, is_pcie); 450 if (revision == 2) 451 return dump_regs_t3b(argc, argv, start_arg, 452 (uint32_t *)regs.data, is_pcie); 453 } 454#endif 455 errx(1, "unknown card type %d", vers); 456 return 0; 457} 458 459static int t3_meminfo(const uint32_t *regs) 460{ 461 enum { 462 SG_EGR_CNTX_BADDR = 0x58, 463 SG_CQ_CONTEXT_BADDR = 0x6c, 464 CIM_SDRAM_BASE_ADDR = 0x28c, 465 CIM_SDRAM_ADDR_SIZE = 0x290, 466 TP_CMM_MM_BASE = 0x314, 467 TP_CMM_TIMER_BASE = 0x318, 468 TP_CMM_MM_RX_FLST_BASE = 0x460, 469 TP_CMM_MM_TX_FLST_BASE = 0x464, 470 TP_CMM_MM_PS_FLST_BASE = 0x468, 471 ULPRX_ISCSI_LLIMIT = 0x50c, 472 ULPRX_ISCSI_ULIMIT = 0x510, 473 ULPRX_TDDP_LLIMIT = 0x51c, 474 ULPRX_TDDP_ULIMIT = 0x520, 475 ULPRX_STAG_LLIMIT = 0x52c, 476 ULPRX_STAG_ULIMIT = 0x530, 477 ULPRX_RQ_LLIMIT = 0x534, 478 ULPRX_RQ_ULIMIT = 0x538, 479 ULPRX_PBL_LLIMIT = 0x53c, 480 ULPRX_PBL_ULIMIT = 0x540, 481 }; 482 483 unsigned int egr_cntxt = regs[SG_EGR_CNTX_BADDR / 4], 484 cq_cntxt = regs[SG_CQ_CONTEXT_BADDR / 4], 485 timers = regs[TP_CMM_TIMER_BASE / 4] & 0xfffffff, 486 pstructs = regs[TP_CMM_MM_BASE / 4], 487 pstruct_fl = regs[TP_CMM_MM_PS_FLST_BASE / 4], 488 rx_fl = regs[TP_CMM_MM_RX_FLST_BASE / 4], 489 tx_fl = regs[TP_CMM_MM_TX_FLST_BASE / 4], 490 cim_base = regs[CIM_SDRAM_BASE_ADDR / 4], 491 cim_size = regs[CIM_SDRAM_ADDR_SIZE / 4]; 492 unsigned int iscsi_ll = regs[ULPRX_ISCSI_LLIMIT / 4], 493 iscsi_ul = regs[ULPRX_ISCSI_ULIMIT / 4], 494 tddp_ll = regs[ULPRX_TDDP_LLIMIT / 4], 495 tddp_ul = regs[ULPRX_TDDP_ULIMIT / 4], 496 stag_ll = regs[ULPRX_STAG_LLIMIT / 4], 497 stag_ul = regs[ULPRX_STAG_ULIMIT / 4], 498 rq_ll = regs[ULPRX_RQ_LLIMIT / 4], 499 rq_ul = regs[ULPRX_RQ_ULIMIT / 4], 500 pbl_ll = regs[ULPRX_PBL_LLIMIT / 4], 501 pbl_ul = regs[ULPRX_PBL_ULIMIT / 4]; 502 503 printf("CM memory map:\n"); 504 printf(" TCB region: 0x%08x - 0x%08x [%u]\n", 0, egr_cntxt - 1, 505 egr_cntxt); 506 printf(" Egress contexts: 0x%08x - 0x%08x [%u]\n", egr_cntxt, 507 cq_cntxt - 1, cq_cntxt - egr_cntxt); 508 printf(" CQ contexts: 0x%08x - 0x%08x [%u]\n", cq_cntxt, 509 timers - 1, timers - cq_cntxt); 510 printf(" Timers: 0x%08x - 0x%08x [%u]\n", timers, 511 pstructs - 1, pstructs - timers); 512 printf(" Pstructs: 0x%08x - 0x%08x [%u]\n", pstructs, 513 pstruct_fl - 1, pstruct_fl - pstructs); 514 printf(" Pstruct FL: 0x%08x - 0x%08x [%u]\n", pstruct_fl, 515 rx_fl - 1, rx_fl - pstruct_fl); 516 printf(" Rx FL: 0x%08x - 0x%08x [%u]\n", rx_fl, tx_fl - 1, 517 tx_fl - rx_fl); 518 printf(" Tx FL: 0x%08x - 0x%08x [%u]\n", tx_fl, cim_base - 1, 519 cim_base - tx_fl); 520 printf(" uP RAM: 0x%08x - 0x%08x [%u]\n", cim_base, 521 cim_base + cim_size - 1, cim_size); 522 523 printf("\nPMRX memory map:\n"); 524 printf(" iSCSI region: 0x%08x - 0x%08x [%u]\n", iscsi_ll, iscsi_ul, 525 iscsi_ul - iscsi_ll + 1); 526 printf(" TCP DDP region: 0x%08x - 0x%08x [%u]\n", tddp_ll, tddp_ul, 527 tddp_ul - tddp_ll + 1); 528 printf(" TPT region: 0x%08x - 0x%08x [%u]\n", stag_ll, stag_ul, 529 stag_ul - stag_ll + 1); 530 printf(" RQ region: 0x%08x - 0x%08x [%u]\n", rq_ll, rq_ul, 531 rq_ul - rq_ll + 1); 532 printf(" PBL region: 0x%08x - 0x%08x [%u]\n", pbl_ll, pbl_ul, 533 pbl_ul - pbl_ll + 1); 534 return 0; 535} 536 537static int meminfo(int argc, char *argv[], int start_arg, const char *iff_name) 538{ 539 int vers; 540 struct ifconf_regs regs; 541 542 if ((regs.data = malloc(REGDUMP_SIZE)) == NULL) 543 err(1, "can't malloc"); 544 545 if (doit(iff_name, CHELSIO_IFCONF_GETREGS, ®s)) 546 err(1, "can't read registers"); 547 548 vers = regs.version & 0x3ff; 549 if (vers == 3) 550 return t3_meminfo((uint32_t *)regs.data); 551 552 errx(1, "unknown card type %d", vers); 553 return 0; 554} 555 556#ifdef notyet 557static int mtu_tab_op(int argc, char *argv[], int start_arg, 558 const char *iff_name) 559{ 560 struct toetool_mtus op; 561 int i; 562 563 if (argc == start_arg) { 564 op.cmd = TOETOOL_GETMTUTAB; 565 op.nmtus = MAX_NMTUS; 566 567 if (doit(iff_name, &op) < 0) 568 err(1, "get MTU table"); 569 for (i = 0; i < op.nmtus; ++i) 570 printf("%u ", op.mtus[i]); 571 printf("\n"); 572 } else if (argc <= start_arg + MAX_NMTUS) { 573 op.cmd = TOETOOL_SETMTUTAB; 574 op.nmtus = argc - start_arg; 575 576 for (i = 0; i < op.nmtus; ++i) { 577 char *p; 578 unsigned long m = strtoul(argv[start_arg + i], &p, 0); 579 580 if (*p || m > 9600) { 581 warnx("bad parameter \"%s\"", 582 argv[start_arg + i]); 583 return -1; 584 } 585 if (i && m < op.mtus[i - 1]) 586 errx(1, "MTUs must be in ascending order"); 587 op.mtus[i] = m; 588 } 589 if (doit(iff_name, &op) < 0) 590 err(1, "set MTU table"); 591 } else 592 return -1; 593 594 return 0; 595} 596#endif 597 598#ifdef CHELSIO_INTERNAL 599static void show_egress_cntxt(uint32_t data[]) 600{ 601 printf("credits: %u\n", data[0] & 0x7fff); 602 printf("GTS: %u\n", (data[0] >> 15) & 1); 603 printf("index: %u\n", data[0] >> 16); 604 printf("queue size: %u\n", data[1] & 0xffff); 605 printf("base address: 0x%llx\n", 606 ((data[1] >> 16) | ((uint64_t)data[2] << 16) | 607 (((uint64_t)data[3] & 0xf) << 48)) << 12); 608 printf("rsp queue #: %u\n", (data[3] >> 4) & 7); 609 printf("cmd queue #: %u\n", (data[3] >> 7) & 1); 610 printf("TUN: %u\n", (data[3] >> 8) & 1); 611 printf("TOE: %u\n", (data[3] >> 9) & 1); 612 printf("generation: %u\n", (data[3] >> 10) & 1); 613 printf("uP token: %u\n", (data[3] >> 11) & 0xfffff); 614 printf("valid: %u\n", (data[3] >> 31) & 1); 615} 616 617static void show_fl_cntxt(uint32_t data[]) 618{ 619 printf("base address: 0x%llx\n", 620 ((uint64_t)data[0] | ((uint64_t)data[1] & 0xfffff) << 32) << 12); 621 printf("index: %u\n", (data[1] >> 20) | ((data[2] & 0xf) << 12)); 622 printf("queue size: %u\n", (data[2] >> 4) & 0xffff); 623 printf("generation: %u\n", (data[2] >> 20) & 1); 624 printf("entry size: %u\n", 625 ((data[2] >> 21) & 0x7ff) | (data[3] & 0x1fffff)); 626 printf("congest thr: %u\n", (data[3] >> 21) & 0x3ff); 627 printf("GTS: %u\n", (data[3] >> 31) & 1); 628} 629 630static void show_response_cntxt(uint32_t data[]) 631{ 632 printf("index: %u\n", data[0] & 0xffff); 633 printf("size: %u\n", data[0] >> 16); 634 printf("base address: 0x%llx\n", 635 ((uint64_t)data[1] | ((uint64_t)data[2] & 0xfffff) << 32) << 12); 636 printf("MSI-X/RspQ: %u\n", (data[2] >> 20) & 0x3f); 637 printf("intr enable: %u\n", (data[2] >> 26) & 1); 638 printf("intr armed: %u\n", (data[2] >> 27) & 1); 639 printf("generation: %u\n", (data[2] >> 28) & 1); 640 printf("CQ mode: %u\n", (data[2] >> 31) & 1); 641 printf("FL threshold: %u\n", data[3]); 642} 643 644static void show_cq_cntxt(uint32_t data[]) 645{ 646 printf("index: %u\n", data[0] & 0xffff); 647 printf("size: %u\n", data[0] >> 16); 648 printf("base address: 0x%llx\n", 649 ((uint64_t)data[1] | ((uint64_t)data[2] & 0xfffff) << 32) << 12); 650 printf("rsp queue #: %u\n", (data[2] >> 20) & 0x3f); 651 printf("AN: %u\n", (data[2] >> 26) & 1); 652 printf("armed: %u\n", (data[2] >> 27) & 1); 653 printf("ANS: %u\n", (data[2] >> 28) & 1); 654 printf("generation: %u\n", (data[2] >> 29) & 1); 655 printf("overflow mode: %u\n", (data[2] >> 31) & 1); 656 printf("credits: %u\n", data[3] & 0xffff); 657 printf("credit threshold: %u\n", data[3] >> 16); 658} 659 660static int get_sge_context(int argc, char *argv[], int start_arg, 661 const char *iff_name) 662{ 663 struct ch_cntxt ctx; 664 665 if (argc != start_arg + 2) return -1; 666 667 if (!strcmp(argv[start_arg], "egress")) 668 ctx.cntxt_type = CNTXT_TYPE_EGRESS; 669 else if (!strcmp(argv[start_arg], "fl")) 670 ctx.cntxt_type = CNTXT_TYPE_FL; 671 else if (!strcmp(argv[start_arg], "response")) 672 ctx.cntxt_type = CNTXT_TYPE_RSP; 673 else if (!strcmp(argv[start_arg], "cq")) 674 ctx.cntxt_type = CNTXT_TYPE_CQ; 675 else { 676 warnx("unknown context type \"%s\"; known types are egress, " 677 "fl, cq, and response", argv[start_arg]); 678 return -1; 679 } 680 681 if (get_int_arg(argv[start_arg + 1], &ctx.cntxt_id)) 682 return -1; 683 684 if (doit(iff_name, CHELSIO_GET_SGE_CONTEXT, &ctx) < 0) 685 err(1, "get SGE context"); 686 687 if (!strcmp(argv[start_arg], "egress")) 688 show_egress_cntxt(ctx.data); 689 else if (!strcmp(argv[start_arg], "fl")) 690 show_fl_cntxt(ctx.data); 691 else if (!strcmp(argv[start_arg], "response")) 692 show_response_cntxt(ctx.data); 693 else if (!strcmp(argv[start_arg], "cq")) 694 show_cq_cntxt(ctx.data); 695 return 0; 696} 697 698#if __BYTE_ORDER == __BIG_ENDIAN 699# define ntohll(n) (n) 700#else 701# define ntohll(n) bswap_64(n) 702#endif 703 704static int get_sge_desc(int argc, char *argv[], int start_arg, 705 const char *iff_name) 706{ 707 uint64_t *p, wr_hdr; 708 unsigned int n = 1, qset, qnum; 709 struct ch_desc desc; 710 711 if (argc != start_arg + 3 && argc != start_arg + 4) 712 return -1; 713 714 if (get_int_arg(argv[start_arg], &qset) || 715 get_int_arg(argv[start_arg + 1], &qnum) || 716 get_int_arg(argv[start_arg + 2], &desc.idx)) 717 return -1; 718 719 if (argc == start_arg + 4 && get_int_arg(argv[start_arg + 3], &n)) 720 return -1; 721 722 if (qnum > 5) 723 errx(1, "invalid queue number %d, range is 0..5", qnum); 724 725 desc.queue_num = qset * 6 + qnum; 726 727 for (; n--; desc.idx++) { 728 if (doit(iff_name, CHELSIO_GET_SGE_DESC, &desc) < 0) 729 err(1, "get SGE descriptor"); 730 731 p = (uint64_t *)desc.data; 732 wr_hdr = ntohll(*p); 733 printf("Descriptor %u: cmd %u, TID %u, %s%s%s%s%u flits\n", 734 desc.idx, (unsigned int)(wr_hdr >> 56), 735 ((unsigned int)wr_hdr >> 8) & 0xfffff, 736 ((wr_hdr >> 55) & 1) ? "SOP, " : "", 737 ((wr_hdr >> 54) & 1) ? "EOP, " : "", 738 ((wr_hdr >> 53) & 1) ? "COMPL, " : "", 739 ((wr_hdr >> 52) & 1) ? "SGL, " : "", 740 (unsigned int)wr_hdr & 0xff); 741 742 for (; desc.size; p++, desc.size -= sizeof(uint64_t)) 743 printf("%016" PRIx64 "%c", ntohll(*p), 744 desc.size % 32 == 8 ? '\n' : ' '); 745 } 746 return 0; 747} 748#endif 749 750#ifdef notyet 751static int get_tcb2(unsigned int tcb_idx, const char *iff_name) 752{ 753 uint64_t *d; 754 unsigned int i; 755 struct toetool_mem_range *op; 756 757 op = malloc(sizeof(*op) + TCB_SIZE); 758 if (!op) 759 err(1, "get TCB"); 760 761 op->cmd = TOETOOL_GET_MEM; 762 op->mem_id = MEM_CM; 763 op->addr = tcb_idx * TCB_SIZE; 764 op->len = TCB_SIZE; 765 766 if (doit(iff_name, op) < 0) 767 err(1, "get TCB"); 768 769 for (d = (uint64_t *)op->buf, i = 0; i < TCB_SIZE / 32; i++) { 770 printf("%2u:", i); 771 printf(" %08x %08x %08x %08x", (uint32_t)d[1], 772 (uint32_t)(d[1] >> 32), (uint32_t)d[0], 773 (uint32_t)(d[0] >> 32)); 774 d += 2; 775 printf(" %08x %08x %08x %08x\n", (uint32_t)d[1], 776 (uint32_t)(d[1] >> 32), (uint32_t)d[0], 777 (uint32_t)(d[0] >> 32)); 778 d += 2; 779 } 780 free(op); 781 return 0; 782} 783 784static int get_tcb(int argc, char *argv[], int start_arg, const char *iff_name) 785{ 786 int i; 787 uint32_t *d; 788 struct toetool_tcb op; 789 790 if (argc != start_arg + 1) return -1; 791 792 op.cmd = TOETOOL_GET_TCB; 793 if (get_int_arg(argv[start_arg], &op.tcb_index)) 794 return -1; 795 796 /* 797 * If this operation isn't directly supported by the driver we may 798 * still be able to read TCBs using the generic memory dump operation. 799 */ 800 if (doit(iff_name, &op) < 0) { 801 if (errno != EOPNOTSUPP) 802 err(1, "get TCB"); 803 return get_tcb2(op.tcb_index, iff_name); 804 } 805 806 for (d = op.tcb_data, i = 0; i < TCB_WORDS; i += 8) { 807 int j; 808 809 printf("%2u:", 4 * i); 810 for (j = 0; j < 8; ++j) 811 printf(" %08x", *d++); 812 printf("\n"); 813 } 814 return 0; 815} 816#endif 817#ifdef WRC 818/* 819 * The following defines, typedefs and structures are defined in the FW and 820 * should be exported instead of being redefined here (and kept up in sync). 821 * We'll fix this in the next round of FW cleanup. 822 */ 823#define CM_WRCONTEXT_BASE 0x20300000 824#define CM_WRCONTEXT_OFFSET 0x300000 825#define WRC_SIZE (FW_WR_SIZE * (2 + FW_WR_NUM) + 32 + 4 * 128) 826#define FW_WR_SIZE 128 827#define FW_WR_NUM 16 828#define FBUF_SIZE (FW_WR_SIZE * FW_WR_NUM) 829#define FBUF_WRAP_SIZE 128 830#define FBUF_WRAP_FSZ (FBUF_WRAP_SZ >> 3) 831#define MEM_CM_WRC_SIZE WRC_SIZE 832 833typedef char int8_t; 834typedef short int16_t; 835typedef int int32_t; 836typedef long long _s64; 837typedef unsigned char _u8; 838typedef unsigned short _u16; 839typedef unsigned int _uint32_t; 840typedef unsigned long long uint64_t; 841 842enum fw_ri_mpa_attrs { 843 FW_RI_MPA_RX_MARKER_ENABLE = 0x1, 844 FW_RI_MPA_TX_MARKER_ENABLE = 0x2, 845 FW_RI_MPA_CRC_ENABLE = 0x4, 846 FW_RI_MPA_IETF_ENABLE = 0x8 847} __attribute__ ((packed)); 848 849enum fw_ri_qp_caps { 850 FW_RI_QP_RDMA_READ_ENABLE = 0x01, 851 FW_RI_QP_RDMA_WRITE_ENABLE = 0x02, 852 FW_RI_QP_BIND_ENABLE = 0x04, 853 FW_RI_QP_FAST_REGISTER_ENABLE = 0x08, 854 FW_RI_QP_STAG0_ENABLE = 0x10 855} __attribute__ ((packed)); 856 857enum wrc_state { 858 WRC_STATE_CLOSED, 859 WRC_STATE_ABORTED, 860 WRC_STATE_HALFCLOSED, 861 WRC_STATE_TOE_ESTABLISHED, 862 WRC_STATE_RDMA_TX_DATA_PEND, 863 WRC_STATE_RDMA_PEND, 864 WRC_STATE_RDMA_ESTABLISHED, 865}; 866 867struct _wr { 868 uint32_t a; 869 uint32_t b; 870}; 871 872struct fbuf { 873 uint32_t pp; /* fifo producer pointer */ 874 uint32_t cp; /* fifo consumer pointer */ 875 int32_t num_bytes; /* num bytes stored in the fbuf */ 876 char bufferb[FBUF_SIZE]; /* buffer space in bytes */ 877 char _wrap[FBUF_WRAP_SIZE]; /* wrap buffer size*/ 878}; 879struct wrc { 880 uint32_t wrc_tid; 881 _u16 wrc_flags; 882 _u8 wrc_state; 883 _u8 wrc_credits; 884 885 /* IO */ 886 _u16 wrc_sge_ec; 887 _u8 wrc_sge_respQ; 888 _u8 wrc_port; 889 _u8 wrc_ulp; 890 891 _u8 wrc_coherency_counter; 892 893 /* REASSEMBLY */ 894 _u8 wrc_frag_len; 895 _u8 wrc_frag_credits; 896 uint32_t wrc_frag; 897 898 union { 899 struct { 900 901 /* TOE */ 902 _u8 aborted; 903 _u8 wrc_num_tx_pages; 904 _u8 wrc_max_tx_pages; 905 _u8 wrc_trace_idx; 906 uint32_t wrc_snd_nxt; 907 uint32_t wrc_snd_max; 908 uint32_t wrc_snd_una; 909 uint32_t wrc_snd_iss; 910 911 /* RI */ 912 uint32_t wrc_pdid; 913 uint32_t wrc_scqid; 914 uint32_t wrc_rcqid; 915 uint32_t wrc_rq_addr_32a; 916 _u16 wrc_rq_size; 917 _u16 wrc_rq_wr_idx; 918 enum fw_ri_mpa_attrs wrc_mpaattrs; 919 enum fw_ri_qp_caps wrc_qpcaps; 920 _u16 wrc_mulpdu_tagged; 921 _u16 wrc_mulpdu_untagged; 922 _u16 wrc_ord_max; 923 _u16 wrc_ird_max; 924 _u16 wrc_ord; 925 _u16 wrc_ird; 926 _u16 wrc_markeroffset; 927 uint32_t wrc_msn_send; 928 uint32_t wrc_msn_rdma_read; 929 uint32_t wrc_msn_rdma_read_req; 930 _u16 wrc_rdma_read_req_err; 931 _u8 wrc_ack_mode; 932 _u8 wrc_sge_ec_credits; 933 _u16 wrc_maxiolen_tagged; 934 _u16 wrc_maxiolen_untagged; 935 uint32_t wrc_mo; 936 } toe_ri; 937 938 struct { 939 940 } ipmi; 941 942 struct { 943 uint32_t wrc_pad2[24]; 944 } pad; 945 } u __attribute__ ((packed)); 946 947 /* BUFFERING */ 948 struct fbuf wrc_fbuf __attribute__ ((packed)); 949}; 950#define wrc_aborted u.toe_ri.aborted 951#define wrc_num_tx_pages u.toe_ri.wrc_num_tx_pages 952#define wrc_max_tx_pages u.toe_ri.wrc_max_tx_pages 953#define wrc_trace_idx u.toe_ri.wrc_trace_idx 954#define wrc_snd_nxt u.toe_ri.wrc_snd_nxt 955#define wrc_snd_max u.toe_ri.wrc_snd_max 956#define wrc_snd_una u.toe_ri.wrc_snd_una 957#define wrc_snd_iss u.toe_ri.wrc_snd_iss 958#define wrc_pdid u.toe_ri.wrc_pdid 959#define wrc_scqid u.toe_ri.wrc_scqid 960#define wrc_rcqid u.toe_ri.wrc_rcqid 961#define wrc_rq_addr_32a u.toe_ri.wrc_rq_addr_32a 962#define wrc_rq_size u.toe_ri.wrc_rq_size 963#define wrc_rq_wr_idx u.toe_ri.wrc_rq_wr_idx 964#define wrc_mpaattrs u.toe_ri.wrc_mpaattrs 965#define wrc_qpcaps u.toe_ri.wrc_qpcaps 966#define wrc_mulpdu_tagged u.toe_ri.wrc_mulpdu_tagged 967#define wrc_mulpdu_untagged u.toe_ri.wrc_mulpdu_untagged 968#define wrc_ord_max u.toe_ri.wrc_ord_max 969#define wrc_ird_max u.toe_ri.wrc_ird_max 970#define wrc_ord u.toe_ri.wrc_ord 971#define wrc_ird u.toe_ri.wrc_ird 972#define wrc_markeroffset u.toe_ri.wrc_markeroffset 973#define wrc_msn_send u.toe_ri.wrc_msn_send 974#define wrc_msn_rdma_read u.toe_ri.wrc_msn_rdma_read 975#define wrc_msn_rdma_read_req u.toe_ri.wrc_msn_rdma_read_req 976#define wrc_rdma_read_req_err u.toe_ri.wrc_rdma_read_req_err 977#define wrc_ack_mode u.toe_ri.wrc_ack_mode 978#define wrc_sge_ec_credits u.toe_ri.wrc_sge_ec_credits 979#define wrc_maxiolen_tagged u.toe_ri.wrc_maxiolen_tagged 980#define wrc_maxiolen_untagged u.toe_ri.wrc_maxiolen_untagged 981#define wrc_mo u.toe_ri.wrc_mo 982 983static void print_wrc_field(char *field, unsigned int value, unsigned int size) 984{ 985 switch(size) { 986 case 1: 987 printf(" 1 %s: 0x%02x (%u)\n", field, value, value); 988 break; 989 case 2: { 990 unsigned short host_value = ntohs(value); 991 printf(" 2 %s: 0x%04x (%u)\n", field, host_value, host_value); 992 break; 993 } 994 case 4: { 995 unsigned int host_value = ntohl(value); 996 printf(" 4 %s: 0x%08x (%u)\n", field, host_value, host_value); 997 break; 998 } 999 default: 1000 printf(" unknown size %u for field %s\n", size, field); 1001 } 1002} 1003 1004#define P(field) print_wrc_field(#field, p->wrc_ ## field, sizeof (p->wrc_ ## field)) 1005 1006static void print_wrc(unsigned int wrc_idx, struct wrc *p) 1007{ 1008 u32 *buf = (u32 *)p; 1009 unsigned int i, j; 1010 1011 printf("WRC STATE (raw)\n"); 1012 for (i = 0; i < 32;) { 1013 printf("[%08x]:", 0x20300000 + wrc_idx * MEM_CM_WRC_SIZE + i * 4); 1014 for (j = 0; j < 8; j++) { 1015 printf(" %08x ", htonl(buf[i++])); 1016 } 1017 printf("\n"); 1018 } 1019 printf("WRC BASIC\n"); 1020 P(tid); P(flags); P(state); P(credits); 1021 printf("WRC IO\n"); 1022 P(sge_ec); P(sge_respQ); P(port); P(ulp); P(coherency_counter); 1023 printf("WRC REASSEMBLY\n"); 1024 P(frag_len); P(frag_credits); P(frag); 1025 printf("WRC TOE\n"); 1026 P(aborted); P(num_tx_pages); P(max_tx_pages); P(trace_idx); P(snd_nxt); 1027 P(snd_max); P(snd_una); P(snd_iss); 1028 printf("WRC RI\n"); 1029 P(pdid); P(scqid); P(rcqid); P(rq_addr_32a); P(rq_size); P(rq_wr_idx); 1030 P(mpaattrs); P(qpcaps); P(mulpdu_tagged); P(mulpdu_untagged); P(ord_max); 1031 P(ird_max); P(ord); P(ird); P(markeroffset); P(msn_send); P(msn_rdma_read); 1032 P(msn_rdma_read_req); P(rdma_read_req_err); P(ack_mode); 1033 P(sge_ec_credits); P(maxiolen_tagged); P(maxiolen_untagged); P(mo); 1034 printf("WRC BUFFERING\n"); 1035 printf(" 4 fbuf.pp: 0x%08x (%u)\n", htonl(p->wrc_fbuf.pp), htonl(p->wrc_fbuf.pp)); 1036 printf(" 4 fbuf.cp: 0x%08x (%u)\n", htonl(p->wrc_fbuf.cp), htonl(p->wrc_fbuf.cp)); 1037 printf(" 4 fbuf.num_bytes: 0x%08x (%d)\n", htonl(p->wrc_fbuf.num_bytes), htonl(p->wrc_fbuf.num_bytes)); 1038 printf("WRC BUFFER (raw)\n"); 1039 for (i = 32; i < (FBUF_SIZE + FBUF_WRAP_SIZE) / 4;) { 1040 printf("[%08x]:", 0x20300000 + wrc_idx * MEM_CM_WRC_SIZE + i * 4); 1041 for (j = 0; j < 4; j++) { 1042 printf(" %08x%08x", htonl(buf[i++]), htonl(buf[i++])); 1043 } 1044 printf("\n"); 1045 } 1046} 1047 1048#undef P 1049 1050#define P(field) print_sizeof(#field, ##field, sizeof (p->##field)) 1051 1052struct history_e { 1053 uint32_t wr_addr; 1054 uint32_t debug; 1055 uint64_t wr_flit0; 1056 uint64_t wr_flit1; 1057 uint64_t wr_flit2; 1058}; 1059 1060static void print_wrc_zero(unsigned int wrc_idx, struct wrc *p) 1061{ 1062 uint32_t *buf = 1063 (uint32_t *)((unsigned long)p + FW_WR_SIZE * (2 + FW_WR_NUM)); 1064 unsigned int i; 1065 1066 printf("WRC ZERO\n"); 1067 printf("[%08x]:", CM_WRCONTEXT_BASE + wrc_idx * MEM_CM_WRC_SIZE + 1068 FW_WR_SIZE * (2 + FW_WR_NUM)); 1069 for (i = 0; i < 4;) 1070 printf(" %08x%08x", htonl(buf[i]), htonl(buf[i++])); 1071 printf("\n"); 1072} 1073 1074static void print_wrc_history(struct wrc *p) 1075{ 1076 unsigned int i, idx; 1077 struct history_e *e = 1078 (struct history_e *)((unsigned long)p + FW_WR_SIZE * 1079 (2 + FW_WR_NUM) + 32); 1080 printf("WRC WR HISTORY, idx %u\n", p->wrc_trace_idx); 1081 idx = p->wrc_trace_idx; 1082 for (i = 0; i < 16; i++) { 1083 printf("%02u: %08x %08x %08x%08x %08x%08x %08x%08x\n", idx, 1084 htonl(e[idx].wr_addr), htonl(e[idx].debug), 1085 htonl(e[idx].wr_flit0 & 0xFFFFFFFF), 1086 htonl(e[idx].wr_flit0 >> 32), 1087 htonl(e[idx].wr_flit1 & 0xFFFFFFFF), 1088 htonl(e[idx].wr_flit1 >> 32), 1089 htonl(e[idx].wr_flit2 & 0xFFFFFFFF), 1090 htonl(e[idx].wr_flit2 >> 32)); 1091 idx = (idx - 1) & 0xF; 1092 } 1093} 1094 1095static int get_wrc(int argc, char *argv[], int start_arg, const char *iff_name) 1096{ 1097 struct toetool_mem_range *op; 1098 uint64_t *p; 1099 uint32_t *buf; 1100 unsigned int idx, i = 0; 1101 1102 if (argc != start_arg + 1) 1103 return -1; 1104 1105 if (get_int_arg(argv[start_arg], &idx)) 1106 return -1; 1107 1108 op = malloc(sizeof(*op) + MEM_CM_WRC_SIZE); 1109 if (!op) 1110 err(1, "get_wrc: malloc failed"); 1111 1112 op->cmd = TOETOOL_GET_MEM; 1113 op->mem_id = MEM_CM; 1114 op->addr = read_reg(iff_name, 0x28c) + CM_WRCONTEXT_OFFSET + 1115 idx * MEM_CM_WRC_SIZE; 1116 op->len = MEM_CM_WRC_SIZE; 1117 buf = (uint32_t *)op->buf; 1118 1119 if (doit(iff_name, op) < 0) 1120 err(1, "get_wrc"); 1121 1122 /* driver manges with the data... put it back into the the FW's view 1123 */ 1124 for (p = (uint64_t *)op->buf; 1125 p < (uint64_t *)(op->buf + MEM_CM_WRC_SIZE); p++) { 1126 uint64_t flit = *p; 1127 buf[i++] = htonl((uint32_t)(flit >> 32)); 1128 buf[i++] = htonl((uint32_t)flit); 1129 } 1130 1131 print_wrc(idx, (struct wrc *)op->buf); 1132 print_wrc_zero(idx, (struct wrc *)op->buf); 1133 print_wrc_history((struct wrc *)op->buf); 1134 1135 free(op); 1136 return 0; 1137} 1138#endif 1139 1140#ifdef notyet 1141static int get_pm_page_spec(const char *s, unsigned int *page_size, 1142 unsigned int *num_pages) 1143{ 1144 char *p; 1145 unsigned long val; 1146 1147 val = strtoul(s, &p, 0); 1148 if (p == s) return -1; 1149 if (*p == 'x' && p[1]) { 1150 *num_pages = val; 1151 *page_size = strtoul(p + 1, &p, 0); 1152 } else { 1153 *num_pages = -1; 1154 *page_size = val; 1155 } 1156 *page_size <<= 10; // KB -> bytes 1157 return *p; 1158} 1159 1160static int conf_pm(int argc, char *argv[], int start_arg, const char *iff_name) 1161{ 1162 struct toetool_pm op; 1163 1164 if (argc == start_arg) { 1165 op.cmd = TOETOOL_GET_PM; 1166 if (doit(iff_name, &op) < 0) 1167 err(1, "read pm config"); 1168 printf("%ux%uKB TX pages, %ux%uKB RX pages, %uKB total memory\n", 1169 op.tx_num_pg, op.tx_pg_sz >> 10, op.rx_num_pg, 1170 op.rx_pg_sz >> 10, op.pm_total >> 10); 1171 return 0; 1172 } 1173 1174 if (argc != start_arg + 2) return -1; 1175 1176 if (get_pm_page_spec(argv[start_arg], &op.tx_pg_sz, &op.tx_num_pg)) { 1177 warnx("bad parameter \"%s\"", argv[start_arg]); 1178 return -1; 1179 } 1180 if (get_pm_page_spec(argv[start_arg + 1], &op.rx_pg_sz, 1181 &op.rx_num_pg)) { 1182 warnx("bad parameter \"%s\"", argv[start_arg + 1]); 1183 return -1; 1184 } 1185 op.cmd = TOETOOL_SET_PM; 1186 if (doit(iff_name, &op) < 0) 1187 err(1, "pm config"); 1188 return 0; 1189} 1190 1191static int conf_tcam(int argc, char *argv[], int start_arg, 1192 const char *iff_name) 1193{ 1194 struct toetool_tcam op; 1195 1196 if (argc == start_arg) { 1197 op.cmd = TOETOOL_GET_TCAM; 1198 op.nfilters = 0; 1199 if (doit(iff_name, &op) < 0) 1200 err(1, "read tcam config"); 1201 printf("%u total entries, %u servers, %u filters, %u routes\n", 1202 op.tcam_size, op.nservers, op.nfilters, op.nroutes); 1203 return 0; 1204 } 1205 1206 if (argc != start_arg + 3) return -1; 1207 1208 if (get_int_arg(argv[start_arg], &op.nservers) || 1209 get_int_arg(argv[start_arg + 1], &op.nroutes) || 1210 get_int_arg(argv[start_arg + 2], &op.nfilters)) 1211 return -1; 1212 op.cmd = TOETOOL_SET_TCAM; 1213 if (doit(iff_name, &op) < 0) 1214 err(1, "tcam config"); 1215 return 0; 1216} 1217#endif 1218 1219#ifdef CHELSIO_INTERNAL 1220#ifdef notyet 1221static int dump_tcam(int argc, char *argv[], int start_arg, 1222 const char *iff_name) 1223{ 1224 unsigned int nwords; 1225 struct toetool_tcam_word op; 1226 1227 if (argc != start_arg + 2) return -1; 1228 1229 if (get_int_arg(argv[start_arg], &op.addr) || 1230 get_int_arg(argv[start_arg + 1], &nwords)) 1231 return -1; 1232 op.cmd = TOETOOL_READ_TCAM_WORD; 1233 1234 while (nwords--) { 1235 if (doit(iff_name, &op) < 0) 1236 err(1, "tcam dump"); 1237 1238 printf("0x%08x: 0x%02x 0x%08x 0x%08x\n", op.addr, 1239 op.buf[0] & 0xff, op.buf[1], op.buf[2]); 1240 op.addr++; 1241 } 1242 return 0; 1243} 1244#endif 1245static void hexdump_8b(unsigned int start, uint64_t *data, unsigned int len) 1246{ 1247 int i; 1248 1249 while (len) { 1250 printf("0x%08x:", start); 1251 for (i = 0; i < 4 && len; ++i, --len) 1252 printf(" %016llx", (unsigned long long)*data++); 1253 printf("\n"); 1254 start += 32; 1255 } 1256} 1257 1258static int dump_mc7(int argc, char *argv[], int start_arg, 1259 const char *iff_name) 1260{ 1261 struct ch_mem_range mem; 1262 unsigned int mem_id, addr, len; 1263 1264 if (argc != start_arg + 3) return -1; 1265 1266 if (!strcmp(argv[start_arg], "cm")) 1267 mem_id = MEM_CM; 1268 else if (!strcmp(argv[start_arg], "rx")) 1269 mem_id = MEM_PMRX; 1270 else if (!strcmp(argv[start_arg], "tx")) 1271 mem_id = MEM_PMTX; 1272 else 1273 errx(1, "unknown memory \"%s\"; must be one of \"cm\", \"tx\"," 1274 " or \"rx\"", argv[start_arg]); 1275 1276 if (get_int_arg(argv[start_arg + 1], &addr) || 1277 get_int_arg(argv[start_arg + 2], &len)) 1278 return -1; 1279 1280 mem.buf = malloc(len); 1281 if (!mem.buf) 1282 err(1, "memory dump"); 1283 1284 mem.mem_id = mem_id; 1285 mem.addr = addr; 1286 mem.len = len; 1287 1288 if (doit(iff_name, CHELSIO_GET_MEM, &mem) < 0) 1289 err(1, "memory dump"); 1290 1291 hexdump_8b(mem.addr, (uint64_t *)mem.buf, mem.len >> 3); 1292 free(mem.buf); 1293 return 0; 1294} 1295#endif 1296 1297#ifdef notyet 1298/* Max FW size is 32K including version, +4 bytes for the checksum. */ 1299#define MAX_FW_IMAGE_SIZE (32768 + 4) 1300 1301static int load_fw(int argc, char *argv[], int start_arg, const char *iff_name) 1302{ 1303 int fd, len; 1304 struct toetool_mem_range *op; 1305 const char *fname = argv[start_arg]; 1306 1307 if (argc != start_arg + 1) return -1; 1308 1309 fd = open(fname, O_RDONLY); 1310 if (fd < 0) 1311 err(1, "load firmware"); 1312 1313 op = malloc(sizeof(*op) + MAX_FW_IMAGE_SIZE + 1); 1314 if (!op) 1315 err(1, "load firmware"); 1316 1317 len = read(fd, op->buf, MAX_FW_IMAGE_SIZE + 1); 1318 if (len < 0) 1319 err(1, "load firmware"); 1320 if (len > MAX_FW_IMAGE_SIZE) 1321 errx(1, "FW image too large"); 1322 1323 op->cmd = TOETOOL_LOAD_FW; 1324 op->len = len; 1325 1326 if (doit(iff_name, op) < 0) 1327 err(1, "load firmware"); 1328 return 0; 1329} 1330 1331 1332static int write_proto_sram(const char *fname, const char *iff_name) 1333{ 1334 int i; 1335 char c; 1336 struct toetool_proto op = { .cmd = TOETOOL_SET_PROTO }; 1337 uint32_t *p = op.data; 1338 FILE *fp = fopen(fname, "r"); 1339 1340 if (!fp) 1341 err(1, "load protocol sram"); 1342 1343 for (i = 0; i < 128; i++, p += 5) { 1344 int n = fscanf(fp, "%1x%8x%8x%8x%8x", 1345 &p[0], &p[1], &p[2], &p[3], &p[4]); 1346 if (n != 5) 1347 errx(1, "%s: bad line %d", fname, i); 1348 } 1349 if (fscanf(fp, "%1s", &c) != EOF) 1350 errx(1, "%s: protocol sram image has too many lines", fname); 1351 fclose(fp); 1352 1353 if (doit(iff_name, &op) < 0) 1354 err(1, "load protocol sram"); 1355 return 0; 1356} 1357 1358static int dump_proto_sram(const char *iff_name) 1359{ 1360 int i, j; 1361 u8 buf[sizeof(struct ethtool_eeprom) + PROTO_SRAM_SIZE]; 1362 struct ethtool_eeprom *ee = (struct ethtool_eeprom *)buf; 1363 u8 *p = buf + sizeof(struct ethtool_eeprom); 1364 1365 ee->cmd = ETHTOOL_GEEPROM; 1366 ee->len = PROTO_SRAM_SIZE; 1367 ee->offset = PROTO_SRAM_EEPROM_ADDR; 1368 if (ethtool_call(iff_name, ee)) 1369 err(1, "show protocol sram"); 1370 1371 for (i = 0; i < PROTO_SRAM_LINES; i++) { 1372 for (j = PROTO_SRAM_LINE_NIBBLES - 1; j >= 0; j--) { 1373 int nibble_idx = i * PROTO_SRAM_LINE_NIBBLES + j; 1374 u8 nibble = p[nibble_idx / 2]; 1375 1376 if (nibble_idx & 1) 1377 nibble >>= 4; 1378 else 1379 nibble &= 0xf; 1380 printf("%x", nibble); 1381 } 1382 putchar('\n'); 1383 } 1384 return 0; 1385} 1386 1387static int proto_sram_op(int argc, char *argv[], int start_arg, 1388 const char *iff_name) 1389{ 1390 if (argc == start_arg + 1) 1391 return write_proto_sram(argv[start_arg], iff_name); 1392 if (argc == start_arg) 1393 return dump_proto_sram(iff_name); 1394 return -1; 1395} 1396#endif 1397 1398static int dump_qset_params(const char *iff_name) 1399{ 1400 struct ch_qset_params qp; 1401 1402 qp.qset_idx = 0; 1403 1404 while (doit(iff_name, CHELSIO_GET_QSET_PARAMS, &qp) == 0) { 1405 if (!qp.qset_idx) 1406 printf("Qnum TxQ0 TxQ1 TxQ2 RspQ RxQ0 RxQ1" 1407 " Cong Intr Lat Rx Mode\n"); 1408 printf("%4u %6u %6u %6u %6u %6u %6u %5u %9u %s \n", 1409 qp.qset_idx, 1410 qp.txq_size[0], qp.txq_size[1], qp.txq_size[2], 1411 qp.rspq_size, qp.fl_size[0], qp.fl_size[1], 1412 qp.cong_thres, qp.intr_lat, 1413 qp.polling ? "Polling" : "Interrupt"); 1414 qp.qset_idx++; 1415 } 1416 if (!qp.qset_idx || (errno && errno != EINVAL)) 1417 err(1, "get qset parameters"); 1418 return 0; 1419} 1420 1421static int qset_config(int argc, char *argv[], int start_arg, 1422 const char *iff_name) 1423{ 1424 struct ch_qset_params qp; 1425 1426 if (argc == start_arg) 1427 return dump_qset_params(iff_name); 1428 1429 if (get_int_arg(argv[start_arg++], &qp.qset_idx)) 1430 return -1; 1431 1432 qp.txq_size[0] = qp.txq_size[1] = qp.txq_size[2] = -1; 1433 qp.fl_size[0] = qp.fl_size[1] = qp.rspq_size = -1; 1434 qp.polling = qp.intr_lat = qp.cong_thres = -1; 1435 1436 while (start_arg + 2 <= argc) { 1437 int32_t *param = NULL; 1438 1439 if (!strcmp(argv[start_arg], "txq0")) 1440 param = &qp.txq_size[0]; 1441 else if (!strcmp(argv[start_arg], "txq1")) 1442 param = &qp.txq_size[1]; 1443 else if (!strcmp(argv[start_arg], "txq2")) 1444 param = &qp.txq_size[2]; 1445 else if (!strcmp(argv[start_arg], "rspq")) 1446 param = &qp.rspq_size; 1447 else if (!strcmp(argv[start_arg], "fl0")) 1448 param = &qp.fl_size[0]; 1449 else if (!strcmp(argv[start_arg], "fl1")) 1450 param = &qp.fl_size[1]; 1451 else if (!strcmp(argv[start_arg], "lat")) 1452 param = &qp.intr_lat; 1453 else if (!strcmp(argv[start_arg], "cong")) 1454 param = &qp.cong_thres; 1455 else if (!strcmp(argv[start_arg], "mode")) 1456 param = &qp.polling; 1457 else 1458 errx(1, "unknown qset parameter \"%s\"\n" 1459 "allowed parameters are \"txq0\", \"txq1\", " 1460 "\"txq2\", \"rspq\", \"fl0\", \"fl1\", \"lat\", " 1461 "\"cong\", \"mode\' and \"lro\"", argv[start_arg]); 1462 1463 start_arg++; 1464 1465 if (param == &qp.polling) { 1466 if (!strcmp(argv[start_arg], "irq")) 1467 qp.polling = 0; 1468 else if (!strcmp(argv[start_arg], "polling")) 1469 qp.polling = 1; 1470 else 1471 errx(1, "illegal qset mode \"%s\"\n" 1472 "known modes are \"irq\" and \"polling\"", 1473 argv[start_arg]); 1474 } else if (get_int_arg(argv[start_arg], (uint32_t *)param)) 1475 return -1; 1476 start_arg++; 1477 } 1478 if (start_arg != argc) 1479 errx(1, "unknown parameter %s", argv[start_arg]); 1480 1481#if 0 1482 printf("%4u %6d %6d %6d %6d %6d %6d %5d %9d %d\n", op.qset_idx, 1483 op.txq_size[0], op.txq_size[1], op.txq_size[2], 1484 op.rspq_size, op.fl_size[0], op.fl_size[1], op.cong_thres, 1485 op.intr_lat, op.polling); 1486#endif 1487 if (doit(iff_name, CHELSIO_SET_QSET_PARAMS, &qp) < 0) 1488 err(1, "set qset parameters"); 1489 1490 return 0; 1491} 1492 1493static int qset_num_config(int argc, char *argv[], int start_arg, 1494 const char *iff_name) 1495{ 1496 struct ch_reg reg; 1497 1498 if (argc == start_arg) { 1499 if (doit(iff_name, CHELSIO_GET_QSET_NUM, ®) < 0) 1500 err(1, "get qsets"); 1501 printf("%u\n", reg.val); 1502 return 0; 1503 } 1504 1505 if (argc != start_arg + 1) 1506 return -1; 1507 if (get_int_arg(argv[start_arg], ®.val)) 1508 return -1; 1509 1510 if (doit(iff_name, CHELSIO_SET_QSET_NUM, ®) < 0) 1511 err(1, "set qsets"); 1512 return 0; 1513} 1514 1515/* 1516 * Parse a string containing an IP address with an optional network prefix. 1517 */ 1518static int parse_ipaddr(const char *s, uint32_t *addr, uint32_t *mask) 1519{ 1520 char *p, *slash; 1521 struct in_addr ia; 1522 1523 *mask = 0xffffffffU; 1524 slash = strchr(s, '/'); 1525 if (slash) 1526 *slash = 0; 1527 if (!inet_aton(s, &ia)) { 1528 if (slash) 1529 *slash = '/'; 1530 *addr = 0; 1531 return -1; 1532 } 1533 *addr = ntohl(ia.s_addr); 1534 if (slash) { 1535 unsigned int prefix = strtoul(slash + 1, &p, 10); 1536 1537 *slash = '/'; 1538 if (p == slash + 1 || *p || prefix > 32) 1539 return -1; 1540 *mask <<= (32 - prefix); 1541 } 1542 return 0; 1543} 1544 1545/* 1546 * Parse a string containing a value and an optional colon separated mask. 1547 */ 1548static int parse_val_mask_param(const char *s, uint32_t *val, uint32_t *mask) 1549{ 1550 char *p; 1551 1552 *mask = 0xffffffffU; 1553 *val = strtoul(s, &p, 0); 1554 if (p == s) 1555 return -1; 1556 if (*p == ':' && p[1]) 1557 *mask = strtoul(p + 1, &p, 0); 1558 return *p ? -1 : 0; 1559} 1560 1561static int parse_trace_param(const char *s, uint32_t *val, uint32_t *mask) 1562{ 1563 return strchr(s, '.') ? parse_ipaddr(s, val, mask) : 1564 parse_val_mask_param(s, val, mask); 1565} 1566 1567static int trace_config(int argc, char *argv[], int start_arg, 1568 const char *iff_name) 1569{ 1570 uint32_t val, mask; 1571 struct ch_trace trace; 1572 1573 if (argc == start_arg) 1574 return -1; 1575 1576 memset(&trace, 0, sizeof(trace)); 1577 if (!strcmp(argv[start_arg], "tx")) 1578 trace.config_tx = 1; 1579 else if (!strcmp(argv[start_arg], "rx")) 1580 trace.config_rx = 1; 1581 else if (!strcmp(argv[start_arg], "all")) 1582 trace.config_tx = trace.config_rx = 1; 1583 else 1584 errx(1, "bad trace filter \"%s\"; must be one of \"rx\", " 1585 "\"tx\" or \"all\"", argv[start_arg]); 1586 1587 if (argc == ++start_arg) 1588 return -1; 1589 if (!strcmp(argv[start_arg], "on")) { 1590 trace.trace_tx = trace.config_tx; 1591 trace.trace_rx = trace.config_rx; 1592 } else if (strcmp(argv[start_arg], "off")) 1593 errx(1, "bad argument \"%s\"; must be \"on\" or \"off\"", 1594 argv[start_arg]); 1595 1596 start_arg++; 1597 if (start_arg < argc && !strcmp(argv[start_arg], "not")) { 1598 trace.invert_match = 1; 1599 start_arg++; 1600 } 1601 1602 while (start_arg + 2 <= argc) { 1603 int ret = parse_trace_param(argv[start_arg + 1], &val, &mask); 1604 1605 if (!strcmp(argv[start_arg], "interface")) { 1606 trace.intf = val; 1607 trace.intf_mask = mask; 1608 } else if (!strcmp(argv[start_arg], "sip")) { 1609 trace.sip = val; 1610 trace.sip_mask = mask; 1611 } else if (!strcmp(argv[start_arg], "dip")) { 1612 trace.dip = val; 1613 trace.dip_mask = mask; 1614 } else if (!strcmp(argv[start_arg], "sport")) { 1615 trace.sport = val; 1616 trace.sport_mask = mask; 1617 } else if (!strcmp(argv[start_arg], "dport")) { 1618 trace.dport = val; 1619 trace.dport_mask = mask; 1620 } else if (!strcmp(argv[start_arg], "vlan")) { 1621 trace.vlan = val; 1622 trace.vlan_mask = mask; 1623 } else if (!strcmp(argv[start_arg], "proto")) { 1624 trace.proto = val; 1625 trace.proto_mask = mask; 1626 } else 1627 errx(1, "unknown trace parameter \"%s\"\n" 1628 "known parameters are \"interface\", \"sip\", " 1629 "\"dip\", \"sport\", \"dport\", \"vlan\", " 1630 "\"proto\"", argv[start_arg]); 1631 if (ret < 0) 1632 errx(1, "bad parameter \"%s\"", argv[start_arg + 1]); 1633 start_arg += 2; 1634 } 1635 if (start_arg != argc) 1636 errx(1, "unknown parameter \"%s\"", argv[start_arg]); 1637 1638#if 0 1639 printf("sip: %x:%x, dip: %x:%x, sport: %x:%x, dport: %x:%x, " 1640 "interface: %x:%x, vlan: %x:%x, tx_config: %u, rx_config: %u, " 1641 "invert: %u, tx_enable: %u, rx_enable: %u\n", op.sip, 1642 op.sip_mask, op.dip, op.dip_mask, op.sport, op.sport_mask, 1643 op.dport, op.dport_mask, op.intf, op.intf_mask, op.vlan, 1644 op.vlan_mask, op.config_tx, op.config_rx, op.invert_match, 1645 op.trace_tx, op.trace_rx); 1646#endif 1647 if (doit(iff_name, CHELSIO_SET_TRACE_FILTER, &trace) < 0) 1648 err(1, "trace"); 1649 return 0; 1650} 1651 1652#ifdef notyet 1653static int t1_powersave(int argc, char *argv[], int start_arg, 1654 const char *iff_name) 1655{ 1656 struct toetool_t1powersave op = { 1657 .cmd = TOETOOL_T1POWERSAVE, 1658 .mode = 0 1659 }; 1660 1661 if (argc == start_arg) 1662 op.mode = 2; /* Check powersave mode */ 1663 1664 else if (argc == start_arg + 1) { 1665 if (strcmp(argv[start_arg], "on") == 0) 1666 op.mode = 1; 1667 else if (strcmp(argv[start_arg], "off") == 0) 1668 op.mode = 0; 1669 else { 1670 warnx("bad parameter \"%s\"", argv[start_arg]); 1671 return -1; 1672 } 1673 } else { 1674 errx(1, "too many arguments"); 1675 return -1; 1676 } 1677 1678 if (doit(iff_name, &op) < 0) 1679 err(1, "t1powersave"); 1680 1681 if (op.mode & 2) 1682 printf("t1powersave is %s\n", (op.mode & 1) ? "on" : "off"); 1683 1684 return 0; 1685} 1686#endif 1687 1688static int pktsched(int argc, char *argv[], int start_arg, const char *iff_name) 1689{ 1690 struct ch_pktsched_params pktsched; 1691 unsigned int idx, min = -1, max, binding = -1; 1692 1693 if (!strcmp(argv[start_arg], "port")) { 1694 if (argc != start_arg + 4) 1695 return -1; 1696 if (get_int_arg(argv[start_arg + 1], &idx) || 1697 get_int_arg(argv[start_arg + 2], &min) || 1698 get_int_arg(argv[start_arg + 3], &max)) 1699 return -1; 1700 pktsched.sched = 0; 1701 } else if (!strcmp(argv[start_arg], "tunnelq")) { 1702 if (argc != start_arg + 4) 1703 return -1; 1704 if (get_int_arg(argv[start_arg + 1], &idx) || 1705 get_int_arg(argv[start_arg + 2], &max) || 1706 get_int_arg(argv[start_arg + 3], &binding)) 1707 return -1; 1708 pktsched.sched = 1; 1709 } else 1710 errx(1, "unknown scheduler \"%s\"; must be one of \"port\"" 1711 " or \"tunnelq\"", argv[start_arg]); 1712 1713 pktsched.idx = idx; 1714 pktsched.min = min; 1715 pktsched.max = max; 1716 pktsched.binding = binding; 1717 if (doit(iff_name, CHELSIO_SET_PKTSCHED, &pktsched) < 0) 1718 err(1, "pktsched"); 1719 1720 return 0; 1721} 1722 1723int main(int argc, char *argv[]) 1724{ 1725 int r = -1; 1726 const char *iff_name; 1727 1728 progname = argv[0]; 1729 1730 if (argc == 2) { 1731 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) 1732 usage(stdout); 1733 if (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version")) { 1734 printf("%s version %s\n", PROGNAME, VERSION); 1735 printf("%s\n", COPYRIGHT); 1736 exit(0); 1737 } 1738 } 1739 1740 if (argc < 3) usage(stderr); 1741 1742 iff_name = argv[1]; 1743 if (!strcmp(argv[2], "reg")) 1744 r = register_io(argc, argv, 3, iff_name); 1745 else if (!strcmp(argv[2], "mdio")) 1746 r = mdio_io(argc, argv, 3, iff_name); 1747#ifdef notyet 1748 else if (!strcmp(argv[2], "tpi")) 1749 r = tpi_io(argc, argv, 3, iff_name); 1750 else if (!strcmp(argv[2], "up")) 1751 r = device_up(argc, argv, 3, iff_name); 1752 else if (!strcmp(argv[2], "mtus")) 1753 r = mtu_tab_op(argc, argv, 3, iff_name); 1754 else if (!strcmp(argv[2], "pm")) 1755 r = conf_pm(argc, argv, 3, iff_name); 1756 else if (!strcmp(argv[2], "tcam")) 1757 r = conf_tcam(argc, argv, 3, iff_name); 1758 else if (!strcmp(argv[2], "tcb")) 1759 r = get_tcb(argc, argv, 3, iff_name); 1760#ifdef WRC 1761 else if (!strcmp(argv[2], "wrc")) 1762 r = get_wrc(argc, argv, 3, iff_name); 1763#endif 1764#endif 1765 else if (!strcmp(argv[2], "regdump")) 1766 r = dump_regs(argc, argv, 3, iff_name); 1767#ifdef CHELSIO_INTERNAL 1768 else if (!strcmp(argv[2], "memdump")) 1769 r = dump_mc7(argc, argv, 3, iff_name); 1770 else if (!strcmp(argv[2], "meminfo")) 1771 r = meminfo(argc, argv, 3, iff_name); 1772 else if (!strcmp(argv[2], "context")) 1773 r = get_sge_context(argc, argv, 3, iff_name); 1774 else if (!strcmp(argv[2], "desc")) 1775 r = get_sge_desc(argc, argv, 3, iff_name); 1776#endif 1777 else if (!strcmp(argv[2], "qset")) 1778 r = qset_config(argc, argv, 3, iff_name); 1779 else if (!strcmp(argv[2], "qsets")) 1780 r = qset_num_config(argc, argv, 3, iff_name); 1781 else if (!strcmp(argv[2], "trace")) 1782 r = trace_config(argc, argv, 3, iff_name); 1783#ifdef notyet 1784 else if (!strcmp(argv[2], "tcamdump")) 1785 r = dump_tcam(argc, argv, 3, iff_name); 1786 else if (!strcmp(argv[2], "loadfw")) 1787 r = load_fw(argc, argv, 3, iff_name); 1788 else if (!strcmp(argv[2], "proto")) 1789 r = proto_sram_op(argc, argv, 3, iff_name); 1790 else if (!strcmp(argv[2], "t1powersave")) 1791 r = t1_powersave(argc, argv, 3, iff_name); 1792#endif 1793 else if (!strcmp(argv[2], "pktsched")) 1794 r = pktsched(argc, argv, 3, iff_name); 1795 if (r == -1) 1796 usage(stderr); 1797 return 0; 1798} 1799