Re: sfp module info and diagnostics

2019-04-09 Thread Hrvoje Popovski
On 8.4.2019. 22:13, Stuart Henderson wrote:
> On 2019/04/08 19:55, Hrvoje Popovski wrote:
>> On 8.4.2019. 11:33, David Gwynne wrote:
>>> this updates the ifconfig part of the diff
>> This is great feature... thank you ..
>> it would be great if dBm could be exported via snmp :)
> You can do this via net-snmp already:
> http://sysadvent.blogspot.com/2008/12/day-4-extending-net-snmps-snmpd.html?m=1
> 
> Better integration would be nice one day, but it adds complication (not
> least it wants some caching mechanism, rather than triggering a slow NIC
> operation every time a query comes in), and what already works is enough
> to save a lot of time, disruption and expense (especially if €quinix
> £emote hand$ are involved!) moving fibres to alternative equipment to
> check light levels. Which is why I deliberately didn't mention the
> S word ;)
> 

ok ok, no S word :)



Re: sfp module info and diagnostics

2019-04-09 Thread Hrvoje Popovski
On 8.4.2019. 19:55, Hrvoje Popovski wrote:
> On 8.4.2019. 11:33, David Gwynne wrote:
>> this updates the ifconfig part of the diff
> 
> This is great feature... thank you ..

maybe to put laser wavelength in sff output?

ix0 - 1000BASE-LX
x3550m4# ifconfig ix0 sff
ix0: identifier SFP (03)
connector: LC (07)
vendor: FiberStore
product: SFP1G-LX-31
revision: (unknown)
serial: F175EX02389
date: 2017-05-31
temperature: 39.33 C
vcc: 3.39 V
tx-bias: 15.35 mA
tx-power: -6.13 dBm
rx-power: -5.58 dBm average

SFP 33 Temperature  = 31.285C
SFP 33 Voltage  = 3.333V
SFP 33 Tx Bias Current  = 18.400mA
SFP 33 Tx Power = -6.0467dBm
SFP 33 Rx Power = -5.1670dBm



ix0 - 10GBASE-ER
x3550m4# ifconfig ix0 sff
ix0: identifier SFP (03)
connector: LC (07)
vendor: OEM
product: CSS-907A15DE-15
revision: 1.0
serial: 1803070025
date: 2018-03-08
temperature: 37.88 C
vcc: 3.31 V
tx-bias: 72.39 mA
tx-power: 0.90 dBm
rx-power: -0.14 dBm average

SFP+ 33 Temperature  = 24.453C
SFP+ 33 Voltage  = 3.252V
SFP+ 33 Tx Bias Current  = 74.740mA
SFP+ 33 Tx Power = 1.1598dBm
SFP+ 33 Rx Power = -0.4479dBm

it's strange that with ix0 media is 10GSFP+Cu. i think that is should be
10GbaseER ?

ix0: flags=8843 mtu 1500
media: Ethernet autoselect (10GSFP+Cu full-duplex,rxpause,txpause)
status: active
supported media:
media 10GSFP+Cu
media autoselect



ixl1 - 10GBASE-SR
x3550m4# ifconfig ixl1 sff
ixl1: identifier SFP (03)
connector: LC (07)
vendor: OEM
product: 10GB-SFP-SR-H
revision: 10
serial: HXP96S02
date: 2014-03-03
temperature: 30.80 C
vcc: 3.33 V
tx-bias: 5.85 mA
tx-power: -3.31 dBm
rx-power: -4.40 dBm average

SFP+ 34 Temperature  = 35.398C
SFP+ 34 Voltage  = 3.277V
SFP+ 34 Tx Bias Current  = 10.884mA
SFP+ 34 Tx Power = -2.6930dBm
SFP+ 34 Rx Power = -3.3838dBm



Re: sfp module info and diagnostics

2019-04-08 Thread Stuart Henderson
FWIW (I was interested so put something together), here's a sample diff
on top with one method of printing alarms. (I went for the < > checks
rather than table 3.18 flag bits, mostly because I didn't fancy the
"check again after 100ms" that the latter wanted).

--- sff.c.orig  Mon Apr  8 22:27:45 2019
+++ sff.c   Mon Apr  8 22:46:34 2019
@@ -202,6 +202,10 @@ static const char *sff8024_con_names[] = {
 #define SFF8472_DDM_TEC108 /* Measured TEC current */
/* optional */
 
+#define ALRM_LOW_OFFSET2
+#define WARN_HIGH_OFFSET   4
+#define WARN_LOW_OFFSET6
+
 #define SFF_TEMP_FACTOR256.0
 #define SFF_VCC_FACTOR 1.0
 #define SFF_BIAS_FACTOR500.0
@@ -380,6 +384,27 @@ if_sff_power2dbm(uint16_t power)
return (10.0 * log10f((float)power / 1.0));
 }
 
