* [PATCH v3 net-next 0/3] update seville to use shared MDIO driver
@ 2021-11-29 1:57 Colin Foster
2021-11-29 1:57 ` [PATCH v3 net-next 1/3] net: mdio: mscc-miim: convert to a regmap implementation Colin Foster
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Colin Foster @ 2021-11-29 1:57 UTC (permalink / raw)
To: linux-kernel, netdev
Cc: Vladimir Oltean, Claudiu Manoil, Alexandre Belloni,
UNGLinuxDriver, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S. Miller, Jakub Kicinski, Heiner Kallweit, Russell King
This patch set exposes and utilizes the shared MDIO bus in
drivers/net/mdio/msio-mscc-miim.c
v3:
* Fix errors using uninitilized "dev" inside the probe function.
* Remove phy_regmap from the setup function, since it currently
isn't used
* Remove GCB_PHY_PHY_CFG definition from ocelot.h - it isn't used
yet...
v2:
* Error handling (thanks Andrew Lunn)
* Fix logic errors calling mscc_miim_setup during patch 1/3 (thanks
Jakub Kicinski)
* Remove unnecessary felix_mdio file (thanks Vladimir Oltean)
* Pass NULL to mscc_miim_setup instead of GCB_PHY_PHY_CFG, since the
phy reset isn't handled at that point of the Seville driver (patch
3/3)
Colin Foster (3):
net: mdio: mscc-miim: convert to a regmap implementation
net: dsa: ocelot: seville: utilize of_mdiobus_register
net: dsa: ocelot: felix: utilize shared mscc-miim driver for indirect
MDIO access
drivers/net/dsa/ocelot/Kconfig | 1 +
drivers/net/dsa/ocelot/seville_vsc9953.c | 103 ++-----------
drivers/net/mdio/mdio-mscc-miim.c | 181 +++++++++++++++++------
include/linux/mdio/mdio-mscc-miim.h | 19 +++
4 files changed, 168 insertions(+), 136 deletions(-)
create mode 100644 include/linux/mdio/mdio-mscc-miim.h
--
2.25.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 net-next 1/3] net: mdio: mscc-miim: convert to a regmap implementation
2021-11-29 1:57 [PATCH v3 net-next 0/3] update seville to use shared MDIO driver Colin Foster
@ 2021-11-29 1:57 ` Colin Foster
2021-11-29 1:57 ` [PATCH v3 net-next 2/3] net: dsa: ocelot: seville: utilize of_mdiobus_register Colin Foster
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Colin Foster @ 2021-11-29 1:57 UTC (permalink / raw)
To: linux-kernel, netdev
Cc: Vladimir Oltean, Claudiu Manoil, Alexandre Belloni,
UNGLinuxDriver, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S. Miller, Jakub Kicinski, Heiner Kallweit, Russell King
Utilize regmap instead of __iomem to perform indirect mdio access. This
will allow for custom regmaps to be used by way of the mscc_miim_setup
function.
Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/mdio/mdio-mscc-miim.c | 163 ++++++++++++++++++++++--------
1 file changed, 121 insertions(+), 42 deletions(-)
diff --git a/drivers/net/mdio/mdio-mscc-miim.c b/drivers/net/mdio/mdio-mscc-miim.c
index 17f98f609ec8..e016b32ad208 100644
--- a/drivers/net/mdio/mdio-mscc-miim.c
+++ b/drivers/net/mdio/mdio-mscc-miim.c
@@ -14,6 +14,7 @@
#include <linux/of_mdio.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
+#include <linux/regmap.h>
#define MSCC_MIIM_REG_STATUS 0x0
#define MSCC_MIIM_STATUS_STAT_PENDING BIT(2)
@@ -35,37 +36,49 @@
#define MSCC_PHY_REG_PHY_STATUS 0x4
struct mscc_miim_dev {
- void __iomem *regs;
- void __iomem *phy_regs;
+ struct regmap *regs;
+ struct regmap *phy_regs;
};
/* When high resolution timers aren't built-in: we can't use usleep_range() as
* we would sleep way too long. Use udelay() instead.
*/
-#define mscc_readl_poll_timeout(addr, val, cond, delay_us, timeout_us) \
-({ \
- if (!IS_ENABLED(CONFIG_HIGH_RES_TIMERS)) \
- readl_poll_timeout_atomic(addr, val, cond, delay_us, \
- timeout_us); \
- readl_poll_timeout(addr, val, cond, delay_us, timeout_us); \
+#define mscc_readx_poll_timeout(op, addr, val, cond, delay_us, timeout_us)\
+({ \
+ if (!IS_ENABLED(CONFIG_HIGH_RES_TIMERS)) \
+ readx_poll_timeout_atomic(op, addr, val, cond, delay_us, \
+ timeout_us); \
+ readx_poll_timeout(op, addr, val, cond, delay_us, timeout_us); \
})
-static int mscc_miim_wait_ready(struct mii_bus *bus)
+static int mscc_miim_status(struct mii_bus *bus)
{
struct mscc_miim_dev *miim = bus->priv;
+ int val, ret;
+
+ ret = regmap_read(miim->regs, MSCC_MIIM_REG_STATUS, &val);
+ if (ret < 0) {
+ WARN_ONCE(1, "mscc miim status read error %d\n", ret);
+ return ret;
+ }
+
+ return val;
+}
+
+static int mscc_miim_wait_ready(struct mii_bus *bus)
+{
u32 val;
- return mscc_readl_poll_timeout(miim->regs + MSCC_MIIM_REG_STATUS, val,
+ return mscc_readx_poll_timeout(mscc_miim_status, bus, val,
!(val & MSCC_MIIM_STATUS_STAT_BUSY), 50,
10000);
}
static int mscc_miim_wait_pending(struct mii_bus *bus)
{
- struct mscc_miim_dev *miim = bus->priv;
u32 val;
- return mscc_readl_poll_timeout(miim->regs + MSCC_MIIM_REG_STATUS, val,
+ return mscc_readx_poll_timeout(mscc_miim_status, bus, val,
!(val & MSCC_MIIM_STATUS_STAT_PENDING),
50, 10000);
}
@@ -80,15 +93,27 @@ static int mscc_miim_read(struct mii_bus *bus, int mii_id, int regnum)
if (ret)
goto out;
- writel(MSCC_MIIM_CMD_VLD | (mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
- (regnum << MSCC_MIIM_CMD_REGAD_SHIFT) | MSCC_MIIM_CMD_OPR_READ,
- miim->regs + MSCC_MIIM_REG_CMD);
+ ret = regmap_write(miim->regs, MSCC_MIIM_REG_CMD, MSCC_MIIM_CMD_VLD |
+ (mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
+ (regnum << MSCC_MIIM_CMD_REGAD_SHIFT) |
+ MSCC_MIIM_CMD_OPR_READ);
+
+ if (ret < 0) {
+ WARN_ONCE(1, "mscc miim write cmd reg error %d\n", ret);
+ goto out;
+ }
ret = mscc_miim_wait_ready(bus);
if (ret)
goto out;
- val = readl(miim->regs + MSCC_MIIM_REG_DATA);
+ ret = regmap_read(miim->regs, MSCC_MIIM_REG_DATA, &val);
+
+ if (ret < 0) {
+ WARN_ONCE(1, "mscc miim read data reg error %d\n", ret);
+ goto out;
+ }
+
if (val & MSCC_MIIM_DATA_ERROR) {
ret = -EIO;
goto out;
@@ -109,12 +134,14 @@ static int mscc_miim_write(struct mii_bus *bus, int mii_id,
if (ret < 0)
goto out;
- writel(MSCC_MIIM_CMD_VLD | (mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
- (regnum << MSCC_MIIM_CMD_REGAD_SHIFT) |
- (value << MSCC_MIIM_CMD_WRDATA_SHIFT) |
- MSCC_MIIM_CMD_OPR_WRITE,
- miim->regs + MSCC_MIIM_REG_CMD);
+ ret = regmap_write(miim->regs, MSCC_MIIM_REG_CMD, MSCC_MIIM_CMD_VLD |
+ (mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
+ (regnum << MSCC_MIIM_CMD_REGAD_SHIFT) |
+ (value << MSCC_MIIM_CMD_WRDATA_SHIFT) |
+ MSCC_MIIM_CMD_OPR_WRITE);
+ if (ret < 0)
+ WARN_ONCE(1, "mscc miim write error %d\n", ret);
out:
return ret;
}
@@ -122,24 +149,40 @@ static int mscc_miim_write(struct mii_bus *bus, int mii_id,
static int mscc_miim_reset(struct mii_bus *bus)
{
struct mscc_miim_dev *miim = bus->priv;
+ int ret;
if (miim->phy_regs) {
- writel(0, miim->phy_regs + MSCC_PHY_REG_PHY_CFG);
- writel(0x1ff, miim->phy_regs + MSCC_PHY_REG_PHY_CFG);
+ ret = regmap_write(miim->phy_regs, MSCC_PHY_REG_PHY_CFG, 0);
+ if (ret < 0) {
+ WARN_ONCE(1, "mscc reset set error %d\n", ret);
+ return ret;
+ }
+
+ ret = regmap_write(miim->phy_regs, MSCC_PHY_REG_PHY_CFG, 0x1ff);
+ if (ret < 0) {
+ WARN_ONCE(1, "mscc reset clear error %d\n", ret);
+ return ret;
+ }
+
mdelay(500);
}
return 0;
}
-static int mscc_miim_probe(struct platform_device *pdev)
+static const struct regmap_config mscc_miim_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
+static int mscc_miim_setup(struct device *dev, struct mii_bus **pbus,
+ struct regmap *mii_regmap)
{
- struct mscc_miim_dev *dev;
- struct resource *res;
+ struct mscc_miim_dev *miim;
struct mii_bus *bus;
- int ret;
- bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*dev));
+ bus = devm_mdiobus_alloc_size(dev, sizeof(*miim));
if (!bus)
return -ENOMEM;
@@ -147,26 +190,62 @@ static int mscc_miim_probe(struct platform_device *pdev)
bus->read = mscc_miim_read;
bus->write = mscc_miim_write;
bus->reset = mscc_miim_reset;
- snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(&pdev->dev));
- bus->parent = &pdev->dev;
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(dev));
+ bus->parent = dev;
+
+ miim = bus->priv;
+
+ *pbus = bus;
+
+ miim->regs = mii_regmap;
+
+ return 0;
+}
+
+static int mscc_miim_probe(struct platform_device *pdev)
+{
+ struct regmap *mii_regmap, *phy_regmap;
+ void __iomem *regs, *phy_regs;
+ struct mscc_miim_dev *miim;
+ struct mii_bus *bus;
+ int ret;
- dev = bus->priv;
- dev->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
- if (IS_ERR(dev->regs)) {
+ regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+ if (IS_ERR(regs)) {
dev_err(&pdev->dev, "Unable to map MIIM registers\n");
- return PTR_ERR(dev->regs);
+ return PTR_ERR(regs);
}
- /* This resource is optional */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (res) {
- dev->phy_regs = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(dev->phy_regs)) {
- dev_err(&pdev->dev, "Unable to map internal phy registers\n");
- return PTR_ERR(dev->phy_regs);
- }
+ mii_regmap = devm_regmap_init_mmio(&pdev->dev, regs,
+ &mscc_miim_regmap_config);
+
+ if (IS_ERR(mii_regmap)) {
+ dev_err(&pdev->dev, "Unable to create MIIM regmap\n");
+ return PTR_ERR(mii_regmap);
}
+ phy_regs = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(phy_regs)) {
+ dev_err(&pdev->dev, "Unable to map internal phy registers\n");
+ return PTR_ERR(phy_regs);
+ }
+
+ phy_regmap = devm_regmap_init_mmio(&pdev->dev, phy_regs,
+ &mscc_miim_regmap_config);
+ if (IS_ERR(phy_regmap)) {
+ dev_err(&pdev->dev, "Unable to create phy register regmap\n");
+ return PTR_ERR(phy_regmap);
+ }
+
+ ret = mscc_miim_setup(&pdev->dev, &bus, mii_regmap);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Unable to setup the MDIO bus\n");
+ return ret;
+ }
+
+ miim = bus->priv;
+ miim->phy_regs = phy_regmap;
+
ret = of_mdiobus_register(bus, pdev->dev.of_node);
if (ret < 0) {
dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
--
2.25.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 net-next 2/3] net: dsa: ocelot: seville: utilize of_mdiobus_register
2021-11-29 1:57 [PATCH v3 net-next 0/3] update seville to use shared MDIO driver Colin Foster
2021-11-29 1:57 ` [PATCH v3 net-next 1/3] net: mdio: mscc-miim: convert to a regmap implementation Colin Foster
@ 2021-11-29 1:57 ` Colin Foster
2021-11-29 1:57 ` [PATCH v3 net-next 3/3] net: dsa: ocelot: felix: utilize shared mscc-miim driver for indirect MDIO access Colin Foster
2021-11-29 13:10 ` [PATCH v3 net-next 0/3] update seville to use shared MDIO driver patchwork-bot+netdevbpf
3 siblings, 0 replies; 5+ messages in thread
From: Colin Foster @ 2021-11-29 1:57 UTC (permalink / raw)
To: linux-kernel, netdev
Cc: Vladimir Oltean, Claudiu Manoil, Alexandre Belloni,
UNGLinuxDriver, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S. Miller, Jakub Kicinski, Heiner Kallweit, Russell King
Switch seville to use of_mdiobus_register(bus, NULL) instead of just
mdiobus_register. This code is about to be pulled into a separate module
that can optionally define ports by the device_node.
Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/dsa/ocelot/seville_vsc9953.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
index 899b98193b4a..db124922c374 100644
--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -10,6 +10,7 @@
#include <linux/pcs-lynx.h>
#include <linux/dsa/ocelot.h>
#include <linux/iopoll.h>
+#include <linux/of_mdio.h>
#include "felix.h"
#define MSCC_MIIM_CMD_OPR_WRITE BIT(1)
@@ -1112,7 +1113,7 @@ static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot)
snprintf(bus->id, MII_BUS_ID_SIZE, "%s-imdio", dev_name(dev));
/* Needed in order to initialize the bus mutex lock */
- rc = mdiobus_register(bus);
+ rc = of_mdiobus_register(bus, NULL);
if (rc < 0) {
dev_err(dev, "failed to register MDIO bus\n");
return rc;
--
2.25.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 net-next 3/3] net: dsa: ocelot: felix: utilize shared mscc-miim driver for indirect MDIO access
2021-11-29 1:57 [PATCH v3 net-next 0/3] update seville to use shared MDIO driver Colin Foster
2021-11-29 1:57 ` [PATCH v3 net-next 1/3] net: mdio: mscc-miim: convert to a regmap implementation Colin Foster
2021-11-29 1:57 ` [PATCH v3 net-next 2/3] net: dsa: ocelot: seville: utilize of_mdiobus_register Colin Foster
@ 2021-11-29 1:57 ` Colin Foster
2021-11-29 13:10 ` [PATCH v3 net-next 0/3] update seville to use shared MDIO driver patchwork-bot+netdevbpf
3 siblings, 0 replies; 5+ messages in thread
From: Colin Foster @ 2021-11-29 1:57 UTC (permalink / raw)
To: linux-kernel, netdev
Cc: Vladimir Oltean, Claudiu Manoil, Alexandre Belloni,
UNGLinuxDriver, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S. Miller, Jakub Kicinski, Heiner Kallweit, Russell King
Switch to a shared MDIO access implementation by way of the mdio-mscc-miim
driver.
Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/dsa/ocelot/Kconfig | 1 +
drivers/net/dsa/ocelot/seville_vsc9953.c | 102 ++---------------------
drivers/net/mdio/mdio-mscc-miim.c | 38 ++++++---
include/linux/mdio/mdio-mscc-miim.h | 19 +++++
4 files changed, 56 insertions(+), 104 deletions(-)
create mode 100644 include/linux/mdio/mdio-mscc-miim.h
diff --git a/drivers/net/dsa/ocelot/Kconfig b/drivers/net/dsa/ocelot/Kconfig
index 9948544ba1c4..220b0b027b55 100644
--- a/drivers/net/dsa/ocelot/Kconfig
+++ b/drivers/net/dsa/ocelot/Kconfig
@@ -21,6 +21,7 @@ config NET_DSA_MSCC_SEVILLE
depends on NET_VENDOR_MICROSEMI
depends on HAS_IOMEM
depends on PTP_1588_CLOCK_OPTIONAL
+ select MDIO_MSCC_MIIM
select MSCC_OCELOT_SWITCH_LIB
select NET_DSA_TAG_OCELOT_8021Q
select NET_DSA_TAG_OCELOT
diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
index db124922c374..b9be889016ce 100644
--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -6,19 +6,14 @@
#include <soc/mscc/ocelot_vcap.h>
#include <soc/mscc/ocelot_sys.h>
#include <soc/mscc/ocelot.h>
+#include <linux/mdio/mdio-mscc-miim.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/pcs-lynx.h>
#include <linux/dsa/ocelot.h>
#include <linux/iopoll.h>
-#include <linux/of_mdio.h>
#include "felix.h"
-#define MSCC_MIIM_CMD_OPR_WRITE BIT(1)
-#define MSCC_MIIM_CMD_OPR_READ BIT(2)
-#define MSCC_MIIM_CMD_WRDATA_SHIFT 4
-#define MSCC_MIIM_CMD_REGAD_SHIFT 20
-#define MSCC_MIIM_CMD_PHYAD_SHIFT 25
-#define MSCC_MIIM_CMD_VLD BIT(31)
#define VSC9953_VCAP_POLICER_BASE 11
#define VSC9953_VCAP_POLICER_MAX 31
#define VSC9953_VCAP_POLICER_BASE2 120
@@ -862,7 +857,6 @@ static struct vcap_props vsc9953_vcap_props[] = {
#define VSC9953_INIT_TIMEOUT 50000
#define VSC9953_GCB_RST_SLEEP 100
#define VSC9953_SYS_RAMINIT_SLEEP 80
-#define VCS9953_MII_TIMEOUT 10000
static int vsc9953_gcb_soft_rst_status(struct ocelot *ocelot)
{
@@ -882,82 +876,6 @@ static int vsc9953_sys_ram_init_status(struct ocelot *ocelot)
return val;
}
-static int vsc9953_gcb_miim_pending_status(struct ocelot *ocelot)
-{
- int val;
-
- ocelot_field_read(ocelot, GCB_MIIM_MII_STATUS_PENDING, &val);
-
- return val;
-}
-
-static int vsc9953_gcb_miim_busy_status(struct ocelot *ocelot)
-{
- int val;
-
- ocelot_field_read(ocelot, GCB_MIIM_MII_STATUS_BUSY, &val);
-
- return val;
-}
-
-static int vsc9953_mdio_write(struct mii_bus *bus, int phy_id, int regnum,
- u16 value)
-{
- struct ocelot *ocelot = bus->priv;
- int err, cmd, val;
-
- /* Wait while MIIM controller becomes idle */
- err = readx_poll_timeout(vsc9953_gcb_miim_pending_status, ocelot,
- val, !val, 10, VCS9953_MII_TIMEOUT);
- if (err) {
- dev_err(ocelot->dev, "MDIO write: pending timeout\n");
- goto out;
- }
-
- cmd = MSCC_MIIM_CMD_VLD | (phy_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
- (regnum << MSCC_MIIM_CMD_REGAD_SHIFT) |
- (value << MSCC_MIIM_CMD_WRDATA_SHIFT) |
- MSCC_MIIM_CMD_OPR_WRITE;
-
- ocelot_write(ocelot, cmd, GCB_MIIM_MII_CMD);
-
-out:
- return err;
-}
-
-static int vsc9953_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
-{
- struct ocelot *ocelot = bus->priv;
- int err, cmd, val;
-
- /* Wait until MIIM controller becomes idle */
- err = readx_poll_timeout(vsc9953_gcb_miim_pending_status, ocelot,
- val, !val, 10, VCS9953_MII_TIMEOUT);
- if (err) {
- dev_err(ocelot->dev, "MDIO read: pending timeout\n");
- goto out;
- }
-
- /* Write the MIIM COMMAND register */
- cmd = MSCC_MIIM_CMD_VLD | (phy_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
- (regnum << MSCC_MIIM_CMD_REGAD_SHIFT) | MSCC_MIIM_CMD_OPR_READ;
-
- ocelot_write(ocelot, cmd, GCB_MIIM_MII_CMD);
-
- /* Wait while read operation via the MIIM controller is in progress */
- err = readx_poll_timeout(vsc9953_gcb_miim_busy_status, ocelot,
- val, !val, 10, VCS9953_MII_TIMEOUT);
- if (err) {
- dev_err(ocelot->dev, "MDIO read: busy timeout\n");
- goto out;
- }
-
- val = ocelot_read(ocelot, GCB_MIIM_MII_DATA);
-
- err = val & 0xFFFF;
-out:
- return err;
-}
/* CORE_ENA is in SYS:SYSTEM:RESET_CFG
* MEM_INIT is in SYS:SYSTEM:RESET_CFG
@@ -1101,16 +1019,14 @@ static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot)
return -ENOMEM;
}
- bus = devm_mdiobus_alloc(dev);
- if (!bus)
- return -ENOMEM;
+ rc = mscc_miim_setup(dev, &bus, "VSC9953 internal MDIO bus",
+ ocelot->targets[GCB],
+ ocelot->map[GCB][GCB_MIIM_MII_STATUS & REG_MASK]);
- bus->name = "VSC9953 internal MDIO bus";
- bus->read = vsc9953_mdio_read;
- bus->write = vsc9953_mdio_write;
- bus->parent = dev;
- bus->priv = ocelot;
- snprintf(bus->id, MII_BUS_ID_SIZE, "%s-imdio", dev_name(dev));
+ if (rc) {
+ dev_err(dev, "failed to setup MDIO bus\n");
+ return rc;
+ }
/* Needed in order to initialize the bus mutex lock */
rc = of_mdiobus_register(bus, NULL);
diff --git a/drivers/net/mdio/mdio-mscc-miim.c b/drivers/net/mdio/mdio-mscc-miim.c
index e016b32ad208..2d420c9d7520 100644
--- a/drivers/net/mdio/mdio-mscc-miim.c
+++ b/drivers/net/mdio/mdio-mscc-miim.c
@@ -10,6 +10,7 @@
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
+#include <linux/mdio/mdio-mscc-miim.h>
#include <linux/module.h>
#include <linux/of_mdio.h>
#include <linux/phy.h>
@@ -37,7 +38,9 @@
struct mscc_miim_dev {
struct regmap *regs;
+ int mii_status_offset;
struct regmap *phy_regs;
+ int phy_reset_offset;
};
/* When high resolution timers aren't built-in: we can't use usleep_range() as
@@ -56,7 +59,8 @@ static int mscc_miim_status(struct mii_bus *bus)
struct mscc_miim_dev *miim = bus->priv;
int val, ret;
- ret = regmap_read(miim->regs, MSCC_MIIM_REG_STATUS, &val);
+ ret = regmap_read(miim->regs,
+ MSCC_MIIM_REG_STATUS + miim->mii_status_offset, &val);
if (ret < 0) {
WARN_ONCE(1, "mscc miim status read error %d\n", ret);
return ret;
@@ -93,7 +97,9 @@ static int mscc_miim_read(struct mii_bus *bus, int mii_id, int regnum)
if (ret)
goto out;
- ret = regmap_write(miim->regs, MSCC_MIIM_REG_CMD, MSCC_MIIM_CMD_VLD |
+ ret = regmap_write(miim->regs,
+ MSCC_MIIM_REG_CMD + miim->mii_status_offset,
+ MSCC_MIIM_CMD_VLD |
(mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
(regnum << MSCC_MIIM_CMD_REGAD_SHIFT) |
MSCC_MIIM_CMD_OPR_READ);
@@ -107,8 +113,8 @@ static int mscc_miim_read(struct mii_bus *bus, int mii_id, int regnum)
if (ret)
goto out;
- ret = regmap_read(miim->regs, MSCC_MIIM_REG_DATA, &val);
-
+ ret = regmap_read(miim->regs,
+ MSCC_MIIM_REG_DATA + miim->mii_status_offset, &val);
if (ret < 0) {
WARN_ONCE(1, "mscc miim read data reg error %d\n", ret);
goto out;
@@ -134,7 +140,9 @@ static int mscc_miim_write(struct mii_bus *bus, int mii_id,
if (ret < 0)
goto out;
- ret = regmap_write(miim->regs, MSCC_MIIM_REG_CMD, MSCC_MIIM_CMD_VLD |
+ ret = regmap_write(miim->regs,
+ MSCC_MIIM_REG_CMD + miim->mii_status_offset,
+ MSCC_MIIM_CMD_VLD |
(mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
(regnum << MSCC_MIIM_CMD_REGAD_SHIFT) |
(value << MSCC_MIIM_CMD_WRDATA_SHIFT) |
@@ -149,16 +157,19 @@ static int mscc_miim_write(struct mii_bus *bus, int mii_id,
static int mscc_miim_reset(struct mii_bus *bus)
{
struct mscc_miim_dev *miim = bus->priv;
+ int offset = miim->phy_reset_offset;
int ret;
if (miim->phy_regs) {
- ret = regmap_write(miim->phy_regs, MSCC_PHY_REG_PHY_CFG, 0);
+ ret = regmap_write(miim->phy_regs,
+ MSCC_PHY_REG_PHY_CFG + offset, 0);
if (ret < 0) {
WARN_ONCE(1, "mscc reset set error %d\n", ret);
return ret;
}
- ret = regmap_write(miim->phy_regs, MSCC_PHY_REG_PHY_CFG, 0x1ff);
+ ret = regmap_write(miim->phy_regs,
+ MSCC_PHY_REG_PHY_CFG + offset, 0x1ff);
if (ret < 0) {
WARN_ONCE(1, "mscc reset clear error %d\n", ret);
return ret;
@@ -176,8 +187,8 @@ static const struct regmap_config mscc_miim_regmap_config = {
.reg_stride = 4,
};
-static int mscc_miim_setup(struct device *dev, struct mii_bus **pbus,
- struct regmap *mii_regmap)
+int mscc_miim_setup(struct device *dev, struct mii_bus **pbus, const char *name,
+ struct regmap *mii_regmap, int status_offset)
{
struct mscc_miim_dev *miim;
struct mii_bus *bus;
@@ -186,7 +197,7 @@ static int mscc_miim_setup(struct device *dev, struct mii_bus **pbus,
if (!bus)
return -ENOMEM;
- bus->name = "mscc_miim";
+ bus->name = name;
bus->read = mscc_miim_read;
bus->write = mscc_miim_write;
bus->reset = mscc_miim_reset;
@@ -198,9 +209,13 @@ static int mscc_miim_setup(struct device *dev, struct mii_bus **pbus,
*pbus = bus;
miim->regs = mii_regmap;
+ miim->mii_status_offset = status_offset;
+
+ *pbus = bus;
return 0;
}
+EXPORT_SYMBOL(mscc_miim_setup);
static int mscc_miim_probe(struct platform_device *pdev)
{
@@ -237,7 +252,7 @@ static int mscc_miim_probe(struct platform_device *pdev)
return PTR_ERR(phy_regmap);
}
- ret = mscc_miim_setup(&pdev->dev, &bus, mii_regmap);
+ ret = mscc_miim_setup(&pdev->dev, &bus, "mscc_miim", mii_regmap, 0);
if (ret < 0) {
dev_err(&pdev->dev, "Unable to setup the MDIO bus\n");
return ret;
@@ -245,6 +260,7 @@ static int mscc_miim_probe(struct platform_device *pdev)
miim = bus->priv;
miim->phy_regs = phy_regmap;
+ miim->phy_reset_offset = 0;
ret = of_mdiobus_register(bus, pdev->dev.of_node);
if (ret < 0) {
diff --git a/include/linux/mdio/mdio-mscc-miim.h b/include/linux/mdio/mdio-mscc-miim.h
new file mode 100644
index 000000000000..5b4ed2c3cbb9
--- /dev/null
+++ b/include/linux/mdio/mdio-mscc-miim.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Driver for the MDIO interface of Microsemi network switches.
+ *
+ * Author: Colin Foster <colin.foster@in-advantage.com>
+ * Copyright (C) 2021 Innovative Advantage
+ */
+#ifndef MDIO_MSCC_MIIM_H
+#define MDIO_MSCC_MIIM_H
+
+#include <linux/device.h>
+#include <linux/phy.h>
+#include <linux/regmap.h>
+
+int mscc_miim_setup(struct device *device, struct mii_bus **bus,
+ const char *name, struct regmap *mii_regmap,
+ int status_offset);
+
+#endif
--
2.25.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 net-next 0/3] update seville to use shared MDIO driver
2021-11-29 1:57 [PATCH v3 net-next 0/3] update seville to use shared MDIO driver Colin Foster
` (2 preceding siblings ...)
2021-11-29 1:57 ` [PATCH v3 net-next 3/3] net: dsa: ocelot: felix: utilize shared mscc-miim driver for indirect MDIO access Colin Foster
@ 2021-11-29 13:10 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2021-11-29 13:10 UTC (permalink / raw)
To: Colin Foster
Cc: linux-kernel, netdev, vladimir.oltean, claudiu.manoil,
alexandre.belloni, UNGLinuxDriver, andrew, vivien.didelot,
f.fainelli, davem, kuba, hkallweit1, linux
Hello:
This series was applied to netdev/net-next.git (master)
by David S. Miller <davem@davemloft.net>:
On Sun, 28 Nov 2021 17:57:34 -0800 you wrote:
> This patch set exposes and utilizes the shared MDIO bus in
> drivers/net/mdio/msio-mscc-miim.c
>
> v3:
> * Fix errors using uninitilized "dev" inside the probe function.
> * Remove phy_regmap from the setup function, since it currently
> isn't used
> * Remove GCB_PHY_PHY_CFG definition from ocelot.h - it isn't used
> yet...
>
> [...]
Here is the summary with links:
- [v3,net-next,1/3] net: mdio: mscc-miim: convert to a regmap implementation
https://git.kernel.org/netdev/net-next/c/a27a76282837
- [v3,net-next,2/3] net: dsa: ocelot: seville: utilize of_mdiobus_register
https://git.kernel.org/netdev/net-next/c/5186c4a05b97
- [v3,net-next,3/3] net: dsa: ocelot: felix: utilize shared mscc-miim driver for indirect MDIO access
https://git.kernel.org/netdev/net-next/c/b99658452355
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-11-29 14:39 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-29 1:57 [PATCH v3 net-next 0/3] update seville to use shared MDIO driver Colin Foster
2021-11-29 1:57 ` [PATCH v3 net-next 1/3] net: mdio: mscc-miim: convert to a regmap implementation Colin Foster
2021-11-29 1:57 ` [PATCH v3 net-next 2/3] net: dsa: ocelot: seville: utilize of_mdiobus_register Colin Foster
2021-11-29 1:57 ` [PATCH v3 net-next 3/3] net: dsa: ocelot: felix: utilize shared mscc-miim driver for indirect MDIO access Colin Foster
2021-11-29 13:10 ` [PATCH v3 net-next 0/3] update seville to use shared MDIO driver patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®