diff options
Diffstat (limited to 'drivers/net/fec.c')
-rw-r--r-- | drivers/net/fec.c | 50 |
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 | ||
762 | err_out_unregister_bus: | ||
763 | mdiobus_unregister(fep->mii_bus); | ||
764 | err_out_free_mdio_irq: | 768 | err_out_free_mdio_irq: |
765 | kfree(fep->mii_bus->irq); | 769 | kfree(fep->mii_bus->irq); |
766 | err_out_free_mdiobus: | 770 | err_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 | |||
1226 | fec_probe(struct platform_device *pdev) | 1252 | fec_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 | ||
1304 | failed_register: | 1330 | failed_register: |