aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcnet32.c
diff options
context:
space:
mode:
authorDon Fry <brazilnut@us.ibm.com>2006-06-29 16:55:27 -0400
committerJeff Garzik <jeff@garzik.org>2006-07-05 14:07:15 -0400
commitac5bfe40f94cc8df512d247a5588897b0bc6dbea (patch)
tree04f03610d663f751782a3f4b9c8c51091c321033 /drivers/net/pcnet32.c
parentdf27f4a610e22e8c8c740286368cc13e0600f22c (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>
Diffstat (limited to 'drivers/net/pcnet32.c')
-rw-r--r--drivers/net/pcnet32.c102
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
648static 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
649static void pcnet32_poll_controller(struct net_device *dev) 668static 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