1 /**************************************************************************
3 Copyright (c) 2007-2008, Chelsio Inc.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
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.
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.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
33 ***************************************************************************/
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
46 #include <sys/param.h>
48 #include <sys/ioctl.h>
49 #include <sys/socket.h>
51 #include <netinet/in.h>
52 #include <arpa/inet.h>
55 #include <net/if_var.h>
56 #include <net/if_types.h>
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
67 #include <cxgb_ioctl.h>
68 #include <common/cxgb_regs.h>
79 #if defined(CONFIG_T3_REGS)
80 # include "reg_defs_t3.c"
81 # include "reg_defs_t3b.c"
82 # include "reg_defs_t3c.c"
85 static const char *progname;
87 static void __attribute__((noreturn)) usage(FILE *fp)
89 fprintf(fp, "Usage: %s <interface> [operation]\n", progname);
91 "\tclearstats clear MAC statistics\n"
92 "\tcontext <type> <id> show an SGE context\n"
93 "\tdesc <qset> <queue> <idx> [<cnt>] dump SGE descriptors\n"
94 "\tloadboot <boot image> download boot image\n"
95 "\tloadfw <FW image> download firmware\n"
96 "\tmdio <phy_addr> <mmd_addr>\n"
97 "\t <reg_addr> [<val>] read/write MDIO register\n"
98 "\tmemdump cm|tx|rx <addr> <len> dump a mem range\n"
99 "\tmeminfo show memory info\n"
100 "\tmtus [<mtu0>...<mtuN>] read/write MTU table\n"
101 "\tpktsched port <idx> <min> <max> set TX port scheduler params\n"
102 "\tpktsched tunnelq <idx> <max>\n"
103 "\t <binding> set TX tunnelq scheduler params\n"
104 "\tpktsched tx <idx>\n"
105 "\t [<param> <val>] ... set Tx HW scheduler\n"
106 "\tpm [<TX page spec> <RX page spec>] read/write PM config\n"
107 "\tproto read proto SRAM\n"
108 "\tqset read qset parameters\n"
109 "\tqsets read # of qsets\n"
110 "\treg <address>[=<val>] read/write register\n"
111 "\tregdump [<module>] dump registers\n"
112 "\ttcamdump <address> <count> show TCAM contents\n"
113 "\ttcb <index> read TCB\n"
114 "\ttrace tx|rx|all on|off [not]\n"
115 "\t [<param> <val>[:<mask>]] ... write trace parameters\n"
117 exit(fp == stderr ? 1 : 0);
121 doit(const char *iff_name, unsigned long cmd, void *data)
127 snprintf(buf, 64, "/dev/%s", iff_name);
129 if ((fd = open(buf, O_RDWR)) < 0)
133 return ioctl(fd, cmd, data) < 0 ? -1 : 0;
136 static int get_int_arg(const char *s, uint32_t *valp)
140 *valp = strtoul(s, &p, 0);
142 warnx("bad parameter \"%s\"", s);
149 read_reg(const char *iff_name, uint32_t addr)
155 if (doit(iff_name, CHELSIO_GETREG, ®) < 0)
156 err(1, "register read");
161 write_reg(const char *iff_name, uint32_t addr, uint32_t val)
163 struct ch_reg ch_reg;
168 if (doit(iff_name, CHELSIO_SETREG, &ch_reg) < 0)
169 err(1, "register write");
172 static int register_io(int argc, char *argv[], int start_arg,
173 const char *iff_name)
176 uint32_t addr, val = 0, write = 0;
178 if (argc != start_arg + 1) return -1;
180 addr = strtoul(argv[start_arg], &p, 0);
181 if (p == argv[start_arg]) return -1;
182 if (*p == '=' && p[1]) {
183 val = strtoul(p + 1, &p, 0);
187 warnx("bad parameter \"%s\"", argv[start_arg]);
192 write_reg(iff_name, addr, val);
194 val = read_reg(iff_name, addr);
195 printf("%#x [%u]\n", val, val);
200 static int mdio_io(int argc, char *argv[], int start_arg, const char *iff_name)
203 struct ch_mii_data p;
204 unsigned int cmd, phy_addr, reg, mmd, val;
206 if (argc == start_arg + 3)
207 cmd = CHELSIO_GET_MIIREG;
208 else if (argc == start_arg + 4)
209 cmd = CHELSIO_SET_MIIREG;
213 if (get_int_arg(argv[start_arg], &phy_addr) ||
214 get_int_arg(argv[start_arg + 1], &mmd) ||
215 get_int_arg(argv[start_arg + 2], ®) ||
216 (cmd == CHELSIO_SET_MIIREG && get_int_arg(argv[start_arg + 3], &val)))
219 p.phy_id = phy_addr | (mmd << 8);
223 if (doit(iff_name, cmd, &p) < 0)
224 err(1, "MDIO %s", cmd == CHELSIO_GET_MIIREG ? "read" : "write");
225 if (cmd == CHELSIO_GET_MIIREG)
226 printf("%#x [%u]\n", p.val_out, p.val_out);
230 static inline uint32_t xtract(uint32_t val, int shift, int len)
232 return (val >> shift) & ((1 << len) - 1);
235 static int dump_block_regs(const struct reg_info *reg_array, uint32_t *regs)
237 uint32_t reg_val = 0; // silence compiler warning
239 for ( ; reg_array->name; ++reg_array)
240 if (!reg_array->len) {
241 reg_val = regs[reg_array->addr / 4];
242 printf("[%#5x] %-40s %#-10x [%u]\n", reg_array->addr,
243 reg_array->name, reg_val, reg_val);
245 uint32_t v = xtract(reg_val, reg_array->addr,
248 printf(" %-40s %#-10x [%u]\n", reg_array->name,
254 static int dump_regs_t2(int argc, char *argv[], int start_arg, uint32_t *regs)
257 char *block_name = NULL;
259 if (argc == start_arg + 1)
260 block_name = argv[start_arg];
261 else if (argc != start_arg)
264 if (!block_name || !strcmp(block_name, "sge"))
265 match += dump_block_regs(sge_regs, regs);
266 if (!block_name || !strcmp(block_name, "mc3"))
267 match += dump_block_regs(mc3_regs, regs);
268 if (!block_name || !strcmp(block_name, "mc4"))
269 match += dump_block_regs(mc4_regs, regs);
270 if (!block_name || !strcmp(block_name, "tpi"))
271 match += dump_block_regs(tpi_regs, regs);
272 if (!block_name || !strcmp(block_name, "tp"))
273 match += dump_block_regs(tp_regs, regs);
274 if (!block_name || !strcmp(block_name, "rat"))
275 match += dump_block_regs(rat_regs, regs);
276 if (!block_name || !strcmp(block_name, "cspi"))
277 match += dump_block_regs(cspi_regs, regs);
278 if (!block_name || !strcmp(block_name, "espi"))
279 match += dump_block_regs(espi_regs, regs);
280 if (!block_name || !strcmp(block_name, "ulp"))
281 match += dump_block_regs(ulp_regs, regs);
282 if (!block_name || !strcmp(block_name, "pl"))
283 match += dump_block_regs(pl_regs, regs);
284 if (!block_name || !strcmp(block_name, "mc5"))
285 match += dump_block_regs(mc5_regs, regs);
287 errx(1, "unknown block \"%s\"", block_name);
291 #if defined(CONFIG_T3_REGS)
292 static int dump_regs_t3(int argc, char *argv[], int start_arg, uint32_t *regs,
296 char *block_name = NULL;
298 if (argc == start_arg + 1)
299 block_name = argv[start_arg];
300 else if (argc != start_arg)
303 if (!block_name || !strcmp(block_name, "sge"))
304 match += dump_block_regs(sge3_regs, regs);
305 if (!block_name || !strcmp(block_name, "pci"))
306 match += dump_block_regs(is_pcie ? pcie0_regs : pcix1_regs,
308 if (!block_name || !strcmp(block_name, "t3dbg"))
309 match += dump_block_regs(t3dbg_regs, regs);
310 if (!block_name || !strcmp(block_name, "pmrx"))
311 match += dump_block_regs(mc7_pmrx_regs, regs);
312 if (!block_name || !strcmp(block_name, "pmtx"))
313 match += dump_block_regs(mc7_pmtx_regs, regs);
314 if (!block_name || !strcmp(block_name, "cm"))
315 match += dump_block_regs(mc7_cm_regs, regs);
316 if (!block_name || !strcmp(block_name, "cim"))
317 match += dump_block_regs(cim_regs, regs);
318 if (!block_name || !strcmp(block_name, "tp"))
319 match += dump_block_regs(tp1_regs, regs);
320 if (!block_name || !strcmp(block_name, "ulp_rx"))
321 match += dump_block_regs(ulp2_rx_regs, regs);
322 if (!block_name || !strcmp(block_name, "ulp_tx"))
323 match += dump_block_regs(ulp2_tx_regs, regs);
324 if (!block_name || !strcmp(block_name, "pmrx"))
325 match += dump_block_regs(pm1_rx_regs, regs);
326 if (!block_name || !strcmp(block_name, "pmtx"))
327 match += dump_block_regs(pm1_tx_regs, regs);
328 if (!block_name || !strcmp(block_name, "mps"))
329 match += dump_block_regs(mps0_regs, regs);
330 if (!block_name || !strcmp(block_name, "cplsw"))
331 match += dump_block_regs(cpl_switch_regs, regs);
332 if (!block_name || !strcmp(block_name, "smb"))
333 match += dump_block_regs(smb0_regs, regs);
334 if (!block_name || !strcmp(block_name, "i2c"))
335 match += dump_block_regs(i2cm0_regs, regs);
336 if (!block_name || !strcmp(block_name, "mi1"))
337 match += dump_block_regs(mi1_regs, regs);
338 if (!block_name || !strcmp(block_name, "sf"))
339 match += dump_block_regs(sf1_regs, regs);
340 if (!block_name || !strcmp(block_name, "pl"))
341 match += dump_block_regs(pl3_regs, regs);
342 if (!block_name || !strcmp(block_name, "mc5"))
343 match += dump_block_regs(mc5a_regs, regs);
344 if (!block_name || !strcmp(block_name, "xgmac0"))
345 match += dump_block_regs(xgmac0_0_regs, regs);
346 if (!block_name || !strcmp(block_name, "xgmac1"))
347 match += dump_block_regs(xgmac0_1_regs, regs);
349 errx(1, "unknown block \"%s\"", block_name);
353 static int dump_regs_t3b(int argc, char *argv[], int start_arg, uint32_t *regs,
357 char *block_name = NULL;
359 if (argc == start_arg + 1)
360 block_name = argv[start_arg];
361 else if (argc != start_arg)
364 if (!block_name || !strcmp(block_name, "sge"))
365 match += dump_block_regs(t3b_sge3_regs, regs);
366 if (!block_name || !strcmp(block_name, "pci"))
367 match += dump_block_regs(is_pcie ? t3b_pcie0_regs :
368 t3b_pcix1_regs, regs);
369 if (!block_name || !strcmp(block_name, "t3dbg"))
370 match += dump_block_regs(t3b_t3dbg_regs, regs);
371 if (!block_name || !strcmp(block_name, "pmrx"))
372 match += dump_block_regs(t3b_mc7_pmrx_regs, regs);
373 if (!block_name || !strcmp(block_name, "pmtx"))
374 match += dump_block_regs(t3b_mc7_pmtx_regs, regs);
375 if (!block_name || !strcmp(block_name, "cm"))
376 match += dump_block_regs(t3b_mc7_cm_regs, regs);
377 if (!block_name || !strcmp(block_name, "cim"))
378 match += dump_block_regs(t3b_cim_regs, regs);
379 if (!block_name || !strcmp(block_name, "tp"))
380 match += dump_block_regs(t3b_tp1_regs, regs);
381 if (!block_name || !strcmp(block_name, "ulp_rx"))
382 match += dump_block_regs(t3b_ulp2_rx_regs, regs);
383 if (!block_name || !strcmp(block_name, "ulp_tx"))
384 match += dump_block_regs(t3b_ulp2_tx_regs, regs);
385 if (!block_name || !strcmp(block_name, "pmrx"))
386 match += dump_block_regs(t3b_pm1_rx_regs, regs);
387 if (!block_name || !strcmp(block_name, "pmtx"))
388 match += dump_block_regs(t3b_pm1_tx_regs, regs);
389 if (!block_name || !strcmp(block_name, "mps"))
390 match += dump_block_regs(t3b_mps0_regs, regs);
391 if (!block_name || !strcmp(block_name, "cplsw"))
392 match += dump_block_regs(t3b_cpl_switch_regs, regs);
393 if (!block_name || !strcmp(block_name, "smb"))
394 match += dump_block_regs(t3b_smb0_regs, regs);
395 if (!block_name || !strcmp(block_name, "i2c"))
396 match += dump_block_regs(t3b_i2cm0_regs, regs);
397 if (!block_name || !strcmp(block_name, "mi1"))
398 match += dump_block_regs(t3b_mi1_regs, regs);
399 if (!block_name || !strcmp(block_name, "sf"))
400 match += dump_block_regs(t3b_sf1_regs, regs);
401 if (!block_name || !strcmp(block_name, "pl"))
402 match += dump_block_regs(t3b_pl3_regs, regs);
403 if (!block_name || !strcmp(block_name, "mc5"))
404 match += dump_block_regs(t3b_mc5a_regs, regs);
405 if (!block_name || !strcmp(block_name, "xgmac0"))
406 match += dump_block_regs(t3b_xgmac0_0_regs, regs);
407 if (!block_name || !strcmp(block_name, "xgmac1"))
408 match += dump_block_regs(t3b_xgmac0_1_regs, regs);
410 errx(1, "unknown block \"%s\"", block_name);
414 static int dump_regs_t3c(int argc, char *argv[], int start_arg, uint32_t *regs,
418 char *block_name = NULL;
420 if (argc == start_arg + 1)
421 block_name = argv[start_arg];
422 else if (argc != start_arg)
425 if (!block_name || !strcmp(block_name, "sge"))
426 match += dump_block_regs(t3c_sge3_regs, regs);
427 if (!block_name || !strcmp(block_name, "pci"))
428 match += dump_block_regs(is_pcie ? t3c_pcie0_regs :
429 t3c_pcix1_regs, regs);
430 if (!block_name || !strcmp(block_name, "t3dbg"))
431 match += dump_block_regs(t3c_t3dbg_regs, regs);
432 if (!block_name || !strcmp(block_name, "pmrx"))
433 match += dump_block_regs(t3c_mc7_pmrx_regs, regs);
434 if (!block_name || !strcmp(block_name, "pmtx"))
435 match += dump_block_regs(t3c_mc7_pmtx_regs, regs);
436 if (!block_name || !strcmp(block_name, "cm"))
437 match += dump_block_regs(t3c_mc7_cm_regs, regs);
438 if (!block_name || !strcmp(block_name, "cim"))
439 match += dump_block_regs(t3c_cim_regs, regs);
440 if (!block_name || !strcmp(block_name, "tp"))
441 match += dump_block_regs(t3c_tp1_regs, regs);
442 if (!block_name || !strcmp(block_name, "ulp_rx"))
443 match += dump_block_regs(t3c_ulp2_rx_regs, regs);
444 if (!block_name || !strcmp(block_name, "ulp_tx"))
445 match += dump_block_regs(t3c_ulp2_tx_regs, regs);
446 if (!block_name || !strcmp(block_name, "pmrx"))
447 match += dump_block_regs(t3c_pm1_rx_regs, regs);
448 if (!block_name || !strcmp(block_name, "pmtx"))
449 match += dump_block_regs(t3c_pm1_tx_regs, regs);
450 if (!block_name || !strcmp(block_name, "mps"))
451 match += dump_block_regs(t3c_mps0_regs, regs);
452 if (!block_name || !strcmp(block_name, "cplsw"))
453 match += dump_block_regs(t3c_cpl_switch_regs, regs);
454 if (!block_name || !strcmp(block_name, "smb"))
455 match += dump_block_regs(t3c_smb0_regs, regs);
456 if (!block_name || !strcmp(block_name, "i2c"))
457 match += dump_block_regs(t3c_i2cm0_regs, regs);
458 if (!block_name || !strcmp(block_name, "mi1"))
459 match += dump_block_regs(t3c_mi1_regs, regs);
460 if (!block_name || !strcmp(block_name, "sf"))
461 match += dump_block_regs(t3c_sf1_regs, regs);
462 if (!block_name || !strcmp(block_name, "pl"))
463 match += dump_block_regs(t3c_pl3_regs, regs);
464 if (!block_name || !strcmp(block_name, "mc5"))
465 match += dump_block_regs(t3c_mc5a_regs, regs);
466 if (!block_name || !strcmp(block_name, "xgmac0"))
467 match += dump_block_regs(t3c_xgmac0_0_regs, regs);
468 if (!block_name || !strcmp(block_name, "xgmac1"))
469 match += dump_block_regs(t3c_xgmac0_1_regs, regs);
471 errx(1, "unknown block \"%s\"", block_name);
477 dump_regs(int argc, char *argv[], int start_arg, const char *iff_name)
479 int i, vers, revision, is_pcie;
480 struct ch_ifconf_regs regs;
482 regs.len = REGDUMP_SIZE;
484 /* XXX: This is never freed. Looks like we don't care. */
485 if ((regs.data = malloc(regs.len)) == NULL)
486 err(1, "can't malloc");
488 if (doit(iff_name, CHELSIO_IFCONF_GETREGS, ®s))
489 err(1, "can't read registers");
491 vers = regs.version & 0x3ff;
492 revision = (regs.version >> 10) & 0x3f;
493 is_pcie = (regs.version & 0x80000000) != 0;
496 return dump_regs_t2(argc, argv, start_arg, (uint32_t *)regs.data);
497 #if defined(CONFIG_T3_REGS)
500 return dump_regs_t3(argc, argv, start_arg,
501 (uint32_t *)regs.data, is_pcie);
503 return dump_regs_t3b(argc, argv, start_arg,
504 (uint32_t *)regs.data, is_pcie);
506 return dump_regs_t3c(argc, argv, start_arg,
507 (uint32_t *)regs.data, is_pcie);
510 errx(1, "unknown card type %d.%d", vers, revision);
514 static int t3_meminfo(const uint32_t *regs)
517 SG_EGR_CNTX_BADDR = 0x58,
518 SG_CQ_CONTEXT_BADDR = 0x6c,
519 CIM_SDRAM_BASE_ADDR = 0x28c,
520 CIM_SDRAM_ADDR_SIZE = 0x290,
521 TP_CMM_MM_BASE = 0x314,
522 TP_CMM_TIMER_BASE = 0x318,
523 TP_CMM_MM_RX_FLST_BASE = 0x460,
524 TP_CMM_MM_TX_FLST_BASE = 0x464,
525 TP_CMM_MM_PS_FLST_BASE = 0x468,
526 ULPRX_ISCSI_LLIMIT = 0x50c,
527 ULPRX_ISCSI_ULIMIT = 0x510,
528 ULPRX_TDDP_LLIMIT = 0x51c,
529 ULPRX_TDDP_ULIMIT = 0x520,
530 ULPRX_STAG_LLIMIT = 0x52c,
531 ULPRX_STAG_ULIMIT = 0x530,
532 ULPRX_RQ_LLIMIT = 0x534,
533 ULPRX_RQ_ULIMIT = 0x538,
534 ULPRX_PBL_LLIMIT = 0x53c,
535 ULPRX_PBL_ULIMIT = 0x540,
538 unsigned int egr_cntxt = regs[SG_EGR_CNTX_BADDR / 4],
539 cq_cntxt = regs[SG_CQ_CONTEXT_BADDR / 4],
540 timers = regs[TP_CMM_TIMER_BASE / 4] & 0xfffffff,
541 pstructs = regs[TP_CMM_MM_BASE / 4],
542 pstruct_fl = regs[TP_CMM_MM_PS_FLST_BASE / 4],
543 rx_fl = regs[TP_CMM_MM_RX_FLST_BASE / 4],
544 tx_fl = regs[TP_CMM_MM_TX_FLST_BASE / 4],
545 cim_base = regs[CIM_SDRAM_BASE_ADDR / 4],
546 cim_size = regs[CIM_SDRAM_ADDR_SIZE / 4];
547 unsigned int iscsi_ll = regs[ULPRX_ISCSI_LLIMIT / 4],
548 iscsi_ul = regs[ULPRX_ISCSI_ULIMIT / 4],
549 tddp_ll = regs[ULPRX_TDDP_LLIMIT / 4],
550 tddp_ul = regs[ULPRX_TDDP_ULIMIT / 4],
551 stag_ll = regs[ULPRX_STAG_LLIMIT / 4],
552 stag_ul = regs[ULPRX_STAG_ULIMIT / 4],
553 rq_ll = regs[ULPRX_RQ_LLIMIT / 4],
554 rq_ul = regs[ULPRX_RQ_ULIMIT / 4],
555 pbl_ll = regs[ULPRX_PBL_LLIMIT / 4],
556 pbl_ul = regs[ULPRX_PBL_ULIMIT / 4];
558 printf("CM memory map:\n");
559 printf(" TCB region: 0x%08x - 0x%08x [%u]\n", 0, egr_cntxt - 1,
561 printf(" Egress contexts: 0x%08x - 0x%08x [%u]\n", egr_cntxt,
562 cq_cntxt - 1, cq_cntxt - egr_cntxt);
563 printf(" CQ contexts: 0x%08x - 0x%08x [%u]\n", cq_cntxt,
564 timers - 1, timers - cq_cntxt);
565 printf(" Timers: 0x%08x - 0x%08x [%u]\n", timers,
566 pstructs - 1, pstructs - timers);
567 printf(" Pstructs: 0x%08x - 0x%08x [%u]\n", pstructs,
568 pstruct_fl - 1, pstruct_fl - pstructs);
569 printf(" Pstruct FL: 0x%08x - 0x%08x [%u]\n", pstruct_fl,
570 rx_fl - 1, rx_fl - pstruct_fl);
571 printf(" Rx FL: 0x%08x - 0x%08x [%u]\n", rx_fl, tx_fl - 1,
573 printf(" Tx FL: 0x%08x - 0x%08x [%u]\n", tx_fl, cim_base - 1,
575 printf(" uP RAM: 0x%08x - 0x%08x [%u]\n", cim_base,
576 cim_base + cim_size - 1, cim_size);
578 printf("\nPMRX memory map:\n");
579 printf(" iSCSI region: 0x%08x - 0x%08x [%u]\n", iscsi_ll, iscsi_ul,
580 iscsi_ul - iscsi_ll + 1);
581 printf(" TCP DDP region: 0x%08x - 0x%08x [%u]\n", tddp_ll, tddp_ul,
582 tddp_ul - tddp_ll + 1);
583 printf(" TPT region: 0x%08x - 0x%08x [%u]\n", stag_ll, stag_ul,
584 stag_ul - stag_ll + 1);
585 printf(" RQ region: 0x%08x - 0x%08x [%u]\n", rq_ll, rq_ul,
587 printf(" PBL region: 0x%08x - 0x%08x [%u]\n", pbl_ll, pbl_ul,
588 pbl_ul - pbl_ll + 1);
592 static int meminfo(int argc, char *argv[], int start_arg, const char *iff_name)
595 struct ch_ifconf_regs regs;
597 regs.len = REGDUMP_SIZE;
598 if ((regs.data = malloc(regs.len)) == NULL)
599 err(1, "can't malloc");
601 if (doit(iff_name, CHELSIO_IFCONF_GETREGS, ®s))
602 err(1, "can't read registers");
604 vers = regs.version & 0x3ff;
606 return t3_meminfo((uint32_t *)regs.data);
608 errx(1, "unknown card type %d", vers);
612 static int mtu_tab_op(int argc, char *argv[], int start_arg,
613 const char *iff_name)
618 if (argc == start_arg) {
619 if (doit(iff_name, CHELSIO_GETMTUTAB, &m) < 0)
620 err(1, "get MTU table");
621 for (i = 0; i < m.nmtus; ++i)
622 printf("%u ", m.mtus[i]);
624 } else if (argc <= start_arg + NMTUS) {
625 m.nmtus = argc - start_arg;
627 for (i = 0; i < m.nmtus; ++i) {
629 unsigned long mt = strtoul(argv[start_arg + i], &p, 0);
631 if (*p || mt > 9600) {
632 warnx("bad parameter \"%s\"",
633 argv[start_arg + i]);
636 if (i && mt < m.mtus[i - 1])
637 errx(1, "MTUs must be in ascending order");
640 if (doit(iff_name, CHELSIO_SETMTUTAB, &m) < 0)
641 err(1, "set MTU table");
648 #ifdef CHELSIO_INTERNAL
649 static void show_egress_cntxt(uint32_t data[])
651 printf("credits: %u\n", data[0] & 0x7fff);
652 printf("GTS: %u\n", (data[0] >> 15) & 1);
653 printf("index: %u\n", data[0] >> 16);
654 printf("queue size: %u\n", data[1] & 0xffff);
655 printf("base address: 0x%llx\n",
656 ((data[1] >> 16) | ((uint64_t)data[2] << 16) |
657 (((uint64_t)data[3] & 0xf) << 48)) << 12);
658 printf("rsp queue #: %u\n", (data[3] >> 4) & 7);
659 printf("cmd queue #: %u\n", (data[3] >> 7) & 1);
660 printf("TUN: %u\n", (data[3] >> 8) & 1);
661 printf("TOE: %u\n", (data[3] >> 9) & 1);
662 printf("generation: %u\n", (data[3] >> 10) & 1);
663 printf("uP token: %u\n", (data[3] >> 11) & 0xfffff);
664 printf("valid: %u\n", (data[3] >> 31) & 1);
667 static void show_fl_cntxt(uint32_t data[])
669 printf("base address: 0x%llx\n",
670 ((uint64_t)data[0] | ((uint64_t)data[1] & 0xfffff) << 32) << 12);
671 printf("index: %u\n", (data[1] >> 20) | ((data[2] & 0xf) << 12));
672 printf("queue size: %u\n", (data[2] >> 4) & 0xffff);
673 printf("generation: %u\n", (data[2] >> 20) & 1);
674 printf("entry size: %u\n",
675 ((data[2] >> 21) & 0x7ff) | (data[3] & 0x1fffff));
676 printf("congest thr: %u\n", (data[3] >> 21) & 0x3ff);
677 printf("GTS: %u\n", (data[3] >> 31) & 1);
680 static void show_response_cntxt(uint32_t data[])
682 printf("index: %u\n", data[0] & 0xffff);
683 printf("size: %u\n", data[0] >> 16);
684 printf("base address: 0x%llx\n",
685 ((uint64_t)data[1] | ((uint64_t)data[2] & 0xfffff) << 32) << 12);
686 printf("MSI-X/RspQ: %u\n", (data[2] >> 20) & 0x3f);
687 printf("intr enable: %u\n", (data[2] >> 26) & 1);
688 printf("intr armed: %u\n", (data[2] >> 27) & 1);
689 printf("generation: %u\n", (data[2] >> 28) & 1);
690 printf("CQ mode: %u\n", (data[2] >> 31) & 1);
691 printf("FL threshold: %u\n", data[3]);
694 static void show_cq_cntxt(uint32_t data[])
696 printf("index: %u\n", data[0] & 0xffff);
697 printf("size: %u\n", data[0] >> 16);
698 printf("base address: 0x%llx\n",
699 ((uint64_t)data[1] | ((uint64_t)data[2] & 0xfffff) << 32) << 12);
700 printf("rsp queue #: %u\n", (data[2] >> 20) & 0x3f);
701 printf("AN: %u\n", (data[2] >> 26) & 1);
702 printf("armed: %u\n", (data[2] >> 27) & 1);
703 printf("ANS: %u\n", (data[2] >> 28) & 1);
704 printf("generation: %u\n", (data[2] >> 29) & 1);
705 printf("overflow mode: %u\n", (data[2] >> 31) & 1);
706 printf("credits: %u\n", data[3] & 0xffff);
707 printf("credit threshold: %u\n", data[3] >> 16);
710 static int get_sge_context(int argc, char *argv[], int start_arg,
711 const char *iff_name)
715 if (argc != start_arg + 2) return -1;
717 if (!strcmp(argv[start_arg], "egress"))
718 ctx.cntxt_type = CNTXT_TYPE_EGRESS;
719 else if (!strcmp(argv[start_arg], "fl"))
720 ctx.cntxt_type = CNTXT_TYPE_FL;
721 else if (!strcmp(argv[start_arg], "response"))
722 ctx.cntxt_type = CNTXT_TYPE_RSP;
723 else if (!strcmp(argv[start_arg], "cq"))
724 ctx.cntxt_type = CNTXT_TYPE_CQ;
726 warnx("unknown context type \"%s\"; known types are egress, "
727 "fl, cq, and response", argv[start_arg]);
731 if (get_int_arg(argv[start_arg + 1], &ctx.cntxt_id))
734 if (doit(iff_name, CHELSIO_GET_SGE_CONTEXT, &ctx) < 0)
735 err(1, "get SGE context");
737 if (!strcmp(argv[start_arg], "egress"))
738 show_egress_cntxt(ctx.data);
739 else if (!strcmp(argv[start_arg], "fl"))
740 show_fl_cntxt(ctx.data);
741 else if (!strcmp(argv[start_arg], "response"))
742 show_response_cntxt(ctx.data);
743 else if (!strcmp(argv[start_arg], "cq"))
744 show_cq_cntxt(ctx.data);
748 #if __BYTE_ORDER == __BIG_ENDIAN
749 # define ntohll(n) (n)
751 # define ntohll(n) bswap_64(n)
754 static int get_sge_desc(int argc, char *argv[], int start_arg,
755 const char *iff_name)
758 unsigned int n = 1, qset, qnum;
761 if (argc != start_arg + 3 && argc != start_arg + 4)
764 if (get_int_arg(argv[start_arg], &qset) ||
765 get_int_arg(argv[start_arg + 1], &qnum) ||
766 get_int_arg(argv[start_arg + 2], &desc.idx))
769 if (argc == start_arg + 4 && get_int_arg(argv[start_arg + 3], &n))
773 errx(1, "invalid queue number %d, range is 0..5", qnum);
775 desc.queue_num = qset * 6 + qnum;
777 for (; n--; desc.idx++) {
778 if (doit(iff_name, CHELSIO_GET_SGE_DESC, &desc) < 0)
779 err(1, "get SGE descriptor");
781 p = (uint64_t *)desc.data;
783 printf("Descriptor %u: cmd %u, TID %u, %s%s%s%s%u flits\n",
784 desc.idx, (unsigned int)(wr_hdr >> 56),
785 ((unsigned int)wr_hdr >> 8) & 0xfffff,
786 ((wr_hdr >> 55) & 1) ? "SOP, " : "",
787 ((wr_hdr >> 54) & 1) ? "EOP, " : "",
788 ((wr_hdr >> 53) & 1) ? "COMPL, " : "",
789 ((wr_hdr >> 52) & 1) ? "SGL, " : "",
790 (unsigned int)wr_hdr & 0xff);
792 for (; desc.size; p++, desc.size -= sizeof(uint64_t))
793 printf("%016" PRIx64 "%c", ntohll(*p),
794 desc.size % 32 == 8 ? '\n' : ' ');
800 static int get_tcb2(int argc, char *argv[], int start_arg, const char *iff_name)
804 unsigned int tcb_idx;
805 struct ch_mem_range mr;
807 if (argc != start_arg + 1)
810 if (get_int_arg(argv[start_arg], &tcb_idx))
813 mr.buf = calloc(1, TCB_SIZE);
818 mr.addr = tcb_idx * TCB_SIZE;
821 if (doit(iff_name, CHELSIO_GET_MEM, &mr) < 0)
824 for (d = (uint64_t *)&mr.buf, i = 0; i < TCB_SIZE / 32; i++) {
826 printf(" %08x %08x %08x %08x", (uint32_t)d[1],
827 (uint32_t)(d[1] >> 32), (uint32_t)d[0],
828 (uint32_t)(d[0] >> 32));
830 printf(" %08x %08x %08x %08x\n", (uint32_t)d[1],
831 (uint32_t)(d[1] >> 32), (uint32_t)d[0],
832 (uint32_t)(d[0] >> 32));
839 static int get_pm_page_spec(const char *s, unsigned int *page_size,
840 unsigned int *num_pages)
845 val = strtoul(s, &p, 0);
846 if (p == s) return -1;
847 if (*p == 'x' && p[1]) {
849 *page_size = strtoul(p + 1, &p, 0);
854 *page_size <<= 10; // KB -> bytes
858 static int conf_pm(int argc, char *argv[], int start_arg, const char *iff_name)
862 if (argc == start_arg) {
863 if (doit(iff_name, CHELSIO_GET_PM, &pm) < 0)
864 err(1, "read pm config");
865 printf("%ux%uKB TX pages, %ux%uKB RX pages, %uKB total memory\n",
866 pm.tx_num_pg, pm.tx_pg_sz >> 10, pm.rx_num_pg,
867 pm.rx_pg_sz >> 10, pm.pm_total >> 10);
871 if (argc != start_arg + 2) return -1;
873 if (get_pm_page_spec(argv[start_arg], &pm.tx_pg_sz, &pm.tx_num_pg)) {
874 warnx("bad parameter \"%s\"", argv[start_arg]);
877 if (get_pm_page_spec(argv[start_arg + 1], &pm.rx_pg_sz,
879 warnx("bad parameter \"%s\"", argv[start_arg + 1]);
882 if (doit(iff_name, CHELSIO_SET_PM, &pm) < 0)
887 #ifdef CHELSIO_INTERNAL
888 static int dump_tcam(int argc, char *argv[], int start_arg,
889 const char *iff_name)
892 struct ch_tcam_word op;
894 if (argc != start_arg + 2) return -1;
896 if (get_int_arg(argv[start_arg], &op.addr) ||
897 get_int_arg(argv[start_arg + 1], &nwords))
901 if (doit(iff_name, CHELSIO_READ_TCAM_WORD, &op) < 0)
904 printf("0x%08x: 0x%02x 0x%08x 0x%08x\n", op.addr,
905 op.buf[0] & 0xff, op.buf[1], op.buf[2]);
911 static void hexdump_8b(unsigned int start, uint64_t *data, unsigned int len)
916 printf("0x%08x:", start);
917 for (i = 0; i < 4 && len; ++i, --len)
918 printf(" %016llx", (unsigned long long)*data++);
924 static int dump_mc7(int argc, char *argv[], int start_arg,
925 const char *iff_name)
927 struct ch_mem_range mem;
928 unsigned int mem_id, addr, len;
930 if (argc != start_arg + 3) return -1;
932 if (!strcmp(argv[start_arg], "cm"))
934 else if (!strcmp(argv[start_arg], "rx"))
936 else if (!strcmp(argv[start_arg], "tx"))
939 errx(1, "unknown memory \"%s\"; must be one of \"cm\", \"tx\","
940 " or \"rx\"", argv[start_arg]);
942 if (get_int_arg(argv[start_arg + 1], &addr) ||
943 get_int_arg(argv[start_arg + 2], &len))
946 mem.buf = malloc(len);
948 err(1, "memory dump");
954 if (doit(iff_name, CHELSIO_GET_MEM, &mem) < 0)
955 err(1, "memory dump");
957 hexdump_8b(mem.addr, (uint64_t *)mem.buf, mem.len >> 3);
963 /* Max FW size is 32K including version, +4 bytes for the checksum. */
964 #define MAX_FW_IMAGE_SIZE (32768 + 4)
966 static int load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
969 struct ch_mem_range op;
970 const char *fname = argv[start_arg];
972 if (argc != start_arg + 1) return -1;
974 fd = open(fname, O_RDONLY);
976 err(1, "load firmware");
978 bzero(&op, sizeof(op));
979 op.buf = malloc(MAX_FW_IMAGE_SIZE + 1);
981 err(1, "load firmware");
983 op.len = read(fd, op.buf, MAX_FW_IMAGE_SIZE + 1);
985 err(1, "load firmware");
986 if (op.len > MAX_FW_IMAGE_SIZE)
987 errx(1, "FW image too large");
989 if (doit(iff_name, CHELSIO_LOAD_FW, &op) < 0)
990 err(1, "load firmware");
994 /* Max BOOT size is 255*512 bytes including the BIOS boot ROM basic header */
995 #define MAX_BOOT_IMAGE_SIZE (0xff * 512)
997 static int load_boot(int argc, char *argv[],
998 int start_arg, const char *iff_name)
1001 struct ch_mem_range op;
1002 const char *fname = argv[start_arg];
1004 if (argc != start_arg + 1) return -1;
1006 fd = open(fname, O_RDONLY);
1008 err(1, "load boot image");
1010 op.buf = malloc(MAX_BOOT_IMAGE_SIZE + 1);
1012 err(1, "load boot image");
1014 len = read(fd, op.buf, MAX_BOOT_IMAGE_SIZE + 1);
1016 err(1, "load boot image");
1017 if (len > MAX_BOOT_IMAGE_SIZE)
1018 errx(1, "boot image too large");
1022 if (doit(iff_name, CHELSIO_LOAD_BOOT, &op) < 0)
1023 err(1, "load boot image");
1028 static int dump_proto_sram(const char *iff_name)
1031 uint8_t buf[PROTO_SRAM_SIZE];
1032 struct ch_eeprom ee;
1035 bzero(buf, sizeof(buf));
1036 ee.offset = PROTO_SRAM_EEPROM_ADDR;
1038 ee.len = sizeof(buf);
1039 if (doit(iff_name, CHELSIO_GET_EEPROM, &ee))
1040 err(1, "show protocol sram");
1042 for (i = 0; i < PROTO_SRAM_LINES; i++) {
1043 for (j = PROTO_SRAM_LINE_NIBBLES - 1; j >= 0; j--) {
1044 int nibble_idx = i * PROTO_SRAM_LINE_NIBBLES + j;
1045 uint8_t nibble = p[nibble_idx / 2];
1051 printf("%x", nibble);
1058 static int proto_sram_op(int argc, char *argv[], int start_arg,
1059 const char *iff_name)
1061 if (argc == start_arg)
1062 return dump_proto_sram(iff_name);
1066 static int dump_qset_params(const char *iff_name)
1068 struct ch_qset_params qp;
1072 while (doit(iff_name, CHELSIO_GET_QSET_PARAMS, &qp) == 0) {
1074 printf("Qset TxQ0 TxQ1 TxQ2 RspQ RxQ0 RxQ1"
1076 printf("%4u %6u %6u %6u %6u %6u %6u %5u %4u %5d\n",
1078 qp.txq_size[0], qp.txq_size[1], qp.txq_size[2],
1079 qp.rspq_size, qp.fl_size[0], qp.fl_size[1],
1080 qp.cong_thres, qp.intr_lat, qp.vector);
1083 if (!qp.qset_idx || (errno && errno != EINVAL))
1084 err(1, "get qset parameters");
1088 static int qset_config(int argc, char *argv[], int start_arg,
1089 const char *iff_name)
1091 struct ch_qset_params qp;
1093 if (argc == start_arg)
1094 return dump_qset_params(iff_name);
1099 static int qset_num_config(int argc, char *argv[], int start_arg,
1100 const char *iff_name)
1104 if (argc == start_arg) {
1105 if (doit(iff_name, CHELSIO_GET_QSET_NUM, ®) < 0)
1106 err(1, "get qsets");
1107 printf("%u\n", reg.val);
1115 * Parse a string containing an IP address with an optional network prefix.
1117 static int parse_ipaddr(const char *s, uint32_t *addr, uint32_t *mask)
1122 *mask = 0xffffffffU;
1123 slash = strchr(s, '/');
1126 if (!inet_aton(s, &ia)) {
1132 *addr = ntohl(ia.s_addr);
1134 unsigned int prefix = strtoul(slash + 1, &p, 10);
1137 if (p == slash + 1 || *p || prefix > 32)
1139 *mask <<= (32 - prefix);
1145 * Parse a string containing a value and an optional colon separated mask.
1147 static int parse_val_mask_param(const char *s, uint32_t *val, uint32_t *mask)
1151 *mask = 0xffffffffU;
1152 *val = strtoul(s, &p, 0);
1155 if (*p == ':' && p[1])
1156 *mask = strtoul(p + 1, &p, 0);
1160 static int parse_trace_param(const char *s, uint32_t *val, uint32_t *mask)
1162 return strchr(s, '.') ? parse_ipaddr(s, val, mask) :
1163 parse_val_mask_param(s, val, mask);
1166 static int trace_config(int argc, char *argv[], int start_arg,
1167 const char *iff_name)
1170 struct ch_trace trace;
1172 if (argc == start_arg)
1175 memset(&trace, 0, sizeof(trace));
1176 if (!strcmp(argv[start_arg], "tx"))
1177 trace.config_tx = 1;
1178 else if (!strcmp(argv[start_arg], "rx"))
1179 trace.config_rx = 1;
1180 else if (!strcmp(argv[start_arg], "all"))
1181 trace.config_tx = trace.config_rx = 1;
1183 errx(1, "bad trace filter \"%s\"; must be one of \"rx\", "
1184 "\"tx\" or \"all\"", argv[start_arg]);
1186 if (argc == ++start_arg)
1188 if (!strcmp(argv[start_arg], "on")) {
1189 trace.trace_tx = trace.config_tx;
1190 trace.trace_rx = trace.config_rx;
1191 } else if (strcmp(argv[start_arg], "off"))
1192 errx(1, "bad argument \"%s\"; must be \"on\" or \"off\"",
1196 if (start_arg < argc && !strcmp(argv[start_arg], "not")) {
1197 trace.invert_match = 1;
1201 while (start_arg + 2 <= argc) {
1202 int ret = parse_trace_param(argv[start_arg + 1], &val, &mask);
1204 if (!strcmp(argv[start_arg], "interface")) {
1206 trace.intf_mask = mask;
1207 } else if (!strcmp(argv[start_arg], "sip")) {
1209 trace.sip_mask = mask;
1210 } else if (!strcmp(argv[start_arg], "dip")) {
1212 trace.dip_mask = mask;
1213 } else if (!strcmp(argv[start_arg], "sport")) {
1215 trace.sport_mask = mask;
1216 } else if (!strcmp(argv[start_arg], "dport")) {
1218 trace.dport_mask = mask;
1219 } else if (!strcmp(argv[start_arg], "vlan")) {
1221 trace.vlan_mask = mask;
1222 } else if (!strcmp(argv[start_arg], "proto")) {
1224 trace.proto_mask = mask;
1226 errx(1, "unknown trace parameter \"%s\"\n"
1227 "known parameters are \"interface\", \"sip\", "
1228 "\"dip\", \"sport\", \"dport\", \"vlan\", "
1229 "\"proto\"", argv[start_arg]);
1231 errx(1, "bad parameter \"%s\"", argv[start_arg + 1]);
1234 if (start_arg != argc)
1235 errx(1, "unknown parameter \"%s\"", argv[start_arg]);
1237 if (doit(iff_name, CHELSIO_SET_TRACE_FILTER, &trace) < 0)
1242 static int get_sched_param(int argc, char *argv[], int pos, unsigned int *valp)
1244 if (pos + 1 >= argc)
1245 errx(1, "missing value for %s", argv[pos]);
1246 if (get_int_arg(argv[pos + 1], valp))
1251 static int tx_sched(int argc, char *argv[], int start_arg, const char *iff_name)
1253 struct ch_hw_sched op;
1254 unsigned int idx, val;
1256 if (argc < 5 || get_int_arg(argv[start_arg++], &idx))
1260 op.mode = op.channel = -1;
1261 op.kbps = op.class_ipg = op.flow_ipg = -1;
1263 while (argc > start_arg) {
1264 if (!strcmp(argv[start_arg], "mode")) {
1265 if (start_arg + 1 >= argc)
1266 errx(1, "missing value for mode");
1267 if (!strcmp(argv[start_arg + 1], "class"))
1269 else if (!strcmp(argv[start_arg + 1], "flow"))
1272 errx(1, "bad mode \"%s\"", argv[start_arg + 1]);
1273 } else if (!strcmp(argv[start_arg], "channel") &&
1274 !get_sched_param(argc, argv, start_arg, &val))
1276 else if (!strcmp(argv[start_arg], "rate") &&
1277 !get_sched_param(argc, argv, start_arg, &val))
1279 else if (!strcmp(argv[start_arg], "ipg") &&
1280 !get_sched_param(argc, argv, start_arg, &val))
1282 else if (!strcmp(argv[start_arg], "flowipg") &&
1283 !get_sched_param(argc, argv, start_arg, &val))
1286 errx(1, "unknown scheduler parameter \"%s\"",
1291 if (doit(iff_name, CHELSIO_SET_HW_SCHED, &op) < 0)
1297 static int pktsched(int argc, char *argv[], int start_arg, const char *iff_name)
1299 struct ch_pktsched_params op;
1300 unsigned int idx, min = -1, max, binding = -1;
1303 errx(1, "no scheduler specified");
1305 if (!strcmp(argv[start_arg], "port")) {
1306 if (argc != start_arg + 4)
1308 if (get_int_arg(argv[start_arg + 1], &idx) ||
1309 get_int_arg(argv[start_arg + 2], &min) ||
1310 get_int_arg(argv[start_arg + 3], &max))
1313 } else if (!strcmp(argv[start_arg], "tunnelq")) {
1314 if (argc != start_arg + 4)
1316 if (get_int_arg(argv[start_arg + 1], &idx) ||
1317 get_int_arg(argv[start_arg + 2], &max) ||
1318 get_int_arg(argv[start_arg + 3], &binding))
1321 } else if (!strcmp(argv[start_arg], "tx"))
1322 return tx_sched(argc, argv, start_arg + 1, iff_name);
1324 errx(1, "unknown scheduler \"%s\"; must be one of \"port\", "
1325 "\"tunnelq\" or \"tx\"", argv[start_arg]);
1330 op.binding = binding;
1331 if (doit(iff_name, CHELSIO_SET_PKTSCHED, &op) < 0)
1336 static int clear_stats(int argc, char *argv[], int start_arg,
1337 const char *iff_name)
1339 if (doit(iff_name, CHELSIO_CLEAR_STATS, NULL) < 0)
1340 err(1, "clearstats");
1345 int main(int argc, char *argv[])
1348 const char *iff_name;
1353 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
1355 if (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version")) {
1356 printf("%s version %s\n", PROGNAME, VERSION);
1357 printf("%s\n", COPYRIGHT);
1362 if (argc < 3) usage(stderr);
1365 if (!strcmp(argv[2], "reg"))
1366 r = register_io(argc, argv, 3, iff_name);
1367 else if (!strcmp(argv[2], "mdio"))
1368 r = mdio_io(argc, argv, 3, iff_name);
1369 else if (!strcmp(argv[2], "mtus"))
1370 r = mtu_tab_op(argc, argv, 3, iff_name);
1371 else if (!strcmp(argv[2], "pm"))
1372 r = conf_pm(argc, argv, 3, iff_name);
1373 else if (!strcmp(argv[2], "regdump"))
1374 r = dump_regs(argc, argv, 3, iff_name);
1375 else if (!strcmp(argv[2], "tcamdump"))
1376 r = dump_tcam(argc, argv, 3, iff_name);
1377 else if (!strcmp(argv[2], "memdump"))
1378 r = dump_mc7(argc, argv, 3, iff_name);
1379 else if (!strcmp(argv[2], "meminfo"))
1380 r = meminfo(argc, argv, 3, iff_name);
1381 else if (!strcmp(argv[2], "context"))
1382 r = get_sge_context(argc, argv, 3, iff_name);
1383 else if (!strcmp(argv[2], "desc"))
1384 r = get_sge_desc(argc, argv, 3, iff_name);
1385 else if (!strcmp(argv[2], "loadfw"))
1386 r = load_fw(argc, argv, 3, iff_name);
1387 else if (!strcmp(argv[2], "loadboot"))
1388 r = load_boot(argc, argv, 3, iff_name);
1389 else if (!strcmp(argv[2], "proto"))
1390 r = proto_sram_op(argc, argv, 3, iff_name);
1391 else if (!strcmp(argv[2], "qset"))
1392 r = qset_config(argc, argv, 3, iff_name);
1393 else if (!strcmp(argv[2], "qsets"))
1394 r = qset_num_config(argc, argv, 3, iff_name);
1395 else if (!strcmp(argv[2], "trace"))
1396 r = trace_config(argc, argv, 3, iff_name);
1397 else if (!strcmp(argv[2], "pktsched"))
1398 r = pktsched(argc, argv, 3, iff_name);
1399 else if (!strcmp(argv[2], "tcb"))
1400 r = get_tcb2(argc, argv, 3, iff_name);
1401 else if (!strcmp(argv[2], "clearstats"))
1402 r = clear_stats(argc, argv, 3, iff_name);