mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-01 14:14:56 +00:00
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:
parent
0dc98b57f3
commit
e827b61cac
|
@ -42,6 +42,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -55,9 +56,16 @@
|
||||||
#define in_range(val, lo, hi) ( val < 0 || (val <= hi && val >= lo))
|
#define in_range(val, lo, hi) ( val < 0 || (val <= hi && val >= lo))
|
||||||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||||
|
|
||||||
static const char *progname, *nexus;
|
static struct {
|
||||||
static int chip_id; /* 4 for T4, 5 for T5, and so on. */
|
const char *progname, *nexus;
|
||||||
static int inst; /* instance of nexus device */
|
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 {
|
struct reg_info {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -87,7 +95,7 @@ struct field_desc {
|
||||||
static void
|
static void
|
||||||
usage(FILE *fp)
|
usage(FILE *fp)
|
||||||
{
|
{
|
||||||
fprintf(fp, "Usage: %s <nexus> [operation]\n", progname);
|
fprintf(fp, "Usage: %s <nexus> [operation]\n", g.progname);
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
"\tclearstats <port> clear port statistics\n"
|
"\tclearstats <port> clear port statistics\n"
|
||||||
"\tclip hold|release <ip6> hold/release an address\n"
|
"\tclip hold|release <ip6> hold/release an address\n"
|
||||||
|
@ -136,27 +144,12 @@ get_card_vers(unsigned int version)
|
||||||
static int
|
static int
|
||||||
real_doit(unsigned long cmd, void *data, const char *cmdstr)
|
real_doit(unsigned long cmd, void *data, const char *cmdstr)
|
||||||
{
|
{
|
||||||
static int fd = -1;
|
if (ioctl(g.fd, cmd, data) < 0) {
|
||||||
int rc = 0;
|
if (g.warn_on_ioctl_err)
|
||||||
|
warn("%s", cmdstr);
|
||||||
if (fd == -1) {
|
return (errno);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return (0);
|
||||||
rc = ioctl(fd, cmd, data);
|
|
||||||
if (rc < 0) {
|
|
||||||
warn("%s", cmdstr);
|
|
||||||
rc = errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (rc);
|
|
||||||
}
|
}
|
||||||
#define doit(x, y) real_doit(x, y, #x)
|
#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);
|
rc = dump_regs_t6(argc, argv, regs.data);
|
||||||
} else {
|
} else {
|
||||||
warnx("%s (type %d, rev %d) is not a known card.",
|
warnx("%s (type %d, rev %d) is not a known card.",
|
||||||
nexus, vers, revision);
|
g.nexus, vers, revision);
|
||||||
return (ENOTSUP);
|
return (ENOTSUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,7 +907,7 @@ do_show_one_filter_info(struct t4_filter *t, uint32_t mode)
|
||||||
printf("(hash)");
|
printf("(hash)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chip_id <= 5 && t->fs.prio)
|
if (g.chip_id <= 5 && t->fs.prio)
|
||||||
printf(" Prio");
|
printf(" Prio");
|
||||||
if (t->fs.rpttid)
|
if (t->fs.rpttid)
|
||||||
printf(" RptTID");
|
printf(" RptTID");
|
||||||
|
@ -933,7 +926,7 @@ show_filters(int hash)
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
return (rc);
|
return (rc);
|
||||||
|
|
||||||
if (!hash && chip_id >= 6) {
|
if (!hash && g.chip_id >= 6) {
|
||||||
header = 0;
|
header = 0;
|
||||||
bzero(&t, sizeof (t));
|
bzero(&t, sizeof (t));
|
||||||
t.idx = 0;
|
t.idx = 0;
|
||||||
|
@ -1924,10 +1917,10 @@ get_sge_context(int argc, const char *argv[])
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
return (rc);
|
return (rc);
|
||||||
|
|
||||||
if (chip_id == 4)
|
if (g.chip_id == 4)
|
||||||
show_t4_ctxt(&cntxt);
|
show_t4_ctxt(&cntxt);
|
||||||
else
|
else
|
||||||
show_t5t6_ctxt(&cntxt, chip_id);
|
show_t5t6_ctxt(&cntxt, g.chip_id);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -2243,7 +2236,7 @@ show_tcb(uint32_t *buf, uint32_t len)
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
set_tcb_info(TIDTYPE_TCB, chip_id);
|
set_tcb_info(TIDTYPE_TCB, g.chip_id);
|
||||||
set_print_style(PRNTSTYL_COMP);
|
set_print_style(PRNTSTYL_COMP);
|
||||||
swizzle_tcb(tcb);
|
swizzle_tcb(tcb);
|
||||||
parse_n_display_xcb(tcb);
|
parse_n_display_xcb(tcb);
|
||||||
|
@ -2447,7 +2440,7 @@ static void
|
||||||
create_tracing_ifnet()
|
create_tracing_ifnet()
|
||||||
{
|
{
|
||||||
char *cmd[] = {
|
char *cmd[] = {
|
||||||
"/sbin/ifconfig", __DECONST(char *, nexus), "create", NULL
|
"/sbin/ifconfig", __DECONST(char *, g.nexus), "create", NULL
|
||||||
};
|
};
|
||||||
char *env[] = {NULL};
|
char *env[] = {NULL};
|
||||||
|
|
||||||
|
@ -3494,7 +3487,7 @@ display_clip(void)
|
||||||
return (errno);
|
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);
|
rc = sysctlbyname(name, buf, &clip_buf_size, NULL, 0);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
warn("sysctl %s", name);
|
warn("sysctl %s", name);
|
||||||
|
@ -3649,14 +3642,57 @@ run_cmd_loop(void)
|
||||||
return (rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
#define A_PL_WHOAMI 0x19400
|
||||||
parse_nexus_name(const char *s)
|
#define A_PL_REV 0x1943c
|
||||||
{
|
#define A_PL_VF_WHOAMI 0x200
|
||||||
char junk;
|
#define A_PL_VF_REV 0x204
|
||||||
|
|
||||||
if (sscanf(s, "t%unex%u%c", &chip_id, &inst, &junk) != 2)
|
static void
|
||||||
errx(EINVAL, "invalid nexus \"%s\"", s);
|
open_nexus_device(const char *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
|
int
|
||||||
|
@ -3664,7 +3700,7 @@ main(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
progname = argv[0];
|
g.progname = argv[0];
|
||||||
|
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
|
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
|
||||||
|
@ -3678,7 +3714,7 @@ main(int argc, const char *argv[])
|
||||||
exit(EINVAL);
|
exit(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_nexus_name(argv[1]);
|
open_nexus_device(argv[1]);
|
||||||
|
|
||||||
/* progname and nexus */
|
/* progname and nexus */
|
||||||
argc -= 2;
|
argc -= 2;
|
||||||
|
|
Loading…
Reference in a new issue