+static const char *
+if_sff_alarm(struct if_sffpage *ddm, size_t value)
+{
+   /* SFF-8472 table 3.15 */
+   size_t alrm_high = (value-96) * 4;
+   size_t alrm_low = alrm_high + ALRM_LOW_OFFSET;
+   size_t warn_high = alrm_high + WARN_HIGH_OFFSET;
+   size_t warn_low = alrm_high + WARN_LOW_OFFSET;
+
+   if(if_sff_int(ddm, value) > if_sff_int(ddm, alrm_high))
+   return " (HIGH ALARM)";
+   else if(if_sff_int(ddm, value) < if_sff_int(ddm, alrm_low))
+   return " (LOW ALARM)";
+   else if(if_sff_int(ddm, value) > if_sff_int(ddm, warn_high))
+   return " (HIGH WARNING)";
+   else if(if_sff_int(ddm, value) < if_sff_int(ddm, warn_low))
+   return " (LOW WARNING)";
+
+   return "";
+}
+
 static int
 if_sff8472(int s, const char *ifname, int dump, const struct if_sffpage *pg0)
 {
@@ -416,17 +441,22 @@ if_sff8472(int s, const char *ifname, int dump, const 
"(WARNING: needs more code)\n");
}
 
-   printf("\ttemperature: %.02f C\n",
-   if_sff_int(&ddm, SFF8472_DDM_TEMP) / SFF_TEMP_FACTOR);
-   printf("\tvcc: %.02f V\n",
-   if_sff_uint(&ddm, SFF8472_DDM_VCC) / SFF_VCC_FACTOR);
-   printf("\ttx-bias: %.02f mA\n",
-   if_sff_uint(&ddm, SFF8472_DDM_TX_BIAS) / SFF_BIAS_FACTOR);
-   printf("\ttx-power: %.02f dBm\n",
-   if_sff_power2dbm(if_sff_uint(&ddm, SFF8472_DDM_TX_POWER)));
-   printf("\trx-power: %.02f dBm %s\n",
+   printf("\ttemperature: %.02f C%s\n",
+   if_sff_int(&ddm, SFF8472_DDM_TEMP) / SFF_TEMP_FACTOR,
+   if_sff_alarm(&ddm, SFF8472_DDM_TEMP));
+   printf("\tvcc: %.02f V%s\n",
+   if_sff_uint(&ddm, SFF8472_DDM_VCC) / SFF_VCC_FACTOR,
+   if_sff_alarm(&ddm, SFF8472_DDM_VCC));
+   printf("\ttx-bias: %.02f mA%s\n",
+   if_sff_uint(&ddm, SFF8472_DDM_TX_BIAS) / SFF_BIAS_FACTOR,
+   if_sff_alarm(&ddm, SFF8472_DDM_TX_BIAS));
+   printf("\ttx-power: %.02f dBm%s\n",
+   if_sff_power2dbm(if_sff_uint(&ddm, SFF8472_DDM_TX_POWER)),
+   if_sff_alarm(&ddm, SFF8472_DDM_TX_BIAS));
+   printf("\trx-power: %.02f dBm %s%s\n",
if_sff_power2dbm(if_sff_uint(&ddm, SFF8472_DDM_RX_POWER)),
-   ISSET(ddm_types, SFF8472_DDM_TYPE_AVG_POWER) ? "average" : "OMA");
+   ISSET(ddm_types, SFF8472_DDM_TYPE_AVG_POWER) ? "average" : "OMA",
+   if_sff_alarm(&ddm, SFF8472_DDM_RX_POWER));
 
return (0);
 }



Re: sfp module info and diagnostics

2019-04-08 Thread Stuart Henderson
On 2019/04/08 19:55, Hrvoje Popovski wrote:
> On 8.4.2019. 11:33, David Gwynne wrote:
> > this updates the ifconfig part of the diff
> 
> This is great feature... thank you ..
> it would be great if dBm could be exported via snmp :)

You can do this via net-snmp already:
http://sysadvent.blogspot.com/2008/12/day-4-extending-net-snmps-snmpd.html?m=1

Better integration would be nice one day, but it adds complication (not
least it wants some caching mechanism, rather than triggering a slow NIC
operation every time a query comes in), and what already works is enough
to save a lot of time, disruption and expense (especially if €quinix
£emote hand$ are involved!) moving fibres to alternative equipment to
check light levels. Which is why I deliberately didn't mention the
S word ;)

