cxgbetool.c (65ecf39910b97501cd4a7cddd37a5177aba96025) cxgbetool.c (d81537f42f656d7d5d57dc138f876c0c9bfeff87)
1/*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12/*
13 * Copyright (c) 2018 by Chelsio Communications, Inc.
14 */
15
16/*
17 * Copyright 2019 Joyent, Inc.
1/*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12/*
13 * Copyright (c) 2018 by Chelsio Communications, Inc.
14 */
15
16/*
17 * Copyright 2019 Joyent, Inc.
18 * Copyright 2023 Oxide Computer Company
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <unistd.h>
23#include <stropts.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
27#include <sys/socket.h>
28#include <strings.h>
29#include <sys/varargs.h>
30#include <errno.h>
31#include <sys/byteorder.h>
32#include <inttypes.h>
33#include <sys/sysmacros.h>
34#include <err.h>
19 */
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <unistd.h>
24#include <stropts.h>
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <fcntl.h>
28#include <sys/socket.h>
29#include <strings.h>
30#include <sys/varargs.h>
31#include <errno.h>
32#include <sys/byteorder.h>
33#include <inttypes.h>
34#include <sys/sysmacros.h>
35#include <err.h>
36#include <libdevinfo.h>
35
36#include "t4nex.h"
37#include "version.h"
38#include "osdep.h"
39#include "t4fw_interface.h"
40#include "cudbg.h"
41#include "cudbg_lib_common.h"
42
43#define CUDBG_SIZE (32 * 1024 * 1024)
44#define CUDBG_MAX_ENTITY_STR_LEN 4096
45#define MAX_PARAM_LEN 4096
46
37
38#include "t4nex.h"
39#include "version.h"
40#include "osdep.h"
41#include "t4fw_interface.h"
42#include "cudbg.h"
43#include "cudbg_lib_common.h"
44
45#define CUDBG_SIZE (32 * 1024 * 1024)
46#define CUDBG_MAX_ENTITY_STR_LEN 4096
47#define MAX_PARAM_LEN 4096
48
49static char cxgbetool_nexus[PATH_MAX];
50
47char *option_list[] = {
48 "--collect",
49 "--view",
50 "--version",
51};
52
53enum {
54 CUDBG_OPT_COLLECT,

--- 53 unchanged lines hidden (view full) ---

108 if (!strcmp(opt, option_list[i]))
109 return i;
110 }
111 return -1;
112}
113
114static void usage(FILE *fp)
115{
51char *option_list[] = {
52 "--collect",
53 "--view",
54 "--version",
55};
56
57enum {
58 CUDBG_OPT_COLLECT,

--- 53 unchanged lines hidden (view full) ---

112 if (!strcmp(opt, option_list[i]))
113 return i;
114 }
115 return -1;
116}
117
118static void usage(FILE *fp)
119{
116 fprintf(fp, "Usage: %s <path to t4nex#> [operation]\n", progname);
120 fprintf(fp, "Usage: %s <t4nex# | cxgbe#> [operation]\n", progname);
117 fprintf(fp,
118 "\tdevlog show device log\n"
119 "\tloadfw <FW image> Flash the FW image\n"
120 "\tcudbg <option> [<args>] Chelsio Unified Debugger\n");
121 exit(fp == stderr ? 1 : 0);
122}
123
124static int

--- 511 unchanged lines hidden (view full) ---

636 else if (strcmp(argv[2], "loadfw") == 0)
637 load_fw(argc, argv, 3, iff_name);
638 else if (strcmp(argv[2], "cudbg") == 0)
639 get_cudbg(argc, argv, 3, iff_name);
640 else
641 usage(stderr);
642}
643
121 fprintf(fp,
122 "\tdevlog show device log\n"
123 "\tloadfw <FW image> Flash the FW image\n"
124 "\tcudbg <option> [<args>] Chelsio Unified Debugger\n");
125 exit(fp == stderr ? 1 : 0);
126}
127
128static int

--- 511 unchanged lines hidden (view full) ---

