diff options
Diffstat (limited to 'drivers/net/sunlance.c')
-rw-r--r-- | drivers/net/sunlance.c | 180 |
1 files changed, 68 insertions, 112 deletions
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 4e994f87469e..704301a5a7ff 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c | |||
@@ -91,6 +91,9 @@ static char lancestr[] = "LANCE"; | |||
91 | #include <linux/skbuff.h> | 91 | #include <linux/skbuff.h> |
92 | #include <linux/ethtool.h> | 92 | #include <linux/ethtool.h> |
93 | #include <linux/bitops.h> | 93 | #include <linux/bitops.h> |
94 | #include <linux/dma-mapping.h> | ||
95 | #include <linux/of.h> | ||
96 | #include <linux/of_device.h> | ||
94 | 97 | ||
95 | #include <asm/system.h> | 98 | #include <asm/system.h> |
96 | #include <asm/io.h> | 99 | #include <asm/io.h> |
@@ -98,7 +101,6 @@ static char lancestr[] = "LANCE"; | |||
98 | #include <asm/pgtable.h> | 101 | #include <asm/pgtable.h> |
99 | #include <asm/byteorder.h> /* Used by the checksum routines */ | 102 | #include <asm/byteorder.h> /* Used by the checksum routines */ |
100 | #include <asm/idprom.h> | 103 | #include <asm/idprom.h> |
101 | #include <asm/sbus.h> | ||
102 | #include <asm/prom.h> | 104 | #include <asm/prom.h> |
103 | #include <asm/auxio.h> /* For tpe-link-test? setting */ | 105 | #include <asm/auxio.h> /* For tpe-link-test? setting */ |
104 | #include <asm/irq.h> | 106 | #include <asm/irq.h> |
@@ -248,7 +250,7 @@ struct lance_private { | |||
248 | int rx_new, tx_new; | 250 | int rx_new, tx_new; |
249 | int rx_old, tx_old; | 251 | int rx_old, tx_old; |
250 | 252 | ||
251 | struct sbus_dma *ledma; /* If set this points to ledma */ | 253 | struct of_device *ledma; /* If set this points to ledma */ |
252 | char tpe; /* cable-selection is TPE */ | 254 | char tpe; /* cable-selection is TPE */ |
253 | char auto_select; /* cable-selection by carrier */ | 255 | char auto_select; /* cable-selection by carrier */ |
254 | char burst_sizes; /* ledma SBus burst sizes */ | 256 | char burst_sizes; /* ledma SBus burst sizes */ |
@@ -263,7 +265,8 @@ struct lance_private { | |||
263 | char *name; | 265 | char *name; |
264 | dma_addr_t init_block_dvma; | 266 | dma_addr_t init_block_dvma; |
265 | struct net_device *dev; /* Backpointer */ | 267 | struct net_device *dev; /* Backpointer */ |
266 | struct sbus_dev *sdev; | 268 | struct of_device *op; |
269 | struct of_device *lebuffer; | ||
267 | struct timer_list multicast_timer; | 270 | struct timer_list multicast_timer; |
268 | }; | 271 | }; |
269 | 272 | ||
@@ -1272,27 +1275,29 @@ static void lance_set_multicast_retry(unsigned long _opaque) | |||
1272 | static void lance_free_hwresources(struct lance_private *lp) | 1275 | static void lance_free_hwresources(struct lance_private *lp) |
1273 | { | 1276 | { |
1274 | if (lp->lregs) | 1277 | if (lp->lregs) |
1275 | sbus_iounmap(lp->lregs, LANCE_REG_SIZE); | 1278 | of_iounmap(&lp->op->resource[0], lp->lregs, LANCE_REG_SIZE); |
1279 | if (lp->dregs) { | ||
1280 | struct of_device *ledma = lp->ledma; | ||
1281 | |||
1282 | of_iounmap(&ledma->resource[0], lp->dregs, | ||
1283 | resource_size(&ledma->resource[0])); | ||
1284 | } | ||
1276 | if (lp->init_block_iomem) { | 1285 | if (lp->init_block_iomem) { |
1277 | sbus_iounmap(lp->init_block_iomem, | 1286 | of_iounmap(&lp->lebuffer->resource[0], lp->init_block_iomem, |
1278 | sizeof(struct lance_init_block)); | 1287 | sizeof(struct lance_init_block)); |
1279 | } else if (lp->init_block_mem) { | 1288 | } else if (lp->init_block_mem) { |
1280 | sbus_free_consistent(lp->sdev, | 1289 | dma_free_coherent(&lp->op->dev, |
1281 | sizeof(struct lance_init_block), | 1290 | sizeof(struct lance_init_block), |
1282 | lp->init_block_mem, | 1291 | lp->init_block_mem, |
1283 | lp->init_block_dvma); | 1292 | lp->init_block_dvma); |
1284 | } | 1293 | } |
1285 | } | 1294 | } |
1286 | 1295 | ||
1287 | /* Ethtool support... */ | 1296 | /* Ethtool support... */ |
1288 | static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 1297 | static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
1289 | { | 1298 | { |
1290 | struct lance_private *lp = netdev_priv(dev); | ||
1291 | |||
1292 | strcpy(info->driver, "sunlance"); | 1299 | strcpy(info->driver, "sunlance"); |
1293 | strcpy(info->version, "2.02"); | 1300 | strcpy(info->version, "2.02"); |
1294 | sprintf(info->bus_info, "SBUS:%d", | ||
1295 | lp->sdev->slot); | ||
1296 | } | 1301 | } |
1297 | 1302 | ||
1298 | static u32 sparc_lance_get_link(struct net_device *dev) | 1303 | static u32 sparc_lance_get_link(struct net_device *dev) |
@@ -1308,16 +1313,16 @@ static const struct ethtool_ops sparc_lance_ethtool_ops = { | |||
1308 | .get_link = sparc_lance_get_link, | 1313 | .get_link = sparc_lance_get_link, |
1309 | }; | 1314 | }; |
1310 | 1315 | ||
1311 | static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, | 1316 | static int __devinit sparc_lance_probe_one(struct of_device *op, |
1312 | struct sbus_dma *ledma, | 1317 | struct of_device *ledma, |
1313 | struct sbus_dev *lebuffer) | 1318 | struct of_device *lebuffer) |
1314 | { | 1319 | { |
1320 | struct device_node *dp = op->node; | ||
1315 | static unsigned version_printed; | 1321 | static unsigned version_printed; |
1316 | struct device_node *dp = sdev->ofdev.node; | ||
1317 | struct net_device *dev; | ||
1318 | struct lance_private *lp; | 1322 | struct lance_private *lp; |
1319 | int i; | 1323 | struct net_device *dev; |
1320 | DECLARE_MAC_BUF(mac); | 1324 | DECLARE_MAC_BUF(mac); |
1325 | int i; | ||
1321 | 1326 | ||
1322 | dev = alloc_etherdev(sizeof(struct lance_private) + 8); | 1327 | dev = alloc_etherdev(sizeof(struct lance_private) + 8); |
1323 | if (!dev) | 1328 | if (!dev) |
@@ -1338,14 +1343,27 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, | |||
1338 | dev->dev_addr[i] = idprom->id_ethaddr[i]; | 1343 | dev->dev_addr[i] = idprom->id_ethaddr[i]; |
1339 | 1344 | ||
1340 | /* Get the IO region */ | 1345 | /* Get the IO region */ |
1341 | lp->lregs = sbus_ioremap(&sdev->resource[0], 0, | 1346 | lp->lregs = of_ioremap(&op->resource[0], 0, |
1342 | LANCE_REG_SIZE, lancestr); | 1347 | LANCE_REG_SIZE, lancestr); |
1343 | if (!lp->lregs) { | 1348 | if (!lp->lregs) { |
1344 | printk(KERN_ERR "SunLance: Cannot map registers.\n"); | 1349 | printk(KERN_ERR "SunLance: Cannot map registers.\n"); |
1345 | goto fail; | 1350 | goto fail; |
1346 | } | 1351 | } |
1347 | 1352 | ||
1348 | lp->sdev = sdev; | 1353 | lp->ledma = ledma; |
1354 | if (lp->ledma) { | ||
1355 | lp->dregs = of_ioremap(&ledma->resource[0], 0, | ||
1356 | resource_size(&ledma->resource[0]), | ||
1357 | "ledma"); | ||
1358 | if (!lp->dregs) { | ||
1359 | printk(KERN_ERR "SunLance: Cannot map " | ||
1360 | "ledma registers.\n"); | ||
1361 | goto fail; | ||
1362 | } | ||
1363 | } | ||
1364 | |||
1365 | lp->op = op; | ||
1366 | lp->lebuffer = lebuffer; | ||
1349 | if (lebuffer) { | 1367 | if (lebuffer) { |
1350 | /* sanity check */ | 1368 | /* sanity check */ |
1351 | if (lebuffer->resource[0].start & 7) { | 1369 | if (lebuffer->resource[0].start & 7) { |
@@ -1353,8 +1371,8 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, | |||
1353 | goto fail; | 1371 | goto fail; |
1354 | } | 1372 | } |
1355 | lp->init_block_iomem = | 1373 | lp->init_block_iomem = |
1356 | sbus_ioremap(&lebuffer->resource[0], 0, | 1374 | of_ioremap(&lebuffer->resource[0], 0, |
1357 | sizeof(struct lance_init_block), "lebuffer"); | 1375 | sizeof(struct lance_init_block), "lebuffer"); |
1358 | if (!lp->init_block_iomem) { | 1376 | if (!lp->init_block_iomem) { |
1359 | printk(KERN_ERR "SunLance: Cannot map PIO buffer.\n"); | 1377 | printk(KERN_ERR "SunLance: Cannot map PIO buffer.\n"); |
1360 | goto fail; | 1378 | goto fail; |
@@ -1366,9 +1384,10 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, | |||
1366 | lp->tx = lance_tx_pio; | 1384 | lp->tx = lance_tx_pio; |
1367 | } else { | 1385 | } else { |
1368 | lp->init_block_mem = | 1386 | lp->init_block_mem = |
1369 | sbus_alloc_consistent(sdev, sizeof(struct lance_init_block), | 1387 | dma_alloc_coherent(&op->dev, |
1370 | &lp->init_block_dvma); | 1388 | sizeof(struct lance_init_block), |
1371 | if (!lp->init_block_mem || lp->init_block_dvma == 0) { | 1389 | &lp->init_block_dvma, GFP_ATOMIC); |
1390 | if (!lp->init_block_mem) { | ||
1372 | printk(KERN_ERR "SunLance: Cannot allocate consistent DMA memory.\n"); | 1391 | printk(KERN_ERR "SunLance: Cannot allocate consistent DMA memory.\n"); |
1373 | goto fail; | 1392 | goto fail; |
1374 | } | 1393 | } |
@@ -1383,13 +1402,13 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, | |||
1383 | LE_C3_BCON)); | 1402 | LE_C3_BCON)); |
1384 | 1403 | ||
1385 | lp->name = lancestr; | 1404 | lp->name = lancestr; |
1386 | lp->ledma = ledma; | ||
1387 | 1405 | ||
1388 | lp->burst_sizes = 0; | 1406 | lp->burst_sizes = 0; |
1389 | if (lp->ledma) { | 1407 | if (lp->ledma) { |
1390 | struct device_node *ledma_dp = ledma->sdev->ofdev.node; | 1408 | struct device_node *ledma_dp = ledma->node; |
1391 | const char *prop; | 1409 | struct device_node *sbus_dp; |
1392 | unsigned int sbmask; | 1410 | unsigned int sbmask; |
1411 | const char *prop; | ||
1393 | u32 csr; | 1412 | u32 csr; |
1394 | 1413 | ||
1395 | /* Find burst-size property for ledma */ | 1414 | /* Find burst-size property for ledma */ |
@@ -1397,7 +1416,8 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, | |||
1397 | "burst-sizes", 0); | 1416 | "burst-sizes", 0); |
1398 | 1417 | ||
1399 | /* ledma may be capable of fast bursts, but sbus may not. */ | 1418 | /* ledma may be capable of fast bursts, but sbus may not. */ |
1400 | sbmask = of_getintprop_default(ledma_dp, "burst-sizes", | 1419 | sbus_dp = ledma_dp->parent; |
1420 | sbmask = of_getintprop_default(sbus_dp, "burst-sizes", | ||
1401 | DMA_BURSTBITS); | 1421 | DMA_BURSTBITS); |
1402 | lp->burst_sizes &= sbmask; | 1422 | lp->burst_sizes &= sbmask; |
1403 | 1423 | ||
@@ -1435,8 +1455,6 @@ no_link_test: | |||
1435 | lp->tpe = 1; | 1455 | lp->tpe = 1; |
1436 | } | 1456 | } |
1437 | 1457 | ||
1438 | lp->dregs = ledma->regs; | ||
1439 | |||
1440 | /* Reset ledma */ | 1458 | /* Reset ledma */ |
1441 | csr = sbus_readl(lp->dregs + DMA_CSR); | 1459 | csr = sbus_readl(lp->dregs + DMA_CSR); |
1442 | sbus_writel(csr | DMA_RST_ENET, lp->dregs + DMA_CSR); | 1460 | sbus_writel(csr | DMA_RST_ENET, lp->dregs + DMA_CSR); |
@@ -1446,7 +1464,7 @@ no_link_test: | |||
1446 | lp->dregs = NULL; | 1464 | lp->dregs = NULL; |
1447 | 1465 | ||
1448 | lp->dev = dev; | 1466 | lp->dev = dev; |
1449 | SET_NETDEV_DEV(dev, &sdev->ofdev.dev); | 1467 | SET_NETDEV_DEV(dev, &op->dev); |
1450 | dev->open = &lance_open; | 1468 | dev->open = &lance_open; |
1451 | dev->stop = &lance_close; | 1469 | dev->stop = &lance_close; |
1452 | dev->hard_start_xmit = &lance_start_xmit; | 1470 | dev->hard_start_xmit = &lance_start_xmit; |
@@ -1455,9 +1473,7 @@ no_link_test: | |||
1455 | dev->set_multicast_list = &lance_set_multicast; | 1473 | dev->set_multicast_list = &lance_set_multicast; |
1456 | dev->ethtool_ops = &sparc_lance_ethtool_ops; | 1474 | dev->ethtool_ops = &sparc_lance_ethtool_ops; |
1457 | 1475 | ||
1458 | dev->irq = sdev->irqs[0]; | 1476 | dev->irq = op->irqs[0]; |
1459 | |||
1460 | dev->dma = 0; | ||
1461 | 1477 | ||
1462 | /* We cannot sleep if the chip is busy during a | 1478 | /* We cannot sleep if the chip is busy during a |
1463 | * multicast list update event, because such events | 1479 | * multicast list update event, because such events |
@@ -1473,7 +1489,7 @@ no_link_test: | |||
1473 | goto fail; | 1489 | goto fail; |
1474 | } | 1490 | } |
1475 | 1491 | ||
1476 | dev_set_drvdata(&sdev->ofdev.dev, lp); | 1492 | dev_set_drvdata(&op->dev, lp); |
1477 | 1493 | ||
1478 | printk(KERN_INFO "%s: LANCE %s\n", | 1494 | printk(KERN_INFO "%s: LANCE %s\n", |
1479 | dev->name, print_mac(mac, dev->dev_addr)); | 1495 | dev->name, print_mac(mac, dev->dev_addr)); |
@@ -1486,80 +1502,25 @@ fail: | |||
1486 | return -ENODEV; | 1502 | return -ENODEV; |
1487 | } | 1503 | } |
1488 | 1504 | ||
1489 | /* On 4m, find the associated dma for the lance chip */ | 1505 | static int __devinit sunlance_sbus_probe(struct of_device *op, const struct of_device_id *match) |
1490 | static struct sbus_dma * __devinit find_ledma(struct sbus_dev *sdev) | ||
1491 | { | ||
1492 | struct sbus_dma *p; | ||
1493 | |||
1494 | for_each_dvma(p) { | ||
1495 | if (p->sdev == sdev) | ||
1496 | return p; | ||
1497 | } | ||
1498 | return NULL; | ||
1499 | } | ||
1500 | |||
1501 | #ifdef CONFIG_SUN4 | ||
1502 | |||
1503 | #include <asm/sun4paddr.h> | ||
1504 | #include <asm/machines.h> | ||
1505 | |||
1506 | /* Find all the lance cards on the system and initialize them */ | ||
1507 | static struct sbus_dev sun4_sdev; | ||
1508 | static int __devinit sparc_lance_init(void) | ||
1509 | { | ||
1510 | if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || | ||
1511 | (idprom->id_machtype == (SM_SUN4|SM_4_470))) { | ||
1512 | memset(&sun4_sdev, 0, sizeof(struct sbus_dev)); | ||
1513 | sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; | ||
1514 | sun4_sdev.irqs[0] = 6; | ||
1515 | return sparc_lance_probe_one(&sun4_sdev, NULL, NULL); | ||
1516 | } | ||
1517 | return -ENODEV; | ||
1518 | } | ||
1519 | |||
1520 | static int __exit sunlance_sun4_remove(void) | ||
1521 | { | 1506 | { |
1522 | struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev); | 1507 | struct of_device *parent = to_of_device(op->dev.parent); |
1523 | struct net_device *net_dev = lp->dev; | 1508 | struct device_node *parent_dp = parent->node; |
1524 | |||
1525 | unregister_netdev(net_dev); | ||
1526 | |||
1527 | lance_free_hwresources(lp); | ||
1528 | |||
1529 | free_netdev(net_dev); | ||
1530 | |||
1531 | dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL); | ||
1532 | |||
1533 | return 0; | ||
1534 | } | ||
1535 | |||
1536 | #else /* !CONFIG_SUN4 */ | ||
1537 | |||
1538 | static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match) | ||
1539 | { | ||
1540 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); | ||
1541 | int err; | 1509 | int err; |
1542 | 1510 | ||
1543 | if (sdev->parent) { | 1511 | if (!strcmp(parent_dp->name, "ledma")) { |
1544 | struct of_device *parent = &sdev->parent->ofdev; | 1512 | err = sparc_lance_probe_one(op, parent, NULL); |
1545 | 1513 | } else if (!strcmp(parent_dp->name, "lebuffer")) { | |
1546 | if (!strcmp(parent->node->name, "ledma")) { | 1514 | err = sparc_lance_probe_one(op, NULL, parent); |
1547 | struct sbus_dma *ledma = find_ledma(to_sbus_device(&parent->dev)); | ||
1548 | |||
1549 | err = sparc_lance_probe_one(sdev, ledma, NULL); | ||
1550 | } else if (!strcmp(parent->node->name, "lebuffer")) { | ||
1551 | err = sparc_lance_probe_one(sdev, NULL, to_sbus_device(&parent->dev)); | ||
1552 | } else | ||
1553 | err = sparc_lance_probe_one(sdev, NULL, NULL); | ||
1554 | } else | 1515 | } else |
1555 | err = sparc_lance_probe_one(sdev, NULL, NULL); | 1516 | err = sparc_lance_probe_one(op, NULL, NULL); |
1556 | 1517 | ||
1557 | return err; | 1518 | return err; |
1558 | } | 1519 | } |
1559 | 1520 | ||
1560 | static int __devexit sunlance_sbus_remove(struct of_device *dev) | 1521 | static int __devexit sunlance_sbus_remove(struct of_device *op) |
1561 | { | 1522 | { |
1562 | struct lance_private *lp = dev_get_drvdata(&dev->dev); | 1523 | struct lance_private *lp = dev_get_drvdata(&op->dev); |
1563 | struct net_device *net_dev = lp->dev; | 1524 | struct net_device *net_dev = lp->dev; |
1564 | 1525 | ||
1565 | unregister_netdev(net_dev); | 1526 | unregister_netdev(net_dev); |
@@ -1568,12 +1529,12 @@ static int __devexit sunlance_sbus_remove(struct of_device *dev) | |||
1568 | 1529 | ||
1569 | free_netdev(net_dev); | 1530 | free_netdev(net_dev); |
1570 | 1531 | ||
1571 | dev_set_drvdata(&dev->dev, NULL); | 1532 | dev_set_drvdata(&op->dev, NULL); |
1572 | 1533 | ||
1573 | return 0; | 1534 | return 0; |
1574 | } | 1535 | } |
1575 | 1536 | ||
1576 | static struct of_device_id sunlance_sbus_match[] = { | 1537 | static const struct of_device_id sunlance_sbus_match[] = { |
1577 | { | 1538 | { |
1578 | .name = "le", | 1539 | .name = "le", |
1579 | }, | 1540 | }, |
@@ -1593,17 +1554,12 @@ static struct of_platform_driver sunlance_sbus_driver = { | |||
1593 | /* Find all the lance cards on the system and initialize them */ | 1554 | /* Find all the lance cards on the system and initialize them */ |
1594 | static int __init sparc_lance_init(void) | 1555 | static int __init sparc_lance_init(void) |
1595 | { | 1556 | { |
1596 | return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type); | 1557 | return of_register_driver(&sunlance_sbus_driver, &of_bus_type); |
1597 | } | 1558 | } |
1598 | #endif /* !CONFIG_SUN4 */ | ||
1599 | 1559 | ||
1600 | static void __exit sparc_lance_exit(void) | 1560 | static void __exit sparc_lance_exit(void) |
1601 | { | 1561 | { |
1602 | #ifdef CONFIG_SUN4 | ||
1603 | sunlance_sun4_remove(); | ||
1604 | #else | ||
1605 | of_unregister_driver(&sunlance_sbus_driver); | 1562 | of_unregister_driver(&sunlance_sbus_driver); |
1606 | #endif | ||
1607 | } | 1563 | } |
1608 | 1564 | ||
1609 | module_init(sparc_lance_init); | 1565 | module_init(sparc_lance_init); |