diff options
Diffstat (limited to 'target/linux/realtek/patches-5.10/711-net-phy-add-an-MDIO-SMBus-library.patch')
-rw-r--r-- | target/linux/realtek/patches-5.10/711-net-phy-add-an-MDIO-SMBus-library.patch | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/target/linux/realtek/patches-5.10/711-net-phy-add-an-MDIO-SMBus-library.patch b/target/linux/realtek/patches-5.10/711-net-phy-add-an-MDIO-SMBus-library.patch new file mode 100644 index 0000000000..5e1053ca6c --- /dev/null +++ b/target/linux/realtek/patches-5.10/711-net-phy-add-an-MDIO-SMBus-library.patch @@ -0,0 +1,168 @@ +From d585c55b9f70cf9e8c66820d7efe7130c683f19e Mon Sep 17 00:00:00 2001 +From: Antoine Tenart <antoine.tenart@bootlin.com> +Date: Fri, 21 Feb 2020 11:51:27 +0100 +Subject: [PATCH 2/3] net: phy: add an MDIO SMBus library + +Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com> +--- + drivers/net/mdio/Kconfig | 11 +++++++ + drivers/net/mdio/Makefile | 1 + + drivers/net/mdio/mdio-smbus.c | 62 +++++++++++++++++++++++++++++++++++ + drivers/net/phy/Kconfig | 1 + + include/linux/mdio/mdio-i2c.h | 16 +++++++++ + 5 files changed, 91 insertions(+) + create mode 100644 drivers/net/mdio/mdio-smbus.c + +--- a/drivers/net/mdio/Kconfig ++++ b/drivers/net/mdio/Kconfig +@@ -40,6 +40,17 @@ config MDIO_SUN4I + interface units of the Allwinner SoC that have an EMAC (A10, + A12, A10s, etc.) + ++config MDIO_SMBUS ++ tristate ++ depends on I2C_SMBUS ++ help ++ Support SMBus based PHYs. This provides a MDIO bus bridged ++ to SMBus to allow PHYs connected in SMBus mode to be accessed ++ using the existing infrastructure. ++ ++ This is library mode. ++ ++ + config MDIO_XGENE + tristate "APM X-Gene SoC MDIO bus controller" + depends on ARCH_XGENE || COMPILE_TEST +--- a/drivers/net/mdio/Makefile ++++ b/drivers/net/mdio/Makefile +@@ -17,6 +17,7 @@ obj-$(CONFIG_MDIO_MOXART) += mdio-moxar + obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o + obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o + obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o ++obj-$(CONFIG_MDIO_SMBUS) += mdio-smbus.o + obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o + obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o + obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o +--- /dev/null ++++ b/drivers/net/mdio/mdio-smbus.c +@@ -0,0 +1,62 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * MDIO SMBus bridge ++ * ++ * Copyright (C) 2020 Antoine Tenart ++ * ++ * Network PHYs can appear on SMBus when they are part of SFP modules. ++ */ ++#include <linux/i2c.h> ++#include <linux/phy.h> ++#include <linux/mdio/mdio-i2c.h> ++ ++static int smbus_mii_read(struct mii_bus *mii, int phy_id, int reg) ++{ ++ struct i2c_adapter *i2c = mii->priv; ++ union i2c_smbus_data data; ++ int ret; ++ ++ ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0, I2C_SMBUS_READ, ++ reg, I2C_SMBUS_BYTE_DATA, &data); ++ if (ret < 0) ++ return 0xff; ++ ++ return data.byte; ++} ++ ++static int smbus_mii_write(struct mii_bus *mii, int phy_id, int reg, u16 val) ++{ ++ struct i2c_adapter *i2c = mii->priv; ++ union i2c_smbus_data data; ++ int ret; ++ ++ data.byte = val; ++ ++ ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0, I2C_SMBUS_WRITE, ++ reg, I2C_SMBUS_BYTE_DATA, &data); ++ return ret < 0 ? ret : 0; ++} ++ ++struct mii_bus *mdio_smbus_alloc(struct device *parent, struct i2c_adapter *i2c) ++{ ++ struct mii_bus *mii; ++ ++ if (!i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA)) ++ return ERR_PTR(-EINVAL); ++ ++ mii = mdiobus_alloc(); ++ if (!mii) ++ return ERR_PTR(-ENOMEM); ++ ++ snprintf(mii->id, MII_BUS_ID_SIZE, "smbus:%s", dev_name(parent)); ++ mii->parent = parent; ++ mii->read = smbus_mii_read; ++ mii->write = smbus_mii_write; ++ mii->priv = i2c; ++ ++ return mii; ++} ++ ++MODULE_AUTHOR("Antoine Tenart"); ++MODULE_DESCRIPTION("MDIO SMBus bridge library"); ++MODULE_LICENSE("GPL"); +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -60,6 +60,7 @@ config SFP + depends on I2C && PHYLINK + depends on HWMON || HWMON=n + select MDIO_I2C ++ select MDIO_SMBUS + + comment "Switch configuration API + drivers" + +--- a/include/linux/mdio/mdio-i2c.h ++++ b/include/linux/mdio/mdio-i2c.h +@@ -12,5 +12,21 @@ struct i2c_adapter; + struct mii_bus; + + struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c); ++struct mii_bus *mdio_smbus_alloc(struct device *parent, struct i2c_adapter *i2c); ++ ++/* ++ * I2C bus addresses 0x50 and 0x51 are normally an EEPROM, which is ++ * specified to be present in SFP modules. These correspond with PHY ++ * addresses 16 and 17. Disallow access to these "phy" addresses. ++ */ ++static bool i2c_mii_valid_phy_id(int phy_id) ++{ ++ return phy_id != 0x10 && phy_id != 0x11; ++} ++ ++static unsigned int i2c_mii_phy_addr(int phy_id) ++{ ++ return phy_id + 0x40; ++} + + #endif +--- a/drivers/net/mdio/mdio-i2c.c ++++ b/drivers/net/mdio/mdio-i2c.c +@@ -13,21 +13,6 @@ + #include <linux/mdio/mdio-i2c.h> + #include <linux/phy.h> + +-/* +- * I2C bus addresses 0x50 and 0x51 are normally an EEPROM, which is +- * specified to be present in SFP modules. These correspond with PHY +- * addresses 16 and 17. Disallow access to these "phy" addresses. +- */ +-static bool i2c_mii_valid_phy_id(int phy_id) +-{ +- return phy_id != 0x10 && phy_id != 0x11; +-} +- +-static unsigned int i2c_mii_phy_addr(int phy_id) +-{ +- return phy_id + 0x40; +-} +- + static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg) + { + struct i2c_adapter *i2c = bus->priv; |