[PATCH] smc-ultra.c, kernel 2.2.2

Ulf Betlehem (flu@iki.fi)
24 Feb 1999 16:21:49 +0200


(Note, I do not subscribe to this mailinglist.)

The smc-ultra driver normally ignores early receive warning
interrupts by setting the ERW level high enough, but when the
NIC is reset (e.g. via a "Tx timed out") this level is also
reset and thus we are again getting ERW interrupts.
This is bad, since these interrupts are counted as "work" by
8390.c, which during heavy traffic will generate the following
annoying messages: "eth0: Too much work at interrupt, ..."

As you probably have guessed by now, this patch ensures that
the ERW level is correctly set also after a reset. I suspect
that the smc-ultra32 suffers from the same problem, but I
don't have access to such a card for testing, so this patch is
only for smc-ultra.c v2.00 (kernel 2.2.2), which I have tested
on my "SMC Elite Ultra 16".

----------------------------------------------------------------
--- linux/drivers/net/smc-ultra.c.orig Wed Feb 24 13:31:19 1999
+++ linux/drivers/net/smc-ultra.c Wed Feb 24 15:41:46 1999
@@ -41,6 +41,7 @@
Paul Gortmaker : multiple card support for module users.
Donald Becker : 4/17/96 PIO support, minor potential problems avoided.
Donald Becker : 6/6/96 correctly set auto-wrap bit.
+ Ulf Betlehem : Now ignores ERW-interrupts also after a reset.
*/

static const char *version =
@@ -254,22 +255,10 @@
static int
ultra_open(struct device *dev)
{
- int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
-
if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name, dev))
return -EAGAIN;

- outb(0x00, ioaddr); /* Disable shared memory for safety. */
- outb(0x80, ioaddr + 5);
- if (ei_status.block_input == &ultra_pio_input) {
- outb(0x11, ioaddr + 6); /* Enable interrupts and PIO. */
- outb(0x01, ioaddr + 0x19); /* Enable ring read auto-wrap. */
- } else
- outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */
- /* Set the early receive warning level in window 0 high enough not
- to receive ERW interrupts. */
- outb_p(E8390_NODMA+E8390_PAGE0, dev->base_addr);
- outb(0xff, dev->base_addr + EN0_ERWCNT);
+ ultra_reset_8390(dev);
ei_open(dev);
MOD_INC_USE_COUNT;
return 0;
@@ -278,18 +267,24 @@
static void
ultra_reset_8390(struct device *dev)
{
- int cmd_port = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC base addr */
+ int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC base addr */

- outb(ULTRA_RESET, cmd_port);
+ outb(ULTRA_RESET, ioaddr);
if (ei_debug > 1) printk("resetting Ultra, t=%ld...", jiffies);
ei_status.txing = 0;
n
- outb(0x00, cmd_port); /* Disable shared memory for safety. */
- outb(0x80, cmd_port + 5);
- if (ei_status.block_input == &ultra_pio_input)
- outb(0x11, cmd_port + 6); /* Enable interrupts and PIO. */
- else
- outb(0x01, cmd_port + 6); /* Enable interrupts and memory. */
+ outb(0x00, ioaddr); /* Disable shared memory for safety. */
+ outb(0x80, ioaddr + 5);
+ if (ei_status.block_input == &ultra_pio_input) {
+ outb(0x11, ioaddr + 6); /* Enable interrupts and PIO. */
+ outb(0x01, ioaddr + 0x19); /* Enable ring read auto-wrap. */
+ } else
+ outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */
+
+ /* Set the early receive warning level in window 0 high enough not
+ to receive ERW interrupts. */
+ outb_p(E8390_NODMA+E8390_PAGE0, dev->base_addr);
+ outb(0xff, dev->base_addr + EN0_ERWCNT);

if (ei_debug > 1) printk("reset done\n");
return;
----------------------------------------------------------------

-- 
 flu

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/