123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- From d585c55b9f70cf9e8c66820d7efe7130c683f19e Mon Sep 17 00:00:00 2001
- From: Antoine Tenart <[email protected]>
- 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 <[email protected]>
- ---
- 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
- @@ -54,6 +54,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
- @@ -19,6 +19,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
- @@ -61,6 +61,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,8 @@ 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);
- +bool i2c_mii_valid_phy_id(int phy_id);
- +unsigned int i2c_mii_phy_addr(int phy_id);
-
- #endif
- --- a/drivers/net/mdio/mdio-i2c.c
- +++ b/drivers/net/mdio/mdio-i2c.c
- @@ -18,12 +18,12 @@
- * 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)
- +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)
- +unsigned int i2c_mii_phy_addr(int phy_id)
- {
- return phy_id + 0x40;
- }
|