aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/stmmac/stmmac.h6
-rw-r--r--drivers/net/stmmac/stmmac_main.c95
-rw-r--r--drivers/net/stmmac/stmmac_mdio.c83
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
1531static 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
1541static int stmmacphy_dvr_remove(struct platform_device *pdev)
1542{
1543 return 0;
1544}
1545
1546static 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 */
1562static 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 */
1906static void __exit stmmac_cleanup_module(void) 1826static 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
195bus_register_fail: 227bus_register_fail:
196 kfree(irqlist); 228 mdiobus_free(new_bus);
197irqlist_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}