Lines Matching +full:device +full:- +full:addr

1 // SPDX-License-Identifier: GPL-2.0-only
3 STMMAC Ethernet Driver -- MDIO bus implementation
6 Copyright (C) 2007-2009 STMicroelectronics Ltd
54 tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P); in stmmac_xgmac2_c45_format()
56 writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P); in stmmac_xgmac2_c45_format()
68 /* HW does not support C22 addr >= 4 */ in stmmac_xgmac2_c22_format()
70 return -ENODEV; in stmmac_xgmac2_c22_format()
73 tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P); in stmmac_xgmac2_c22_format()
76 writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P); in stmmac_xgmac2_c22_format()
84 struct net_device *ndev = bus->priv; in stmmac_xgmac2_mdio_read()
86 unsigned int mii_address = priv->hw->mii.addr; in stmmac_xgmac2_mdio_read()
87 unsigned int mii_data = priv->hw->mii.data; in stmmac_xgmac2_mdio_read()
88 u32 tmp, addr, value = MII_XGMAC_BUSY; in stmmac_xgmac2_mdio_read() local
91 ret = pm_runtime_get_sync(priv->device); in stmmac_xgmac2_mdio_read()
93 pm_runtime_put_noidle(priv->device); in stmmac_xgmac2_mdio_read()
98 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, in stmmac_xgmac2_mdio_read()
100 ret = -EBUSY; in stmmac_xgmac2_mdio_read()
107 ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr); in stmmac_xgmac2_mdio_read()
111 ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr); in stmmac_xgmac2_mdio_read()
118 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) in stmmac_xgmac2_mdio_read()
119 & priv->hw->mii.clk_csr_mask; in stmmac_xgmac2_mdio_read()
123 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, in stmmac_xgmac2_mdio_read()
125 ret = -EBUSY; in stmmac_xgmac2_mdio_read()
130 writel(addr, priv->ioaddr + mii_address); in stmmac_xgmac2_mdio_read()
131 writel(value, priv->ioaddr + mii_data); in stmmac_xgmac2_mdio_read()
134 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, in stmmac_xgmac2_mdio_read()
136 ret = -EBUSY; in stmmac_xgmac2_mdio_read()
141 ret = (int)readl(priv->ioaddr + mii_data) & GENMASK(15, 0); in stmmac_xgmac2_mdio_read()
144 pm_runtime_put(priv->device); in stmmac_xgmac2_mdio_read()
152 struct net_device *ndev = bus->priv; in stmmac_xgmac2_mdio_write()
154 unsigned int mii_address = priv->hw->mii.addr; in stmmac_xgmac2_mdio_write()
155 unsigned int mii_data = priv->hw->mii.data; in stmmac_xgmac2_mdio_write()
156 u32 addr, tmp, value = MII_XGMAC_BUSY; in stmmac_xgmac2_mdio_write() local
159 ret = pm_runtime_get_sync(priv->device); in stmmac_xgmac2_mdio_write()
161 pm_runtime_put_noidle(priv->device); in stmmac_xgmac2_mdio_write()
166 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, in stmmac_xgmac2_mdio_write()
168 ret = -EBUSY; in stmmac_xgmac2_mdio_write()
175 ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr); in stmmac_xgmac2_mdio_write()
179 ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr); in stmmac_xgmac2_mdio_write()
186 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) in stmmac_xgmac2_mdio_write()
187 & priv->hw->mii.clk_csr_mask; in stmmac_xgmac2_mdio_write()
192 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, in stmmac_xgmac2_mdio_write()
194 ret = -EBUSY; in stmmac_xgmac2_mdio_write()
199 writel(addr, priv->ioaddr + mii_address); in stmmac_xgmac2_mdio_write()
200 writel(value, priv->ioaddr + mii_data); in stmmac_xgmac2_mdio_write()
203 ret = readl_poll_timeout(priv->ioaddr + mii_data, tmp, in stmmac_xgmac2_mdio_write()
207 pm_runtime_put(priv->device); in stmmac_xgmac2_mdio_write()
215 * @phyaddr: MII addr
217 * Description: it reads data from the MII register from within the phy device.
224 struct net_device *ndev = bus->priv; in stmmac_mdio_read()
226 unsigned int mii_address = priv->hw->mii.addr; in stmmac_mdio_read()
227 unsigned int mii_data = priv->hw->mii.data; in stmmac_mdio_read()
232 data = pm_runtime_get_sync(priv->device); in stmmac_mdio_read()
234 pm_runtime_put_noidle(priv->device); in stmmac_mdio_read()
238 value |= (phyaddr << priv->hw->mii.addr_shift) in stmmac_mdio_read()
239 & priv->hw->mii.addr_mask; in stmmac_mdio_read()
240 value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask; in stmmac_mdio_read()
241 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) in stmmac_mdio_read()
242 & priv->hw->mii.clk_csr_mask; in stmmac_mdio_read()
243 if (priv->plat->has_gmac4) { in stmmac_mdio_read()
247 value &= ~priv->hw->mii.reg_mask; in stmmac_mdio_read()
249 priv->hw->mii.reg_shift) & in stmmac_mdio_read()
250 priv->hw->mii.reg_mask; in stmmac_mdio_read()
257 if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), in stmmac_mdio_read()
259 data = -EBUSY; in stmmac_mdio_read()
263 writel(data, priv->ioaddr + mii_data); in stmmac_mdio_read()
264 writel(value, priv->ioaddr + mii_address); in stmmac_mdio_read()
266 if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), in stmmac_mdio_read()
268 data = -EBUSY; in stmmac_mdio_read()
273 data = (int)readl(priv->ioaddr + mii_data) & MII_DATA_MASK; in stmmac_mdio_read()
276 pm_runtime_put(priv->device); in stmmac_mdio_read()
284 * @phyaddr: MII addr
287 * Description: it writes the data into the MII register from within the device.
292 struct net_device *ndev = bus->priv; in stmmac_mdio_write()
294 unsigned int mii_address = priv->hw->mii.addr; in stmmac_mdio_write()
295 unsigned int mii_data = priv->hw->mii.data; in stmmac_mdio_write()
300 ret = pm_runtime_get_sync(priv->device); in stmmac_mdio_write()
302 pm_runtime_put_noidle(priv->device); in stmmac_mdio_write()
306 value |= (phyaddr << priv->hw->mii.addr_shift) in stmmac_mdio_write()
307 & priv->hw->mii.addr_mask; in stmmac_mdio_write()
308 value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask; in stmmac_mdio_write()
310 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) in stmmac_mdio_write()
311 & priv->hw->mii.clk_csr_mask; in stmmac_mdio_write()
312 if (priv->plat->has_gmac4) { in stmmac_mdio_write()
316 value &= ~priv->hw->mii.reg_mask; in stmmac_mdio_write()
318 priv->hw->mii.reg_shift) & in stmmac_mdio_write()
319 priv->hw->mii.reg_mask; in stmmac_mdio_write()
329 if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), in stmmac_mdio_write()
331 ret = -EBUSY; in stmmac_mdio_write()
336 writel(data, priv->ioaddr + mii_data); in stmmac_mdio_write()
337 writel(value, priv->ioaddr + mii_address); in stmmac_mdio_write()
340 ret = readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), in stmmac_mdio_write()
344 pm_runtime_put(priv->device); in stmmac_mdio_write()
357 struct net_device *ndev = bus->priv; in stmmac_mdio_reset()
359 unsigned int mii_address = priv->hw->mii.addr; in stmmac_mdio_reset()
362 if (priv->device->of_node) { in stmmac_mdio_reset()
366 reset_gpio = devm_gpiod_get_optional(priv->device, in stmmac_mdio_reset()
372 device_property_read_u32_array(priv->device, in stmmac_mdio_reset()
373 "snps,reset-delays-us", in stmmac_mdio_reset()
394 if (!priv->plat->has_gmac4) in stmmac_mdio_reset()
395 writel(0, priv->ioaddr + mii_address); in stmmac_mdio_reset()
402 struct net_device *ndev = bus->priv; in stmmac_xpcs_setup()
406 int mode, addr; in stmmac_xpcs_setup() local
409 mode = priv->plat->phy_interface; in stmmac_xpcs_setup()
412 for (addr = 0; addr < PHY_MAX_ADDR; addr++) { in stmmac_xpcs_setup()
413 mdiodev = mdio_device_create(bus, addr); in stmmac_xpcs_setup()
423 priv->hw->xpcs = xpcs; in stmmac_xpcs_setup()
427 if (!priv->hw->xpcs) { in stmmac_xpcs_setup()
428 dev_warn(priv->device, "No xPCS found\n"); in stmmac_xpcs_setup()
429 return -ENODEV; in stmmac_xpcs_setup()
437 * @ndev: net device structure
445 struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data; in stmmac_mdio_register()
446 struct device_node *mdio_node = priv->plat->mdio_node; in stmmac_mdio_register()
447 struct device *dev = ndev->dev.parent; in stmmac_mdio_register()
448 int addr, found, max_addr; in stmmac_mdio_register() local
455 return -ENOMEM; in stmmac_mdio_register()
457 if (mdio_bus_data->irqs) in stmmac_mdio_register()
458 memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq)); in stmmac_mdio_register()
460 new_bus->name = "stmmac"; in stmmac_mdio_register()
462 if (priv->plat->has_gmac4) in stmmac_mdio_register()
463 new_bus->probe_capabilities = MDIOBUS_C22_C45; in stmmac_mdio_register()
465 if (priv->plat->has_xgmac) { in stmmac_mdio_register()
466 new_bus->read = &stmmac_xgmac2_mdio_read; in stmmac_mdio_register()
467 new_bus->write = &stmmac_xgmac2_mdio_write; in stmmac_mdio_register()
472 /* Check if DT specified an unsupported phy addr */ in stmmac_mdio_register()
473 if (priv->plat->phy_addr > MII_XGMAC_MAX_C22ADDR) in stmmac_mdio_register()
477 new_bus->read = &stmmac_mdio_read; in stmmac_mdio_register()
478 new_bus->write = &stmmac_mdio_write; in stmmac_mdio_register()
482 if (mdio_bus_data->needs_reset) in stmmac_mdio_register()
483 new_bus->reset = &stmmac_mdio_reset; in stmmac_mdio_register()
485 snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x", in stmmac_mdio_register()
486 new_bus->name, priv->plat->bus_id); in stmmac_mdio_register()
487 new_bus->priv = ndev; in stmmac_mdio_register()
488 new_bus->phy_mask = mdio_bus_data->phy_mask; in stmmac_mdio_register()
489 new_bus->parent = priv->device; in stmmac_mdio_register()
498 if (priv->plat->has_xgmac) in stmmac_mdio_register()
501 if (priv->plat->phy_node || mdio_node) in stmmac_mdio_register()
505 for (addr = 0; addr < max_addr; addr++) { in stmmac_mdio_register()
506 struct phy_device *phydev = mdiobus_get_phy(new_bus, addr); in stmmac_mdio_register()
515 if (!mdio_bus_data->irqs && in stmmac_mdio_register()
516 (mdio_bus_data->probed_phy_irq > 0)) { in stmmac_mdio_register()
517 new_bus->irq[addr] = mdio_bus_data->probed_phy_irq; in stmmac_mdio_register()
518 phydev->irq = mdio_bus_data->probed_phy_irq; in stmmac_mdio_register()
526 if (priv->plat->phy_addr == -1) in stmmac_mdio_register()
527 priv->plat->phy_addr = addr; in stmmac_mdio_register()
535 err = -ENODEV; in stmmac_mdio_register()
540 priv->mii = new_bus; in stmmac_mdio_register()
553 * @ndev: net device structure
560 if (!priv->mii) in stmmac_mdio_unregister()
563 if (priv->hw->xpcs) { in stmmac_mdio_unregister()
564 mdio_device_free(priv->hw->xpcs->mdiodev); in stmmac_mdio_unregister()
565 xpcs_destroy(priv->hw->xpcs); in stmmac_mdio_unregister()
568 mdiobus_unregister(priv->mii); in stmmac_mdio_unregister()
569 priv->mii->priv = NULL; in stmmac_mdio_unregister()
570 mdiobus_free(priv->mii); in stmmac_mdio_unregister()
571 priv->mii = NULL; in stmmac_mdio_unregister()