Commit 36bcfe7d74782c07f601edc4831f6b1ef40e9e43

Authored by Giuseppe CAVALLARO
Committed by David S. Miller
1 parent f3240e2811

stmmac: unify MAC and PHY configuration parameters (V2)

Prior to this change, most PHY configuration parameters were passed
into the STMMAC device as a separate PHY device. As well as being
unusual, this made it difficult to make changes to the MAC/PHY
relationship.

This patch moves all the PHY parameters into the MAC configuration
structure, mainly as a separate structure. This allows us to completely
ignore the MDIO bus attached to a stmmac if desired, and not create
the PHY bus. It also allows the stmmac driver to use a different PHY
from the one it is connected to, for example a fixed PHY or bit banging
PHY.

Also derive the stmmac/PHY connection type (MII/RMII etc) from the
mode can be passed into <platf>_configure_ethernet.
STLinux kernel at git://git.stlinux.com/stm/linux-sh4-2.6.32.y.git
provides several examples how to use this new infrastructure (that
actually is easier to maintain and clearer).

Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 4 changed files with 77 additions and 131 deletions Side-by-side Diff

drivers/net/stmmac/stmmac.h
... ... @@ -56,14 +56,9 @@
56 56 struct stmmac_extra_stats xstats;
57 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 59 int rx_coe;
64 60 int no_csum_insertion;
65 61  
66   - int phy_irq;
67 62 struct phy_device *phydev;
68 63 int oldlink;
69 64 int speed;
... ... @@ -71,6 +66,7 @@
71 66 unsigned int flow_ctrl;
72 67 unsigned int pause;
73 68 struct mii_bus *mii;
  69 + int mii_irq[PHY_MAX_ADDR];
74 70  
75 71 u32 msg_enable;
76 72 spinlock_t lock;
drivers/net/stmmac/stmmac_main.c
... ... @@ -49,7 +49,6 @@
49 49 #include "stmmac.h"
50 50  
51 51 #define STMMAC_RESOURCE_NAME "stmmaceth"
52   -#define PHY_RESOURCE_NAME "stmmacphy"
53 52  
54 53 #undef STMMAC_DEBUG
55 54 /*#define STMMAC_DEBUG*/
56 55  
57 56  
... ... @@ -305,18 +304,13 @@
305 304 priv->speed = 0;
306 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 307 snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id);
314 308 snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
315   - priv->phy_addr);
  309 + priv->plat->phy_addr);
316 310 pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id);
317 311  
318 312 phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0,
319   - priv->phy_interface);
  313 + priv->plat->interface);
320 314  
321 315 if (IS_ERR(phydev)) {
322 316 pr_err("%s: Could not attach to PHY\n", dev->name);
... ... @@ -335,7 +329,7 @@
335 329 return -ENODEV;
336 330 }
337 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 334 priv->phydev = phydev;
341 335  
342 336  
... ... @@ -1528,72 +1522,7 @@
1528 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 1525 /**
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   -/**
1597 1526 * stmmac_dvr_probe
1598 1527 * @pdev: platform device pointer
1599 1528 * Description: the driver is initialized through platform_device.
... ... @@ -1683,14 +1612,10 @@
1683 1612 if (ret < 0)
1684 1613 goto out_plat_exit;
1685 1614  
1686   - /* associate a PHY - it is provided by another platform bus */
1687   - if (!driver_for_each_device
1688   - (&(stmmacphy_driver.driver), NULL, (void *)priv,
1689   - stmmac_associate_phy)) {
1690   - pr_err("No PHY device is associated with this MAC!\n");
1691   - ret = -ENODEV;
1692   - goto out_unregister;
1693   - }
  1615 + /* Override with kernel parameters if supplied XXX CRS XXX
  1616 + * this needs to have multiple instances */
  1617 + if ((phyaddr >= 0) && (phyaddr <= 31))
  1618 + priv->plat->phy_addr = phyaddr;
