| From f0b4f847673299577c29b71d3f3acd3c313d81b7 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> |
| Date: Mon, 25 Jan 2021 16:02:28 +0100 |
| Subject: net: sfp: add mode quirk for GPON module Ubiquiti U-Fiber Instant |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| The Ubiquiti U-Fiber Instant SFP GPON module has nonsensical information |
| stored in its EEPROM. It claims to support all transceiver types including |
| 10G Ethernet. Clear all claimed modes and set only 1000baseX_Full, which is |
| the only one supported. |
| |
| This module has also phys_id set to SFF, and the SFP subsystem currently |
| does not allow to use SFP modules detected as SFFs. Add exception for this |
| module so it can be detected as supported. |
| |
| This change finally allows to detect and use SFP GPON module Ubiquiti |
| U-Fiber Instant on Linux system. |
| |
| EEPROM content of this SFP module is (where XX is serial number): |
| |
| 00: 02 04 0b ff ff ff ff ff ff ff ff 03 0c 00 14 c8 ???........??.?? |
| 10: 00 00 00 00 55 42 4e 54 20 20 20 20 20 20 20 20 ....UBNT |
| 20: 20 20 20 20 00 18 e8 29 55 46 2d 49 4e 53 54 41 .??)UF-INSTA |
| 30: 4e 54 20 20 20 20 20 20 34 20 20 20 05 1e 00 36 NT 4 ??.6 |
| 40: 00 06 00 00 55 42 4e 54 XX XX XX XX XX XX XX XX .?..UBNTXXXXXXXX |
| 50: 20 20 20 20 31 34 30 31 32 33 20 20 60 80 02 41 140123 `??A |
| |
| Signed-off-by: Pali Rohár <pali@kernel.org> |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| --- |
| drivers/net/phy/sfp-bus.c | 15 +++++++++++++++ |
| drivers/net/phy/sfp.c | 17 +++++++++++++++-- |
| 2 files changed, 30 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/net/phy/sfp-bus.c |
| +++ b/drivers/net/phy/sfp-bus.c |
| @@ -44,6 +44,17 @@ static void sfp_quirk_2500basex(const st |
| phylink_set(modes, 2500baseX_Full); |
| } |
| |
| +static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id, |
| + unsigned long *modes) |
| +{ |
| + /* Ubiquiti U-Fiber Instant module claims that support all transceiver |
| + * types including 10G Ethernet which is not truth. So clear all claimed |
| + * modes and set only one mode which module supports: 1000baseX_Full. |
| + */ |
| + phylink_zero(modes); |
| + phylink_set(modes, 1000baseX_Full); |
| +} |
| + |
| static const struct sfp_quirk sfp_quirks[] = { |
| { |
| // Alcatel Lucent G-010S-P can operate at 2500base-X, but |
| @@ -63,6 +74,10 @@ static const struct sfp_quirk sfp_quirks |
| .vendor = "HUAWEI", |
| .part = "MA5671A", |
| .modes = sfp_quirk_2500basex, |
| + }, { |
| + .vendor = "UBNT", |
| + .part = "UF-INSTANT", |
| + .modes = sfp_quirk_ubnt_uf_instant, |
| }, |
| }; |
| |
| --- a/drivers/net/phy/sfp.c |
| +++ b/drivers/net/phy/sfp.c |
| @@ -273,8 +273,21 @@ static const struct sff_data sff_data = |
| |
| static bool sfp_module_supported(const struct sfp_eeprom_id *id) |
| { |
| - return id->base.phys_id == SFF8024_ID_SFP && |
| - id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP; |
| + if (id->base.phys_id == SFF8024_ID_SFP && |
| + id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP) |
| + return true; |
| + |
| + /* SFP GPON module Ubiquiti U-Fiber Instant has in its EEPROM stored |
| + * phys id SFF instead of SFP. Therefore mark this module explicitly |
| + * as supported based on vendor name and pn match. |
| + */ |
| + if (id->base.phys_id == SFF8024_ID_SFF_8472 && |
| + id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP && |
| + !memcmp(id->base.vendor_name, "UBNT ", 16) && |
| + !memcmp(id->base.vendor_pn, "UF-INSTANT ", 16)) |
| + return true; |
| + |
| + return false; |
| } |
| |
| static const struct sff_data sfp_data = { |