int hieth_mdiobus_driver_init(void) { mdio_bus_ld.iobase_phys = ETH_IO_ADDRESS_BASE; mdio_bus_ld.mdio_frqdiv = ETH_MDIO_FRQDIV; hieth_mdio_init(&mdio_bus_ld); /* UpEther PHY init */ miiphy_register(U_PHY_NAME, hieth_mdiobus_read, hieth_mdiobus_write); if(!get_phy_device(U_PHY_NAME,U_PHY_ADDR)) { miiphy_reset(U_PHY_NAME, U_PHY_ADDR); miiphy_set_current_dev(U_PHY_NAME); } /* DownEther PHY init */ miiphy_register(D_PHY_NAME, hieth_mdiobus_read, hieth_mdiobus_write); if(!get_phy_device(D_PHY_NAME,D_PHY_ADDR)) { miiphy_reset(D_PHY_NAME, D_PHY_ADDR); miiphy_set_current_dev(D_PHY_NAME); } return 0; }
static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *child, u32 addr) { struct phy_device *phy; int ret; phy = get_phy_device(mdio, addr); if (IS_ERR(phy)) return PTR_ERR(phy); /* * Associate the OF node with the device structure so it * can be looked up later */ phy->dev.device_node = child; /* * All data is now stored in the phy struct; * register it */ ret = phy_register_device(phy); if (ret) return ret; dev_dbg(&mdio->dev, "registered phy %s at address %i\n", child->name, addr); return 0; }
/* mdiobus_register * * description: Called by a bus driver to bring up all the PHYs * on a given bus, and attach them to the bus */ int mdiobus_register(struct mii_bus *bus) { int i; int err = 0; spin_lock_init(&bus->mdio_lock); if (NULL == bus || NULL == bus->name || NULL == bus->read || NULL == bus->write) return -EINVAL; if (bus->reset) bus->reset(bus); for (i = 0; i < PHY_MAX_ADDR; i++) { struct phy_device *phydev; if (bus->phy_mask & (1 << i)) continue; phydev = get_phy_device(bus, i); if (IS_ERR(phydev)) return PTR_ERR(phydev); /* There's a PHY at this address * We need to set: * 1) IRQ * 2) bus_id * 3) parent * 4) bus * 5) mii_bus * And, we need to register it */ if (phydev) { phydev->irq = bus->irq[i]; phydev->dev.parent = bus->dev; phydev->dev.bus = &mdio_bus_type; snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, i); phydev->bus = bus; err = device_register(&phydev->dev); if (err) printk(KERN_ERR "phy %d failed to register\n", i); } bus->phy_map[i] = phydev; } pr_info("%s: probed\n", bus->name); return err; }
void hieth_mdiobus_driver_exit(void) { /*add this to avoid the first time to use eth will print 'No such device: XXXXX' message.*/ if (!miiphy_get_current_dev()) return; /* UpEther PHY exit */ if(!get_phy_device(U_PHY_NAME,U_PHY_ADDR)) { miiphy_reset(U_PHY_NAME, U_PHY_ADDR); } /* DownEther PHY exit */ if(!get_phy_device(D_PHY_NAME,D_PHY_ADDR)) { miiphy_reset(D_PHY_NAME, D_PHY_ADDR); } hieth_mdio_exit(&mdio_bus_ld); }
struct phy_device *xgene_enet_phy_register(struct mii_bus *bus, int phy_addr) { struct phy_device *phy_dev; phy_dev = get_phy_device(bus, phy_addr, false); if (!phy_dev || IS_ERR(phy_dev)) return NULL; if (phy_device_register(phy_dev)) phy_device_free(phy_dev); return phy_dev; }
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) { struct phy_device *phydev; if (bus->phy_map[addr]) return bus->phy_map[addr]; phydev = get_phy_device(bus, addr); if (IS_ERR(phydev) || phydev == NULL) return phydev; bus->phy_map[addr] = phydev; return phydev; }
int stmmac_mdiobus_driver_init(void) { stmmac_mdio_local_device.iobase_phys = STMMAC_MDIO_IO_BASE; stmmac_mdio_local_device.iobase = STMMAC_MDIO_IO_BASE; stmmac_mdio_clk_init(&stmmac_mdio_local_device); /* GMAC0 PHY init */ miiphy_register(GMAC0_PHY_NAME, stmmac_mdiobus_read, stmmac_mdiobus_write); if (!get_phy_device(GMAC0_PHY_NAME, GMAC0_PHY_ADDR)) miiphy_set_current_dev(GMAC0_PHY_NAME); return 0; }
int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) { struct phy_device *phy; struct device_node *child; int rc, i; mdio->phy_mask = ~0; if (mdio->irq) for (i=0; i<PHY_MAX_ADDR; i++) mdio->irq[i] = PHY_POLL; rc = mdiobus_register(mdio); if (rc) return rc; for_each_child_of_node(np, child) { const __be32 *paddr; u32 addr; int len; paddr = of_get_property(child, "reg", &len); if (!paddr || len < sizeof(*paddr)) { dev_err(&mdio->dev, "%s has invalid PHY address\n", child->full_name); continue; } addr = be32_to_cpup(paddr); if (addr >= 32) { dev_err(&mdio->dev, "%s PHY address %i is too large\n", child->full_name, addr); continue; } if (mdio->irq) { mdio->irq[addr] = irq_of_parse_and_map(child, 0); if (!mdio->irq[addr]) mdio->irq[addr] = PHY_POLL; } phy = get_phy_device(mdio, addr); if (!phy || IS_ERR(phy)) { dev_err(&mdio->dev, "error probing PHY at address %i\n", addr); continue; } of_node_get(child); phy->dev.of_node = child; rc = phy_device_register(phy); if (rc) { phy_device_free(phy); of_node_put(child); continue; } dev_dbg(&mdio->dev, "registered phy %s at address %i\n", child->name, addr); } return 0; }
/** * of_mdiobus_register - Register mii_bus and create PHYs from the device tree * @mdio: pointer to mii_bus structure * @np: pointer to device_node of MDIO bus. * * This function registers the mii_bus structure and registers a phy_device * for each child node of @np. */ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) { struct phy_device *phy; struct device_node *child; int rc, i; /* Mask out all PHYs from auto probing. Instead the PHYs listed in * the device tree are populated after the bus has been registered */ mdio->phy_mask = ~0; /* Clear all the IRQ properties */ if (mdio->irq) for (i=0; i<PHY_MAX_ADDR; i++) mdio->irq[i] = PHY_POLL; mdio->dev.of_node = np; /* Register the MDIO bus */ rc = mdiobus_register(mdio); if (rc) return rc; /* Loop over the child nodes and register a phy_device for each one */ for_each_available_child_of_node(np, child) { const __be32 *paddr; u32 addr; int len; bool is_c45; /* A PHY must have a reg property in the range [0-31] */ paddr = of_get_property(child, "reg", &len); if (!paddr || len < sizeof(*paddr)) { dev_err(&mdio->dev, "%s has invalid PHY address\n", child->full_name); continue; } addr = be32_to_cpup(paddr); if (addr >= 32) { dev_err(&mdio->dev, "%s PHY address %i is too large\n", child->full_name, addr); continue; } if (mdio->irq) { mdio->irq[addr] = irq_of_parse_and_map(child, 0); if (!mdio->irq[addr]) mdio->irq[addr] = PHY_POLL; } is_c45 = of_device_is_compatible(child, "ethernet-phy-ieee802.3-c45"); phy = get_phy_device(mdio, addr, is_c45); if (!phy || IS_ERR(phy)) { phy = phy_device_create(mdio, addr, 0, false, NULL); if (!phy || IS_ERR(phy)) { dev_err(&mdio->dev, "error creating PHY at address %i\n", addr); continue; } } /* Associate the OF node with the device structure so it * can be looked up later */ of_node_get(child); phy->dev.of_node = child; /* All data is now stored in the phy struct; register it */ rc = phy_device_register(phy); if (rc) { phy_device_free(phy); of_node_put(child); continue; } dev_dbg(&mdio->dev, "registered phy %s at address %i\n", child->name, addr); } return 0; }
int xgbe_mdio_register(struct xgbe_prv_data *pdata) { struct device_node *phy_node; struct mii_bus *mii; struct phy_device *phydev; int ret = 0; DBGPR("-->xgbe_mdio_register\n"); /* Retrieve the phy-handle */ phy_node = of_parse_phandle(pdata->dev->of_node, "phy-handle", 0); if (!phy_node) { dev_err(pdata->dev, "unable to parse phy-handle\n"); return -EINVAL; } mii = mdiobus_alloc(); if (mii == NULL) { dev_err(pdata->dev, "mdiobus_alloc failed\n"); ret = -ENOMEM; goto err_node_get; } /* Register on the MDIO bus (don't probe any PHYs) */ mii->name = XGBE_PHY_NAME; mii->read = xgbe_mdio_read; mii->write = xgbe_mdio_write; snprintf(mii->id, sizeof(mii->id), "%s", pdata->mii_bus_id); mii->priv = pdata; mii->phy_mask = ~0; mii->parent = pdata->dev; ret = mdiobus_register(mii); if (ret) { dev_err(pdata->dev, "mdiobus_register failed\n"); goto err_mdiobus_alloc; } DBGPR(" mdiobus_register succeeded for %s\n", pdata->mii_bus_id); /* Probe the PCS using Clause 45 */ phydev = get_phy_device(mii, XGBE_PRTAD, true); if (IS_ERR(phydev) || !phydev || !phydev->c45_ids.device_ids[MDIO_MMD_PCS]) { dev_err(pdata->dev, "get_phy_device failed\n"); ret = phydev ? PTR_ERR(phydev) : -ENOLINK; goto err_mdiobus_register; } request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phydev->c45_ids.device_ids[MDIO_MMD_PCS])); of_node_get(phy_node); phydev->dev.of_node = phy_node; ret = phy_device_register(phydev); if (ret) { dev_err(pdata->dev, "phy_device_register failed\n"); of_node_put(phy_node); goto err_phy_device; } /* Add a reference to the PHY driver so it can't be unloaded */ pdata->phy_module = phydev->dev.driver ? phydev->dev.driver->owner : NULL; if (!try_module_get(pdata->phy_module)) { dev_err(pdata->dev, "try_module_get failed\n"); ret = -EIO; goto err_phy_device; } pdata->mii = mii; pdata->mdio_mmd = MDIO_MMD_PCS; phydev->autoneg = pdata->default_autoneg; if (phydev->autoneg == AUTONEG_DISABLE) { phydev->speed = pdata->default_speed; phydev->duplex = DUPLEX_FULL; phydev->advertising &= ~ADVERTISED_Autoneg; } pdata->phydev = phydev; of_node_put(phy_node); DBGPHY_REGS(pdata); DBGPR("<--xgbe_mdio_register\n"); return 0; err_phy_device: phy_device_free(phydev); err_mdiobus_register: mdiobus_unregister(mii); err_mdiobus_alloc: mdiobus_free(mii); err_node_get: of_node_put(phy_node); return ret; }