diff options
Diffstat (limited to 'drivers/net/fs_enet/fs_enet-main.c')
-rw-r--r-- | drivers/net/fs_enet/fs_enet-main.c | 319 |
1 files changed, 4 insertions, 315 deletions
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 445763e5648e..9a51ec8293cc 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c | |||
@@ -36,26 +36,18 @@ | |||
36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/phy.h> | 38 | #include <linux/phy.h> |
39 | #include <linux/of_platform.h> | ||
40 | #include <linux/of_gpio.h> | ||
39 | 41 | ||
40 | #include <linux/vmalloc.h> | 42 | #include <linux/vmalloc.h> |
41 | #include <asm/pgtable.h> | 43 | #include <asm/pgtable.h> |
42 | #include <asm/irq.h> | 44 | #include <asm/irq.h> |
43 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
44 | 46 | ||
45 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
46 | #include <linux/of_gpio.h> | ||
47 | #include <linux/of_platform.h> | ||
48 | #endif | ||
49 | |||
50 | #include "fs_enet.h" | 47 | #include "fs_enet.h" |
51 | 48 | ||
52 | /*************************************************/ | 49 | /*************************************************/ |
53 | 50 | ||
54 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
55 | static char version[] __devinitdata = | ||
56 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n"; | ||
57 | #endif | ||
58 | |||
59 | MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>"); | 51 | MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>"); |
60 | MODULE_DESCRIPTION("Freescale Ethernet Driver"); | 52 | MODULE_DESCRIPTION("Freescale Ethernet Driver"); |
61 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
@@ -738,9 +730,6 @@ static void generic_adjust_link(struct net_device *dev) | |||
738 | if (!fep->oldlink) { | 730 | if (!fep->oldlink) { |
739 | new_state = 1; | 731 | new_state = 1; |
740 | fep->oldlink = 1; | 732 | fep->oldlink = 1; |
741 | netif_tx_schedule_all(dev); | ||
742 | netif_carrier_on(dev); | ||
743 | netif_start_queue(dev); | ||
744 | } | 733 | } |
745 | 734 | ||
746 | if (new_state) | 735 | if (new_state) |
@@ -750,8 +739,6 @@ static void generic_adjust_link(struct net_device *dev) | |||
750 | fep->oldlink = 0; | 739 | fep->oldlink = 0; |
751 | fep->oldspeed = 0; | 740 | fep->oldspeed = 0; |
752 | fep->oldduplex = -1; | 741 | fep->oldduplex = -1; |
753 | netif_carrier_off(dev); | ||
754 | netif_stop_queue(dev); | ||
755 | } | 742 | } |
756 | 743 | ||
757 | if (new_state && netif_msg_link(fep)) | 744 | if (new_state && netif_msg_link(fep)) |
@@ -826,6 +813,8 @@ static int fs_enet_open(struct net_device *dev) | |||
826 | } | 813 | } |
827 | phy_start(fep->phydev); | 814 | phy_start(fep->phydev); |
828 | 815 | ||
816 | netif_start_queue(dev); | ||
817 | |||
829 | return 0; | 818 | return 0; |
830 | } | 819 | } |
831 | 820 | ||
@@ -958,190 +947,6 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
958 | extern int fs_mii_connect(struct net_device *dev); | 947 | extern int fs_mii_connect(struct net_device *dev); |
959 | extern void fs_mii_disconnect(struct net_device *dev); | 948 | extern void fs_mii_disconnect(struct net_device *dev); |
960 | 949 | ||
961 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
962 | static struct net_device *fs_init_instance(struct device *dev, | ||
963 | struct fs_platform_info *fpi) | ||
964 | { | ||
965 | struct net_device *ndev = NULL; | ||
966 | struct fs_enet_private *fep = NULL; | ||
967 | int privsize, i, r, err = 0, registered = 0; | ||
968 | |||
969 | fpi->fs_no = fs_get_id(fpi); | ||
970 | /* guard */ | ||
971 | if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX) | ||
972 | return ERR_PTR(-EINVAL); | ||
973 | |||
974 | privsize = sizeof(*fep) + (sizeof(struct sk_buff **) * | ||
975 | (fpi->rx_ring + fpi->tx_ring)); | ||
976 | |||
977 | ndev = alloc_etherdev(privsize); | ||
978 | if (!ndev) { | ||
979 | err = -ENOMEM; | ||
980 | goto err; | ||
981 | } | ||
982 | |||
983 | fep = netdev_priv(ndev); | ||
984 | |||
985 | fep->dev = dev; | ||
986 | dev_set_drvdata(dev, ndev); | ||
987 | fep->fpi = fpi; | ||
988 | if (fpi->init_ioports) | ||
989 | fpi->init_ioports((struct fs_platform_info *)fpi); | ||
990 | |||
991 | #ifdef CONFIG_FS_ENET_HAS_FEC | ||
992 | if (fs_get_fec_index(fpi->fs_no) >= 0) | ||
993 | fep->ops = &fs_fec_ops; | ||
994 | #endif | ||
995 | |||
996 | #ifdef CONFIG_FS_ENET_HAS_SCC | ||
997 | if (fs_get_scc_index(fpi->fs_no) >=0) | ||
998 | fep->ops = &fs_scc_ops; | ||
999 | #endif | ||
1000 | |||
1001 | #ifdef CONFIG_FS_ENET_HAS_FCC | ||
1002 | if (fs_get_fcc_index(fpi->fs_no) >= 0) | ||
1003 | fep->ops = &fs_fcc_ops; | ||
1004 | #endif | ||
1005 | |||
1006 | if (fep->ops == NULL) { | ||
1007 | printk(KERN_ERR DRV_MODULE_NAME | ||
1008 | ": %s No matching ops found (%d).\n", | ||
1009 | ndev->name, fpi->fs_no); | ||
1010 | err = -EINVAL; | ||
1011 | goto err; | ||
1012 | } | ||
1013 | |||
1014 | r = (*fep->ops->setup_data)(ndev); | ||
1015 | if (r != 0) { | ||
1016 | printk(KERN_ERR DRV_MODULE_NAME | ||
1017 | ": %s setup_data failed\n", | ||
1018 | ndev->name); | ||
1019 | err = r; | ||
1020 | goto err; | ||
1021 | } | ||
1022 | |||
1023 | /* point rx_skbuff, tx_skbuff */ | ||
1024 | fep->rx_skbuff = (struct sk_buff **)&fep[1]; | ||
1025 | fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; | ||
1026 | |||
1027 | /* init locks */ | ||
1028 | spin_lock_init(&fep->lock); | ||
1029 | spin_lock_init(&fep->tx_lock); | ||
1030 | |||
1031 | /* | ||
1032 | * Set the Ethernet address. | ||
1033 | */ | ||
1034 | for (i = 0; i < 6; i++) | ||
1035 | ndev->dev_addr[i] = fpi->macaddr[i]; | ||
1036 | |||
1037 | r = (*fep->ops->allocate_bd)(ndev); | ||
1038 | |||
1039 | if (fep->ring_base == NULL) { | ||
1040 | printk(KERN_ERR DRV_MODULE_NAME | ||
1041 | ": %s buffer descriptor alloc failed (%d).\n", ndev->name, r); | ||
1042 | err = r; | ||
1043 | goto err; | ||
1044 | } | ||
1045 | |||
1046 | /* | ||
1047 | * Set receive and transmit descriptor base. | ||
1048 | */ | ||
1049 | fep->rx_bd_base = fep->ring_base; | ||
1050 | fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; | ||
1051 | |||
1052 | /* initialize ring size variables */ | ||
1053 | fep->tx_ring = fpi->tx_ring; | ||
1054 | fep->rx_ring = fpi->rx_ring; | ||
1055 | |||
1056 | /* | ||
1057 | * The FEC Ethernet specific entries in the device structure. | ||
1058 | */ | ||
1059 | ndev->open = fs_enet_open; | ||
1060 | ndev->hard_start_xmit = fs_enet_start_xmit; | ||
1061 | ndev->tx_timeout = fs_timeout; | ||
1062 | ndev->watchdog_timeo = 2 * HZ; | ||
1063 | ndev->stop = fs_enet_close; | ||
1064 | ndev->get_stats = fs_enet_get_stats; | ||
1065 | ndev->set_multicast_list = fs_set_multicast_list; | ||
1066 | |||
1067 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1068 | ndev->poll_controller = fs_enet_netpoll; | ||
1069 | #endif | ||
1070 | |||
1071 | netif_napi_add(ndev, &fep->napi, | ||
1072 | fs_enet_rx_napi, fpi->napi_weight); | ||
1073 | |||
1074 | ndev->ethtool_ops = &fs_ethtool_ops; | ||
1075 | ndev->do_ioctl = fs_ioctl; | ||
1076 | |||
1077 | init_timer(&fep->phy_timer_list); | ||
1078 | |||
1079 | netif_carrier_off(ndev); | ||
1080 | |||
1081 | err = register_netdev(ndev); | ||
1082 | if (err != 0) { | ||
1083 | printk(KERN_ERR DRV_MODULE_NAME | ||
1084 | ": %s register_netdev failed.\n", ndev->name); | ||
1085 | goto err; | ||
1086 | } | ||
1087 | registered = 1; | ||
1088 | |||
1089 | |||
1090 | return ndev; | ||
1091 | |||
1092 | err: | ||
1093 | if (ndev != NULL) { | ||
1094 | if (registered) | ||
1095 | unregister_netdev(ndev); | ||
1096 | |||
1097 | if (fep && fep->ops) { | ||
1098 | (*fep->ops->free_bd)(ndev); | ||
1099 | (*fep->ops->cleanup_data)(ndev); | ||
1100 | } | ||
1101 | |||
1102 | free_netdev(ndev); | ||
1103 | } | ||
1104 | |||
1105 | dev_set_drvdata(dev, NULL); | ||
1106 | |||
1107 | return ERR_PTR(err); | ||
1108 | } | ||
1109 | |||
1110 | static int fs_cleanup_instance(struct net_device *ndev) | ||
1111 | { | ||
1112 | struct fs_enet_private *fep; | ||
1113 | const struct fs_platform_info *fpi; | ||
1114 | struct device *dev; | ||
1115 | |||
1116 | if (ndev == NULL) | ||
1117 | return -EINVAL; | ||
1118 | |||
1119 | fep = netdev_priv(ndev); | ||
1120 | if (fep == NULL) | ||
1121 | return -EINVAL; | ||
1122 | |||
1123 | fpi = fep->fpi; | ||
1124 | |||
1125 | unregister_netdev(ndev); | ||
1126 | |||
1127 | dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), | ||
1128 | (void __force *)fep->ring_base, fep->ring_mem_addr); | ||
1129 | |||
1130 | /* reset it */ | ||
1131 | (*fep->ops->cleanup_data)(ndev); | ||
1132 | |||
1133 | dev = fep->dev; | ||
1134 | if (dev != NULL) { | ||
1135 | dev_set_drvdata(dev, NULL); | ||
1136 | fep->dev = NULL; | ||
1137 | } | ||
1138 | |||
1139 | free_netdev(ndev); | ||
1140 | |||
1141 | return 0; | ||
1142 | } | ||
1143 | #endif | ||
1144 | |||
1145 | /**************************************************************************************/ | 950 | /**************************************************************************************/ |
1146 | 951 | ||
1147 | /* handy pointer to the immap */ | 952 | /* handy pointer to the immap */ |
@@ -1168,7 +973,6 @@ static void cleanup_immap(void) | |||
1168 | 973 | ||
1169 | /**************************************************************************************/ | 974 | /**************************************************************************************/ |
1170 | 975 | ||
1171 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
1172 | static int __devinit find_phy(struct device_node *np, | 976 | static int __devinit find_phy(struct device_node *np, |
1173 | struct fs_platform_info *fpi) | 977 | struct fs_platform_info *fpi) |
1174 | { | 978 | { |
@@ -1408,121 +1212,6 @@ static void __exit fs_cleanup(void) | |||
1408 | of_unregister_platform_driver(&fs_enet_driver); | 1212 | of_unregister_platform_driver(&fs_enet_driver); |
1409 | cleanup_immap(); | 1213 | cleanup_immap(); |
1410 | } | 1214 | } |
1411 | #else | ||
1412 | static int __devinit fs_enet_probe(struct device *dev) | ||
1413 | { | ||
1414 | struct net_device *ndev; | ||
1415 | |||
1416 | /* no fixup - no device */ | ||
1417 | if (dev->platform_data == NULL) { | ||
1418 | printk(KERN_INFO "fs_enet: " | ||
1419 | "probe called with no platform data; " | ||
1420 | "remove unused devices\n"); | ||
1421 | return -ENODEV; | ||
1422 | } | ||
1423 | |||
1424 | ndev = fs_init_instance(dev, dev->platform_data); | ||
1425 | if (IS_ERR(ndev)) | ||
1426 | return PTR_ERR(ndev); | ||
1427 | return 0; | ||
1428 | } | ||
1429 | |||
1430 | static int fs_enet_remove(struct device *dev) | ||
1431 | { | ||
1432 | return fs_cleanup_instance(dev_get_drvdata(dev)); | ||
1433 | } | ||
1434 | |||
1435 | static struct device_driver fs_enet_fec_driver = { | ||
1436 | .name = "fsl-cpm-fec", | ||
1437 | .bus = &platform_bus_type, | ||
1438 | .probe = fs_enet_probe, | ||
1439 | .remove = fs_enet_remove, | ||
1440 | #ifdef CONFIG_PM | ||
1441 | /* .suspend = fs_enet_suspend, TODO */ | ||
1442 | /* .resume = fs_enet_resume, TODO */ | ||
1443 | #endif | ||
1444 | }; | ||
1445 | |||
1446 | static struct device_driver fs_enet_scc_driver = { | ||
1447 | .name = "fsl-cpm-scc", | ||
1448 | .bus = &platform_bus_type, | ||
1449 | .probe = fs_enet_probe, | ||
1450 | .remove = fs_enet_remove, | ||
1451 | #ifdef CONFIG_PM | ||
1452 | /* .suspend = fs_enet_suspend, TODO */ | ||
1453 | /* .resume = fs_enet_resume, TODO */ | ||
1454 | #endif | ||
1455 | }; | ||
1456 | |||
1457 | static struct device_driver fs_enet_fcc_driver = { | ||
1458 | .name = "fsl-cpm-fcc", | ||
1459 | .bus = &platform_bus_type, | ||
1460 | .probe = fs_enet_probe, | ||
1461 | .remove = fs_enet_remove, | ||
1462 | #ifdef CONFIG_PM | ||
1463 | /* .suspend = fs_enet_suspend, TODO */ | ||
1464 | /* .resume = fs_enet_resume, TODO */ | ||
1465 | #endif | ||
1466 | }; | ||
1467 | |||
1468 | static int __init fs_init(void) | ||
1469 | { | ||
1470 | int r; | ||
1471 | |||
1472 | printk(KERN_INFO | ||
1473 | "%s", version); | ||
1474 | |||
1475 | r = setup_immap(); | ||
1476 | if (r != 0) | ||
1477 | return r; | ||
1478 | |||
1479 | #ifdef CONFIG_FS_ENET_HAS_FCC | ||
1480 | /* let's insert mii stuff */ | ||
1481 | r = fs_enet_mdio_bb_init(); | ||
1482 | |||
1483 | if (r != 0) { | ||
1484 | printk(KERN_ERR DRV_MODULE_NAME | ||
1485 | "BB PHY init failed.\n"); | ||
1486 | return r; | ||
1487 | } | ||
1488 | r = driver_register(&fs_enet_fcc_driver); | ||
1489 | if (r != 0) | ||
1490 | goto err; | ||
1491 | #endif | ||
1492 | |||
1493 | #ifdef CONFIG_FS_ENET_HAS_FEC | ||
1494 | r = fs_enet_mdio_fec_init(); | ||
1495 | if (r != 0) { | ||
1496 | printk(KERN_ERR DRV_MODULE_NAME | ||
1497 | "FEC PHY init failed.\n"); | ||
1498 | return r; | ||
1499 | } | ||
1500 | |||
1501 | r = driver_register(&fs_enet_fec_driver); | ||
1502 | if (r != 0) | ||
1503 | goto err; | ||
1504 | #endif | ||
1505 | |||
1506 | #ifdef CONFIG_FS_ENET_HAS_SCC | ||
1507 | r = driver_register(&fs_enet_scc_driver); | ||
1508 | if (r != 0) | ||
1509 | goto err; | ||
1510 | #endif | ||
1511 | |||
1512 | return 0; | ||
1513 | err: | ||
1514 | cleanup_immap(); | ||
1515 | return r; | ||
1516 | } | ||
1517 | |||
1518 | static void __exit fs_cleanup(void) | ||
1519 | { | ||
1520 | driver_unregister(&fs_enet_fec_driver); | ||
1521 | driver_unregister(&fs_enet_fcc_driver); | ||
1522 | driver_unregister(&fs_enet_scc_driver); | ||
1523 | cleanup_immap(); | ||
1524 | } | ||
1525 | #endif | ||
1526 | 1215 | ||
1527 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1216 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1528 | static void fs_enet_netpoll(struct net_device *dev) | 1217 | static void fs_enet_netpoll(struct net_device *dev) |