> x3550m4# ifconfig ix0 sff
> ix0: identifier SFP (03)
> connector: LC (07)
> vendor: Intel Corp
> product: FTLX8571D3BCV-IT
> revision: A
> serial: MTB07YW
> date: 2015-03-26
> temperature: 39.21 C
> vcc: 3.36 V
> tx-bias: 7.97 mA
> tx-power: -2.66 dBm
> rx-power: -4.22 dBm average
> 
> 
> switch side
> SFP+ 33 Temperature  = 32.133C
> SFP+ 33 Voltage  = 3.283V
> SFP+ 33 Tx Bias Current  = 10.728mA
> SFP+ 33 Tx Power = -2.6978dBm
> SFP+ 33 Rx Power = -2.2643dBm
> 
> dBm values on openbsd and switch should be similar, right ?

It depends ..

When I tested, openbsd<>flexbox, the values were different for each SFP,
but swapping the SFPs between the devices, the values followed the SFP.

This does make sense though.

Typically you have two strands of fibre and different connectors which
can behave differently (or in the other case with bidi, losses are a
little higher for one wavelength than the other).

Also the SFPs are individual devices with manufacturing differences, some
will be better than others.



Re: sfp module info and diagnostics

2019-04-08 Thread Sebastian Benoit
David Gwynne(da...@gwynne.id.au) on 2019.04.08 19:33:53 +1000:
> this updates the ifconfig part of the diff
> 
> it should have the following improvements:
> 
> - actually applying to -current (thanks hrvoje)
> - use vis(3) when printing the strings out (thanks deraadt@)
> - make the code less special
> - use %.02f for the diag values consistently, and more sane units
>   (thanks mikeb@)
> 
> mikeb also suggested showing dBm instead of watts for power. this adds
> it, but uses log10f, which in turn uses libm. is that ok/worth it?

yes, dBm is what you need to see if the link checks out.

Actually printing both would be nice. ethtool has

Laser output power: 0.4939 mW / -3.06 dBm

but if you dont like that, dBm is preferable.

Thanks for doing this!

> 
> ix1 now looks like this:
> 
> dlg@ix ifconfig$ sudo ./obj/ifconfig ix1 sff   
> ix1: identifier SFP (03)
>   connector: LC (07)
>   vendor: FINISAR CORP.
>   product: FTLX8571D3BCL-FC
>   revision: A
>   serial: AQG28W3
>   date: 2013-10-19
>   temperature: 34.88 C
>   vcc: 3.36 V
>   tx-bias: 7.97 mA
>   tx-power: -2.11 dBm
>   rx-power: -2.13 dBm average
> 
> the other end (so you can compare):
> 
> eait-78-520-16-1#sh int te0/6 trans
> Interface Name : TenGigabitEthernet 0/6
> SFP+ is present
> SFP+ 6 Serial Base ID fields
> SFP+ 6 Id   = 0x03
> SFP+ 6 Ext Id   = 0x04
> SFP+ 6 Connector= 0x07
> SFP+ 6 Transceiver Code = 0x10 0x00 0x00 0x00 0x00 0x00
> 0x00 0x00 
> SFP+ 6 Encoding = 0x06
> SFP+ 6 BR Nominal   = 0x67
> SFP+ 6 Length(SFM)Km= 0x00
> SFP+ 6 Length(SFM)  100m= 0x00
> SFP+ 6 Length(OM3)   10m= 0x1e
> SFP+ 6 Length(OM2)   10m= 0x08
> SFP+ 6 Length(OM1)   10m= 0x03
> SFP+ 6 Length(Copper-1m/AOC-1m/OM4-10m) = 0x00
> SFP+ 6 Vendor Rev   = A   
> SFP+ 6 Laser Wavelength = 850 nm
> SFP+ 6 CheckCodeBase= 0x9e
> SFP+ 6 Serial Extended ID fields
> SFP+ 6 Options  = 0x00 0x1a 
> SFP+ 6 BR max   = 0
> SFP+ 6 BR min   = 0
> SFP+ 6 Vendor SN= AQG2A7A 
> SFP+ 6 Datecode = 131020  
> SFP+ 6 CheckCodeExt = 0xc0
> SFP+ 6 Extended Transceiver Code= 0x00
> 
> SFP+ 6 Diagnostic Information
> ===
> SFP+ 6 Rx Power measurement type= Average
> ===
> SFP+ 6 Temp High Alarm threshold= 78.000C 
> SFP+ 6 Voltage High Alarm threshold = 3.700V 
> SFP+ 6 Bias High Alarm threshold= 13.200mA 
> SFP+ 6 TX Power High Alarm threshold= 0.dBm 
> SFP+ 6 RX Power High Alarm threshold= 0.dBm 
> SFP+ 6 Temp Low Alarm threshold = -13.000C 
> SFP+ 6 Voltage Low Alarm threshold  = 2.900V 
> SFP+ 6 Bias Low Alarm threshold = 4.000mA 
> SFP+ 6 TX Power Low Alarm threshold = -5.9998dBm 
> SFP+ 6 RX Power Low Alarm threshold = -20.dBm 
> ===
> SFP+ 6 Temp High Warning threshold  = 73.000C 
> SFP+ 6 Voltage High Warning threshold   = 3.600V 
> SFP+ 6 Bias High Warning threshold  = 12.600mA 
> SFP+ 6 TX Power High Warning threshold  = -1.0002dBm 
> SFP+ 6 RX Power High Warning threshold  = -1.0002dBm 
> SFP+ 6 Temp Low Warning threshold   = -8.000C 
> SFP+ 6 Voltage Low Warning threshold= 3.000V 
> SFP+ 6 Bias Low Warning threshold   = 5.000mA 
> SFP+ 6 TX Power Low Warning threshold   = -5.0004dBm 
> SFP+ 6 RX Power Low Warning threshold   = -18.0134dBm 
> ===
> SFP+ 6 Temperature  = 48.875C
> SFP+ 6 Voltage  = 3.338V
> SFP+ 6 Tx Bias Current  = 8.660mA
> SFP+ 6 Tx Power = -2.4260dBm
> SFP+ 6 Rx Power = -2.2243dBm
> ===
> SFP+ 6 Data Ready state Bar = False
> SFP+ 6 Rx LOS state = False
> SFP+ 6 Tx Fault state   = False
> SFP+ 6 Rate Select state= False
> SFP+ 6 RS state = False
> SFP+ 6 Tx Disable state = False
> ===
> SFP+ 6 Temperature High Alarm Flag  = False
> SFP+ 6 Voltage High Alarm Flag  = False
> SFP+ 6 Tx Bias High Alarm Flag  = False
> SFP+ 6 Tx Power High Alarm Flag = False
> SFP+ 6 Rx Power High Alarm Flag = False
> SFP+ 6 Temperature Low Alarm Flag   = False
> SFP+ 6 Voltage Low Alarm Flag   = False
> SFP+ 6 Tx Bias Low Alarm Flag   = False
> SFP+ 6 Tx Power Low Alarm Flag  = False
> SFP+ 6 Rx Power Low Al

