aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sundance.c
diff options
context:
space:
mode:
authorJesse Huang <jesse@icplus.com.tw>2006-11-08 22:49:12 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-02 00:12:03 -0500
commit31f817e9d6f325b10a316bb84237cae3739487ed (patch)
treece02e27d3e6c7d6c0083b06462b82758c6f02f51 /drivers/net/sundance.c
parentd0bb53e102e10cc90de50953531a163d95da1e07 (diff)
[PATCH] sundance: solve host error problem in low performance embedded system when continune down and up
Solve host error problem in low performance embedded system when continune down and up. It will cause IP100A DMA TargetAbort. So we need more safe process to up and down IP100A with wait hardware completely stop and software cur_tx/ dirty_tx/cur_task/last_tx be clear. Signed-off-by: Jesse Huang <jesse@icplus.com.tw> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/sundance.c')
-rw-r--r--drivers/net/sundance.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index fba64d39ba19..02679e688c4c 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -1642,6 +1642,14 @@ static int netdev_close(struct net_device *dev)
1642 struct sk_buff *skb; 1642 struct sk_buff *skb;
1643 int i; 1643 int i;
1644 1644
1645 /* Wait and kill tasklet */
1646 tasklet_kill(&np->rx_tasklet);
1647 tasklet_kill(&np->tx_tasklet);
1648 np->cur_tx = 0;
1649 np->dirty_tx = 0;
1650 np->cur_task = 0;
1651 np->last_tx = 0;
1652
1645 netif_stop_queue(dev); 1653 netif_stop_queue(dev);
1646 1654
1647 if (netif_msg_ifdown(np)) { 1655 if (netif_msg_ifdown(np)) {
@@ -1662,9 +1670,20 @@ static int netdev_close(struct net_device *dev)
1662 /* Stop the chip's Tx and Rx processes. */ 1670 /* Stop the chip's Tx and Rx processes. */
1663 iowrite16(TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl1); 1671 iowrite16(TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl1);
1664 1672
1665 /* Wait and kill tasklet */ 1673 for (i = 2000; i > 0; i--) {
1666 tasklet_kill(&np->rx_tasklet); 1674 if ((ioread32(ioaddr + DMACtrl) & 0xc000) == 0)
1667 tasklet_kill(&np->tx_tasklet); 1675 break;
1676 mdelay(1);
1677 }
1678
1679 iowrite16(GlobalReset | DMAReset | FIFOReset | NetworkReset,
1680 ioaddr +ASICCtrl + 2);
1681
1682 for (i = 2000; i > 0; i--) {
1683 if ((ioread16(ioaddr + ASICCtrl +2) & ResetBusy) == 0)
1684 break;
1685 mdelay(1);
1686 }
1668 1687
1669#ifdef __i386__ 1688#ifdef __i386__
1670 if (netif_msg_hw(np)) { 1689 if (netif_msg_hw(np)) {
@@ -1702,6 +1721,7 @@ static int netdev_close(struct net_device *dev)
1702 } 1721 }
1703 } 1722 }
1704 for (i = 0; i < TX_RING_SIZE; i++) { 1723 for (i = 0; i < TX_RING_SIZE; i++) {
1724 np->tx_ring[i].next_desc = 0;
1705 skb = np->tx_skbuff[i]; 1725 skb = np->tx_skbuff[i];
1706 if (skb) { 1726 if (skb) {
1707 pci_unmap_single(np->pci_dev, 1727 pci_unmap_single(np->pci_dev,