diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/stmmac/stmmac.h | 6 | ||||
-rw-r--r-- | drivers/net/stmmac/stmmac_main.c | 95 | ||||
-rw-r--r-- | drivers/net/stmmac/stmmac_mdio.c | 83 |
3 files changed, 65 insertions, 119 deletions
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index 63979b75f085..de1929b2641b 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h | |||
@@ -56,14 +56,9 @@ struct stmmac_priv { | |||
56 | struct stmmac_extra_stats xstats; | 56 | struct stmmac_extra_stats xstats; |
57 | struct napi_struct napi; | 57 | struct napi_struct napi; |
58 | 58 | ||
59 | phy_interface_t phy_interface; | ||
60 | int phy_addr; | ||
61 | int phy_mask; | ||
62 | int (*phy_reset) (void *priv); | ||
63 | int rx_coe; | 59 | int rx_coe; |
64 | int no_csum_insertion; | 60 | int no_csum_insertion; |
65 | 61 | ||
66 | int phy_irq; | ||
67 | struct phy_device *phydev; | 62 | struct phy_device *phydev; |
68 | int oldlink; | 63 | int oldlink; |
69 | int speed; | 64 | int speed; |
@@ -71,6 +66,7 @@ struct stmmac_priv { | |||
71 | unsigned int flow_ctrl; | 66 | unsigned int flow_ctrl; |
72 | unsigned int pause; | 67 | unsigned int pause; |
73 | struct mii_bus *mii; | 68 | struct mii_bus *mii; |
69 | int mii_irq[PHY_MAX_ADDR]; | ||
74 | 70 | ||
75 | u32 msg_enable; | 71 | u32 msg_enable; |
76 | spinlock_t lock; | 72 | spinlock_t lock; |
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 40a6ae582800..c6e567e04eff 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include "stmmac.h" | 49 | #include "stmmac.h" |
50 | 50 | ||
51 | #define STMMAC_RESOURCE_NAME "stmmaceth" | 51 | #define STMMAC_RESOURCE_NAME "stmmaceth" |
52 | #define PHY_RESOURCE_NAME "stmmacphy" | ||
53 | 52 | ||
54 | #undef STMMAC_DEBUG | 53 | #undef STMMAC_DEBUG |
55 | /*#define STMMAC_DEBUG*/ | 54 | /*#define STMMAC_DEBUG*/ |
@@ -305,18 +304,13 @@ static int stmmac_init_phy(struct net_device *dev) | |||
305 | priv->speed = 0; | 304 | priv->speed = 0; |
306 | priv->oldduplex = -1; | 305 | priv->oldduplex = -1; |
307 | 306 | ||
308 | if (priv->phy_addr == -1) { | ||
309 | /* We don't have a PHY, so do nothing */ | ||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); | 307 | snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); |
314 | snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, | 308 | snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, |
315 | priv->phy_addr); | 309 | priv->plat->phy_addr); |
316 | pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id); | 310 | pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id); |
317 | 311 | ||
318 | phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, | 312 | phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, |
319 | priv->phy_interface); | 313 | priv->plat->interface); |
320 | 314 | ||
321 | if (IS_ERR(phydev)) { | 315 | if (IS_ERR(phydev)) { |
322 | pr_err("%s: Could not attach to PHY\n", dev->name); | 316 | pr_err("%s: Could not attach to PHY\n", dev->name); |
@@ -335,7 +329,7 @@ static int stmmac_init_phy(struct net_device *dev) | |||
335 | return -ENODEV; | 329 | return -ENODEV; |
336 | } | 330 | } |
337 | pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" | 331 | pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" |
338 | " Link = %d\n", dev->name, phydev->phy_id, phydev->link); | 332 | " Link = %d\n", dev->name, phydev->phy_id, phydev->link); |
339 | 333 | ||
340 | priv->phydev = phydev; | 334 | priv->phydev = phydev; |
341 | 335 | ||
@@ -1528,71 +1522,6 @@ static int stmmac_mac_device_setup(struct net_device *dev) | |||
1528 | return 0; | 1522 | return 0; |
1529 | } | 1523 | } |
1530 | 1524 | ||
1531 | static int stmmacphy_dvr_probe(struct platform_device *pdev) | ||
1532 | { | ||
1533 | struct plat_stmmacphy_data *plat_dat = pdev->dev.platform_data; | ||
1534 | |||
1535 | pr_debug("stmmacphy_dvr_probe: added phy for bus %d\n", | ||
1536 | plat_dat->bus_id); | ||
1537 | |||
1538 | return 0; | ||
1539 | } | ||
1540 | |||
1541 | static int stmmacphy_dvr_remove(struct platform_device *pdev) | ||
1542 | { | ||
1543 | return 0; | ||
1544 | } | ||
1545 | |||
1546 | static struct platform_driver stmmacphy_driver = { | ||
1547 | .driver = { | ||
1548 | .name = PHY_RESOURCE_NAME, | ||
1549 | }, | ||
1550 | .probe = stmmacphy_dvr_probe, | ||
1551 | .remove = stmmacphy_dvr_remove, | ||
1552 | }; | ||
1553 | |||
1554 | /** | ||
1555 | * stmmac_associate_phy | ||
1556 | * @dev: pointer to device structure | ||
1557 | * @data: points to the private structure. | ||
1558 | * Description: Scans through all the PHYs we have registered and checks if | ||
1559 | * any are associated with our MAC. If so, then just fill in | ||
1560 | * the blanks in our local context structure | ||
1561 | */ | ||
1562 | static int stmmac_associate_phy(struct device *dev, void *data) | ||
1563 | { | ||
1564 | struct stmmac_priv *priv = (struct stmmac_priv *)data; | ||
1565 | struct plat_stmmacphy_data *plat_dat = dev->platform_data; | ||
1566 | |||
1567 | DBG(probe, DEBUG, "%s: checking phy for bus %d\n", __func__, | ||
1568 | plat_dat->bus_id); | ||
1569 | |||
1570 | /* Check that this phy is for the MAC being initialised */ | ||
1571 | if (priv->plat->bus_id != plat_dat->bus_id) | ||
1572 | return 0; | ||
1573 | |||
1574 | /* OK, this PHY is connected to the MAC. | ||
1575 | Go ahead and get the parameters */ | ||
1576 | DBG(probe, DEBUG, "%s: OK. Found PHY config\n", __func__); | ||
1577 | priv->phy_irq = | ||
1578 | platform_get_irq_byname(to_platform_device(dev), "phyirq"); | ||
1579 | DBG(probe, DEBUG, "%s: PHY irq on bus %d is %d\n", __func__, | ||
1580 | plat_dat->bus_id, priv->phy_irq); | ||
1581 | |||
1582 | /* Override with kernel parameters if supplied XXX CRS XXX | ||
1583 | * this needs to have multiple instances */ | ||
1584 | if ((phyaddr >= 0) && (phyaddr <= 31)) | ||
1585 | plat_dat->phy_addr = phyaddr; | ||
1586 | |||
1587 | priv->phy_addr = plat_dat->phy_addr; | ||
1588 | priv->phy_mask = plat_dat->phy_mask; | ||
1589 | priv->phy_interface = plat_dat->interface; | ||
1590 | priv->phy_reset = plat_dat->phy_reset; | ||
1591 | |||
1592 | DBG(probe, DEBUG, "%s: exiting\n", __func__); | ||
1593 | return 1; /* forces exit of driver_for_each_device() */ | ||
1594 | } | ||
1595 | |||
1596 | /** | 1525 | /** |
1597 | * stmmac_dvr_probe | 1526 | * stmmac_dvr_probe |
1598 | * @pdev: platform device pointer | 1527 | * @pdev: platform device pointer |
@@ -1683,14 +1612,10 @@ static int stmmac_dvr_probe(struct platform_device *pdev) | |||
1683 | if (ret < 0) | 1612 | if (ret < 0) |
1684 | goto out_plat_exit; | 1613 | goto out_plat_exit; |
1685 | 1614 | ||
1686 | /* associate a PHY - it is provided by another platform bus */ | 1615 | /* Override with kernel parameters if supplied XXX CRS XXX |
1687 | if (!driver_for_each_device | 1616 | * this needs to have multiple instances */ |
1688 | (&(stmmacphy_driver.driver), NULL, (void *)priv, | 1617 | if ((phyaddr >= 0) && (phyaddr <= 31)) |
1689 | stmmac_associate_phy)) { | 1618 | priv->plat->phy_addr = phyaddr; |
1690 | pr_err("No PHY device is associated with this MAC!\n"); | ||
1691 | ret = -ENODEV; | ||
1692 | goto out_unregister; | ||
1693 | } | ||
1694 | 1619 | ||
1695 | pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n" | 1620 | pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n" |
1696 | "\tIO base addr: 0x%p)\n", ndev->name, pdev->name, | 1621 | "\tIO base addr: 0x%p)\n", ndev->name, pdev->name, |
@@ -1890,11 +1815,6 @@ static int __init stmmac_init_module(void) | |||
1890 | { | 1815 | { |
1891 | int ret; | 1816 | int ret; |
1892 | 1817 | ||
1893 | if (platform_driver_register(&stmmacphy_driver)) { | ||
1894 | pr_err("No PHY devices registered!\n"); | ||
1895 | return -ENODEV; | ||
1896 | } | ||
1897 | |||
1898 | ret = platform_driver_register(&stmmac_driver); | 1818 | ret = platform_driver_register(&stmmac_driver); |
1899 | return ret; | 1819 | return ret; |
1900 | } | 1820 | } |
@@ -1905,7 +1825,6 @@ static int __init stmmac_init_module(void) | |||
1905 | */ | 1825 | */ |
1906 | static void __exit stmmac_cleanup_module(void) | 1826 | static void __exit stmmac_cleanup_module(void) |
1907 | { | 1827 | { |
1908 | platform_driver_unregister(&stmmacphy_driver); | ||
1909 | platform_driver_unregister(&stmmac_driver); | 1828 | platform_driver_unregister(&stmmac_driver); |
1910 | } | 1829 | } |
1911 | 1830 | ||
diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c index 29a6bb6b8058..9c3b9d5c3411 100644 --- a/drivers/net/stmmac/stmmac_mdio.c +++ b/drivers/net/stmmac/stmmac_mdio.c | |||
@@ -113,9 +113,9 @@ static int stmmac_mdio_reset(struct mii_bus *bus) | |||
113 | struct stmmac_priv *priv = netdev_priv(ndev); | 113 | struct stmmac_priv *priv = netdev_priv(ndev); |
114 | unsigned int mii_address = priv->hw->mii.addr; | 114 | unsigned int mii_address = priv->hw->mii.addr; |
115 | 115 | ||
116 | if (priv->phy_reset) { | 116 | if (priv->plat->mdio_bus_data->phy_reset) { |
117 | pr_debug("stmmac_mdio_reset: calling phy_reset\n"); | 117 | pr_debug("stmmac_mdio_reset: calling phy_reset\n"); |
118 | priv->phy_reset(priv->plat->bsp_priv); | 118 | priv->plat->mdio_bus_data->phy_reset(priv->plat->bsp_priv); |
119 | } | 119 | } |
120 | 120 | ||
121 | /* This is a workaround for problems with the STE101P PHY. | 121 | /* This is a workaround for problems with the STE101P PHY. |
@@ -138,30 +138,29 @@ int stmmac_mdio_register(struct net_device *ndev) | |||
138 | struct mii_bus *new_bus; | 138 | struct mii_bus *new_bus; |
139 | int *irqlist; | 139 | int *irqlist; |
140 | struct stmmac_priv *priv = netdev_priv(ndev); | 140 | struct stmmac_priv *priv = netdev_priv(ndev); |
141 | struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data; | ||
141 | int addr, found; | 142 | int addr, found; |
142 | 143 | ||
144 | if (!mdio_bus_data) | ||
145 | return 0; | ||
146 | |||
143 | new_bus = mdiobus_alloc(); | 147 | new_bus = mdiobus_alloc(); |
144 | if (new_bus == NULL) | 148 | if (new_bus == NULL) |
145 | return -ENOMEM; | 149 | return -ENOMEM; |
146 | 150 | ||
147 | irqlist = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); | 151 | if (mdio_bus_data->irqs) |
148 | if (irqlist == NULL) { | 152 | irqlist = mdio_bus_data->irqs; |
149 | err = -ENOMEM; | 153 | else |
150 | goto irqlist_alloc_fail; | 154 | irqlist = priv->mii_irq; |
151 | } | ||
152 | |||
153 | /* Assign IRQ to phy at address phy_addr */ | ||
154 | if (priv->phy_addr != -1) | ||
155 | irqlist[priv->phy_addr] = priv->phy_irq; | ||
156 | 155 | ||
157 | new_bus->name = "STMMAC MII Bus"; | 156 | new_bus->name = "STMMAC MII Bus"; |
158 | new_bus->read = &stmmac_mdio_read; | 157 | new_bus->read = &stmmac_mdio_read; |
159 | new_bus->write = &stmmac_mdio_write; | 158 | new_bus->write = &stmmac_mdio_write; |
160 | new_bus->reset = &stmmac_mdio_reset; | 159 | new_bus->reset = &stmmac_mdio_reset; |
161 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); | 160 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", mdio_bus_data->bus_id); |
162 | new_bus->priv = ndev; | 161 | new_bus->priv = ndev; |
163 | new_bus->irq = irqlist; | 162 | new_bus->irq = irqlist; |
164 | new_bus->phy_mask = priv->phy_mask; | 163 | new_bus->phy_mask = mdio_bus_data->phy_mask; |
165 | new_bus->parent = priv->device; | 164 | new_bus->parent = priv->device; |
166 | err = mdiobus_register(new_bus); | 165 | err = mdiobus_register(new_bus); |
167 | if (err != 0) { | 166 | if (err != 0) { |
@@ -172,18 +171,50 @@ int stmmac_mdio_register(struct net_device *ndev) | |||
172 | priv->mii = new_bus; | 171 | priv->mii = new_bus; |
173 | 172 | ||
174 | found = 0; | 173 | found = 0; |
175 | for (addr = 0; addr < 32; addr++) { | 174 | for (addr = 0; addr < PHY_MAX_ADDR; addr++) { |
176 | struct phy_device *phydev = new_bus->phy_map[addr]; | 175 | struct phy_device *phydev = new_bus->phy_map[addr]; |
177 | if (phydev) { | 176 | if (phydev) { |
178 | if (priv->phy_addr == -1) { | 177 | int act = 0; |
179 | priv->phy_addr = addr; | 178 | char irq_num[4]; |
180 | phydev->irq = priv->phy_irq; | 179 | char *irq_str; |
181 | irqlist[addr] = priv->phy_irq; | 180 | |
181 | /* | ||
182 | * If an IRQ was provided to be assigned after | ||
183 | * the bus probe, do it here. | ||
184 | */ | ||
185 | if ((mdio_bus_data->irqs == NULL) && | ||
186 | (mdio_bus_data->probed_phy_irq > 0)) { | ||
187 | irqlist[addr] = mdio_bus_data->probed_phy_irq; | ||
188 | phydev->irq = mdio_bus_data->probed_phy_irq; | ||
182 | } | 189 | } |
183 | pr_info("%s: PHY ID %08x at %d IRQ %d (%s)%s\n", | 190 | |
184 | ndev->name, phydev->phy_id, addr, | 191 | /* |
185 | phydev->irq, dev_name(&phydev->dev), | 192 | * If we're going to bind the MAC to this PHY bus, |
186 | (addr == priv->phy_addr) ? " active" : ""); | 193 | * and no PHY number was provided to the MAC, |
194 | * use the one probed here. | ||
195 | */ | ||
196 | if ((priv->plat->bus_id == mdio_bus_data->bus_id) && | ||
197 | (priv->plat->phy_addr == -1)) | ||
198 | priv->plat->phy_addr = addr; | ||
199 | |||
200 | act = (priv->plat->bus_id == mdio_bus_data->bus_id) && | ||
201 | (priv->plat->phy_addr == addr); | ||
202 | switch (phydev->irq) { | ||
203 | case PHY_POLL: | ||
204 | irq_str = "POLL"; | ||
205 | break; | ||
206 | case PHY_IGNORE_INTERRUPT: | ||
207 | irq_str = "IGNORE"; | ||
208 | break; | ||
209 | default: | ||
210 | sprintf(irq_num, "%d", phydev->irq); | ||
211 | irq_str = irq_num; | ||
212 | break; | ||
213 | } | ||
214 | pr_info("%s: PHY ID %08x at %d IRQ %s (%s)%s\n", | ||
215 | ndev->name, phydev->phy_id, addr, | ||
216 | irq_str, dev_name(&phydev->dev), | ||
217 | act ? " active" : ""); | ||
187 | found = 1; | 218 | found = 1; |
188 | } | 219 | } |
189 | } | 220 | } |
@@ -192,10 +223,9 @@ int stmmac_mdio_register(struct net_device *ndev) | |||
192 | pr_warning("%s: No PHY found\n", ndev->name); | 223 | pr_warning("%s: No PHY found\n", ndev->name); |
193 | 224 | ||
194 | return 0; | 225 | return 0; |
226 | |||
195 | bus_register_fail: | 227 | bus_register_fail: |
196 | kfree(irqlist); | 228 | mdiobus_free(new_bus); |
197 | irqlist_alloc_fail: | ||
198 | kfree(new_bus); | ||
199 | return err; | 229 | return err; |
200 | } | 230 | } |
201 | 231 | ||
@@ -210,7 +240,8 @@ int stmmac_mdio_unregister(struct net_device *ndev) | |||
210 | 240 | ||
211 | mdiobus_unregister(priv->mii); | 241 | mdiobus_unregister(priv->mii); |
212 | priv->mii->priv = NULL; | 242 | priv->mii->priv = NULL; |
213 | kfree(priv->mii); | 243 | mdiobus_free(priv->mii); |
244 | priv->mii = NULL; | ||
214 | 245 | ||
215 | return 0; | 246 | return 0; |
216 | } | 247 | } |