1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright 2021, NXP Semiconductors
4 #include <linux/of_mdio.h>
7 enum sja1105_mdio_opcode {
11 SJA1105_C45_DATA_AUTOINC = 3,
14 static u64 sja1105_base_t1_encode_addr(struct sja1105_private *priv,
15 int phy, enum sja1105_mdio_opcode op,
18 const struct sja1105_regs *regs = priv->info->regs;
20 return regs->mdio_100base_t1 | (phy << 7) | (op << 5) | (xad << 0);
23 static int sja1105_base_t1_mdio_read(struct mii_bus *bus, int phy, int reg)
25 struct sja1105_mdio_private *mdio_priv = bus->priv;
26 struct sja1105_private *priv = mdio_priv->priv;
31 if (reg & MII_ADDR_C45) {
32 u16 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
34 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR,
37 tmp = reg & MII_REGADDR_C45_MASK;
39 rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
43 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA,
46 rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL);
54 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f);
56 rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL);
63 static int sja1105_base_t1_mdio_write(struct mii_bus *bus, int phy, int reg,
66 struct sja1105_mdio_private *mdio_priv = bus->priv;
67 struct sja1105_private *priv = mdio_priv->priv;
72 if (reg & MII_ADDR_C45) {
73 u16 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
75 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR,
78 tmp = reg & MII_REGADDR_C45_MASK;
80 rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
84 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA,
89 rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
97 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f);
101 return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
104 static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg)
106 struct sja1105_mdio_private *mdio_priv = bus->priv;
107 struct sja1105_private *priv = mdio_priv->priv;
108 const struct sja1105_regs *regs = priv->info->regs;
112 rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg,
120 static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg,
123 struct sja1105_mdio_private *mdio_priv = bus->priv;
124 struct sja1105_private *priv = mdio_priv->priv;
125 const struct sja1105_regs *regs = priv->info->regs;
128 return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg,
132 static int sja1105_mdiobus_base_tx_register(struct sja1105_private *priv,
133 struct device_node *mdio_node)
135 struct sja1105_mdio_private *mdio_priv;
136 struct device_node *np;
140 np = of_find_compatible_node(mdio_node, NULL,
141 "nxp,sja1110-base-tx-mdio");
145 if (!of_device_is_available(np))
148 bus = mdiobus_alloc_size(sizeof(*mdio_priv));
154 bus->name = "SJA1110 100base-TX MDIO bus";
155 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-tx",
156 dev_name(priv->ds->dev));
157 bus->read = sja1105_base_tx_mdio_read;
158 bus->write = sja1105_base_tx_mdio_write;
159 bus->parent = priv->ds->dev;
160 mdio_priv = bus->priv;
161 mdio_priv->priv = priv;
163 rc = of_mdiobus_register(bus, np);
169 priv->mdio_base_tx = bus;
177 static void sja1105_mdiobus_base_tx_unregister(struct sja1105_private *priv)
179 if (!priv->mdio_base_tx)
182 mdiobus_unregister(priv->mdio_base_tx);
183 mdiobus_free(priv->mdio_base_tx);
184 priv->mdio_base_tx = NULL;
187 static int sja1105_mdiobus_base_t1_register(struct sja1105_private *priv,
188 struct device_node *mdio_node)
190 struct sja1105_mdio_private *mdio_priv;
191 struct device_node *np;
195 np = of_find_compatible_node(mdio_node, NULL,
196 "nxp,sja1110-base-t1-mdio");
200 if (!of_device_is_available(np))
203 bus = mdiobus_alloc_size(sizeof(*mdio_priv));
209 bus->name = "SJA1110 100base-T1 MDIO bus";
210 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-t1",
211 dev_name(priv->ds->dev));
212 bus->read = sja1105_base_t1_mdio_read;
213 bus->write = sja1105_base_t1_mdio_write;
214 bus->parent = priv->ds->dev;
215 mdio_priv = bus->priv;
216 mdio_priv->priv = priv;
218 rc = of_mdiobus_register(bus, np);
224 priv->mdio_base_t1 = bus;
232 static void sja1105_mdiobus_base_t1_unregister(struct sja1105_private *priv)
234 if (!priv->mdio_base_t1)
237 mdiobus_unregister(priv->mdio_base_t1);
238 mdiobus_free(priv->mdio_base_t1);
239 priv->mdio_base_t1 = NULL;
242 int sja1105_mdiobus_register(struct dsa_switch *ds)
244 struct sja1105_private *priv = ds->priv;
245 const struct sja1105_regs *regs = priv->info->regs;
246 struct device_node *switch_node = ds->dev->of_node;
247 struct device_node *mdio_node;
250 mdio_node = of_get_child_by_name(switch_node, "mdios");
254 if (!of_device_is_available(mdio_node))
255 goto out_put_mdio_node;
257 if (regs->mdio_100base_tx != SJA1105_RSV_ADDR) {
258 rc = sja1105_mdiobus_base_tx_register(priv, mdio_node);
260 goto err_put_mdio_node;
263 if (regs->mdio_100base_t1 != SJA1105_RSV_ADDR) {
264 rc = sja1105_mdiobus_base_t1_register(priv, mdio_node);
266 goto err_free_base_tx_mdiobus;
270 of_node_put(mdio_node);
274 err_free_base_tx_mdiobus:
275 sja1105_mdiobus_base_tx_unregister(priv);
277 of_node_put(mdio_node);
282 void sja1105_mdiobus_unregister(struct dsa_switch *ds)
284 struct sja1105_private *priv = ds->priv;
286 sja1105_mdiobus_base_t1_unregister(priv);
287 sja1105_mdiobus_base_tx_unregister(priv);