640 else if (strcmp(argv[2], "loadfw") == 0)
641 load_fw(argc, argv, 3, iff_name);
642 else if (strcmp(argv[2], "cudbg") == 0)
643 get_cudbg(argc, argv, 3, iff_name);
644 else
645 usage(stderr);
646}
647
648/*
649 * Traditionally we expect to be given a path to the t4nex device control file
650 * hidden in /devices. To make life easier, we want to also support folks using
651 * the driver instance numbers for either a given t4nex%d or cxgbe%d. We check
652 * to see if we've been given a path to a character device and if so, just
653 * continue straight on with the given argument. Otherwise we attempt to map it
654 * to something known.
655 */
656static const char *
657cxgbetool_parse_path(char *arg)
658{
659 struct stat st;
660 di_node_t root, node;
661 const char *numptr, *errstr;
662 size_t drvlen;
663 int inst;
664 boolean_t is_t4nex = B_TRUE;
665 char mname[64];
666
667 if (stat(arg, &st) == 0) {
668 if (S_ISCHR(st.st_mode)) {
669 return (arg);
670 }
671 }
672
673 if (strncmp(arg, T4_NEXUS_NAME, sizeof (T4_NEXUS_NAME) - 1) == 0) {
674 drvlen = sizeof (T4_NEXUS_NAME) - 1;
675 } else if (strncmp(arg, T4_PORT_NAME, sizeof (T4_PORT_NAME) - 1) == 0) {
676 is_t4nex = B_FALSE;
677 drvlen = sizeof (T4_PORT_NAME) - 1;
678 } else {
679 errx(EXIT_FAILURE, "cannot use device %s: not a character "
680 "device or a %s/%s device instance", arg, T4_PORT_NAME,
681 T4_NEXUS_NAME);
682 }
683
684 numptr = arg + drvlen;
685 inst = (int)strtonum(numptr, 0, INT_MAX, &errstr);
686 if (errstr != NULL) {
687 errx(EXIT_FAILURE, "failed to parse instance number '%s': %s",
688 numptr, errstr);
689 }
690
691 /*
692 * Now that we have the instance here, we need to truncate the string at
693 * the end of the driver name otherwise di_drv_first_node() will be very
694 * confused as there is no driver called say 't4nex0'.
695 */
696 arg[drvlen] = '\0';
697 root = di_init("/", DINFOCPYALL);
698 if (root == DI_NODE_NIL) {
699 err(EXIT_FAILURE, "failed to initialize libdevinfo while "
700 "trying to map device name %s", arg);
701 }
702
703 for (node = di_drv_first_node(arg, root); node != DI_NODE_NIL;
704 node = di_drv_next_node(node)) {
705 char *bpath;
706 di_minor_t minor = DI_MINOR_NIL;
707
708 if (di_instance(node) != inst) {
709 continue;
710 }
711
712 if (!is_t4nex) {
713 const char *pdrv;
714 node = di_parent_node(node);
715 pdrv = di_driver_name(node);
716 if (pdrv == NULL || strcmp(pdrv, T4_NEXUS_NAME) != 0) {
717 errx(EXIT_FAILURE, "%s does not have %s "
718 "parent, found %s%d", arg, T4_NEXUS_NAME,
719 pdrv != NULL ? pdrv : "unknown",
720 pdrv != NULL ? di_instance(node) : -1);
721 }
722 }
723
724 (void) snprintf(mname, sizeof (mname), "%s,%d", T4_NEXUS_NAME,
725 di_instance(node));
726
727 while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
728 if (strcmp(di_minor_name(minor), mname) == 0) {
729 break;
730 }
731 }
732
733 if (minor == DI_MINOR_NIL) {
734 errx(EXIT_FAILURE, "failed to find minor %s on %s%d",
735 mname, di_driver_name(node), di_instance(node));
736 }
737
738 bpath = di_devfs_minor_path(minor);
739 if (bpath == NULL) {
740 err(EXIT_FAILURE, "failed to get minor path for "
741 "%s%d:%s", di_driver_name(node), di_instance(node),
742 di_minor_name(minor));
743 }
744 if (snprintf(cxgbetool_nexus, sizeof (cxgbetool_nexus),
745 "/devices%s", bpath) >= sizeof (cxgbetool_nexus)) {
746 errx(EXIT_FAILURE, "failed to construct full /devices "
747 "path for %s: internal path buffer would have "
748 "overflowed");
749 }
750 di_devfs_path_free(bpath);
751
752 di_fini(root);
753 return (cxgbetool_nexus);
754 }
755
756 errx(EXIT_FAILURE, "failed to map %s%d to a %s or %s instance",
757 arg, inst, T4_PORT_NAME, T4_NEXUS_NAME);
758}
759
644int
645main(int argc, char *argv[])
646{
647 const char *iff_name;
648
649 progname = argv[0];
650
651 if (argc == 2) {

--- 7 unchanged lines hidden (view full) ---

659 printf("cxgbetool version %s\n", DRV_VERSION);
660 exit(0);
661 }
662 }
663
664 if (argc < 3)
665 usage(stderr);
666
760int
761main(int argc, char *argv[])
762{
763 const char *iff_name;
764
765 progname = argv[0];
766
767 if (argc == 2) {

--- 7 unchanged lines hidden (view full) ---

775 printf("cxgbetool version %s\n", DRV_VERSION);
776 exit(0);
777 }
778 }
779
780 if (argc < 3)
781 usage(stderr);
782
667 iff_name = argv[1];
783 iff_name = cxgbetool_parse_path(argv[1]);
668
669 run_cmd(argc, argv, iff_name);
670
671 return (0);
672}
784
785 run_cmd(argc, argv, iff_name);
786
787 return (0);
788}