Index: oldkernel/linux/drivers/net/eepro100.c diff -u linux/drivers/net/eepro100.c:1.3 linux/drivers/net/eepro100.c:1.4 --- linux/drivers/net/eepro100.c:1.3 Thu Jun 1 16:52:50 2000 +++ linux/drivers/net/eepro100.c Thu Jun 1 17:15:13 2000 @@ -1,6 +1,6 @@ /* drivers/net/eepro100.c: An Intel i82557-559 Ethernet driver for Linux. */ /* - NOTICE: this version tested with kernels 1.3.72 and later only! + NOTICE: this version of the driver is supposed to work with 2.2 kernels. Written 1996-1999 by Donald Becker. This software may be used and distributed according to the terms @@ -21,15 +21,14 @@ There is a Majordomo mailing list based at linux-eepro100@cesdis.gsfc.nasa.gov - This driver also contains updates by Andrey Savochkin and others. - For this specific driver variant please use linux-kernel for - bug reports. - + The driver also contains updates by different kernel developers. + This driver clone is maintained by Andrey V. Savochkin . + Please use this email address and linux-kernel mailing list for bug reports. */ static const char *version = "eepro100.c:v1.09j-t 9/29/99 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html\n" -"eepro100.c: $Revision: 1.18 $ 1999/12/29 Modified by Andrey V. Savochkin \n"; +"eepro100.c: $Revision: 1.1.2.1 $ 2000/03/02 Modified by Andrey V. Savochkin and others\n"; /* A few user-configurable values that apply to all boards. First set is undocumented and spelled per Intel recommendations. */ @@ -360,19 +359,16 @@ CmdIntr = 0x20000000, /* Interrupt after completion. */ CmdTxFlex = 0x00080000, /* Use "Flexible mode" for CmdTx command. */ }; -/* Clear CmdSuspend (1<<30) atomically. - Otherwise the command status in the lower 16 bits may be reset after - an asynchronous change. Previous driver version used separate 16 bit fields - for commands and statuses. --SAW +/* Clear CmdSuspend (1<<30) avoiding interference with the card access to the + status bits. Previous driver versions used separate 16 bit fields for + commands and statuses. --SAW */ -#ifdef __i386__ -#define speedo_fool_gcc(x) (*(volatile struct { int a[100]; } *)x) -#define speedo_clear_mask(mask, addr) \ -__asm__ __volatile__("lock; andl %0,%1" \ -: : "r" (~(mask)),"m" (speedo_fool_gcc(addr)) : "memory") -#define clear_suspend(cmd) speedo_clear_mask(CmdSuspend, &(cmd)->cmd_status) +#if defined(__LITTLE_ENDIAN) +#define clear_suspend(cmd) ((__u16 *)&(cmd)->cmd_status)[1] &= ~0x4000 +#elif defined(__BIG_ENDIAN) +#define clear_suspend(cmd) ((__u16 *)&(cmd)->cmd_status)[0] &= ~0x4000 #else -#define clear_suspend(cmd) (cmd)->cmd_status &= cpu_to_le32(~CmdSuspend) +#error Unsupported byteorder #endif enum SCBCmdBits { @@ -566,7 +562,7 @@ for (; pci_index < 8; pci_index++) { unsigned char pci_bus, pci_device_fn, pci_latency; - u32 pciaddr; + unsigned long pciaddr; long ioaddr; int irq; @@ -592,7 +588,7 @@ if (check_region(ioaddr, 32)) continue; } else if ((ioaddr = (long)ioremap(pciaddr & ~0xfUL, 0x1000)) == 0) { - printk(KERN_INFO "Failed to map PCI address %#x.\n", + printk(KERN_INFO "Failed to map PCI address %#lx.\n", pciaddr); continue; } @@ -1018,7 +1014,7 @@ sp->advertising = mdio_read(ioaddr, sp->phy[0] & 0x1f, 4); if (speedo_debug > 2) { - printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n", + printk(KERN_DEBUG "%s: Done speedo_open(), status %4.4x.\n", dev->name, inw(ioaddr + SCBStatus)); } @@ -1193,6 +1189,7 @@ int i; sp->cur_rx = 0; + sp->rx_ring_state = 0; for (i = 0; i < RX_RING_SIZE; i++) { struct sk_buff *skb; @@ -1491,13 +1488,13 @@ do { status = inw(ioaddr + SCBStatus); /* Acknowledge all of the current interrupt sources ASAP. */ - outw(status & 0xfc00, ioaddr + SCBStatus); + outw(status & 0xfd00, ioaddr + SCBStatus); if (speedo_debug > 4) printk(KERN_DEBUG "%s: interrupt status=%#4.4x.\n", dev->name, status); - if ((status & 0xfc00) == 0) + if ((status & 0xfd00) == 0) break; /* Always check if all rx buffers are allocated. --SAW */ @@ -1512,8 +1509,9 @@ spin_lock(&sp->lock); if ((status & 0x003c) == 0x0028) { /* No more Rx buffers. */ struct RxFD *rxf; - printk(KERN_WARNING "%s: card reports no RX buffers.\n", - dev->name); + printk(KERN_WARNING "%s: card reports no RX buffers, status=%#4.4x, flow control=%s.\n", + dev->name, status, + sp->flow_ctrl ? "on" : "off"); rxf = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE]; if (rxf == NULL) { if (speedo_debug > 2) @@ -1531,8 +1529,9 @@ outb(RxResumeNoResources, ioaddr + SCBCmd); } else if ((status & 0x003c) == 0x0008) { /* No resources. */ struct RxFD *rxf; - printk(KERN_WARNING "%s: card reports no resources.\n", - dev->name); + printk(KERN_WARNING "%s: card reports no resources, status=%#4.4x, flow control=%s.\n", + dev->name, status, + sp->flow_ctrl ? "on" : "off"); rxf = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE]; if (rxf == NULL) { if (speedo_debug > 2) @@ -1590,7 +1589,7 @@ printk(KERN_ERR "%s: Too much work at interrupt, status=0x%4.4x.\n", dev->name, status); /* Clear all interrupt sources. */ - outl(0xfc00, ioaddr + SCBStatus); + outw(0xfd00, ioaddr + SCBStatus); break; } } while (1); @@ -1991,7 +1990,16 @@ config_cmd_data[4] = rxdmacount; config_cmd_data[5] = txdmacount + 0x80; config_cmd_data[15] |= (new_rx_mode & 2) ? 1 : 0; - config_cmd_data[19] = sp->flow_ctrl ? 0xBD : 0x80; + if (sp->flow_ctrl) { + config_cmd_data[16] = 0x1f; + config_cmd_data[17] = 0x01; + config_cmd_data[19] = 0xb8; + } + else { + config_cmd_data[16] = 0; + config_cmd_data[17] = 0x40; + config_cmd_data[19] = 0x84; + } config_cmd_data[19] |= sp->full_duplex ? 0x40 : 0; config_cmd_data[21] = (new_rx_mode & 1) ? 0x0D : 0x05; if (sp->phy[0] & 0x8000) { /* Use the AUI port instead. */ @@ -2162,9 +2170,8 @@ while (root_speedo_dev) { struct speedo_private *sp = (void *)root_speedo_dev->priv; unregister_netdev(root_speedo_dev); -#ifdef USE_IO release_region(root_speedo_dev->base_addr, SPEEDO3_TOTAL_SIZE); -#else +#ifndef USE_IO iounmap((char *)root_speedo_dev->base_addr); #endif #if defined(HAS_PCI_NETIF)