Re: sfp module info and diagnostics

2019-04-08 Thread Hrvoje Popovski
On 8.4.2019. 11:33, David Gwynne wrote:
> this updates the ifconfig part of the diff

This is great feature... thank you ..
it would be great if dBm could be exported via snmp :)


switch - Dell S4810
ix0 - sfp+ 10GBASE-SR optics
ix1 - sfp 1000BASE-SX optics
ixl0 - 10G passive DAC cables


x3550m4# ifconfig ix0 sff
ix0: identifier SFP (03)
connector: LC (07)
vendor: Intel Corp
product: FTLX8571D3BCV-IT
revision: A
serial: MTB07YW
date: 2015-03-26
temperature: 39.21 C
vcc: 3.36 V
tx-bias: 7.97 mA
tx-power: -2.66 dBm
rx-power: -4.22 dBm average


switch side
SFP+ 33 Temperature  = 32.133C
SFP+ 33 Voltage  = 3.283V
SFP+ 33 Tx Bias Current  = 10.728mA
SFP+ 33 Tx Power = -2.6978dBm
SFP+ 33 Rx Power = -2.2643dBm

dBm values on openbsd and switch should be similar, right ?



x3550m4# ifconfig ix1 sff
ix1: identifier SFP (03)
connector: LC (07)
vendor: CISCO-FINISAR
product: FTRJ-8519-7D-CSC
revision: (unknown)
serial: H11H167
date: 2004-01-23




x3550m4# ifconfig ixl0 sff
ixl0: identifier SFP (03)
connector: Copper Pigtail (21)
vendor: Amphenol
product: 616740005
revision: C
serial: CN0358VV6751650
date: 2016-07-07



Re: sfp module info and diagnostics

2019-04-08 Thread Stuart Henderson
On 2019/04/08 13:57, Stuart Henderson wrote:
> Here's a complete diff. Tested on amd64 with ix, working great there.
> distrib/special/ifconfig still builds okay, I'll run a full mkr later on
> i386/amd64.
> 
> This is extremely useful for the bgpd "target market" ;)

oops, here's attempt #2 with the missing piece.

Index: sbin/ifconfig/Makefile
===
RCS file: /cvs/src/sbin/ifconfig/Makefile,v
retrieving revision 1.14
diff -u -p -r1.14 Makefile
--- sbin/ifconfig/Makefile  3 May 2016 17:52:33 -   1.14
+++ sbin/ifconfig/Makefile  8 Apr 2019 13:01:28 -
@@ -1,10 +1,10 @@
 #  $OpenBSD: Makefile,v 1.14 2016/05/03 17:52:33 jca Exp $
 
 PROG=  ifconfig
-SRCS=  ifconfig.c brconfig.c
+SRCS=  ifconfig.c brconfig.c sff.c
 MAN=   ifconfig.8
 
-LDADD= -lutil
+LDADD= -lutil -lm
 DPADD= ${LIBUTIL}
 
 .include 
