aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/fs_enet/fs_enet-main.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2007-10-02 11:55:58 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:54:03 -0400
commit976de6a8c304dcc43e38efcb8a0bace7866b6242 (patch)
treebae132693bbcfa65c03cf44c7db924fdebf13158 /drivers/net/fs_enet/fs_enet-main.c
parent0d0d9c150c046cbd3e507adcfa2d78db82f1f452 (diff)
fs_enet: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set.
The existing OF glue code was crufty and broken. Rather than fix it, it will be removed, and the ethernet driver now talks to the device tree directly. The old, non-CONFIG_PPC_CPM_NEW_BINDING code can go away once CPM platforms are dropped from arch/ppc (which will hopefully be soon), and existing arch/powerpc boards that I wasn't able to test on for this patchset get converted (which should be even sooner). Signed-off-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/fs_enet/fs_enet-main.c')
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c258
1 files changed, 241 insertions, 17 deletions
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 7a0298687875..fc4fda805d44 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -42,12 +42,18 @@
42#include <asm/irq.h> 42#include <asm/irq.h>
43#include <asm/uaccess.h> 43#include <asm/uaccess.h>
44 44
45#ifdef CONFIG_PPC_CPM_NEW_BINDING
46#include <asm/of_platform.h>
47#endif
48
45#include "fs_enet.h" 49#include "fs_enet.h"
46 50
47/*************************************************/ 51/*************************************************/
48 52
53#ifndef CONFIG_PPC_CPM_NEW_BINDING
49static char version[] __devinitdata = 54static char version[] __devinitdata =
50 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n"; 55 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n";
56#endif
51 57
52MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>"); 58MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>");
53MODULE_DESCRIPTION("Freescale Ethernet Driver"); 59MODULE_DESCRIPTION("Freescale Ethernet Driver");
@@ -948,6 +954,7 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
948extern int fs_mii_connect(struct net_device *dev); 954extern int fs_mii_connect(struct net_device *dev);
949extern void fs_mii_disconnect(struct net_device *dev); 955extern void fs_mii_disconnect(struct net_device *dev);
950 956
957#ifndef CONFIG_PPC_CPM_NEW_BINDING
951static struct net_device *fs_init_instance(struct device *dev, 958static struct net_device *fs_init_instance(struct device *dev,
952 struct fs_platform_info *fpi) 959 struct fs_platform_info *fpi)
953{ 960{
@@ -1129,6 +1136,7 @@ static int fs_cleanup_instance(struct net_device *ndev)
1129 1136
1130 return 0; 1137 return 0;
1131} 1138}
1139#endif
1132 1140
1133/**************************************************************************************/ 1141/**************************************************************************************/
1134 1142
@@ -1137,35 +1145,250 @@ void *fs_enet_immap = NULL;
1137 1145
1138static int setup_immap(void) 1146static int setup_immap(void)
1139{ 1147{
1140 phys_addr_t paddr = 0;
1141 unsigned long size = 0;
1142
1143#ifdef CONFIG_CPM1 1148#ifdef CONFIG_CPM1
1144 paddr = IMAP_ADDR; 1149 fs_enet_immap = ioremap(IMAP_ADDR, 0x4000);
1145 size = 0x10000; /* map 64K */ 1150 WARN_ON(!fs_enet_immap);
1146#endif 1151#elif defined(CONFIG_CPM2)
1147 1152 fs_enet_immap = cpm2_immr;
1148#ifdef CONFIG_CPM2
1149 paddr = CPM_MAP_ADDR;
1150 size = 0x40000; /* map 256 K */
1151#endif 1153#endif
1152 fs_enet_immap = ioremap(paddr, size);
1153 if (fs_enet_immap == NULL)
1154 return -EBADF; /* XXX ahem; maybe just BUG_ON? */
1155 1154
1156 return 0; 1155 return 0;
1157} 1156}
1158 1157
1159static void cleanup_immap(void) 1158static void cleanup_immap(void)
1160{ 1159{
1161 if (fs_enet_immap != NULL) { 1160#if defined(CONFIG_CPM1)
1162 iounmap(fs_enet_immap); 1161 iounmap(fs_enet_immap);
1163 fs_enet_immap = NULL; 1162#endif
1164 }
1165} 1163}
1166 1164
1167/**************************************************************************************/ 1165/**************************************************************************************/
1168 1166
1167#ifdef CONFIG_PPC_CPM_NEW_BINDING
1168static int __devinit find_phy(struct device_node *np,
1169 struct fs_platform_info *fpi)
1170{
1171 struct device_node *phynode, *mdionode;
1172 struct resource res;
1173 int ret = 0, len;
1174
1175 const u32 *data = of_get_property(np, "phy-handle", &len);
1176 if (!data || len != 4)
1177 return -EINVAL;
1178
1179 phynode = of_find_node_by_phandle(*data);
1180 if (!phynode)
1181 return -EINVAL;
1182
1183 mdionode = of_get_parent(phynode);
1184 if (!mdionode)
1185 goto out_put_phy;
1186
1187 ret = of_address_to_resource(mdionode, 0, &res);
1188 if (ret)
1189 goto out_put_mdio;
1190
1191 data = of_get_property(phynode, "reg", &len);
1192 if (!data || len != 4)
1193 goto out_put_mdio;
1194
1195 snprintf(fpi->bus_id, 16, PHY_ID_FMT, res.start, *data);
1196
1197out_put_mdio:
1198 of_node_put(mdionode);
1199out_put_phy:
1200 of_node_put(phynode);
1201 return ret;
1202}
1203
1204#ifdef CONFIG_FS_ENET_HAS_FEC
1205#define IS_FEC(match) ((match)->data == &fs_fec_ops)
1206#else
1207#define IS_FEC(match) 0
1208#endif
1209
1210static int __devinit fs_enet_probe(struct of_device *ofdev,
1211 const struct of_device_id *match)
1212{
1213 struct net_device *ndev;
1214 struct fs_enet_private *fep;
1215 struct fs_platform_info *fpi;
1216 const u32 *data;
1217 const u8 *mac_addr;
1218 int privsize, len, ret = -ENODEV;
1219
1220 fpi = kzalloc(sizeof(*fpi), GFP_KERNEL);
1221 if (!fpi)
1222 return -ENOMEM;
1223
1224 if (!IS_FEC(match)) {
1225 data = of_get_property(ofdev->node, "fsl,cpm-command", &len);
1226 if (!data || len != 4)
1227 goto out_free_fpi;
1228
1229 fpi->cp_command = *data;
1230 }
1231
1232 fpi->rx_ring = 32;
1233 fpi->tx_ring = 32;
1234 fpi->rx_copybreak = 240;
1235 fpi->use_napi = 0;
1236 fpi->napi_weight = 17;
1237
1238 ret = find_phy(ofdev->node, fpi);
1239 if (ret)
1240 goto out_free_fpi;
1241
1242 privsize = sizeof(*fep) +
1243 sizeof(struct sk_buff **) *
1244 (fpi->rx_ring + fpi->tx_ring);
1245
1246 ndev = alloc_etherdev(privsize);
1247 if (!ndev) {
1248 ret = -ENOMEM;
1249 goto out_free_fpi;
1250 }
1251
1252 SET_MODULE_OWNER(ndev);
1253 dev_set_drvdata(&ofdev->dev, ndev);
1254
1255 fep = netdev_priv(ndev);
1256 fep->dev = &ofdev->dev;
1257 fep->fpi = fpi;
1258 fep->ops = match->data;
1259
1260 ret = fep->ops->setup_data(ndev);
1261 if (ret)
1262 goto out_free_dev;
1263
1264 fep->rx_skbuff = (struct sk_buff **)&fep[1];
1265 fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring;
1266
1267 spin_lock_init(&fep->lock);
1268 spin_lock_init(&fep->tx_lock);
1269
1270 mac_addr = of_get_mac_address(ofdev->node);
1271 if (mac_addr)
1272 memcpy(ndev->dev_addr, mac_addr, 6);
1273
1274 ret = fep->ops->allocate_bd(ndev);
1275 if (ret)
1276 goto out_cleanup_data;
1277
1278 fep->rx_bd_base = fep->ring_base;
1279 fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring;
1280
1281 fep->tx_ring = fpi->tx_ring;
1282 fep->rx_ring = fpi->rx_ring;
1283
1284 ndev->open = fs_enet_open;
1285 ndev->hard_start_xmit = fs_enet_start_xmit;
1286 ndev->tx_timeout = fs_timeout;
1287 ndev->watchdog_timeo = 2 * HZ;
1288 ndev->stop = fs_enet_close;
1289 ndev->get_stats = fs_enet_get_stats;
1290 ndev->set_multicast_list = fs_set_multicast_list;
1291 if (fpi->use_napi) {
1292 ndev->poll = fs_enet_rx_napi;
1293 ndev->weight = fpi->napi_weight;
1294 }
1295 ndev->ethtool_ops = &fs_ethtool_ops;
1296 ndev->do_ioctl = fs_ioctl;
1297
1298 init_timer(&fep->phy_timer_list);
1299
1300 netif_carrier_off(ndev);
1301
1302 ret = register_netdev(ndev);
1303 if (ret)
1304 goto out_free_bd;
1305
1306 printk(KERN_INFO "%s: fs_enet: %02x:%02x:%02x:%02x:%02x:%02x\n",
1307 ndev->name,
1308 ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
1309 ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
1310
1311 return 0;
1312
1313out_free_bd:
1314 fep->ops->free_bd(ndev);
1315out_cleanup_data:
1316 fep->ops->cleanup_data(ndev);
1317out_free_dev:
1318 free_netdev(ndev);
1319 dev_set_drvdata(&ofdev->dev, NULL);
1320out_free_fpi:
1321 kfree(fpi);
1322 return ret;
1323}
1324
1325static int fs_enet_remove(struct of_device *ofdev)
1326{
1327 struct net_device *ndev = dev_get_drvdata(&ofdev->dev);
1328 struct fs_enet_private *fep = netdev_priv(ndev);
1329
1330 unregister_netdev(ndev);
1331
1332 fep->ops->free_bd(ndev);
1333 fep->ops->cleanup_data(ndev);
1334 dev_set_drvdata(fep->dev, NULL);
1335
1336 free_netdev(ndev);
1337 return 0;
1338}
1339
1340static struct of_device_id fs_enet_match[] = {
1341#ifdef CONFIG_FS_ENET_HAS_SCC
1342 {
1343 .compatible = "fsl,cpm1-scc-enet",
1344 .data = (void *)&fs_scc_ops,
1345 },
1346#endif
1347#ifdef CONFIG_FS_ENET_HAS_FCC
1348 {
1349 .compatible = "fsl,cpm2-fcc-enet",
1350 .data = (void *)&fs_fcc_ops,
1351 },
1352#endif
1353#ifdef CONFIG_FS_ENET_HAS_FEC
1354 {
1355 .compatible = "fsl,pq1-fec-enet",
1356 .data = (void *)&fs_fec_ops,
1357 },
1358#endif
1359 {}
1360};
1361
1362static struct of_platform_driver fs_enet_driver = {
1363 .name = "fs_enet",
1364 .match_table = fs_enet_match,
1365 .probe = fs_enet_probe,
1366 .remove = fs_enet_remove,
1367};
1368
1369static int __init fs_init(void)
1370{
1371 int r = setup_immap();
1372 if (r != 0)
1373 return r;
1374
1375 r = of_register_platform_driver(&fs_enet_driver);
1376 if (r != 0)
1377 goto out;
1378
1379 return 0;
1380
1381out:
1382 cleanup_immap();
1383 return r;
1384}
1385
1386static void __exit fs_cleanup(void)
1387{
1388 of_unregister_platform_driver(&fs_enet_driver);
1389 cleanup_immap();
1390}
1391#else
1169static int __devinit fs_enet_probe(struct device *dev) 1392static int __devinit fs_enet_probe(struct device *dev)
1170{ 1393{
1171 struct net_device *ndev; 1394 struct net_device *ndev;
@@ -1279,6 +1502,7 @@ static void __exit fs_cleanup(void)
1279 driver_unregister(&fs_enet_scc_driver); 1502 driver_unregister(&fs_enet_scc_driver);
1280 cleanup_immap(); 1503 cleanup_immap();
1281} 1504}
1505#endif
1282 1506
1283#ifdef CONFIG_NET_POLL_CONTROLLER 1507#ifdef CONFIG_NET_POLL_CONTROLLER
1284static void fs_enet_netpoll(struct net_device *dev) 1508static void fs_enet_netpoll(struct net_device *dev)