The branch main has been updated by np:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=e827b61cacddd4bc9a2f1657ad8c6d2bcd70d52e

commit e827b61cacddd4bc9a2f1657ad8c6d2bcd70d52e
Author:     Navdeep Parhar <[email protected]>
AuthorDate: 2024-06-13 20:17:55 +0000
Commit:     Navdeep Parhar <[email protected]>
CommitDate: 2024-06-17 01:54:02 +0000

    cxgbetool(8): Be flexible about the nexus name.
    
    Use the name as-is but perform cxgbe specific ioctls on the device to
    make sure that it is a Terminator device nexus.  Determine the chip
    type, pf/vf, etc. from the device registers rather than the nexus name.
    
    This allows cxgbetool to work with the VF driver.
    
    MFC after:      1 week
    Sponsored by:   Chelsio Communications
---
 usr.sbin/cxgbetool/cxgbetool.c | 116 +++++++++++++++++++++++++++--------------
 1 file changed, 76 insertions(+), 40 deletions(-)

diff --git a/usr.sbin/cxgbetool/cxgbetool.c b/usr.sbin/cxgbetool/cxgbetool.c
index bef99ff0f3da..8f58fe8107dc 100644
--- a/usr.sbin/cxgbetool/cxgbetool.c
+++ b/usr.sbin/cxgbetool/cxgbetool.c
@@ -42,6 +42,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -55,9 +56,16 @@
 #define in_range(val, lo, hi) ( val < 0 || (val <= hi && val >= lo))
 #define        max(x, y) ((x) > (y) ? (x) : (y))
 
-static const char *progname, *nexus;
-static int chip_id;    /* 4 for T4, 5 for T5, and so on. */
-static int inst;       /* instance of nexus device */
+static struct {
+       const char *progname, *nexus;
+       int chip_id;    /* 4 for T4, 5 for T5, and so on. */
+       int inst;       /* instance of nexus device */
+       int pf;         /* PF# of the nexus (if not VF). */
+       bool vf;        /* Nexus is a VF. */
+
+       int fd;
+       bool warn_on_ioctl_err;
+} g;
 
 struct reg_info {
        const char *name;
@@ -87,7 +95,7 @@ struct field_desc {
 static void
 usage(FILE *fp)
 {
-       fprintf(fp, "Usage: %s <nexus> [operation]\n", progname);
+       fprintf(fp, "Usage: %s <nexus> [operation]\n", g.progname);
        fprintf(fp,
            "\tclearstats <port>                   clear port statistics\n"
            "\tclip hold|release <ip6>             hold/release an address\n"
@@ -136,27 +144,12 @@ get_card_vers(unsigned int version)
 static int
 real_doit(unsigned long cmd, void *data, const char *cmdstr)
 {
-       static int fd = -1;
-       int rc = 0;
-
-       if (fd == -1) {
-               char buf[64];
-
-               snprintf(buf, sizeof(buf), "/dev/%s", nexus);
-               if ((fd = open(buf, O_RDWR)) < 0) {
-                       warn("open(%s)", nexus);
-                       rc = errno;
-                       return (rc);
-               }
-       }
-
-       rc = ioctl(fd, cmd, data);
-       if (rc < 0) {
-               warn("%s", cmdstr);
-               rc = errno;
+       if (ioctl(g.fd, cmd, data) < 0) {
+               if (g.warn_on_ioctl_err)
+                       warn("%s", cmdstr);
+               return (errno);
        }
-
-       return (rc);
+       return (0);
 }
 #define doit(x, y) real_doit(x, y, #x)
 
@@ -522,7 +515,7 @@ dump_regs(int argc, const char *argv[])
                        rc = dump_regs_t6(argc, argv, regs.data);
        } else {
                warnx("%s (type %d, rev %d) is not a known card.",
-                   nexus, vers, revision);
+                   g.nexus, vers, revision);
                return (ENOTSUP);
        }
 
@@ -914,7 +907,7 @@ do_show_one_filter_info(struct t4_filter *t, uint32_t mode)
                                printf("(hash)");
                }
        }
-       if (chip_id <= 5 && t->fs.prio)
+       if (g.chip_id <= 5 && t->fs.prio)
                printf(" Prio");
        if (t->fs.rpttid)
                printf(" RptTID");
@@ -933,7 +926,7 @@ show_filters(int hash)
        if (rc != 0)
                return (rc);
 
-       if (!hash && chip_id >= 6) {
+       if (!hash && g.chip_id >= 6) {
                header = 0;
                bzero(&t, sizeof (t));
                t.idx = 0;
@@ -1924,10 +1917,10 @@ get_sge_context(int argc, const char *argv[])
        if (rc != 0)
                return (rc);
 
-       if (chip_id == 4)
+       if (g.chip_id == 4)
                show_t4_ctxt(&cntxt);
        else
-               show_t5t6_ctxt(&cntxt, chip_id);
+               show_t5t6_ctxt(&cntxt, g.chip_id);
 
        return (0);
 }
@@ -2243,7 +2236,7 @@ show_tcb(uint32_t *buf, uint32_t len)
                }
                printf("\n");
        }