Index: sbin/ifconfig/ifconfig.c
===
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.397
diff -u -p -r1.397 ifconfig.c
--- sbin/ifconfig/ifconfig.c11 Mar 2019 11:25:48 -  1.397
+++ sbin/ifconfig/ifconfig.c8 Apr 2019 13:01:28 -
@@ -340,6 +340,8 @@ voidumb_setclass(const char *, int);
 void   umb_roaming(const char *, int);
 void   utf16_to_char(uint16_t *, int, char *, size_t);
 intchar_to_utf16(const char *, uint16_t *, size_t);
+void   transceiver(const char *, int);
+void   transceiverdump(const char *, int);
 #else
 void   setignore(const char *, int);
 #endif
@@ -589,6 +591,9 @@ const structcmd {
{ "datapath",   NEXTARG,0,  switch_datapathid },
{ "portno", NEXTARG2,   0,  NULL, switch_portno },
{ "addlocal",   NEXTARG,0,  addlocal },
+   { "transceiver", 0, 0,  transceiver },
+   { "sff",0,  0,  transceiver },
+   { "sffdump",0,  0,  transceiverdump },
 #else /* SMALL */
{ "powersave",  NEXTARG0,   0,  setignore },
{ "priority",   NEXTARG,0,  setignore },
@@ -4033,6 +4038,22 @@ unsetpwe3neighbor(const char *val, int d
 
if (ioctl(s, SIOCDPWE3NEIGHBOR, &req) == -1)
warn("-pweneighbor");
+}
+
+intif_sff_info(int, const char *, int);
+
+void
+transceiver(const char *value, int d)
+{
+   if (if_sff_info(s, name, 0) == -1)
+   err(1, "%s %s", name, __func__);
+}
+
+void
+transceiverdump(const char *value, int d)
+{
+   if (if_sff_info(s, name, 1) == -1)
+   err(1, "%s transceiver", name);
 }
 #endif /* SMALL */
 
Index: sbin/ifconfig/sff.c
===
RCS file: sbin/ifconfig/sff.c
diff -N sbin/ifconfig/sff.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ sbin/ifconfig/sff.c 8 Apr 2019 13:01:28 -
@@ -0,0 +1,464 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) David Gwynne 
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SMALL
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef nitems
+#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
+#endif
+
+#ifndef ISSET
+#define ISSET(_w, _m)  ((_w) & (_m))
+#endif
+
+#define SFF8024_ID_UNKNOWN 0x00
+#define SFF8024_ID_GBIC0x01
+#define SFF8024_ID_MOBO0x02 /* Module/connector soldered to 
mobo */
+/* using SFF-8472 */
+#define SFF8024_ID_SFP 0x03 /* SFP/SFP+/SFP28 */
+#define SFF8024_ID_300PIN_XBI  0x04 /* 300 pin XBI */
+#define SFF8024_ID_XENPAK  0x05
+#define SFF8024_ID_XFP 0x06
+#define SFF8024_ID_XFF 0x07
+#define SFF8024_ID_XFPE0x08 /* XFP-E */
+#define SFF8024_ID_XPAK0x09
+#define SFF8024_ID_X2  0x0a
+#define SFF8024_ID_DWDM_SFP0x0b /* DWDM-SFP/SFP+ */
+/* not using SFF-8472 */
+#define SFF8024_ID_QSFP0x0c
+#define SFF8024_ID_QSFP_PLUS   0x0d /* or later */
+/* using SFF-8436/8665/8685 et 

Re: sfp module info and diagnostics

2019-04-08 Thread Stuart Henderson
Here's a complete diff. Tested on amd64 with ix, working great there.
distrib/special/ifconfig still builds okay, I'll run a full mkr later on
i386/amd64.

This is extremely useful for the bgpd "target market" ;)

Index: sbin/ifconfig/Makefile
===
RCS file: /cvs/src/sbin/ifconfig/Makefile,v
retrieving revision 1.14
diff -u -p -r1.14 Makefile
--- sbin/ifconfig/Makefile  3 May 2016 17:52:33 -   1.14
+++ sbin/ifconfig/Makefile  8 Apr 2019 12:45:33 -
@@ -1,10 +1,10 @@
 #  $OpenBSD: Makefile,v 1.14 2016/05/03 17:52:33 jca Exp $
 
 PROG=  ifconfig
-SRCS=  ifconfig.c brconfig.c
+SRCS=  ifconfig.c brconfig.c sff.c
 MAN=   ifconfig.8
 
-LDADD= -lutil
+LDADD= -lutil -lm
 DPADD= ${LIBUTIL}
 
 .include 
Index: sbin/ifconfig/ifconfig.c
===
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.397
diff -u -p -r1.397 ifconfig.c
--- sbin/ifconfig/ifconfig.c11 Mar 2019 11:25:48 -  1.397
+++ sbin/ifconfig/ifconfig.c8 Apr 2019 12:45:33 -
@@ -340,6 +340,8 @@ voidumb_setclass(const char *, int);
 void   umb_roaming(const char *, int);
 void   utf16_to_char(uint16_t *, int, char *, size_t);
 intchar_to_utf16(const char *, uint16_t *, size_t);
+void   transceiver(const char *, int);
+void   transceiverdump(const char *, int);
 #else
 void   setignore(const char *, int);
 #endif
@@ -589,6 +591,9 @@ const structcmd {
{ "datapath",   NEXTARG,0,  switch_datapathid },
{ "portno", NEXTARG2,   0,  NULL, switch_portno },
{ "addlocal",   NEXTARG,0,  addlocal },
+   { "transceiver", 0, 0,  transceiver },
+   { "sff",0,  0,  transceiver },
+   { "sffdump",0,  0,  transceiverdump },
 #else /* SMALL */
{ "powersave",  NEXTARG0,   0,  setignore },
{ "priority",   NEXTARG,0,  setignore },
@@ -4033,6 +4038,22 @@ unsetpwe3neighbor(const char *val, int d
 
if (ioctl(s, SIOCDPWE3NEIGHBOR, &req) == -1)
warn("-pweneighbor");
+}
+
+intif_sff_info(int, const char *, int);
+
+void
+transceiver(const char *value, int d)
+{
+   if (if_sff_info(s, name, 0) == -1)
+   err(1, "%s %s", name, __func__);
+}
+
+void
+transceiverdump(const char *value, int d)
+{
+   if (if_sff_info(s, name, 1) == -1)
+   err(1, "%s transceiver", name);
 }
 #endif /* SMALL */
 
