--- linux/drivers/net/eepro.c.old Fri May 5 17:43:29 2000 +++ linux/drivers/net/eepro.c Fri May 5 17:57:16 2000 @@ -23,6 +23,8 @@ This is a compatibility hardware problem. Versions: + 0.12 added support to 82595FX etherexpress 10 based cards + (aris ), 04/26/2000) 0.11e some tweaks about multiple cards support (PdP, jul/aug 1999) 0.11d added __initdata, __initfunc stuff; call spin_lock_init in eepro_probe1. Replaced "eepro" by dev->name. Augmented @@ -93,7 +95,7 @@ */ static const char *version = - "eepro.c: v0.11d 08/12/1998 dupuis@lei.ucl.ac.be\n"; + "eepro.c: v0.12 04/26/2000 aris@conectiva.com.br\n"; #include @@ -176,7 +178,12 @@ /* First, a few definitions that the brave might change. */ /* A zero-terminated list of I/O addresses to be probed. */ static unsigned int eepro_portlist[] compat_init_data = - { 0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0}; +#ifdef PnPWakeup + { 0x210, 0x300, +#else + { 0x300, 0x210, +#endif + 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0}; /* note: 0x300 is default, the 595FX supports ALL IO Ports from 0x000 to 0x3F0, some of which are reserved in PCs */ @@ -199,6 +206,9 @@ #define LAN595TX 1 #define LAN595FX 2 +/* global to recall the read_eepro */ +static unsigned char etherexpress10 = 0; + /* Information that need to be kept for each board. */ struct eepro_local { struct enet_statistics stats; @@ -350,18 +360,33 @@ buffer (transmit-buffer = 32K - receive-buffer). */ + +/* now this section could be used by both boards: the oldies and the ee10: + * ee10 uses tx buffer before of rx buffer and the oldies the inverse. + * (aris) + */ #define RAM_SIZE 0x8000 + #define RCV_HEADER 8 -#define RCV_RAM 0x6000 /* 24KB default for RCV buffer */ -#define RCV_LOWER_LIMIT 0x00 /* 0x0000 */ -/* #define RCV_UPPER_LIMIT ((RCV_RAM - 2) >> 8) */ /* 0x5ffe */ -#define RCV_UPPER_LIMIT (((rcv_ram) - 2) >> 8) -/* #define XMT_RAM (RAM_SIZE - RCV_RAM) */ /* 8KB for XMT buffer */ -#define XMT_RAM (RAM_SIZE - (rcv_ram)) /* 8KB for XMT buffer */ -/* #define XMT_LOWER_LIMIT (RCV_RAM >> 8) */ /* 0x6000 */ -#define XMT_LOWER_LIMIT ((rcv_ram) >> 8) -#define XMT_UPPER_LIMIT ((RAM_SIZE - 2) >> 8) /* 0x7ffe */ -#define XMT_HEADER 8 +#define RCV_DEFAULT_RAM 0x6000 +#define RCV_RAM rcv_ram + +static unsigned rcv_ram = RCV_DEFAULT_RAM; + +#define XMT_HEADER 8 +#define XMT_RAM (RAM_SIZE - RCV_RAM) + +#define XMT_START ((rcv_start + RCV_RAM) % RAM_SIZE) + +#define RCV_LOWER_LIMIT (rcv_start >> 8) +#define RCV_UPPER_LIMIT (((rcv_start + RCV_RAM) - 2) >> 8) +#define XMT_LOWER_LIMIT (XMT_START >> 8) +#define XMT_UPPER_LIMIT (((XMT_START + XMT_RAM) - 2) >> 8) + +#define RCV_START_PRO 0x00 +#define RCV_START_10 XMT_RAM + /* by default the old driver */ +static unsigned rcv_start = RCV_START_PRO; #define RCV_DONE 0x0008 #define RX_OK 0x2000 @@ -407,7 +432,11 @@ #define IO_32_BIT 0x10 #define RCV_BAR 0x04 /* The following are word (16-bit) registers */ #define RCV_STOP 0x06 -#define XMT_BAR 0x0a + +#define XMT_BAR_PRO 0x0a +#define XMT_BAR_10 0x0b +static unsigned xmt_bar = XMT_BAR_PRO; + #define HOST_ADDRESS_REG 0x0c #define IO_PORT 0x0e #define IO_PORT_32_BIT 0x0c @@ -419,8 +448,13 @@ #define INT_NO_REG 0x02 #define RCV_LOWER_LIMIT_REG 0x08 #define RCV_UPPER_LIMIT_REG 0x09 -#define XMT_LOWER_LIMIT_REG 0x0a -#define XMT_UPPER_LIMIT_REG 0x0b + +#define XMT_LOWER_LIMIT_REG_PRO 0x0a +#define XMT_UPPER_LIMIT_REG_PRO 0x0b +#define XMT_LOWER_LIMIT_REG_10 0x0b +#define XMT_UPPER_LIMIT_REG_10 0x0a +static unsigned xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO; +static unsigned xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO; /* Bank 2 registers */ #define XMT_Chain_Int 0x20 /* Interrupt at the end of the transmit chain */ @@ -443,7 +477,10 @@ #define I_ADD_REG4 0x08 #define I_ADD_REG5 0x09 -#define EEPROM_REG 0x0a +#define EEPROM_REG_PRO 0x0a +#define EEPROM_REG_10 0x0b +static unsigned eeprom_reg = EEPROM_REG_PRO; + #define EESK 0x01 #define EECS 0x02 #define EEDI 0x04 @@ -457,10 +494,10 @@ (detachable devices only). */ #ifdef HAVE_DEVLIST -/* Support for an alternate probe manager, which will eliminate the - boilerplate below. */ + /* Support for an alternate probe manager, which will eliminate the + boilerplate below. */ struct netdev_entry netcard_drv = -{"eepro", eepro_probe1, EEPRO_IO_EXTENT, eepro_portlist}; + {"eepro", eepro_probe1, EEPRO_IO_EXTENT, eepro_portlist}; #else compat_init_func(int eepro_probe(struct device *dev)) { @@ -517,7 +554,7 @@ } #endif -void printEEPROMInfo(short ioaddr) +static void printEEPROMInfo(short ioaddr) { unsigned short Word; int i,j; @@ -589,40 +626,59 @@ id=inb(ioaddr + ID_REG); - printk(KERN_DEBUG " id: %#x ",id); - printk(" io: %#x ",ioaddr); - if (((id) & ID_REG_MASK) == ID_REG_SIG) { /* We seem to have the 82595 signature, let's play with its counter (last 2 bits of register 2 of bank 0) to be sure. */ - + counter = (id & R_ROBIN_BITS); if (((id=inb(ioaddr+ID_REG)) & R_ROBIN_BITS) == (counter + 0x40)) { /* Yes, the 82595 has been found */ + printk(KERN_DEBUG " id: %#x ",id); + printk(" io: %#x ",ioaddr); /* Now, get the ethernet hardware address from the EEPROM */ station_addr[0] = read_eeprom(ioaddr, 2); + + /* FIXME - find another way to know that we've found + * a Etherexpress 10 + */ + if (station_addr[0] == 0x0000 || + station_addr[0] == 0xffff) { + etherexpress10 = 1; + eeprom_reg = EEPROM_REG_10; + rcv_start = RCV_START_10; + xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10; + xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10; + + station_addr[0] = read_eeprom(ioaddr, 2); + } + station_addr[1] = read_eeprom(ioaddr, 3); station_addr[2] = read_eeprom(ioaddr, 4); /* Check the station address for the manufacturer's code */ if (net_debug>3) printEEPROMInfo(ioaddr); - - if (read_eeprom(ioaddr,7)== ee_FX_INT2IRQ) { /* int to IRQ Mask */ + + if (etherexpress10) { + eepro = 2; + printk("%s: Intel EtherExpress 10 ISA\n at %#x,", + dev->name, ioaddr); + } else if (read_eeprom(ioaddr,7)== ee_FX_INT2IRQ) { + /* int to IRQ Mask */ eepro = 2; printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", dev->name, ioaddr); } else if (station_addr[2] == 0x00aa) { eepro = 1; - printk("%s: Intel EtherExpress Pro/10 ISA at %#x,", + printk("%s: Intel EtherExpress Pro/10 ISA at %#x,", dev->name, ioaddr); } else { @@ -639,17 +695,25 @@ printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]); } + dev->mem_start = (RCV_LOWER_LIMIT << 8); + if ((dev->mem_end & 0x3f) < 3 || /* RX buffer must be more than 3K */ (dev->mem_end & 0x3f) > 29) /* and less than 29K */ - dev->mem_end = RCV_RAM; /* or it will be set to 24K */ - else dev->mem_end = 1024*dev->mem_end; /* Maybe I should shift << 10 */ + dev->mem_end = (RCV_UPPER_LIMIT << 8); + else { + dev->mem_end = (dev->mem_end * 1024) + + (RCV_LOWER_LIMIT << 8); + rcv_ram = dev->mem_end - (RCV_LOWER_LIMIT << 8); + } - /* From now on, dev->mem_end contains the actual size of rx buffer */ + /* From now on, dev->mem_end - dev->mem_start contains + * the actual size of rx buffer + */ if (net_debug > 3) - printk(", %dK RCV buffer", (int)(dev->mem_end)/1024); - - + printk(", %dK RCV buffer", + (int)(dev->mem_end - dev->mem_start)/1024); + /* ............... */ if (GetBit( read_eeprom(ioaddr, 5),ee_BNC_TPE)) @@ -678,10 +742,8 @@ return ENODEV; } else - if (dev->irq==2) dev->irq = 9; - - else if (dev->irq == 2) - dev->irq = 9; + if (dev->irq==2) + dev->irq = 9; } if (dev->irq > 2) { @@ -690,9 +752,6 @@ } else printk(", %s.\n", ifmap[dev->if_port]); - if ((dev->mem_start & 0xf) > 0) /* I don't know if this is */ - net_debug = dev->mem_start & 7; /* still useful or not */ - if (net_debug > 3) { i = read_eeprom(ioaddr, 5); if (i & 0x2000) /* bit 13 of EEPROM word 5 */ @@ -809,7 +868,8 @@ { unsigned short temp_reg, old8, old9; int irqMask; - int i, ioaddr = dev->base_addr, rcv_ram = dev->mem_end; + int i, ioaddr = dev->base_addr; + struct eepro_local *lp = (struct eepro_local *)dev->priv; if (net_debug > 3) @@ -854,7 +914,7 @@ /* Initialize the 82595. */ outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */ - temp_reg = inb(ioaddr + EEPROM_REG); + temp_reg = inb(ioaddr + eeprom_reg); lp->stepping = temp_reg >> 5; /* Get the stepping number of the 595 */ @@ -862,8 +922,8 @@ printk(KERN_DEBUG "The stepping of the 82595 is %d\n", lp->stepping); if (temp_reg & 0x10) /* Check the TurnOff Enable bit */ - outb(temp_reg & 0xef, ioaddr + EEPROM_REG); - for (i=0; i < 6; i++) + outb(temp_reg & 0xef, ioaddr + eeprom_reg); + for (i=0; i < 6; i++) outb(dev->dev_addr[i] , ioaddr + I_ADD_REG0 + i); temp_reg = inb(ioaddr + REG1); /* Setup Transmit Chaining */ @@ -898,8 +958,8 @@ /* Initialize the RCV and XMT upper and lower limits */ outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG); outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG); - outb(XMT_LOWER_LIMIT, ioaddr + XMT_LOWER_LIMIT_REG); - outb(XMT_UPPER_LIMIT, ioaddr + XMT_UPPER_LIMIT_REG); + outb(XMT_LOWER_LIMIT, ioaddr + xmt_lower_limit_reg); + outb(XMT_UPPER_LIMIT, ioaddr + xmt_upper_limit_reg); /* Enable the interrupt line. */ temp_reg = inb(ioaddr + REG1); @@ -914,12 +974,12 @@ outb(ALL_MASK, ioaddr + STATUS_REG); /* Initialize RCV */ - outw(RCV_LOWER_LIMIT << 8, ioaddr + RCV_BAR); - lp->rx_start = (RCV_LOWER_LIMIT << 8) ; - outw((RCV_UPPER_LIMIT << 8) | 0xfe, ioaddr + RCV_STOP); + outw((RCV_LOWER_LIMIT << 8), ioaddr + RCV_BAR); + lp->rx_start = (RCV_LOWER_LIMIT << 8); + outw(((RCV_UPPER_LIMIT << 8) | 0xfe), ioaddr + RCV_STOP); /* Initialize XMT */ - outw(XMT_LOWER_LIMIT << 8, ioaddr + XMT_BAR); + outw((XMT_LOWER_LIMIT << 8), ioaddr + xmt_bar); /* Check for the i82595TX and i82595FX */ old8 = inb(ioaddr + 8); @@ -969,7 +1029,7 @@ SLOW_DOWN; SLOW_DOWN; - lp->tx_start = lp->tx_end = XMT_LOWER_LIMIT << 8; /* or = RCV_RAM */ + lp->tx_start = lp->tx_end = (XMT_LOWER_LIMIT << 8); lp->tx_last = 0; dev->tbusy = 0; @@ -989,7 +1049,6 @@ { struct eepro_local *lp = (struct eepro_local *)dev->priv; int ioaddr = dev->base_addr; - int rcv_ram = dev->mem_end; #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155 unsigned long flags; @@ -1005,6 +1064,10 @@ if (tickssofar < 40) return 1; + /* let's disable interrupts so we can avoid confusion on SMP + */ + outb(ALL_MASK, ioaddr + INT_MASK_REG); + /* if (net_debug > 1) */ printk(KERN_ERR "%s: transmit timed out, %s?\n", dev->name, "network cable problem"); @@ -1021,27 +1084,19 @@ SLOW_DOWN; /* Do I also need to flush the transmit buffers here? YES? */ - lp->tx_start = lp->tx_end = rcv_ram; + lp->tx_start = lp->tx_end = (XMT_LOWER_LIMIT << 8); lp->tx_last = 0; dev->tbusy=0; dev->trans_start = jiffies; - outb(RCV_ENABLE_CMD, ioaddr); + /* re-enabling all interrupts */ + outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); + + outb(RCV_ENABLE_CMD, ioaddr); } -#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x20155 - /* If some higher layer thinks we've missed an tx-done interrupt - we are passed NULL. Caution: dev_tint() handles the cli()/sti() - itself. */ - /* if (skb == NULL) { - dev_tint(dev); - return 0; - }*/ - /* according to A. Cox, this is obsolete since 1.0 */ -#endif - #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155 spin_lock_irqsave(&lp->lock, flags); #endif @@ -1056,12 +1111,17 @@ } else { short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; + int discard = lp->stats.tx_dropped; #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155 lp->stats.tx_bytes+=skb->len; #endif hardware_send_packet(dev, buf, length); + + if (lp->stats.tx_dropped != discard) + return 1; + dev->trans_start = jiffies; } @@ -1119,33 +1179,36 @@ ioaddr = dev->base_addr; - do { - status = inb(ioaddr + STATUS_REG); - + while (((status = inb(ioaddr + STATUS_REG)) & 0x06) && (boguscount--)) + { + switch (status & (RX_INT | TX_INT)) { + case (RX_INT | TX_INT): + outb (RX_INT | TX_INT, ioaddr + STATUS_REG); + break; + case RX_INT: + outb (RX_INT, ioaddr + STATUS_REG); + break; + case TX_INT: + outb (TX_INT, ioaddr + STATUS_REG); + break; + } if (status & RX_INT) { if (net_debug > 4) - printk(KERN_DEBUG "%s: packet received interrupt.\n", dev->name); + printk(KERN_DEBUG "%s: packet received interrupt.\n", dev->name); - /* Acknowledge the RX_INT */ - outb(RX_INT, ioaddr + STATUS_REG); /* Get the received packets */ eepro_rx(dev); } - - else if (status & TX_INT) { + if (status & TX_INT) { if (net_debug > 4) - printk(KERN_DEBUG "%s: packet transmit interrupt.\n", dev->name); - - /* Acknowledge the TX_INT */ - outb(TX_INT, ioaddr + STATUS_REG); + printk(KERN_DEBUG "%s: packet transmit interrupt.\n", dev->name); /* Process the status of transmitted packets */ eepro_transmit_interrupt(dev); } + } - } while ((boguscount-- > 0) && (status & 0x06)); - - dev->interrupt = 0; + dev->interrupt = 0; if (net_debug > 5) printk(KERN_DEBUG "%s: exiting eepro_interrupt routine.\n", dev->name); @@ -1160,7 +1223,6 @@ { struct eepro_local *lp = (struct eepro_local *)dev->priv; int ioaddr = dev->base_addr; - int rcv_ram = dev->mem_end; short temp_reg; dev->tbusy = 1; @@ -1176,7 +1238,7 @@ /* Flush the Tx and disable Rx. */ outb(STOP_RCV_CMD, ioaddr); - lp->tx_start = lp->tx_end = rcv_ram ; + lp->tx_start = lp->tx_end = (XMT_LOWER_LIMIT << 8); lp->tx_last = 0; /* Mask all the interrupts. */ @@ -1289,7 +1351,7 @@ outw(eaddrs[0], ioaddr + IO_PORT); outw(eaddrs[1], ioaddr + IO_PORT); outw(eaddrs[2], ioaddr + IO_PORT); - outw(lp->tx_end, ioaddr + XMT_BAR); + outw(lp->tx_end, ioaddr + xmt_bar); outb(MC_SETUP, ioaddr); /* Update the transmit queue */ @@ -1351,10 +1413,19 @@ { int i; unsigned short retval = 0; - short ee_addr = ioaddr + EEPROM_REG; + short ee_addr = ioaddr + eeprom_reg; int read_cmd = location | EE_READ_CMD; short ctrl_val = EECS ; + /* XXXX - this is not the final version. We must test this on other + * boards other than eepro10. I think that it won't let other + * boards to fail. (aris) + */ + if (etherexpress10) { + outb(BANK1_SELECT, ioaddr); + outb(0x00, ioaddr + STATUS_REG); + } + outb(BANK2_SELECT, ioaddr); outb(ctrl_val, ee_addr); @@ -1391,7 +1462,6 @@ { struct eepro_local *lp = (struct eepro_local *)dev->priv; short ioaddr = dev->base_addr; - int rcv_ram = dev->mem_end; unsigned status, tx_available, last, end, boguscount = 100; if (net_debug > 5) @@ -1406,7 +1476,7 @@ if (dev->interrupt == 1) { /* Enable RX and TX interrupts */ - outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); + outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); continue; } @@ -1430,21 +1500,19 @@ last = lp->tx_end; end = last + (((length + 3) >> 1) << 1) + XMT_HEADER; - if (end >= RAM_SIZE) { /* the transmit buffer is wrapped around */ - - if ((RAM_SIZE - last) <= XMT_HEADER) { + if (end >= (XMT_UPPER_LIMIT << 8)) { /* the transmit buffer is wrapped around */ + if (((XMT_UPPER_LIMIT << 8) - last) <= XMT_HEADER) { /* Arrrr!!!, must keep the xmt header together, several days were lost to chase this one down. */ - last = rcv_ram; + last = (XMT_LOWER_LIMIT << 8); end = last + (((length + 3) >> 1) << 1) + XMT_HEADER; } - - else end = rcv_ram + (end - RAM_SIZE); + else end = (XMT_LOWER_LIMIT << 8) + (end - XMT_RAM); } outw(last, ioaddr + HOST_ADDRESS_REG); - outw(XMT_CMD, ioaddr + IO_PORT); + outw(XMT_CMD, ioaddr + IO_PORT); outw(0, ioaddr + IO_PORT); outw(end, ioaddr + IO_PORT); outw(length, ioaddr + IO_PORT); @@ -1461,9 +1529,9 @@ /* A dummy read to flush the DRAM write pipeline */ status = inw(ioaddr + IO_PORT); - if (lp->tx_start == lp->tx_end) { - outw(last, ioaddr + XMT_BAR); - outb(XMT_CMD, ioaddr); + if (lp->tx_start == lp->tx_end) { + outw(last, ioaddr + xmt_bar); + outb(XMT_CMD, ioaddr); lp->tx_start = last; /* I don't like to change tx_start here */ } else { @@ -1490,6 +1558,12 @@ dev->tbusy = 0; } + /* now we are serializing tx. tbusy won't come back until + * the tx interrupt + */ + if (etherexpress10) + dev->tbusy = 1; + /* Enable RX and TX interrupts */ outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); @@ -1498,7 +1572,9 @@ return; } + outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); dev->tbusy = 1; + if (net_debug > 5) printk(KERN_DEBUG "%s: exiting hardware_send_packet routine.\n", dev->name); } @@ -1507,14 +1583,17 @@ eepro_rx(struct device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; - short ioaddr = dev->base_addr, rcv_ram = dev->mem_end; + short ioaddr = dev->base_addr; short boguscount = 20; - short rcv_car = lp->rx_start; + unsigned rcv_car = lp->rx_start; unsigned rcv_event, rcv_status, rcv_next_frame, rcv_size; if (net_debug > 5) printk(KERN_DEBUG "%s: entering eepro_rx routine.\n", dev->name); + /* disabling all interrupts */ + outb(ALL_MASK, ioaddr + STATUS_REG); + /* Set the read pointer to the start of the RCV */ outw(rcv_car, ioaddr + HOST_ADDRESS_REG); @@ -1589,12 +1668,14 @@ } if (rcv_car == 0) - rcv_car = (RCV_UPPER_LIMIT << 8) | 0xff; + rcv_car = ((RCV_UPPER_LIMIT << 8) | 0xff); outw(rcv_car - 1, ioaddr + RCV_STOP); if (net_debug > 5) printk(KERN_DEBUG "%s: exiting eepro_rx routine.\n", dev->name); + + outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); } static void @@ -1603,7 +1684,7 @@ struct eepro_local *lp = (struct eepro_local *)dev->priv; short ioaddr = dev->base_addr; short boguscount = 20; - short xmt_status; + unsigned xmt_status; /* if (dev->tbusy == 0) { @@ -1613,30 +1694,71 @@ dev->name); } */ + while (lp->tx_start != lp->tx_end && boguscount) { - while (lp->tx_start != lp->tx_end) { - - outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG); + outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG); xmt_status = inw(ioaddr+IO_PORT); - - if ((xmt_status & TX_DONE_BIT) == 0) break; + + if ((xmt_status & TX_DONE_BIT) == 0) { + udelay(40); + boguscount--; + continue; + } xmt_status = inw(ioaddr+IO_PORT); lp->tx_start = inw(ioaddr+IO_PORT); + if (etherexpress10) { + lp->tx_start = (XMT_LOWER_LIMIT << 8); + lp->tx_end = lp->tx_start; + + /* yeah, black magic :( */ + outb(BANK0_SELECT, ioaddr); + outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); + + outb(RCV_DISABLE_CMD, ioaddr); + outb(RCV_ENABLE_CMD, ioaddr); + } + + /* here the tbusy comes to 0 for normal and ee10 cards + */ dev->tbusy = 0; + mark_bh(NET_BH); - - if (xmt_status & 0x2000) + + if (xmt_status & 0x2000) { lp->stats.tx_packets++; + } else { lp->stats.tx_errors++; - if (xmt_status & 0x0400) + if (xmt_status & 0x0400) { lp->stats.tx_carrier_errors++; - printk("%s: XMT status = %#x\n", - dev->name, xmt_status); - printk(KERN_DEBUG "%s: XMT status = %#x\n", - dev->name, xmt_status); + printk(KERN_DEBUG "%s: carrier error\n", + dev->name); + printk(KERN_DEBUG "%s: XMT status = %#x\n", + dev->name, xmt_status); + } + else { + printk(KERN_DEBUG "%s: XMT status = %#x\n", + dev->name, xmt_status); + printk(KERN_DEBUG "%s: XMT status = %#x\n", + dev->name, xmt_status); + } + + if (etherexpress10) { + /* Try to restart the adaptor. */ + outb(SEL_RESET_CMD, ioaddr); + + /* We are supposed to wait for 2 us after a SEL_RESET */ + SLOW_DOWN; + SLOW_DOWN; + + /* first enable interrupts */ + outb(BANK0_SELECT, ioaddr); + outb(ALL_MASK & ~(RX_INT | TX_INT), ioaddr + STATUS_REG); + + outb(RCV_ENABLE_CMD, ioaddr); + } } if (xmt_status & 0x000f) { @@ -1646,9 +1768,7 @@ if ((xmt_status & 0x0040) == 0x0) { lp->stats.tx_heartbeat_errors++; } - - if (--boguscount == 0) - break; + boguscount--; } } @@ -1658,17 +1778,12 @@ static char devicename[MAX_EEPRO][9]; static struct device dev_eepro[MAX_EEPRO]; -static int io[MAX_EEPRO] = { -#ifdef PnPWakeup - 0x210, /*: default for PnP enabled FX chips */ -#else - 0x200, /* Why? */ -#endif - [1 ... MAX_EEPRO - 1] = -1 }; +static int io[MAX_EEPRO]; static int irq[MAX_EEPRO] = { [0 ... MAX_EEPRO-1] = 0 }; static int mem[MAX_EEPRO] = { /* Size of the rx buffer in KB */ - [0 ... MAX_EEPRO-1] = RCV_RAM/1024 + [0 ... MAX_EEPRO-1] = RCV_DEFAULT_RAM/1024 }; +static int autodetect; static int n_eepro = 0; /* For linux 2.1.xx */ @@ -1678,26 +1793,35 @@ MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EEPRO) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EEPRO) "i"); MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_EEPRO) "i"); +MODULE_PARM(autodetect, "1-" __MODULE_STRING(1) "i"); #endif int init_module(void) { - if (io[0] == 0) - printk("eepro_init_module: You should not use auto-probing with insmod!\n"); - - while (n_eepro < MAX_EEPRO && io[n_eepro] >= 0) { + int i; + if (io[0] == 0 && autodetect == 0) { + printk("eepro_init_module: Probe is very dangerous in ISA boards!\n"); + printk("eepro_init_module: Please add \"autodetect=1\" to force probe\n"); + return 1; + } + else if (autodetect) { + /* if autodetect is set then we must force detection */ + io[0] = 0; + + printk("eepro_init_module: Auto-detecting boards (May God protect us...)\n"); + } + + for (i = 0; i < MAX_EEPRO; i++) { struct device *d = &dev_eepro[n_eepro]; d->name = devicename[n_eepro]; /* inserted by drivers/net/net_init.c */ d->mem_end = mem[n_eepro]; - d->base_addr = io[n_eepro]; + d->base_addr = io[0]; d->irq = irq[n_eepro]; d->init = eepro_probe; if (register_netdev(d) == 0) n_eepro++; - else - break; } return n_eepro ? 0 : -ENODEV; --- linux/drivers/net/Config.in~ Fri May 5 17:43:23 2000 +++ linux/drivers/net/Config.in Fri May 5 18:00:06 2000 @@ -103,7 +103,7 @@ tristate 'DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA tristate 'EtherWORKS 3 (DE203, DE204, DE205) support' CONFIG_EWRK3 tristate 'EtherExpress 16 support' CONFIG_EEXPRESS - tristate 'EtherExpressPro support' CONFIG_EEXPRESS_PRO + tristate 'EtherExpressPro/EtherExpress 10 (i82595) support' CONFIG_EEXPRESS_PRO tristate 'FMV-181/182/183/184 support' CONFIG_FMV18X tristate 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS tristate 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN --- linux/Documentation/Configure.help~ Fri May 5 17:43:14 2000 +++ linux/Documentation/Configure.help Fri May 5 18:00:06 2000 @@ -6320,9 +6320,10 @@ EtherExpress PRO support CONFIG_EEXPRESS_PRO - If you have a network (Ethernet) card of this type, say Y. Note - however that the EtherExpress PRO/100 Ethernet card has its own - separate driver. Please read the Ethernet-HOWTO, available via FTP + If you have a network (Ethernet) card of this type, say Y. This + driver supports intel i82595{FX,TX} based boards. Note however + that the EtherExpress PRO/100 Ethernet card has its own separate + driver. Please read the Ethernet-HOWTO, available via FTP (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be --- linux/CREDITS~ Fri May 5 17:41:03 2000 +++ linux/CREDITS Fri May 5 18:00:06 2000 @@ -1744,6 +1744,13 @@ S: 95170 Deuil La Barre S: France +N: Aristeu Sergio Rozanski Filho +E: aris@conectiva.com.br +D: Support for EtherExpress 10 ISA (i82595) in eepro driver +S: Rua Tocantins, 89 - Cristo Rei +S: 80050-430 - Curitiba - Parana +S: Brazil + N: Alessandro Rubini E: rubini@ipvvis.unipv.it D: the gpm mouse server and kernel support for it