-       set_tcb_info(TIDTYPE_TCB, chip_id);
+       set_tcb_info(TIDTYPE_TCB, g.chip_id);
        set_print_style(PRNTSTYL_COMP);
        swizzle_tcb(tcb);
        parse_n_display_xcb(tcb);
@@ -2447,7 +2440,7 @@ static void
 create_tracing_ifnet()
 {
        char *cmd[] = {
-               "/sbin/ifconfig", __DECONST(char *, nexus), "create", NULL
+               "/sbin/ifconfig", __DECONST(char *, g.nexus), "create", NULL
        };
        char *env[] = {NULL};
 
@@ -3494,7 +3487,7 @@ display_clip(void)
                return (errno);
        }
 
-       snprintf(name, sizeof(name), "dev.t%unex.%u.misc.clip", chip_id, inst);
+       snprintf(name, sizeof(name), "dev.t%unex.%u.misc.clip", g.chip_id, 
g.inst);
        rc = sysctlbyname(name, buf, &clip_buf_size, NULL, 0);
        if (rc != 0) {
                warn("sysctl %s", name);
@@ -3649,14 +3642,57 @@ run_cmd_loop(void)
        return (rc);
 }
 
+#define A_PL_WHOAMI 0x19400
+#define A_PL_REV 0x1943c
+#define A_PL_VF_WHOAMI 0x200
+#define A_PL_VF_REV 0x204
+
 static void
-parse_nexus_name(const char *s)
+open_nexus_device(const char *s)
 {
-       char junk;
-
-       if (sscanf(s, "t%unex%u%c", &chip_id, &inst, &junk) != 2)
-               errx(EINVAL, "invalid nexus \"%s\"", s);
-       nexus = s;
+       const int len = strlen(s);
+       long long val;
+       const char *num;
+       int rc;
+       u_int chip_id, whoami;
+       char buf[128];
+
+       if (len < 2 || isdigit(s[0]) || !isdigit(s[len - 1]))
+               errx(1, "invalid nexus name \"%s\"", s);
+       for (num = s + len - 1; isdigit(*num); num--)
+               continue;
+       g.inst = strtoll(num, NULL, 0);
+       g.nexus = s;
+       snprintf(buf, sizeof(buf), "/dev/%s", g.nexus);
+       if ((g.fd = open(buf, O_RDWR)) < 0)
+               err(1, "open(%s)", buf);
+
+       g.warn_on_ioctl_err = false;
+       rc = read_reg(A_PL_REV, 4, &val);
+       if (rc == 0) {
+               /* PF */
+               g.vf = false;
+               whoami = A_PL_WHOAMI;
+       } else {
+               rc = read_reg(A_PL_VF_REV, 4, &val);
+               if (rc != 0)
+                       errx(1, "%s is not a Terminator device.", s);
+               /* VF */
+               g.vf = true;
+               whoami = A_PL_VF_WHOAMI;
+       }
+       chip_id = (val >> 4) & 0xf;
+       if (chip_id == 0)
+               chip_id = 4;
+       if (chip_id < 4 || chip_id > 7)
+               warnx("%s reports chip_id %d.", s, chip_id);
+       g.chip_id = chip_id;
+
+       rc = read_reg(whoami, 4, &val);
+       if (rc != 0)
+               errx(rc, "failed to read whoami(0x%x): %d", whoami, rc);
+       g.pf = g.chip_id > 5 ? (val >> 9) & 7 : (val >> 8) & 7;
+       g.warn_on_ioctl_err = true;
 }
 
 int
@@ -3664,7 +3700,7 @@ main(int argc, const char *argv[])
 {
        int rc = -1;
 
-       progname = argv[0];
+       g.progname = argv[0];
 
        if (argc == 2) {
                if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
@@ -3678,7 +3714,7 @@ main(int argc, const char *argv[])
                exit(EINVAL);
        }
 
-       parse_nexus_name(argv[1]);
+       open_nexus_device(argv[1]);
 
        /* progname and nexus */
        argc -= 2;

Reply via email to