diff options
| author | Don Fry <brazilnut@us.ibm.com> | 2006-06-29 16:55:27 -0400 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2006-07-05 14:07:15 -0400 |
| commit | ac5bfe40f94cc8df512d247a5588897b0bc6dbea (patch) | |
| tree | 04f03610d663f751782a3f4b9c8c51091c321033 | |
| parent | df27f4a610e22e8c8c740286368cc13e0600f22c (diff) | |
[PATCH] pcnet32: Cleanup rx buffers after loopback test.
More cleanup to pcnet32_loopback_test to release receive buffers if
device is not up. Created common routine to free rx buffers.
Tested ia32 and ppc64
Signed-off-by: Don Fry <brazilnut@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
| -rw-r--r-- | drivers/net/pcnet32.c | 102 |
1 files changed, 43 insertions, 59 deletions
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index fe0558242835..4daafe303358 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
| @@ -645,6 +645,25 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, | |||
| 645 | return; | 645 | return; |
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | static void pcnet32_purge_rx_ring(struct net_device *dev) | ||
| 649 | { | ||
| 650 | struct pcnet32_private *lp = dev->priv; | ||
| 651 | int i; | ||
| 652 | |||
| 653 | /* free all allocated skbuffs */ | ||
| 654 | for (i = 0; i < lp->rx_ring_size; i++) { | ||
| 655 | lp->rx_ring[i].status = 0; /* CPU owns buffer */ | ||
| 656 | wmb(); /* Make sure adapter sees owner change */ | ||
| 657 | if (lp->rx_skbuff[i]) { | ||
| 658 | pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], | ||
| 659 | PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); | ||
| 660 | dev_kfree_skb_any(lp->rx_skbuff[i]); | ||
| 661 | } | ||
| 662 | lp->rx_skbuff[i] = NULL; | ||
| 663 | lp->rx_dma_addr[i] = 0; | ||
| 664 | } | ||
| 665 | } | ||
| 666 | |||
| 648 | #ifdef CONFIG_NET_POLL_CONTROLLER | 667 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 649 | static void pcnet32_poll_controller(struct net_device *dev) | 668 | static void pcnet32_poll_controller(struct net_device *dev) |
| 650 | { | 669 | { |
| @@ -856,29 +875,27 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) | |||
| 856 | unsigned long flags; | 875 | unsigned long flags; |
| 857 | unsigned long ticks; | 876 | unsigned long ticks; |
| 858 | 877 | ||
| 859 | *data1 = 1; /* status of test, default to fail */ | ||
| 860 | rc = 1; /* default to fail */ | 878 | rc = 1; /* default to fail */ |
| 861 | 879 | ||
| 862 | if (netif_running(dev)) | 880 | if (netif_running(dev)) |
| 863 | pcnet32_close(dev); | 881 | pcnet32_close(dev); |
| 864 | 882 | ||
| 865 | spin_lock_irqsave(&lp->lock, flags); | 883 | spin_lock_irqsave(&lp->lock, flags); |
| 884 | lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); /* stop the chip */ | ||
| 885 | |||
| 886 | numbuffs = min(numbuffs, (int)min(lp->rx_ring_size, lp->tx_ring_size)); | ||
| 866 | 887 | ||
| 867 | /* Reset the PCNET32 */ | 888 | /* Reset the PCNET32 */ |
| 868 | lp->a.reset(ioaddr); | 889 | lp->a.reset(ioaddr); |
| 890 | lp->a.write_csr(ioaddr, CSR4, 0x0915); | ||
| 869 | 891 | ||
| 870 | /* switch pcnet32 to 32bit mode */ | 892 | /* switch pcnet32 to 32bit mode */ |
| 871 | lp->a.write_bcr(ioaddr, 20, 2); | 893 | lp->a.write_bcr(ioaddr, 20, 2); |
| 872 | 894 | ||
| 873 | lp->init_block.mode = | ||
| 874 | le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); | ||
| 875 | lp->init_block.filter[0] = 0; | ||
| 876 | lp->init_block.filter[1] = 0; | ||
| 877 | |||
| 878 | /* purge & init rings but don't actually restart */ | 895 | /* purge & init rings but don't actually restart */ |
| 879 | pcnet32_restart(dev, 0x0000); | 896 | pcnet32_restart(dev, 0x0000); |
| 880 | 897 | ||
| 881 | lp->a.write_csr(ioaddr, 0, 0x0004); /* Set STOP bit */ | 898 | lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); /* Set STOP bit */ |
| 882 | 899 | ||
| 883 | /* Initialize Transmit buffers. */ | 900 | /* Initialize Transmit buffers. */ |
| 884 | size = data_len + 15; | 901 | size = data_len + 15; |
| @@ -920,14 +937,15 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) | |||
| 920 | } | 937 | } |
| 921 | } | 938 | } |
| 922 | 939 | ||
| 923 | x = a->read_bcr(ioaddr, 32); /* set internal loopback in BSR32 */ | 940 | x = a->read_bcr(ioaddr, 32); /* set internal loopback in BCR32 */ |
| 924 | x = x | 0x0002; | 941 | a->write_bcr(ioaddr, 32, x | 0x0002); |
| 925 | a->write_bcr(ioaddr, 32, x); | ||
| 926 | 942 | ||
| 927 | lp->a.write_csr(ioaddr, 15, 0x0044); /* set int loopback in CSR15 */ | 943 | /* set int loopback in CSR15 */ |
| 944 | x = a->read_csr(ioaddr, CSR15) & 0xfffc; | ||
| 945 | lp->a.write_csr(ioaddr, CSR15, x | 0x0044); | ||
| 928 | 946 | ||
| 929 | teststatus = le16_to_cpu(0x8000); | 947 | teststatus = le16_to_cpu(0x8000); |
| 930 | lp->a.write_csr(ioaddr, 0, 0x0002); /* Set STRT bit */ | 948 | lp->a.write_csr(ioaddr, CSR0, CSR0_START); /* Set STRT bit */ |
| 931 | 949 | ||
| 932 | /* Check status of descriptors */ | 950 | /* Check status of descriptors */ |
| 933 | for (x = 0; x < numbuffs; x++) { | 951 | for (x = 0; x < numbuffs; x++) { |
| @@ -935,7 +953,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) | |||
| 935 | rmb(); | 953 | rmb(); |
| 936 | while ((lp->rx_ring[x].status & teststatus) && (ticks < 200)) { | 954 | while ((lp->rx_ring[x].status & teststatus) && (ticks < 200)) { |
| 937 | spin_unlock_irqrestore(&lp->lock, flags); | 955 | spin_unlock_irqrestore(&lp->lock, flags); |
| 938 | mdelay(1); | 956 | msleep(1); |
| 939 | spin_lock_irqsave(&lp->lock, flags); | 957 | spin_lock_irqsave(&lp->lock, flags); |
| 940 | rmb(); | 958 | rmb(); |
| 941 | ticks++; | 959 | ticks++; |
| @@ -948,7 +966,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) | |||
| 948 | } | 966 | } |
| 949 | } | 967 | } |
| 950 | 968 | ||
| 951 | lp->a.write_csr(ioaddr, 0, 0x0004); /* Set STOP bit */ | 969 | lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); /* Set STOP bit */ |
| 952 | wmb(); | 970 | wmb(); |
| 953 | if (netif_msg_hw(lp) && netif_msg_pktdata(lp)) { | 971 | if (netif_msg_hw(lp) && netif_msg_pktdata(lp)) { |
| 954 | printk(KERN_DEBUG "%s: RX loopback packets:\n", dev->name); | 972 | printk(KERN_DEBUG "%s: RX loopback packets:\n", dev->name); |
| @@ -981,25 +999,24 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) | |||
| 981 | } | 999 | } |
| 982 | x++; | 1000 | x++; |
| 983 | } | 1001 | } |
| 984 | if (!rc) { | ||
| 985 | *data1 = 0; | ||
| 986 | } | ||
| 987 | 1002 | ||
| 988 | clean_up: | 1003 | clean_up: |
| 1004 | *data1 = rc; | ||
| 989 | pcnet32_purge_tx_ring(dev); | 1005 | pcnet32_purge_tx_ring(dev); |
| 990 | x = a->read_csr(ioaddr, 15) & 0xFFFF; | ||
| 991 | a->write_csr(ioaddr, 15, (x & ~0x0044)); /* reset bits 6 and 2 */ | ||
| 992 | 1006 | ||
| 993 | x = a->read_bcr(ioaddr, 32); /* reset internal loopback */ | 1007 | x = a->read_csr(ioaddr, CSR15); |
| 994 | x = x & ~0x0002; | 1008 | a->write_csr(ioaddr, CSR15, (x & ~0x0044)); /* reset bits 6 and 2 */ |
| 995 | a->write_bcr(ioaddr, 32, x); | ||
| 996 | 1009 | ||
| 997 | spin_unlock_irqrestore(&lp->lock, flags); | 1010 | x = a->read_bcr(ioaddr, 32); /* reset internal loopback */ |
| 1011 | a->write_bcr(ioaddr, 32, (x & ~0x0002)); | ||
| 998 | 1012 | ||
| 999 | if (netif_running(dev)) { | 1013 | if (netif_running(dev)) { |
| 1014 | spin_unlock_irqrestore(&lp->lock, flags); | ||
| 1000 | pcnet32_open(dev); | 1015 | pcnet32_open(dev); |
| 1001 | } else { | 1016 | } else { |
| 1017 | pcnet32_purge_rx_ring(dev); | ||
| 1002 | lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */ | 1018 | lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */ |
| 1019 | spin_unlock_irqrestore(&lp->lock, flags); | ||
| 1003 | } | 1020 | } |
| 1004 | 1021 | ||
| 1005 | return (rc); | 1022 | return (rc); |
| @@ -1997,16 +2014,7 @@ static int pcnet32_open(struct net_device *dev) | |||
| 1997 | 2014 | ||
| 1998 | err_free_ring: | 2015 | err_free_ring: |
| 1999 | /* free any allocated skbuffs */ | 2016 | /* free any allocated skbuffs */ |
| 2000 | for (i = 0; i < lp->rx_ring_size; i++) { | 2017 | pcnet32_purge_rx_ring(dev); |
| 2001 | lp->rx_ring[i].status = 0; | ||
| 2002 | if (lp->rx_skbuff[i]) { | ||
| 2003 | pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], | ||
| 2004 | PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); | ||
| 2005 | dev_kfree_skb(lp->rx_skbuff[i]); | ||
| 2006 | } | ||
| 2007 | lp->rx_skbuff[i] = NULL; | ||
| 2008 | lp->rx_dma_addr[i] = 0; | ||
| 2009 | } | ||
| 2010 | 2018 | ||
| 2011 | /* | 2019 | /* |
| 2012 | * Switch back to 16bit mode to avoid problems with dumb | 2020 | * Switch back to 16bit mode to avoid problems with dumb |
| @@ -2588,7 +2596,6 @@ static int pcnet32_close(struct net_device *dev) | |||
| 2588 | { | 2596 | { |
| 2589 | unsigned long ioaddr = dev->base_addr; | 2597 | unsigned long ioaddr = dev->base_addr; |
| 2590 | struct pcnet32_private *lp = dev->priv; | 2598 | struct pcnet32_private *lp = dev->priv; |
| 2591 | int i; | ||
| 2592 | unsigned long flags; | 2599 | unsigned long flags; |
| 2593 | 2600 | ||
| 2594 | del_timer_sync(&lp->watchdog_timer); | 2601 | del_timer_sync(&lp->watchdog_timer); |
| @@ -2619,31 +2626,8 @@ static int pcnet32_close(struct net_device *dev) | |||
| 2619 | 2626 | ||
| 2620 | spin_lock_irqsave(&lp->lock, flags); | 2627 | spin_lock_irqsave(&lp->lock, flags); |
| 2621 | 2628 | ||
| 2622 | /* free all allocated skbuffs */ | 2629 | pcnet32_purge_rx_ring(dev); |
| 2623 | for (i = 0; i < lp->rx_ring_size; i++) { | 2630 | pcnet32_purge_tx_ring(dev); |
| 2624 | lp->rx_ring[i].status = 0; | ||
| 2625 | wmb(); /* Make sure adapter sees owner change */ | ||
| 2626 | if (lp->rx_skbuff[i]) { | ||
| 2627 | pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], | ||
| 2628 | PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); | ||
| 2629 | dev_kfree_skb(lp->rx_skbuff[i]); | ||
| 2630 | } | ||
| 2631 | lp->rx_skbuff[i] = NULL; | ||
| 2632 | lp->rx_dma_addr[i] = 0; | ||
| 2633 | } | ||
| 2634 | |||
| 2635 | for (i = 0; i < lp->tx_ring_size; i++) { | ||
| 2636 | lp->tx_ring[i].status = 0; /* CPU owns buffer */ | ||
| 2637 | wmb(); /* Make sure adapter sees owner change */ | ||
| 2638 | if (lp->tx_skbuff[i]) { | ||
| 2639 | pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i], | ||
| 2640 | lp->tx_skbuff[i]->len, | ||
| 2641 | PCI_DMA_TODEVICE); | ||
| 2642 | dev_kfree_skb(lp->tx_skbuff[i]); | ||
| 2643 | } | ||
| 2644 | lp->tx_skbuff[i] = NULL; | ||
| 2645 | lp->tx_dma_addr[i] = 0; | ||
| 2646 | } | ||
| 2647 | 2631 | ||
| 2648 | spin_unlock_irqrestore(&lp->lock, flags); | 2632 | spin_unlock_irqrestore(&lp->lock, flags); |
| 2649 | 2633 | ||
