Merge branch 'mdio-devices'
Andrew Lunn says: ==================== Support MDIO devices The discussions about changing the way DSA probes switches resulted in the wish to have switches attached to an MDIO bus to be represented as an MDIO device. However the current code only supports PHYs on MDIO busses. This patchset remedies this problem. It consists of a number of cleanups, abstraction for accessing structure members, and refactoring, as well as adding the concept of a generic MDIO device and MDIO driver. v2: Added Reviewed-by from Florian Made phydev_name() an inline function Added phy_attached_info/phy_attached_print() for information about the attached phy. Removed now redundant irq setup from of_mdio.c Dropped hunks from PHYMII ioctl which prevented access to any address DSA carrier off before phy setup ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
1235817753
|
@ -131,23 +131,15 @@ static int ep8248e_mdio_probe(struct platform_device *ofdev)
|
|||
if (!bus)
|
||||
return -ENOMEM;
|
||||
|
||||
bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (bus->irq == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_bus;
|
||||
}
|
||||
|
||||
bus->name = "ep8248e-mdio-bitbang";
|
||||
bus->parent = &ofdev->dev;
|
||||
snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
|
||||
|
||||
ret = of_mdiobus_register(bus, ofdev->dev.of_node);
|
||||
if (ret)
|
||||
goto err_free_irq;
|
||||
goto err_free_bus;
|
||||
|
||||
return 0;
|
||||
err_free_irq:
|
||||
kfree(bus->irq);
|
||||
err_free_bus:
|
||||
free_mdio_bitbang(bus);
|
||||
return ret;
|
||||
|
|
|
@ -41,7 +41,6 @@ static void __iomem *gpio_regs;
|
|||
struct gpio_priv {
|
||||
int mdc_pin;
|
||||
int mdio_pin;
|
||||
int mdio_irqs[PHY_MAX_ADDR];
|
||||
};
|
||||
|
||||
#define MDC_PIN(bus) (((struct gpio_priv *)bus->priv)->mdc_pin)
|
||||
|
@ -245,8 +244,6 @@ static int gpio_mdio_probe(struct platform_device *ofdev)
|
|||
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", *prop);
|
||||
new_bus->priv = priv;
|
||||
|
||||
new_bus->irq = priv->mdio_irqs;
|
||||
|
||||
prop = of_get_property(np, "mdc-pin", NULL);
|
||||
priv->mdc_pin = *prop;
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ static int ax_mii_probe(struct net_device *dev)
|
|||
ax->phy_dev = phy_dev;
|
||||
|
||||
netdev_info(dev, "PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
|
||||
phy_dev->drv->name, dev_name(&phy_dev->dev), phy_dev->irq);
|
||||
phy_dev->drv->name, phydev_name(phy_dev), phy_dev->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -627,7 +627,7 @@ static int ax_mii_init(struct net_device *dev)
|
|||
struct platform_device *pdev = to_platform_device(dev->dev.parent);
|
||||
struct ei_device *ei_local = netdev_priv(dev);
|
||||
struct ax_device *ax = to_ax_dev(dev);
|
||||
int err, i;
|
||||
int err;
|
||||
|
||||
ax->bb_ctrl.ops = &bb_ops;
|
||||
ax->addr_memr = ei_local->mem + AX_MEMR;
|
||||
|
@ -642,23 +642,12 @@ static int ax_mii_init(struct net_device *dev)
|
|||
snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
pdev->name, pdev->id);
|
||||
|
||||
ax->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!ax->mii_bus->irq) {
|
||||
err = -ENOMEM;
|
||||
goto out_free_mdio_bitbang;
|
||||
}
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
ax->mii_bus->irq[i] = PHY_POLL;
|
||||
|
||||
err = mdiobus_register(ax->mii_bus);
|
||||
if (err)
|
||||
goto out_free_irq;
|
||||
goto out_free_mdio_bitbang;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_irq:
|
||||
kfree(ax->mii_bus->irq);
|
||||
out_free_mdio_bitbang:
|
||||
free_mdio_bitbang(ax->mii_bus);
|
||||
out:
|
||||
|
|
|
@ -419,7 +419,7 @@ static int mii_probe(struct net_device *dev, int phy_mode)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
phydev = phy_connect(dev, dev_name(&phydev->dev),
|
||||
phydev = phy_connect(dev, phydev_name(phydev),
|
||||
&bfin_mac_adjust_link, phy_mode);
|
||||
|
||||
if (IS_ERR(phydev)) {
|
||||
|
@ -444,10 +444,8 @@ static int mii_probe(struct net_device *dev, int phy_mode)
|
|||
lp->old_duplex = -1;
|
||||
lp->phydev = phydev;
|
||||
|
||||
pr_info("attached PHY driver [%s] "
|
||||
"(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)@sclk=%dMHz)\n",
|
||||
phydev->drv->name, dev_name(&phydev->dev), phydev->irq,
|
||||
MDC_CLK, mdc_div, sclk/1000000);
|
||||
phy_attached_print(phydev, "mdc_clk=%dHz(mdc_div=%d)@sclk=%dMHz)\n",
|
||||
MDC_CLK, mdc_div, sclk / 1000000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1840,12 +1838,6 @@ static int bfin_mii_bus_probe(struct platform_device *pdev)
|
|||
|
||||
snprintf(miibus->id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
pdev->name, pdev->id);
|
||||
miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!miibus->irq)
|
||||
goto out_err_irq_alloc;
|
||||
|
||||
for (i = rc; i < PHY_MAX_ADDR; ++i)
|
||||
miibus->irq[i] = PHY_POLL;
|
||||
|
||||
rc = clamp(mii_bus_pd->phydev_number, 0, PHY_MAX_ADDR);
|
||||
if (rc != mii_bus_pd->phydev_number)
|
||||
|
@ -1864,14 +1856,12 @@ static int bfin_mii_bus_probe(struct platform_device *pdev)
|
|||
rc = mdiobus_register(miibus);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
|
||||
goto out_err_mdiobus_register;
|
||||
goto out_err_alloc;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, miibus);
|
||||
return 0;
|
||||
|
||||
out_err_mdiobus_register:
|
||||
kfree(miibus->irq);
|
||||
out_err_irq_alloc:
|
||||
mdiobus_free(miibus);
|
||||
out_err_alloc:
|
||||
|
@ -1887,7 +1877,6 @@ static int bfin_mii_bus_remove(struct platform_device *pdev)
|
|||
dev_get_platdata(&pdev->dev);
|
||||
|
||||
mdiobus_unregister(miibus);
|
||||
kfree(miibus->irq);
|
||||
mdiobus_free(miibus);
|
||||
peripheral_free_list(mii_bus_pd->mac_peripherals);
|
||||
|
||||
|
|
|
@ -1337,11 +1337,6 @@ static int greth_mdio_init(struct greth_private *greth)
|
|||
greth->mdio->write = greth_mdio_write;
|
||||
greth->mdio->priv = greth;
|
||||
|
||||
greth->mdio->irq = greth->mdio_irqs;
|
||||
|
||||
for (phy = 0; phy < PHY_MAX_ADDR; phy++)
|
||||
greth->mdio->irq[phy] = PHY_POLL;
|
||||
|
||||
ret = mdiobus_register(greth->mdio);
|
||||
if (ret) {
|
||||
goto error;
|
||||
|
|
|
@ -125,7 +125,6 @@ struct greth_private {
|
|||
|
||||
struct phy_device *phy;
|
||||
struct mii_bus *mdio;
|
||||
int mdio_irqs[PHY_MAX_ADDR];
|
||||
unsigned int link;
|
||||
unsigned int speed;
|
||||
unsigned int duplex;
|
||||
|
|
|
@ -1235,7 +1235,7 @@ static int et131x_mii_read(struct et131x_adapter *adapter, u8 reg, u16 *value)
|
|||
if (!phydev)
|
||||
return -EIO;
|
||||
|
||||
return et131x_phy_mii_read(adapter, phydev->addr, reg, value);
|
||||
return et131x_phy_mii_read(adapter, phydev->mdio.addr, reg, value);
|
||||
}
|
||||
|
||||
static int et131x_mii_write(struct et131x_adapter *adapter, u8 addr, u8 reg,
|
||||
|
@ -1462,7 +1462,7 @@ static void et1310_phy_power_switch(struct et131x_adapter *adapter, bool down)
|
|||
data &= ~BMCR_PDOWN;
|
||||
if (down)
|
||||
data |= BMCR_PDOWN;
|
||||
et131x_mii_write(adapter, phydev->addr, MII_BMCR, data);
|
||||
et131x_mii_write(adapter, phydev->mdio.addr, MII_BMCR, data);
|
||||
}
|
||||
|
||||
/* et131x_xcvr_init - Init the phy if we are setting it into force mode */
|
||||
|
@ -1490,7 +1490,7 @@ static void et131x_xcvr_init(struct et131x_adapter *adapter)
|
|||
else
|
||||
lcr2 |= (LED_VAL_LINKON << LED_TXRX_SHIFT);
|
||||
|
||||
et131x_mii_write(adapter, phydev->addr, PHY_LED_2, lcr2);
|
||||
et131x_mii_write(adapter, phydev->mdio.addr, PHY_LED_2, lcr2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3192,14 +3192,14 @@ static void et131x_adjust_link(struct net_device *netdev)
|
|||
|
||||
et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG,
|
||||
®ister18);
|
||||
et131x_mii_write(adapter, phydev->addr,
|
||||
et131x_mii_write(adapter, phydev->mdio.addr,
|
||||
PHY_MPHY_CONTROL_REG,
|
||||
register18 | 0x4);
|
||||
et131x_mii_write(adapter, phydev->addr, PHY_INDEX_REG,
|
||||
register18 | 0x8402);
|
||||
et131x_mii_write(adapter, phydev->addr, PHY_DATA_REG,
|
||||
register18 | 511);
|
||||
et131x_mii_write(adapter, phydev->addr,
|
||||
et131x_mii_write(adapter, phydev->mdio.addr,
|
||||
PHY_INDEX_REG, register18 | 0x8402);
|
||||
et131x_mii_write(adapter, phydev->mdio.addr,
|
||||
PHY_DATA_REG, register18 | 511);
|
||||
et131x_mii_write(adapter, phydev->mdio.addr,
|
||||
PHY_MPHY_CONTROL_REG, register18);
|
||||
}
|
||||
|
||||
|
@ -3212,8 +3212,8 @@ static void et131x_adjust_link(struct net_device *netdev)
|
|||
et131x_mii_read(adapter, PHY_CONFIG, ®);
|
||||
reg &= ~ET_PHY_CONFIG_TX_FIFO_DEPTH;
|
||||
reg |= ET_PHY_CONFIG_FIFO_DEPTH_32;
|
||||
et131x_mii_write(adapter, phydev->addr, PHY_CONFIG,
|
||||
reg);
|
||||
et131x_mii_write(adapter, phydev->mdio.addr,
|
||||
PHY_CONFIG, reg);
|
||||
}
|
||||
|
||||
et131x_set_rx_dma_timer(adapter);
|
||||
|
@ -3226,14 +3226,14 @@ static void et131x_adjust_link(struct net_device *netdev)
|
|||
|
||||
et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG,
|
||||
®ister18);
|
||||
et131x_mii_write(adapter, phydev->addr,
|
||||
et131x_mii_write(adapter, phydev->mdio.addr,
|
||||
PHY_MPHY_CONTROL_REG,
|
||||
register18 | 0x4);
|
||||
et131x_mii_write(adapter, phydev->addr,
|
||||
et131x_mii_write(adapter, phydev->mdio.addr,
|
||||
PHY_INDEX_REG, register18 | 0x8402);
|
||||
et131x_mii_write(adapter, phydev->addr,
|
||||
et131x_mii_write(adapter, phydev->mdio.addr,
|
||||
PHY_DATA_REG, register18 | 511);
|
||||
et131x_mii_write(adapter, phydev->addr,
|
||||
et131x_mii_write(adapter, phydev->mdio.addr,
|
||||
PHY_MPHY_CONTROL_REG, register18);
|
||||
}
|
||||
|
||||
|
@ -3265,7 +3265,7 @@ static int et131x_mii_probe(struct net_device *netdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
phydev = phy_connect(netdev, dev_name(&phydev->dev),
|
||||
phydev = phy_connect(netdev, phydev_name(phydev),
|
||||
&et131x_adjust_link, PHY_INTERFACE_MODE_MII);
|
||||
|
||||
if (IS_ERR(phydev)) {
|
||||
|
@ -3289,9 +3289,7 @@ static int et131x_mii_probe(struct net_device *netdev)
|
|||
phydev->autoneg = AUTONEG_ENABLE;
|
||||
adapter->phydev = phydev;
|
||||
|
||||
dev_info(&adapter->pdev->dev,
|
||||
"attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
|
||||
phydev->drv->name, dev_name(&phydev->dev));
|
||||
phy_attached_info(phydev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3327,7 +3325,6 @@ static void et131x_pci_remove(struct pci_dev *pdev)
|
|||
netif_napi_del(&adapter->napi);
|
||||
phy_disconnect(adapter->phydev);
|
||||
mdiobus_unregister(adapter->mii_bus);
|
||||
kfree(adapter->mii_bus->irq);
|
||||
mdiobus_free(adapter->mii_bus);
|
||||
|
||||
et131x_adapter_memory_free(adapter);
|
||||
|
@ -3946,7 +3943,6 @@ static int et131x_pci_setup(struct pci_dev *pdev,
|
|||
struct net_device *netdev;
|
||||
struct et131x_adapter *adapter;
|
||||
int rc;
|
||||
int ii;
|
||||
|
||||
rc = pci_enable_device(pdev);
|
||||
if (rc < 0) {
|
||||
|
@ -4036,18 +4032,11 @@ static int et131x_pci_setup(struct pci_dev *pdev,
|
|||
adapter->mii_bus->priv = netdev;
|
||||
adapter->mii_bus->read = et131x_mdio_read;
|
||||
adapter->mii_bus->write = et131x_mdio_write;
|
||||
adapter->mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int),
|
||||
GFP_KERNEL);
|
||||
if (!adapter->mii_bus->irq)
|
||||
goto err_mdio_free;
|
||||
|
||||
for (ii = 0; ii < PHY_MAX_ADDR; ii++)
|
||||
adapter->mii_bus->irq[ii] = PHY_POLL;
|
||||
|
||||
rc = mdiobus_register(adapter->mii_bus);
|
||||
if (rc < 0) {
|
||||
dev_err(&pdev->dev, "failed to register MII bus\n");
|
||||
goto err_mdio_free_irq;
|
||||
goto err_mdio_free;
|
||||
}
|
||||
|
||||
rc = et131x_mii_probe(netdev);
|
||||
|
@ -4087,8 +4076,6 @@ static int et131x_pci_setup(struct pci_dev *pdev,
|
|||
phy_disconnect(adapter->phydev);
|
||||
err_mdio_unregister:
|
||||
mdiobus_unregister(adapter->mii_bus);
|
||||
err_mdio_free_irq:
|
||||
kfree(adapter->mii_bus->irq);
|
||||
err_mdio_free:
|
||||
mdiobus_free(adapter->mii_bus);
|
||||
err_mem_free:
|
||||
|
|
|
@ -131,7 +131,6 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id)
|
|||
{
|
||||
struct altera_tse_private *priv = netdev_priv(dev);
|
||||
int ret;
|
||||
int i;
|
||||
struct device_node *mdio_node = NULL;
|
||||
struct mii_bus *mdio = NULL;
|
||||
struct device_node *child_node = NULL;
|
||||
|
@ -161,14 +160,6 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id)
|
|||
mdio->write = &altera_tse_mdio_write;
|
||||
snprintf(mdio->id, MII_BUS_ID_SIZE, "%s-%u", mdio->name, id);
|
||||
|
||||
mdio->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
|
||||
if (mdio->irq == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto out_free_mdio;
|
||||
}
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
mdio->irq[i] = PHY_POLL;
|
||||
|
||||
mdio->priv = dev;
|
||||
mdio->parent = priv->device;
|
||||
|
||||
|
@ -176,7 +167,7 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id)
|
|||
if (ret != 0) {
|
||||
netdev_err(dev, "Cannot register MDIO bus %s\n",
|
||||
mdio->id);
|
||||
goto out_free_mdio_irq;
|
||||
goto out_free_mdio;
|
||||
}
|
||||
|
||||
if (netif_msg_drv(priv))
|
||||
|
@ -184,8 +175,6 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id)
|
|||
|
||||
priv->mdio = mdio;
|
||||
return 0;
|
||||
out_free_mdio_irq:
|
||||
kfree(mdio->irq);
|
||||
out_free_mdio:
|
||||
mdiobus_free(mdio);
|
||||
mdio = NULL;
|
||||
|
@ -855,7 +844,7 @@ static int init_phy(struct net_device *dev)
|
|||
}
|
||||
|
||||
netdev_dbg(dev, "attached to PHY %d UID 0x%08x Link = %d\n",
|
||||
phydev->addr, phydev->phy_id, phydev->link);
|
||||
phydev->mdio.addr, phydev->phy_id, phydev->link);
|
||||
|
||||
priv->phydev = phydev;
|
||||
return 0;
|
||||
|
|
|
@ -502,7 +502,7 @@ static int au1000_mii_probe(struct net_device *dev)
|
|||
BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
|
||||
|
||||
if (aup->phy_addr)
|
||||
phydev = aup->mii_bus->phy_map[aup->phy_addr];
|
||||
phydev = mdiobus_get_phy(aup->mii_bus, aup->phy_addr);
|
||||
else
|
||||
netdev_info(dev, "using PHY-less setup\n");
|
||||
return 0;
|
||||
|
@ -512,8 +512,8 @@ static int au1000_mii_probe(struct net_device *dev)
|
|||
* on the current MAC's MII bus
|
||||
*/
|
||||
for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
|
||||
if (aup->mii_bus->phy_map[phy_addr]) {
|
||||
phydev = aup->mii_bus->phy_map[phy_addr];
|
||||
if (mdiobus_get_phy(aup->mii_bus, aup->phy_addr)) {
|
||||
phydev = mdiobus_get_phy(aup->mii_bus, aup->phy_addr);
|
||||
if (!aup->phy_search_highest_addr)
|
||||
/* break out with first one found */
|
||||
break;
|
||||
|
@ -531,7 +531,8 @@ static int au1000_mii_probe(struct net_device *dev)
|
|||
*/
|
||||
for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
|
||||
struct phy_device *const tmp_phydev =
|
||||
aup->mii_bus->phy_map[phy_addr];
|
||||
mdiobus_get_phy(aup->mii_bus,
|
||||
phy_addr);
|
||||
|
||||
if (aup->mac_id == 1)
|
||||
break;
|
||||
|
@ -558,7 +559,7 @@ static int au1000_mii_probe(struct net_device *dev)
|
|||
/* now we are supposed to have a proper phydev, to attach to... */
|
||||
BUG_ON(phydev->attached_dev);
|
||||
|
||||
phydev = phy_connect(dev, dev_name(&phydev->dev),
|
||||
phydev = phy_connect(dev, phydev_name(phydev),
|
||||
&au1000_adjust_link, PHY_INTERFACE_MODE_MII);
|
||||
|
||||
if (IS_ERR(phydev)) {
|
||||
|
@ -583,9 +584,7 @@ static int au1000_mii_probe(struct net_device *dev)
|
|||
aup->old_duplex = -1;
|
||||
aup->phy_dev = phydev;
|
||||
|
||||
netdev_info(dev, "attached PHY driver [%s] "
|
||||
"(mii_bus:phy_addr=%s, irq=%d)\n",
|
||||
phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
|
||||
phy_attached_info(phydev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1293,14 +1292,7 @@ static int au1000_probe(struct platform_device *pdev)
|
|||
aup->mii_bus->name = "au1000_eth_mii";
|
||||
snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
pdev->name, aup->mac_id);
|
||||
aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (aup->mii_bus->irq == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; ++i)
|
||||
aup->mii_bus->irq[i] = PHY_POLL;
|
||||
/* if known, set corresponding PHY IRQs */
|
||||
if (aup->phy_static_config)
|
||||
if (aup->phy_irq && aup->phy_busid == aup->mac_id)
|
||||
|
|
|
@ -2263,24 +2263,16 @@ static int b44_register_phy_one(struct b44 *bp)
|
|||
mii_bus->parent = sdev->dev;
|
||||
mii_bus->phy_mask = ~(1 << bp->phy_addr);
|
||||
snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%x", instance);
|
||||
mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!mii_bus->irq) {
|
||||
dev_err(sdev->dev, "mii_bus irq allocation failed\n");
|
||||
err = -ENOMEM;
|
||||
goto err_out_mdiobus;
|
||||
}
|
||||
|
||||
memset(mii_bus->irq, PHY_POLL, sizeof(int) * PHY_MAX_ADDR);
|
||||
|
||||
bp->mii_bus = mii_bus;
|
||||
|
||||
err = mdiobus_register(mii_bus);
|
||||
if (err) {
|
||||
dev_err(sdev->dev, "failed to register MII bus\n");
|
||||
goto err_out_mdiobus_irq;
|
||||
goto err_out_mdiobus;
|
||||
}
|
||||
|
||||
if (!bp->mii_bus->phy_map[bp->phy_addr] &&
|
||||
if (!mdiobus_is_registered_device(bp->mii_bus, bp->phy_addr) &&
|
||||
(sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) {
|
||||
|
||||
dev_info(sdev->dev,
|
||||
|
@ -2313,19 +2305,15 @@ static int b44_register_phy_one(struct b44 *bp)
|
|||
|
||||
bp->phydev = phydev;
|
||||
bp->old_link = 0;
|
||||
bp->phy_addr = phydev->addr;
|
||||
bp->phy_addr = phydev->mdio.addr;
|
||||
|
||||
dev_info(sdev->dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
|
||||
phydev->drv->name, dev_name(&phydev->dev));
|
||||
phy_attached_info(phydev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_out_mdiobus_unregister:
|
||||
mdiobus_unregister(mii_bus);
|
||||
|
||||
err_out_mdiobus_irq:
|
||||
kfree(mii_bus->irq);
|
||||
|
||||
err_out_mdiobus:
|
||||
mdiobus_free(mii_bus);
|
||||
|
||||
|
@ -2339,7 +2327,6 @@ static void b44_unregister_phy_one(struct b44 *bp)
|
|||
|
||||
phy_disconnect(bp->phydev);
|
||||
mdiobus_unregister(mii_bus);
|
||||
kfree(mii_bus->irq);
|
||||
mdiobus_free(mii_bus);
|
||||
}
|
||||
|
||||
|
|
|
@ -908,8 +908,7 @@ static int bcm_enet_open(struct net_device *dev)
|
|||
else
|
||||
phydev->advertising &= ~SUPPORTED_Pause;
|
||||
|
||||
dev_info(kdev, "attached PHY at address %d [%s]\n",
|
||||
phydev->addr, phydev->drv->name);
|
||||
phy_attached_info(phydev);
|
||||
|
||||
priv->old_link = 0;
|
||||
priv->old_duplex = -1;
|
||||
|
@ -1849,17 +1848,8 @@ static int bcm_enet_probe(struct platform_device *pdev)
|
|||
* if a slave is not present on hw */
|
||||
bus->phy_mask = ~(1 << priv->phy_id);
|
||||
|
||||
bus->irq = devm_kzalloc(&pdev->dev, sizeof(int) * PHY_MAX_ADDR,
|
||||
GFP_KERNEL);
|
||||
if (!bus->irq) {
|
||||
ret = -ENOMEM;
|
||||
goto out_free_mdio;
|
||||
}
|
||||
|
||||
if (priv->has_phy_interrupt)
|
||||
bus->irq[priv->phy_id] = priv->phy_interrupt;
|
||||
else
|
||||
bus->irq[priv->phy_id] = PHY_POLL;
|
||||
|
||||
ret = mdiobus_register(bus);
|
||||
if (ret) {
|
||||
|
|
|
@ -1471,7 +1471,7 @@ static int bgmac_mii_register(struct bgmac *bgmac)
|
|||
struct mii_bus *mii_bus;
|
||||
struct phy_device *phy_dev;
|
||||
char bus_id[MII_BUS_ID_SIZE + 3];
|
||||
int i, err = 0;
|
||||
int err = 0;
|
||||
|
||||
if (ci->id == BCMA_CHIP_ID_BCM4707 ||
|
||||
ci->id == BCMA_CHIP_ID_BCM53018)
|
||||
|
@ -1490,18 +1490,10 @@ static int bgmac_mii_register(struct bgmac *bgmac)
|
|||
mii_bus->parent = &bgmac->core->dev;
|
||||
mii_bus->phy_mask = ~(1 << bgmac->phyaddr);
|
||||
|
||||
mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
|
||||
if (!mii_bus->irq) {
|
||||
err = -ENOMEM;
|
||||
goto err_free_bus;
|
||||
}
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
mii_bus->irq[i] = PHY_POLL;
|
||||
|
||||
err = mdiobus_register(mii_bus);
|
||||
if (err) {
|
||||
bgmac_err(bgmac, "Registration of mii bus failed\n");
|
||||
goto err_free_irq;
|
||||
goto err_free_bus;
|
||||
}
|
||||
|
||||
bgmac->mii_bus = mii_bus;
|
||||
|
@ -1522,8 +1514,6 @@ static int bgmac_mii_register(struct bgmac *bgmac)
|
|||
|
||||
err_unregister_bus:
|
||||
mdiobus_unregister(mii_bus);
|
||||
err_free_irq:
|
||||
kfree(mii_bus->irq);
|
||||
err_free_bus:
|
||||
mdiobus_free(mii_bus);
|
||||
return err;
|
||||
|
@ -1534,7 +1524,6 @@ static void bgmac_mii_unregister(struct bgmac *bgmac)
|
|||
struct mii_bus *mii_bus = bgmac->mii_bus;
|
||||
|
||||
mdiobus_unregister(mii_bus);
|
||||
kfree(mii_bus->irq);
|
||||
mdiobus_free(mii_bus);
|
||||
}
|
||||
|
||||
|
|
|
@ -401,9 +401,7 @@ int bcmgenet_mii_probe(struct net_device *dev)
|
|||
* Ethernet MAC ISRs
|
||||
*/
|
||||
if (priv->internal_phy)
|
||||
priv->mii_bus->irq[phydev->addr] = PHY_IGNORE_INTERRUPT;
|
||||
else
|
||||
priv->mii_bus->irq[phydev->addr] = PHY_POLL;
|
||||
priv->mii_bus->irq[phydev->mdio.addr] = PHY_IGNORE_INTERRUPT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -477,12 +475,6 @@ static int bcmgenet_mii_alloc(struct bcmgenet_priv *priv)
|
|||
snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d",
|
||||
priv->pdev->name, priv->pdev->id);
|
||||
|
||||
bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
|
||||
if (!bus->irq) {
|
||||
mdiobus_free(priv->mii_bus);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -581,7 +573,7 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
|
|||
}
|
||||
|
||||
if (pd->phy_address >= 0 && pd->phy_address < PHY_MAX_ADDR)
|
||||
phydev = mdio->phy_map[pd->phy_address];
|
||||
phydev = mdiobus_get_phy(mdio, pd->phy_address);
|
||||
else
|
||||
phydev = phy_find_first(mdio);
|
||||
|
||||
|
@ -648,7 +640,6 @@ int bcmgenet_mii_init(struct net_device *dev)
|
|||
out:
|
||||
of_node_put(priv->phy_dn);
|
||||
mdiobus_unregister(priv->mii_bus);
|
||||
kfree(priv->mii_bus->irq);
|
||||
mdiobus_free(priv->mii_bus);
|
||||
return ret;
|
||||
}
|
||||
|
@ -659,6 +650,5 @@ void bcmgenet_mii_exit(struct net_device *dev)
|
|||
|
||||
of_node_put(priv->phy_dn);
|
||||
mdiobus_unregister(priv->mii_bus);
|
||||
kfree(priv->mii_bus->irq);
|
||||
mdiobus_free(priv->mii_bus);
|
||||
}
|
||||
|
|
|
@ -238,7 +238,6 @@ struct sbmac_softc {
|
|||
struct napi_struct napi;
|
||||
struct phy_device *phy_dev; /* the associated PHY device */
|
||||
struct mii_bus *mii_bus; /* the MII bus */
|
||||
int phy_irq[PHY_MAX_ADDR];
|
||||
spinlock_t sbm_lock; /* spin lock */
|
||||
int sbm_devflags; /* current device flags */
|
||||
|
||||
|
@ -2250,9 +2249,6 @@ static int sbmac_init(struct platform_device *pldev, long long base)
|
|||
sc->mii_bus->priv = sc;
|
||||
sc->mii_bus->read = sbmac_mii_read;
|
||||
sc->mii_bus->write = sbmac_mii_write;
|
||||
sc->mii_bus->irq = sc->phy_irq;
|
||||
for (i = 0; i < PHY_MAX_ADDR; ++i)
|
||||
sc->mii_bus->irq[i] = SBMAC_PHY_INT;
|
||||
|
||||
sc->mii_bus->parent = &pldev->dev;
|
||||
/*
|
||||
|
@ -2370,8 +2366,8 @@ static int sbmac_mii_probe(struct net_device *dev)
|
|||
return -ENXIO;
|
||||
}
|
||||
|
||||
phy_dev = phy_connect(dev, dev_name(&phy_dev->dev), &sbmac_mii_poll,
|
||||
PHY_INTERFACE_MODE_GMII);
|
||||
phy_dev = phy_connect(dev, dev_name(&phy_dev->mdio.dev),
|
||||
&sbmac_mii_poll, PHY_INTERFACE_MODE_GMII);
|
||||
if (IS_ERR(phy_dev)) {
|
||||
printk(KERN_ERR "%s: could not attach to PHY\n", dev->name);
|
||||
return PTR_ERR(phy_dev);
|
||||
|
@ -2388,11 +2384,10 @@ static int sbmac_mii_probe(struct net_device *dev)
|
|||
SUPPORTED_MII |
|
||||
SUPPORTED_Pause |
|
||||
SUPPORTED_Asym_Pause;
|
||||
phy_dev->advertising = phy_dev->supported;
|
||||
|
||||
pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
|
||||
dev->name, phy_dev->drv->name,
|
||||
dev_name(&phy_dev->dev), phy_dev->irq);
|
||||
phy_attached_info(phydev);
|
||||
|
||||
phy_dev->advertising = phy_dev->supported;
|
||||
|
||||
sc->phy_dev = phy_dev;
|
||||
|
||||
|
|
|
@ -1406,7 +1406,7 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
|
|||
u32 val;
|
||||
struct phy_device *phydev;
|
||||
|
||||
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
|
||||
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
|
||||
switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
|
||||
case PHY_ID_BCM50610:
|
||||
case PHY_ID_BCM50610M:
|
||||
|
@ -1538,10 +1538,6 @@ static int tg3_mdio_init(struct tg3 *tp)
|
|||
tp->mdio_bus->read = &tg3_mdio_read;
|
||||
tp->mdio_bus->write = &tg3_mdio_write;
|
||||
tp->mdio_bus->phy_mask = ~(1 << tp->phy_addr);
|
||||
tp->mdio_bus->irq = &tp->mdio_irq[0];
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
tp->mdio_bus->irq[i] = PHY_POLL;
|
||||
|
||||
/* The bus registration will look for all the PHYs on the mdio bus.
|
||||
* Unfortunately, it does not ensure the PHY is powered up before
|
||||
|
@ -1558,7 +1554,7 @@ static int tg3_mdio_init(struct tg3 *tp)
|
|||
return i;
|
||||
}
|
||||
|
||||
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
|
||||
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
|
||||
|
||||
if (!phydev || !phydev->drv) {
|
||||
dev_warn(&tp->pdev->dev, "No PHY devices\n");
|
||||
|
@ -1968,7 +1964,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
|
|||
u32 old_tx_mode = tp->tx_mode;
|
||||
|
||||
if (tg3_flag(tp, USE_PHYLIB))
|
||||
autoneg = tp->mdio_bus->phy_map[tp->phy_addr]->autoneg;
|
||||
autoneg = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr)->autoneg;
|
||||
else
|
||||
autoneg = tp->link_config.autoneg;
|
||||
|
||||
|
@ -2004,7 +2000,7 @@ static void tg3_adjust_link(struct net_device *dev)
|
|||
u8 oldflowctrl, linkmesg = 0;
|
||||
u32 mac_mode, lcl_adv, rmt_adv;
|
||||
struct tg3 *tp = netdev_priv(dev);
|
||||
struct phy_device *phydev = tp->mdio_bus->phy_map[tp->phy_addr];
|
||||
struct phy_device *phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
|
||||
|
||||
spin_lock_bh(&tp->lock);
|
||||
|
||||
|
@ -2093,10 +2089,10 @@ static int tg3_phy_init(struct tg3 *tp)
|
|||
/* Bring the PHY back to a known state. */
|
||||
tg3_bmcr_reset(tp);
|
||||
|
||||
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
|
||||
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
|
||||
|
||||
/* Attach the MAC to the PHY. */
|
||||
phydev = phy_connect(tp->dev, dev_name(&phydev->dev),
|
||||
phydev = phy_connect(tp->dev, phydev_name(phydev),
|
||||
tg3_adjust_link, phydev->interface);
|
||||
if (IS_ERR(phydev)) {
|
||||
dev_err(&tp->pdev->dev, "Could not attach to PHY\n");
|
||||
|
@ -2120,7 +2116,7 @@ static int tg3_phy_init(struct tg3 *tp)
|
|||
SUPPORTED_Asym_Pause);
|
||||
break;
|
||||
default:
|
||||
phy_disconnect(tp->mdio_bus->phy_map[tp->phy_addr]);
|
||||
phy_disconnect(mdiobus_get_phy(tp->mdio_bus, tp->phy_addr));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -2128,6 +2124,8 @@ static int tg3_phy_init(struct tg3 *tp)
|
|||
|
||||
phydev->advertising = phydev->supported;
|
||||
|
||||
phy_attached_info(phydev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2138,7 +2136,7 @@ static void tg3_phy_start(struct tg3 *tp)
|
|||
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
|
||||
return;
|
||||
|
||||
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
|
||||
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
|
||||
|
||||
if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
|
||||
tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER;
|
||||
|
@ -2158,13 +2156,13 @@ static void tg3_phy_stop(struct tg3 *tp)
|
|||
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
|
||||
return;
|
||||
|
||||
phy_stop(tp->mdio_bus->phy_map[tp->phy_addr]);
|
||||
phy_stop(mdiobus_get_phy(tp->mdio_bus, tp->phy_addr));
|
||||
}
|
||||
|
||||
static void tg3_phy_fini(struct tg3 *tp)
|
||||
{
|
||||
if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) {
|
||||
phy_disconnect(tp->mdio_bus->phy_map[tp->phy_addr]);
|
||||
phy_disconnect(mdiobus_get_phy(tp->mdio_bus, tp->phy_addr));
|
||||
tp->phy_flags &= ~TG3_PHYFLG_IS_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
@ -4048,7 +4046,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
|
|||
struct phy_device *phydev;
|
||||
u32 phyid, advertising;
|
||||
|
||||
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
|
||||
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
|
||||
|
||||
tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER;
|
||||
|
||||
|
@ -12076,7 +12074,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
|||
struct phy_device *phydev;
|
||||
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
|
||||
return -EAGAIN;
|
||||
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
|
||||
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
|
||||
return phy_ethtool_gset(phydev, cmd);
|
||||
}
|
||||
|
||||
|
@ -12143,7 +12141,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
|||
struct phy_device *phydev;
|
||||
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
|
||||
return -EAGAIN;
|
||||
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
|
||||
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
|
||||
return phy_ethtool_sset(phydev, cmd);
|
||||
}
|
||||
|
||||
|
@ -12298,7 +12296,7 @@ static int tg3_nway_reset(struct net_device *dev)
|
|||
if (tg3_flag(tp, USE_PHYLIB)) {
|
||||
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
|
||||
return -EAGAIN;
|
||||
r = phy_start_aneg(tp->mdio_bus->phy_map[tp->phy_addr]);
|
||||
r = phy_start_aneg(mdiobus_get_phy(tp->mdio_bus, tp->phy_addr));
|
||||
} else {
|
||||
u32 bmcr;
|
||||
|
||||
|
@ -12416,7 +12414,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
|
|||
u32 newadv;
|
||||
struct phy_device *phydev;
|
||||
|
||||
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
|
||||
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
|
||||
|
||||
if (!(phydev->supported & SUPPORTED_Pause) ||
|
||||
(!(phydev->supported & SUPPORTED_Asym_Pause) &&
|
||||
|
@ -13926,7 +13924,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|||
struct phy_device *phydev;
|
||||
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
|
||||
return -EAGAIN;
|
||||
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
|
||||
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
|
||||
return phy_mii_ioctl(phydev, ifr, cmd);
|
||||
}
|
||||
|
||||
|
@ -17898,13 +17896,7 @@ static int tg3_init_one(struct pci_dev *pdev,
|
|||
tg3_bus_string(tp, str),
|
||||
dev->dev_addr);
|
||||
|
||||
if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) {
|
||||
struct phy_device *phydev;
|
||||
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
|
||||
netdev_info(dev,
|
||||
"attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
|
||||
phydev->drv->name, dev_name(&phydev->dev));
|
||||
} else {
|
||||
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) {
|
||||
char *ethtype;
|
||||
|
||||
if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
|
||||
|
|
|
@ -3254,7 +3254,6 @@ struct tg3 {
|
|||
int pcie_readrq;
|
||||
|
||||
struct mii_bus *mdio_bus;
|
||||
int mdio_irq[PHY_MAX_ADDR];
|
||||
int old_link;
|
||||
|
||||
u8 phy_addr;
|
||||
|
|
|
@ -441,12 +441,6 @@ static int macb_mii_init(struct macb *bp)
|
|||
bp->mii_bus->parent = &bp->dev->dev;
|
||||
pdata = dev_get_platdata(&bp->pdev->dev);
|
||||
|
||||
bp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!bp->mii_bus->irq) {
|
||||
err = -ENOMEM;
|
||||
goto err_out_free_mdiobus;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&bp->dev->dev, bp->mii_bus);
|
||||
|
||||
np = bp->pdev->dev.of_node;
|
||||
|
@ -471,9 +465,6 @@ static int macb_mii_init(struct macb *bp)
|
|||
goto err_out_unregister_bus;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
bp->mii_bus->irq[i] = PHY_POLL;
|
||||
|
||||
if (pdata)
|
||||
bp->mii_bus->phy_mask = pdata->phy_mask;
|
||||
|
||||
|
@ -481,7 +472,7 @@ static int macb_mii_init(struct macb *bp)
|
|||
}
|
||||
|
||||
if (err)
|
||||
goto err_out_free_mdio_irq;
|
||||
goto err_out_free_mdiobus;
|
||||
|
||||
err = macb_mii_probe(bp->dev);
|
||||
if (err)
|
||||
|
@ -491,8 +482,6 @@ static int macb_mii_init(struct macb *bp)
|
|||
|
||||
err_out_unregister_bus:
|
||||
mdiobus_unregister(bp->mii_bus);
|
||||
err_out_free_mdio_irq:
|
||||
kfree(bp->mii_bus->irq);
|
||||
err_out_free_mdiobus:
|
||||
mdiobus_free(bp->mii_bus);
|
||||
err_out:
|
||||
|
@ -2950,8 +2939,7 @@ static int macb_probe(struct platform_device *pdev)
|
|||
dev->base_addr, dev->irq, dev->dev_addr);
|
||||
|
||||
phydev = bp->phy_dev;
|
||||
netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
|
||||
phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
|
||||
phy_attached_info(phydev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -2981,7 +2969,6 @@ static int macb_remove(struct platform_device *pdev)
|
|||
if (bp->phy_dev)
|
||||
phy_disconnect(bp->phy_dev);
|
||||
mdiobus_unregister(bp->mii_bus);
|
||||
kfree(bp->mii_bus->irq);
|
||||
mdiobus_free(bp->mii_bus);
|
||||
|
||||
/* Shutdown the PHY if there is a GPIO reset */
|
||||
|
|
|
@ -255,15 +255,9 @@ static int dnet_mii_probe(struct net_device *dev)
|
|||
{
|
||||
struct dnet *bp = netdev_priv(dev);
|
||||
struct phy_device *phydev = NULL;
|
||||
int phy_addr;
|
||||
|
||||
/* find the first phy */
|
||||
for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
|
||||
if (bp->mii_bus->phy_map[phy_addr]) {
|
||||
phydev = bp->mii_bus->phy_map[phy_addr];
|
||||
break;
|
||||
}
|
||||
}
|
||||
phydev = phy_find_first(bp->mii_bus);
|
||||
|
||||
if (!phydev) {
|
||||
printk(KERN_ERR "%s: no PHY found\n", dev->name);
|
||||
|
@ -274,11 +268,11 @@ static int dnet_mii_probe(struct net_device *dev)
|
|||
|
||||
/* attach the mac to the phy */
|
||||
if (bp->capabilities & DNET_HAS_RMII) {
|
||||
phydev = phy_connect(dev, dev_name(&phydev->dev),
|
||||
phydev = phy_connect(dev, phydev_name(phydev),
|
||||
&dnet_handle_link_change,
|
||||
PHY_INTERFACE_MODE_RMII);
|
||||
} else {
|
||||
phydev = phy_connect(dev, dev_name(&phydev->dev),
|
||||
phydev = phy_connect(dev, phydev_name(phydev),
|
||||
&dnet_handle_link_change,
|
||||
PHY_INTERFACE_MODE_MII);
|
||||
}
|
||||
|
@ -308,7 +302,7 @@ static int dnet_mii_probe(struct net_device *dev)
|
|||
|
||||
static int dnet_mii_init(struct dnet *bp)
|
||||
{
|
||||
int err, i;
|
||||
int err;
|
||||
|
||||
bp->mii_bus = mdiobus_alloc();
|
||||
if (bp->mii_bus == NULL)
|
||||
|
@ -323,16 +317,6 @@ static int dnet_mii_init(struct dnet *bp)
|
|||
|
||||
bp->mii_bus->priv = bp;
|
||||
|
||||
bp->mii_bus->irq = devm_kmalloc(&bp->pdev->dev,
|
||||
sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!bp->mii_bus->irq) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
bp->mii_bus->irq[i] = PHY_POLL;
|
||||
|
||||
if (mdiobus_register(bp->mii_bus)) {
|
||||
err = -ENXIO;
|
||||
goto err_out;
|
||||
|
@ -892,9 +876,7 @@ static int dnet_probe(struct platform_device *pdev)
|
|||
(bp->capabilities & DNET_HAS_GIGABIT) ? "" : "no ",
|
||||
(bp->capabilities & DNET_HAS_DMA) ? "" : "no ");
|
||||
phydev = bp->phy_dev;
|
||||
dev_info(&pdev->dev, "attached PHY driver [%s] "
|
||||
"(mii_bus:phy_addr=%s, irq=%d)\n",
|
||||
phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
|
||||
phy_attached_info(phydev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -678,7 +678,7 @@ static int ethoc_mdio_probe(struct net_device *dev)
|
|||
int err;
|
||||
|
||||
if (priv->phy_id != -1)
|
||||
phy = priv->mdio->phy_map[priv->phy_id];
|
||||
phy = mdiobus_get_phy(priv->mdio, priv->phy_id);
|
||||
else
|
||||
phy = phy_find_first(priv->mdio);
|
||||
|
||||
|
@ -766,7 +766,7 @@ static int ethoc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|||
if (mdio->phy_id >= PHY_MAX_ADDR)
|
||||
return -ERANGE;
|
||||
|
||||
phy = priv->mdio->phy_map[mdio->phy_id];
|
||||
phy = mdiobus_get_phy(priv->mdio, mdio->phy_id);
|
||||
if (!phy)
|
||||
return -ENODEV;
|
||||
} else {
|
||||
|
@ -1015,7 +1015,6 @@ static int ethoc_probe(struct platform_device *pdev)
|
|||
struct resource *mmio = NULL;
|
||||
struct resource *mem = NULL;
|
||||
struct ethoc *priv = NULL;
|
||||
unsigned int phy;
|
||||
int num_bd;
|
||||
int ret = 0;
|
||||
bool random_mac = false;
|
||||
|
@ -1206,19 +1205,10 @@ static int ethoc_probe(struct platform_device *pdev)
|
|||
priv->mdio->write = ethoc_mdio_write;
|
||||
priv->mdio->priv = priv;
|
||||
|
||||
priv->mdio->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!priv->mdio->irq) {
|
||||
ret = -ENOMEM;
|
||||
goto free_mdio;
|
||||
}
|
||||
|
||||
for (phy = 0; phy < PHY_MAX_ADDR; phy++)
|
||||
priv->mdio->irq[phy] = PHY_POLL;
|
||||
|
||||
ret = mdiobus_register(priv->mdio);
|
||||
if (ret) {
|
||||
dev_err(&netdev->dev, "failed to register MDIO bus\n");
|
||||
goto free_mdio;
|
||||
goto free;
|
||||
}
|
||||
|
||||
ret = ethoc_mdio_probe(netdev);
|
||||
|
@ -1250,8 +1240,6 @@ static int ethoc_probe(struct platform_device *pdev)
|
|||
netif_napi_del(&priv->napi);
|
||||
error:
|
||||
mdiobus_unregister(priv->mdio);
|
||||
free_mdio:
|
||||
kfree(priv->mdio->irq);
|
||||
mdiobus_free(priv->mdio);
|
||||
free:
|
||||
if (priv->clk)
|
||||
|
|
|
@ -71,7 +71,6 @@ struct ftgmac100 {
|
|||
struct napi_struct napi;
|
||||
|
||||
struct mii_bus *mii_bus;
|
||||
int phy_irq[PHY_MAX_ADDR];
|
||||
struct phy_device *phydev;
|
||||
int old_speed;
|
||||
};
|
||||
|
@ -840,7 +839,7 @@ static int ftgmac100_mii_probe(struct ftgmac100 *priv)
|
|||
|
||||
/* search for connect PHY device */
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++) {
|
||||
struct phy_device *tmp = priv->mii_bus->phy_map[i];
|
||||
struct phy_device *tmp = mdiobus_get_phy(priv->mii_bus, i);
|
||||
|
||||
if (tmp) {
|
||||
phydev = tmp;
|
||||
|
@ -854,7 +853,7 @@ static int ftgmac100_mii_probe(struct ftgmac100 *priv)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
phydev = phy_connect(netdev, dev_name(&phydev->dev),
|
||||
phydev = phy_connect(netdev, phydev_name(phydev),
|
||||
&ftgmac100_adjust_link, PHY_INTERFACE_MODE_GMII);
|
||||
|
||||
if (IS_ERR(phydev)) {
|
||||
|
@ -1188,7 +1187,6 @@ static int ftgmac100_probe(struct platform_device *pdev)
|
|||
struct net_device *netdev;
|
||||
struct ftgmac100 *priv;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
if (!pdev)
|
||||
return -ENODEV;
|
||||
|
@ -1257,10 +1255,6 @@ static int ftgmac100_probe(struct platform_device *pdev)
|
|||
priv->mii_bus->priv = netdev;
|
||||
priv->mii_bus->read = ftgmac100_mdiobus_read;
|
||||
priv->mii_bus->write = ftgmac100_mdiobus_write;
|
||||
priv->mii_bus->irq = priv->phy_irq;
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
priv->mii_bus->irq[i] = PHY_POLL;
|
||||
|
||||
err = mdiobus_register(priv->mii_bus);
|
||||
if (err) {
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/fec.h>
|
||||
#include <linux/of.h>
|
||||
|
@ -1926,11 +1927,7 @@ static int fec_enet_mii_probe(struct net_device *ndev)
|
|||
} else {
|
||||
/* check for attached phy */
|
||||
for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {
|
||||
if ((fep->mii_bus->phy_mask & (1 << phy_id)))
|
||||
continue;
|
||||
if (fep->mii_bus->phy_map[phy_id] == NULL)
|
||||
continue;
|
||||
if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
|
||||
if (!mdiobus_is_registered_device(fep->mii_bus, phy_id))
|
||||
continue;
|
||||
if (dev_id--)
|
||||
continue;
|
||||
|
@ -1972,9 +1969,7 @@ static int fec_enet_mii_probe(struct net_device *ndev)
|
|||
fep->link = 0;
|
||||
fep->full_duplex = 0;
|
||||
|
||||
netdev_info(ndev, "Freescale FEC PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
|
||||
fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev),
|
||||
fep->phy_dev->irq);
|
||||
phy_attached_info(phy_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1985,7 +1980,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
|
|||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||
struct device_node *node;
|
||||
int err = -ENXIO, i;
|
||||
int err = -ENXIO;
|
||||
u32 mii_speed, holdtime;
|
||||
|
||||
/*
|
||||
|
@ -2067,15 +2062,6 @@ static int fec_enet_mii_init(struct platform_device *pdev)
|
|||
fep->mii_bus->priv = fep;
|
||||
fep->mii_bus->parent = &pdev->dev;
|
||||
|
||||
fep->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!fep->mii_bus->irq) {
|
||||
err = -ENOMEM;
|
||||
goto err_out_free_mdiobus;
|
||||
}
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
fep->mii_bus->irq[i] = PHY_POLL;
|
||||
|
||||
node = of_get_child_by_name(pdev->dev.of_node, "mdio");
|
||||
if (node) {
|
||||
err = of_mdiobus_register(fep->mii_bus, node);
|
||||
|
@ -2085,7 +2071,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
if (err)
|
||||
goto err_out_free_mdio_irq;
|
||||
goto err_out_free_mdiobus;
|
||||
|
||||
mii_cnt++;
|
||||
|
||||
|
@ -2095,8 +2081,6 @@ static int fec_enet_mii_init(struct platform_device *pdev)
|
|||
|
||||
return 0;
|
||||
|
||||
err_out_free_mdio_irq:
|
||||
kfree(fep->mii_bus->irq);
|
||||
err_out_free_mdiobus:
|
||||
mdiobus_free(fep->mii_bus);
|
||||
err_out:
|
||||
|
@ -2107,7 +2091,6 @@ static void fec_enet_mii_remove(struct fec_enet_private *fep)
|
|||
{
|
||||
if (--mii_cnt == 0) {
|
||||
mdiobus_unregister(fep->mii_bus);
|
||||
kfree(fep->mii_bus->irq);
|
||||
mdiobus_free(fep->mii_bus);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
struct mpc52xx_fec_mdio_priv {
|
||||
struct mpc52xx_fec __iomem *regs;
|
||||
int mdio_irqs[PHY_MAX_ADDR];
|
||||
};
|
||||
|
||||
static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
|
||||
|
@ -83,9 +82,6 @@ static int mpc52xx_fec_mdio_probe(struct platform_device *of)
|
|||
bus->read = mpc52xx_fec_mdio_read;
|
||||
bus->write = mpc52xx_fec_mdio_write;
|
||||
|
||||
/* setup irqs */
|
||||
bus->irq = priv->mdio_irqs;
|
||||
|
||||
/* setup registers */
|
||||
err = of_address_to_resource(np, 0, &res);
|
||||
if (err)
|
||||
|
|
|
@ -1295,7 +1295,7 @@ int dtsec_init(struct fman_mac *dtsec)
|
|||
|
||||
err = init(dtsec->regs, dtsec_drv_param, dtsec->phy_if,
|
||||
dtsec->max_speed, (u8 *)eth_addr, dtsec->exceptions,
|
||||
dtsec->tbiphy->addr);
|
||||
dtsec->tbiphy->mdio.addr);
|
||||
if (err) {
|
||||
free_init_resources(dtsec);
|
||||
pr_err("DTSEC version doesn't support this i/f mode\n");
|
||||
|
@ -1434,11 +1434,11 @@ struct fman_mac *dtsec_config(struct fman_mac_params *params)
|
|||
dtsec->tbiphy = of_phy_find_device(params->internal_phy_node);
|
||||
if (!dtsec->tbiphy) {
|
||||
pr_err("of_phy_find_device (TBI PHY) failed\n");
|
||||
put_device(&dtsec->tbiphy->dev);
|
||||
put_device(&dtsec->tbiphy->mdio.dev);
|
||||
goto err_dtsec_drv_param;
|
||||
}
|
||||
|
||||
put_device(&dtsec->tbiphy->dev);
|
||||
put_device(&dtsec->tbiphy->mdio.dev);
|
||||
|
||||
/* Save FMan revision */
|
||||
fman_get_revision(dtsec->fm, &dtsec->fm_rev_info);
|
||||
|
|
|
@ -1054,15 +1054,15 @@ int memac_init(struct fman_mac *memac)
|
|||
* register address space and access each one of 4
|
||||
* ports inside QSGMII.
|
||||
*/
|
||||
phy_addr = memac->pcsphy->addr;
|
||||
phy_addr = memac->pcsphy->mdio.addr;
|
||||
qsmgii_phy_addr = (u8)((phy_addr << 2) | i);
|
||||
memac->pcsphy->addr = qsmgii_phy_addr;
|
||||
memac->pcsphy->mdio.addr = qsmgii_phy_addr;
|
||||
if (memac->basex_if)
|
||||
setup_sgmii_internal_phy_base_x(memac);
|
||||
else
|
||||
setup_sgmii_internal_phy(memac, fixed_link);
|
||||
|
||||
memac->pcsphy->addr = phy_addr;
|
||||
memac->pcsphy->mdio.addr = phy_addr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ static void restart(struct net_device *dev)
|
|||
int r;
|
||||
u32 addrhi, addrlo;
|
||||
|
||||
struct mii_bus* mii = fep->phydev->bus;
|
||||
struct mii_bus *mii = fep->phydev->mdio.bus;
|
||||
struct fec_info* fec_inf = mii->priv;
|
||||
|
||||
r = whack_reset(fep->fec.fecp);
|
||||
|
|
|
@ -172,23 +172,16 @@ static int fs_enet_mdio_probe(struct platform_device *ofdev)
|
|||
goto out_free_bus;
|
||||
|
||||
new_bus->phy_mask = ~0;
|
||||
new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!new_bus->irq) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unmap_regs;
|
||||
}
|
||||
|
||||
new_bus->parent = &ofdev->dev;
|
||||
platform_set_drvdata(ofdev, new_bus);
|
||||
|
||||
ret = of_mdiobus_register(new_bus, ofdev->dev.of_node);
|
||||
if (ret)
|
||||
goto out_free_irqs;
|
||||
goto out_unmap_regs;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_irqs:
|
||||
kfree(new_bus->irq);
|
||||
out_unmap_regs:
|
||||
iounmap(bitbang->dir);
|
||||
out_free_bus:
|
||||
|
@ -205,7 +198,6 @@ static int fs_enet_mdio_remove(struct platform_device *ofdev)
|
|||
struct bb_info *bitbang = bus->priv;
|
||||
|
||||
mdiobus_unregister(bus);
|
||||
kfree(bus->irq);
|
||||
free_mdio_bitbang(bus);
|
||||
iounmap(bitbang->dir);
|
||||
kfree(bitbang);
|
||||
|
|
|
@ -166,23 +166,16 @@ static int fs_enet_mdio_probe(struct platform_device *ofdev)
|
|||
clrsetbits_be32(&fec->fecp->fec_mii_speed, 0x7E, fec->mii_speed);
|
||||
|
||||
new_bus->phy_mask = ~0;
|
||||
new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!new_bus->irq) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unmap_regs;
|
||||
}
|
||||
|
||||
new_bus->parent = &ofdev->dev;
|
||||
platform_set_drvdata(ofdev, new_bus);
|
||||
|
||||
ret = of_mdiobus_register(new_bus, ofdev->dev.of_node);
|
||||
if (ret)
|
||||
goto out_free_irqs;
|
||||
goto out_unmap_regs;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_irqs:
|
||||
kfree(new_bus->irq);
|
||||
out_unmap_regs:
|
||||
iounmap(fec->fecp);
|
||||
out_res:
|
||||
|
@ -200,7 +193,6 @@ static int fs_enet_mdio_remove(struct platform_device *ofdev)
|
|||
struct fec_info *fec = bus->priv;
|
||||
|
||||
mdiobus_unregister(bus);
|
||||
kfree(bus->irq);
|
||||
iounmap(fec->fecp);
|
||||
kfree(fec);
|
||||
mdiobus_free(bus);
|
||||
|
|
|
@ -69,7 +69,6 @@ struct fsl_pq_mdio {
|
|||
struct fsl_pq_mdio_priv {
|
||||
void __iomem *map;
|
||||
struct fsl_pq_mii __iomem *regs;
|
||||
int irqs[PHY_MAX_ADDR];
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -401,7 +400,6 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev)
|
|||
new_bus->read = &fsl_pq_mdio_read;
|
||||
new_bus->write = &fsl_pq_mdio_write;
|
||||
new_bus->reset = &fsl_pq_mdio_reset;
|
||||
new_bus->irq = priv->irqs;
|
||||
|
||||
err = of_address_to_resource(np, 0, &res);
|
||||
if (err < 0) {
|
||||
|
|
|
@ -1834,7 +1834,7 @@ static void gfar_configure_serdes(struct net_device *dev)
|
|||
* several seconds for it to come back.
|
||||
*/
|
||||
if (phy_read(tbiphy, MII_BMSR) & BMSR_LSTATUS) {
|
||||
put_device(&tbiphy->dev);
|
||||
put_device(&tbiphy->mdio.dev);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1849,7 +1849,7 @@ static void gfar_configure_serdes(struct net_device *dev)
|
|||
BMCR_ANENABLE | BMCR_ANRESTART | BMCR_FULLDPLX |
|
||||
BMCR_SPEED1000);
|
||||
|
||||
put_device(&tbiphy->dev);
|
||||
put_device(&tbiphy->mdio.dev);
|
||||
}
|
||||
|
||||
static int __gfar_is_rx_idle(struct gfar_private *priv)
|
||||
|
|
|
@ -1385,7 +1385,7 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
|
|||
value &= ~0x1000; /* Turn off autonegotiation */
|
||||
phy_write(tbiphy, ENET_TBI_MII_CR, value);
|
||||
|
||||
put_device(&tbiphy->dev);
|
||||
put_device(&tbiphy->mdio.dev);
|
||||
}
|
||||
|
||||
init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2);
|
||||
|
@ -1705,7 +1705,7 @@ static void uec_configure_serdes(struct net_device *dev)
|
|||
* several seconds for it to come back.
|
||||
*/
|
||||
if (phy_read(tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS) {
|
||||
put_device(&tbiphy->dev);
|
||||
put_device(&tbiphy->mdio.dev);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,24 +71,22 @@ static void hns_get_mdix_mode(struct net_device *net_dev,
|
|||
struct hns_nic_priv *priv = netdev_priv(net_dev);
|
||||
struct phy_device *phy_dev = priv->phy;
|
||||
|
||||
if (!phy_dev || !phy_dev->bus) {
|
||||
if (!phy_dev || !phy_dev->mdio.bus) {
|
||||
cmd->eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID;
|
||||
cmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
|
||||
return;
|
||||
}
|
||||
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr, HNS_PHY_PAGE_REG,
|
||||
HNS_PHY_PAGE_MDIX);
|
||||
phy_write(phy_dev, HNS_PHY_PAGE_REG, HNS_PHY_PAGE_MDIX);
|
||||
|
||||
retval = mdiobus_read(phy_dev->bus, phy_dev->addr, HNS_PHY_CSC_REG);
|
||||
retval = phy_read(phy_dev, HNS_PHY_CSC_REG);
|
||||
mdix_ctrl = hnae_get_field(retval, PHY_MDIX_CTRL_M, PHY_MDIX_CTRL_S);
|
||||
|
||||
retval = mdiobus_read(phy_dev->bus, phy_dev->addr, HNS_PHY_CSS_REG);
|
||||
retval = phy_read(phy_dev, HNS_PHY_CSS_REG);
|
||||
mdix = hnae_get_bit(retval, PHY_MDIX_STATUS_B);
|
||||
is_resolved = hnae_get_bit(retval, PHY_SPEED_DUP_RESOLVE_B);
|
||||
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr, HNS_PHY_PAGE_REG,
|
||||
HNS_PHY_PAGE_COPPER);
|
||||
phy_write(phy_dev, HNS_PHY_PAGE_REG, HNS_PHY_PAGE_COPPER);
|
||||
|
||||
switch (mdix_ctrl) {
|
||||
case 0x0:
|
||||
|
@ -253,53 +251,36 @@ static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en)
|
|||
|
||||
if (en) {
|
||||
/* speed : 1000M */
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
HNS_PHY_PAGE_REG, 2);
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
21, 0x1046);
|
||||
phy_write(phy_dev, HNS_PHY_PAGE_REG, 2);
|
||||
phy_write(phy_dev, 21, 0x1046);
|
||||
/* Force Master */
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
9, 0x1F00);
|
||||
phy_write(phy_dev, 9, 0x1F00);
|
||||
/* Soft-reset */
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
0, 0x9140);
|
||||
phy_write(phy_dev, 0, 0x9140);
|
||||
/* If autoneg disabled,two soft-reset operations */
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
0, 0x9140);
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
22, 0xFA);
|
||||
phy_write(phy_dev, 0, 0x9140);
|
||||
phy_write(phy_dev, 22, 0xFA);
|
||||
|
||||
/* Default is 0x0400 */
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
1, 0x418);
|
||||
phy_write(phy_dev, 1, 0x418);
|
||||
|
||||
/* Force 1000M Link, Default is 0x0200 */
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
7, 0x20C);
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
22, 0);
|
||||
phy_write(phy_dev, 7, 0x20C);
|
||||
phy_write(phy_dev, 22, 0);
|
||||
|
||||
/* Enable MAC loop-back */
|
||||
val = (u16)mdiobus_read(phy_dev->bus, phy_dev->addr,
|
||||
COPPER_CONTROL_REG);
|
||||
val = phy_read(phy_dev, COPPER_CONTROL_REG);
|
||||
val |= PHY_LOOP_BACK;
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
COPPER_CONTROL_REG, val);
|
||||
phy_write(phy_dev, COPPER_CONTROL_REG, val);
|
||||
} else {
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
22, 0xFA);
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
1, 0x400);
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
7, 0x200);
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
22, 0);
|
||||
phy_write(phy_dev, 22, 0xFA);
|
||||
phy_write(phy_dev, 1, 0x400);
|
||||
phy_write(phy_dev, 7, 0x200);
|
||||
phy_write(phy_dev, 22, 0);
|
||||
|
||||
val = (u16)mdiobus_read(phy_dev->bus, phy_dev->addr,
|
||||
COPPER_CONTROL_REG);
|
||||
val = phy_read(phy_dev, COPPER_CONTROL_REG);
|
||||
val &= ~PHY_LOOP_BACK;
|
||||
(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
COPPER_CONTROL_REG, val);
|
||||
phy_write(phy_dev, COPPER_CONTROL_REG, val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1018,16 +999,9 @@ int hns_phy_led_set(struct net_device *netdev, int value)
|
|||
struct hns_nic_priv *priv = netdev_priv(netdev);
|
||||
struct phy_device *phy_dev = priv->phy;
|
||||
|
||||
if (!phy_dev->bus) {
|
||||
netdev_err(netdev, "phy_dev->bus is null!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
retval = mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
HNS_PHY_PAGE_REG, HNS_PHY_PAGE_LED);
|
||||
retval = mdiobus_write(phy_dev->bus, phy_dev->addr, HNS_LED_FC_REG,
|
||||
value);
|
||||
retval = mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
HNS_PHY_PAGE_REG, HNS_PHY_PAGE_COPPER);
|
||||
retval = phy_write(phy_dev, HNS_PHY_PAGE_REG, HNS_PHY_PAGE_LED);
|
||||
retval = phy_write(phy_dev, HNS_LED_FC_REG, value);
|
||||
retval = phy_write(phy_dev, HNS_PHY_PAGE_REG, HNS_PHY_PAGE_COPPER);
|
||||
if (retval) {
|
||||
netdev_err(netdev, "mdiobus_write fail !\n");
|
||||
return retval;
|
||||
|
@ -1052,19 +1026,15 @@ int hns_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
|
|||
if (phy_dev)
|
||||
switch (state) {
|
||||
case ETHTOOL_ID_ACTIVE:
|
||||
ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
HNS_PHY_PAGE_REG,
|
||||
HNS_PHY_PAGE_LED);
|
||||
ret = phy_write(phy_dev, HNS_PHY_PAGE_REG,
|
||||
HNS_PHY_PAGE_LED);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->phy_led_val = (u16)mdiobus_read(phy_dev->bus,
|
||||
phy_dev->addr,
|
||||
HNS_LED_FC_REG);
|
||||
priv->phy_led_val = phy_read(phy_dev, HNS_LED_FC_REG);
|
||||
|
||||
ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
HNS_PHY_PAGE_REG,
|
||||
HNS_PHY_PAGE_COPPER);
|
||||
ret = phy_write(phy_dev, HNS_PHY_PAGE_REG,
|
||||
HNS_PHY_PAGE_COPPER);
|
||||
if (ret)
|
||||
return ret;
|
||||
return 2;
|
||||
|
@ -1079,20 +1049,18 @@ int hns_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
|
|||
return ret;
|
||||
break;
|
||||
case ETHTOOL_ID_INACTIVE:
|
||||
ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
HNS_PHY_PAGE_REG,
|
||||
HNS_PHY_PAGE_LED);
|
||||
ret = phy_write(phy_dev, HNS_PHY_PAGE_REG,
|
||||
HNS_PHY_PAGE_LED);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
HNS_LED_FC_REG, priv->phy_led_val);
|
||||
ret = phy_write(phy_dev, HNS_LED_FC_REG,
|
||||
priv->phy_led_val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
|
||||
HNS_PHY_PAGE_REG,
|
||||
HNS_PHY_PAGE_COPPER);
|
||||
ret = phy_write(phy_dev, HNS_PHY_PAGE_REG,
|
||||
HNS_PHY_PAGE_COPPER);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
|
|
|
@ -463,11 +463,6 @@ static int hns_mdio_probe(struct platform_device *pdev)
|
|||
dev_warn(&pdev->dev, "no syscon hisilicon,peri-c-subctrl\n");
|
||||
mdio_dev->subctrl_vbase = NULL;
|
||||
}
|
||||
new_bus->irq = devm_kcalloc(&pdev->dev, PHY_MAX_ADDR,
|
||||
sizeof(int), GFP_KERNEL);
|
||||
if (!new_bus->irq)
|
||||
return -ENOMEM;
|
||||
|
||||
new_bus->parent = &pdev->dev;
|
||||
platform_set_drvdata(pdev, new_bus);
|
||||
|
||||
|
|
|
@ -390,7 +390,7 @@ ltq_etop_mdio_probe(struct net_device *dev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
phydev = phy_connect(dev, dev_name(&phydev->dev),
|
||||
phydev = phy_connect(dev, phydev_name(phydev),
|
||||
<q_etop_mdio_link, priv->pldata->mii_mode);
|
||||
|
||||
if (IS_ERR(phydev)) {
|
||||
|
@ -408,9 +408,7 @@ ltq_etop_mdio_probe(struct net_device *dev)
|
|||
|
||||
phydev->advertising = phydev->supported;
|
||||
priv->phydev = phydev;
|
||||
pr_info("%s: attached PHY [%s] (phy_addr=%s, irq=%d)\n",
|
||||
dev->name, phydev->drv->name,
|
||||
dev_name(&phydev->dev), phydev->irq);
|
||||
phy_attached_info(phydev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -435,18 +433,9 @@ ltq_etop_mdio_init(struct net_device *dev)
|
|||
priv->mii_bus->name = "ltq_mii";
|
||||
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
priv->pdev->name, priv->pdev->id);
|
||||
priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!priv->mii_bus->irq) {
|
||||
err = -ENOMEM;
|
||||
goto err_out_free_mdiobus;
|
||||
}
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; ++i)
|
||||
priv->mii_bus->irq[i] = PHY_POLL;
|
||||
|
||||
if (mdiobus_register(priv->mii_bus)) {
|
||||
err = -ENXIO;
|
||||
goto err_out_free_mdio_irq;
|
||||
goto err_out_free_mdiobus;
|
||||
}
|
||||
|
||||
if (ltq_etop_mdio_probe(dev)) {
|
||||
|
@ -457,8 +446,6 @@ ltq_etop_mdio_init(struct net_device *dev)
|
|||
|
||||
err_out_unregister_bus:
|
||||
mdiobus_unregister(priv->mii_bus);
|
||||
err_out_free_mdio_irq:
|
||||
kfree(priv->mii_bus->irq);
|
||||
err_out_free_mdiobus:
|
||||
mdiobus_free(priv->mii_bus);
|
||||
err_out:
|
||||
|
@ -472,7 +459,6 @@ ltq_etop_mdio_cleanup(struct net_device *dev)
|
|||
|
||||
phy_disconnect(priv->phydev);
|
||||
mdiobus_unregister(priv->mii_bus);
|
||||
kfree(priv->mii_bus->irq);
|
||||
mdiobus_free(priv->mii_bus);
|
||||
}
|
||||
|
||||
|
|
|
@ -3133,7 +3133,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
|
|||
if (!mp->phy)
|
||||
err = -ENODEV;
|
||||
else
|
||||
phy_addr_set(mp, mp->phy->addr);
|
||||
phy_addr_set(mp, mp->phy->mdio.addr);
|
||||
} else if (pd->phy_addr != MV643XX_ETH_PHY_NONE) {
|
||||
mp->phy = phy_scan(mp, pd->phy_addr);
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ static int orion_mdio_probe(struct platform_device *pdev)
|
|||
struct resource *r;
|
||||
struct mii_bus *bus;
|
||||
struct orion_mdio_dev *dev;
|
||||
int i, ret;
|
||||
int ret;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!r) {
|
||||
|
@ -207,14 +207,6 @@ static int orion_mdio_probe(struct platform_device *pdev)
|
|||
dev_name(&pdev->dev));
|
||||
bus->parent = &pdev->dev;
|
||||
|
||||
bus->irq = devm_kmalloc_array(&pdev->dev, PHY_MAX_ADDR, sizeof(int),
|
||||
GFP_KERNEL);
|
||||
if (!bus->irq)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
bus->irq[i] = PHY_POLL;
|
||||
|
||||
dev = bus->priv;
|
||||
dev->regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
|
||||
if (!dev->regs) {
|
||||
|
|
|
@ -3714,7 +3714,7 @@ static int mvneta_probe(struct platform_device *pdev)
|
|||
|
||||
mvneta_fixed_link_update(pp, phy);
|
||||
|
||||
put_device(&phy->dev);
|
||||
put_device(&phy->mdio.dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -797,7 +797,7 @@ static int lpc_mii_probe(struct net_device *ndev)
|
|||
netdev_info(ndev, "using MII interface\n");
|
||||
else
|
||||
netdev_info(ndev, "using RMII interface\n");
|
||||
phydev = phy_connect(ndev, dev_name(&phydev->dev),
|
||||
phydev = phy_connect(ndev, phydev_name(phydev),
|
||||
&lpc_handle_link_change,
|
||||
lpc_phy_interface_mode(&pldat->pdev->dev));
|
||||
|
||||
|
@ -816,9 +816,8 @@ static int lpc_mii_probe(struct net_device *ndev)
|
|||
pldat->duplex = -1;
|
||||
pldat->phy_dev = phydev;
|
||||
|
||||
netdev_info(ndev,
|
||||
"attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
|
||||
phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
|
||||
phy_attached_info(phydev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -851,19 +850,10 @@ static int lpc_mii_init(struct netdata_local *pldat)
|
|||
pldat->mii_bus->priv = pldat;
|
||||
pldat->mii_bus->parent = &pldat->pdev->dev;
|
||||
|
||||
pldat->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!pldat->mii_bus->irq) {
|
||||
err = -ENOMEM;
|
||||
goto err_out_1;
|
||||
}
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
pldat->mii_bus->irq[i] = PHY_POLL;
|
||||
|
||||
platform_set_drvdata(pldat->pdev, pldat->mii_bus);
|
||||
|
||||
if (mdiobus_register(pldat->mii_bus))
|
||||
goto err_out_free_mdio_irq;
|
||||
goto err_out_unregister_bus;
|
||||
|
||||
if (lpc_mii_probe(pldat->ndev) != 0)
|
||||
goto err_out_unregister_bus;
|
||||
|
@ -872,8 +862,6 @@ static int lpc_mii_init(struct netdata_local *pldat)
|
|||
|
||||
err_out_unregister_bus:
|
||||
mdiobus_unregister(pldat->mii_bus);
|
||||
err_out_free_mdio_irq:
|
||||
kfree(pldat->mii_bus->irq);
|
||||
err_out_1:
|
||||
mdiobus_free(pldat->mii_bus);
|
||||
err_out:
|
||||
|
|
|
@ -1039,7 +1039,7 @@ static int r6040_mii_probe(struct net_device *dev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
phydev = phy_connect(dev, dev_name(&phydev->dev), &r6040_adjust_link,
|
||||
phydev = phy_connect(dev, phydev_name(phydev), &r6040_adjust_link,
|
||||
PHY_INTERFACE_MODE_MII);
|
||||
|
||||
if (IS_ERR(phydev)) {
|
||||
|
@ -1061,9 +1061,7 @@ static int r6040_mii_probe(struct net_device *dev)
|
|||
lp->old_link = 0;
|
||||
lp->old_duplex = -1;
|
||||
|
||||
dev_info(&lp->pdev->dev, "attached PHY driver [%s] "
|
||||
"(mii_bus:phy_addr=%s)\n",
|
||||
phydev->drv->name, dev_name(&phydev->dev));
|
||||
phy_attached_info(phydev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1077,7 +1075,6 @@ static int r6040_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
static int card_idx = -1;
|
||||
int bar = 0;
|
||||
u16 *adrp;
|
||||
int i;
|
||||
|
||||
pr_info("%s\n", version);
|
||||
|
||||
|
@ -1189,19 +1186,11 @@ static int r6040_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
lp->mii_bus->name = "r6040_eth_mii";
|
||||
snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
dev_name(&pdev->dev), card_idx);
|
||||
lp->mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
|
||||
if (!lp->mii_bus->irq) {
|
||||
err = -ENOMEM;
|
||||
goto err_out_mdio;
|
||||
}
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
lp->mii_bus->irq[i] = PHY_POLL;
|
||||
|
||||
err = mdiobus_register(lp->mii_bus);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to register MII bus\n");
|
||||
goto err_out_mdio_irq;
|
||||
goto err_out_mdio;
|
||||
}
|
||||
|
||||
err = r6040_mii_probe(dev);
|
||||
|
@ -1220,8 +1209,6 @@ static int r6040_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
err_out_mdio_unregister:
|
||||
mdiobus_unregister(lp->mii_bus);
|
||||
err_out_mdio_irq:
|
||||
kfree(lp->mii_bus->irq);
|
||||
err_out_mdio:
|
||||
mdiobus_free(lp->mii_bus);
|
||||
err_out_unmap:
|
||||
|
@ -1244,7 +1231,6 @@ static void r6040_remove_one(struct pci_dev *pdev)
|
|||
|
||||
unregister_netdev(dev);
|
||||
mdiobus_unregister(lp->mii_bus);
|
||||
kfree(lp->mii_bus->irq);
|
||||
mdiobus_free(lp->mii_bus);
|
||||
netif_napi_del(&lp->napi);
|
||||
pci_iounmap(pdev, lp->base);
|
||||
|
|
|
@ -927,8 +927,7 @@ static int ravb_phy_init(struct net_device *ndev)
|
|||
/* 10BASE is not supported */
|
||||
phydev->supported &= ~PHY_10BT_FEATURES;
|
||||
|
||||
netdev_info(ndev, "attached PHY %d (IRQ %d) to driver %s\n",
|
||||
phydev->addr, phydev->irq, phydev->drv->name);
|
||||
phy_attached_info(phydev);
|
||||
|
||||
priv->phydev = phydev;
|
||||
|
||||
|
|
|
@ -1826,8 +1826,7 @@ static int sh_eth_phy_init(struct net_device *ndev)
|
|||
return PTR_ERR(phydev);
|
||||
}
|
||||
|
||||
netdev_info(ndev, "attached PHY %d (IRQ %d) to driver %s\n",
|
||||
phydev->addr, phydev->irq, phydev->drv->name);
|
||||
phy_attached_info(phydev);
|
||||
|
||||
mdp->phydev = phydev;
|
||||
|
||||
|
@ -2860,7 +2859,7 @@ static int sh_mdio_release(struct sh_eth_private *mdp)
|
|||
static int sh_mdio_init(struct sh_eth_private *mdp,
|
||||
struct sh_eth_plat_data *pd)
|
||||
{
|
||||
int ret, i;
|
||||
int ret;
|
||||
struct bb_info *bitbang;
|
||||
struct platform_device *pdev = mdp->pdev;
|
||||
struct device *dev = &mdp->pdev->dev;
|
||||
|
@ -2886,20 +2885,10 @@ static int sh_mdio_init(struct sh_eth_private *mdp,
|
|||
snprintf(mdp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
pdev->name, pdev->id);
|
||||
|
||||
/* PHY IRQ */
|
||||
mdp->mii_bus->irq = devm_kmalloc_array(dev, PHY_MAX_ADDR, sizeof(int),
|
||||
GFP_KERNEL);
|
||||
if (!mdp->mii_bus->irq) {
|
||||
ret = -ENOMEM;
|
||||
goto out_free_bus;
|
||||
}
|
||||
|
||||
/* register MDIO bus */
|
||||
if (dev->of_node) {
|
||||
ret = of_mdiobus_register(mdp->mii_bus, dev->of_node);
|
||||
} else {
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
mdp->mii_bus->irq[i] = PHY_POLL;
|
||||
if (pd->phy_irq > 0)
|
||||
mdp->mii_bus->irq[pd->phy] = pd->phy_irq;
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ int sxgbe_mdio_register(struct net_device *ndev)
|
|||
}
|
||||
|
||||
for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
|
||||
struct phy_device *phy = mdio_bus->phy_map[phy_addr];
|
||||
struct phy_device *phy = mdiobus_get_phy(mdio_bus, phy_addr);
|
||||
|
||||
if (phy) {
|
||||
char irq_num[4];
|
||||
|
@ -216,7 +216,7 @@ int sxgbe_mdio_register(struct net_device *ndev)
|
|||
}
|
||||
netdev_info(ndev, "PHY ID %08x at %d IRQ %s (%s)%s\n",
|
||||
phy->phy_id, phy_addr, irq_str,
|
||||
dev_name(&phy->dev), act ? " active" : "");
|
||||
phydev_name(phy), act ? " active" : "");
|
||||
phy_found = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -864,8 +864,8 @@ static int smsc911x_phy_loopbacktest(struct net_device *dev)
|
|||
|
||||
for (i = 0; i < 10; i++) {
|
||||
/* Set PHY to 10/FD, no ANEG, and loopback mode */
|
||||
smsc911x_mii_write(phy_dev->bus, phy_dev->addr, MII_BMCR,
|
||||
BMCR_LOOPBACK | BMCR_FULLDPLX);
|
||||
smsc911x_mii_write(phy_dev->mdio.bus, phy_dev->mdio.addr,
|
||||
MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX);
|
||||
|
||||
/* Enable MAC tx/rx, FD */
|
||||
spin_lock_irqsave(&pdata->mac_lock, flags);
|
||||
|
@ -893,7 +893,7 @@ static int smsc911x_phy_loopbacktest(struct net_device *dev)
|
|||
spin_unlock_irqrestore(&pdata->mac_lock, flags);
|
||||
|
||||
/* Cancel PHY loopback mode */
|
||||
smsc911x_mii_write(phy_dev->bus, phy_dev->addr, MII_BMCR, 0);
|
||||
smsc911x_mii_write(phy_dev->mdio.bus, phy_dev->mdio.addr, MII_BMCR, 0);
|
||||
|
||||
smsc911x_reg_write(pdata, TX_CFG, 0);
|
||||
smsc911x_reg_write(pdata, RX_CFG, 0);
|
||||
|
@ -1021,7 +1021,7 @@ static int smsc911x_mii_probe(struct net_device *dev)
|
|||
}
|
||||
|
||||
SMSC_TRACE(pdata, probe, "PHY: addr %d, phy_id 0x%08X",
|
||||
phydev->addr, phydev->phy_id);
|
||||
phydev->mdio.addr, phydev->phy_id);
|
||||
|
||||
ret = phy_connect_direct(dev, phydev, &smsc911x_phy_adjust_link,
|
||||
pdata->config.phy_interface);
|
||||
|
@ -1031,9 +1031,7 @@ static int smsc911x_mii_probe(struct net_device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
netdev_info(dev,
|
||||
"attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
|
||||
phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
|
||||
phy_attached_info(phydev);
|
||||
|
||||
/* mask with MAC supported features */
|
||||
phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
|
||||
|
@ -1061,7 +1059,7 @@ static int smsc911x_mii_init(struct platform_device *pdev,
|
|||
struct net_device *dev)
|
||||
{
|
||||
struct smsc911x_data *pdata = netdev_priv(dev);
|
||||
int err = -ENXIO, i;
|
||||
int err = -ENXIO;
|
||||
|
||||
pdata->mii_bus = mdiobus_alloc();
|
||||
if (!pdata->mii_bus) {
|
||||
|
@ -1075,9 +1073,7 @@ static int smsc911x_mii_init(struct platform_device *pdev,
|
|||
pdata->mii_bus->priv = pdata;
|
||||
pdata->mii_bus->read = smsc911x_mii_read;
|
||||
pdata->mii_bus->write = smsc911x_mii_write;
|
||||
pdata->mii_bus->irq = pdata->phy_irq;
|
||||
for (i = 0; i < PHY_MAX_ADDR; ++i)
|
||||
pdata->mii_bus->irq[i] = PHY_POLL;
|
||||
memcpy(pdata->mii_bus->irq, pdata->phy_irq, sizeof(pdata->mii_bus));
|
||||
|
||||
pdata->mii_bus->parent = &pdev->dev;
|
||||
|
||||
|
@ -1992,7 +1988,8 @@ smsc911x_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs,
|
|||
}
|
||||
|
||||
for (i = 0; i <= 31; i++)
|
||||
data[j++] = smsc911x_mii_read(phy_dev->bus, phy_dev->addr, i);
|
||||
data[j++] = smsc911x_mii_read(phy_dev->mdio.bus,
|
||||
phy_dev->mdio.addr, i);
|
||||
}
|
||||
|
||||
static void smsc911x_eeprom_enable_access(struct smsc911x_data *pdata)
|
||||
|
|
|
@ -78,7 +78,6 @@ struct smsc9420_pdata {
|
|||
|
||||
struct phy_device *phy_dev;
|
||||
struct mii_bus *mii_bus;
|
||||
int phy_irq[PHY_MAX_ADDR];
|
||||
int last_duplex;
|
||||
int last_carrier;
|
||||
};
|
||||
|
@ -316,7 +315,8 @@ smsc9420_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs,
|
|||
return;
|
||||
|
||||
for (i = 0; i <= 31; i++)
|
||||
data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i);
|
||||
data[j++] = smsc9420_mii_read(phy_dev->mdio.bus,
|
||||
phy_dev->mdio.addr, i);
|
||||
}
|
||||
|
||||
static void smsc9420_eeprom_enable_access(struct smsc9420_pdata *pd)
|
||||
|
@ -1158,16 +1158,13 @@ static int smsc9420_mii_probe(struct net_device *dev)
|
|||
BUG_ON(pd->phy_dev);
|
||||
|
||||
/* Device only supports internal PHY at address 1 */
|
||||
if (!pd->mii_bus->phy_map[1]) {
|
||||
phydev = mdiobus_get_phy(pd->mii_bus, 1);
|
||||
if (!phydev) {
|
||||
netdev_err(dev, "no PHY found at address 1\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
phydev = pd->mii_bus->phy_map[1];
|
||||
netif_info(pd, probe, pd->dev, "PHY addr %d, phy_id 0x%08X\n",
|
||||
phydev->addr, phydev->phy_id);
|
||||
|
||||
phydev = phy_connect(dev, dev_name(&phydev->dev),
|
||||
phydev = phy_connect(dev, phydev_name(phydev),
|
||||
smsc9420_phy_adjust_link, PHY_INTERFACE_MODE_MII);
|
||||
|
||||
if (IS_ERR(phydev)) {
|
||||
|
@ -1175,14 +1172,13 @@ static int smsc9420_mii_probe(struct net_device *dev)
|
|||
return PTR_ERR(phydev);
|
||||
}
|
||||
|
||||
netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
|
||||
phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
|
||||
|
||||
/* mask with MAC supported features */
|
||||
phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
|
||||
SUPPORTED_Asym_Pause);
|
||||
phydev->advertising = phydev->supported;
|
||||
|
||||
phy_attached_info(phydev);
|
||||
|
||||
pd->phy_dev = phydev;
|
||||
pd->last_duplex = -1;
|
||||
pd->last_carrier = -1;
|
||||
|
@ -1193,7 +1189,7 @@ static int smsc9420_mii_probe(struct net_device *dev)
|
|||
static int smsc9420_mii_init(struct net_device *dev)
|
||||
{
|
||||
struct smsc9420_pdata *pd = netdev_priv(dev);
|
||||
int err = -ENXIO, i;
|
||||
int err = -ENXIO;
|
||||
|
||||
pd->mii_bus = mdiobus_alloc();
|
||||
if (!pd->mii_bus) {
|
||||
|
@ -1206,9 +1202,6 @@ static int smsc9420_mii_init(struct net_device *dev)
|
|||
pd->mii_bus->priv = pd;
|
||||
pd->mii_bus->read = smsc9420_mii_read;
|
||||
pd->mii_bus->write = smsc9420_mii_write;
|
||||
pd->mii_bus->irq = pd->phy_irq;
|
||||
for (i = 0; i < PHY_MAX_ADDR; ++i)
|
||||
pd->mii_bus->irq[i] = PHY_POLL;
|
||||
|
||||
/* Mask all PHYs except ID 1 (internal) */
|
||||
pd->mii_bus->phy_mask = ~(1 << 1);
|
||||
|
|
|
@ -196,7 +196,6 @@ int stmmac_mdio_register(struct net_device *ndev)
|
|||
{
|
||||
int err = 0;
|
||||
struct mii_bus *new_bus;
|
||||
int *irqlist;
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
|
||||
int addr, found;
|
||||
|
@ -227,13 +226,8 @@ int stmmac_mdio_register(struct net_device *ndev)
|
|||
if (new_bus == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
if (mdio_bus_data->irqs) {
|
||||
irqlist = mdio_bus_data->irqs;
|
||||
} else {
|
||||
for (addr = 0; addr < PHY_MAX_ADDR; addr++)
|
||||
priv->mii_irq[addr] = PHY_POLL;
|
||||
irqlist = priv->mii_irq;
|
||||
}
|
||||
if (mdio_bus_data->irqs)
|
||||
memcpy(new_bus->irq, mdio_bus_data, sizeof(new_bus->irq));
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
if (priv->device->of_node)
|
||||
|
@ -247,7 +241,6 @@ int stmmac_mdio_register(struct net_device *ndev)
|
|||
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
new_bus->name, priv->plat->bus_id);
|
||||
new_bus->priv = ndev;
|
||||
new_bus->irq = irqlist;
|
||||
new_bus->phy_mask = mdio_bus_data->phy_mask;
|
||||
new_bus->parent = priv->device;
|
||||
|
||||
|
@ -259,7 +252,7 @@ int stmmac_mdio_register(struct net_device *ndev)
|
|||
|
||||
found = 0;
|
||||
for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
|
||||
struct phy_device *phydev = new_bus->phy_map[addr];
|
||||
struct phy_device *phydev = mdiobus_get_phy(new_bus, addr);
|
||||
if (phydev) {
|
||||
int act = 0;
|
||||
char irq_num[4];
|
||||
|
@ -271,7 +264,8 @@ int stmmac_mdio_register(struct net_device *ndev)
|
|||
*/
|
||||
if ((mdio_bus_data->irqs == NULL) &&
|
||||
(mdio_bus_data->probed_phy_irq > 0)) {
|
||||
irqlist[addr] = mdio_bus_data->probed_phy_irq;
|
||||
new_bus->irq[addr] =
|
||||
mdio_bus_data->probed_phy_irq;
|
||||
phydev->irq = mdio_bus_data->probed_phy_irq;
|
||||
}
|
||||
|
||||
|
@ -298,7 +292,7 @@ int stmmac_mdio_register(struct net_device *ndev)
|
|||
}
|
||||
pr_info("%s: PHY ID %08x at %d IRQ %s (%s)%s\n",
|
||||
ndev->name, phydev->phy_id, addr,
|
||||
irq_str, dev_name(&phydev->dev),
|
||||
irq_str, phydev_name(phydev),
|
||||
act ? " active" : "");
|
||||
found = 1;
|
||||
}
|
||||
|
|
|
@ -972,9 +972,7 @@ static int dwceqos_mii_probe(struct net_device *ndev)
|
|||
}
|
||||
|
||||
if (netif_msg_probe(lp))
|
||||
netdev_dbg(lp->ndev,
|
||||
"phydev %p, phydev->phy_id 0xa%x, phydev->addr 0x%x\n",
|
||||
phydev, phydev->phy_id, phydev->addr);
|
||||
phy_attached_info(phydev);
|
||||
|
||||
phydev->supported &= PHY_GBIT_FEATURES;
|
||||
|
||||
|
@ -983,14 +981,6 @@ static int dwceqos_mii_probe(struct net_device *ndev)
|
|||
lp->duplex = DUPLEX_UNKNOWN;
|
||||
lp->phy_dev = phydev;
|
||||
|
||||
if (netif_msg_probe(lp)) {
|
||||
netdev_dbg(lp->ndev, "phy_addr 0x%x, phy_id 0x%08x\n",
|
||||
lp->phy_dev->addr, lp->phy_dev->phy_id);
|
||||
|
||||
netdev_dbg(lp->ndev, "attach [%s] phy driver\n",
|
||||
lp->phy_dev->drv->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1230,7 +1220,7 @@ static void dwceqos_enable_mmc_interrupt(struct net_local *lp)
|
|||
|
||||
static int dwceqos_mii_init(struct net_local *lp)
|
||||
{
|
||||
int ret = -ENXIO, i;
|
||||
int ret = -ENXIO;
|
||||
struct resource res;
|
||||
struct device_node *mdionode;
|
||||
|
||||
|
@ -1251,24 +1241,14 @@ static int dwceqos_mii_init(struct net_local *lp)
|
|||
lp->mii_bus->priv = lp;
|
||||
lp->mii_bus->parent = &lp->ndev->dev;
|
||||
|
||||
lp->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!lp->mii_bus->irq) {
|
||||
ret = -ENOMEM;
|
||||
goto err_out_free_mdiobus;
|
||||
}
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
lp->mii_bus->irq[i] = PHY_POLL;
|
||||
of_address_to_resource(lp->pdev->dev.of_node, 0, &res);
|
||||
snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "%.8llx",
|
||||
(unsigned long long)res.start);
|
||||
if (of_mdiobus_register(lp->mii_bus, mdionode))
|
||||
goto err_out_free_mdio_irq;
|
||||
goto err_out_free_mdiobus;
|
||||
|
||||
return 0;
|
||||
|
||||
err_out_free_mdio_irq:
|
||||
kfree(lp->mii_bus->irq);
|
||||
err_out_free_mdiobus:
|
||||
mdiobus_free(lp->mii_bus);
|
||||
err_out:
|
||||
|
@ -2987,7 +2967,6 @@ static int dwceqos_remove(struct platform_device *pdev)
|
|||
if (lp->phy_dev)
|
||||
phy_disconnect(lp->phy_dev);
|
||||
mdiobus_unregister(lp->mii_bus);
|
||||
kfree(lp->mii_bus->irq);
|
||||
mdiobus_free(lp->mii_bus);
|
||||
|
||||
unregister_netdev(ndev);
|
||||
|
|
|
@ -316,8 +316,6 @@ static int cpmac_mdio_reset(struct mii_bus *bus)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mii_irqs[PHY_MAX_ADDR] = { PHY_POLL, };
|
||||
|
||||
static struct mii_bus *cpmac_mii;
|
||||
|
||||
static void cpmac_set_multicast_list(struct net_device *dev)
|
||||
|
@ -1226,7 +1224,6 @@ int cpmac_init(void)
|
|||
cpmac_mii->read = cpmac_mdio_read;
|
||||
cpmac_mii->write = cpmac_mdio_write;
|
||||
cpmac_mii->reset = cpmac_mdio_reset;
|
||||
cpmac_mii->irq = mii_irqs;
|
||||
|
||||
cpmac_mii->priv = ioremap(AR7_REGS_MDIO, 256);
|
||||
|
||||
|
|
|
@ -1159,8 +1159,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
|
|||
slave->data->phy_id, slave->slave_num);
|
||||
slave->phy = NULL;
|
||||
} else {
|
||||
dev_info(priv->dev, "phy found : id is : 0x%x\n",
|
||||
slave->phy->phy_id);
|
||||
phy_attached_info(slave->phy);
|
||||
|
||||
phy_start(slave->phy);
|
||||
|
||||
/* Configure GMII_SEL register */
|
||||
|
@ -2050,7 +2050,8 @@ static int cpsw_probe_dt(struct cpsw_priv *priv,
|
|||
if (!phy_dev)
|
||||
return -ENODEV;
|
||||
snprintf(slave_data->phy_id, sizeof(slave_data->phy_id),
|
||||
PHY_ID_FMT, phy_dev->bus->id, phy_dev->addr);
|
||||
PHY_ID_FMT, phy_dev->mdio.bus->id,
|
||||
phy_dev->mdio.addr);
|
||||
} else if (parp) {
|
||||
u32 phyid;
|
||||
struct device_node *mdio_node;
|
||||
|
|
|
@ -1644,10 +1644,7 @@ static int emac_dev_open(struct net_device *ndev)
|
|||
priv->speed = 0;
|
||||
priv->duplex = ~0;
|
||||
|
||||
dev_info(emac_dev, "attached PHY driver [%s] "
|
||||
"(mii_bus:phy_addr=%s, id=%x)\n",
|
||||
priv->phydev->drv->name, dev_name(&priv->phydev->dev),
|
||||
priv->phydev->phy_id);
|
||||
phy_attached_info(priv->phydev);
|
||||
}
|
||||
|
||||
if (!priv->phydev) {
|
||||
|
|
|
@ -393,10 +393,10 @@ static int davinci_mdio_probe(struct platform_device *pdev)
|
|||
|
||||
/* scan and dump the bus */
|
||||
for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
|
||||
phy = data->bus->phy_map[addr];
|
||||
phy = mdiobus_get_phy(data->bus, addr);
|
||||
if (phy) {
|
||||
dev_info(dev, "phy[%d]: device %s, driver %s\n",
|
||||
phy->addr, dev_name(&phy->dev),
|
||||
phy->mdio.addr, phydev_name(phy),
|
||||
phy->drv ? phy->drv->name : "unknown");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2178,7 +2178,7 @@ static int gbe_slave_open(struct gbe_intf *gbe_intf)
|
|||
return -ENODEV;
|
||||
}
|
||||
dev_dbg(priv->dev, "phy found: id is: 0x%s\n",
|
||||
dev_name(&slave->phy->dev));
|
||||
phydev_name(slave->phy));
|
||||
phy_start(slave->phy);
|
||||
phy_read_status(slave->phy);
|
||||
}
|
||||
|
@ -2681,7 +2681,7 @@ static void init_secondary_ports(struct gbe_priv *gbe_dev,
|
|||
slave->phy = NULL;
|
||||
} else {
|
||||
dev_dbg(dev, "phy found: id is: 0x%s\n",
|
||||
dev_name(&slave->phy->dev));
|
||||
phydev_name(slave->phy));
|
||||
phy_start(slave->phy);
|
||||
phy_read_status(slave->phy);
|
||||
}
|
||||
|
|
|
@ -631,17 +631,15 @@ static int tc_mii_probe(struct net_device *dev)
|
|||
}
|
||||
|
||||
/* attach the mac to the phy */
|
||||
phydev = phy_connect(dev, dev_name(&phydev->dev),
|
||||
phydev = phy_connect(dev, phydev_name(phydev),
|
||||
&tc_handle_link_change,
|
||||
lp->chiptype == TC35815_TX4939 ? PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII);
|
||||
if (IS_ERR(phydev)) {
|
||||
printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
|
||||
return PTR_ERR(phydev);
|
||||
}
|
||||
printk(KERN_INFO "%s: attached PHY driver [%s] "
|
||||
"(mii_bus:phy_addr=%s, id=%x)\n",
|
||||
dev->name, phydev->drv->name, dev_name(&phydev->dev),
|
||||
phydev->phy_id);
|
||||
|
||||
phy_attached_info(phydev);
|
||||
|
||||
/* mask with MAC supported features */
|
||||
phydev->supported &= PHY_BASIC_FEATURES;
|
||||
|
@ -684,18 +682,9 @@ static int tc_mii_init(struct net_device *dev)
|
|||
(lp->pci_dev->bus->number << 8) | lp->pci_dev->devfn);
|
||||
lp->mii_bus->priv = dev;
|
||||
lp->mii_bus->parent = &lp->pci_dev->dev;
|
||||
lp->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!lp->mii_bus->irq) {
|
||||
err = -ENOMEM;
|
||||
goto err_out_free_mii_bus;
|
||||
}
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
lp->mii_bus->irq[i] = PHY_POLL;
|
||||
|
||||
err = mdiobus_register(lp->mii_bus);
|
||||
if (err)
|
||||
goto err_out_free_mdio_irq;
|
||||
goto err_out_free_mii_bus;
|
||||
err = tc_mii_probe(dev);
|
||||
if (err)
|
||||
goto err_out_unregister_bus;
|
||||
|
@ -703,8 +692,6 @@ static int tc_mii_init(struct net_device *dev)
|
|||
|
||||
err_out_unregister_bus:
|
||||
mdiobus_unregister(lp->mii_bus);
|
||||
err_out_free_mdio_irq:
|
||||
kfree(lp->mii_bus->irq);
|
||||
err_out_free_mii_bus:
|
||||
mdiobus_free(lp->mii_bus);
|
||||
err_out:
|
||||
|
@ -882,7 +869,6 @@ static void tc35815_remove_one(struct pci_dev *pdev)
|
|||
|
||||
phy_disconnect(lp->phy_dev);
|
||||
mdiobus_unregister(lp->mii_bus);
|
||||
kfree(lp->mii_bus->irq);
|
||||
mdiobus_free(lp->mii_bus);
|
||||
unregister_netdev(dev);
|
||||
free_netdev(dev);
|
||||
|
|
|
@ -337,7 +337,6 @@ struct temac_local {
|
|||
|
||||
/* MDIO bus data */
|
||||
struct mii_bus *mii_bus; /* MII bus reference */
|
||||
int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */
|
||||
|
||||
/* IO registers, dma functions and IRQs */
|
||||
void __iomem *regs;
|
||||
|
|
|
@ -92,7 +92,6 @@ int temac_mdio_setup(struct temac_local *lp, struct device_node *np)
|
|||
bus->read = temac_mdio_read;
|
||||
bus->write = temac_mdio_write;
|
||||
bus->parent = lp->dev;
|
||||
bus->irq = lp->mdio_irqs; /* preallocated IRQ table */
|
||||
|
||||
lp->mii_bus = bus;
|
||||
|
||||
|
@ -114,7 +113,6 @@ int temac_mdio_setup(struct temac_local *lp, struct device_node *np)
|
|||
void temac_mdio_teardown(struct temac_local *lp)
|
||||
{
|
||||
mdiobus_unregister(lp->mii_bus);
|
||||
kfree(lp->mii_bus->irq);
|
||||
mdiobus_free(lp->mii_bus);
|
||||
lp->mii_bus = NULL;
|
||||
}
|
||||
|
|
|
@ -385,7 +385,6 @@ struct axidma_bd {
|
|||
* @phy_dev: Pointer to PHY device structure attached to the axienet_local
|
||||
* @phy_node: Pointer to device node structure
|
||||
* @mii_bus: Pointer to MII bus structure
|
||||
* @mdio_irqs: IRQs table for MDIO bus required in mii_bus structure
|
||||
* @regs: Base address for the axienet_local device address space
|
||||
* @dma_regs: Base address for the axidma device address space
|
||||
* @dma_err_tasklet: Tasklet structure to process Axi DMA errors
|
||||
|
@ -426,7 +425,6 @@ struct axienet_local {
|
|||
|
||||
/* MDIO bus data */
|
||||
struct mii_bus *mii_bus; /* MII bus reference */
|
||||
int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */
|
||||
|
||||
/* IO registers, dma functions and IRQs */
|
||||
void __iomem *regs;
|
||||
|
|
|
@ -212,7 +212,6 @@ int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np)
|
|||
bus->read = axienet_mdio_read;
|
||||
bus->write = axienet_mdio_write;
|
||||
bus->parent = lp->dev;
|
||||
bus->irq = lp->mdio_irqs; /* preallocated IRQ table */
|
||||
lp->mii_bus = bus;
|
||||
|
||||
ret = of_mdiobus_register(bus, np1);
|
||||
|
@ -232,7 +231,6 @@ int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np)
|
|||
void axienet_mdio_teardown(struct axienet_local *lp)
|
||||
{
|
||||
mdiobus_unregister(lp->mii_bus);
|
||||
kfree(lp->mii_bus->irq);
|
||||
mdiobus_free(lp->mii_bus);
|
||||
lp->mii_bus = NULL;
|
||||
}
|
||||
|
|
|
@ -114,7 +114,6 @@
|
|||
* @phy_dev: pointer to the PHY device
|
||||
* @phy_node: pointer to the PHY device node
|
||||
* @mii_bus: pointer to the MII bus
|
||||
* @mdio_irqs: IRQs table for MDIO bus
|
||||
* @last_link: last link status
|
||||
* @has_mdio: indicates whether MDIO is included in the HW
|
||||
*/
|
||||
|
@ -135,7 +134,6 @@ struct net_local {
|
|||
struct device_node *phy_node;
|
||||
|
||||
struct mii_bus *mii_bus;
|
||||
int mdio_irqs[PHY_MAX_ADDR];
|
||||
|
||||
int last_link;
|
||||
bool has_mdio;
|
||||
|
@ -829,7 +827,7 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev)
|
|||
dev_info(dev,
|
||||
"MDIO of the phy is not registered yet\n");
|
||||
else
|
||||
put_device(&phydev->dev);
|
||||
put_device(&phydev->mdio.dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -852,7 +850,6 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev)
|
|||
bus->read = xemaclite_mdio_read;
|
||||
bus->write = xemaclite_mdio_write;
|
||||
bus->parent = dev;
|
||||
bus->irq = lp->mdio_irqs; /* preallocated IRQ table */
|
||||
|
||||
lp->mii_bus = bus;
|
||||
|
||||
|
@ -1196,7 +1193,6 @@ static int xemaclite_of_remove(struct platform_device *of_dev)
|
|||
/* Un-register the mii_bus, if configured */
|
||||
if (lp->has_mdio) {
|
||||
mdiobus_unregister(lp->mii_bus);
|
||||
kfree(lp->mii_bus->irq);
|
||||
mdiobus_free(lp->mii_bus);
|
||||
lp->mii_bus = NULL;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Makefile for Linux PHY drivers
|
||||
|
||||
libphy-objs := phy.o phy_device.o mdio_bus.o
|
||||
libphy-objs := phy.o phy_device.o mdio_bus.o mdio_device.o
|
||||
|
||||
obj-$(CONFIG_PHYLIB) += libphy.o
|
||||
obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
|
||||
|
|
|
@ -72,7 +72,6 @@ static struct phy_driver am79c_driver[] = { {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = am79c_ack_interrupt,
|
||||
.config_intr = am79c_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
} };
|
||||
|
||||
module_phy_driver(am79c_driver);
|
||||
|
|
|
@ -128,7 +128,6 @@ static struct phy_driver aquantia_driver[] = {
|
|||
.config_intr = aquantia_config_intr,
|
||||
.ack_interrupt = aquantia_ack_interrupt,
|
||||
.read_status = aquantia_read_status,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
},
|
||||
{
|
||||
.phy_id = PHY_ID_AQ2104,
|
||||
|
@ -141,7 +140,6 @@ static struct phy_driver aquantia_driver[] = {
|
|||
.config_intr = aquantia_config_intr,
|
||||
.ack_interrupt = aquantia_ack_interrupt,
|
||||
.read_status = aquantia_read_status,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
},
|
||||
{
|
||||
.phy_id = PHY_ID_AQR105,
|
||||
|
@ -154,7 +152,6 @@ static struct phy_driver aquantia_driver[] = {
|
|||
.config_intr = aquantia_config_intr,
|
||||
.ack_interrupt = aquantia_ack_interrupt,
|
||||
.read_status = aquantia_read_status,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
},
|
||||
{
|
||||
.phy_id = PHY_ID_AQR405,
|
||||
|
@ -167,7 +164,6 @@ static struct phy_driver aquantia_driver[] = {
|
|||
.config_intr = aquantia_config_intr,
|
||||
.ack_interrupt = aquantia_ack_interrupt,
|
||||
.read_status = aquantia_read_status,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ static int at803x_resume(struct phy_device *phydev)
|
|||
|
||||
static int at803x_probe(struct phy_device *phydev)
|
||||
{
|
||||
struct device *dev = &phydev->dev;
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
struct at803x_priv *priv;
|
||||
struct gpio_desc *gpiod_reset;
|
||||
|
||||
|
@ -281,8 +281,8 @@ static void at803x_link_change_notify(struct phy_device *phydev)
|
|||
|
||||
at803x_context_restore(phydev, &context);
|
||||
|
||||
dev_dbg(&phydev->dev, "%s(): phy was reset\n",
|
||||
__func__);
|
||||
phydev_dbg(phydev, "%s(): phy was reset\n",
|
||||
__func__);
|
||||
priv->phy_reset = true;
|
||||
}
|
||||
} else {
|
||||
|
@ -310,9 +310,6 @@ static struct phy_driver at803x_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = at803x_ack_interrupt,
|
||||
.config_intr = at803x_config_intr,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
}, {
|
||||
/* ATHEROS 8030 */
|
||||
.phy_id = ATH8030_PHY_ID,
|
||||
|
@ -331,9 +328,6 @@ static struct phy_driver at803x_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = at803x_ack_interrupt,
|
||||
.config_intr = at803x_config_intr,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
}, {
|
||||
/* ATHEROS 8031 */
|
||||
.phy_id = ATH8031_PHY_ID,
|
||||
|
@ -352,9 +346,6 @@ static struct phy_driver at803x_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = &at803x_ack_interrupt,
|
||||
.config_intr = &at803x_config_intr,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
} };
|
||||
|
||||
module_phy_driver(at803x_driver);
|
||||
|
|
|
@ -184,25 +184,25 @@ int bcm_phy_enable_eee(struct phy_device *phydev)
|
|||
|
||||
/* Enable EEE at PHY level */
|
||||
val = phy_read_mmd_indirect(phydev, BRCM_CL45VEN_EEE_CONTROL,
|
||||
MDIO_MMD_AN, phydev->addr);
|
||||
MDIO_MMD_AN);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
val |= LPI_FEATURE_EN | LPI_FEATURE_EN_DIG1000X;
|
||||
|
||||
phy_write_mmd_indirect(phydev, BRCM_CL45VEN_EEE_CONTROL,
|
||||
MDIO_MMD_AN, phydev->addr, (u32)val);
|
||||
MDIO_MMD_AN, (u32)val);
|
||||
|
||||
/* Advertise EEE */
|
||||
val = phy_read_mmd_indirect(phydev, BCM_CL45VEN_EEE_ADV,
|
||||
MDIO_MMD_AN, phydev->addr);
|
||||
MDIO_MMD_AN);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
val |= (MDIO_AN_EEE_ADV_100TX | MDIO_AN_EEE_ADV_1000T);
|
||||
|
||||
phy_write_mmd_indirect(phydev, BCM_CL45VEN_EEE_ADV,
|
||||
MDIO_MMD_AN, phydev->addr, (u32)val);
|
||||
MDIO_MMD_AN, (u32)val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,6 @@ static struct phy_driver bcm63xx_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = bcm_phy_ack_intr,
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
/* same phy as above, with just a different OUI */
|
||||
.phy_id = 0x002bdc00,
|
||||
|
@ -69,7 +68,6 @@ static struct phy_driver bcm63xx_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = bcm_phy_ack_intr,
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
} };
|
||||
|
||||
module_phy_driver(bcm63xx_driver);
|
||||
|
|
|
@ -170,7 +170,7 @@ static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
|
|||
int ret = 0;
|
||||
|
||||
pr_info_once("%s: %s PHY revision: 0x%02x, patch: %d\n",
|
||||
dev_name(&phydev->dev), phydev->drv->name, rev, patch);
|
||||
phydev_name(phydev), phydev->drv->name, rev, patch);
|
||||
|
||||
/* Dummy read to a register to workaround an issue upon reset where the
|
||||
* internal inverter may not allow the first MDIO transaction to pass
|
||||
|
@ -324,7 +324,6 @@ static int bcm7xxx_dummy_config_init(struct phy_device *phydev)
|
|||
.config_aneg = genphy_config_aneg, \
|
||||
.read_status = genphy_read_status, \
|
||||
.resume = bcm7xxx_28nm_resume, \
|
||||
.driver = { .owner = THIS_MODULE }, \
|
||||
}
|
||||
|
||||
static struct phy_driver bcm7xxx_driver[] = {
|
||||
|
@ -346,7 +345,6 @@ static struct phy_driver bcm7xxx_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.suspend = bcm7xxx_suspend,
|
||||
.resume = bcm7xxx_config_init,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM7429,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -359,7 +357,6 @@ static struct phy_driver bcm7xxx_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.suspend = bcm7xxx_suspend,
|
||||
.resume = bcm7xxx_config_init,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM7435,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -372,7 +369,6 @@ static struct phy_driver bcm7xxx_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.suspend = bcm7xxx_suspend,
|
||||
.resume = bcm7xxx_config_init,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_BCM_OUI_4,
|
||||
.phy_id_mask = 0xffff0000,
|
||||
|
@ -385,7 +381,6 @@ static struct phy_driver bcm7xxx_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.suspend = bcm7xxx_suspend,
|
||||
.resume = bcm7xxx_config_init,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_BCM_OUI_5,
|
||||
.phy_id_mask = 0xffffff00,
|
||||
|
@ -398,7 +393,6 @@ static struct phy_driver bcm7xxx_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.suspend = bcm7xxx_suspend,
|
||||
.resume = bcm7xxx_config_init,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
} };
|
||||
|
||||
static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = {
|
||||
|
|
|
@ -40,10 +40,10 @@ static int bcm87xx_of_reg_init(struct phy_device *phydev)
|
|||
const __be32 *paddr_end;
|
||||
int len, ret;
|
||||
|
||||
if (!phydev->dev.of_node)
|
||||
if (!phydev->mdio.dev.of_node)
|
||||
return 0;
|
||||
|
||||
paddr = of_get_property(phydev->dev.of_node,
|
||||
paddr = of_get_property(phydev->mdio.dev.of_node,
|
||||
"broadcom,c45-reg-init", &len);
|
||||
if (!paddr)
|
||||
return 0;
|
||||
|
@ -163,8 +163,9 @@ static int bcm87xx_did_interrupt(struct phy_device *phydev)
|
|||
reg = phy_read(phydev, BCM87XX_LASI_STATUS);
|
||||
|
||||
if (reg < 0) {
|
||||
dev_err(&phydev->dev,
|
||||
"Error: Read of BCM87XX_LASI_STATUS failed: %d\n", reg);
|
||||
phydev_err(phydev,
|
||||
"Error: Read of BCM87XX_LASI_STATUS failed: %d\n",
|
||||
reg);
|
||||
return 0;
|
||||
}
|
||||
return (reg & 1) != 0;
|
||||
|
@ -200,7 +201,6 @@ static struct phy_driver bcm87xx_driver[] = {
|
|||
.config_intr = bcm87xx_config_intr,
|
||||
.did_interrupt = bcm87xx_did_interrupt,
|
||||
.match_phy_device = bcm8706_match_phy_device,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM8727,
|
||||
.phy_id_mask = 0xffffffff,
|
||||
|
@ -213,7 +213,6 @@ static struct phy_driver bcm87xx_driver[] = {
|
|||
.config_intr = bcm87xx_config_intr,
|
||||
.did_interrupt = bcm87xx_did_interrupt,
|
||||
.match_phy_device = bcm8727_match_phy_device,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
} };
|
||||
|
||||
module_phy_driver(bcm87xx_driver);
|
||||
|
|
|
@ -460,7 +460,6 @@ static struct phy_driver broadcom_drivers[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = bcm_phy_ack_intr,
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM5421,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -473,7 +472,6 @@ static struct phy_driver broadcom_drivers[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = bcm_phy_ack_intr,
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM5461,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -486,7 +484,6 @@ static struct phy_driver broadcom_drivers[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = bcm_phy_ack_intr,
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM54616S,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -499,7 +496,6 @@ static struct phy_driver broadcom_drivers[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = bcm_phy_ack_intr,
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM5464,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -512,7 +508,6 @@ static struct phy_driver broadcom_drivers[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = bcm_phy_ack_intr,
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM5481,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -525,7 +520,6 @@ static struct phy_driver broadcom_drivers[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = bcm_phy_ack_intr,
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM5482,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -538,7 +532,6 @@ static struct phy_driver broadcom_drivers[] = {
|
|||
.read_status = bcm5482_read_status,
|
||||
.ack_interrupt = bcm_phy_ack_intr,
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM50610,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -551,7 +544,6 @@ static struct phy_driver broadcom_drivers[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = bcm_phy_ack_intr,
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM50610M,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -564,7 +556,6 @@ static struct phy_driver broadcom_drivers[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = bcm_phy_ack_intr,
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM57780,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -577,7 +568,6 @@ static struct phy_driver broadcom_drivers[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = bcm_phy_ack_intr,
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCMAC131,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -590,7 +580,6 @@ static struct phy_driver broadcom_drivers[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = brcm_fet_ack_interrupt,
|
||||
.config_intr = brcm_fet_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM5241,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -603,7 +592,6 @@ static struct phy_driver broadcom_drivers[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = brcm_fet_ack_interrupt,
|
||||
.config_intr = brcm_fet_config_intr,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
} };
|
||||
|
||||
module_phy_driver(broadcom_drivers);
|
||||
|
|
|
@ -114,7 +114,6 @@ static struct phy_driver cis820x_driver[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &cis820x_ack_interrupt,
|
||||
.config_intr = &cis820x_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x000fc440,
|
||||
.name = "Cicada Cis8204",
|
||||
|
@ -126,7 +125,6 @@ static struct phy_driver cis820x_driver[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &cis820x_ack_interrupt,
|
||||
.config_intr = &cis820x_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
} };
|
||||
|
||||
module_phy_driver(cis820x_driver);
|
||||
|
|
|
@ -156,7 +156,6 @@ static struct phy_driver dm91xx_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = dm9161_ack_interrupt,
|
||||
.config_intr = dm9161_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x0181b8b0,
|
||||
.name = "Davicom DM9161B/C",
|
||||
|
@ -168,7 +167,6 @@ static struct phy_driver dm91xx_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = dm9161_ack_interrupt,
|
||||
.config_intr = dm9161_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x0181b8a0,
|
||||
.name = "Davicom DM9161A",
|
||||
|
@ -180,7 +178,6 @@ static struct phy_driver dm91xx_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = dm9161_ack_interrupt,
|
||||
.config_intr = dm9161_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x00181b80,
|
||||
.name = "Davicom DM9131",
|
||||
|
@ -191,7 +188,6 @@ static struct phy_driver dm91xx_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = dm9161_ack_interrupt,
|
||||
.config_intr = dm9161_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
} };
|
||||
|
||||
module_phy_driver(dm91xx_driver);
|
||||
|
|
|
@ -220,9 +220,10 @@ static void rx_timestamp_work(struct work_struct *work);
|
|||
|
||||
#define BROADCAST_ADDR 31
|
||||
|
||||
static inline int broadcast_write(struct mii_bus *bus, u32 regnum, u16 val)
|
||||
static inline int broadcast_write(struct phy_device *phydev, u32 regnum,
|
||||
u16 val)
|
||||
{
|
||||
return mdiobus_write(bus, BROADCAST_ADDR, regnum, val);
|
||||
return mdiobus_write(phydev->mdio.bus, BROADCAST_ADDR, regnum, val);
|
||||
}
|
||||
|
||||
/* Caller must hold extreg_lock. */
|
||||
|
@ -232,7 +233,7 @@ static int ext_read(struct phy_device *phydev, int page, u32 regnum)
|
|||
int val;
|
||||
|
||||
if (dp83640->clock->page != page) {
|
||||
broadcast_write(phydev->bus, PAGESEL, page);
|
||||
broadcast_write(phydev, PAGESEL, page);
|
||||
dp83640->clock->page = page;
|
||||
}
|
||||
val = phy_read(phydev, regnum);
|
||||
|
@ -247,11 +248,11 @@ static void ext_write(int broadcast, struct phy_device *phydev,
|
|||
struct dp83640_private *dp83640 = phydev->priv;
|
||||
|
||||
if (dp83640->clock->page != page) {
|
||||
broadcast_write(phydev->bus, PAGESEL, page);
|
||||
broadcast_write(phydev, PAGESEL, page);
|
||||
dp83640->clock->page = page;
|
||||
}
|
||||
if (broadcast)
|
||||
broadcast_write(phydev->bus, regnum, val);
|
||||
broadcast_write(phydev, regnum, val);
|
||||
else
|
||||
phy_write(phydev, regnum, val);
|
||||
}
|
||||
|
@ -1039,7 +1040,7 @@ static int choose_this_phy(struct dp83640_clock *clock,
|
|||
if (chosen_phy == -1 && !clock->chosen)
|
||||
return 1;
|
||||
|
||||
if (chosen_phy == phydev->addr)
|
||||
if (chosen_phy == phydev->mdio.addr)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
@ -1103,10 +1104,10 @@ static int dp83640_probe(struct phy_device *phydev)
|
|||
struct dp83640_private *dp83640;
|
||||
int err = -ENOMEM, i;
|
||||
|
||||
if (phydev->addr == BROADCAST_ADDR)
|
||||
if (phydev->mdio.addr == BROADCAST_ADDR)
|
||||
return 0;
|
||||
|
||||
clock = dp83640_clock_get_bus(phydev->bus);
|
||||
clock = dp83640_clock_get_bus(phydev->mdio.bus);
|
||||
if (!clock)
|
||||
goto no_clock;
|
||||
|
||||
|
@ -1132,7 +1133,8 @@ static int dp83640_probe(struct phy_device *phydev)
|
|||
|
||||
if (choose_this_phy(clock, phydev)) {
|
||||
clock->chosen = dp83640;
|
||||
clock->ptp_clock = ptp_clock_register(&clock->caps, &phydev->dev);
|
||||
clock->ptp_clock = ptp_clock_register(&clock->caps,
|
||||
&phydev->mdio.dev);
|
||||
if (IS_ERR(clock->ptp_clock)) {
|
||||
err = PTR_ERR(clock->ptp_clock);
|
||||
goto no_register;
|
||||
|
@ -1158,7 +1160,7 @@ static void dp83640_remove(struct phy_device *phydev)
|
|||
struct list_head *this, *next;
|
||||
struct dp83640_private *tmp, *dp83640 = phydev->priv;
|
||||
|
||||
if (phydev->addr == BROADCAST_ADDR)
|
||||
if (phydev->mdio.addr == BROADCAST_ADDR)
|
||||
return;
|
||||
|
||||
enable_status_frames(phydev, false);
|
||||
|
@ -1490,12 +1492,11 @@ static struct phy_driver dp83640_driver = {
|
|||
.hwtstamp = dp83640_hwtstamp,
|
||||
.rxtstamp = dp83640_rxtstamp,
|
||||
.txtstamp = dp83640_txtstamp,
|
||||
.driver = {.owner = THIS_MODULE,}
|
||||
};
|
||||
|
||||
static int __init dp83640_init(void)
|
||||
{
|
||||
return phy_driver_register(&dp83640_driver);
|
||||
return phy_driver_register(&dp83640_driver, THIS_MODULE);
|
||||
}
|
||||
|
||||
static void __exit dp83640_exit(void)
|
||||
|
|
|
@ -88,8 +88,6 @@ static struct phy_driver dp83848_driver[] = {
|
|||
/* IRQ related */
|
||||
.ack_interrupt = dp83848_ack_interrupt,
|
||||
.config_intr = dp83848_config_intr,
|
||||
|
||||
.driver = { .owner = THIS_MODULE, },
|
||||
},
|
||||
};
|
||||
module_phy_driver(dp83848_driver);
|
||||
|
|
|
@ -103,7 +103,7 @@ static int dp83867_config_intr(struct phy_device *phydev)
|
|||
static int dp83867_of_init(struct phy_device *phydev)
|
||||
{
|
||||
struct dp83867_private *dp83867 = phydev->priv;
|
||||
struct device *dev = &phydev->dev;
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
struct device_node *of_node = dev->of_node;
|
||||
int ret;
|
||||
|
||||
|
@ -137,7 +137,7 @@ static int dp83867_config_init(struct phy_device *phydev)
|
|||
u16 val, delay;
|
||||
|
||||
if (!phydev->priv) {
|
||||
dp83867 = devm_kzalloc(&phydev->dev, sizeof(*dp83867),
|
||||
dp83867 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83867),
|
||||
GFP_KERNEL);
|
||||
if (!dp83867)
|
||||
return -ENOMEM;
|
||||
|
@ -160,7 +160,7 @@ static int dp83867_config_init(struct phy_device *phydev)
|
|||
if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) &&
|
||||
(phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) {
|
||||
val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL,
|
||||
DP83867_DEVADDR, phydev->addr);
|
||||
DP83867_DEVADDR);
|
||||
|
||||
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
|
||||
val |= (DP83867_RGMII_TX_CLK_DELAY_EN | DP83867_RGMII_RX_CLK_DELAY_EN);
|
||||
|
@ -172,13 +172,13 @@ static int dp83867_config_init(struct phy_device *phydev)
|
|||
val |= DP83867_RGMII_RX_CLK_DELAY_EN;
|
||||
|
||||
phy_write_mmd_indirect(phydev, DP83867_RGMIICTL,
|
||||
DP83867_DEVADDR, phydev->addr, val);
|
||||
DP83867_DEVADDR, val);
|
||||
|
||||
delay = (dp83867->rx_id_delay |
|
||||
(dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
|
||||
|
||||
phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL,
|
||||
DP83867_DEVADDR, phydev->addr, delay);
|
||||
DP83867_DEVADDR, delay);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -214,8 +214,6 @@ static struct phy_driver dp83867_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
|
||||
.driver = {.owner = THIS_MODULE,}
|
||||
},
|
||||
};
|
||||
module_phy_driver(dp83867_driver);
|
||||
|
|
|
@ -95,7 +95,6 @@ static struct phy_driver et1011c_driver[] = { {
|
|||
.flags = PHY_POLL,
|
||||
.config_aneg = et1011c_config_aneg,
|
||||
.read_status = et1011c_read_status,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
} };
|
||||
|
||||
module_phy_driver(et1011c_driver);
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#define MII_REGS_NUM 29
|
||||
|
||||
struct fixed_mdio_bus {
|
||||
int irqs[PHY_MAX_ADDR];
|
||||
struct mii_bus *mii_bus;
|
||||
struct list_head phys;
|
||||
};
|
||||
|
@ -198,11 +197,11 @@ int fixed_phy_set_link_update(struct phy_device *phydev,
|
|||
struct fixed_mdio_bus *fmb = &platform_fmb;
|
||||
struct fixed_phy *fp;
|
||||
|
||||
if (!phydev || !phydev->bus)
|
||||
if (!phydev || !phydev->mdio.bus)
|
||||
return -EINVAL;
|
||||
|
||||
list_for_each_entry(fp, &fmb->phys, node) {
|
||||
if (fp->addr == phydev->addr) {
|
||||
if (fp->addr == phydev->mdio.addr) {
|
||||
fp->link_update = link_update;
|
||||
fp->phydev = phydev;
|
||||
return 0;
|
||||
|
@ -220,11 +219,11 @@ int fixed_phy_update_state(struct phy_device *phydev,
|
|||
struct fixed_mdio_bus *fmb = &platform_fmb;
|
||||
struct fixed_phy *fp;
|
||||
|
||||
if (!phydev || phydev->bus != fmb->mii_bus)
|
||||
if (!phydev || phydev->mdio.bus != fmb->mii_bus)
|
||||
return -EINVAL;
|
||||
|
||||
list_for_each_entry(fp, &fmb->phys, node) {
|
||||
if (fp->addr == phydev->addr) {
|
||||
if (fp->addr == phydev->mdio.addr) {
|
||||
#define _UPD(x) if (changed->x) \
|
||||
fp->status.x = status->x
|
||||
_UPD(link);
|
||||
|
@ -256,7 +255,7 @@ int fixed_phy_add(unsigned int irq, int phy_addr,
|
|||
|
||||
memset(fp->regs, 0xFF, sizeof(fp->regs[0]) * MII_REGS_NUM);
|
||||
|
||||
fmb->irqs[phy_addr] = irq;
|
||||
fmb->mii_bus->irq[phy_addr] = irq;
|
||||
|
||||
fp->addr = phy_addr;
|
||||
fp->status = *status;
|
||||
|
@ -345,7 +344,7 @@ struct phy_device *fixed_phy_register(unsigned int irq,
|
|||
}
|
||||
|
||||
of_node_get(np);
|
||||
phy->dev.of_node = np;
|
||||
phy->mdio.dev.of_node = np;
|
||||
phy->is_pseudo_fixed_link = true;
|
||||
|
||||
switch (status->speed) {
|
||||
|
@ -395,7 +394,6 @@ static int __init fixed_mdio_bus_init(void)
|
|||
fmb->mii_bus->parent = &pdev->dev;
|
||||
fmb->mii_bus->read = &fixed_mdio_read;
|
||||
fmb->mii_bus->write = &fixed_mdio_write;
|
||||
fmb->mii_bus->irq = fmb->irqs;
|
||||
|
||||
ret = mdiobus_register(fmb->mii_bus);
|
||||
if (ret)
|
||||
|
|
|
@ -53,43 +53,43 @@ static int ip175c_config_init(struct phy_device *phydev)
|
|||
if (full_reset_performed == 0) {
|
||||
|
||||
/* master reset */
|
||||
err = mdiobus_write(phydev->bus, 30, 0, 0x175c);
|
||||
err = mdiobus_write(phydev->mdio.bus, 30, 0, 0x175c);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* ensure no bus delays overlap reset period */
|
||||
err = mdiobus_read(phydev->bus, 30, 0);
|
||||
err = mdiobus_read(phydev->mdio.bus, 30, 0);
|
||||
|
||||
/* data sheet specifies reset period is 2 msec */
|
||||
mdelay(2);
|
||||
|
||||
/* enable IP175C mode */
|
||||
err = mdiobus_write(phydev->bus, 29, 31, 0x175c);
|
||||
err = mdiobus_write(phydev->mdio.bus, 29, 31, 0x175c);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Set MII0 speed and duplex (in PHY mode) */
|
||||
err = mdiobus_write(phydev->bus, 29, 22, 0x420);
|
||||
err = mdiobus_write(phydev->mdio.bus, 29, 22, 0x420);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* reset switch ports */
|
||||
for (i = 0; i < 5; i++) {
|
||||
err = mdiobus_write(phydev->bus, i,
|
||||
err = mdiobus_write(phydev->mdio.bus, i,
|
||||
MII_BMCR, BMCR_RESET);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
err = mdiobus_read(phydev->bus, i, MII_BMCR);
|
||||
err = mdiobus_read(phydev->mdio.bus, i, MII_BMCR);
|
||||
|
||||
mdelay(2);
|
||||
|
||||
full_reset_performed = 1;
|
||||
}
|
||||
|
||||
if (phydev->addr != 4) {
|
||||
if (phydev->mdio.addr != 4) {
|
||||
phydev->state = PHY_RUNNING;
|
||||
phydev->speed = SPEED_100;
|
||||
phydev->duplex = DUPLEX_FULL;
|
||||
|
@ -184,7 +184,7 @@ static int ip101a_g_config_init(struct phy_device *phydev)
|
|||
|
||||
static int ip175c_read_status(struct phy_device *phydev)
|
||||
{
|
||||
if (phydev->addr == 4) /* WAN port */
|
||||
if (phydev->mdio.addr == 4) /* WAN port */
|
||||
genphy_read_status(phydev);
|
||||
else
|
||||
/* Don't need to read status for switch ports */
|
||||
|
@ -195,7 +195,7 @@ static int ip175c_read_status(struct phy_device *phydev)
|
|||
|
||||
static int ip175c_config_aneg(struct phy_device *phydev)
|
||||
{
|
||||
if (phydev->addr == 4) /* WAN port */
|
||||
if (phydev->mdio.addr == 4) /* WAN port */
|
||||
genphy_config_aneg(phydev);
|
||||
|
||||
return 0;
|
||||
|
@ -221,7 +221,6 @@ static struct phy_driver icplus_driver[] = {
|
|||
.read_status = &ip175c_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x02430d90,
|
||||
.name = "ICPlus IP1001",
|
||||
|
@ -233,7 +232,6 @@ static struct phy_driver icplus_driver[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x02430c54,
|
||||
.name = "ICPlus IP101A/G",
|
||||
|
@ -247,7 +245,6 @@ static struct phy_driver icplus_driver[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
} };
|
||||
|
||||
module_phy_driver(icplus_driver);
|
||||
|
|
|
@ -278,7 +278,6 @@ static struct phy_driver lxt97x_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = lxt970_ack_interrupt,
|
||||
.config_intr = lxt970_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x001378e0,
|
||||
.name = "LXT971",
|
||||
|
@ -289,7 +288,6 @@ static struct phy_driver lxt97x_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = lxt971_ack_interrupt,
|
||||
.config_intr = lxt971_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x00137a10,
|
||||
.name = "LXT973-A2",
|
||||
|
@ -299,7 +297,6 @@ static struct phy_driver lxt97x_driver[] = {
|
|||
.probe = lxt973_probe,
|
||||
.config_aneg = lxt973_config_aneg,
|
||||
.read_status = lxt973a2_read_status,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x00137a10,
|
||||
.name = "LXT973",
|
||||
|
@ -309,7 +306,6 @@ static struct phy_driver lxt97x_driver[] = {
|
|||
.probe = lxt973_probe,
|
||||
.config_aneg = lxt973_config_aneg,
|
||||
.read_status = genphy_read_status,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
} };
|
||||
|
||||
module_phy_driver(lxt97x_driver);
|
||||
|
|
|
@ -300,10 +300,11 @@ static int marvell_of_reg_init(struct phy_device *phydev)
|
|||
const __be32 *paddr;
|
||||
int len, i, saved_page, current_page, page_changed, ret;
|
||||
|
||||
if (!phydev->dev.of_node)
|
||||
if (!phydev->mdio.dev.of_node)
|
||||
return 0;
|
||||
|
||||
paddr = of_get_property(phydev->dev.of_node, "marvell,reg-init", &len);
|
||||
paddr = of_get_property(phydev->mdio.dev.of_node,
|
||||
"marvell,reg-init", &len);
|
||||
if (!paddr || len < (4 * sizeof(*paddr)))
|
||||
return 0;
|
||||
|
||||
|
@ -1060,7 +1061,7 @@ static int marvell_probe(struct phy_device *phydev)
|
|||
{
|
||||
struct marvell_priv *priv;
|
||||
|
||||
priv = devm_kzalloc(&phydev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1086,7 +1087,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E1112,
|
||||
|
@ -1105,7 +1105,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E1111,
|
||||
|
@ -1124,7 +1123,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E1118,
|
||||
|
@ -1143,7 +1141,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = {.owner = THIS_MODULE,},
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E1121R,
|
||||
|
@ -1162,7 +1159,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E1318S,
|
||||
|
@ -1183,7 +1179,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E1145,
|
||||
|
@ -1202,7 +1197,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E1149R,
|
||||
|
@ -1221,7 +1215,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E1240,
|
||||
|
@ -1240,7 +1233,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E1116R,
|
||||
|
@ -1259,7 +1251,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E1510,
|
||||
|
@ -1278,7 +1269,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E1540,
|
||||
|
@ -1297,7 +1287,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E3016,
|
||||
|
@ -1318,7 +1307,6 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -200,16 +200,10 @@ static int unimac_mdio_probe(struct platform_device *pdev)
|
|||
bus->reset = unimac_mdio_reset;
|
||||
snprintf(bus->id, MII_BUS_ID_SIZE, "%s", pdev->name);
|
||||
|
||||
bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
|
||||
if (!bus->irq) {
|
||||
ret = -ENOMEM;
|
||||
goto out_mdio_free;
|
||||
}
|
||||
|
||||
ret = of_mdiobus_register(bus, np);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "MDIO bus registration failed\n");
|
||||
goto out_mdio_irq;
|
||||
goto out_mdio_free;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
@ -218,8 +212,6 @@ static int unimac_mdio_probe(struct platform_device *pdev)
|
|||
|
||||
return 0;
|
||||
|
||||
out_mdio_irq:
|
||||
kfree(bus->irq);
|
||||
out_mdio_free:
|
||||
mdiobus_free(bus);
|
||||
return ret;
|
||||
|
@ -230,7 +222,6 @@ static int unimac_mdio_remove(struct platform_device *pdev)
|
|||
struct unimac_mdio_priv *priv = platform_get_drvdata(pdev);
|
||||
|
||||
mdiobus_unregister(priv->mii_bus);
|
||||
kfree(priv->mii_bus->irq);
|
||||
mdiobus_free(priv->mii_bus);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -159,7 +159,7 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev,
|
|||
|
||||
new_bus->phy_mask = pdata->phy_mask;
|
||||
new_bus->phy_ignore_ta_mask = pdata->phy_ignore_ta_mask;
|
||||
new_bus->irq = pdata->irqs;
|
||||
memcpy(new_bus->irq, pdata->irqs, sizeof(new_bus->irq));
|
||||
new_bus->parent = dev;
|
||||
|
||||
if (new_bus->phy_mask == ~0)
|
||||
|
|
|
@ -130,13 +130,6 @@ static int moxart_mdio_probe(struct platform_device *pdev)
|
|||
snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d-mii", pdev->name, pdev->id);
|
||||
bus->parent = &pdev->dev;
|
||||
|
||||
bus->irq = devm_kzalloc(&pdev->dev, sizeof(int) * PHY_MAX_ADDR,
|
||||
GFP_KERNEL);
|
||||
if (!bus->irq) {
|
||||
ret = -ENOMEM;
|
||||
goto err_out_free_mdiobus;
|
||||
}
|
||||
|
||||
/* Setting PHY_IGNORE_INTERRUPT here even if it has no effect,
|
||||
* of_mdiobus_register() sets these PHY_POLL.
|
||||
* Ideally, the interrupt from MAC controller could be used to
|
||||
|
|
|
@ -34,7 +34,6 @@ struct mdio_mux_child_bus {
|
|||
struct mdio_mux_parent_bus *parent;
|
||||
struct mdio_mux_child_bus *next;
|
||||
int bus_number;
|
||||
int phy_irq[PHY_MAX_ADDR];
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -157,7 +156,7 @@ int mdio_mux_init(struct device *dev,
|
|||
break;
|
||||
}
|
||||
cb->mii_bus->priv = cb;
|
||||
cb->mii_bus->irq = cb->phy_irq;
|
||||
|
||||
cb->mii_bus->name = "mdio_mux";
|
||||
snprintf(cb->mii_bus->id, MII_BUS_ID_SIZE, "%x.%x",
|
||||
pb->parent_id, v);
|
||||
|
|
|
@ -113,7 +113,6 @@ struct octeon_mdiobus {
|
|||
resource_size_t mdio_phys;
|
||||
resource_size_t regsize;
|
||||
enum octeon_mdiobus_mode mode;
|
||||
int phy_irq[PHY_MAX_ADDR];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CAVIUM_OCTEON_SOC
|
||||
|
@ -268,12 +267,13 @@ static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
|
|||
static int octeon_mdiobus_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct octeon_mdiobus *bus;
|
||||
struct mii_bus *mii_bus;
|
||||
struct resource *res_mem;
|
||||
union cvmx_smix_en smi_en;
|
||||
int err = -ENOENT;
|
||||
|
||||
bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
|
||||
if (!bus)
|
||||
mii_bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*bus));
|
||||
if (!mii_bus)
|
||||
return -ENOMEM;
|
||||
|
||||
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
@ -282,6 +282,8 @@ static int octeon_mdiobus_probe(struct platform_device *pdev)
|
|||
return -ENXIO;
|
||||
}
|
||||
|
||||
bus = mii_bus->priv;
|
||||
bus->mii_bus = mii_bus;
|
||||
bus->mdio_phys = res_mem->start;
|
||||
bus->regsize = resource_size(res_mem);
|
||||
|
||||
|
@ -298,16 +300,11 @@ static int octeon_mdiobus_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
bus->mii_bus = mdiobus_alloc();
|
||||
if (!bus->mii_bus)
|
||||
goto fail;
|
||||
|
||||
smi_en.u64 = 0;
|
||||
smi_en.s.en = 1;
|
||||
oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN);
|
||||
|
||||
bus->mii_bus->priv = bus;
|
||||
bus->mii_bus->irq = bus->phy_irq;
|
||||
bus->mii_bus->name = "mdio-octeon";
|
||||
snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%llx", bus->register_base);
|
||||
bus->mii_bus->parent = &pdev->dev;
|
||||
|
@ -326,7 +323,6 @@ static int octeon_mdiobus_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
fail_register:
|
||||
mdiobus_free(bus->mii_bus);
|
||||
fail:
|
||||
smi_en.u64 = 0;
|
||||
oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN);
|
||||
return err;
|
||||
|
|
|
@ -96,7 +96,7 @@ static int sun4i_mdio_probe(struct platform_device *pdev)
|
|||
struct mii_bus *bus;
|
||||
struct sun4i_mdio_data *data;
|
||||
struct resource *res;
|
||||
int ret, i;
|
||||
int ret;
|
||||
|
||||
bus = mdiobus_alloc_size(sizeof(*data));
|
||||
if (!bus)
|
||||
|
@ -108,16 +108,6 @@ static int sun4i_mdio_probe(struct platform_device *pdev)
|
|||
snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(&pdev->dev));
|
||||
bus->parent = &pdev->dev;
|
||||
|
||||
bus->irq = devm_kzalloc(&pdev->dev, sizeof(int) * PHY_MAX_ADDR,
|
||||
GFP_KERNEL);
|
||||
if (!bus->irq) {
|
||||
ret = -ENOMEM;
|
||||
goto err_out_free_mdiobus;
|
||||
}
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
bus->irq[i] = PHY_POLL;
|
||||
|
||||
data = bus->priv;
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
data->membase = devm_ioremap_resource(&pdev->dev, res);
|
||||
|
|
|
@ -38,6 +38,48 @@
|
|||
|
||||
#include <asm/irq.h>
|
||||
|
||||
int mdiobus_register_device(struct mdio_device *mdiodev)
|
||||
{
|
||||
if (mdiodev->bus->mdio_map[mdiodev->addr])
|
||||
return -EBUSY;
|
||||
|
||||
mdiodev->bus->mdio_map[mdiodev->addr] = mdiodev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mdiobus_register_device);
|
||||
|
||||
int mdiobus_unregister_device(struct mdio_device *mdiodev)
|
||||
{
|
||||
if (mdiodev->bus->mdio_map[mdiodev->addr] != mdiodev)
|
||||
return -EINVAL;
|
||||
|
||||
mdiodev->bus->mdio_map[mdiodev->addr] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mdiobus_unregister_device);
|
||||
|
||||
struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr)
|
||||
{
|
||||
struct mdio_device *mdiodev = bus->mdio_map[addr];
|
||||
|
||||
if (!mdiodev)
|
||||
return NULL;
|
||||
|
||||
if (!(mdiodev->flags & MDIO_DEVICE_FLAG_PHY))
|
||||
return NULL;
|
||||
|
||||
return container_of(mdiodev, struct phy_device, mdio);
|
||||
}
|
||||
EXPORT_SYMBOL(mdiobus_get_phy);
|
||||
|
||||
bool mdiobus_is_registered_device(struct mii_bus *bus, int addr)
|
||||
{
|
||||
return bus->mdio_map[addr];
|
||||
}
|
||||
EXPORT_SYMBOL(mdiobus_is_registered_device);
|
||||
|
||||
/**
|
||||
* mdiobus_alloc_size - allocate a mii_bus structure
|
||||
* @size: extra amount of memory to allocate for private storage.
|
||||
|
@ -51,6 +93,7 @@ struct mii_bus *mdiobus_alloc_size(size_t size)
|
|||
struct mii_bus *bus;
|
||||
size_t aligned_size = ALIGN(sizeof(*bus), NETDEV_ALIGN);
|
||||
size_t alloc_size;
|
||||
int i;
|
||||
|
||||
/* If we alloc extra space, it should be aligned */
|
||||
if (size)
|
||||
|
@ -65,6 +108,10 @@ struct mii_bus *mdiobus_alloc_size(size_t size)
|
|||
bus->priv = (void *)bus + aligned_size;
|
||||
}
|
||||
|
||||
/* Initialise the interrupts to polling */
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
bus->irq[i] = PHY_POLL;
|
||||
|
||||
return bus;
|
||||
}
|
||||
EXPORT_SYMBOL(mdiobus_alloc_size);
|
||||
|
@ -190,47 +237,48 @@ struct mii_bus *of_mdio_find_bus(struct device_node *mdio_bus_np)
|
|||
}
|
||||
EXPORT_SYMBOL(of_mdio_find_bus);
|
||||
|
||||
/* Walk the list of subnodes of a mdio bus and look for a node that matches the
|
||||
* phy's address with its 'reg' property. If found, set the of_node pointer for
|
||||
* the phy. This allows auto-probed pyh devices to be supplied with information
|
||||
* passed in via DT.
|
||||
/* Walk the list of subnodes of a mdio bus and look for a node that
|
||||
* matches the mdio device's address with its 'reg' property. If
|
||||
* found, set the of_node pointer for the mdio device. This allows
|
||||
* auto-probed phy devices to be supplied with information passed in
|
||||
* via DT.
|
||||
*/
|
||||
static void of_mdiobus_link_phydev(struct mii_bus *mdio,
|
||||
struct phy_device *phydev)
|
||||
static void of_mdiobus_link_mdiodev(struct mii_bus *bus,
|
||||
struct mdio_device *mdiodev)
|
||||
{
|
||||
struct device *dev = &phydev->dev;
|
||||
struct device *dev = &mdiodev->dev;
|
||||
struct device_node *child;
|
||||
|
||||
if (dev->of_node || !mdio->dev.of_node)
|
||||
if (dev->of_node || !bus->dev.of_node)
|
||||
return;
|
||||
|
||||
for_each_available_child_of_node(mdio->dev.of_node, child) {
|
||||
for_each_available_child_of_node(bus->dev.of_node, child) {
|
||||
int addr;
|
||||
int ret;
|
||||
|
||||
ret = of_property_read_u32(child, "reg", &addr);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s has invalid PHY address\n",
|
||||
dev_err(dev, "%s has invalid MDIO address\n",
|
||||
child->full_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* A PHY must have a reg property in the range [0-31] */
|
||||
/* A MDIO device must have a reg property in the range [0-31] */
|
||||
if (addr >= PHY_MAX_ADDR) {
|
||||
dev_err(dev, "%s PHY address %i is too large\n",
|
||||
dev_err(dev, "%s MDIO address %i is too large\n",
|
||||
child->full_name, addr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (addr == phydev->addr) {
|
||||
if (addr == mdiodev->addr) {
|
||||
dev->of_node = child;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* !IS_ENABLED(CONFIG_OF_MDIO) */
|
||||
static inline void of_mdiobus_link_phydev(struct mii_bus *mdio,
|
||||
struct phy_device *phydev)
|
||||
static inline void of_mdiobus_link_mdiodev(struct mii_bus *mdio,
|
||||
struct mdio_device *mdiodev)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
@ -243,12 +291,15 @@ static inline void of_mdiobus_link_phydev(struct mii_bus *mdio,
|
|||
* Description: Called by a bus driver to bring up all the PHYs
|
||||
* on a given bus, and attach them to the bus. Drivers should use
|
||||
* mdiobus_register() rather than __mdiobus_register() unless they
|
||||
* need to pass a specific owner module.
|
||||
* need to pass a specific owner module. MDIO devices which are not
|
||||
* PHYs will not be brought up by this function. They are expected to
|
||||
* to be explicitly listed in DT and instantiated by of_mdiobus_register().
|
||||
*
|
||||
* Returns 0 on success or < 0 on error.
|
||||
*/
|
||||
int __mdiobus_register(struct mii_bus *bus, struct module *owner)
|
||||
{
|
||||
struct mdio_device *mdiodev;
|
||||
int i, err;
|
||||
|
||||
if (NULL == bus || NULL == bus->name ||
|
||||
|
@ -294,11 +345,12 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
|
|||
|
||||
error:
|
||||
while (--i >= 0) {
|
||||
struct phy_device *phydev = bus->phy_map[i];
|
||||
if (phydev) {
|
||||
phy_device_remove(phydev);
|
||||
phy_device_free(phydev);
|
||||
}
|
||||
mdiodev = bus->mdio_map[i];
|
||||
if (!mdiodev)
|
||||
continue;
|
||||
|
||||
mdiodev->device_remove(mdiodev);
|
||||
mdiodev->device_free(mdiodev);
|
||||
}
|
||||
device_del(&bus->dev);
|
||||
return err;
|
||||
|
@ -307,17 +359,19 @@ EXPORT_SYMBOL(__mdiobus_register);
|
|||
|
||||
void mdiobus_unregister(struct mii_bus *bus)
|
||||
{
|
||||
struct mdio_device *mdiodev;
|
||||
int i;
|
||||
|
||||
BUG_ON(bus->state != MDIOBUS_REGISTERED);
|
||||
bus->state = MDIOBUS_UNREGISTERED;
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++) {
|
||||
struct phy_device *phydev = bus->phy_map[i];
|
||||
if (phydev) {
|
||||
phy_device_remove(phydev);
|
||||
phy_device_free(phydev);
|
||||
}
|
||||
mdiodev = bus->mdio_map[i];
|
||||
if (!mdiodev)
|
||||
continue;
|
||||
|
||||
mdiodev->device_remove(mdiodev);
|
||||
mdiodev->device_free(mdiodev);
|
||||
}
|
||||
device_del(&bus->dev);
|
||||
}
|
||||
|
@ -346,6 +400,18 @@ void mdiobus_free(struct mii_bus *bus)
|
|||
}
|
||||
EXPORT_SYMBOL(mdiobus_free);
|
||||
|
||||
/**
|
||||
* mdiobus_scan - scan a bus for MDIO devices.
|
||||
* @bus: mii_bus to scan
|
||||
* @addr: address on bus to scan
|
||||
*
|
||||
* This function scans the MDIO bus, looking for devices which can be
|
||||
* identified using a vendor/product ID in registers 2 and 3. Not all
|
||||
* MDIO devices have such registers, but PHY devices typically
|
||||
* do. Hence this function assumes anything found is a PHY, or can be
|
||||
* treated as a PHY. Other MDIO devices, such as switches, will
|
||||
* probably not be found during the scan.
|
||||
*/
|
||||
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
|
||||
{
|
||||
struct phy_device *phydev;
|
||||
|
@ -359,7 +425,7 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
|
|||
* For DT, see if the auto-probed phy has a correspoding child
|
||||
* in the bus node, and set the of_node pointer in this case.
|
||||
*/
|
||||
of_mdiobus_link_phydev(bus, phydev);
|
||||
of_mdiobus_link_mdiodev(bus, &phydev->mdio);
|
||||
|
||||
err = phy_device_register(phydev);
|
||||
if (err) {
|
||||
|
@ -476,133 +542,56 @@ int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val)
|
|||
EXPORT_SYMBOL(mdiobus_write);
|
||||
|
||||
/**
|
||||
* mdio_bus_match - determine if given PHY driver supports the given PHY device
|
||||
* @dev: target PHY device
|
||||
* @drv: given PHY driver
|
||||
* mdio_bus_match - determine if given MDIO driver supports the given
|
||||
* MDIO device
|
||||
* @dev: target MDIO device
|
||||
* @drv: given MDIO driver
|
||||
*
|
||||
* Description: Given a PHY device, and a PHY driver, return 1 if
|
||||
* the driver supports the device. Otherwise, return 0.
|
||||
* Description: Given a MDIO device, and a MDIO driver, return 1 if
|
||||
* the driver supports the device. Otherwise, return 0. This may
|
||||
* require calling the devices own match function, since different classes
|
||||
* of MDIO devices have different match criteria.
|
||||
*/
|
||||
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);
|
||||
const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids);
|
||||
int i;
|
||||
struct mdio_device *mdio = to_mdio_device(dev);
|
||||
|
||||
if (of_driver_match_device(dev, drv))
|
||||
return 1;
|
||||
|
||||
if (phydrv->match_phy_device)
|
||||
return phydrv->match_phy_device(phydev);
|
||||
if (mdio->bus_match)
|
||||
return mdio->bus_match(dev, drv);
|
||||
|
||||
if (phydev->is_c45) {
|
||||
for (i = 1; i < num_ids; i++) {
|
||||
if (!(phydev->c45_ids.devices_in_package & (1 << i)))
|
||||
continue;
|
||||
|
||||
if ((phydrv->phy_id & phydrv->phy_id_mask) ==
|
||||
(phydev->c45_ids.device_ids[i] &
|
||||
phydrv->phy_id_mask))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return (phydrv->phy_id & phydrv->phy_id_mask) ==
|
||||
(phydev->phy_id & phydrv->phy_id_mask);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
|
||||
{
|
||||
struct device_driver *drv = phydev->dev.driver;
|
||||
struct phy_driver *phydrv = to_phy_driver(drv);
|
||||
struct net_device *netdev = phydev->attached_dev;
|
||||
|
||||
if (!drv || !phydrv->suspend)
|
||||
return false;
|
||||
|
||||
/* PHY not attached? May suspend if the PHY has not already been
|
||||
* suspended as part of a prior call to phy_disconnect() ->
|
||||
* phy_detach() -> phy_suspend() because the parent netdev might be the
|
||||
* MDIO bus driver and clock gated at this point.
|
||||
*/
|
||||
if (!netdev)
|
||||
return !phydev->suspended;
|
||||
|
||||
/* Don't suspend PHY if the attched netdev parent may wakeup.
|
||||
* The parent may point to a PCI device, as in tg3 driver.
|
||||
*/
|
||||
if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent))
|
||||
return false;
|
||||
|
||||
/* Also don't suspend PHY if the netdev itself may wakeup. This
|
||||
* is the case for devices w/o underlaying pwr. mgmt. aware bus,
|
||||
* e.g. SoC devices.
|
||||
*/
|
||||
if (device_may_wakeup(&netdev->dev))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int mdio_bus_suspend(struct device *dev)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
struct mdio_device *mdio = to_mdio_device(dev);
|
||||
|
||||
/* We must stop the state machine manually, otherwise it stops out of
|
||||
* control, possibly with the phydev->lock held. Upon resume, netdev
|
||||
* may call phy routines that try to grab the same lock, and that may
|
||||
* lead to a deadlock.
|
||||
*/
|
||||
if (phydev->attached_dev && phydev->adjust_link)
|
||||
phy_stop_machine(phydev);
|
||||
if (mdio->pm_ops && mdio->pm_ops->suspend)
|
||||
return mdio->pm_ops->suspend(dev);
|
||||
|
||||
if (!mdio_bus_phy_may_suspend(phydev))
|
||||
return 0;
|
||||
|
||||
return phy_suspend(phydev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mdio_bus_resume(struct device *dev)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
int ret;
|
||||
struct mdio_device *mdio = to_mdio_device(dev);
|
||||
|
||||
if (!mdio_bus_phy_may_suspend(phydev))
|
||||
goto no_resume;
|
||||
|
||||
ret = phy_resume(phydev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
no_resume:
|
||||
if (phydev->attached_dev && phydev->adjust_link)
|
||||
phy_start_machine(phydev);
|
||||
if (mdio->pm_ops && mdio->pm_ops->resume)
|
||||
return mdio->pm_ops->resume(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mdio_bus_restore(struct device *dev)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
struct net_device *netdev = phydev->attached_dev;
|
||||
int ret;
|
||||
struct mdio_device *mdio = to_mdio_device(dev);
|
||||
|
||||
if (!netdev)
|
||||
return 0;
|
||||
|
||||
ret = phy_init_hw(phydev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* The PHY needs to renegotiate. */
|
||||
phydev->link = 0;
|
||||
phydev->state = PHY_UP;
|
||||
|
||||
phy_start_machine(phydev);
|
||||
if (mdio->pm_ops && mdio->pm_ops->restore)
|
||||
return mdio->pm_ops->restore(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -623,52 +612,10 @@ static const struct dev_pm_ops mdio_bus_pm_ops = {
|
|||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static ssize_t
|
||||
phy_id_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
|
||||
return sprintf(buf, "0x%.8lx\n", (unsigned long)phydev->phy_id);
|
||||
}
|
||||
static DEVICE_ATTR_RO(phy_id);
|
||||
|
||||
static ssize_t
|
||||
phy_interface_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
const char *mode = NULL;
|
||||
|
||||
if (phy_is_internal(phydev))
|
||||
mode = "internal";
|
||||
else
|
||||
mode = phy_modes(phydev->interface);
|
||||
|
||||
return sprintf(buf, "%s\n", mode);
|
||||
}
|
||||
static DEVICE_ATTR_RO(phy_interface);
|
||||
|
||||
static ssize_t
|
||||
phy_has_fixups_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
|
||||
return sprintf(buf, "%d\n", phydev->has_fixups);
|
||||
}
|
||||
static DEVICE_ATTR_RO(phy_has_fixups);
|
||||
|
||||
static struct attribute *mdio_dev_attrs[] = {
|
||||
&dev_attr_phy_id.attr,
|
||||
&dev_attr_phy_interface.attr,
|
||||
&dev_attr_phy_has_fixups.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(mdio_dev);
|
||||
|
||||
struct bus_type mdio_bus_type = {
|
||||
.name = "mdio_bus",
|
||||
.match = mdio_bus_match,
|
||||
.pm = MDIO_BUS_PM_OPS,
|
||||
.dev_groups = mdio_dev_groups,
|
||||
};
|
||||
EXPORT_SYMBOL(mdio_bus_type);
|
||||
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
/* Framework for MDIO devices, other than PHYs.
|
||||
*
|
||||
* Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/unistd.h>
|
||||
|
||||
void mdio_device_free(struct mdio_device *mdiodev)
|
||||
{
|
||||
put_device(&mdiodev->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(mdio_device_free);
|
||||
|
||||
static void mdio_device_release(struct device *dev)
|
||||
{
|
||||
kfree(to_mdio_device(dev));
|
||||
}
|
||||
|
||||
struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr)
|
||||
{
|
||||
struct mdio_device *mdiodev;
|
||||
|
||||
/* We allocate the device, and initialize the default values */
|
||||
mdiodev = kzalloc(sizeof(*mdiodev), GFP_KERNEL);
|
||||
if (!mdiodev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
mdiodev->dev.release = mdio_device_release;
|
||||
mdiodev->dev.parent = &bus->dev;
|
||||
mdiodev->dev.bus = &mdio_bus_type;
|
||||
mdiodev->device_free = mdio_device_free;
|
||||
mdiodev->device_remove = mdio_device_remove;
|
||||
mdiodev->bus = bus;
|
||||
mdiodev->addr = addr;
|
||||
|
||||
dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr);
|
||||
|
||||
device_initialize(&mdiodev->dev);
|
||||
|
||||
return mdiodev;
|
||||
}
|
||||
EXPORT_SYMBOL(mdio_device_create);
|
||||
|
||||
/**
|
||||
* mdio_device_register - Register the mdio device on the MDIO bus
|
||||
* @mdiodev: mdio_device structure to be added to the MDIO bus
|
||||
*/
|
||||
int mdio_device_register(struct mdio_device *mdiodev)
|
||||
{
|
||||
int err;
|
||||
|
||||
dev_info(&mdiodev->dev, "mdio_device_register\n");
|
||||
|
||||
err = mdiobus_register_device(mdiodev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = device_add(&mdiodev->dev);
|
||||
if (err) {
|
||||
pr_err("MDIO %d failed to add\n", mdiodev->addr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
mdiobus_unregister_device(mdiodev);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(mdio_device_register);
|
||||
|
||||
/**
|
||||
* mdio_device_remove - Remove a previously registered mdio device from the
|
||||
* MDIO bus
|
||||
* @mdiodev: mdio_device structure to remove
|
||||
*
|
||||
* This doesn't free the mdio_device itself, it merely reverses the effects
|
||||
* of mdio_device_register(). Use mdio_device_free() to free the device
|
||||
* after calling this function.
|
||||
*/
|
||||
void mdio_device_remove(struct mdio_device *mdiodev)
|
||||
{
|
||||
device_del(&mdiodev->dev);
|
||||
mdiobus_unregister_device(mdiodev);
|
||||
}
|
||||
EXPORT_SYMBOL(mdio_device_remove);
|
||||
|
||||
/**
|
||||
* mdio_probe - probe an MDIO device
|
||||
* @dev: device to probe
|
||||
*
|
||||
* Description: Take care of setting up the mdio_device structure
|
||||
* and calling the driver to probe the device.
|
||||
*/
|
||||
static int mdio_probe(struct device *dev)
|
||||
{
|
||||
struct mdio_device *mdiodev = to_mdio_device(dev);
|
||||
struct device_driver *drv = mdiodev->dev.driver;
|
||||
struct mdio_driver *mdiodrv = to_mdio_driver(drv);
|
||||
int err = 0;
|
||||
|
||||
if (mdiodrv->probe)
|
||||
err = mdiodrv->probe(mdiodev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mdio_remove(struct device *dev)
|
||||
{
|
||||
struct mdio_device *mdiodev = to_mdio_device(dev);
|
||||
struct device_driver *drv = mdiodev->dev.driver;
|
||||
struct mdio_driver *mdiodrv = to_mdio_driver(drv);
|
||||
|
||||
if (mdiodrv->remove)
|
||||
mdiodrv->remove(mdiodev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mdio_driver_register - register an mdio_driver with the MDIO layer
|
||||
* @new_driver: new mdio_driver to register
|
||||
*/
|
||||
int mdio_driver_register(struct mdio_driver *drv)
|
||||
{
|
||||
struct mdio_driver_common *mdiodrv = &drv->mdiodrv;
|
||||
int retval;
|
||||
|
||||
pr_info("mdio_driver_register: %s\n", mdiodrv->driver.name);
|
||||
|
||||
mdiodrv->driver.bus = &mdio_bus_type;
|
||||
mdiodrv->driver.probe = mdio_probe;
|
||||
mdiodrv->driver.remove = mdio_remove;
|
||||
|
||||
retval = driver_register(&mdiodrv->driver);
|
||||
if (retval) {
|
||||
pr_err("%s: Error %d in registering driver\n",
|
||||
mdiodrv->driver.name, retval);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mdio_driver_register);
|
||||
|
||||
void mdio_driver_unregister(struct mdio_driver *drv)
|
||||
{
|
||||
struct mdio_driver_common *mdiodrv = &drv->mdiodrv;
|
||||
|
||||
driver_unregister(&mdiodrv->driver);
|
||||
}
|
||||
EXPORT_SYMBOL(mdio_driver_unregister);
|
|
@ -224,7 +224,7 @@ static int kszphy_setup_led(struct phy_device *phydev, u32 reg, int val)
|
|||
rc = phy_write(phydev, reg, temp);
|
||||
out:
|
||||
if (rc < 0)
|
||||
dev_err(&phydev->dev, "failed to set led mode\n");
|
||||
phydev_err(phydev, "failed to set led mode\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ static int kszphy_broadcast_disable(struct phy_device *phydev)
|
|||
ret = phy_write(phydev, MII_KSZPHY_OMSO, ret | KSZPHY_OMSO_B_CAST_OFF);
|
||||
out:
|
||||
if (ret)
|
||||
dev_err(&phydev->dev, "failed to disable broadcast address\n");
|
||||
phydev_err(phydev, "failed to disable broadcast address\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ static int kszphy_nand_tree_disable(struct phy_device *phydev)
|
|||
ret & ~KSZPHY_OMSO_NAND_TREE_ON);
|
||||
out:
|
||||
if (ret)
|
||||
dev_err(&phydev->dev, "failed to disable NAND tree mode\n");
|
||||
phydev_err(phydev, "failed to disable NAND tree mode\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -288,7 +288,8 @@ static int kszphy_config_init(struct phy_device *phydev)
|
|||
if (priv->rmii_ref_clk_sel) {
|
||||
ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val);
|
||||
if (ret) {
|
||||
dev_err(&phydev->dev, "failed to set rmii reference clock\n");
|
||||
phydev_err(phydev,
|
||||
"failed to set rmii reference clock\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -349,7 +350,7 @@ static int ksz9021_load_values_from_of(struct phy_device *phydev,
|
|||
|
||||
static int ksz9021_config_init(struct phy_device *phydev)
|
||||
{
|
||||
const struct device *dev = &phydev->dev;
|
||||
const struct device *dev = &phydev->mdio.dev;
|
||||
const struct device_node *of_node = dev->of_node;
|
||||
const struct device *dev_walker;
|
||||
|
||||
|
@ -357,7 +358,7 @@ static int ksz9021_config_init(struct phy_device *phydev)
|
|||
* properties in the MAC node. Walk up the tree of devices to
|
||||
* find a device with an OF node.
|
||||
*/
|
||||
dev_walker = &phydev->dev;
|
||||
dev_walker = &phydev->mdio.dev;
|
||||
do {
|
||||
of_node = dev_walker->of_node;
|
||||
dev_walker = dev_walker->parent;
|
||||
|
@ -470,7 +471,7 @@ static int ksz9031_center_flp_timing(struct phy_device *phydev)
|
|||
|
||||
static int ksz9031_config_init(struct phy_device *phydev)
|
||||
{
|
||||
const struct device *dev = &phydev->dev;
|
||||
const struct device *dev = &phydev->mdio.dev;
|
||||
const struct device_node *of_node = dev->of_node;
|
||||
static const char *clk_skews[2] = {"rxc-skew-ps", "txc-skew-ps"};
|
||||
static const char *rx_data_skews[4] = {
|
||||
|
@ -629,12 +630,12 @@ static void kszphy_get_stats(struct phy_device *phydev,
|
|||
static int kszphy_probe(struct phy_device *phydev)
|
||||
{
|
||||
const struct kszphy_type *type = phydev->drv->driver_data;
|
||||
const struct device_node *np = phydev->dev.of_node;
|
||||
const struct device_node *np = phydev->mdio.dev.of_node;
|
||||
struct kszphy_priv *priv;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(&phydev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -649,15 +650,15 @@ static int kszphy_probe(struct phy_device *phydev)
|
|||
priv->led_mode = -1;
|
||||
|
||||
if (priv->led_mode > 3) {
|
||||
dev_err(&phydev->dev, "invalid led mode: 0x%02x\n",
|
||||
priv->led_mode);
|
||||
phydev_err(phydev, "invalid led mode: 0x%02x\n",
|
||||
priv->led_mode);
|
||||
priv->led_mode = -1;
|
||||
}
|
||||
} else {
|
||||
priv->led_mode = -1;
|
||||
}
|
||||
|
||||
clk = devm_clk_get(&phydev->dev, "rmii-ref");
|
||||
clk = devm_clk_get(&phydev->mdio.dev, "rmii-ref");
|
||||
/* NOTE: clk may be NULL if building without CONFIG_HAVE_CLK */
|
||||
if (!IS_ERR_OR_NULL(clk)) {
|
||||
unsigned long rate = clk_get_rate(clk);
|
||||
|
@ -672,7 +673,8 @@ static int kszphy_probe(struct phy_device *phydev)
|
|||
} else if (rate > 49500000 && rate < 50500000) {
|
||||
priv->rmii_ref_clk_sel_val = !rmii_ref_clk_sel_25_mhz;
|
||||
} else {
|
||||
dev_err(&phydev->dev, "Clock rate out of range: %ld\n", rate);
|
||||
phydev_err(phydev, "Clock rate out of range: %ld\n",
|
||||
rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
@ -704,7 +706,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.get_stats = kszphy_get_stats,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ8021,
|
||||
.phy_id_mask = 0x00ffffff,
|
||||
|
@ -724,7 +725,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.get_stats = kszphy_get_stats,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ8031,
|
||||
.phy_id_mask = 0x00ffffff,
|
||||
|
@ -744,7 +744,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.get_stats = kszphy_get_stats,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ8041,
|
||||
.phy_id_mask = 0x00fffff0,
|
||||
|
@ -764,7 +763,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.get_stats = kszphy_get_stats,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ8041RNLI,
|
||||
.phy_id_mask = 0x00fffff0,
|
||||
|
@ -784,7 +782,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.get_stats = kszphy_get_stats,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ8051,
|
||||
.phy_id_mask = 0x00fffff0,
|
||||
|
@ -804,7 +801,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.get_stats = kszphy_get_stats,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ8001,
|
||||
.name = "Micrel KSZ8001 or KS8721",
|
||||
|
@ -823,7 +819,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.get_stats = kszphy_get_stats,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ8081,
|
||||
.name = "Micrel KSZ8081 or KSZ8091",
|
||||
|
@ -842,7 +837,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.get_stats = kszphy_get_stats,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ8061,
|
||||
.name = "Micrel KSZ8061",
|
||||
|
@ -859,7 +853,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.get_stats = kszphy_get_stats,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ9021,
|
||||
.phy_id_mask = 0x000ffffe,
|
||||
|
@ -879,7 +872,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.resume = genphy_resume,
|
||||
.read_mmd_indirect = ksz9021_rd_mmd_phyreg,
|
||||
.write_mmd_indirect = ksz9021_wr_mmd_phyreg,
|
||||
.driver = { .owner = THIS_MODULE, },
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ9031,
|
||||
.phy_id_mask = 0x00fffff0,
|
||||
|
@ -897,7 +889,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.get_stats = kszphy_get_stats,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE, },
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ8873MLL,
|
||||
.phy_id_mask = 0x00fffff0,
|
||||
|
@ -912,7 +903,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.get_stats = kszphy_get_stats,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE, },
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ886X,
|
||||
.phy_id_mask = 0x00fffff0,
|
||||
|
@ -927,7 +917,6 @@ static struct phy_driver ksphy_driver[] = {
|
|||
.get_stats = kszphy_get_stats,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE, },
|
||||
} };
|
||||
|
||||
module_phy_driver(ksphy_driver);
|
||||
|
|
|
@ -68,7 +68,7 @@ int lan88xx_suspend(struct phy_device *phydev)
|
|||
|
||||
static int lan88xx_probe(struct phy_device *phydev)
|
||||
{
|
||||
struct device *dev = &phydev->dev;
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
struct lan88xx_priv *priv;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
|
@ -78,10 +78,9 @@ static int lan88xx_probe(struct phy_device *phydev)
|
|||
priv->wolopts = 0;
|
||||
|
||||
/* these values can be used to identify internal PHY */
|
||||
priv->chip_id = phy_read_mmd_indirect(phydev, LAN88XX_MMD3_CHIP_ID,
|
||||
3, phydev->addr);
|
||||
priv->chip_id = phy_read_mmd_indirect(phydev, LAN88XX_MMD3_CHIP_ID, 3);
|
||||
priv->chip_rev = phy_read_mmd_indirect(phydev, LAN88XX_MMD3_CHIP_REV,
|
||||
3, phydev->addr);
|
||||
3);
|
||||
|
||||
phydev->priv = priv;
|
||||
|
||||
|
@ -90,7 +89,7 @@ static int lan88xx_probe(struct phy_device *phydev)
|
|||
|
||||
static void lan88xx_remove(struct phy_device *phydev)
|
||||
{
|
||||
struct device *dev = &phydev->dev;
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
struct lan88xx_priv *priv = phydev->priv;
|
||||
|
||||
if (priv)
|
||||
|
@ -130,8 +129,6 @@ static struct phy_driver microchip_phy_driver[] = {
|
|||
.suspend = lan88xx_suspend,
|
||||
.resume = genphy_resume,
|
||||
.set_wol = lan88xx_set_wol,
|
||||
|
||||
.driver = { .owner = THIS_MODULE, }
|
||||
} };
|
||||
|
||||
module_phy_driver(microchip_phy_driver);
|
||||
|
|
|
@ -140,7 +140,6 @@ static struct phy_driver dp83865_driver[] = { {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = ns_ack_interrupt,
|
||||
.config_intr = ns_config_intr,
|
||||
.driver = {.owner = THIS_MODULE,}
|
||||
} };
|
||||
|
||||
module_phy_driver(dp83865_driver);
|
||||
|
|
|
@ -319,7 +319,7 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
|
|||
{
|
||||
u32 speed = ethtool_cmd_speed(cmd);
|
||||
|
||||
if (cmd->phy_address != phydev->addr)
|
||||
if (cmd->phy_address != phydev->mdio.addr)
|
||||
return -EINVAL;
|
||||
|
||||
/* We make sure that we don't pass unsupported values in to the PHY */
|
||||
|
@ -375,7 +375,7 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
|
|||
cmd->port = PORT_BNC;
|
||||
else
|
||||
cmd->port = PORT_MII;
|
||||
cmd->phy_address = phydev->addr;
|
||||
cmd->phy_address = phydev->mdio.addr;
|
||||
cmd->transceiver = phy_is_internal(phydev) ?
|
||||
XCVR_INTERNAL : XCVR_EXTERNAL;
|
||||
cmd->autoneg = phydev->autoneg;
|
||||
|
@ -403,16 +403,17 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
|
|||
|
||||
switch (cmd) {
|
||||
case SIOCGMIIPHY:
|
||||
mii_data->phy_id = phydev->addr;
|
||||
mii_data->phy_id = phydev->mdio.addr;
|
||||
/* fall through */
|
||||
|
||||
case SIOCGMIIREG:
|
||||
mii_data->val_out = mdiobus_read(phydev->bus, mii_data->phy_id,
|
||||
mii_data->val_out = mdiobus_read(phydev->mdio.bus,
|
||||
mii_data->phy_id,
|
||||
mii_data->reg_num);
|
||||
return 0;
|
||||
|
||||
case SIOCSMIIREG:
|
||||
if (mii_data->phy_id == phydev->addr) {
|
||||
if (mii_data->phy_id == phydev->mdio.addr) {
|
||||
switch (mii_data->reg_num) {
|
||||
case MII_BMCR:
|
||||
if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) {
|
||||
|
@ -445,10 +446,10 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
|
|||
}
|
||||
}
|
||||
|
||||
mdiobus_write(phydev->bus, mii_data->phy_id,
|
||||
mdiobus_write(phydev->mdio.bus, mii_data->phy_id,
|
||||
mii_data->reg_num, val);
|
||||
|
||||
if (mii_data->phy_id == phydev->addr &&
|
||||
if (mii_data->phy_id == phydev->mdio.addr &&
|
||||
mii_data->reg_num == MII_BMCR &&
|
||||
val & BMCR_RESET)
|
||||
return phy_init_hw(phydev);
|
||||
|
@ -643,7 +644,7 @@ int phy_start_interrupts(struct phy_device *phydev)
|
|||
if (request_irq(phydev->irq, phy_interrupt, 0, "phy_interrupt",
|
||||
phydev) < 0) {
|
||||
pr_warn("%s: Can't get IRQ %d (PHY)\n",
|
||||
phydev->bus->name, phydev->irq);
|
||||
phydev->mdio.bus->name, phydev->irq);
|
||||
phydev->irq = PHY_POLL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -995,8 +996,9 @@ void phy_state_machine(struct work_struct *work)
|
|||
if (err < 0)
|
||||
phy_error(phydev);
|
||||
|
||||
dev_dbg(&phydev->dev, "PHY state change %s -> %s\n",
|
||||
phy_state_to_str(old_state), phy_state_to_str(phydev->state));
|
||||
phydev_dbg(phydev, "PHY state change %s -> %s\n",
|
||||
phy_state_to_str(old_state),
|
||||
phy_state_to_str(phydev->state));
|
||||
|
||||
queue_delayed_work(system_power_efficient_wq, &phydev->state_queue,
|
||||
PHY_STATE_TIME * HZ);
|
||||
|
@ -1028,7 +1030,6 @@ static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
|
|||
* @phydev: The PHY device bus
|
||||
* @prtad: MMD Address
|
||||
* @devad: MMD DEVAD
|
||||
* @addr: PHY address on the MII bus
|
||||
*
|
||||
* Description: it reads data from the MMD registers (clause 22 to access to
|
||||
* clause 45) of the specified phy address.
|
||||
|
@ -1038,14 +1039,14 @@ static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
|
|||
* 3) Write reg 13 // MMD Data Command for MMD DEVAD
|
||||
* 3) Read reg 14 // Read MMD data
|
||||
*/
|
||||
int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
|
||||
int devad, int addr)
|
||||
int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, int devad)
|
||||
{
|
||||
struct phy_driver *phydrv = phydev->drv;
|
||||
int addr = phydev->mdio.addr;
|
||||
int value = -1;
|
||||
|
||||
if (!phydrv->read_mmd_indirect) {
|
||||
struct mii_bus *bus = phydev->bus;
|
||||
struct mii_bus *bus = phydev->mdio.bus;
|
||||
|
||||
mutex_lock(&bus->mdio_lock);
|
||||
mmd_phy_indirect(bus, prtad, devad, addr);
|
||||
|
@ -1065,7 +1066,6 @@ EXPORT_SYMBOL(phy_read_mmd_indirect);
|
|||
* @phydev: The PHY device
|
||||
* @prtad: MMD Address
|
||||
* @devad: MMD DEVAD
|
||||
* @addr: PHY address on the MII bus
|
||||
* @data: data to write in the MMD register
|
||||
*
|
||||
* Description: Write data from the MMD registers of the specified
|
||||
|
@ -1077,12 +1077,13 @@ EXPORT_SYMBOL(phy_read_mmd_indirect);
|
|||
* 3) Write reg 14 // Write MMD data
|
||||
*/
|
||||
void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
|
||||
int devad, int addr, u32 data)
|
||||
int devad, u32 data)
|
||||
{
|
||||
struct phy_driver *phydrv = phydev->drv;
|
||||
int addr = phydev->mdio.addr;
|
||||
|
||||
if (!phydrv->write_mmd_indirect) {
|
||||
struct mii_bus *bus = phydev->bus;
|
||||
struct mii_bus *bus = phydev->mdio.bus;
|
||||
|
||||
mutex_lock(&bus->mdio_lock);
|
||||
mmd_phy_indirect(bus, prtad, devad, addr);
|
||||
|
@ -1129,7 +1130,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
|
|||
|
||||
/* First check if the EEE ability is supported */
|
||||
eee_cap = phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_ABLE,
|
||||
MDIO_MMD_PCS, phydev->addr);
|
||||
MDIO_MMD_PCS);
|
||||
if (eee_cap <= 0)
|
||||
goto eee_exit_err;
|
||||
|
||||
|
@ -1141,12 +1142,12 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
|
|||
* the EEE advertising registers.
|
||||
*/
|
||||
eee_lp = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_LPABLE,
|
||||
MDIO_MMD_AN, phydev->addr);
|
||||
MDIO_MMD_AN);
|
||||
if (eee_lp <= 0)
|
||||
goto eee_exit_err;
|
||||
|
||||
eee_adv = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
|
||||
MDIO_MMD_AN, phydev->addr);
|
||||
MDIO_MMD_AN);
|
||||
if (eee_adv <= 0)
|
||||
goto eee_exit_err;
|
||||
|
||||
|
@ -1160,15 +1161,13 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
|
|||
* clock while it is signaling LPI.
|
||||
*/
|
||||
int val = phy_read_mmd_indirect(phydev, MDIO_CTRL1,
|
||||
MDIO_MMD_PCS,
|
||||
phydev->addr);
|
||||
MDIO_MMD_PCS);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
val |= MDIO_PCS_CTRL1_CLKSTOP_EN;
|
||||
phy_write_mmd_indirect(phydev, MDIO_CTRL1,
|
||||
MDIO_MMD_PCS, phydev->addr,
|
||||
val);
|
||||
MDIO_MMD_PCS, val);
|
||||
}
|
||||
|
||||
return 0; /* EEE supported */
|
||||
|
@ -1187,8 +1186,7 @@ EXPORT_SYMBOL(phy_init_eee);
|
|||
*/
|
||||
int phy_get_eee_err(struct phy_device *phydev)
|
||||
{
|
||||
return phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_WK_ERR,
|
||||
MDIO_MMD_PCS, phydev->addr);
|
||||
return phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_WK_ERR, MDIO_MMD_PCS);
|
||||
}
|
||||
EXPORT_SYMBOL(phy_get_eee_err);
|
||||
|
||||
|
@ -1205,22 +1203,19 @@ int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data)
|
|||
int val;
|
||||
|
||||
/* Get Supported EEE */
|
||||
val = phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_ABLE,
|
||||
MDIO_MMD_PCS, phydev->addr);
|
||||
val = phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_ABLE, MDIO_MMD_PCS);
|
||||
if (val < 0)
|
||||
return val;
|
||||
data->supported = mmd_eee_cap_to_ethtool_sup_t(val);
|
||||
|
||||
/* Get advertisement EEE */
|
||||
val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
|
||||
MDIO_MMD_AN, phydev->addr);
|
||||
val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN);
|
||||
if (val < 0)
|
||||
return val;
|
||||
data->advertised = mmd_eee_adv_to_ethtool_adv_t(val);
|
||||
|
||||
/* Get LP advertisement EEE */
|
||||
val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_LPABLE,
|
||||
MDIO_MMD_AN, phydev->addr);
|
||||
val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_LPABLE, MDIO_MMD_AN);
|
||||
if (val < 0)
|
||||
return val;
|
||||
data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val);
|
||||
|
@ -1240,8 +1235,7 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
|
|||
{
|
||||
int val = ethtool_adv_to_mmd_eee_adv_t(data->advertised);
|
||||
|
||||
phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN,
|
||||
phydev->addr, val);
|
||||
phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -43,15 +43,31 @@ MODULE_LICENSE("GPL");
|
|||
|
||||
void phy_device_free(struct phy_device *phydev)
|
||||
{
|
||||
put_device(&phydev->dev);
|
||||
put_device(&phydev->mdio.dev);
|
||||
}
|
||||
EXPORT_SYMBOL(phy_device_free);
|
||||
|
||||
static void phy_mdio_device_free(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct phy_device *phydev;
|
||||
|
||||
phydev = container_of(mdiodev, struct phy_device, mdio);
|
||||
phy_device_free(phydev);
|
||||
}
|
||||
|
||||
static void phy_device_release(struct device *dev)
|
||||
{
|
||||
kfree(to_phy_device(dev));
|
||||
}
|
||||
|
||||
static void phy_mdio_device_remove(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct phy_device *phydev;
|
||||
|
||||
phydev = container_of(mdiodev, struct phy_device, mdio);
|
||||
phy_device_remove(phydev);
|
||||
}
|
||||
|
||||
enum genphy_driver {
|
||||
GENPHY_DRV_1G,
|
||||
GENPHY_DRV_10G,
|
||||
|
@ -63,9 +79,118 @@ static struct phy_driver genphy_driver[GENPHY_DRV_MAX];
|
|||
static LIST_HEAD(phy_fixup_list);
|
||||
static DEFINE_MUTEX(phy_fixup_lock);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
|
||||
{
|
||||
struct device_driver *drv = phydev->mdio.dev.driver;
|
||||
struct phy_driver *phydrv = to_phy_driver(drv);
|
||||
struct net_device *netdev = phydev->attached_dev;
|
||||
|
||||
if (!drv || !phydrv->suspend)
|
||||
return false;
|
||||
|
||||
/* PHY not attached? May suspend if the PHY has not already been
|
||||
* suspended as part of a prior call to phy_disconnect() ->
|
||||
* phy_detach() -> phy_suspend() because the parent netdev might be the
|
||||
* MDIO bus driver and clock gated at this point.
|
||||
*/
|
||||
if (!netdev)
|
||||
return !phydev->suspended;
|
||||
|
||||
/* Don't suspend PHY if the attached netdev parent may wakeup.
|
||||
* The parent may point to a PCI device, as in tg3 driver.
|
||||
*/
|
||||
if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent))
|
||||
return false;
|
||||
|
||||
/* Also don't suspend PHY if the netdev itself may wakeup. This
|
||||
* is the case for devices w/o underlaying pwr. mgmt. aware bus,
|
||||
* e.g. SoC devices.
|
||||
*/
|
||||
if (device_may_wakeup(&netdev->dev))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int mdio_bus_phy_suspend(struct device *dev)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
|
||||
/* We must stop the state machine manually, otherwise it stops out of
|
||||
* control, possibly with the phydev->lock held. Upon resume, netdev
|
||||
* may call phy routines that try to grab the same lock, and that may
|
||||
* lead to a deadlock.
|
||||
*/
|
||||
if (phydev->attached_dev && phydev->adjust_link)
|
||||
phy_stop_machine(phydev);
|
||||
|
||||
if (!mdio_bus_phy_may_suspend(phydev))
|
||||
return 0;
|
||||
|
||||
return phy_suspend(phydev);
|
||||
}
|
||||
|
||||
static int mdio_bus_phy_resume(struct device *dev)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
int ret;
|
||||
|
||||
if (!mdio_bus_phy_may_suspend(phydev))
|
||||
goto no_resume;
|
||||
|
||||
ret = phy_resume(phydev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
no_resume:
|
||||
if (phydev->attached_dev && phydev->adjust_link)
|
||||
phy_start_machine(phydev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mdio_bus_phy_restore(struct device *dev)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
struct net_device *netdev = phydev->attached_dev;
|
||||
int ret;
|
||||
|
||||
if (!netdev)
|
||||
return 0;
|
||||
|
||||
ret = phy_init_hw(phydev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* The PHY needs to renegotiate. */
|
||||
phydev->link = 0;
|
||||
phydev->state = PHY_UP;
|
||||
|
||||
phy_start_machine(phydev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops mdio_bus_phy_pm_ops = {
|
||||
.suspend = mdio_bus_phy_suspend,
|
||||
.resume = mdio_bus_phy_resume,
|
||||
.freeze = mdio_bus_phy_suspend,
|
||||
.thaw = mdio_bus_phy_resume,
|
||||
.restore = mdio_bus_phy_restore,
|
||||
};
|
||||
|
||||
#define MDIO_BUS_PHY_PM_OPS (&mdio_bus_phy_pm_ops)
|
||||
|
||||
#else
|
||||
|
||||
#define MDIO_BUS_PHY_PM_OPS NULL
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
/**
|
||||
* phy_register_fixup - creates a new phy_fixup and adds it to the list
|
||||
* @bus_id: A string which matches phydev->dev.bus_id (or PHY_ANY_ID)
|
||||
* @bus_id: A string which matches phydev->mdio.dev.bus_id (or PHY_ANY_ID)
|
||||
* @phy_uid: Used to match against phydev->phy_id (the UID of the PHY)
|
||||
* It can also be PHY_ANY_UID
|
||||
* @phy_uid_mask: Applied to phydev->phy_id and fixup->phy_uid before
|
||||
|
@ -114,7 +239,7 @@ EXPORT_SYMBOL(phy_register_fixup_for_id);
|
|||
*/
|
||||
static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup)
|
||||
{
|
||||
if (strcmp(fixup->bus_id, dev_name(&phydev->dev)) != 0)
|
||||
if (strcmp(fixup->bus_id, phydev_name(phydev)) != 0)
|
||||
if (strcmp(fixup->bus_id, PHY_ANY_ID) != 0)
|
||||
return 0;
|
||||
|
||||
|
@ -148,18 +273,59 @@ static int phy_scan_fixups(struct phy_device *phydev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int phy_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);
|
||||
const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids);
|
||||
int i;
|
||||
|
||||
if (!(phydrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY))
|
||||
return 0;
|
||||
|
||||
if (phydrv->match_phy_device)
|
||||
return phydrv->match_phy_device(phydev);
|
||||
|
||||
if (phydev->is_c45) {
|
||||
for (i = 1; i < num_ids; i++) {
|
||||
if (!(phydev->c45_ids.devices_in_package & (1 << i)))
|
||||
continue;
|
||||
|
||||
if ((phydrv->phy_id & phydrv->phy_id_mask) ==
|
||||
(phydev->c45_ids.device_ids[i] &
|
||||
phydrv->phy_id_mask))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return (phydrv->phy_id & phydrv->phy_id_mask) ==
|
||||
(phydev->phy_id & phydrv->phy_id_mask);
|
||||
}
|
||||
}
|
||||
|
||||
struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
|
||||
bool is_c45,
|
||||
struct phy_c45_device_ids *c45_ids)
|
||||
{
|
||||
struct phy_device *dev;
|
||||
struct mdio_device *mdiodev;
|
||||
|
||||
/* We allocate the device, and initialize the default values */
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
dev->dev.release = phy_device_release;
|
||||
mdiodev = &dev->mdio;
|
||||
mdiodev->dev.release = phy_device_release;
|
||||
mdiodev->dev.parent = &bus->dev;
|
||||
mdiodev->dev.bus = &mdio_bus_type;
|
||||
mdiodev->bus = bus;
|
||||
mdiodev->pm_ops = MDIO_BUS_PHY_PM_OPS;
|
||||
mdiodev->bus_match = phy_bus_match;
|
||||
mdiodev->addr = addr;
|
||||
mdiodev->flags = MDIO_DEVICE_FLAG_PHY;
|
||||
mdiodev->device_free = phy_mdio_device_free;
|
||||
mdiodev->device_remove = phy_mdio_device_remove;
|
||||
|
||||
dev->speed = 0;
|
||||
dev->duplex = -1;
|
||||
|
@ -171,15 +337,11 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
|
|||
dev->autoneg = AUTONEG_ENABLE;
|
||||
|
||||
dev->is_c45 = is_c45;
|
||||
dev->addr = addr;
|
||||
dev->phy_id = phy_id;
|
||||
if (c45_ids)
|
||||
dev->c45_ids = *c45_ids;
|
||||
dev->bus = bus;
|
||||
dev->dev.parent = &bus->dev;
|
||||
dev->dev.bus = &mdio_bus_type;
|
||||
dev->irq = bus->irq ? bus->irq[addr] : PHY_POLL;
|
||||
dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
|
||||
dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr);
|
||||
|
||||
dev->state = PHY_DOWN;
|
||||
|
||||
|
@ -199,7 +361,7 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
|
|||
*/
|
||||
request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phy_id));
|
||||
|
||||
device_initialize(&dev->dev);
|
||||
device_initialize(&mdiodev->dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
@ -373,6 +535,48 @@ struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
|
|||
}
|
||||
EXPORT_SYMBOL(get_phy_device);
|
||||
|
||||
static ssize_t
|
||||
phy_id_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
|
||||
return sprintf(buf, "0x%.8lx\n", (unsigned long)phydev->phy_id);
|
||||
}
|
||||
static DEVICE_ATTR_RO(phy_id);
|
||||
|
||||
static ssize_t
|
||||
phy_interface_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
const char *mode = NULL;
|
||||
|
||||
if (phy_is_internal(phydev))
|
||||
mode = "internal";
|
||||
else
|
||||
mode = phy_modes(phydev->interface);
|
||||
|
||||
return sprintf(buf, "%s\n", mode);
|
||||
}
|
||||
static DEVICE_ATTR_RO(phy_interface);
|
||||
|
||||
static ssize_t
|
||||
phy_has_fixups_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
|
||||
return sprintf(buf, "%d\n", phydev->has_fixups);
|
||||
}
|
||||
static DEVICE_ATTR_RO(phy_has_fixups);
|
||||
|
||||
static struct attribute *phy_dev_attrs[] = {
|
||||
&dev_attr_phy_id.attr,
|
||||
&dev_attr_phy_interface.attr,
|
||||
&dev_attr_phy_has_fixups.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(phy_dev);
|
||||
|
||||
/**
|
||||
* phy_device_register - Register the phy device on the MDIO bus
|
||||
* @phydev: phy_device structure to be added to the MDIO bus
|
||||
|
@ -381,28 +585,29 @@ int phy_device_register(struct phy_device *phydev)
|
|||
{
|
||||
int err;
|
||||
|
||||
/* Don't register a phy if one is already registered at this address */
|
||||
if (phydev->bus->phy_map[phydev->addr])
|
||||
return -EINVAL;
|
||||
phydev->bus->phy_map[phydev->addr] = phydev;
|
||||
err = mdiobus_register_device(&phydev->mdio);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Run all of the fixups for this PHY */
|
||||
err = phy_scan_fixups(phydev);
|
||||
if (err) {
|
||||
pr_err("PHY %d failed to initialize\n", phydev->addr);
|
||||
pr_err("PHY %d failed to initialize\n", phydev->mdio.addr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = device_add(&phydev->dev);
|
||||
phydev->mdio.dev.groups = phy_dev_groups;
|
||||
|
||||
err = device_add(&phydev->mdio.dev);
|
||||
if (err) {
|
||||
pr_err("PHY %d failed to add\n", phydev->addr);
|
||||
pr_err("PHY %d failed to add\n", phydev->mdio.addr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
phydev->bus->phy_map[phydev->addr] = NULL;
|
||||
mdiobus_unregister_device(&phydev->mdio);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(phy_device_register);
|
||||
|
@ -417,11 +622,8 @@ EXPORT_SYMBOL(phy_device_register);
|
|||
*/
|
||||
void phy_device_remove(struct phy_device *phydev)
|
||||
{
|
||||
struct mii_bus *bus = phydev->bus;
|
||||
int addr = phydev->addr;
|
||||
|
||||
device_del(&phydev->dev);
|
||||
bus->phy_map[addr] = NULL;
|
||||
device_del(&phydev->mdio.dev);
|
||||
mdiobus_unregister_device(&phydev->mdio);
|
||||
}
|
||||
EXPORT_SYMBOL(phy_device_remove);
|
||||
|
||||
|
@ -431,11 +633,13 @@ EXPORT_SYMBOL(phy_device_remove);
|
|||
*/
|
||||
struct phy_device *phy_find_first(struct mii_bus *bus)
|
||||
{
|
||||
struct phy_device *phydev;
|
||||
int addr;
|
||||
|
||||
for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
|
||||
if (bus->phy_map[addr])
|
||||
return bus->phy_map[addr];
|
||||
phydev = mdiobus_get_phy(bus, addr);
|
||||
if (phydev)
|
||||
return phydev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -607,6 +811,33 @@ int phy_init_hw(struct phy_device *phydev)
|
|||
}
|
||||
EXPORT_SYMBOL(phy_init_hw);
|
||||
|
||||
void phy_attached_info(struct phy_device *phydev)
|
||||
{
|
||||
phy_attached_print(phydev, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(phy_attached_info);
|
||||
|
||||
#define ATTACHED_FMT "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)"
|
||||
void phy_attached_print(struct phy_device *phydev, const char *fmt, ...)
|
||||
{
|
||||
if (!fmt) {
|
||||
dev_info(&phydev->mdio.dev, ATTACHED_FMT "\n",
|
||||
phydev->drv->name, phydev_name(phydev),
|
||||
phydev->irq);
|
||||
} else {
|
||||
va_list ap;
|
||||
|
||||
dev_info(&phydev->mdio.dev, ATTACHED_FMT,
|
||||
phydev->drv->name, phydev_name(phydev),
|
||||
phydev->irq);
|
||||
|
||||
va_start(ap, fmt);
|
||||
vprintk(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(phy_attached_print);
|
||||
|
||||
/**
|
||||
* phy_attach_direct - attach a network device to a given PHY device pointer
|
||||
* @dev: network device to attach
|
||||
|
@ -625,8 +856,8 @@ EXPORT_SYMBOL(phy_init_hw);
|
|||
int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
|
||||
u32 flags, phy_interface_t interface)
|
||||
{
|
||||
struct mii_bus *bus = phydev->bus;
|
||||
struct device *d = &phydev->dev;
|
||||
struct mii_bus *bus = phydev->mdio.bus;
|
||||
struct device *d = &phydev->mdio.dev;
|
||||
int err;
|
||||
|
||||
if (!try_module_get(bus->owner)) {
|
||||
|
@ -641,9 +872,11 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
|
|||
*/
|
||||
if (!d->driver) {
|
||||
if (phydev->is_c45)
|
||||
d->driver = &genphy_driver[GENPHY_DRV_10G].driver;
|
||||
d->driver =
|
||||
&genphy_driver[GENPHY_DRV_10G].mdiodrv.driver;
|
||||
else
|
||||
d->driver = &genphy_driver[GENPHY_DRV_1G].driver;
|
||||
d->driver =
|
||||
&genphy_driver[GENPHY_DRV_1G].mdiodrv.driver;
|
||||
|
||||
err = d->driver->probe(d);
|
||||
if (err >= 0)
|
||||
|
@ -744,8 +977,9 @@ void phy_detach(struct phy_device *phydev)
|
|||
* real driver could be loaded
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(genphy_driver); i++) {
|
||||
if (phydev->dev.driver == &genphy_driver[i].driver) {
|
||||
device_release_driver(&phydev->dev);
|
||||
if (phydev->mdio.dev.driver ==
|
||||
&genphy_driver[i].mdiodrv.driver) {
|
||||
device_release_driver(&phydev->mdio.dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -754,16 +988,16 @@ void phy_detach(struct phy_device *phydev)
|
|||
* The phydev might go away on the put_device() below, so avoid
|
||||
* a use-after-free bug by reading the underlying bus first.
|
||||
*/
|
||||
bus = phydev->bus;
|
||||
bus = phydev->mdio.bus;
|
||||
|
||||
put_device(&phydev->dev);
|
||||
put_device(&phydev->mdio.dev);
|
||||
module_put(bus->owner);
|
||||
}
|
||||
EXPORT_SYMBOL(phy_detach);
|
||||
|
||||
int phy_suspend(struct phy_device *phydev)
|
||||
{
|
||||
struct phy_driver *phydrv = to_phy_driver(phydev->dev.driver);
|
||||
struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver);
|
||||
struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
|
||||
int ret = 0;
|
||||
|
||||
|
@ -786,7 +1020,7 @@ EXPORT_SYMBOL(phy_suspend);
|
|||
|
||||
int phy_resume(struct phy_device *phydev)
|
||||
{
|
||||
struct phy_driver *phydrv = to_phy_driver(phydev->dev.driver);
|
||||
struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver);
|
||||
int ret = 0;
|
||||
|
||||
if (phydrv->resume)
|
||||
|
@ -1303,7 +1537,7 @@ EXPORT_SYMBOL(phy_set_max_speed);
|
|||
|
||||
static void of_set_phy_supported(struct phy_device *phydev)
|
||||
{
|
||||
struct device_node *node = phydev->dev.of_node;
|
||||
struct device_node *node = phydev->mdio.dev.of_node;
|
||||
u32 max_speed;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_OF_MDIO))
|
||||
|
@ -1327,7 +1561,7 @@ static void of_set_phy_supported(struct phy_device *phydev)
|
|||
static int phy_probe(struct device *dev)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
struct device_driver *drv = phydev->dev.driver;
|
||||
struct device_driver *drv = phydev->mdio.dev.driver;
|
||||
struct phy_driver *phydrv = to_phy_driver(drv);
|
||||
int err = 0;
|
||||
|
||||
|
@ -1382,17 +1616,20 @@ static int phy_remove(struct device *dev)
|
|||
/**
|
||||
* phy_driver_register - register a phy_driver with the PHY layer
|
||||
* @new_driver: new phy_driver to register
|
||||
* @owner: module owning this PHY
|
||||
*/
|
||||
int phy_driver_register(struct phy_driver *new_driver)
|
||||
int phy_driver_register(struct phy_driver *new_driver, struct module *owner)
|
||||
{
|
||||
int retval;
|
||||
|
||||
new_driver->driver.name = new_driver->name;
|
||||
new_driver->driver.bus = &mdio_bus_type;
|
||||
new_driver->driver.probe = phy_probe;
|
||||
new_driver->driver.remove = phy_remove;
|
||||
new_driver->mdiodrv.flags |= MDIO_DEVICE_IS_PHY;
|
||||
new_driver->mdiodrv.driver.name = new_driver->name;
|
||||
new_driver->mdiodrv.driver.bus = &mdio_bus_type;
|
||||
new_driver->mdiodrv.driver.probe = phy_probe;
|
||||
new_driver->mdiodrv.driver.remove = phy_remove;
|
||||
new_driver->mdiodrv.driver.owner = owner;
|
||||
|
||||
retval = driver_register(&new_driver->driver);
|
||||
retval = driver_register(&new_driver->mdiodrv.driver);
|
||||
if (retval) {
|
||||
pr_err("%s: Error %d in registering driver\n",
|
||||
new_driver->name, retval);
|
||||
|
@ -1406,12 +1643,13 @@ int phy_driver_register(struct phy_driver *new_driver)
|
|||
}
|
||||
EXPORT_SYMBOL(phy_driver_register);
|
||||
|
||||
int phy_drivers_register(struct phy_driver *new_driver, int n)
|
||||
int phy_drivers_register(struct phy_driver *new_driver, int n,
|
||||
struct module *owner)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
ret = phy_driver_register(new_driver + i);
|
||||
ret = phy_driver_register(new_driver + i, owner);
|
||||
if (ret) {
|
||||
while (i-- > 0)
|
||||
phy_driver_unregister(new_driver + i);
|
||||
|
@ -1424,7 +1662,7 @@ EXPORT_SYMBOL(phy_drivers_register);
|
|||
|
||||
void phy_driver_unregister(struct phy_driver *drv)
|
||||
{
|
||||
driver_unregister(&drv->driver);
|
||||
driver_unregister(&drv->mdiodrv.driver);
|
||||
}
|
||||
EXPORT_SYMBOL(phy_driver_unregister);
|
||||
|
||||
|
@ -1452,7 +1690,6 @@ static struct phy_driver genphy_driver[] = {
|
|||
.read_status = genphy_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE, },
|
||||
}, {
|
||||
.phy_id = 0xffffffff,
|
||||
.phy_id_mask = 0xffffffff,
|
||||
|
@ -1464,7 +1701,6 @@ static struct phy_driver genphy_driver[] = {
|
|||
.read_status = gen10g_read_status,
|
||||
.suspend = gen10g_suspend,
|
||||
.resume = gen10g_resume,
|
||||
.driver = {.owner = THIS_MODULE, },
|
||||
} };
|
||||
|
||||
static int __init phy_init(void)
|
||||
|
@ -1476,7 +1712,7 @@ static int __init phy_init(void)
|
|||
return rc;
|
||||
|
||||
rc = phy_drivers_register(genphy_driver,
|
||||
ARRAY_SIZE(genphy_driver));
|
||||
ARRAY_SIZE(genphy_driver), THIS_MODULE);
|
||||
if (rc)
|
||||
mdio_bus_exit();
|
||||
|
||||
|
|
|
@ -122,7 +122,6 @@ static struct phy_driver qs6612_driver[] = { {
|
|||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = qs6612_ack_interrupt,
|
||||
.config_intr = qs6612_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
} };
|
||||
|
||||
module_phy_driver(qs6612_driver);
|
||||
|
|
|
@ -124,7 +124,6 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.flags = PHY_HAS_INTERRUPT,
|
||||
.config_aneg = &genphy_config_aneg,
|
||||
.read_status = &genphy_read_status,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x001cc912,
|
||||
.name = "RTL8211B Gigabit Ethernet",
|
||||
|
@ -135,7 +134,6 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &rtl821x_ack_interrupt,
|
||||
.config_intr = &rtl8211b_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x001cc914,
|
||||
.name = "RTL8211DN Gigabit Ethernet",
|
||||
|
@ -148,7 +146,6 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.config_intr = rtl8211e_config_intr,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x001cc915,
|
||||
.name = "RTL8211E Gigabit Ethernet",
|
||||
|
@ -161,7 +158,6 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.config_intr = &rtl8211e_config_intr,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = 0x001cc916,
|
||||
.name = "RTL8211F Gigabit Ethernet",
|
||||
|
@ -175,7 +171,6 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.config_intr = &rtl8211f_config_intr,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = { .owner = THIS_MODULE },
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ static int smsc_phy_ack_interrupt(struct phy_device *phydev)
|
|||
static int smsc_phy_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int __maybe_unused len;
|
||||
struct device *dev __maybe_unused = &phydev->dev;
|
||||
struct device *dev __maybe_unused = &phydev->mdio.dev;
|
||||
struct device_node *of_node __maybe_unused = dev->of_node;
|
||||
int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
|
||||
int enable_energy = 1;
|
||||
|
@ -171,8 +171,6 @@ static struct phy_driver smsc_phy_driver[] = {
|
|||
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
|
||||
.driver = { .owner = THIS_MODULE, }
|
||||
}, {
|
||||
.phy_id = 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -194,8 +192,6 @@ static struct phy_driver smsc_phy_driver[] = {
|
|||
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
|
||||
.driver = { .owner = THIS_MODULE, }
|
||||
}, {
|
||||
.phy_id = 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -217,8 +213,6 @@ static struct phy_driver smsc_phy_driver[] = {
|
|||
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
|
||||
.driver = { .owner = THIS_MODULE, }
|
||||
}, {
|
||||
.phy_id = 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -239,8 +233,6 @@ static struct phy_driver smsc_phy_driver[] = {
|
|||
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
|
||||
.driver = { .owner = THIS_MODULE, }
|
||||
}, {
|
||||
.phy_id = 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
|
@ -262,8 +254,6 @@ static struct phy_driver smsc_phy_driver[] = {
|
|||
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
|
||||
.driver = { .owner = THIS_MODULE, }
|
||||
} };
|
||||
|
||||
module_phy_driver(smsc_phy_driver);
|
||||
|
|
|
@ -95,7 +95,6 @@ static struct phy_driver ste10xp_pdriver[] = {
|
|||
.config_intr = ste10Xp_config_intr,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = {.owner = THIS_MODULE,}
|
||||
}, {
|
||||
.phy_id = STE100P_PHY_ID,
|
||||
.phy_id_mask = 0xffffffff,
|
||||
|
@ -109,7 +108,6 @@ static struct phy_driver ste10xp_pdriver[] = {
|
|||
.config_intr = ste10Xp_config_intr,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.driver = {.owner = THIS_MODULE,}
|
||||
} };
|
||||
|
||||
module_phy_driver(ste10xp_pdriver);
|
||||
|
|
|
@ -108,7 +108,6 @@ static struct phy_driver teranetics_driver[] = {
|
|||
.config_aneg = teranetics_config_aneg,
|
||||
.read_status = teranetics_read_status,
|
||||
.match_phy_device = teranetics_match_phy_device,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -236,7 +236,6 @@ static struct phy_driver vsc82xx_driver[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &vsc824x_ack_interrupt,
|
||||
.config_intr = &vsc82xx_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_VSC8244,
|
||||
.name = "Vitesse VSC8244",
|
||||
|
@ -248,7 +247,6 @@ static struct phy_driver vsc82xx_driver[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &vsc824x_ack_interrupt,
|
||||
.config_intr = &vsc82xx_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_VSC8514,
|
||||
.name = "Vitesse VSC8514",
|
||||
|
@ -260,7 +258,6 @@ static struct phy_driver vsc82xx_driver[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &vsc824x_ack_interrupt,
|
||||
.config_intr = &vsc82xx_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_VSC8574,
|
||||
.name = "Vitesse VSC8574",
|
||||
|
@ -272,7 +269,6 @@ static struct phy_driver vsc82xx_driver[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &vsc824x_ack_interrupt,
|
||||
.config_intr = &vsc82xx_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_VSC8601,
|
||||
.name = "Vitesse VSC8601",
|
||||
|
@ -284,7 +280,6 @@ static struct phy_driver vsc82xx_driver[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &vsc824x_ack_interrupt,
|
||||
.config_intr = &vsc82xx_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_VSC8662,
|
||||
.name = "Vitesse VSC8662",
|
||||
|
@ -296,7 +291,6 @@ static struct phy_driver vsc82xx_driver[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &vsc824x_ack_interrupt,
|
||||
.config_intr = &vsc82xx_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
/* Vitesse 8221 */
|
||||
.phy_id = PHY_ID_VSC8221,
|
||||
|
@ -309,7 +303,6 @@ static struct phy_driver vsc82xx_driver[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &vsc824x_ack_interrupt,
|
||||
.config_intr = &vsc82xx_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
/* Vitesse 8211 */
|
||||
.phy_id = PHY_ID_VSC8211,
|
||||
|
@ -322,7 +315,6 @@ static struct phy_driver vsc82xx_driver[] = {
|
|||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &vsc824x_ack_interrupt,
|
||||
.config_intr = &vsc82xx_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
} };
|
||||
|
||||
module_phy_driver(vsc82xx_driver);
|
||||
|
|
|
@ -98,7 +98,7 @@ static void ax88172a_status(struct usbnet *dev, struct urb *urb)
|
|||
static int ax88172a_init_mdio(struct usbnet *dev)
|
||||
{
|
||||
struct ax88172a_private *priv = dev->driver_priv;
|
||||
int ret, i;
|
||||
int ret;
|
||||
|
||||
priv->mdio = mdiobus_alloc();
|
||||
if (!priv->mdio) {
|
||||
|
@ -114,25 +114,15 @@ static int ax88172a_init_mdio(struct usbnet *dev)
|
|||
snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "usb-%03d:%03d",
|
||||
dev->udev->bus->busnum, dev->udev->devnum);
|
||||
|
||||
priv->mdio->irq = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!priv->mdio->irq) {
|
||||
ret = -ENOMEM;
|
||||
goto mfree;
|
||||
}
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
priv->mdio->irq[i] = PHY_POLL;
|
||||
|
||||
ret = mdiobus_register(priv->mdio);
|
||||
if (ret) {
|
||||
netdev_err(dev->net, "Could not register MDIO bus\n");
|
||||
goto ifree;
|
||||
goto mfree;
|
||||
}
|
||||
|
||||
netdev_info(dev->net, "registered mdio bus %s\n", priv->mdio->id);
|
||||
return 0;
|
||||
|
||||
ifree:
|
||||
kfree(priv->mdio->irq);
|
||||
mfree:
|
||||
mdiobus_free(priv->mdio);
|
||||
return ret;
|
||||
|
|
|
@ -1458,12 +1458,6 @@ static int lan78xx_mdio_init(struct lan78xx_net *dev)
|
|||
snprintf(dev->mdiobus->id, MII_BUS_ID_SIZE, "usb-%03d:%03d",
|
||||
dev->udev->bus->busnum, dev->udev->devnum);
|
||||
|
||||
dev->mdiobus->irq = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (!dev->mdiobus->irq) {
|
||||
ret = -ENOMEM;
|
||||
goto exit1;
|
||||
}
|
||||
|
||||
/* handle our own interrupt */
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
||||
dev->mdiobus->irq[i] = PHY_IGNORE_INTERRUPT;
|
||||
|
@ -1479,13 +1473,11 @@ static int lan78xx_mdio_init(struct lan78xx_net *dev)
|
|||
ret = mdiobus_register(dev->mdiobus);
|
||||
if (ret) {
|
||||
netdev_err(dev->net, "can't register MDIO bus\n");
|
||||
goto exit2;
|
||||
goto exit1;
|
||||
}
|
||||
|
||||
netdev_dbg(dev->net, "registered mdiobus bus %s\n", dev->mdiobus->id);
|
||||
return 0;
|
||||
exit2:
|
||||
kfree(dev->mdiobus->irq);
|
||||
exit1:
|
||||
mdiobus_free(dev->mdiobus);
|
||||
return ret;
|
||||
|
@ -1494,7 +1486,6 @@ static int lan78xx_mdio_init(struct lan78xx_net *dev)
|
|||
static void lan78xx_remove_mdio(struct lan78xx_net *dev)
|
||||
{
|
||||
mdiobus_unregister(dev->mdiobus);
|
||||
kfree(dev->mdiobus->irq);
|
||||
mdiobus_free(dev->mdiobus);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
|
|||
/* Associate the OF node with the device structure so it
|
||||
* can be looked up later */
|
||||
of_node_get(child);
|
||||
phy->dev.of_node = child;
|
||||
phy->mdio.dev.of_node = child;
|
||||
|
||||
/* All data is now stored in the phy struct;
|
||||
* register it */
|
||||
|
@ -92,6 +92,37 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int of_mdiobus_register_device(struct mii_bus *mdio,
|
||||
struct device_node *child,
|
||||
u32 addr)
|
||||
{
|
||||
struct mdio_device *mdiodev;
|
||||
int rc;
|
||||
|
||||
mdiodev = mdio_device_create(mdio, addr);
|
||||
if (!mdiodev || IS_ERR(mdiodev))
|
||||
return 1;
|
||||
|
||||
/* Associate the OF node with the device structure so it
|
||||
* can be looked up later.
|
||||
*/
|
||||
of_node_get(child);
|
||||
mdiodev->dev.of_node = child;
|
||||
|
||||
/* All data is now stored in the mdiodev struct; register it. */
|
||||
rc = mdio_device_register(mdiodev);
|
||||
if (rc) {
|
||||
mdio_device_free(mdiodev);
|
||||
of_node_put(child);
|
||||
return 1;
|
||||
}
|
||||
|
||||
dev_dbg(&mdio->dev, "registered mdio device %s at address %i\n",
|
||||
child->name, addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int of_mdio_parse_addr(struct device *dev, const struct device_node *np)
|
||||
{
|
||||
u32 addr;
|
||||
|
@ -114,6 +145,35 @@ int of_mdio_parse_addr(struct device *dev, const struct device_node *np)
|
|||
}
|
||||
EXPORT_SYMBOL(of_mdio_parse_addr);
|
||||
|
||||
/*
|
||||
* Return true if the child node is for a phy. It must either:
|
||||
* o Compatible string of "ethernet-phy-idX.X"
|
||||
* o Compatible string of "ethernet-phy-ieee802.3-c45"
|
||||
* o Compatible string of "ethernet-phy-ieee802.3-c22"
|
||||
* o No compatibility string
|
||||
*
|
||||
* A device which is not a phy is expected to have a compatible string
|
||||
* indicating what sort of device it is.
|
||||
*/
|
||||
static bool of_mdiobus_child_is_phy(struct device_node *child)
|
||||
{
|
||||
u32 phy_id;
|
||||
|
||||
if (of_get_phy_id(child, &phy_id) != -EINVAL)
|
||||
return true;
|
||||
|
||||
if (of_device_is_compatible(child, "ethernet-phy-ieee802.3-c45"))
|
||||
return true;
|
||||
|
||||
if (of_device_is_compatible(child, "ethernet-phy-ieee802.3-c22"))
|
||||
return true;
|
||||
|
||||
if (!of_find_property(child, "compatible", NULL))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_mdiobus_register - Register mii_bus and create PHYs from the device tree
|
||||
* @mdio: pointer to mii_bus structure
|
||||
|
@ -127,17 +187,12 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
|
|||
struct device_node *child;
|
||||
const __be32 *paddr;
|
||||
bool scanphys = false;
|
||||
int addr, rc, i;
|
||||
int addr, rc;
|
||||
|
||||
/* 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 */
|
||||
|
@ -145,7 +200,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Loop over the child nodes and register a phy_device for each one */
|
||||
/* Loop over the child nodes and register a phy_device for each phy */
|
||||
for_each_available_child_of_node(np, child) {
|
||||
addr = of_mdio_parse_addr(&mdio->dev, child);
|
||||
if (addr < 0) {
|
||||
|
@ -153,9 +208,10 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
|
|||
continue;
|
||||
}
|
||||
|
||||
rc = of_mdiobus_register_phy(mdio, child, addr);
|
||||
if (rc)
|
||||
continue;
|
||||
if (of_mdiobus_child_is_phy(child))
|
||||
of_mdiobus_register_phy(mdio, child, addr);
|
||||
else
|
||||
of_mdiobus_register_device(mdio, child, addr);
|
||||
}
|
||||
|
||||
if (!scanphys)
|
||||
|
@ -170,16 +226,15 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
|
|||
|
||||
for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
|
||||
/* skip already registered PHYs */
|
||||
if (mdio->phy_map[addr])
|
||||
if (mdiobus_is_registered_device(mdio, addr))
|
||||
continue;
|
||||
|
||||
/* be noisy to encourage people to set reg property */
|
||||
dev_info(&mdio->dev, "scan phy %s at address %i\n",
|
||||
child->name, addr);
|
||||
|
||||
rc = of_mdiobus_register_phy(mdio, child, addr);
|
||||
if (rc)
|
||||
continue;
|
||||
if (of_mdiobus_child_is_phy(child))
|
||||
of_mdiobus_register_phy(mdio, child, addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,7 +293,7 @@ struct phy_device *of_phy_connect(struct net_device *dev,
|
|||
ret = phy_connect_direct(dev, phy, hndlr, iface);
|
||||
|
||||
/* refcount is held by phy_connect_direct() on success */
|
||||
put_device(&phy->dev);
|
||||
put_device(&phy->mdio.dev);
|
||||
|
||||
return ret ? NULL : phy;
|
||||
}
|
||||
|
@ -268,7 +323,7 @@ struct phy_device *of_phy_attach(struct net_device *dev,
|
|||
ret = phy_attach_direct(dev, phy, flags, iface);
|
||||
|
||||
/* refcount is held by phy_attach_direct() on success */
|
||||
put_device(&phy->dev);
|
||||
put_device(&phy->mdio.dev);
|
||||
|
||||
return ret ? NULL : phy;
|
||||
}
|
||||
|
|
|
@ -838,8 +838,8 @@ static int xlr_mii_probe(struct xlr_net_priv *priv)
|
|||
}
|
||||
|
||||
/* Attach MAC to PHY */
|
||||
phydev = phy_connect(priv->ndev, dev_name(&phydev->dev),
|
||||
&xlr_gmac_link_adjust, priv->nd->phy_interface);
|
||||
phydev = phy_connect(priv->ndev, phydev_name(phydev),
|
||||
&xlr_gmac_link_adjust, priv->nd->phy_interface);
|
||||
|
||||
if (IS_ERR(phydev)) {
|
||||
pr_err("could not attach PHY\n");
|
||||
|
@ -854,8 +854,7 @@ static int xlr_mii_probe(struct xlr_net_priv *priv)
|
|||
| ADVERTISED_MII);
|
||||
|
||||
phydev->advertising = phydev->supported;
|
||||
pr_info("attached PHY driver [%s] (mii_bus:phy_addr=%s\n",
|
||||
phydev->drv->name, dev_name(&phydev->dev));
|
||||
phy_attached_info(phydev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,55 @@
|
|||
|
||||
#include <uapi/linux/mdio.h>
|
||||
|
||||
struct mii_bus;
|
||||
|
||||
struct mdio_device {
|
||||
struct device dev;
|
||||
|
||||
const struct dev_pm_ops *pm_ops;
|
||||
struct mii_bus *bus;
|
||||
|
||||
int (*bus_match)(struct device *dev, struct device_driver *drv);
|
||||
void (*device_free)(struct mdio_device *mdiodev);
|
||||
void (*device_remove)(struct mdio_device *mdiodev);
|
||||
|
||||
/* Bus address of the MDIO device (0-31) */
|
||||
int addr;
|
||||
int flags;
|
||||
};
|
||||
#define to_mdio_device(d) container_of(d, struct mdio_device, dev)
|
||||
|
||||
/* struct mdio_driver_common: Common to all MDIO drivers */
|
||||
struct mdio_driver_common {
|
||||
struct device_driver driver;
|
||||
int flags;
|
||||
};
|
||||
#define MDIO_DEVICE_FLAG_PHY 1
|
||||
#define to_mdio_common_driver(d) \
|
||||
container_of(d, struct mdio_driver_common, driver)
|
||||
|
||||
/* struct mdio_driver: Generic MDIO driver */
|
||||
struct mdio_driver {
|
||||
struct mdio_driver_common mdiodrv;
|
||||
|
||||
/*
|
||||
* Called during discovery. Used to set
|
||||
* up device-specific structures, if any
|
||||
*/
|
||||
int (*probe)(struct mdio_device *mdiodev);
|
||||
|
||||
/* Clears up any memory if needed */
|
||||
void (*remove)(struct mdio_device *mdiodev);
|
||||
};
|
||||
#define to_mdio_driver(d) \
|
||||
container_of(to_mdio_common_driver(d), struct mdio_driver, mdiodrv)
|
||||
|
||||
void mdio_device_free(struct mdio_device *mdiodev);
|
||||
struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr);
|
||||
int mdio_device_register(struct mdio_device *mdiodev);
|
||||
void mdio_device_remove(struct mdio_device *mdiodev);
|
||||
int mdio_driver_register(struct mdio_driver *drv);
|
||||
void mdio_driver_unregister(struct mdio_driver *drv);
|
||||
|
||||
static inline bool mdio_phy_id_is_c45(int phy_id)
|
||||
{
|
||||
|
@ -173,4 +222,33 @@ static inline u16 ethtool_adv_to_mmd_eee_adv_t(u32 adv)
|
|||
return reg;
|
||||
}
|
||||
|
||||
int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
|
||||
int mdiobus_read_nested(struct mii_bus *bus, int addr, u32 regnum);
|
||||
int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
|
||||
int mdiobus_write_nested(struct mii_bus *bus, int addr, u32 regnum, u16 val);
|
||||
|
||||
int mdiobus_register_device(struct mdio_device *mdiodev);
|
||||
int mdiobus_unregister_device(struct mdio_device *mdiodev);
|
||||
bool mdiobus_is_registered_device(struct mii_bus *bus, int addr);
|
||||
struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr);
|
||||
|
||||
/**
|
||||
* module_mdio_driver() - Helper macro for registering mdio drivers
|
||||
*
|
||||
* Helper macro for MDIO drivers which do not do anything special in module
|
||||
* init/exit. Each module may only use this macro once, and calling it
|
||||
* replaces module_init() and module_exit().
|
||||
*/
|
||||
#define mdio_module_driver(_mdio_driver) \
|
||||
static int __init mdio_module_init(void) \
|
||||
{ \
|
||||
return mdio_driver_register(&_mdio_driver); \
|
||||
} \
|
||||
module_init(mdio_module_init); \
|
||||
static void __exit mdio_module_exit(void) \
|
||||
{ \
|
||||
mdio_driver_unregister(&_mdio_driver); \
|
||||
} \
|
||||
module_exit(mdio_module_exit)
|
||||
|
||||
#endif /* __LINUX_MDIO_H__ */
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
#ifndef __PHY_H
|
||||
#define __PHY_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/timer.h>
|
||||
|
@ -58,6 +60,7 @@
|
|||
#define PHY_HAS_INTERRUPT 0x00000001
|
||||
#define PHY_HAS_MAGICANEG 0x00000002
|
||||
#define PHY_IS_INTERNAL 0x00000004
|
||||
#define MDIO_DEVICE_IS_PHY 0x80000000
|
||||
|
||||
/* Interface Mode definitions */
|
||||
typedef enum {
|
||||
|
@ -158,8 +161,8 @@ struct mii_bus {
|
|||
const char *name;
|
||||
char id[MII_BUS_ID_SIZE];
|
||||
void *priv;
|
||||
int (*read)(struct mii_bus *bus, int phy_id, int regnum);
|
||||
int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val);
|
||||
int (*read)(struct mii_bus *bus, int addr, int regnum);
|
||||
int (*write)(struct mii_bus *bus, int addr, int regnum, u16 val);
|
||||
int (*reset)(struct mii_bus *bus);
|
||||
|
||||
/*
|
||||
|
@ -178,7 +181,7 @@ struct mii_bus {
|
|||
struct device dev;
|
||||
|
||||
/* list of all PHYs on bus */
|
||||
struct phy_device *phy_map[PHY_MAX_ADDR];
|
||||
struct mdio_device *mdio_map[PHY_MAX_ADDR];
|
||||
|
||||
/* PHY addresses to be ignored when probing */
|
||||
u32 phy_mask;
|
||||
|
@ -187,10 +190,10 @@ struct mii_bus {
|
|||
u32 phy_ignore_ta_mask;
|
||||
|
||||
/*
|
||||
* Pointer to an array of interrupts, each PHY's
|
||||
* interrupt at the index matching its address
|
||||
* An array of interrupts, each PHY's interrupt at the index
|
||||
* matching its address
|
||||
*/
|
||||
int *irq;
|
||||
int irq[PHY_MAX_ADDR];
|
||||
};
|
||||
#define to_mii_bus(d) container_of(d, struct mii_bus, dev)
|
||||
|
||||
|
@ -212,11 +215,6 @@ static inline struct mii_bus *devm_mdiobus_alloc(struct device *dev)
|
|||
|
||||
void devm_mdiobus_free(struct device *dev, struct mii_bus *bus);
|
||||
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
|
||||
int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
|
||||
int mdiobus_read_nested(struct mii_bus *bus, int addr, u32 regnum);
|
||||
int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
|
||||
int mdiobus_write_nested(struct mii_bus *bus, int addr, u32 regnum, u16 val);
|
||||
|
||||
|
||||
#define PHY_INTERRUPT_DISABLED 0x0
|
||||
#define PHY_INTERRUPT_ENABLED 0x80000000
|
||||
|
@ -361,14 +359,12 @@ struct phy_c45_device_ids {
|
|||
* handling, as well as handling shifts in PHY hardware state
|
||||
*/
|
||||
struct phy_device {
|
||||
struct mdio_device mdio;
|
||||
|
||||
/* Information about the PHY type */
|
||||
/* And management functions */
|
||||
struct phy_driver *drv;
|
||||
|
||||
struct mii_bus *bus;
|
||||
|
||||
struct device dev;
|
||||
|
||||
u32 phy_id;
|
||||
|
||||
struct phy_c45_device_ids c45_ids;
|
||||
|
@ -384,9 +380,6 @@ struct phy_device {
|
|||
|
||||
phy_interface_t interface;
|
||||
|
||||
/* Bus address of the PHY (0-31) */
|
||||
int addr;
|
||||
|
||||
/*
|
||||
* forced speed & duplex (no autoneg)
|
||||
* partner speed & duplex & pause (autoneg)
|
||||
|
@ -435,10 +428,12 @@ struct phy_device {
|
|||
|
||||
void (*adjust_link)(struct net_device *dev);
|
||||
};
|
||||
#define to_phy_device(d) container_of(d, struct phy_device, dev)
|
||||
#define to_phy_device(d) container_of(to_mdio_device(d), \
|
||||
struct phy_device, mdio)
|
||||
|
||||
/* struct phy_driver: Driver structure for a particular PHY type
|
||||
*
|
||||
* driver_data: static driver data
|
||||
* phy_id: The result of reading the UID registers of this PHY
|
||||
* type, and ANDing them with the phy_id_mask. This driver
|
||||
* only works for PHYs with IDs which match this field
|
||||
|
@ -448,7 +443,6 @@ struct phy_device {
|
|||
* by this PHY
|
||||
* flags: A bitfield defining certain other features this PHY
|
||||
* supports (like interrupts)
|
||||
* driver_data: static driver data
|
||||
*
|
||||
* The drivers must implement config_aneg and read_status. All
|
||||
* other functions are optional. Note that none of these
|
||||
|
@ -459,6 +453,7 @@ struct phy_device {
|
|||
* supported in the driver).
|
||||
*/
|
||||
struct phy_driver {
|
||||
struct mdio_driver_common mdiodrv;
|
||||
u32 phy_id;
|
||||
char *name;
|
||||
unsigned int phy_id_mask;
|
||||
|
@ -594,10 +589,9 @@ struct phy_driver {
|
|||
void (*get_strings)(struct phy_device *dev, u8 *data);
|
||||
void (*get_stats)(struct phy_device *dev,
|
||||
struct ethtool_stats *stats, u64 *data);
|
||||
|
||||
struct device_driver driver;
|
||||
};
|
||||
#define to_phy_driver(d) container_of(d, struct phy_driver, driver)
|
||||
#define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
|
||||
struct phy_driver, mdiodrv)
|
||||
|
||||
#define PHY_ANY_ID "MATCH ANY PHY"
|
||||
#define PHY_ANY_UID 0xffffffff
|
||||
|
@ -625,7 +619,7 @@ static inline int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
|
|||
if (!phydev->is_c45)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return mdiobus_read(phydev->bus, phydev->addr,
|
||||
return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
|
||||
MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff));
|
||||
}
|
||||
|
||||
|
@ -633,14 +627,12 @@ static inline int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
|
|||
* phy_read_mmd_indirect - reads data from the MMD registers
|
||||
* @phydev: The PHY device bus
|
||||
* @prtad: MMD Address
|
||||
* @devad: MMD DEVAD
|
||||
* @addr: PHY address on the MII bus
|
||||
*
|
||||
* Description: it reads data from the MMD registers (clause 22 to access to
|
||||
* clause 45) of the specified phy address.
|
||||
*/
|
||||
int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
|
||||
int devad, int addr);
|
||||
int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, int devad);
|
||||
|
||||
/**
|
||||
* phy_read - Convenience function for reading a given PHY register
|
||||
|
@ -653,7 +645,7 @@ int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
|
|||
*/
|
||||
static inline int phy_read(struct phy_device *phydev, u32 regnum)
|
||||
{
|
||||
return mdiobus_read(phydev->bus, phydev->addr, regnum);
|
||||
return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, regnum);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -668,7 +660,7 @@ static inline int phy_read(struct phy_device *phydev, u32 regnum)
|
|||
*/
|
||||
static inline int phy_write(struct phy_device *phydev, u32 regnum, u16 val)
|
||||
{
|
||||
return mdiobus_write(phydev->bus, phydev->addr, regnum, val);
|
||||
return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum, val);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -731,7 +723,7 @@ static inline int phy_write_mmd(struct phy_device *phydev, int devad,
|
|||
|
||||
regnum = MII_ADDR_C45 | ((devad & 0x1f) << 16) | (regnum & 0xffff);
|
||||
|
||||
return mdiobus_write(phydev->bus, phydev->addr, regnum, val);
|
||||
return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum, val);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -739,14 +731,13 @@ static inline int phy_write_mmd(struct phy_device *phydev, int devad,
|
|||
* @phydev: The PHY device
|
||||
* @prtad: MMD Address
|
||||
* @devad: MMD DEVAD
|
||||
* @addr: PHY address on the MII bus
|
||||
* @data: data to write in the MMD register
|
||||
*
|
||||
* Description: Write data from the MMD registers of the specified
|
||||
* phy address.
|
||||
*/
|
||||
void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
|
||||
int devad, int addr, u32 data);
|
||||
int devad, u32 data);
|
||||
|
||||
struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
|
||||
bool is_c45,
|
||||
|
@ -781,6 +772,20 @@ static inline int phy_read_status(struct phy_device *phydev)
|
|||
return phydev->drv->read_status(phydev);
|
||||
}
|
||||
|
||||
#define phydev_err(_phydev, format, args...) \
|
||||
dev_err(&_phydev->mdio.dev, format, ##args)
|
||||
|
||||
#define phydev_dbg(_phydev, format, args...) \
|
||||
dev_dbg(&_phydev->mdio.dev, format, ##args);
|
||||
|
||||
static inline const char *phydev_name(const struct phy_device *phydev)
|
||||
{
|
||||
return dev_name(&phydev->mdio.dev);
|
||||
}
|
||||
|
||||
void phy_attached_print(struct phy_device *phydev, const char *fmt, ...)
|
||||
__printf(2, 3);
|
||||
void phy_attached_info(struct phy_device *phydev);
|
||||
int genphy_config_init(struct phy_device *phydev);
|
||||
int genphy_setup_forced(struct phy_device *phydev);
|
||||
int genphy_restart_aneg(struct phy_device *phydev);
|
||||
|
@ -793,8 +798,9 @@ int genphy_resume(struct phy_device *phydev);
|
|||
int genphy_soft_reset(struct phy_device *phydev);
|
||||
void phy_driver_unregister(struct phy_driver *drv);
|
||||
void phy_drivers_unregister(struct phy_driver *drv, int n);
|
||||
int phy_driver_register(struct phy_driver *new_driver);
|
||||
int phy_drivers_register(struct phy_driver *new_driver, int n);
|
||||
int phy_driver_register(struct phy_driver *new_driver, struct module *owner);
|
||||
int phy_drivers_register(struct phy_driver *new_driver, int n,
|
||||
struct module *owner);
|
||||
void phy_state_machine(struct work_struct *work);
|
||||
void phy_change(struct work_struct *work);
|
||||
void phy_mac_interrupt(struct phy_device *phydev, int new_link);
|
||||
|
@ -839,7 +845,7 @@ extern struct bus_type mdio_bus_type;
|
|||
#define phy_module_driver(__phy_drivers, __count) \
|
||||
static int __init phy_module_init(void) \
|
||||
{ \
|
||||
return phy_drivers_register(__phy_drivers, __count); \
|
||||
return phy_drivers_register(__phy_drivers, __count, THIS_MODULE); \
|
||||
} \
|
||||
module_init(phy_module_init); \
|
||||
static void __exit phy_module_exit(void) \
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue