aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/realtek/patches-5.10/712-net-phy-sfp-add-support-for-SMBus.patch
diff options
context:
space:
mode:
authorBirger Koblitz <git@birger-koblitz.de>2022-01-16 11:18:38 +0100
committerDaniel Golle <daniel@makrotopia.org>2022-02-17 15:21:46 +0000
commit45053b507c66d93c6db70e25f867e19a3af9bad4 (patch)
tree0881c12757650b55bc5591ef6f362f2b8476e69b /target/linux/realtek/patches-5.10/712-net-phy-sfp-add-support-for-SMBus.patch
parentf4bdb7fdccdfe3fa382abe77f72a16c2f2e6add0 (diff)
downloadupstream-45053b507c66d93c6db70e25f867e19a3af9bad4.tar.gz
upstream-45053b507c66d93c6db70e25f867e19a3af9bad4.tar.bz2
upstream-45053b507c66d93c6db70e25f867e19a3af9bad4.zip
realtek: Add support for SFP EEPROM-access over SMBus
The EEPROMs on SFP modules are compatible both to I2C as well as SMBus. However, the kernel so far only supports I2C access. We add SMBus access routines, because the I2C driver for the RTL9300 HW only supports that protocol. At the same time we disable I2C access to PHYs on SFP modules as otherwise detection of any SFP module would fail. This is not in any way problematic at this point in time since the RTL93XX platform so far does not support PHYs on SFP modules. The patches are copied and rebased version of: https://bootlin.com/blog/sfp-modules-on-a-board-running-linux/ Signed-off-by: Daniel Golle <daniel@makrotopia.org> Signed-off-by: Birger Koblitz <git@birger-koblitz.de>
Diffstat (limited to 'target/linux/realtek/patches-5.10/712-net-phy-sfp-add-support-for-SMBus.patch')
-rw-r--r--target/linux/realtek/patches-5.10/712-net-phy-sfp-add-support-for-SMBus.patch99
1 files changed, 99 insertions, 0 deletions
diff --git a/target/linux/realtek/patches-5.10/712-net-phy-sfp-add-support-for-SMBus.patch b/target/linux/realtek/patches-5.10/712-net-phy-sfp-add-support-for-SMBus.patch
new file mode 100644
index 0000000000..8eef1885ab
--- /dev/null
+++ b/target/linux/realtek/patches-5.10/712-net-phy-sfp-add-support-for-SMBus.patch
@@ -0,0 +1,99 @@
+From 3cb0bde365d913c484d20224367a54a0eac780a7 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart@bootlin.com>
+Date: Fri, 21 Feb 2020 11:55:29 +0100
+Subject: [PATCH 3/3] net: phy: sfp: add support for SMBus
+
+Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
+---
+ drivers/net/phy/sfp.c | 68 ++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 54 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -412,32 +412,72 @@ static int sfp_i2c_write(struct sfp *sfp
+ return ret == ARRAY_SIZE(msgs) ? len : 0;
+ }
+
++static int sfp_smbus_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
++ size_t len)
++{
++ u8 bus_addr = a2 ? 0x51 : 0x50, *val = buf;
++
++ bus_addr -= 0x40;
++
++ while (len > 0) {
++ *val = sfp->i2c_mii->read(sfp->i2c_mii, bus_addr, dev_addr);
++
++ val++;
++ dev_addr++;
++ len--;
++ }
++
++ return val - (u8 *)buf;
++}
++
++static int sfp_smbus_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
++ size_t len)
++{
++ u8 bus_addr = a2 ? 0x51 : 0x50;
++ u16 val;
++
++ memcpy(&val, buf, len);
++
++ return sfp->i2c_mii->write(sfp->i2c_mii, bus_addr, dev_addr, val);
++}
++
+ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
+ {
+- struct mii_bus *i2c_mii;
++ struct mii_bus *mii;
+ int ret;
+
+- if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
+- return -EINVAL;
+-
+ sfp->i2c = i2c;
+- sfp->read = sfp_i2c_read;
+- sfp->write = sfp_i2c_write;
+
+- i2c_mii = mdio_i2c_alloc(sfp->dev, i2c);
+- if (IS_ERR(i2c_mii))
+- return PTR_ERR(i2c_mii);
++ if (i2c_check_functionality(i2c, I2C_FUNC_I2C)) {
++ sfp->read = sfp_i2c_read;
++ sfp->write = sfp_i2c_write;
++
++ mii = mdio_i2c_alloc(sfp->dev, i2c);
++ if (IS_ERR(mii))
++ return PTR_ERR(mii);
++
++ mii->name = "SFP I2C Bus";
++ } else if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA)) {
++ sfp->read = sfp_smbus_read;
++ sfp->write = sfp_smbus_write;
++
++ mii = mdio_smbus_alloc(sfp->dev, i2c);
++ if (IS_ERR(mii))
++ return PTR_ERR(mii);
+
+- i2c_mii->name = "SFP I2C Bus";
+- i2c_mii->phy_mask = ~0;
++ mii->name = "SFP SMBus";
++ } else {
++ return -EINVAL;
++ }
+
+- ret = mdiobus_register(i2c_mii);
++ mii->phy_mask = ~0;
++ ret = mdiobus_register(mii);
+ if (ret < 0) {
+- mdiobus_free(i2c_mii);
++ mdiobus_free(mii);
+ return ret;
+ }
+
+- sfp->i2c_mii = i2c_mii;
++ sfp->i2c_mii = mii;
+
+ return 0;
+ }