diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2017-12-29 12:15:23 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-02 21:45:32 -0500 |
commit | 9962acf7fb8c5c5a28e137d2102ee81b51b4111b (patch) | |
tree | d651dd16ee621202d92f17a5bbaf01cdb44e4035 /drivers/net | |
parent | 3fa7d19abecf5e38f980f37f606bb1bc81360cd6 (diff) | |
download | linux-9962acf7fb8c5c5a28e137d2102ee81b51b4111b.tar.bz2 |
sfp: add support for 1000Base-PX and 1000Base-BX10
Add support for decoding the transceiver information for 1000Base-PX and
1000Base-BX10. These use 1000BASE-X protocol.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/phy/sfp-bus.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c index 9d7a010edf23..ba42e39bd112 100644 --- a/drivers/net/phy/sfp-bus.c +++ b/drivers/net/phy/sfp-bus.c @@ -165,10 +165,26 @@ EXPORT_SYMBOL_GPL(sfp_parse_interface); void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, unsigned long *support) { + unsigned int br_min, br_nom, br_max; + phylink_set(support, Autoneg); phylink_set(support, Pause); phylink_set(support, Asym_Pause); + /* Decode the bitrate information to MBd */ + br_min = br_nom = br_max = 0; + if (id->base.br_nominal) { + if (id->base.br_nominal != 255) { + br_nom = id->base.br_nominal * 100; + br_min = br_nom + id->base.br_nominal * id->ext.br_min; + br_max = br_nom + id->base.br_nominal * id->ext.br_max; + } else if (id->ext.br_max) { + br_nom = 250 * id->ext.br_max; + br_max = br_nom + br_nom * id->ext.br_min / 100; + br_min = br_nom - br_nom * id->ext.br_min / 100; + } + } + /* Set ethtool support from the compliance fields. */ if (id->base.e10g_base_sr) phylink_set(support, 10000baseSR_Full); @@ -187,6 +203,11 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, phylink_set(support, 1000baseT_Full); } + /* 1000Base-PX or 1000Base-BX10 */ + if ((id->base.e_base_px || id->base.e_base_bx10) && + br_min <= 1300 && br_max >= 1200) + phylink_set(support, 1000baseX_Full); + switch (id->base.extended_cc) { case 0x00: /* Unspecified */ break; |