aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ibm_newemac/core.c
diff options
context:
space:
mode:
authorVictor Gallardo <vgallardo@amcc.com>2008-10-02 02:37:57 -0400
committerJosh Boyer <jwboyer@linux.vnet.ibm.com>2008-10-02 13:06:42 -0400
commit9e3cb29497561c846d0e7efc445731764d93c749 (patch)
treefec0caf2a561850074bfcb29013603d2fde9b056 /drivers/net/ibm_newemac/core.c
parent5a013fc7bb48acefe94011f4b83fef95b381f875 (diff)
ibm_newemac: Add support for GPCS, SGMII and M88E1112 PHY
Add support for the phy types found on the Arches and other PowerPC 460 based boards. Signed-off-by: Victor Gallardo <vgallardo@amcc.com> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Diffstat (limited to 'drivers/net/ibm_newemac/core.c')
-rw-r--r--drivers/net/ibm_newemac/core.c58
1 files changed, 49 insertions, 9 deletions
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 4e633870e6e..efcf21c9f5c 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -130,6 +130,7 @@ static inline void emac_report_timeout_error(struct emac_instance *dev,
130 const char *error) 130 const char *error)
131{ 131{
132 if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX | 132 if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX |
133 EMAC_FTR_460EX_PHY_CLK_FIX |
133 EMAC_FTR_440EP_PHY_CLK_FIX)) 134 EMAC_FTR_440EP_PHY_CLK_FIX))
134 DBG(dev, "%s" NL, error); 135 DBG(dev, "%s" NL, error);
135 else if (net_ratelimit()) 136 else if (net_ratelimit())
@@ -201,13 +202,15 @@ static inline int emac_phy_supports_gige(int phy_mode)
201{ 202{
202 return phy_mode == PHY_MODE_GMII || 203 return phy_mode == PHY_MODE_GMII ||
203 phy_mode == PHY_MODE_RGMII || 204 phy_mode == PHY_MODE_RGMII ||
205 phy_mode == PHY_MODE_SGMII ||
204 phy_mode == PHY_MODE_TBI || 206 phy_mode == PHY_MODE_TBI ||
205 phy_mode == PHY_MODE_RTBI; 207 phy_mode == PHY_MODE_RTBI;
206} 208}
207 209
208static inline int emac_phy_gpcs(int phy_mode) 210static inline int emac_phy_gpcs(int phy_mode)
209{ 211{
210 return phy_mode == PHY_MODE_TBI || 212 return phy_mode == PHY_MODE_SGMII ||
213 phy_mode == PHY_MODE_TBI ||
211 phy_mode == PHY_MODE_RTBI; 214 phy_mode == PHY_MODE_RTBI;
212} 215}
213 216
@@ -351,10 +354,24 @@ static int emac_reset(struct emac_instance *dev)
351 emac_tx_disable(dev); 354 emac_tx_disable(dev);
352 } 355 }
353 356
357#ifdef CONFIG_PPC_DCR_NATIVE
358 /* Enable internal clock source */
359 if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX))
360 dcri_clrset(SDR0, SDR0_ETH_CFG,
361 0, SDR0_ETH_CFG_ECS << dev->cell_index);
362#endif
363
354 out_be32(&p->mr0, EMAC_MR0_SRST); 364 out_be32(&p->mr0, EMAC_MR0_SRST);
355 while ((in_be32(&p->mr0) & EMAC_MR0_SRST) && n) 365 while ((in_be32(&p->mr0) & EMAC_MR0_SRST) && n)
356 --n; 366 --n;
357 367
368#ifdef CONFIG_PPC_DCR_NATIVE
369 /* Enable external clock source */
370 if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX))
371 dcri_clrset(SDR0, SDR0_ETH_CFG,
372 SDR0_ETH_CFG_ECS << dev->cell_index, 0);
373#endif
374
358 if (n) { 375 if (n) {
359 dev->reset_failed = 0; 376 dev->reset_failed = 0;
360 return 0; 377 return 0;
@@ -547,8 +564,9 @@ static int emac_configure(struct emac_instance *dev)
547 switch (dev->phy.speed) { 564 switch (dev->phy.speed) {
548 case SPEED_1000: 565 case SPEED_1000:
549 if (emac_phy_gpcs(dev->phy.mode)) { 566 if (emac_phy_gpcs(dev->phy.mode)) {
550 mr1 |= EMAC_MR1_MF_1000GPCS | 567 mr1 |= EMAC_MR1_MF_1000GPCS | EMAC_MR1_MF_IPPA(
551 EMAC_MR1_MF_IPPA(dev->phy.address); 568 (dev->phy.gpcs_address != 0xffffffff) ?
569 dev->phy.gpcs_address : dev->phy.address);
552 570
553 /* Put some arbitrary OUI, Manuf & Rev IDs so we can 571 /* Put some arbitrary OUI, Manuf & Rev IDs so we can
554 * identify this GPCS PHY later. 572 * identify this GPCS PHY later.
@@ -660,8 +678,12 @@ static int emac_configure(struct emac_instance *dev)
660 out_be32(&p->iser, r); 678 out_be32(&p->iser, r);
661 679
662 /* We need to take GPCS PHY out of isolate mode after EMAC reset */ 680 /* We need to take GPCS PHY out of isolate mode after EMAC reset */
663 if (emac_phy_gpcs(dev->phy.mode)) 681 if (emac_phy_gpcs(dev->phy.mode)) {
664 emac_mii_reset_phy(&dev->phy); 682 if (dev->phy.gpcs_address != 0xffffffff)
683 emac_mii_reset_gpcs(&dev->phy);
684 else
685 emac_mii_reset_phy(&dev->phy);
686 }
665 687
666 return 0; 688 return 0;
667} 689}
@@ -866,7 +888,9 @@ static int emac_mdio_read(struct net_device *ndev, int id, int reg)
866 struct emac_instance *dev = netdev_priv(ndev); 888 struct emac_instance *dev = netdev_priv(ndev);
867 int res; 889 int res;
868 890
869 res = __emac_mdio_read(dev->mdio_instance ? dev->mdio_instance : dev, 891 res = __emac_mdio_read((dev->mdio_instance &&
892 dev->phy.gpcs_address != id) ?
893 dev->mdio_instance : dev,
870 (u8) id, (u8) reg); 894 (u8) id, (u8) reg);
871 return res; 895 return res;
872} 896}
@@ -875,7 +899,9 @@ static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val)
875{ 899{
876 struct emac_instance *dev = netdev_priv(ndev); 900 struct emac_instance *dev = netdev_priv(ndev);
877 901
878 __emac_mdio_write(dev->mdio_instance ? dev->mdio_instance : dev, 902 __emac_mdio_write((dev->mdio_instance &&
903 dev->phy.gpcs_address != id) ?
904 dev->mdio_instance : dev,
879 (u8) id, (u8) reg, (u16) val); 905 (u8) id, (u8) reg, (u16) val);
880} 906}
881 907
@@ -2367,7 +2393,11 @@ static int __devinit emac_init_phy(struct emac_instance *dev)
2367 * XXX I probably should move these settings to the dev tree 2393 * XXX I probably should move these settings to the dev tree
2368 */ 2394 */
2369 dev->phy.address = -1; 2395 dev->phy.address = -1;
2370 dev->phy.features = SUPPORTED_100baseT_Full | SUPPORTED_MII; 2396 dev->phy.features = SUPPORTED_MII;
2397 if (emac_phy_supports_gige(dev->phy_mode))
2398 dev->phy.features |= SUPPORTED_1000baseT_Full;
2399 else
2400 dev->phy.features |= SUPPORTED_100baseT_Full;
2371 dev->phy.pause = 1; 2401 dev->phy.pause = 1;
2372 2402
2373 return 0; 2403 return 0;
@@ -2406,7 +2436,9 @@ static int __devinit emac_init_phy(struct emac_instance *dev)
2406 * Note that the busy_phy_map is currently global 2436 * Note that the busy_phy_map is currently global
2407 * while it should probably be per-ASIC... 2437 * while it should probably be per-ASIC...
2408 */ 2438 */
2409 dev->phy.address = dev->cell_index; 2439 dev->phy.gpcs_address = dev->gpcs_address;
2440 if (dev->phy.gpcs_address == 0xffffffff)
2441 dev->phy.address = dev->cell_index;
2410 } 2442 }
2411 2443
2412 emac_configure(dev); 2444 emac_configure(dev);
@@ -2516,6 +2548,8 @@ static int __devinit emac_init_config(struct emac_instance *dev)
2516 dev->phy_address = 0xffffffff; 2548 dev->phy_address = 0xffffffff;
2517 if (emac_read_uint_prop(np, "phy-map", &dev->phy_map, 0)) 2549 if (emac_read_uint_prop(np, "phy-map", &dev->phy_map, 0))
2518 dev->phy_map = 0xffffffff; 2550 dev->phy_map = 0xffffffff;
2551 if (emac_read_uint_prop(np, "gpcs-address", &dev->gpcs_address, 0))
2552 dev->gpcs_address = 0xffffffff;
2519 if (emac_read_uint_prop(np->parent, "clock-frequency", &dev->opb_bus_freq, 1)) 2553 if (emac_read_uint_prop(np->parent, "clock-frequency", &dev->opb_bus_freq, 1))
2520 return -ENXIO; 2554 return -ENXIO;
2521 if (emac_read_uint_prop(np, "tah-device", &dev->tah_ph, 0)) 2555 if (emac_read_uint_prop(np, "tah-device", &dev->tah_ph, 0))
@@ -2559,6 +2593,9 @@ static int __devinit emac_init_config(struct emac_instance *dev)
2559 /* Check EMAC version */ 2593 /* Check EMAC version */
2560 if (of_device_is_compatible(np, "ibm,emac4sync")) { 2594 if (of_device_is_compatible(np, "ibm,emac4sync")) {
2561 dev->features |= (EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC); 2595 dev->features |= (EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC);
2596 if (of_device_is_compatible(np, "ibm,emac-460ex") ||
2597 of_device_is_compatible(np, "ibm,emac-460gt"))
2598 dev->features |= EMAC_FTR_460EX_PHY_CLK_FIX;
2562 } else if (of_device_is_compatible(np, "ibm,emac4")) { 2599 } else if (of_device_is_compatible(np, "ibm,emac4")) {
2563 dev->features |= EMAC_FTR_EMAC4; 2600 dev->features |= EMAC_FTR_EMAC4;
2564 if (of_device_is_compatible(np, "ibm,emac-440gx")) 2601 if (of_device_is_compatible(np, "ibm,emac-440gx"))
@@ -2826,6 +2863,9 @@ static int __devinit emac_probe(struct of_device *ofdev,
2826 ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2], 2863 ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
2827 ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]); 2864 ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
2828 2865
2866 if (dev->phy_mode == PHY_MODE_SGMII)
2867 printk(KERN_NOTICE "%s: in SGMII mode\n", ndev->name);
2868
2829 if (dev->phy.address >= 0) 2869 if (dev->phy.address >= 0)
2830 printk("%s: found %s PHY (0x%02x)\n", ndev->name, 2870 printk("%s: found %s PHY (0x%02x)\n", ndev->name,
2831 dev->phy.def->name, dev->phy.address); 2871 dev->phy.def->name, dev->phy.address);