1694 1619  
1695 1620 pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
1696 1621 "\tIO base addr: 0x%p)\n", ndev->name, pdev->name,
... ... @@ -1890,11 +1815,6 @@
1890 1815 {
1891 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 1818 ret = platform_driver_register(&stmmac_driver);
1899 1819 return ret;
1900 1820 }
... ... @@ -1905,7 +1825,6 @@
1905 1825 */
1906 1826 static void __exit stmmac_cleanup_module(void)
1907 1827 {
1908   - platform_driver_unregister(&stmmacphy_driver);
1909 1828 platform_driver_unregister(&stmmac_driver);
1910 1829 }
1911 1830  
drivers/net/stmmac/stmmac_mdio.c
... ... @@ -113,9 +113,9 @@
113 113 struct stmmac_priv *priv = netdev_priv(ndev);
114 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 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 121 /* This is a workaround for problems with the STE101P PHY.
122 122  
123 123  
124 124  
125 125  
126 126  
... ... @@ -138,30 +138,29 @@
138 138 struct mii_bus *new_bus;
139 139 int *irqlist;
140 140 struct stmmac_priv *priv = netdev_priv(ndev);
  141 + struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
141 142 int addr, found;
142 143  
  144 + if (!mdio_bus_data)
  145 + return 0;
  146 +
143 147 new_bus = mdiobus_alloc();
144 148 if (new_bus == NULL)
145 149 return -ENOMEM;
146 150  
147   - irqlist = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
148   - if (irqlist == NULL) {
149   - err = -ENOMEM;
150   - goto irqlist_alloc_fail;
151   - }
  151 + if (mdio_bus_data->irqs)
  152 + irqlist = mdio_bus_data->irqs;
  153 + else
  154 + irqlist = priv->mii_irq;
152 155  
153   - /* Assign IRQ to phy at address phy_addr */
154   - if (priv->phy_addr != -1)
155   - irqlist[priv->phy_addr] = priv->phy_irq;
156   -
157 156 new_bus->name = "STMMAC MII Bus";
158 157 new_bus->read = &stmmac_mdio_read;
159 158 new_bus->write = &stmmac_mdio_write;
160 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 161 new_bus->priv = ndev;
163 162 new_bus->irq = irqlist;
164   - new_bus->phy_mask = priv->phy_mask;
  163 + new_bus->phy_mask = mdio_bus_data->phy_mask;
165 164 new_bus->parent = priv->device;
166 165 err = mdiobus_register(new_bus);
167 166 if (err != 0) {
168 167  
169 168  
... ... @@ -172,18 +171,50 @@
172 171 priv->mii = new_bus;
173 172  
174 173 found = 0;
175   - for (addr = 0; addr < 32; addr++) {
  174 + for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
176 175 struct phy_device *phydev = new_bus->phy_map[addr];
177 176 if (phydev) {
178   - if (priv->phy_addr == -1) {
179   - priv->phy_addr = addr;
180   - phydev->irq = priv->phy_irq;
181   - irqlist[addr] = priv->phy_irq;
  177 + int act = 0;
  178 + char irq_num[4];
  179 + char *irq_str;
  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",
184   - ndev->name, phydev->phy_id, addr,
185   - phydev->irq, dev_name(&phydev->dev),
186   - (addr == priv->phy_addr) ? " active" : "");
  190 +
  191 + /*
  192 + * If we're going to bind the MAC to this PHY bus,
  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 218 found = 1;
188 219 }
189 220 }
190 221  
... ... @@ -192,10 +223,9 @@
192 223 pr_warning("%s: No PHY found\n", ndev->name);
193 224  
194 225 return 0;
  226 +
195 227 bus_register_fail:
196   - kfree(irqlist);
197   -irqlist_alloc_fail:
198   - kfree(new_bus);
  228 + mdiobus_free(new_bus);
199 229 return err;
200 230 }
201 231  
... ... @@ -210,7 +240,8 @@
210 240  
211 241 mdiobus_unregister(priv->mii);
212 242 priv->mii->priv = NULL;
213   - kfree(priv->mii);
  243 + mdiobus_free(priv->mii);
  244 + priv->mii = NULL;
214 245  
215 246 return 0;
216 247 }
include/linux/stmmac.h
... ... @@ -28,11 +28,21 @@
28 28  
29 29 #include <linux/platform_device.h>
30 30  
31   -/* platform data for platform device structure's platform_data field */
  31 +/* Platfrom data for platform device structure's platform_data field */
32 32  
33   -/* Private data for the STM on-board ethernet driver */
  33 +struct stmmac_mdio_bus_data {
  34 + int bus_id;
  35 + int (*phy_reset)(void *priv);
  36 + unsigned int phy_mask;
  37 + int *irqs;
  38 + int probed_phy_irq;
  39 +};
  40 +
34 41 struct plat_stmmacenet_data {
35 42 int bus_id;
  43 + int phy_addr;
  44 + int interface;
  45 + struct stmmac_mdio_bus_data *mdio_bus_data;
36 46 int pbl;
37 47 int clk_csr;
38 48 int has_gmac;
... ... @@ -47,15 +57,6 @@
47 57 void (*exit)(struct platform_device *pdev);
48 58 void *custom_cfg;
49 59 void *bsp_priv;
50   -};
51   -
52   -struct plat_stmmacphy_data {
53   - int bus_id;
54   - int phy_addr;
55   - unsigned int phy_mask;
56   - int interface;
57   - int (*phy_reset)(void *priv);
58   - void *priv;
59 60 };
60 61 #endif