--- /dev/null
+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
+@@ -556,32 +556,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;
+ }