1 /**************************************************************************
3 Copyright (c) 2007-2009, 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>
57 #include <sys/endian.h>
61 #define TCB_WORDS (TCB_SIZE / 4)
62 #define PROTO_SRAM_LINES 128
63 #define PROTO_SRAM_LINE_BITS 132
64 #define PROTO_SRAM_LINE_NIBBLES (132 / 4)
65 #define PROTO_SRAM_SIZE (PROTO_SRAM_LINE_NIBBLES * PROTO_SRAM_LINES / 2)
66 #define PROTO_SRAM_EEPROM_ADDR 4096
68 #include <cxgb_ioctl.h>
69 #include <common/cxgb_regs.h>
80 #if defined(CONFIG_T3_REGS)
81 # include "reg_defs_t3.c"
82 # include "reg_defs_t3b.c"
83 # include "reg_defs_t3c.c"
86 static const char *progname;
91 fprintf(fp, "Usage: %s <interface> [operation]\n", progname);
93 "\tclearstats clear MAC statistics\n"
94 "\tcontext <type> <id> show an SGE context\n"
95 "\tdesc <qset> <queue> <idx> [<cnt>] dump SGE descriptors\n"
96 "\tioqs dump uP IOQs\n"
97 "\tla dump uP logic analyzer info\n"
98 "\tloadboot <boot image> download boot image\n"
99 "\tloadfw <FW image> download firmware\n"
100 "\tmdio <phy_addr> <mmd_addr>\n"
101 "\t <reg_addr> [<val>] read/write MDIO register\n"
102 "\tmemdump cm|tx|rx <addr> <len> dump a mem range\n"
103 "\tmeminfo show memory info\n"
104 "\tmtus [<mtu0>...<mtuN>] read/write MTU table\n"
105 "\tpktsched port <idx> <min> <max> set TX port scheduler params\n"
106 "\tpktsched tunnelq <idx> <max>\n"
107 "\t <binding> set TX tunnelq scheduler params\n"
108 "\tpktsched tx <idx>\n"
109 "\t [<param> <val>] ... set Tx HW scheduler\n"
110 "\tpm [<TX page spec> <RX page spec>] read/write PM config\n"
111 "\tproto read proto SRAM\n"
112 "\tqset read qset parameters\n"
113 "\tqsets read # of qsets\n"
114 "\treg <address>[=<val>] read/write register\n"
115 "\tregdump [<module>] dump registers\n"
116 "\ttcamdump <address> <count> show TCAM contents\n"
117 "\ttcb <index> read TCB\n"
118 "\ttrace tx|rx|all on|off [not]\n"
119 "\t [<param> <val>[:<mask>]] ... write trace parameters\n"
121 exit(fp == stderr ? 1 : 0);
125 doit(const char *iff_name, unsigned long cmd, void *data)
131 snprintf(buf, 64, "/dev/%s", iff_name);
133 if ((fd = open(buf, O_RDWR)) < 0)
137 return ioctl(fd, cmd, data) < 0 ? -1 : 0;
141 get_int_arg(const char *s, uint32_t *valp)
145 *valp = strtoul(s, &p, 0);
147 warnx("bad parameter \"%s\"", s);
154 read_reg(const char *iff_name, uint32_t addr)
160 if (doit(iff_name, CHELSIO_GETREG, ®) < 0)
161 err(1, "register read");
166 write_reg(const char *iff_name, uint32_t addr, uint32_t val)
168 struct ch_reg ch_reg;
173 if (doit(iff_name, CHELSIO_SETREG, &ch_reg) < 0)
174 err(1, "register write");
178 register_io(int argc, char *argv[], int start_arg,
179 const char *iff_name)
182 uint32_t addr, val = 0, w = 0;
184 if (argc != start_arg + 1) return -1;
186 addr = strtoul(argv[start_arg], &p, 0);
187 if (p == argv[start_arg]) return -1;
188 if (*p == '=' && p[1]) {
189 val = strtoul(p + 1, &p, 0);
193 warnx("bad parameter \"%s\"", argv[start_arg]);
198 write_reg(iff_name, addr, val);
200 val = read_reg(iff_name, addr);
201 printf("%#x [%u]\n", val, val);
207 mdio_io(int argc, char *argv[], int start_arg, const char *iff_name)
209 struct ch_mii_data p;
210 unsigned int cmd, phy_addr, reg, mmd, val;
212 if (argc == start_arg + 3)
213 cmd = CHELSIO_GET_MIIREG;
214 else if (argc == start_arg + 4)
215 cmd = CHELSIO_SET_MIIREG;
219 if (get_int_arg(argv[start_arg], &phy_addr) ||
220 get_int_arg(argv[start_arg + 1], &mmd) ||
221 get_int_arg(argv[start_arg + 2], ®) ||
222 (cmd == CHELSIO_SET_MIIREG && get_int_arg(argv[start_arg + 3], &val)))
225 p.phy_id = phy_addr | (mmd << 8);
229 if (doit(iff_name, cmd, &p) < 0)
230 err(1, "MDIO %s", cmd == CHELSIO_GET_MIIREG ? "read" : "write");
231 if (cmd == CHELSIO_GET_MIIREG)
232 printf("%#x [%u]\n", p.val_out, p.val_out);
237 uint32_t xtract(uint32_t val, int shift, int len)
239 return (val >> shift) & ((1 << len) - 1);
243 dump_block_regs(const struct reg_info *reg_array, uint32_t *regs)
245 uint32_t reg_val = 0; // silence compiler warning
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);
253 uint32_t v = xtract(reg_val, reg_array->addr,
256 printf(" %-40s %#-10x [%u]\n", reg_array->name,
263 dump_regs_t2(int argc, char *argv[], int start_arg, uint32_t *regs)
266 char *block_name = NULL;
268 if (argc == start_arg + 1)
269 block_name = argv[start_arg];
270 else if (argc != start_arg)
273 if (!block_name || !strcmp(block_name, "sge"))
274 match += dump_block_regs(sge_regs, regs);
275 if (!block_name || !strcmp(block_name, "mc3"))
276 match += dump_block_regs(mc3_regs, regs);
277 if (!block_name || !strcmp(block_name, "mc4"))
278 match += dump_block_regs(mc4_regs, regs);
279 if (!block_name || !strcmp(block_name, "tpi"))
280 match += dump_block_regs(tpi_regs, regs);
281 if (!block_name || !strcmp(block_name, "tp"))
282 match += dump_block_regs(tp_regs, regs);
283 if (!block_name || !strcmp(block_name, "rat"))
284 match += dump_block_regs(rat_regs, regs);
285 if (!block_name || !strcmp(block_name, "cspi"))
286 match += dump_block_regs(cspi_regs, regs);
287 if (!block_name || !strcmp(block_name, "espi"))
288 match += dump_block_regs(espi_regs, regs);
289 if (!block_name || !strcmp(block_name, "ulp"))
290 match += dump_block_regs(ulp_regs, regs);
291 if (!block_name || !strcmp(block_name, "pl"))
292 match += dump_block_regs(pl_regs, regs);
293 if (!block_name || !strcmp(block_name, "mc5"))
294 match += dump_block_regs(mc5_regs, regs);
296 errx(1, "unknown block \"%s\"", block_name);
300 #if defined(CONFIG_T3_REGS)
302 dump_regs_t3(int argc, char *argv[], int start_arg, uint32_t *regs, int is_pcie)
305 char *block_name = NULL;
307 if (argc == start_arg + 1)
308 block_name = argv[start_arg];
309 else if (argc != start_arg)
312 if (!block_name || !strcmp(block_name, "sge"))
313 match += dump_block_regs(sge3_regs, regs);
314 if (!block_name || !strcmp(block_name, "pci"))
315 match += dump_block_regs(is_pcie ? pcie0_regs : pcix1_regs,
317 if (!block_name || !strcmp(block_name, "t3dbg"))
318 match += dump_block_regs(t3dbg_regs, regs);
319 if (!block_name || !strcmp(block_name, "pmrx"))
320 match += dump_block_regs(mc7_pmrx_regs, regs);
321 if (!block_name || !strcmp(block_name, "pmtx"))
322 match += dump_block_regs(mc7_pmtx_regs, regs);
323 if (!block_name || !strcmp(block_name, "cm"))
324 match += dump_block_regs(mc7_cm_regs, regs);
325 if (!block_name || !strcmp(block_name, "cim"))
326 match += dump_block_regs(cim_regs, regs);
327 if (!block_name || !strcmp(block_name, "tp"))
328 match += dump_block_regs(tp1_regs, regs);
329 if (!block_name || !strcmp(block_name, "ulp_rx"))
330 match += dump_block_regs(ulp2_rx_regs, regs);
331 if (!block_name || !strcmp(block_name, "ulp_tx"))
332 match += dump_block_regs(ulp2_tx_regs, regs);
333 if (!block_name || !strcmp(block_name, "pmrx"))
334 match += dump_block_regs(pm1_rx_regs, regs);
335 if (!block_name || !strcmp(block_name, "pmtx"))
336 match += dump_block_regs(pm1_tx_regs, regs);
337 if (!block_name || !strcmp(block_name, "mps"))
338 match += dump_block_regs(mps0_regs, regs);
339 if (!block_name || !strcmp(block_name, "cplsw"))
340 match += dump_block_regs(cpl_switch_regs, regs);
341 if (!block_name || !strcmp(block_name, "smb"))
342 match += dump_block_regs(smb0_regs, regs);
343 if (!block_name || !strcmp(block_name, "i2c"))
344 match += dump_block_regs(i2cm0_regs, regs);
345 if (!block_name || !strcmp(block_name, "mi1"))
346 match += dump_block_regs(mi1_regs, regs);
347 if (!block_name || !strcmp(block_name, "sf"))
348 match += dump_block_regs(sf1_regs, regs);
349 if (!block_name || !strcmp(block_name, "pl"))
350 match += dump_block_regs(pl3_regs, regs);
351 if (!block_name || !strcmp(block_name, "mc5"))
352 match += dump_block_regs(mc5a_regs, regs);
353 if (!block_name || !strcmp(block_name, "xgmac0"))
354 match += dump_block_regs(xgmac0_0_regs, regs);
355 if (!block_name || !strcmp(block_name, "xgmac1"))
356 match += dump_block_regs(xgmac0_1_regs, regs);
358 errx(1, "unknown block \"%s\"", block_name);
363 dump_regs_t3b(int argc, char *argv[], int start_arg, uint32_t *regs,
367 char *block_name = NULL;
369 if (argc == start_arg + 1)
370 block_name = argv[start_arg];
371 else if (argc != start_arg)
374 if (!block_name || !strcmp(block_name, "sge"))
375 match += dump_block_regs(t3b_sge3_regs, regs);
376 if (!block_name || !strcmp(block_name, "pci"))
377 match += dump_block_regs(is_pcie ? t3b_pcie0_regs :
378 t3b_pcix1_regs, regs);
379 if (!block_name || !strcmp(block_name, "t3dbg"))
380 match += dump_block_regs(t3b_t3dbg_regs, regs);
381 if (!block_name || !strcmp(block_name, "pmrx"))
382 match += dump_block_regs(t3b_mc7_pmrx_regs, regs);
383 if (!block_name || !strcmp(block_name, "pmtx"))
384 match += dump_block_regs(t3b_mc7_pmtx_regs, regs);
385 if (!block_name || !strcmp(block_name, "cm"))
386 match += dump_block_regs(t3b_mc7_cm_regs, regs);
387 if (!block_name || !strcmp(block_name, "cim"))
388 match += dump_block_regs(t3b_cim_regs, regs);
389 if (!block_name || !strcmp(block_name, "tp"))
390 match += dump_block_regs(t3b_tp1_regs, regs);
391 if (!block_name || !strcmp(block_name, "ulp_rx"))
392 match += dump_block_regs(t3b_ulp2_rx_regs, regs);
393 if (!block_name || !strcmp(block_name, "ulp_tx"))
394 match += dump_block_regs(t3b_ulp2_tx_regs, regs);
395 if (!block_name || !strcmp(block_name, "pmrx"))
396 match += dump_block_regs(t3b_pm1_rx_regs, regs);
397 if (!block_name || !strcmp(block_name, "pmtx"))
398 match += dump_block_regs(t3b_pm1_tx_regs, regs);
399 if (!block_name || !strcmp(block_name, "mps"))
400 match += dump_block_regs(t3b_mps0_regs, regs);
401 if (!block_name || !strcmp(block_name, "cplsw"))
402 match += dump_block_regs(t3b_cpl_switch_regs, regs);
403 if (!block_name || !strcmp(block_name, "smb"))
404 match += dump_block_regs(t3b_smb0_regs, regs);
405 if (!block_name || !strcmp(block_name, "i2c"))
406 match += dump_block_regs(t3b_i2cm0_regs, regs);
407 if (!block_name || !strcmp(block_name, "mi1"))
408 match += dump_block_regs(t3b_mi1_regs, regs);
409 if (!block_name || !strcmp(block_name, "sf"))
410 match += dump_block_regs(t3b_sf1_regs, regs);
411 if (!block_name || !strcmp(block_name, "pl"))
412 match += dump_block_regs(t3b_pl3_regs, regs);
413 if (!block_name || !strcmp(block_name, "mc5"))
414 match += dump_block_regs(t3b_mc5a_regs, regs);
415 if (!block_name || !strcmp(block_name, "xgmac0"))
416 match += dump_block_regs(t3b_xgmac0_0_regs, regs);
417 if (!block_name || !strcmp(block_name, "xgmac1"))
418 match += dump_block_regs(t3b_xgmac0_1_regs, regs);
420 errx(1, "unknown block \"%s\"", block_name);
425 dump_regs_t3c(int argc, char *argv[], int start_arg, uint32_t *regs,
429 char *block_name = NULL;
431 if (argc == start_arg + 1)
432 block_name = argv[start_arg];
433 else if (argc != start_arg)
436 if (!block_name || !strcmp(block_name, "sge"))
437 match += dump_block_regs(t3c_sge3_regs, regs);
438 if (!block_name || !strcmp(block_name, "pci"))
439 match += dump_block_regs(is_pcie ? t3c_pcie0_regs :
440 t3c_pcix1_regs, regs);
441 if (!block_name || !strcmp(block_name, "t3dbg"))
442 match += dump_block_regs(t3c_t3dbg_regs, regs);
443 if (!block_name || !strcmp(block_name, "pmrx"))
444 match += dump_block_regs(t3c_mc7_pmrx_regs, regs);
445 if (!block_name || !strcmp(block_name, "pmtx"))
446 match += dump_block_regs(t3c_mc7_pmtx_regs, regs);
447 if (!block_name || !strcmp(block_name, "cm"))
448 match += dump_block_regs(t3c_mc7_cm_regs, regs);
449 if (!block_name || !strcmp(block_name, "cim"))
450 match += dump_block_regs(t3c_cim_regs, regs);
451 if (!block_name || !strcmp(block_name, "tp"))
452 match += dump_block_regs(t3c_tp1_regs, regs);
453 if (!block_name || !strcmp(block_name, "ulp_rx"))
454 match += dump_block_regs(t3c_ulp2_rx_regs, regs);
455 if (!block_name || !strcmp(block_name, "ulp_tx"))
456 match += dump_block_regs(t3c_ulp2_tx_regs, regs);
457 if (!block_name || !strcmp(block_name, "pmrx"))
458 match += dump_block_regs(t3c_pm1_rx_regs, regs);
459 if (!block_name || !strcmp(block_name, "pmtx"))
460 match += dump_block_regs(t3c_pm1_tx_regs, regs);
461 if (!block_name || !strcmp(block_name, "mps"))
462 match += dump_block_regs(t3c_mps0_regs, regs);
463 if (!block_name || !strcmp(block_name, "cplsw"))
464 match += dump_block_regs(t3c_cpl_switch_regs, regs);
465 if (!block_name || !strcmp(block_name, "smb"))
466 match += dump_block_regs(t3c_smb0_regs, regs);
467 if (!block_name || !strcmp(block_name, "i2c"))
468 match += dump_block_regs(t3c_i2cm0_regs, regs);
469 if (!block_name || !strcmp(block_name, "mi1"))
470 match += dump_block_regs(t3c_mi1_regs, regs);
471 if (!block_name || !strcmp(block_name, "sf"))
472 match += dump_block_regs(t3c_sf1_regs, regs);
473 if (!block_name || !strcmp(block_name, "pl"))
474 match += dump_block_regs(t3c_pl3_regs, regs);
475 if (!block_name || !strcmp(block_name, "mc5"))
476 match += dump_block_regs(t3c_mc5a_regs, regs);
477 if (!block_name || !strcmp(block_name, "xgmac0"))
478 match += dump_block_regs(t3c_xgmac0_0_regs, regs);
479 if (!block_name || !strcmp(block_name, "xgmac1"))
480 match += dump_block_regs(t3c_xgmac0_1_regs, regs);
482 errx(1, "unknown block \"%s\"", block_name);
488 dump_regs(int argc, char *argv[], int start_arg, const char *iff_name)
490 int vers, revision, is_pcie;
491 struct ch_ifconf_regs regs;
493 regs.len = REGDUMP_SIZE;
495 /* XXX: This is never freed. Looks like we don't care. */
496 if ((regs.data = malloc(regs.len)) == NULL)
497 err(1, "can't malloc");
499 if (doit(iff_name, CHELSIO_IFCONF_GETREGS, ®s))
500 err(1, "can't read registers");
502 vers = regs.version & 0x3ff;
503 revision = (regs.version >> 10) & 0x3f;
504 is_pcie = (regs.version & 0x80000000) != 0;
507 return dump_regs_t2(argc, argv, start_arg, (uint32_t *)regs.data);
508 #if defined(CONFIG_T3_REGS)
511 return dump_regs_t3(argc, argv, start_arg,
512 (uint32_t *)regs.data, is_pcie);
513 if (revision == 2 || revision == 3)
514 return dump_regs_t3b(argc, argv, start_arg,
515 (uint32_t *)regs.data, is_pcie);
517 return dump_regs_t3c(argc, argv, start_arg,
518 (uint32_t *)regs.data, is_pcie);
521 errx(1, "unknown card type %d.%d", vers, revision);
526 t3_meminfo(const uint32_t *regs)
529 SG_EGR_CNTX_BADDR = 0x58,
530 SG_CQ_CONTEXT_BADDR = 0x6c,
531 CIM_SDRAM_BASE_ADDR = 0x28c,
532 CIM_SDRAM_ADDR_SIZE = 0x290,
533 TP_CMM_MM_BASE = 0x314,
534 TP_CMM_TIMER_BASE = 0x318,
535 TP_CMM_MM_RX_FLST_BASE = 0x460,
536 TP_CMM_MM_TX_FLST_BASE = 0x464,
537 TP_CMM_MM_PS_FLST_BASE = 0x468,
538 ULPRX_ISCSI_LLIMIT = 0x50c,
539 ULPRX_ISCSI_ULIMIT = 0x510,
540 ULPRX_TDDP_LLIMIT = 0x51c,
541 ULPRX_TDDP_ULIMIT = 0x520,
542 ULPRX_STAG_LLIMIT = 0x52c,
543 ULPRX_STAG_ULIMIT = 0x530,
544 ULPRX_RQ_LLIMIT = 0x534,
545 ULPRX_RQ_ULIMIT = 0x538,
546 ULPRX_PBL_LLIMIT = 0x53c,
547 ULPRX_PBL_ULIMIT = 0x540,
550 unsigned int egr_cntxt = regs[SG_EGR_CNTX_BADDR / 4],
551 cq_cntxt = regs[SG_CQ_CONTEXT_BADDR / 4],
552 timers = regs[TP_CMM_TIMER_BASE / 4] & 0xfffffff,
553 pstructs = regs[TP_CMM_MM_BASE / 4],
554 pstruct_fl = regs[TP_CMM_MM_PS_FLST_BASE / 4],
555 rx_fl = regs[TP_CMM_MM_RX_FLST_BASE / 4],
556 tx_fl = regs[TP_CMM_MM_TX_FLST_BASE / 4],
557 cim_base = regs[CIM_SDRAM_BASE_ADDR / 4],
558 cim_size = regs[CIM_SDRAM_ADDR_SIZE / 4];
559 unsigned int iscsi_ll = regs[ULPRX_ISCSI_LLIMIT / 4],
560 iscsi_ul = regs[ULPRX_ISCSI_ULIMIT / 4],
561 tddp_ll = regs[ULPRX_TDDP_LLIMIT / 4],
562 tddp_ul = regs[ULPRX_TDDP_ULIMIT / 4],
563 stag_ll = regs[ULPRX_STAG_LLIMIT / 4],
564 stag_ul = regs[ULPRX_STAG_ULIMIT / 4],
565 rq_ll = regs[ULPRX_RQ_LLIMIT / 4],
566 rq_ul = regs[ULPRX_RQ_ULIMIT / 4],
567 pbl_ll = regs[ULPRX_PBL_LLIMIT / 4],
568 pbl_ul = regs[ULPRX_PBL_ULIMIT / 4];
570 printf("CM memory map:\n");
571 printf(" TCB region: 0x%08x - 0x%08x [%u]\n", 0, egr_cntxt - 1,
573 printf(" Egress contexts: 0x%08x - 0x%08x [%u]\n", egr_cntxt,
574 cq_cntxt - 1, cq_cntxt - egr_cntxt);
575 printf(" CQ contexts: 0x%08x - 0x%08x [%u]\n", cq_cntxt,
576 timers - 1, timers - cq_cntxt);
577 printf(" Timers: 0x%08x - 0x%08x [%u]\n", timers,
578 pstructs - 1, pstructs - timers);
579 printf(" Pstructs: 0x%08x - 0x%08x [%u]\n", pstructs,
580 pstruct_fl - 1, pstruct_fl - pstructs);
581 printf(" Pstruct FL: 0x%08x - 0x%08x [%u]\n", pstruct_fl,
582 rx_fl - 1, rx_fl - pstruct_fl);
583 printf(" Rx FL: 0x%08x - 0x%08x [%u]\n", rx_fl, tx_fl - 1,
585 printf(" Tx FL: 0x%08x - 0x%08x [%u]\n", tx_fl, cim_base - 1,
587 printf(" uP RAM: 0x%08x - 0x%08x [%u]\n", cim_base,
588 cim_base + cim_size - 1, cim_size);
590 printf("\nPMRX memory map:\n");
591 printf(" iSCSI region: 0x%08x - 0x%08x [%u]\n", iscsi_ll, iscsi_ul,
592 iscsi_ul - iscsi_ll + 1);
593 printf(" TCP DDP region: 0x%08x - 0x%08x [%u]\n", tddp_ll, tddp_ul,
594 tddp_ul - tddp_ll + 1);
595 printf(" TPT region: 0x%08x - 0x%08x [%u]\n", stag_ll, stag_ul,
596 stag_ul - stag_ll + 1);
597 printf(" RQ region: 0x%08x - 0x%08x [%u]\n", rq_ll, rq_ul,
599 printf(" PBL region: 0x%08x - 0x%08x [%u]\n", pbl_ll, pbl_ul,
600 pbl_ul - pbl_ll + 1);
605 meminfo(int argc, char *argv[], int start_arg, const char *iff_name)
608 struct ch_ifconf_regs regs;
614 regs.len = REGDUMP_SIZE;
615 if ((regs.data = malloc(regs.len)) == NULL)
616 err(1, "can't malloc");
618 if (doit(iff_name, CHELSIO_IFCONF_GETREGS, ®s))
619 err(1, "can't read registers");
621 vers = regs.version & 0x3ff;
623 return t3_meminfo((uint32_t *)regs.data);
625 errx(1, "unknown card type %d", vers);
630 mtu_tab_op(int argc, char *argv[], int start_arg, const char *iff_name)
635 if (argc == start_arg) {
636 if (doit(iff_name, CHELSIO_GETMTUTAB, &m) < 0)
637 err(1, "get MTU table");
638 for (i = 0; i < m.nmtus; ++i)
639 printf("%u ", m.mtus[i]);
641 } else if (argc <= start_arg + NMTUS) {
642 m.nmtus = argc - start_arg;
644 for (i = 0; i < m.nmtus; ++i) {
646 unsigned long mt = strtoul(argv[start_arg + i], &p, 0);
648 if (*p || mt > 9600) {
649 warnx("bad parameter \"%s\"",
650 argv[start_arg + i]);
653 if (i && mt < m.mtus[i - 1])
654 errx(1, "MTUs must be in ascending order");
657 if (doit(iff_name, CHELSIO_SETMTUTAB, &m) < 0)
658 err(1, "set MTU table");
665 #ifdef CHELSIO_INTERNAL
667 show_egress_cntxt(uint32_t data[])
669 printf("credits: %u\n", data[0] & 0x7fff);
670 printf("GTS: %u\n", (data[0] >> 15) & 1);
671 printf("index: %u\n", data[0] >> 16);
672 printf("queue size: %u\n", data[1] & 0xffff);
673 printf("base address: 0x%" PRIx64 "\n",
674 ((data[1] >> 16) | ((uint64_t)data[2] << 16) |
675 (((uint64_t)data[3] & 0xf) << 48)) << 12);
676 printf("rsp queue #: %u\n", (data[3] >> 4) & 7);
677 printf("cmd queue #: %u\n", (data[3] >> 7) & 1);
678 printf("TUN: %u\n", (data[3] >> 8) & 1);
679 printf("TOE: %u\n", (data[3] >> 9) & 1);
680 printf("generation: %u\n", (data[3] >> 10) & 1);
681 printf("uP token: %u\n", (data[3] >> 11) & 0xfffff);
682 printf("valid: %u\n", (data[3] >> 31) & 1);
686 show_fl_cntxt(uint32_t data[])
688 printf("base address: 0x%" PRIx64 "\n",
689 ((uint64_t)data[0] | ((uint64_t)data[1] & 0xfffff) << 32) << 12);
690 printf("index: %u\n", (data[1] >> 20) | ((data[2] & 0xf) << 12));
691 printf("queue size: %u\n", (data[2] >> 4) & 0xffff);
692 printf("generation: %u\n", (data[2] >> 20) & 1);
693 printf("entry size: %u\n",
694 (data[2] >> 21) | (data[3] & 0x1fffff) << 11);
695 printf("congest thr: %u\n", (data[3] >> 21) & 0x3ff);
696 printf("GTS: %u\n", (data[3] >> 31) & 1);
700 show_response_cntxt(uint32_t data[])
702 printf("index: %u\n", data[0] & 0xffff);
703 printf("size: %u\n", data[0] >> 16);
704 printf("base address: 0x%" PRIx64 "\n",
705 ((uint64_t)data[1] | ((uint64_t)data[2] & 0xfffff) << 32) << 12);
706 printf("MSI-X/RspQ: %u\n", (data[2] >> 20) & 0x3f);
707 printf("intr enable: %u\n", (data[2] >> 26) & 1);
708 printf("intr armed: %u\n", (data[2] >> 27) & 1);
709 printf("generation: %u\n", (data[2] >> 28) & 1);
710 printf("CQ mode: %u\n", (data[2] >> 31) & 1);
711 printf("FL threshold: %u\n", data[3]);
715 show_cq_cntxt(uint32_t data[])
717 printf("index: %u\n", data[0] & 0xffff);
718 printf("size: %u\n", data[0] >> 16);
719 printf("base address: 0x%" PRIx64 "\n",
720 ((uint64_t)data[1] | ((uint64_t)data[2] & 0xfffff) << 32) << 12);
721 printf("rsp queue #: %u\n", (data[2] >> 20) & 0x3f);
722 printf("AN: %u\n", (data[2] >> 26) & 1);
723 printf("armed: %u\n", (data[2] >> 27) & 1);
724 printf("ANS: %u\n", (data[2] >> 28) & 1);
725 printf("generation: %u\n", (data[2] >> 29) & 1);
726 printf("overflow mode: %u\n", (data[2] >> 31) & 1);
727 printf("credits: %u\n", data[3] & 0xffff);
728 printf("credit threshold: %u\n", data[3] >> 16);
732 get_sge_context(int argc, char *argv[], int start_arg, const char *iff_name)
736 if (argc != start_arg + 2) return -1;
738 if (!strcmp(argv[start_arg], "egress"))
739 ctx.cntxt_type = CNTXT_TYPE_EGRESS;
740 else if (!strcmp(argv[start_arg], "fl"))
741 ctx.cntxt_type = CNTXT_TYPE_FL;
742 else if (!strcmp(argv[start_arg], "response"))
743 ctx.cntxt_type = CNTXT_TYPE_RSP;
744 else if (!strcmp(argv[start_arg], "cq"))
745 ctx.cntxt_type = CNTXT_TYPE_CQ;
747 warnx("unknown context type \"%s\"; known types are egress, "
748 "fl, cq, and response", argv[start_arg]);
752 if (get_int_arg(argv[start_arg + 1], &ctx.cntxt_id))
755 if (doit(iff_name, CHELSIO_GET_SGE_CONTEXT, &ctx) < 0)
756 err(1, "get SGE context");
758 if (!strcmp(argv[start_arg], "egress"))
759 show_egress_cntxt(ctx.data);
760 else if (!strcmp(argv[start_arg], "fl"))
761 show_fl_cntxt(ctx.data);
762 else if (!strcmp(argv[start_arg], "response"))
763 show_response_cntxt(ctx.data);
764 else if (!strcmp(argv[start_arg], "cq"))
765 show_cq_cntxt(ctx.data);
769 #define ntohll(x) be64toh((x))
772 get_sge_desc(int argc, char *argv[], int start_arg, const char *iff_name)
775 unsigned int n = 1, qset, qnum;
778 if (argc != start_arg + 3 && argc != start_arg + 4)
781 if (get_int_arg(argv[start_arg], &qset) ||
782 get_int_arg(argv[start_arg + 1], &qnum) ||
783 get_int_arg(argv[start_arg + 2], &desc.idx))
786 if (argc == start_arg + 4 && get_int_arg(argv[start_arg + 3], &n))
790 errx(1, "invalid queue number %d, range is 0..5", qnum);
792 desc.queue_num = qset * 6 + qnum;
794 for (; n--; desc.idx++) {
795 if (doit(iff_name, CHELSIO_GET_SGE_DESC, &desc) < 0)
796 err(1, "get SGE descriptor");
798 p = (uint64_t *)desc.data;
800 printf("Descriptor %u: cmd %u, TID %u, %s%s%s%s%u flits\n",
801 desc.idx, (unsigned int)(wr_hdr >> 56),
802 ((unsigned int)wr_hdr >> 8) & 0xfffff,
803 ((wr_hdr >> 55) & 1) ? "SOP, " : "",
804 ((wr_hdr >> 54) & 1) ? "EOP, " : "",
805 ((wr_hdr >> 53) & 1) ? "COMPL, " : "",
806 ((wr_hdr >> 52) & 1) ? "SGL, " : "",
807 (unsigned int)wr_hdr & 0xff);
809 for (; desc.size; p++, desc.size -= sizeof(uint64_t))
810 printf("%016" PRIx64 "%c", ntohll(*p),
811 desc.size % 32 == 8 ? '\n' : ' ');
818 get_tcb2(int argc, char *argv[], int start_arg, const char *iff_name)
822 unsigned int tcb_idx;
823 struct ch_mem_range mr;
825 if (argc != start_arg + 1)
828 if (get_int_arg(argv[start_arg], &tcb_idx))
831 mr.buf = calloc(1, TCB_SIZE);
836 mr.addr = tcb_idx * TCB_SIZE;
839 if (doit(iff_name, CHELSIO_GET_MEM, &mr) < 0)
842 for (d = (uint64_t *)mr.buf, i = 0; i < TCB_SIZE / 32; i++) {
844 printf(" %08x %08x %08x %08x", (uint32_t)d[1],
845 (uint32_t)(d[1] >> 32), (uint32_t)d[0],
846 (uint32_t)(d[0] >> 32));
848 printf(" %08x %08x %08x %08x\n", (uint32_t)d[1],
849 (uint32_t)(d[1] >> 32), (uint32_t)d[0],
850 (uint32_t)(d[0] >> 32));
858 get_pm_page_spec(const char *s, unsigned int *page_size,
859 unsigned int *num_pages)
864 val = strtoul(s, &p, 0);
865 if (p == s) return -1;
866 if (*p == 'x' && p[1]) {
868 *page_size = strtoul(p + 1, &p, 0);
873 *page_size <<= 10; // KB -> bytes
878 conf_pm(int argc, char *argv[], int start_arg, const char *iff_name)
882 if (argc == start_arg) {
883 if (doit(iff_name, CHELSIO_GET_PM, &pm) < 0)
884 err(1, "read pm config");
885 printf("%ux%uKB TX pages, %ux%uKB RX pages, %uKB total memory\n",
886 pm.tx_num_pg, pm.tx_pg_sz >> 10, pm.rx_num_pg,
887 pm.rx_pg_sz >> 10, pm.pm_total >> 10);
891 if (argc != start_arg + 2) return -1;
893 if (get_pm_page_spec(argv[start_arg], &pm.tx_pg_sz, &pm.tx_num_pg)) {
894 warnx("bad parameter \"%s\"", argv[start_arg]);
897 if (get_pm_page_spec(argv[start_arg + 1], &pm.rx_pg_sz,
899 warnx("bad parameter \"%s\"", argv[start_arg + 1]);
902 if (doit(iff_name, CHELSIO_SET_PM, &pm) < 0)
907 #ifdef CHELSIO_INTERNAL
909 dump_tcam(int argc, char *argv[], int start_arg, const char *iff_name)
912 struct ch_tcam_word op;
914 if (argc != start_arg + 2) return -1;
916 if (get_int_arg(argv[start_arg], &op.addr) ||
917 get_int_arg(argv[start_arg + 1], &nwords))
921 if (doit(iff_name, CHELSIO_READ_TCAM_WORD, &op) < 0)
924 printf("0x%08x: 0x%02x 0x%08x 0x%08x\n", op.addr,
925 op.buf[0] & 0xff, op.buf[1], op.buf[2]);
932 hexdump_8b(unsigned int start, uint64_t *data, unsigned int len)
937 printf("0x%08x:", start);
938 for (i = 0; i < 4 && len; ++i, --len)
939 printf(" %016llx", (unsigned long long)*data++);
946 dump_mc7(int argc, char *argv[], int start_arg, const char *iff_name)
948 struct ch_mem_range mem;
949 unsigned int mem_id, addr, len;
951 if (argc != start_arg + 3) return -1;
953 if (!strcmp(argv[start_arg], "cm"))
955 else if (!strcmp(argv[start_arg], "rx"))
957 else if (!strcmp(argv[start_arg], "tx"))
960 errx(1, "unknown memory \"%s\"; must be one of \"cm\", \"tx\","
961 " or \"rx\"", argv[start_arg]);
963 if (get_int_arg(argv[start_arg + 1], &addr) ||
964 get_int_arg(argv[start_arg + 2], &len))
967 mem.buf = malloc(len);
969 err(1, "memory dump");
975 if (doit(iff_name, CHELSIO_GET_MEM, &mem) < 0)
976 err(1, "memory dump");
978 hexdump_8b(mem.addr, (uint64_t *)mem.buf, mem.len >> 3);
984 /* Max FW size is 64K including version, +4 bytes for the checksum. */
985 #define MAX_FW_IMAGE_SIZE (64 * 1024)
988 load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
991 struct ch_mem_range op;
992 const char *fname = argv[start_arg];
994 if (argc != start_arg + 1) return -1;
996 fd = open(fname, O_RDONLY);
998 err(1, "load firmware");
1000 bzero(&op, sizeof(op));
1001 op.buf = malloc(MAX_FW_IMAGE_SIZE + 1);
1003 err(1, "load firmware");
1005 len = read(fd, op.buf, MAX_FW_IMAGE_SIZE + 1);
1007 err(1, "load firmware");
1008 if (len > MAX_FW_IMAGE_SIZE)
1009 errx(1, "FW image too large");
1012 if (doit(iff_name, CHELSIO_LOAD_FW, &op) < 0)
1013 err(1, "load firmware");
1017 /* Max BOOT size is 255*512 bytes including the BIOS boot ROM basic header */
1018 #define MAX_BOOT_IMAGE_SIZE (0xff * 512)
1021 load_boot(int argc, char *argv[], int start_arg, const char *iff_name)
1024 struct ch_mem_range op;
1025 const char *fname = argv[start_arg];
1027 if (argc != start_arg + 1) return -1;
1029 fd = open(fname, O_RDONLY);
1031 err(1, "load boot image");
1033 op.buf = malloc(MAX_BOOT_IMAGE_SIZE + 1);
1035 err(1, "load boot image");
1037 len = read(fd, op.buf, MAX_BOOT_IMAGE_SIZE + 1);
1039 err(1, "load boot image");
1040 if (len > MAX_BOOT_IMAGE_SIZE)
1041 errx(1, "boot image too large");
1045 if (doit(iff_name, CHELSIO_LOAD_BOOT, &op) < 0)
1046 err(1, "load boot image");
1052 dump_proto_sram(const char *iff_name)
1055 uint8_t buf[PROTO_SRAM_SIZE];
1056 struct ch_eeprom ee;
1059 bzero(buf, sizeof(buf));
1060 ee.offset = PROTO_SRAM_EEPROM_ADDR;
1062 ee.len = sizeof(buf);
1063 if (doit(iff_name, CHELSIO_GET_EEPROM, &ee))
1064 err(1, "show protocol sram");
1066 for (i = 0; i < PROTO_SRAM_LINES; i++) {
1067 for (j = PROTO_SRAM_LINE_NIBBLES - 1; j >= 0; j--) {
1068 int nibble_idx = i * PROTO_SRAM_LINE_NIBBLES + j;
1069 uint8_t nibble = p[nibble_idx / 2];
1075 printf("%x", nibble);
1083 proto_sram_op(int argc, char *argv[], int start_arg,
1084 const char *iff_name)
1089 if (argc == start_arg)
1090 return dump_proto_sram(iff_name);
1095 dump_qset_params(const char *iff_name)
1097 struct ch_qset_params qp;
1101 while (doit(iff_name, CHELSIO_GET_QSET_PARAMS, &qp) == 0) {
1103 printf("Qset TxQ0 TxQ1 TxQ2 RspQ RxQ0 RxQ1"
1105 printf("%4u %6u %6u %6u %6u %6u %6u %5u %4u %5d\n",
1107 qp.txq_size[0], qp.txq_size[1], qp.txq_size[2],
1108 qp.rspq_size, qp.fl_size[0], qp.fl_size[1],
1109 qp.cong_thres, qp.intr_lat, qp.vector);
1112 if (!qp.qset_idx || (errno && errno != EINVAL))
1113 err(1, "get qset parameters");
1118 qset_config(int argc, char *argv[], int start_arg, const char *iff_name)
1122 if (argc == start_arg)
1123 return dump_qset_params(iff_name);
1129 qset_num_config(int argc, char *argv[], int start_arg, const char *iff_name)
1135 if (argc == start_arg) {
1136 if (doit(iff_name, CHELSIO_GET_QSET_NUM, ®) < 0)
1137 err(1, "get qsets");
1138 printf("%u\n", reg.val);
1146 * Parse a string containing an IP address with an optional network prefix.
1149 parse_ipaddr(const char *s, uint32_t *addr, uint32_t *mask)
1154 *mask = 0xffffffffU;
1155 slash = strchr(s, '/');
1158 if (!inet_aton(s, &ia)) {
1164 *addr = ntohl(ia.s_addr);
1166 unsigned int prefix = strtoul(slash + 1, &p, 10);
1169 if (p == slash + 1 || *p || prefix > 32)
1171 *mask <<= (32 - prefix);
1177 * Parse a string containing a value and an optional colon separated mask.
1180 parse_val_mask_param(const char *s, uint32_t *val, uint32_t *mask)
1184 *mask = 0xffffffffU;
1185 *val = strtoul(s, &p, 0);
1188 if (*p == ':' && p[1])
1189 *mask = strtoul(p + 1, &p, 0);
1194 parse_trace_param(const char *s, uint32_t *val, uint32_t *mask)
1196 return strchr(s, '.') ? parse_ipaddr(s, val, mask) :
1197 parse_val_mask_param(s, val, mask);
1201 trace_config(int argc, char *argv[], int start_arg, const char *iff_name)
1204 struct ch_trace trace;
1206 if (argc == start_arg)
1209 memset(&trace, 0, sizeof(trace));
1210 if (!strcmp(argv[start_arg], "tx"))
1211 trace.config_tx = 1;
1212 else if (!strcmp(argv[start_arg], "rx"))
1213 trace.config_rx = 1;
1214 else if (!strcmp(argv[start_arg], "all"))
1215 trace.config_tx = trace.config_rx = 1;
1217 errx(1, "bad trace filter \"%s\"; must be one of \"rx\", "
1218 "\"tx\" or \"all\"", argv[start_arg]);
1220 if (argc == ++start_arg)
1222 if (!strcmp(argv[start_arg], "on")) {
1223 trace.trace_tx = trace.config_tx;
1224 trace.trace_rx = trace.config_rx;
1225 } else if (strcmp(argv[start_arg], "off"))
1226 errx(1, "bad argument \"%s\"; must be \"on\" or \"off\"",
1230 if (start_arg < argc && !strcmp(argv[start_arg], "not")) {
1231 trace.invert_match = 1;
1235 while (start_arg + 2 <= argc) {
1236 int ret = parse_trace_param(argv[start_arg + 1], &val, &mask);
1238 if (!strcmp(argv[start_arg], "interface")) {
1240 trace.intf_mask = mask;
1241 } else if (!strcmp(argv[start_arg], "sip")) {
1243 trace.sip_mask = mask;
1244 } else if (!strcmp(argv[start_arg], "dip")) {
1246 trace.dip_mask = mask;
1247 } else if (!strcmp(argv[start_arg], "sport")) {
1249 trace.sport_mask = mask;
1250 } else if (!strcmp(argv[start_arg], "dport")) {
1252 trace.dport_mask = mask;
1253 } else if (!strcmp(argv[start_arg], "vlan")) {
1255 trace.vlan_mask = mask;
1256 } else if (!strcmp(argv[start_arg], "proto")) {
1258 trace.proto_mask = mask;
1260 errx(1, "unknown trace parameter \"%s\"\n"
1261 "known parameters are \"interface\", \"sip\", "
1262 "\"dip\", \"sport\", \"dport\", \"vlan\", "
1263 "\"proto\"", argv[start_arg]);
1265 errx(1, "bad parameter \"%s\"", argv[start_arg + 1]);
1268 if (start_arg != argc)
1269 errx(1, "unknown parameter \"%s\"", argv[start_arg]);
1271 if (doit(iff_name, CHELSIO_SET_TRACE_FILTER, &trace) < 0)
1277 get_sched_param(int argc, char *argv[], int pos, unsigned int *valp)
1279 if (pos + 1 >= argc)
1280 errx(1, "missing value for %s", argv[pos]);
1281 if (get_int_arg(argv[pos + 1], valp))
1287 tx_sched(int argc, char *argv[], int start_arg, const char *iff_name)
1289 struct ch_hw_sched op;
1290 unsigned int idx, val;
1292 if (argc < 5 || get_int_arg(argv[start_arg++], &idx))
1296 op.mode = op.channel = -1;
1297 op.kbps = op.class_ipg = op.flow_ipg = -1;
1299 while (argc > start_arg) {
1300 if (!strcmp(argv[start_arg], "mode")) {
1301 if (start_arg + 1 >= argc)
1302 errx(1, "missing value for mode");
1303 if (!strcmp(argv[start_arg + 1], "class"))
1305 else if (!strcmp(argv[start_arg + 1], "flow"))
1308 errx(1, "bad mode \"%s\"", argv[start_arg + 1]);
1309 } else if (!strcmp(argv[start_arg], "channel") &&
1310 !get_sched_param(argc, argv, start_arg, &val))
1312 else if (!strcmp(argv[start_arg], "rate") &&
1313 !get_sched_param(argc, argv, start_arg, &val))
1315 else if (!strcmp(argv[start_arg], "ipg") &&
1316 !get_sched_param(argc, argv, start_arg, &val))
1318 else if (!strcmp(argv[start_arg], "flowipg") &&
1319 !get_sched_param(argc, argv, start_arg, &val))
1322 errx(1, "unknown scheduler parameter \"%s\"",
1327 if (doit(iff_name, CHELSIO_SET_HW_SCHED, &op) < 0)
1334 pktsched(int argc, char *argv[], int start_arg, const char *iff_name)
1336 struct ch_pktsched_params op;
1337 unsigned int idx, min = -1, max, binding = -1;
1340 errx(1, "no scheduler specified");
1342 if (!strcmp(argv[start_arg], "port")) {
1343 if (argc != start_arg + 4)
1345 if (get_int_arg(argv[start_arg + 1], &idx) ||
1346 get_int_arg(argv[start_arg + 2], &min) ||
1347 get_int_arg(argv[start_arg + 3], &max))
1350 } else if (!strcmp(argv[start_arg], "tunnelq")) {
1351 if (argc != start_arg + 4)
1353 if (get_int_arg(argv[start_arg + 1], &idx) ||
1354 get_int_arg(argv[start_arg + 2], &max) ||
1355 get_int_arg(argv[start_arg + 3], &binding))
1358 } else if (!strcmp(argv[start_arg], "tx"))
1359 return tx_sched(argc, argv, start_arg + 1, iff_name);
1361 errx(1, "unknown scheduler \"%s\"; must be one of \"port\", "
1362 "\"tunnelq\" or \"tx\"", argv[start_arg]);
1367 op.binding = binding;
1368 if (doit(iff_name, CHELSIO_SET_PKTSCHED, &op) < 0)
1375 clear_stats(int argc, char *argv[], int start_arg, const char *iff_name)
1381 if (doit(iff_name, CHELSIO_CLEAR_STATS, NULL) < 0)
1382 err(1, "clearstats");
1388 get_up_la(int argc, char *argv[], int start_arg, const char *iff_name)
1391 int i, idx, max_idx, entries;
1399 la.bufsize = LA_BUFSIZE;
1400 la.data = malloc(la.bufsize);
1402 err(1, "uP_LA malloc");
1404 if (doit(iff_name, CHELSIO_GET_UP_LA, &la) < 0)
1408 printf("LA is not running\n");
1410 entries = la.bufsize / 4;
1412 max_idx = (entries / 4) - 1;
1413 for (i = 0; i < max_idx; i++) {
1414 printf("%04x %08x %08x\n",
1415 la.data[idx], la.data[idx+2], la.data[idx+1]);
1416 idx = (idx + 4) & (entries - 1);
1423 get_up_ioqs(int argc, char *argv[], int start_arg, const char *iff_name)
1425 struct ch_up_ioqs ioqs;
1432 bzero(&ioqs, sizeof(ioqs));
1433 ioqs.bufsize = IOQS_BUFSIZE;
1434 ioqs.data = malloc(IOQS_BUFSIZE);
1436 err(1, "uP_IOQs malloc");
1438 if (doit(iff_name, CHELSIO_GET_UP_IOQS, &ioqs) < 0)
1441 printf("ioq_rx_enable : 0x%08x\n", ioqs.ioq_rx_enable);
1442 printf("ioq_tx_enable : 0x%08x\n", ioqs.ioq_tx_enable);
1443 printf("ioq_rx_status : 0x%08x\n", ioqs.ioq_rx_status);
1444 printf("ioq_tx_status : 0x%08x\n", ioqs.ioq_tx_status);
1446 entries = ioqs.bufsize / sizeof(struct t3_ioq_entry);
1447 for (i = 0; i < entries; i++) {
1448 printf("\nioq[%d].cp : 0x%08x\n", i,
1449 ioqs.data[i].ioq_cp);
1450 printf("ioq[%d].pp : 0x%08x\n", i,
1451 ioqs.data[i].ioq_pp);
1452 printf("ioq[%d].alen : 0x%08x\n", i,
1453 ioqs.data[i].ioq_alen);
1454 printf("ioq[%d].stats : 0x%08x\n", i,
1455 ioqs.data[i].ioq_stats);
1456 printf(" sop %u\n", ioqs.data[i].ioq_stats >> 16);
1457 printf(" eop %u\n", ioqs.data[i].ioq_stats & 0xFFFF);
1464 run_cmd(int argc, char *argv[], const char *iff_name)
1468 if (!strcmp(argv[2], "reg"))
1469 r = register_io(argc, argv, 3, iff_name);
1470 else if (!strcmp(argv[2], "mdio"))
1471 r = mdio_io(argc, argv, 3, iff_name);
1472 else if (!strcmp(argv[2], "mtus"))
1473 r = mtu_tab_op(argc, argv, 3, iff_name);
1474 else if (!strcmp(argv[2], "pm"))
1475 r = conf_pm(argc, argv, 3, iff_name);
1476 else if (!strcmp(argv[2], "regdump"))
1477 r = dump_regs(argc, argv, 3, iff_name);
1478 else if (!strcmp(argv[2], "tcamdump"))
1479 r = dump_tcam(argc, argv, 3, iff_name);
1480 else if (!strcmp(argv[2], "memdump"))
1481 r = dump_mc7(argc, argv, 3, iff_name);
1482 else if (!strcmp(argv[2], "meminfo"))
1483 r = meminfo(argc, argv, 3, iff_name);
1484 else if (!strcmp(argv[2], "context"))
1485 r = get_sge_context(argc, argv, 3, iff_name);
1486 else if (!strcmp(argv[2], "desc"))
1487 r = get_sge_desc(argc, argv, 3, iff_name);
1488 else if (!strcmp(argv[2], "loadfw"))
1489 r = load_fw(argc, argv, 3, iff_name);
1490 else if (!strcmp(argv[2], "loadboot"))
1491 r = load_boot(argc, argv, 3, iff_name);
1492 else if (!strcmp(argv[2], "proto"))
1493 r = proto_sram_op(argc, argv, 3, iff_name);
1494 else if (!strcmp(argv[2], "qset"))
1495 r = qset_config(argc, argv, 3, iff_name);
1496 else if (!strcmp(argv[2], "qsets"))
1497 r = qset_num_config(argc, argv, 3, iff_name);
1498 else if (!strcmp(argv[2], "trace"))
1499 r = trace_config(argc, argv, 3, iff_name);
1500 else if (!strcmp(argv[2], "pktsched"))
1501 r = pktsched(argc, argv, 3, iff_name);
1502 else if (!strcmp(argv[2], "tcb"))
1503 r = get_tcb2(argc, argv, 3, iff_name);
1504 else if (!strcmp(argv[2], "clearstats"))
1505 r = clear_stats(argc, argv, 3, iff_name);
1506 else if (!strcmp(argv[2], "la"))
1507 r = get_up_la(argc, argv, 3, iff_name);
1508 else if (!strcmp(argv[2], "ioqs"))
1509 r = get_up_ioqs(argc, argv, 3, iff_name);
1518 run_cmd_loop(int argc, char *argv[], const char *iff_name)
1530 * Fairly simplistic loop. Displays a "> " prompt and processes any
1531 * input as a cxgbtool command. You're supposed to enter only the part
1532 * after "cxgbtool cxgbX". Use "quit" or "exit" to exit. Any error in
1533 * the command will also terminate cxgbtool.
1536 fprintf(stdout, "> ");
1538 n = read(STDIN_FILENO, buf, sizeof(buf) - 1);
1542 if (buf[--n] != '\n')
1548 for (i = 2; i < sizeof(args)/sizeof(args[0]) - 1; i++) {
1549 while (s && (*s == ' ' || *s == '\t'))
1551 if ((args[i] = strsep(&s, " \t")) == NULL)
1554 args[sizeof(args)/sizeof(args[0]) - 1] = 0;
1556 if (!strcmp(args[2], "quit") || !strcmp(args[2], "exit"))
1559 (void) run_cmd(i, args, iff_name);
1562 /* Can't really get here */
1567 main(int argc, char *argv[])
1570 const char *iff_name;
1575 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
1577 if (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version")) {
1578 printf("%s version %s\n", PROGNAME, VERSION);
1579 printf("%s\n", COPYRIGHT);
1584 if (argc < 3) usage(stderr);
1588 if (argc == 3 && !strcmp(argv[2], "stdio"))
1589 r = run_cmd_loop(argc, argv, iff_name);
1591 r = run_cmd(argc, argv, iff_name);