aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/fec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/fec.c')
-rw-r--r--drivers/net/fec.c50
1 files changed, 38 insertions, 12 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 42d9ac9ba395..ddf7a86cd466 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -41,6 +41,7 @@
41#include <linux/clk.h> 41#include <linux/clk.h>
42#include <linux/platform_device.h> 42#include <linux/platform_device.h>
43#include <linux/phy.h> 43#include <linux/phy.h>
44#include <linux/fec.h>
44 45
45#include <asm/cacheflush.h> 46#include <asm/cacheflush.h>
46 47
@@ -182,6 +183,7 @@ struct fec_enet_private {
182 struct phy_device *phy_dev; 183 struct phy_device *phy_dev;
183 int mii_timeout; 184 int mii_timeout;
184 uint phy_speed; 185 uint phy_speed;
186 phy_interface_t phy_interface;
185 int index; 187 int index;
186 int link; 188 int link;
187 int full_duplex; 189 int full_duplex;
@@ -679,6 +681,8 @@ static int fec_enet_mii_probe(struct net_device *dev)
679 struct phy_device *phy_dev = NULL; 681 struct phy_device *phy_dev = NULL;
680 int phy_addr; 682 int phy_addr;
681 683
684 fep->phy_dev = NULL;
685
682 /* find the first phy */ 686 /* find the first phy */
683 for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { 687 for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
684 if (fep->mii_bus->phy_map[phy_addr]) { 688 if (fep->mii_bus->phy_map[phy_addr]) {
@@ -709,6 +713,11 @@ static int fec_enet_mii_probe(struct net_device *dev)
709 fep->link = 0; 713 fep->link = 0;
710 fep->full_duplex = 0; 714 fep->full_duplex = 0;
711 715
716 printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] "
717 "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
718 fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev),
719 fep->phy_dev->irq);
720
712 return 0; 721 return 0;
713} 722}
714 723
@@ -754,13 +763,8 @@ static int fec_enet_mii_init(struct platform_device *pdev)
754 if (mdiobus_register(fep->mii_bus)) 763 if (mdiobus_register(fep->mii_bus))
755 goto err_out_free_mdio_irq; 764 goto err_out_free_mdio_irq;
756 765
757 if (fec_enet_mii_probe(dev) != 0)
758 goto err_out_unregister_bus;
759
760 return 0; 766 return 0;
761 767
762err_out_unregister_bus:
763 mdiobus_unregister(fep->mii_bus);
764err_out_free_mdio_irq: 768err_out_free_mdio_irq:
765 kfree(fep->mii_bus->irq); 769 kfree(fep->mii_bus->irq);
766err_out_free_mdiobus: 770err_out_free_mdiobus:
@@ -913,7 +917,12 @@ fec_enet_open(struct net_device *dev)
913 if (ret) 917 if (ret)
914 return ret; 918 return ret;
915 919
916 /* schedule a link state check */ 920 /* Probe and connect to PHY when open the interface */
921 ret = fec_enet_mii_probe(dev);
922 if (ret) {
923 fec_enet_free_buffers(dev);
924 return ret;
925 }
917 phy_start(fep->phy_dev); 926 phy_start(fep->phy_dev);
918 netif_start_queue(dev); 927 netif_start_queue(dev);
919 fep->opened = 1; 928 fep->opened = 1;
@@ -927,10 +936,12 @@ fec_enet_close(struct net_device *dev)
927 936
928 /* Don't know what to do yet. */ 937 /* Don't know what to do yet. */
929 fep->opened = 0; 938 fep->opened = 0;
930 phy_stop(fep->phy_dev);
931 netif_stop_queue(dev); 939 netif_stop_queue(dev);
932 fec_stop(dev); 940 fec_stop(dev);
933 941
942 if (fep->phy_dev)
943 phy_disconnect(fep->phy_dev);
944
934 fec_enet_free_buffers(dev); 945 fec_enet_free_buffers(dev);
935 946
936 return 0; 947 return 0;
@@ -1191,6 +1202,21 @@ fec_restart(struct net_device *dev, int duplex)
1191 /* Set MII speed */ 1202 /* Set MII speed */
1192 writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); 1203 writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
1193 1204
1205#ifdef FEC_MIIGSK_ENR
1206 if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
1207 /* disable the gasket and wait */
1208 writel(0, fep->hwp + FEC_MIIGSK_ENR);
1209 while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
1210 udelay(1);
1211
1212 /* configure the gasket: RMII, 50 MHz, no loopback, no echo */
1213 writel(1, fep->hwp + FEC_MIIGSK_CFGR);
1214
1215 /* re-enable the gasket */
1216 writel(2, fep->hwp + FEC_MIIGSK_ENR);
1217 }
1218#endif
1219
1194 /* And last, enable the transmit and receive processing */ 1220 /* And last, enable the transmit and receive processing */
1195 writel(2, fep->hwp + FEC_ECNTRL); 1221 writel(2, fep->hwp + FEC_ECNTRL);
1196 writel(0, fep->hwp + FEC_R_DES_ACTIVE); 1222 writel(0, fep->hwp + FEC_R_DES_ACTIVE);
@@ -1226,6 +1252,7 @@ static int __devinit
1226fec_probe(struct platform_device *pdev) 1252fec_probe(struct platform_device *pdev)
1227{ 1253{
1228 struct fec_enet_private *fep; 1254 struct fec_enet_private *fep;
1255 struct fec_platform_data *pdata;
1229 struct net_device *ndev; 1256 struct net_device *ndev;
1230 int i, irq, ret = 0; 1257 int i, irq, ret = 0;
1231 struct resource *r; 1258 struct resource *r;
@@ -1259,6 +1286,10 @@ fec_probe(struct platform_device *pdev)
1259 1286
1260 platform_set_drvdata(pdev, ndev); 1287 platform_set_drvdata(pdev, ndev);
1261 1288
1289 pdata = pdev->dev.platform_data;
1290 if (pdata)
1291 fep->phy_interface = pdata->phy;
1292
1262 /* This device has up to three irqs on some platforms */ 1293 /* This device has up to three irqs on some platforms */
1263 for (i = 0; i < 3; i++) { 1294 for (i = 0; i < 3; i++) {
1264 irq = platform_get_irq(pdev, i); 1295 irq = platform_get_irq(pdev, i);
@@ -1294,11 +1325,6 @@ fec_probe(struct platform_device *pdev)
1294 if (ret) 1325 if (ret)
1295 goto failed_register; 1326 goto failed_register;
1296 1327
1297 printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] "
1298 "(mii_bus:phy_addr=%s, irq=%d)\n", ndev->name,
1299 fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev),
1300 fep->phy_dev->irq);
1301
1302 return 0; 1328 return 0;
1303 1329
1304failed_register: 1330failed_register: