diff options
author | 2019-08-27 00:33:57 +0000 | |
---|---|---|
committer | 2019-08-27 00:33:57 +0000 | |
commit | 392b4b93ecc3184c5fa640e2a83fd9c889cd3dd3 (patch) | |
tree | faa9170ed9874ace3f24b560f039c552bf456a3a | |
parent | replace a mmap() with pread(). The mmap() is not needed, the file is (diff) | |
download | wireguard-openbsd-392b4b93ecc3184c5fa640e2a83fd9c889cd3dd3.tar.xz wireguard-openbsd-392b4b93ecc3184c5fa640e2a83fd9c889cd3dd3.zip |
make a start at reporting qsfp monitor values.
i have some qsfp DACs and a couple of optics, and they're all
terrible, so this is about as far as i can go for now. at least the
code will be robust in the face of terrible modules though.
the DACs are pretty dumb and basically report that they're DACs
with some strings. this code just prints that they're DACs with
strings now.
modules are supposed to be able to report overall temperature and
voltage, and optics can report tx and rx values for the 4 different
signal lanes they're supposed to provide. interestingly the current
values are always reported in the lower page, but thresholds are
reported in page 3, but not all modules support page switching.
devices are supposed to say whether they can switch pages, but i
have one that does say it can switch but then doesn't. anyway, the
take away is that it is therefore possible for a module to report
values without also
reporting thresholds.
this sets the code up to report the values on their own if we can't
query page 3 for any reason.
if the temp sensor value looks bogus (ie, 0x0000 or 0xffff), assume
the monitor values are bogus and bail early.
hopefully i can find a module soon that supports multiple signal
lanes and actually reports their values and thresholds for them.
-rw-r--r-- | sbin/ifconfig/sff.c | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/sbin/ifconfig/sff.c b/sbin/ifconfig/sff.c index 8fb79dbebfb..b1190b39009 100644 --- a/sbin/ifconfig/sff.c +++ b/sbin/ifconfig/sff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sff.c,v 1.12 2019/04/26 15:04:29 denis Exp $ */ +/* $OpenBSD: sff.c,v 1.13 2019/08/27 00:33:57 dlg Exp $ */ /* * Copyright (c) 2019 David Gwynne <dlg@openbsd.org> @@ -228,6 +228,16 @@ static const char *sff8024_con_names[] = { * updated and maintained by SFF-8636. */ +#define SFF8436_STATUS1 1 +#define SFF8436_STATUS2 2 +#define SFF8436_STATUS2_DNR (1 << 0) /* Data_Not_Ready */ +#define SFF8436_STATUS2_INTL (1 << 1) /* Interrupt output state */ +#define SFF8436_STATUS2_FLAT_MEM (1 << 2) /* Upper memory flat/paged */ + +#define SFF8436_AW_TEMP 0 +#define SFF8436_TEMP 22 +#define SFF8436_VOLTAGE 26 + /* * XFP stuff is defined by INF-8077. * @@ -615,10 +625,64 @@ if_inf8077(int s, const char *ifname, int dump, const struct if_sffpage *pg1) } static int +if_sff8636_thresh(int s, const char *ifname, int dump, + const struct if_sffpage *pg0) +{ + struct if_sffpage pg3; + + if_sffpage_init(&pg3, ifname, IFSFF_ADDR_EEPROM, 3); + if (ioctl(s, SIOCGIFSFFPAGE, (caddr_t)&pg3) == -1) { + if (dump) + warn("%s SIOCGIFSFFPAGE page 3", ifname); + return (-1); + } + + if (dump) + if_sffpage_dump(ifname, &pg3); + + if (pg3.sff_data[0x7f] != 3) { /* just in case... */ + if (dump) { + warnx("%s SIOCGIFSFFPAGE: page select unsupported", + ifname); + } + return (-1); + } + + return (-1); /* XXX not supported yet, fallthrough to pg0 values */ +} + +static int if_sff8636(int s, const char *ifname, int dump, const struct if_sffpage *pg0) { + int16_t temp; + uint8_t flat; + if_upper_strings(pg0); + if (pg0->sff_data[SFF8436_STATUS2] & SFF8436_STATUS2_DNR) { + printf("\tmonitor data not ready\n"); + return (0); + } + + temp = if_sff_int(pg0, SFF8436_TEMP); + /* the temp reading look unset, assume the rest will be unset too */ + if ((uint16_t)temp == 0 || (uint16_t)temp == 0xffffU) { + if (!dump) + return (0); + } + + flat = pg0->sff_data[SFF8436_STATUS2] & SFF8436_STATUS2_FLAT_MEM; + if (!flat && if_sff8636_thresh(s, ifname, dump, pg0) == 0) + return (0); + + printf("\t"); + printf("temp: %.02f%s", temp / SFF_TEMP_FACTOR, " C"); + printf(", "); + printf("voltage: %.02f%s", + if_sff_uint(pg0, SFF8436_VOLTAGE) / SFF_VCC_FACTOR, " V"); + + printf("\n"); + return (0); } |