netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Pali Rohár" <pali@kernel.org>
To: "Russell King" <linux@armlinux.org.uk>,
	"Andrew Lunn" <andrew@lunn.ch>,
	"Heiner Kallweit" <hkallweit1@gmail.com>,
	"David S. Miller" <davem@davemloft.net>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Marek Behún" <kabel@kernel.org>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 1/4] net: sfp: add workaround for Realtek RTL8672 and RTL9601C chips
Date: Wed, 30 Dec 2020 16:47:52 +0100	[thread overview]
Message-ID: <20201230154755.14746-2-pali@kernel.org> (raw)
In-Reply-To: <20201230154755.14746-1-pali@kernel.org>

Workaround for GPON SFP modules based on VSOL V2801F brand was added in
commit 0d035bed2a4a ("net: sfp: VSOL V2801F / CarlitoxxPro CPGOS03-0490
v2.0 workaround"). But it works only for ids explicitly added to the list.
As there are more rebraded VSOL V2801F modules and OEM vendors are putting
into vendor name random strings we cannot build workaround based on ids.

Moreover issue which that commit tried to workaround is generic not only to
VSOL based modules, but rather to all GPON modules based on Realtek RTL8672
and RTL9601C chips.

They can be found for example in following GPON modules:
* V-SOL V2801F
* C-Data FD511GX-RM0
* OPTON GP801R
* BAUDCOM BD-1234-SFM
* CPGOS03-0490 v2.0
* Ubiquiti U-Fiber Instant
* EXOT EGS1

Those Realtek chips have broken EEPROM emulator which for N-byte read
operation returns just one byte of EEPROM data followed by N-1 zeros.

So introduce a new function sfp_id_needs_byte_io() which detects SFP
modules with these Realtek chips which have broken EEPROM emulator based on
N-1 zeros and switch to 1 byte EEPROM reading operation which workaround
this issue.

This patch fixes reading EEPROM content from SFP modules based on Realtek
RTL8672 and RTL9601C chips.

Fixes: 0d035bed2a4a ("net: sfp: VSOL V2801F / CarlitoxxPro CPGOS03-0490 v2.0 workaround")
Co-developed-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Pali Rohár <pali@kernel.org>
---
 drivers/net/phy/sfp.c | 78 ++++++++++++++++++++++++-------------------
 1 file changed, 44 insertions(+), 34 deletions(-)

diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 91d74c1a920a..490e78a72dd6 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -336,19 +336,11 @@ static int sfp_i2c_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
 			size_t len)
 {
 	struct i2c_msg msgs[2];
-	size_t block_size;
+	u8 bus_addr = a2 ? 0x51 : 0x50;
+	size_t block_size = sfp->i2c_block_size;
 	size_t this_len;
-	u8 bus_addr;
 	int ret;
 
-	if (a2) {
-		block_size = 16;
-		bus_addr = 0x51;
-	} else {
-		block_size = sfp->i2c_block_size;
-		bus_addr = 0x50;
-	}
-
 	msgs[0].addr = bus_addr;
 	msgs[0].flags = 0;
 	msgs[0].len = 1;
@@ -1642,26 +1634,30 @@ static int sfp_sm_mod_hpower(struct sfp *sfp, bool enable)
 	return 0;
 }
 
-/* Some modules (Nokia 3FE46541AA) lock up if byte 0x51 is read as a
- * single read. Switch back to reading 16 byte blocks unless we have
- * a CarlitoxxPro module (rebranded VSOL V2801F). Even more annoyingly,
- * some VSOL V2801F have the vendor name changed to OEM.
+/* GPON modules based on Realtek RTL8672 and RTL9601C chips (e.g. V-SOL
+ * V2801F, CarlitoxxPro CPGOS03-0490, Ubiquiti U-Fiber Instant, ...) do
+ * not support multibyte reads from the EEPROM. Each multi-byte read
+ * operation returns just one byte of EEPROM followed by zeros. There is
+ * no way to identify which modules are using Realtek RTL8672 and RTL9601C
+ * chips. Moreover every OEM of V-SOL V2801F module puts its own vendor
+ * name and vendor id into EEPROM, so there is even no way to detect if
+ * module is V-SOL V2801F. Therefore check for those zeros in the read
+ * data and then based on check switch to reading EEPROM to one byte
+ * at a time.
  */
