Index: drivers/net/tulip/interrupt.c =================================================================== RCS file: /var/cvs/linux-2.6/drivers/net/tulip/interrupt.c,v retrieving revision 1.11 diff -u -p -r1.11 interrupt.c --- drivers/net/tulip/interrupt.c 30 Jun 2005 14:25:46 -0000 1.11 +++ drivers/net/tulip/interrupt.c 30 May 2006 06:41:13 -0000 @@ -88,6 +88,10 @@ int tulip_refill_rx(struct net_device *d } tp->rx_ring[entry].status = cpu_to_le32(DescOwned); } + +/* FIXME: restarting DMA breaks tulip_down() code path. + tulip_down() will unmap the RX and TX descriptors. + */ if(tp->chip_id == LC82C168) { if(((ioread32(tp->base_addr + CSR5)>>17)&0x07) == 4) { /* Rx stopped due to out of buffers, Index: drivers/net/tulip/tulip.h =================================================================== RCS file: /var/cvs/linux-2.6/drivers/net/tulip/tulip.h,v retrieving revision 1.15 diff -u -p -r1.15 tulip.h --- drivers/net/tulip/tulip.h 14 Sep 2005 12:56:25 -0000 1.15 +++ drivers/net/tulip/tulip.h 30 May 2006 06:41:13 -0000 @@ -31,11 +31,10 @@ /* undefine, or define to various debugging levels (>4 == obscene levels) */ #define TULIP_DEBUG 1 -/* undefine USE_IO_OPS for MMIO, define for PIO */ #ifdef CONFIG_TULIP_MMIO -# undef USE_IO_OPS +#define TULIP_BAR 1 /* CBMA */ #else -# define USE_IO_OPS 1 +#define TULIP_BAR 0 /* CBIO */ #endif @@ -143,6 +142,7 @@ enum status_bits { RxNoBuf = 0x80, RxIntr = 0x40, TxFIFOUnderflow = 0x20, + RxErrIntr = 0x10, TxJabber = 0x08, TxNoBuf = 0x04, TxDied = 0x02, @@ -193,9 +193,14 @@ struct tulip_tx_desc { enum desc_status_bits { - DescOwned = 0x80000000, - RxDescFatalErr = 0x8000, - RxWholePkt = 0x0300, + DescOwned = 0x80000000, + DescWholePkt = 0x60000000, + DescEndPkt = 0x40000000, + DescStartPkt = 0x20000000, + DescEndRing = 0x02000000, + DescUseLink = 0x01000000, + RxDescFatalErr = 0x008000, + RxWholePkt = 0x00000300, }; Index: drivers/net/tulip/tulip_core.c =================================================================== RCS file: /var/cvs/linux-2.6/drivers/net/tulip/tulip_core.c,v retrieving revision 1.35 diff -u -p -r1.35 tulip_core.c --- drivers/net/tulip/tulip_core.c 23 Apr 2006 15:18:28 -0000 1.35 +++ drivers/net/tulip/tulip_core.c 30 May 2006 06:41:13 -0000 @@ -18,11 +18,11 @@ #define DRV_NAME "tulip" #ifdef CONFIG_TULIP_NAPI -#define DRV_VERSION "1.1.13-NAPI" /* Keep at least for test */ +#define DRV_VERSION "1.1.14-NAPI" /* Keep at least for test */ #else -#define DRV_VERSION "1.1.13" +#define DRV_VERSION "1.1.14" #endif -#define DRV_RELDATE "December 15, 2004" +#define DRV_RELDATE "May 6, 2006" #include @@ -296,12 +296,14 @@ static void tulip_up(struct net_device * /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */ iowrite32(0x00000001, ioaddr + CSR0); + pci_read_config_dword(tp->pdev, PCI_COMMAND, &i); /* flush write */ udelay(100); /* Deassert reset. Wait the specified 50 PCI cycles after a reset by initializing Tx and Rx queues and the address filter list. */ iowrite32(tp->csr0, ioaddr + CSR0); + pci_read_config_dword(tp->pdev, PCI_COMMAND, &i); /* flush write */ udelay(100); if (tulip_debug > 1) @@ -774,14 +776,13 @@ static int tulip_close (struct net_devic int i; netif_stop_queue (dev); - + free_irq (dev->irq, dev); /* don't let IRQs race w/tulip_down() */ tulip_down (dev); if (tulip_debug > 1) printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", dev->name, ioread32 (ioaddr + CSR5)); - free_irq (dev->irq, dev); /* Free all the skbuffs in the Rx queue. */ for (i = 0; i < RX_RING_SIZE; i++) { @@ -1362,11 +1363,8 @@ static int __devinit tulip_init_one (str if (pci_request_regions (pdev, "tulip")) goto err_out_free_netdev; -#ifndef USE_IO_OPS - ioaddr = pci_iomap(pdev, 1, tulip_tbl[chip_idx].io_size); -#else - ioaddr = pci_iomap(pdev, 0, tulip_tbl[chip_idx].io_size); -#endif + ioaddr = pci_iomap(pdev, TULIP_BAR, tulip_tbl[chip_idx].io_size); + if (!ioaddr) goto err_out_free_res; @@ -1649,8 +1647,14 @@ static int __devinit tulip_init_one (str if (register_netdev(dev)) goto err_out_free_ring; - printk(KERN_INFO "%s: %s rev %d at %p,", - dev->name, chip_name, chip_rev, ioaddr); + printk(KERN_INFO "%s: %s rev %d at " +#ifdef CONFIG_TULIP_MMIO + "MMIO" +#else + "Port" +#endif + " 0x%lx,", dev->name, chip_name, chip_rev, + pci_resource_start(pdev,TULIP_BAR) ); pci_set_drvdata(pdev, dev); if (eeprom_missing) Index: drivers/net/tulip/winbond-840.c =================================================================== RCS file: /var/cvs/linux-2.6/drivers/net/tulip/winbond-840.c,v retrieving revision 1.16 diff -u -p -r1.16 winbond-840.c --- drivers/net/tulip/winbond-840.c 27 May 2006 16:30:11 -0000 1.16 +++ drivers/net/tulip/winbond-840.c 30 May 2006 06:41:13 -0000 @@ -90,10 +90,8 @@ static int full_duplex[MAX_UNITS] = {-1, Making the Tx ring too large decreases the effectiveness of channel bonding and packet priority. There are no ill effects from too-large receive rings. */ -#define TX_RING_SIZE 16 #define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */ #define TX_QUEUE_LEN_RESTART 5 -#define RX_RING_SIZE 32 #define TX_BUFLIMIT (1024-128) @@ -137,6 +135,8 @@ static int full_duplex[MAX_UNITS] = {-1, #include #include +#include "tulip.h" + /* These identify the driver base version and may not be removed. */ static char version[] __devinitdata = KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) " DRV_RELDATE " Donald Becker \n" @@ -221,7 +221,7 @@ enum pci_id_flags_bits { }; enum chip_capability_flags { CanHaveMII=1, HasBrokenTx=2, AlwaysFDX=4, FDXOnNoMII=8,}; -#ifdef USE_IO_OPS +#ifndef CONFIG_TULIP_MMIO #define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER) #else #define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER) @@ -257,8 +257,8 @@ static struct pci_id_info pci_id_tbl[] = }; /* This driver was written to use PCI memory space, however some x86 systems - work only with I/O space accesses. Pass -DUSE_IO_OPS to use PCI I/O space - accesses instead of memory space. */ + work only with I/O space accesses. See CONFIG_TULIP_MMIO in .config +*/ /* Offsets to the Command and Status Registers, "CSRs". While similar to the Tulip, these registers are longword aligned. @@ -276,21 +276,11 @@ enum w840_offsets { CurTxDescAddr=0x4C, CurTxBufAddr=0x50, }; -/* Bits in the interrupt status/enable registers. */ -/* The bits in the Intr Status/Enable registers, mostly interrupt sources. */ -enum intr_status_bits { - NormalIntr=0x10000, AbnormalIntr=0x8000, - IntrPCIErr=0x2000, TimerInt=0x800, - IntrRxDied=0x100, RxNoBuf=0x80, IntrRxDone=0x40, - TxFIFOUnderflow=0x20, RxErrIntr=0x10, - TxIdle=0x04, IntrTxStopped=0x02, IntrTxDone=0x01, -}; - /* Bits in the NetworkConfig register. */ enum rx_mode_bits { - AcceptErr=0x80, AcceptRunt=0x40, - AcceptBroadcast=0x20, AcceptMulticast=0x10, - AcceptAllPhys=0x08, AcceptMyPhys=0x02, + AcceptErr=0x80, + RxAcceptBroadcast=0x20, AcceptMulticast=0x10, + RxAcceptAllPhys=0x08, AcceptMyPhys=0x02, }; enum mii_reg_bits { @@ -312,13 +302,6 @@ struct w840_tx_desc { u32 buffer1, buffer2; }; -/* Bits in network_desc.status */ -enum desc_status_bits { - DescOwn=0x80000000, DescEndRing=0x02000000, DescUseLink=0x01000000, - DescWholePkt=0x60000000, DescStartPkt=0x20000000, DescEndPkt=0x40000000, - DescIntr=0x80000000, -}; - #define MII_CNT 1 /* winbond only supports one MII */ struct netdev_private { struct w840_rx_desc *rx_ring; @@ -386,7 +369,6 @@ static int __devinit w840_probe1 (struct int irq; int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0; void __iomem *ioaddr; - int bar = 1; i = pci_enable_device(pdev); if (i) return i; @@ -408,10 +390,8 @@ static int __devinit w840_probe1 (struct if (pci_request_regions(pdev, DRV_NAME)) goto err_out_netdev; -#ifdef USE_IO_OPS - bar = 0; -#endif - ioaddr = pci_iomap(pdev, bar, pci_id_tbl[chip_idx].io_size); + + ioaddr = pci_iomap(pdev, TULIP_BAR, pci_id_tbl[chip_idx].io_size); if (!ioaddr) goto err_out_free_res; @@ -853,7 +833,7 @@ static void init_rxtx_rings(struct net_d np->rx_buf_sz,PCI_DMA_FROMDEVICE); np->rx_ring[i].buffer1 = np->rx_addr[i]; - np->rx_ring[i].status = DescOwn; + np->rx_ring[i].status = DescOwned; } np->cur_rx = 0; @@ -938,7 +918,7 @@ static void init_registers(struct net_de } #elif defined(__powerpc__) || defined(__i386__) || defined(__alpha__) || defined(__ia64__) || defined(__x86_64__) i |= 0xE000; -#elif defined(__sparc__) +#elif defined(__sparc__) || defined (CONFIG_PARISC) i |= 0x4800; #else #warning Processor architecture undefined @@ -1058,11 +1038,11 @@ static int start_tx(struct sk_buff *skb, /* Now acquire the irq spinlock. * The difficult race is the the ordering between - * increasing np->cur_tx and setting DescOwn: + * increasing np->cur_tx and setting DescOwned: * - if np->cur_tx is increased first the interrupt * handler could consider the packet as transmitted - * since DescOwn is cleared. - * - If DescOwn is set first the NIC could report the + * since DescOwned is cleared. + * - If DescOwned is set first the NIC could report the * packet as sent, but the interrupt handler would ignore it * since the np->cur_tx was not yet increased. */ @@ -1070,7 +1050,7 @@ static int start_tx(struct sk_buff *skb, np->cur_tx++; wmb(); /* flush length, buffer1, buffer2 */ - np->tx_ring[entry].status = DescOwn; + np->tx_ring[entry].status = DescOwned; wmb(); /* flush status and kick the hardware */ iowrite32(0, np->base_addr + TxStartDemand); np->tx_q_bytes += skb->len; @@ -1170,12 +1150,12 @@ static irqreturn_t intr_handler(int irq, handled = 1; - if (intr_status & (IntrRxDone | RxNoBuf)) + if (intr_status & (RxIntr | RxNoBuf)) netdev_rx(dev); if (intr_status & RxNoBuf) iowrite32(0, ioaddr + RxStartDemand); - if (intr_status & (TxIdle | IntrTxDone) && + if (intr_status & (TxNoBuf | TxIntr) && np->cur_tx != np->dirty_tx) { spin_lock(&np->lock); netdev_tx_done(dev); @@ -1183,8 +1163,8 @@ static irqreturn_t intr_handler(int irq, } /* Abnormal error summary/uncommon events handlers. */ - if (intr_status & (AbnormalIntr | TxFIFOUnderflow | IntrPCIErr | - TimerInt | IntrTxStopped)) + if (intr_status & (AbnormalIntr | TxFIFOUnderflow | SytemError | + TimerInt | TxDied)) netdev_error(dev, intr_status); if (--work_limit < 0) { @@ -1320,7 +1300,7 @@ static int netdev_rx(struct net_device * np->rx_ring[entry].buffer1 = np->rx_addr[entry]; } wmb(); - np->rx_ring[entry].status = DescOwn; + np->rx_ring[entry].status = DescOwned; } return 0; @@ -1357,7 +1337,7 @@ static void netdev_error(struct net_devi dev->name, new); update_csr6(dev, new); } - if (intr_status & IntrRxDied) { /* Missed a Rx frame. */ + if (intr_status & RxDied) { /* Missed a Rx frame. */ np->stats.rx_errors++; } if (intr_status & TimerInt) { @@ -1396,13 +1376,13 @@ static u32 __set_rx_mode(struct net_devi /* Unconditionally log net taps. */ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); memset(mc_filter, 0xff, sizeof(mc_filter)); - rx_mode = AcceptBroadcast | AcceptMulticast | AcceptAllPhys + rx_mode = RxAcceptBroadcast | AcceptMulticast | RxAcceptAllPhys | AcceptMyPhys; } else if ((dev->mc_count > multicast_filter_limit) || (dev->flags & IFF_ALLMULTI)) { /* Too many to match, or accept all multicasts. */ memset(mc_filter, 0xff, sizeof(mc_filter)); - rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + rx_mode = RxAcceptBroadcast | AcceptMulticast | AcceptMyPhys; } else { struct dev_mc_list *mclist; int i; @@ -1413,7 +1393,7 @@ static u32 __set_rx_mode(struct net_devi filterbit &= 0x3f; mc_filter[filterbit >> 5] |= 1 << (filterbit & 31); } - rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + rx_mode = RxAcceptBroadcast | AcceptMulticast | AcceptMyPhys; } iowrite32(mc_filter[0], ioaddr + MulticastFilter0); iowrite32(mc_filter[1], ioaddr + MulticastFilter1);