Intel EtherExpress 3c59x.c [patch]

Richard B. Johnson (root@chaos.analogic.com)
Mon, 19 Apr 1999 20:43:17 -0400 (EDT)


It is possible for two 100 mb/s SMP machines that use the built-in
Intel EtherExpress network interface, to lock up when they are both
`ping -f` each other.

The following simple patch fixes it for me (standard disclaimer).

--- linux-2.2.6/drivers/net/3c59x.c.orig Mon Apr 19 19:15:39 1999
+++ linux-2.2.6/drivers/net/3c59x.c Mon Apr 19 19:27:23 1999
@@ -500,6 +500,7 @@
static void set_rx_mode(struct device *dev);
static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd);

+static spinlock_t xmit_lock;

/* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
/* Option count limit only -- unlimited interfaces are supported. */
@@ -1430,7 +1431,6 @@

}

-
static int
vortex_start_xmit(struct sk_buff *skb, struct device *dev)
{
@@ -1525,9 +1525,7 @@
vp->tx_ring[entry].addr = cpu_to_le32(virt_to_bus(skb->data));
vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG);
vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
-
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&xmit_lock, flags);
outw(DownStall, ioaddr + EL3_CMD);
/* Wait for the stall to complete. */
for (i = 600; i >= 0 ; i--)
@@ -1539,7 +1537,7 @@
queued_packet++;
}
outw(DownUnstall, ioaddr + EL3_CMD);
- restore_flags(flags);
+ spin_unlock_irqrestore(&xmit_lock, flags);

vp->cur_tx++;
if (vp->cur_tx - vp->dirty_tx > TX_RING_SIZE - 1)

Cheers,
Dick Johnson
***** FILE SYSTEM WAS MODIFIED *****
Penguin : Linux version 2.2.6 on an i686 machine (400.59 BogoMips).
Warning : It's hard to remain at the trailing edge of technology.

-
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/