realtek: 6.18: adapt SFP SMBus patches

Adapt our downstream patches for SMBus SFP functionality to kernel 6.18.
Upstream gained support for SMBus byte access on SFP and a patch to
extend that to word and block access is pending.

These downstream patches aren't acceptable for upstream and will need to
be adapted. However, keep them for now to maintain functionality.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21181
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Jonas Jelonek 2026-01-21 23:26:28 +00:00 committed by Robert Marko
parent c3d998f147
commit 56a5e37442
2 changed files with 6 additions and 73 deletions

View File

@ -15,7 +15,7 @@ Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
--- a/drivers/net/mdio/Kconfig
+++ b/drivers/net/mdio/Kconfig
@@ -54,6 +54,17 @@ config MDIO_SUN4I
@@ -37,6 +37,17 @@ config MDIO_SUN4I
interface units of the Allwinner SoC that have an EMAC (A10,
A12, A10s, etc.)
@ -35,9 +35,9 @@ Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
depends on ARCH_XGENE || COMPILE_TEST
--- a/drivers/net/mdio/Makefile
+++ b/drivers/net/mdio/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-ms
obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o
@@ -22,6 +22,7 @@ obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
obj-$(CONFIG_MDIO_REALTEK_RTL9300) += mdio-realtek-rtl9300.o
obj-$(CONFIG_MDIO_REGMAP) += mdio-regmap.o
+obj-$(CONFIG_MDIO_SMBUS) += mdio-smbus.o
obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
@ -389,7 +389,7 @@ Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
+MODULE_LICENSE("GPL");
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -76,6 +76,7 @@ config SFP
@@ -81,6 +81,7 @@ config SFP
depends on I2C && PHYLINK
depends on HWMON || HWMON=n
select MDIO_I2C

View File

@ -10,74 +10,7 @@ Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -729,10 +729,64 @@ 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;
+ union i2c_smbus_data data;
+ int ret;
+
+ bus_addr -= 0x40;
+
+ while (len > 0) {
+ ret = i2c_smbus_xfer(sfp->i2c, i2c_mii_phy_addr(bus_addr), 0,
+ I2C_SMBUS_READ, dev_addr,
+ I2C_SMBUS_BYTE_DATA, &data);
+ if (ret)
+ return ret;
+ *val++ = data.byte;
+ 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, *val = buf;
+ union i2c_smbus_data data;
+ int ret;
+
+ bus_addr -= 0x40;
+
+ while (len > 0) {
+ data.byte = *val++;
+ ret = i2c_smbus_xfer(sfp->i2c, i2c_mii_phy_addr(bus_addr), 0,
+ I2C_SMBUS_WRITE, dev_addr,
+ I2C_SMBUS_BYTE_DATA, &data);
+ if (ret)
+ return ret;
+ dev_addr++;
+ len--;
+ }
+
+ return val - (u8 *)buf;
+}
+
static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
{
- if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
- return -EINVAL;
+ if (!i2c_check_functionality(i2c, I2C_FUNC_I2C)) {
+ if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ sfp->i2c = i2c;
+ sfp->read = sfp_smbus_read;
+ sfp->write = sfp_smbus_write;
+
+ return 0;
+ } else
+ return -EINVAL;
+ }
sfp->i2c = i2c;
sfp->read = sfp_i2c_read;
@@ -764,6 +818,29 @@ static int sfp_i2c_mdiobus_create(struct
@@ -826,6 +826,29 @@ static int sfp_i2c_mdiobus_create(struct
return 0;
}
@ -107,7 +40,7 @@ Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
{
mdiobus_unregister(sfp->i2c_mii);
@@ -1938,9 +2015,15 @@ static void sfp_sm_fault(struct sfp *sfp
@@ -2000,9 +2023,15 @@ static void sfp_sm_fault(struct sfp *sfp
static int sfp_sm_add_mdio_bus(struct sfp *sfp)
{