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
This commit is contained in:
Navdeep Parhar 2024-06-13 13:17:55 -07:00
parent 0dc98b57f3
commit e827b61cac

View File

@ -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);
}
if (ioctl(g.fd, cmd, data) < 0) {
if (g.warn_on_ioctl_err)
warn("%s", cmdstr);
return (errno);
}
rc = ioctl(fd, cmd, data);
if (rc < 0) {
warn("%s", cmdstr);
rc = 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);
}
static void
parse_nexus_name(const char *s)
{
char junk;
#define A_PL_WHOAMI 0x19400
#define A_PL_REV 0x1943c
#define A_PL_VF_WHOAMI 0x200
#define A_PL_VF_REV 0x204
if (sscanf(s, "t%unex%u%c", &chip_id, &inst, &junk) != 2)
errx(EINVAL, "invalid nexus \"%s\"", s);
nexus = s;
static void
open_nexus_device(const char *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;