Index: sbin/ifconfig/sff.c
===
RCS file: sbin/ifconfig/sff.c
diff -N sbin/ifconfig/sff.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ sbin/ifconfig/sff.c 8 Apr 2019 12:45:33 -
@@ -0,0 +1,464 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) David Gwynne 
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SMALL
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef nitems
+#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
+#endif
+
+#ifndef ISSET
+#define ISSET(_w, _m)  ((_w) & (_m))
+#endif
+
+#define SFF8024_ID_UNKNOWN 0x00
+#define SFF8024_ID_GBIC0x01
+#define SFF8024_ID_MOBO0x02 /* Module/connector soldered to 
mobo */
+/* using SFF-8472 */
+#define SFF8024_ID_SFP 0x03 /* SFP/SFP+/SFP28 */
+#define SFF8024_ID_300PIN_XBI  0x04 /* 300 pin XBI */
+#define SFF8024_ID_XENPAK  0x05
+#define SFF8024_ID_XFP 0x06
+#define SFF8024_ID_XFF 0x07
+#define SFF8024_ID_XFPE0x08 /* XFP-E */
+#define SFF8024_ID_XPAK0x09
+#define SFF8024_ID_X2  0x0a
+#define SFF8024_ID_DWDM_SFP0x0b /* DWDM-SFP/SFP+ */
+/* not using SFF-8472 */
+#define SFF8024_ID_QSFP0x0c
+#define SFF8024_ID_QSFP_PLUS   0x0d /* or later */
+/* using SFF-8436/8665/8685 et al */
+#define SFF8024_ID_CXP 0x0e /* or later */
+#define SFF8024_ID_HD4X0x0f /

Re: sfp module info and diagnostics

2019-04-08 Thread David Gwynne
this updates the ifconfig part of the diff

it should have the following improvements:

- actually applying to -current (thanks hrvoje)
- use vis(3) when printing the strings out (thanks deraadt@)
- make the code less special
- use %.02f for the diag values consistently, and more sane units
  (thanks mikeb@)

mikeb also suggested showing dBm instead of watts for power. this adds
it, but uses log10f, which in turn uses libm. is that ok/worth it?

ix1 now looks like this:

dlg@ix ifconfig$ sudo ./obj/ifconfig ix1 sff   
ix1: identifier SFP (03)
connector: LC (07)
vendor: FINISAR CORP.
product: FTLX8571D3BCL-FC
revision: A
serial: AQG28W3
date: 2013-10-19
temperature: 34.88 C
vcc: 3.36 V
tx-bias: 7.97 mA
tx-power: -2.11 dBm
rx-power: -2.13 dBm average

the other end (so you can compare):

