Commit a50b3536 authored by Arun Ramadoss's avatar Arun Ramadoss Committed by David S. Miller
Browse files

net: dsa: microchip: lan937x: register mdio-bus



This patch register mdio-bus for the lan937x series switch. mdio read
and write uses the vphy for accessing the phy register.

Signed-off-by: default avatarArun Ramadoss <arun.ramadoss@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ffaf1de2
Loading
Loading
Loading
Loading
+74 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include <linux/iopoll.h>
#include <linux/phy.h>
#include <linux/of_net.h>
#include <linux/of_mdio.h>
#include <linux/if_bridge.h>
#include <linux/math.h>
#include <net/dsa.h>
@@ -136,6 +137,73 @@ void lan937x_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val)
	lan937x_internal_phy_write(dev, addr, reg, val);
}

static int lan937x_sw_mdio_read(struct mii_bus *bus, int addr, int regnum)
{
	struct ksz_device *dev = bus->priv;
	u16 val;
	int ret;

	if (regnum & MII_ADDR_C45)
		return -EOPNOTSUPP;

	ret = lan937x_internal_phy_read(dev, addr, regnum, &val);
	if (ret < 0)
		return ret;

	return val;
}

static int lan937x_sw_mdio_write(struct mii_bus *bus, int addr, int regnum,
				 u16 val)
{
	struct ksz_device *dev = bus->priv;

	if (regnum & MII_ADDR_C45)
		return -EOPNOTSUPP;

	return lan937x_internal_phy_write(dev, addr, regnum, val);
}

static int lan937x_mdio_register(struct ksz_device *dev)
{
	struct dsa_switch *ds = dev->ds;
	struct device_node *mdio_np;
	struct mii_bus *bus;
	int ret;

	mdio_np = of_get_child_by_name(dev->dev->of_node, "mdio");
	if (!mdio_np) {
		dev_err(ds->dev, "no MDIO bus node\n");
		return -ENODEV;
	}

	bus = devm_mdiobus_alloc(ds->dev);
	if (!bus) {
		of_node_put(mdio_np);
		return -ENOMEM;
	}

	bus->priv = dev;
	bus->read = lan937x_sw_mdio_read;
	bus->write = lan937x_sw_mdio_write;
	bus->name = "lan937x slave smi";
	snprintf(bus->id, MII_BUS_ID_SIZE, "SMI-%d", ds->index);
	bus->parent = ds->dev;
	bus->phy_mask = ~ds->phys_mii_mask;

	ds->slave_mii_bus = bus;

	ret = devm_of_mdiobus_register(ds->dev, bus, mdio_np);
	if (ret) {
		dev_err(ds->dev, "unable to register MDIO bus %s\n",
			bus->id);
	}

	of_node_put(mdio_np);

	return ret;
}

int lan937x_reset_switch(struct ksz_device *dev)
{
	u32 data32;
@@ -228,6 +296,12 @@ int lan937x_setup(struct dsa_switch *ds)
		return ret;
	}

	ret = lan937x_mdio_register(dev);
	if (ret < 0) {
		dev_err(dev->dev, "failed to register the mdio");
		return ret;
	}

	/* The VLAN aware is a global setting. Mixed vlan
	 * filterings are not supported.
	 */