-static int sfp_quirk_i2c_block_size(const struct sfp_eeprom_base *base)
+static bool sfp_id_needs_byte_io(struct sfp *sfp, void *buf, size_t len)
 {
-	if (!memcmp(base->vendor_name, "VSOL            ", 16))
-		return 1;
-	if (!memcmp(base->vendor_name, "OEM             ", 16) &&
-	    !memcmp(base->vendor_pn,   "V2801F          ", 16))
-		return 1;
+	size_t i, block_size = sfp->i2c_block_size;
 
-	/* Some modules can't cope with long reads */
-	return 16;
-}
+	/* Already using byte IO */
+	if (block_size == 1)
+		return false;
 
-static void sfp_quirks_base(struct sfp *sfp, const struct sfp_eeprom_base *base)
-{
-	sfp->i2c_block_size = sfp_quirk_i2c_block_size(base);
+	for (i = 1; i < len; i += block_size) {
+		if (memchr_inv(buf + i, '\0', block_size - 1))
+			return false;
+	}
+	return true;
 }
 
 static int sfp_cotsworks_fixup_check(struct sfp *sfp, struct sfp_eeprom_id *id)
@@ -1705,11 +1701,7 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
 	u8 check;
 	int ret;
 
-	/* Some modules (CarlitoxxPro CPGOS03-0490) do not support multibyte
-	 * reads from the EEPROM, so start by reading the base identifying
-	 * information one byte at a time.
-	 */
-	sfp->i2c_block_size = 1;
+	sfp->i2c_block_size = 16;
 
 	ret = sfp_read(sfp, false, 0, &id.base, sizeof(id.base));
 	if (ret < 0) {
@@ -1723,6 +1715,27 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
 		return -EAGAIN;
 	}
 
