diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2006-04-19 14:46:21 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-20 17:35:26 -0400 |
commit | 89be0501a013737d562f56ce1c5a2ff075995b11 (patch) | |
tree | 95ab664bcc4949235dce678c72436c673fbf06e9 /drivers | |
parent | e2fd956c670928e93208dc5d27dfdc7b51163900 (diff) |
[PATCH] au1000_eth.c probe code straightened up
Straighten up the AMD Au1xx0 Ethernet probing code, make it print out (and
store in the 'net_device' structure) the physical address of the controller,
not the KSEG1-based virtual. Make the driver also claim/release the 4-byte MAC
enable registers and assign to the Ethernet ports two consecutive MAC
addresses to match those that are printed on their stickers.
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/au1000_eth.c | 206 |
1 files changed, 87 insertions, 119 deletions
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 1363083b4d83..d5dfc784bccd 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Alchemy Au1x00 ethernet driver | 3 | * Alchemy Au1x00 ethernet driver |
4 | * | 4 | * |
5 | * Copyright 2001,2002,2003 MontaVista Software Inc. | 5 | * Copyright 2001-2003, 2006 MontaVista Software Inc. |
6 | * Copyright 2002 TimeSys Corp. | 6 | * Copyright 2002 TimeSys Corp. |
7 | * Added ethtool/mii-tool support, | 7 | * Added ethtool/mii-tool support, |
8 | * Copyright 2004 Matt Porter <mporter@kernel.crashing.org> | 8 | * Copyright 2004 Matt Porter <mporter@kernel.crashing.org> |
@@ -67,7 +67,7 @@ static int au1000_debug = 5; | |||
67 | static int au1000_debug = 3; | 67 | static int au1000_debug = 3; |
68 | #endif | 68 | #endif |
69 | 69 | ||
70 | #define DRV_NAME "au1000eth" | 70 | #define DRV_NAME "au1000_eth" |
71 | #define DRV_VERSION "1.5" | 71 | #define DRV_VERSION "1.5" |
72 | #define DRV_AUTHOR "Pete Popov <ppopov@embeddedalley.com>" | 72 | #define DRV_AUTHOR "Pete Popov <ppopov@embeddedalley.com>" |
73 | #define DRV_DESC "Au1xxx on-chip Ethernet driver" | 73 | #define DRV_DESC "Au1xxx on-chip Ethernet driver" |
@@ -79,7 +79,7 @@ MODULE_LICENSE("GPL"); | |||
79 | // prototypes | 79 | // prototypes |
80 | static void hard_stop(struct net_device *); | 80 | static void hard_stop(struct net_device *); |
81 | static void enable_rx_tx(struct net_device *dev); | 81 | static void enable_rx_tx(struct net_device *dev); |
82 | static struct net_device * au1000_probe(u32 ioaddr, int irq, int port_num); | 82 | static struct net_device * au1000_probe(int port_num); |
83 | static int au1000_init(struct net_device *); | 83 | static int au1000_init(struct net_device *); |
84 | static int au1000_open(struct net_device *); | 84 | static int au1000_open(struct net_device *); |
85 | static int au1000_close(struct net_device *); | 85 | static int au1000_close(struct net_device *); |
@@ -1159,12 +1159,27 @@ setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base) | |||
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | static struct { | 1161 | static struct { |
1162 | int port; | ||
1163 | u32 base_addr; | 1162 | u32 base_addr; |
1164 | u32 macen_addr; | 1163 | u32 macen_addr; |
1165 | int irq; | 1164 | int irq; |
1166 | struct net_device *dev; | 1165 | struct net_device *dev; |
1167 | } iflist[2]; | 1166 | } iflist[2] = { |
1167 | #ifdef CONFIG_SOC_AU1000 | ||
1168 | {AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT}, | ||
1169 | {AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT} | ||
1170 | #endif | ||
1171 | #ifdef CONFIG_SOC_AU1100 | ||
1172 | {AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT} | ||
1173 | #endif | ||
1174 | #ifdef CONFIG_SOC_AU1500 | ||
1175 | {AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT}, | ||
1176 | {AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT} | ||
1177 | #endif | ||
1178 | #ifdef CONFIG_SOC_AU1550 | ||
1179 | {AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT}, | ||
1180 | {AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT} | ||
1181 | #endif | ||
1182 | }; | ||
1168 | 1183 | ||
1169 | static int num_ifs; | 1184 | static int num_ifs; |
1170 | 1185 | ||
@@ -1175,58 +1190,14 @@ static int num_ifs; | |||
1175 | */ | 1190 | */ |
1176 | static int __init au1000_init_module(void) | 1191 | static int __init au1000_init_module(void) |
1177 | { | 1192 | { |
1178 | struct cpuinfo_mips *c = ¤t_cpu_data; | ||
1179 | int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4); | 1193 | int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4); |
1180 | struct net_device *dev; | 1194 | struct net_device *dev; |
1181 | int i, found_one = 0; | 1195 | int i, found_one = 0; |
1182 | 1196 | ||
1183 | switch (c->cputype) { | 1197 | num_ifs = NUM_ETH_INTERFACES - ni; |
1184 | #ifdef CONFIG_SOC_AU1000 | 1198 | |
1185 | case CPU_AU1000: | ||
1186 | num_ifs = 2 - ni; | ||
1187 | iflist[0].base_addr = AU1000_ETH0_BASE; | ||
1188 | iflist[1].base_addr = AU1000_ETH1_BASE; | ||
1189 | iflist[0].macen_addr = AU1000_MAC0_ENABLE; | ||
1190 | iflist[1].macen_addr = AU1000_MAC1_ENABLE; | ||
1191 | iflist[0].irq = AU1000_MAC0_DMA_INT; | ||
1192 | iflist[1].irq = AU1000_MAC1_DMA_INT; | ||
1193 | break; | ||
1194 | #endif | ||
1195 | #ifdef CONFIG_SOC_AU1100 | ||
1196 | case CPU_AU1100: | ||
1197 | num_ifs = 1 - ni; | ||
1198 | iflist[0].base_addr = AU1100_ETH0_BASE; | ||
1199 | iflist[0].macen_addr = AU1100_MAC0_ENABLE; | ||
1200 | iflist[0].irq = AU1100_MAC0_DMA_INT; | ||
1201 | break; | ||
1202 | #endif | ||
1203 | #ifdef CONFIG_SOC_AU1500 | ||
1204 | case CPU_AU1500: | ||
1205 | num_ifs = 2 - ni; | ||
1206 | iflist[0].base_addr = AU1500_ETH0_BASE; | ||
1207 | iflist[1].base_addr = AU1500_ETH1_BASE; | ||
1208 | iflist[0].macen_addr = AU1500_MAC0_ENABLE; | ||
1209 | iflist[1].macen_addr = AU1500_MAC1_ENABLE; | ||
1210 | iflist[0].irq = AU1500_MAC0_DMA_INT; | ||
1211 | iflist[1].irq = AU1500_MAC1_DMA_INT; | ||
1212 | break; | ||
1213 | #endif | ||
1214 | #ifdef CONFIG_SOC_AU1550 | ||
1215 | case CPU_AU1550: | ||
1216 | num_ifs = 2 - ni; | ||
1217 | iflist[0].base_addr = AU1550_ETH0_BASE; | ||
1218 | iflist[1].base_addr = AU1550_ETH1_BASE; | ||
1219 | iflist[0].macen_addr = AU1550_MAC0_ENABLE; | ||
1220 | iflist[1].macen_addr = AU1550_MAC1_ENABLE; | ||
1221 | iflist[0].irq = AU1550_MAC0_DMA_INT; | ||
1222 | iflist[1].irq = AU1550_MAC1_DMA_INT; | ||
1223 | break; | ||
1224 | #endif | ||
1225 | default: | ||
1226 | num_ifs = 0; | ||
1227 | } | ||
1228 | for(i = 0; i < num_ifs; i++) { | 1199 | for(i = 0; i < num_ifs; i++) { |
1229 | dev = au1000_probe(iflist[i].base_addr, iflist[i].irq, i); | 1200 | dev = au1000_probe(i); |
1230 | iflist[i].dev = dev; | 1201 | iflist[i].dev = dev; |
1231 | if (dev) | 1202 | if (dev) |
1232 | found_one++; | 1203 | found_one++; |
@@ -1435,8 +1406,7 @@ static struct ethtool_ops au1000_ethtool_ops = { | |||
1435 | .get_link = au1000_get_link | 1406 | .get_link = au1000_get_link |
1436 | }; | 1407 | }; |
1437 | 1408 | ||
1438 | static struct net_device * | 1409 | static struct net_device * au1000_probe(int port_num) |
1439 | au1000_probe(u32 ioaddr, int irq, int port_num) | ||
1440 | { | 1410 | { |
1441 | static unsigned version_printed = 0; | 1411 | static unsigned version_printed = 0; |
1442 | struct au1000_private *aup = NULL; | 1412 | struct au1000_private *aup = NULL; |
@@ -1444,94 +1414,95 @@ au1000_probe(u32 ioaddr, int irq, int port_num) | |||
1444 | db_dest_t *pDB, *pDBfree; | 1414 | db_dest_t *pDB, *pDBfree; |
1445 | char *pmac, *argptr; | 1415 | char *pmac, *argptr; |
1446 | char ethaddr[6]; | 1416 | char ethaddr[6]; |
1447 | int i, err; | 1417 | int irq, i, err; |
1418 | u32 base, macen; | ||
1419 | |||
1420 | if (port_num >= NUM_ETH_INTERFACES) | ||
1421 | return NULL; | ||
1448 | 1422 | ||
1449 | if (!request_mem_region(CPHYSADDR(ioaddr), MAC_IOSIZE, "Au1x00 ENET")) | 1423 | base = CPHYSADDR(iflist[port_num].base_addr ); |
1424 | macen = CPHYSADDR(iflist[port_num].macen_addr); | ||
1425 | irq = iflist[port_num].irq; | ||
1426 | |||
1427 | if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") || | ||
1428 | !request_mem_region(macen, 4, "Au1x00 ENET")) | ||
1450 | return NULL; | 1429 | return NULL; |
1451 | 1430 | ||
1452 | if (version_printed++ == 0) | 1431 | if (version_printed++ == 0) |
1453 | printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR); | 1432 | printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR); |
1454 | 1433 | ||
1455 | dev = alloc_etherdev(sizeof(struct au1000_private)); | 1434 | dev = alloc_etherdev(sizeof(struct au1000_private)); |
1456 | if (!dev) { | 1435 | if (!dev) { |
1457 | printk (KERN_ERR "au1000 eth: alloc_etherdev failed\n"); | 1436 | printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME); |
1458 | return NULL; | 1437 | return NULL; |
1459 | } | 1438 | } |
1460 | 1439 | ||
1461 | if ((err = register_netdev(dev))) { | 1440 | if ((err = register_netdev(dev)) != 0) { |
1462 | printk(KERN_ERR "Au1x_eth Cannot register net device err %d\n", | 1441 | printk(KERN_ERR "%s: Cannot register net device, error %d\n", |
1463 | err); | 1442 | DRV_NAME, err); |
1464 | free_netdev(dev); | 1443 | free_netdev(dev); |
1465 | return NULL; | 1444 | return NULL; |
1466 | } | 1445 | } |
1467 | 1446 | ||
1468 | printk("%s: Au1x Ethernet found at 0x%x, irq %d\n", | 1447 | printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n", |
1469 | dev->name, ioaddr, irq); | 1448 | dev->name, base, irq); |
1470 | 1449 | ||
1471 | aup = dev->priv; | 1450 | aup = dev->priv; |
1472 | 1451 | ||
1473 | /* Allocate the data buffers */ | 1452 | /* Allocate the data buffers */ |
1474 | /* Snooping works fine with eth on all au1xxx */ | 1453 | /* Snooping works fine with eth on all au1xxx */ |
1475 | aup->vaddr = (u32)dma_alloc_noncoherent(NULL, | 1454 | aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE * |
1476 | MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS), | 1455 | (NUM_TX_BUFFS + NUM_RX_BUFFS), |
1477 | &aup->dma_addr, | 1456 | &aup->dma_addr, 0); |
1478 | 0); | ||
1479 | if (!aup->vaddr) { | 1457 | if (!aup->vaddr) { |
1480 | free_netdev(dev); | 1458 | free_netdev(dev); |
1481 | release_mem_region(CPHYSADDR(ioaddr), MAC_IOSIZE); | 1459 | release_mem_region( base, MAC_IOSIZE); |
1460 | release_mem_region(macen, 4); | ||
1482 | return NULL; | 1461 | return NULL; |
1483 | } | 1462 | } |
1484 | 1463 | ||
1485 | /* aup->mac is the base address of the MAC's registers */ | 1464 | /* aup->mac is the base address of the MAC's registers */ |
1486 | aup->mac = (volatile mac_reg_t *)((unsigned long)ioaddr); | 1465 | aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr; |
1466 | |||
1487 | /* Setup some variables for quick register address access */ | 1467 | /* Setup some variables for quick register address access */ |
1488 | if (ioaddr == iflist[0].base_addr) | 1468 | aup->enable = (volatile u32 *)iflist[port_num].macen_addr; |
1489 | { | 1469 | aup->mac_id = port_num; |
1490 | /* check env variables first */ | 1470 | au_macs[port_num] = aup; |
1491 | if (!get_ethernet_addr(ethaddr)) { | 1471 | |
1472 | if (port_num == 0) { | ||
1473 | /* Check the environment variables first */ | ||
1474 | if (get_ethernet_addr(ethaddr) == 0) | ||
1492 | memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr)); | 1475 | memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr)); |
1493 | } else { | 1476 | else { |
1494 | /* Check command line */ | 1477 | /* Check command line */ |
1495 | argptr = prom_getcmdline(); | 1478 | argptr = prom_getcmdline(); |
1496 | if ((pmac = strstr(argptr, "ethaddr=")) == NULL) { | 1479 | if ((pmac = strstr(argptr, "ethaddr=")) == NULL) |
1497 | printk(KERN_INFO "%s: No mac address found\n", | 1480 | printk(KERN_INFO "%s: No MAC address found\n", |
1498 | dev->name); | 1481 | dev->name); |
1499 | /* use the hard coded mac addresses */ | 1482 | /* Use the hard coded MAC addresses */ |
1500 | } else { | 1483 | else { |
1501 | str2eaddr(ethaddr, pmac + strlen("ethaddr=")); | 1484 | str2eaddr(ethaddr, pmac + strlen("ethaddr=")); |
1502 | memcpy(au1000_mac_addr, ethaddr, | 1485 | memcpy(au1000_mac_addr, ethaddr, |
1503 | sizeof(au1000_mac_addr)); | 1486 | sizeof(au1000_mac_addr)); |
1504 | } | 1487 | } |
1505 | } | 1488 | } |
1506 | aup->enable = (volatile u32 *) | 1489 | |
1507 | ((unsigned long)iflist[0].macen_addr); | ||
1508 | memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); | ||
1509 | setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); | 1490 | setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); |
1510 | aup->mac_id = 0; | 1491 | } else if (port_num == 1) |
1511 | au_macs[0] = aup; | ||
1512 | } | ||
1513 | else | ||
1514 | if (ioaddr == iflist[1].base_addr) | ||
1515 | { | ||
1516 | aup->enable = (volatile u32 *) | ||
1517 | ((unsigned long)iflist[1].macen_addr); | ||
1518 | memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); | ||
1519 | dev->dev_addr[4] += 0x10; | ||
1520 | setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR); | 1492 | setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR); |
1521 | aup->mac_id = 1; | ||
1522 | au_macs[1] = aup; | ||
1523 | } | ||
1524 | else | ||
1525 | { | ||
1526 | printk(KERN_ERR "%s: bad ioaddr\n", dev->name); | ||
1527 | } | ||
1528 | 1493 | ||
1529 | /* bring the device out of reset, otherwise probing the mii | 1494 | /* |
1530 | * will hang */ | 1495 | * Assign to the Ethernet ports two consecutive MAC addresses |
1496 | * to match those that are printed on their stickers | ||
1497 | */ | ||
1498 | memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); | ||
1499 | dev->dev_addr[5] += port_num; | ||
1500 | |||
1501 | /* Bring the device out of reset, otherwise probing the MII will hang */ | ||
1531 | *aup->enable = MAC_EN_CLOCK_ENABLE; | 1502 | *aup->enable = MAC_EN_CLOCK_ENABLE; |
1532 | au_sync_delay(2); | 1503 | au_sync_delay(2); |
1533 | *aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | | 1504 | *aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 | |
1534 | MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE; | 1505 | MAC_EN_CLOCK_ENABLE; |
1535 | au_sync_delay(2); | 1506 | au_sync_delay(2); |
1536 | 1507 | ||
1537 | aup->mii = kmalloc(sizeof(struct mii_phy), GFP_KERNEL); | 1508 | aup->mii = kmalloc(sizeof(struct mii_phy), GFP_KERNEL); |
@@ -1580,7 +1551,7 @@ au1000_probe(u32 ioaddr, int irq, int port_num) | |||
1580 | } | 1551 | } |
1581 | 1552 | ||
1582 | spin_lock_init(&aup->lock); | 1553 | spin_lock_init(&aup->lock); |
1583 | dev->base_addr = ioaddr; | 1554 | dev->base_addr = base; |
1584 | dev->irq = irq; | 1555 | dev->irq = irq; |
1585 | dev->open = au1000_open; | 1556 | dev->open = au1000_open; |
1586 | dev->hard_start_xmit = au1000_tx; | 1557 | dev->hard_start_xmit = au1000_tx; |
@@ -1614,13 +1585,12 @@ err_out: | |||
1614 | if (aup->tx_db_inuse[i]) | 1585 | if (aup->tx_db_inuse[i]) |
1615 | ReleaseDB(aup, aup->tx_db_inuse[i]); | 1586 | ReleaseDB(aup, aup->tx_db_inuse[i]); |
1616 | } | 1587 | } |
1617 | dma_free_noncoherent(NULL, | 1588 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS), |
1618 | MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS), | 1589 | (void *)aup->vaddr, aup->dma_addr); |
1619 | (void *)aup->vaddr, | ||
1620 | aup->dma_addr); | ||
1621 | unregister_netdev(dev); | 1590 | unregister_netdev(dev); |
1622 | free_netdev(dev); | 1591 | free_netdev(dev); |
1623 | release_mem_region(CPHYSADDR(ioaddr), MAC_IOSIZE); | 1592 | release_mem_region( base, MAC_IOSIZE); |
1593 | release_mem_region(macen, 4); | ||
1624 | return NULL; | 1594 | return NULL; |
1625 | } | 1595 | } |
1626 | 1596 | ||
@@ -1805,20 +1775,18 @@ static void __exit au1000_cleanup_module(void) | |||
1805 | aup = (struct au1000_private *) dev->priv; | 1775 | aup = (struct au1000_private *) dev->priv; |
1806 | unregister_netdev(dev); | 1776 | unregister_netdev(dev); |
1807 | kfree(aup->mii); | 1777 | kfree(aup->mii); |
1808 | for (j = 0; j < NUM_RX_DMA; j++) { | 1778 | for (j = 0; j < NUM_RX_DMA; j++) |
1809 | if (aup->rx_db_inuse[j]) | 1779 | if (aup->rx_db_inuse[j]) |
1810 | ReleaseDB(aup, aup->rx_db_inuse[j]); | 1780 | ReleaseDB(aup, aup->rx_db_inuse[j]); |
1811 | } | 1781 | for (j = 0; j < NUM_TX_DMA; j++) |
1812 | for (j = 0; j < NUM_TX_DMA; j++) { | ||
1813 | if (aup->tx_db_inuse[j]) | 1782 | if (aup->tx_db_inuse[j]) |
1814 | ReleaseDB(aup, aup->tx_db_inuse[j]); | 1783 | ReleaseDB(aup, aup->tx_db_inuse[j]); |
1815 | } | 1784 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * |
1816 | dma_free_noncoherent(NULL, | 1785 | (NUM_TX_BUFFS + NUM_RX_BUFFS), |
1817 | MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS), | 1786 | (void *)aup->vaddr, aup->dma_addr); |
1818 | (void *)aup->vaddr, | 1787 | release_mem_region(dev->base_addr, MAC_IOSIZE); |
1819 | aup->dma_addr); | 1788 | release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4); |
1820 | free_netdev(dev); | 1789 | free_netdev(dev); |
1821 | release_mem_region(CPHYSADDR(iflist[i].base_addr), MAC_IOSIZE); | ||
1822 | } | 1790 | } |
1823 | } | 1791 | } |
1824 | } | 1792 | } |