/* mdio_bus_match * * description: Given a PHY device, and a PHY driver, return 1 if * the driver supports the device. Otherwise, return 0 */ static int mdio_bus_match(struct device *dev, struct device_driver *drv) { struct phy_device *phydev = to_phy_device(dev); struct phy_driver *phydrv = to_phy_driver(drv); return (phydrv->phy_id == (phydev->phy_id & phydrv->phy_id_mask)); }
static void mdio_bus_remove(struct device_d *_dev) { struct phy_device *dev = to_phy_device(_dev); struct phy_driver *drv = to_phy_driver(_dev->driver); if (drv->remove) drv->remove(dev); free(dev->cdev.name); devfs_remove(&dev->cdev); }
static int mdio_bus_probe(struct device_d *_dev) { struct phy_device *dev = to_phy_device(_dev); struct phy_driver *drv = to_phy_driver(_dev->driver); int ret; if (drv->probe) { ret = drv->probe(dev); if (ret) goto err; } if (dev->dev_flags) { if (dev->dev_flags & PHYLIB_FORCE_10) { dev->speed = SPEED_10; dev->duplex = DUPLEX_FULL; dev->autoneg = !AUTONEG_ENABLE; dev->force = 1; dev->link = 1; } else if (dev->dev_flags & PHYLIB_FORCE_100) { dev->speed = SPEED_100; dev->duplex = DUPLEX_FULL; dev->autoneg = !AUTONEG_ENABLE; dev->force = 1; dev->link = 1; } } /* Start out supporting everything. Eventually, * a controller will attach, and may modify one * or both of these values */ dev->supported = drv->features; dev->advertising = drv->features; dev_add_param_int_ro(&dev->dev, "phy_addr", dev->addr, "%d"); dev_add_param_int_ro(&dev->dev, "phy_id", dev->phy_id, "0x%08x"); dev->cdev.name = asprintf("phy%d", _dev->id); dev->cdev.size = 64; dev->cdev.ops = &phydev_ops; dev->cdev.priv = dev; dev->cdev.dev = _dev; devfs_create(&dev->cdev); return 0; err: return ret; }
/* phy_probe * * description: Take care of setting up the phy_device structure, * set the state to READY (the driver's init function should * set it to STARTING if needed). */ static int phy_probe(struct device *dev) { struct phy_device *phydev; struct phy_driver *phydrv; struct device_driver *drv; int err = 0; phydev = to_phy_device(dev); /* Make sure the driver is held. * XXX -- Is this correct? */ drv = get_driver(phydev->dev.driver); phydrv = to_phy_driver(drv); phydev->drv = phydrv; /* Disable the interrupt if the PHY doesn't support it */ if (!(phydrv->flags & PHY_HAS_INTERRUPT)) phydev->irq = PHY_POLL; spin_lock(&phydev->lock); /* Start out supporting everything. Eventually, * a controller will attach, and may modify one * or both of these values */ phydev->supported = phydrv->features; phydev->advertising = phydrv->features; /* Set the state to READY by default */ phydev->state = PHY_READY; if (phydev->drv->probe) err = phydev->drv->probe(phydev); spin_unlock(&phydev->lock); if (err < 0) return err; if (phydev->drv->config_init) err = phydev->drv->config_init(phydev); return err; }
static int mdio_bus_probe(struct device_d *_dev) { struct phy_device *dev = to_phy_device(_dev); struct phy_driver *drv = to_phy_driver(_dev->driver); int ret; char str[16]; dev->attached_dev->phydev = dev; if (drv->probe) { ret = drv->probe(dev); if (ret) goto err; } if (dev->dev_flags) { if (dev->dev_flags & PHYLIB_FORCE_10) { dev->speed = SPEED_10; dev->duplex = DUPLEX_FULL; dev->autoneg = !AUTONEG_ENABLE; dev->force = 1; dev->link = 1; } else if (dev->dev_flags & PHYLIB_FORCE_100) { dev->speed = SPEED_100; dev->duplex = DUPLEX_FULL; dev->autoneg = !AUTONEG_ENABLE; dev->force = 1; dev->link = 1; } } /* Start out supporting everything. Eventually, * a controller will attach, and may modify one * or both of these values */ dev->supported = drv->features; dev->advertising = drv->features; ret = phy_init_hw(dev); if (ret) goto err; /* Sanitize settings based on PHY capabilities */ if ((dev->supported & SUPPORTED_Autoneg) == 0) dev->autoneg = AUTONEG_DISABLE; sprintf(str, "%d", dev->addr); dev_add_param_fixed(&dev->dev, "phy_addr", str); sprintf(str, "0x%08x", dev->phy_id); dev_add_param_fixed(&dev->dev, "phy_id", str); dev->cdev.name = asprintf("phy%d", _dev->id); dev->cdev.size = 64; dev->cdev.ops = &phydev_ops; dev->cdev.priv = dev; dev->cdev.dev = _dev; devfs_create(&dev->cdev); return 0; err: dev->attached_dev->phydev = NULL; dev->attached_dev = NULL; return ret; }