eait-78-520-16-1#sh int te0/6 trans
Interface Name : TenGigabitEthernet 0/6
SFP+ is present
SFP+ 6 Serial Base ID fields
SFP+ 6 Id   = 0x03
SFP+ 6 Ext Id   = 0x04
SFP+ 6 Connector= 0x07
SFP+ 6 Transceiver Code = 0x10 0x00 0x00 0x00 0x00 0x00
0x00 0x00 
SFP+ 6 Encoding = 0x06
SFP+ 6 BR Nominal   = 0x67
SFP+ 6 Length(SFM)Km= 0x00
SFP+ 6 Length(SFM)  100m= 0x00
SFP+ 6 Length(OM3)   10m= 0x1e
SFP+ 6 Length(OM2)   10m= 0x08
SFP+ 6 Length(OM1)   10m= 0x03
SFP+ 6 Length(Copper-1m/AOC-1m/OM4-10m) = 0x00
SFP+ 6 Vendor Rev   = A   
SFP+ 6 Laser Wavelength = 850 nm
SFP+ 6 CheckCodeBase= 0x9e
SFP+ 6 Serial Extended ID fields
SFP+ 6 Options  = 0x00 0x1a 
SFP+ 6 BR max   = 0
SFP+ 6 BR min   = 0
SFP+ 6 Vendor SN= AQG2A7A 
SFP+ 6 Datecode = 131020  
SFP+ 6 CheckCodeExt = 0xc0
SFP+ 6 Extended Transceiver Code= 0x00

SFP+ 6 Diagnostic Information
===
SFP+ 6 Rx Power measurement type= Average
===
SFP+ 6 Temp High Alarm threshold= 78.000C 
SFP+ 6 Voltage High Alarm threshold = 3.700V 
SFP+ 6 Bias High Alarm threshold= 13.200mA 
SFP+ 6 TX Power High Alarm threshold= 0.dBm 
SFP+ 6 RX Power High Alarm threshold= 0.dBm 
SFP+ 6 Temp Low Alarm threshold = -13.000C 
SFP+ 6 Voltage Low Alarm threshold  = 2.900V 
SFP+ 6 Bias Low Alarm threshold = 4.000mA 
SFP+ 6 TX Power Low Alarm threshold = -5.9998dBm 
SFP+ 6 RX Power Low Alarm threshold = -20.dBm 
===
SFP+ 6 Temp High Warning threshold  = 73.000C 
SFP+ 6 Voltage High Warning threshold   = 3.600V 
SFP+ 6 Bias High Warning threshold  = 12.600mA 
SFP+ 6 TX Power High Warning threshold  = -1.0002dBm 
SFP+ 6 RX Power High Warning threshold  = -1.0002dBm 
SFP+ 6 Temp Low Warning threshold   = -8.000C 
SFP+ 6 Voltage Low Warning threshold= 3.000V 
SFP+ 6 Bias Low Warning threshold   = 5.000mA 
SFP+ 6 TX Power Low Warning threshold   = -5.0004dBm 
SFP+ 6 RX Power Low Warning threshold   = -18.0134dBm 
===
SFP+ 6 Temperature  = 48.875C
SFP+ 6 Voltage  = 3.338V
SFP+ 6 Tx Bias Current  = 8.660mA
SFP+ 6 Tx Power = -2.4260dBm
SFP+ 6 Rx Power = -2.2243dBm
===
SFP+ 6 Data Ready state Bar = False
SFP+ 6 Rx LOS state = False
SFP+ 6 Tx Fault state   = False
SFP+ 6 Rate Select state= False
SFP+ 6 RS state = False
SFP+ 6 Tx Disable state = False
===
SFP+ 6 Temperature High Alarm Flag  = False
SFP+ 6 Voltage High Alarm Flag  = False
SFP+ 6 Tx Bias High Alarm Flag  = False
SFP+ 6 Tx Power High Alarm Flag = False
SFP+ 6 Rx Power High Alarm Flag = False
SFP+ 6 Temperature Low Alarm Flag   = False
SFP+ 6 Voltage Low Alarm Flag   = False
SFP+ 6 Tx Bias Low Alarm Flag   = False
SFP+ 6 Tx Power Low Alarm Flag  = False
SFP+ 6 Rx Power Low Alarm Flag  = False
===
SFP+ 6 Temperature High Warning Flag= False
SFP+ 6 Voltage High Warning Flag= False
SFP+ 6 Tx Bias High Warning Flag= False
SFP+ 6 Tx Power High Warning Flag   = False
SFP+ 6 Rx Power High Warning Flag   = False
SFP+ 6 Temperature Low Warning Flag = False
SFP+ 6 Voltage Low Warning Flag = False
SFP+ 6 Tx Bias Low Warning Flag = False
SFP+ 6 Tx Power Low Warning Flag= False
SFP+ 6 Rx Power Low W

sfp module info and diagnostics

2019-04-07 Thread David Gwynne
this adds support to ifconfig for reading info from transceivers.

it looks like this:

