]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: dsa: microchip: lan937x: register mdio-bus
authorArun Ramadoss <arun.ramadoss@microchip.com>
Fri, 1 Jul 2022 15:07:09 +0000 (20:37 +0530)
committerDavid S. Miller <davem@davemloft.net>
Sat, 2 Jul 2022 15:34:05 +0000 (16:34 +0100)
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: Arun Ramadoss <arun.ramadoss@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/microchip/lan937x_main.c

index 5a2e14fe3cf32be366f55663a7496d92fb81febd..7090947cf52c90c1ebfde5c53f4e98fad8ba058f 100644 (file)
@@ -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.
         */