--- linux/drivers/net/eepro.c.old Mon Jun 26 10:55:16 2000 +++ linux/drivers/net/eepro.c Mon Jun 26 11:01:53 2000 @@ -23,6 +23,10 @@ This is a compatibility hardware problem. Versions: + 0.12b added reset when the tx interrupt is called and TX isn't done + and other minor fixes. this may fix a problem found after + initialization that delays tx until a transmit timeout is + reported and the board is reset. 0.12a fixed bug that would make impossible have ee10 boards and other previous supported boards. (aris, 05/19/2000) 0.12 added support to 82595FX etherexpress 10 based cards @@ -97,7 +101,7 @@ */ static const char *version = - "eepro.c: v0.12a 04/26/2000 aris@conectiva.com.br\n"; + "eepro.c: v0.12b 06/20/2000 aris@conectiva.com.br\n"; #include @@ -470,7 +474,7 @@ #define EEDO 0x08 /* do a full reset */ -#define eepro_reset(ioaddr) outb(RESET_CMD, ioaddr) +#define eepro_reset(ioaddr) outb(RESET_CMD, ioaddr); udelay(40); /* do a nice reset */ #define eepro_sel_reset(ioaddr) { \ @@ -523,6 +527,20 @@ /* ack for tx int */ #define eepro_ack_tx(ioaddr) outb (TX_INT, ioaddr + STATUS_REG) +/* a complete sel reset */ +#define eepro_complete_selreset(ioaddr) { eepro_dis_int(ioaddr);\ + lp->stats.tx_errors++;\ + eepro_sel_reset(ioaddr);\ + lp->tx_end = \ + (XMT_LOWER_LIMIT << 8);\ + lp->tx_start = lp->tx_end;\ + lp->tx_last = 0;\ + dev->tbusy=0;\ + dev->trans_start = jiffies;\ + eepro_en_int(ioaddr);\ + eepro_en_rx(ioaddr);\ + } + /* Check for a network adaptor of this type, and return '0' if one exists. If dev->base_addr == 0, probe all likely locations. If dev->base_addr == 1, always return failure. @@ -1064,10 +1082,6 @@ if (tickssofar < 40) return 1; - /* let's disable interrupts so we can avoid confusion on SMP - */ - eepro_dis_int(ioaddr); - /* if (net_debug > 1) */ printk(KERN_ERR "%s: transmit timed out, %s?\n", dev->name, "network cable problem"); @@ -1075,25 +1089,9 @@ one for the the log file */ printk(KERN_DEBUG "%s: transmit timed out, %s?\n", dev->name, "network cable problem"); - lp->stats.tx_errors++; - - /* Try to restart the adaptor. */ - /* We are supposed to wait for 2 us after a SEL_RESET */ - eepro_sel_reset(ioaddr); - - /* Do I also need to flush the transmit buffers here? YES? */ - lp->tx_start = lp->tx_end = (XMT_LOWER_LIMIT << 8); - lp->tx_last = 0; - - dev->tbusy=0; - dev->trans_start = jiffies; - - - /* re-enabling all interrupts */ - eepro_en_int(ioaddr); - - /* enable rx */ - eepro_en_rx(ioaddr); + + /* let's do a complete sel reset */ + eepro_complete_selreset(ioaddr); } spin_lock_irqsave(&lp->lock, flags); @@ -1379,8 +1377,7 @@ eepro_en_int(ioaddr); } - /* enabling rx */ - eepro_en_rx(ioaddr); + eepro_complete_selreset(ioaddr); } /* The horrible routine to read a word from the serial EEPROM. */ @@ -1492,7 +1489,8 @@ last = (XMT_LOWER_LIMIT << 8); end = last + (((length + 3) >> 1) << 1) + XMT_HEADER; } - else end = (XMT_LOWER_LIMIT << 8) + (end - XMT_RAM); + else end = (XMT_LOWER_LIMIT << 8) + (end - + (XMT_UPPER_LIMIT << 8)); } outw(last, ioaddr + HOST_ADDRESS_REG); @@ -1554,7 +1552,6 @@ return; } - eepro_en_int(ioaddr); dev->tbusy = 1; if (net_debug > 5) @@ -1574,9 +1571,6 @@ if (net_debug > 5) printk(KERN_DEBUG "%s: entering eepro_rx routine.\n", dev->name); - /* clear all interrupts */ - eepro_clear_int(ioaddr); - /* Set the read pointer to the start of the RCV */ outw(rcv_car, ioaddr + HOST_ADDRESS_REG); @@ -1655,9 +1649,6 @@ if (net_debug > 5) printk(KERN_DEBUG "%s: exiting eepro_rx routine.\n", dev->name); - - /* enable tx/rx interrupts */ - eepro_en_int(ioaddr); } static void @@ -1754,6 +1745,12 @@ } boguscount--; } + /* if it reached here then it's probable that the adapter won't + * interrupt again for tx. in other words: tx timeout what will take + * a lot of time to happen, so we'll do a complete selreset. + */ + if (!boguscount) + eepro_complete_selreset(ioaddr); } #ifdef MODULE