dlg@ix ifconfig$ sudo ./obj/ifconfig ix0 transceiver
ix0: identifier SFP (03)
connector: Copper Pigtail (21)
vendor: Amphenol
product: 616740001
revision: B
serial: CN0V250M36J0T86
date: 2013-07-04
dlg@ix ifconfig$ sudo ./obj/ifconfig ix1 transceiver 
ix1: identifier SFP (03)
connector: LC (07)
vendor: FINISAR CORP.
product: FTLX8571D3BCL-FC
revision: A
serial: AQG28W3
date: 2013-10-19
temperature: 34.60 C
vcc: 3.3553 V
tx-bias: 7986.0 uA
tx-power: 0.6128 mW
rx-power: 0.6153 mW average
dlg@ix ifconfig$ sudo ./obj/ifconfig ixl0 transceiver
ixl0: identifier QSFP+ (0d)

this is all specified by the SFF (small formfactor) group in SNIA, but
it is a lot of disparate documentation to get into your head. the top
level summary is that sfp modules have an i2c bus wired up to them, and
answer reads at device address 0xa0. there is a 256 byte page at that
address with information like the type of module, and depending on the
type you can find the manufacturer, product name, serial number, and so
on.

a later spec added support a "digital diagnostics monitoring" (DDM)
or "digital optical monitoring" (DOM) capability where there's live
status/diag information available at i2c address 0xa2. again, it's a 256
byte page, but the values change all the time based on what the module
is doing. this is where the temperature and laser power stuff is.

ive implemented basic support for the above, which is specific to
some sfp shaped modules (so sfp+ and sfp28 too) and gbics. devices
report whether they support the diag page, so it only fetches and
parses that if page 0 on 0xa0 says it can. there are different specs
for the other types of modules, in particular qsfp and related
modules have a very different layout. however, they still use the
same device addresses and pages, it's just that the contents of the
page vary. support for qsfp will be forthcoming if this goes ahead.
dumping more info generally will happen as time and interest permits
too.

i've only implemented the kernel backend for this on ix and ixl. ixl
support is patchy because it relies on a command that only exists in
high API versions (like 1.7). ix seems pretty consistent. other nics can
grow support as time and hw availability permites. i don't have an em(4)
with optics, so that might be hard for me to do myself, but i tried to
make the kernel side as easy as possible so people should have a good
chance at figuring it out.

do those power units sound plausible or are the factors off?

this was originally requested by rachel roch on misc@ in "Viewing SFP
diagnostic data in OpenBSD ?"

thoughts? 

Index: sys/sys/sockio.h
===
RCS file: /cvs/src/sys/sys/sockio.h,v
retrieving revision 1.80
diff -u -p -r1.80 sockio.h
--- sys/sys/sockio.h26 Feb 2019 03:19:11 -  1.80
+++ sys/sys/sockio.h8 Apr 2019 02:05:36 -
@@ -68,6 +68,7 @@
 /* 53 and 54 used to be SIOC[SG]IFMEDIA with a 32 bit media word */
 #defineSIOCSIFMEDIA_IOWR('i', 55, struct ifreq)/* set net 
media */
 #defineSIOCGIFMEDIA_IOWR('i', 56, struct ifmediareq) /* get net 
media */
+#defineSIOCGIFSFFPAGE  _IOWR('i', 57, struct if_sffpage) /* get SFF 
page */
 
 #defineSIOCDIFPHYADDR   _IOW('i', 73, struct ifreq)/* delete gif 
addrs */
 #defineSIOCSLIFPHYADDR  _IOW('i', 74, struct if_laddrreq) /* set gif 
addrs */
Index: sys/net/if.c
===
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.573
diff -u -p -r1.573 if.c
--- sys/net/if.c1 Mar 2019 04:47:32 -   1.573
+++ sys/net/if.c8 Apr 2019 02:05:36 -
@@ -144,6 +144,8 @@ int if_detached_ioctl(struct ifnet *, u_
 
 intifioctl_get(u_long, caddr_t);
 intifconf(caddr_t);
+static int
+   if_sffpage_check(const caddr_t);
 
 intif_getgroup(caddr_t, struct ifnet *);
 intif_getgroupmembers(caddr_t);
@@ -2143,6 +2172,19 @@ ifioctl(struct socket *so, u_long cmd, c
NET_UNLOCK();
break;
 
+   case SIOCGIFSFFPAGE:
+   error = suser(p);
+   if (error != 0)
+   break;
+
+   error = if_sffpage_check(data);
+   if (error != 0)
+   break;
+
+   /* don't take NET_LOCK because i2c reads take a long time */
+   error = ((*ifp->if_ioctl)(ifp, cmd, data));
+   break;
+
case SIOCSETKALIVE:
case SIOCDIFPHYADDR:
case SIOCSLIFPHYADDR:
@@ -2304,6 +2346,22 @@ ifioctl_get(u_long cmd, caddr_t data)
return (error);
 }
 
+static int
+if_sffpage_check(const caddr_t data)
+{
+   const struct if_sffpage *sff = (const struct if_sffpage *)data;