+	if (sfp_id_needs_byte_io(sfp, &id.base, sizeof(id.base))) {
+		dev_info(sfp->dev,
+			 "Detected broken RTL8672/RTL9601C emulated EEPROM\n");
+		dev_info(sfp->dev,
+			 "Switching to reading EEPROM to one byte at a time\n");
+		sfp->i2c_block_size = 1;
+
+		ret = sfp_read(sfp, false, 0, &id.base, sizeof(id.base));
+		if (ret < 0) {
+			if (report)
+				dev_err(sfp->dev, "failed to read EEPROM: %d\n",
+					ret);
+			return -EAGAIN;
+		}
+
+		if (ret != sizeof(id.base)) {
+			dev_err(sfp->dev, "EEPROM short read: %d\n", ret);
+			return -EAGAIN;
+		}
+	}
+
 	/* Cotsworks do not seem to update the checksums when they
 	 * do the final programming with the final module part number,
 	 * serial number and date code.
@@ -1757,9 +1770,6 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
 		}
 	}
 
-	/* Apply any early module-specific quirks */
-	sfp_quirks_base(sfp, &id.base);
-
 	ret = sfp_read(sfp, false, SFP_CC_BASE + 1, &id.ext, sizeof(id.ext));
 	if (ret < 0) {
 		if (report)
-- 
2.20.1


  reply	other threads:[~2020-12-30 15:49 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-30 15:47 [PATCH 0/4] net: sfp: add support for GPON RTL8672/RTL9601C and Ubiquiti U-Fiber Pali Rohár
2020-12-30 15:47 ` Pali Rohár [this message]
2020-12-30 16:10   ` [PATCH 1/4] net: sfp: add workaround for Realtek RTL8672 and RTL9601C chips Russell King - ARM Linux admin
2020-12-30 16:56     ` Pali Rohár
2020-12-30 17:05       ` Russell King - ARM Linux admin
2020-12-30 17:13         ` Andrew Lunn
2020-12-30 17:43           ` Pali Rohár
2020-12-30 19:09             ` Russell King - ARM Linux admin
2020-12-30 19:49               ` Andrew Lunn
2020-12-31 12:14               ` Pali Rohár
2020-12-31 15:09                 ` Andrew Lunn
2020-12-31 15:40                   ` Pali Rohár
2020-12-31 15:30                 ` Andrew Lunn
2020-12-31 17:00                   ` Pali Rohár
2020-12-31 17:13                     ` Andrew Lunn
2021-01-02  1:49                       ` Pali Rohár
2021-01-03  2:25                         ` Thomas Schreiber
2021-01-03  2:41                           ` Pali Rohár
2021-01-06 14:55                             ` Pali Rohár
2021-01-06 15:21                               ` Russell King - ARM Linux admin
2021-01-06 15:23                                 ` Russell King - ARM Linux admin
2021-01-06 15:27                                   ` Russell King - ARM Linux admin
2021-01-06 15:35                                     ` Pali Rohár
2020-12-30 19:30             ` Andrew Lunn
2020-12-30 19:39               ` Russell King - ARM Linux admin
2020-12-30 17:31         ` Pali Rohár
2020-12-30 19:18           ` Russell King - ARM Linux admin
2020-12-30 15:47 ` [PATCH 2/4] net: sfp: allow to use also SFP modules which are detected as SFF Pali Rohár
2020-12-30 16:11   ` Russell King - ARM Linux admin
2020-12-30 17:06     ` Pali Rohár
2020-12-30 17:27       ` Marek Behún
2020-12-30 19:12         ` Russell King - ARM Linux admin
2020-12-31 13:52           ` Pali Rohár
2020-12-30 15:47 ` [PATCH 3/4] net: sfp: assume that LOS is not implemented if both LOS normal and inverted is set Pali Rohár
2020-12-30 16:13   ` Russell King - ARM Linux admin
2020-12-30 16:57     ` Pali Rohár
2020-12-30 17:06       ` Russell King - ARM Linux admin
2020-12-30 17:17         ` Andrew Lunn
2020-12-30 17:32           ` Pali Rohár
2020-12-30 15:47 ` [PATCH 4/4] net: sfp: add mode quirk for GPON module Ubiquiti U-Fiber Instant Pali Rohár
2021-01-06 15:37 ` [PATCH v2 0/3] net: sfp: add support for GPON RTL8672/RTL9601C and Ubiquiti U-Fiber Pali Rohár
2021-01-06 15:37   ` [PATCH v2 1/3] net: sfp: add workaround for Realtek RTL8672 and RTL9601C chips Pali Rohár
2021-01-07  2:02     ` Andrew Lunn
2021-01-07  9:08       ` Pali Rohár
2021-01-07 17:19     ` Andrew Lunn
2021-01-07 17:40       ` Russell King - ARM Linux admin
2021-01-07 19:18         ` Pali Rohár
2021-01-07 19:17       ` Pali Rohár
2021-01-07 19:45       ` Russell King - ARM Linux admin
2021-01-07 20:21         ` Marek Behún
2021-01-08  0:49           ` Pali Rohár
2021-01-06 15:37   ` [PATCH v2 2/3] net: sfp: assume that LOS is not implemented if both LOS normal and inverted is set Pali Rohár
2021-01-07 16:54     ` Andrew Lunn
2021-01-09 15:46       ` Russell King - ARM Linux admin
2021-01-09 15:54         ` Andrew Lunn
2021-01-09 16:27           ` Russell King - ARM Linux admin
2021-01-09 19:14         ` Pali Rohár
2021-01-09 23:19           ` Russell King - ARM Linux admin
2021-01-09 23:50             ` Pali Rohár
2021-01-06 15:37   ` [PATCH v2 3/3] net: sfp: add mode quirk for GPON module Ubiquiti U-Fiber Instant Pali Rohár
2021-01-07 16:51     ` Andrew Lunn
2021-01-11 11:39 ` [PATCH v3 0/2] net: sfp: add support for GPON RTL8672/RTL9601C and Ubiquiti U-Fiber Pali Rohár
2021-01-11 11:39   ` [PATCH v3 1/2] net: sfp: add workaround for Realtek RTL8672 and RTL9601C chips Pali Rohár
2021-01-11 15:28     ` Marek Behún
2021-01-11 11:39   ` [PATCH v3 2/2] net: sfp: add mode quirk for GPON module Ubiquiti U-Fiber Instant Pali Rohár
2021-01-11 15:32     ` Marek Behún
2021-01-12 13:33   ` [PATCH v3 0/2] net: sfp: add support for GPON RTL8672/RTL9601C and Ubiquiti U-Fiber Pali Rohár
2021-01-18  9:34   ` Pali Rohár
2021-01-25 14:09     ` Pali Rohár
2021-01-25 14:16       ` Russell King - ARM Linux admin
2021-01-25 14:23         ` Pali Rohár
2021-01-25 14:42           ` Russell King - ARM Linux admin
2021-01-25 14:47             ` Pali Rohár
2021-01-25 15:41               ` Andrew Lunn
2021-01-25 15:02 ` [PATCH v4 " Pali Rohár
2021-01-25 15:02   ` [PATCH v4 1/2] net: sfp: add workaround for Realtek RTL8672 and RTL9601C chips Pali Rohár
2021-01-25 15:02   ` [PATCH v4 2/2] net: sfp: add mode quirk for GPON module Ubiquiti U-Fiber Instant Pali Rohár
2021-01-28 21:50   ` [PATCH v4 0/2] net: sfp: add support for GPON RTL8672/RTL9601C and Ubiquiti U-Fiber patchwork-bot+netdevbpf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201230154755.14746-2-pali@kernel.org \
    --to=pali@kernel.org \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=hkallweit1@gmail.com \
    --cc=kabel@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).