aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/backport-5.4/852-v5.10-0002-net-sfp-add-workaround-for-Realtek-RTL8672-and-RTL96.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/backport-5.4/852-v5.10-0002-net-sfp-add-workaround-for-Realtek-RTL8672-and-RTL96.patch')
-rw-r--r--target/linux/generic/backport-5.4/852-v5.10-0002-net-sfp-add-workaround-for-Realtek-RTL8672-and-RTL96.patch211
1 files changed, 0 insertions, 211 deletions
diff --git a/target/linux/generic/backport-5.4/852-v5.10-0002-net-sfp-add-workaround-for-Realtek-RTL8672-and-RTL96.patch b/target/linux/generic/backport-5.4/852-v5.10-0002-net-sfp-add-workaround-for-Realtek-RTL8672-and-RTL96.patch
deleted file mode 100644
index 27ae97cee7..0000000000
--- a/target/linux/generic/backport-5.4/852-v5.10-0002-net-sfp-add-workaround-for-Realtek-RTL8672-and-RTL96.patch
+++ /dev/null
@@ -1,211 +0,0 @@
-From 426c6cbc409cbda9ab1a9dbf15d3c2ef947eb8c1 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:27 +0100
-Subject: [PATCH] net: sfp: add workaround for Realtek RTL8672 and RTL9601C
- chips
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The workaround for VSOL V2801F brand based GPON SFP modules added in commit
-0d035bed2a4a ("net: sfp: VSOL V2801F / CarlitoxxPro CPGOS03-0490 v2.0
-workaround") works only for IDs added explicitly to the list. Since there
-are rebranded modules where OEM vendors put different strings into the
-vendor name field, we cannot base workaround on IDs only.
-
-Moreover the issue which the above mentioned commit tried to work around is
-generic not only to VSOL based modules, but rather to all GPON modules
-based on Realtek RTL8672 and RTL9601C chips.
-
-These include at least the 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
-
-These Realtek chips have broken EEPROM emulator which for N-byte read
-operation returns just the first byte of EEPROM data, followed by N-1
-zeros.
-
-Introduce a new function, sfp_id_needs_byte_io(), which detects SFP modules
-with broken EEPROM emulator based on N-1 zeros and switch to 1 byte EEPROM
-reading operation.
-
-Function sfp_i2c_read() now always uses single byte reading when it is
-required and when function sfp_hwmon_probe() detects single byte access,
-it disables registration of hwmon device, because in this case we cannot
-reliably and atomically read 2 bytes as is required by the standard for
-retrieving values from diagnostic area.
-
-(These Realtek chips are broken in a way that violates SFP standards for
-diagnostic interface. Kernel in this case simply cannot do anything less
-of skipping registration of the hwmon interface.)
-
-This patch fixes reading of EEPROM content from SFP modules based on
-Realtek RTL8672 and RTL9601C chips. Diagnostic interface of EEPROM stays
-broken and cannot be fixed.
-
-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>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/sfp.c | 100 ++++++++++++++++++++++++++++--------------
- 1 file changed, 67 insertions(+), 33 deletions(-)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -306,19 +306,11 @@ static int sfp_i2c_read(struct sfp *sfp,
- 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;
-@@ -1245,6 +1237,20 @@ static void sfp_hwmon_probe(struct work_
- struct sfp *sfp = container_of(work, struct sfp, hwmon_probe.work);
- int err, i;
-
-+ /* hwmon interface needs to access 16bit registers in atomic way to
-+ * guarantee coherency of the diagnostic monitoring data. If it is not
-+ * possible to guarantee coherency because EEPROM is broken in such way
-+ * that does not support atomic 16bit read operation then we have to
-+ * skip registration of hwmon device.
-+ */
-+ if (sfp->i2c_block_size < 2) {
-+ dev_info(sfp->dev,
-+ "skipping hwmon device registration due to broken EEPROM\n");
-+ dev_info(sfp->dev,
-+ "diagnostic EEPROM area cannot be read atomically to guarantee data coherency\n");
-+ return;
-+ }
-+
- err = sfp_read(sfp, true, 0, &sfp->diag, sizeof(sfp->diag));
- if (err < 0) {
- if (sfp->hwmon_tries--) {
-@@ -1579,26 +1585,30 @@ static int sfp_sm_mod_hpower(struct sfp
- 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', min(block_size - 1, len - i)))
-+ return false;
-+ }
-+ return true;
- }
-
- static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
-@@ -1609,11 +1619,11 @@ static int sfp_sm_mod_probe(struct sfp *
- 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.
-+ /* Some SFP modules and also some Linux I2C drivers do not like reads
-+ * longer than 16 bytes, so read the EEPROM in chunks of 16 bytes 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) {
-@@ -1627,6 +1637,33 @@ static int sfp_sm_mod_probe(struct sfp *
- return -EAGAIN;
- }
-
-+ /* Some SFP modules (e.g. Nokia 3FE46541AA) lock up if read from
-+ * address 0x51 is just one byte at a time. Also SFF-8472 requires
-+ * that EEPROM supports atomic 16bit read operation for diagnostic
-+ * fields, so do not switch to one byte reading at a time unless it
-+ * is really required and we have no other option.
-+ */
-+ 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.
-@@ -1650,9 +1687,6 @@ static int sfp_sm_mod_probe(struct sfp *
- }
- }
-
-- /* 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)