# --------------------------------------------
# 02/10/16	sparker@sun.com	1.737.3.6
# drivers/net/eepro100.c: mask the interrupt and do a small delay on close()
# --------------------------------------------
#
diff -Nru a/drivers/net/eepro100.c b/drivers/net/eepro100.c
--- a/drivers/net/eepro100.c	Wed Oct 23 21:16:30 2002
+++ b/drivers/net/eepro100.c	Wed Oct 23 21:16:30 2002
@@ -348,6 +348,7 @@
    All accesses need not be longword aligned. */
 enum speedo_offsets {
 	SCBStatus = 0, SCBCmd = 2,	/* Rx/Command Unit command and status. */
+	SCBIntmask = 3,
 	SCBPointer = 4,				/* General purpose pointer. */
 	SCBPort = 8,				/* Misc. commands and operands.  */
 	SCBflash = 12, SCBeeprom = 14, /* EEPROM and flash memory control. */
@@ -511,6 +512,7 @@
 	unsigned short partner;			/* Link partner caps. */
 	struct mii_if_info mii_if;		/* MII API hooks, info */
 	u32 msg_enable;				/* debug message level */
+	unsigned char intmask;			/* Saved interrupt mask bits */
 #ifdef CONFIG_PM
 	u32 pm_state[16];
 #endif
@@ -558,6 +560,7 @@
 static int speedo_rx(struct net_device *dev);
 static void speedo_tx_buffer_gc(struct net_device *dev);
 static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static void speedo_intrmask(void *dev, int onoff);
 static int speedo_close(struct net_device *dev);
 static struct net_device_stats *speedo_get_stats(struct net_device *dev);
 static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -1556,6 +1559,30 @@
 	sp->dirty_tx = dirty_tx;
 }
 
+/*
+ * Interrupt mask control
+ */
+static void
+speedo_intrmask(void *dev_instance, int onoff)
+{
+	struct net_device *dev = (struct net_device *)dev_instance;
+	struct speedo_private *sp;
+	long ioaddr;
+
+	sp = (struct speedo_private *)dev->priv;
+	ioaddr = dev->base_addr;
+
+	if (onoff) {
+		/* enable */
+		outb(sp->intmask, ioaddr + SCBIntmask);
+		break;
+	} else {
+		/* disable */
+		sp->intmask = inb(ioaddr + SCBIntmask);
+		outw(SCBMaskAll, ioaddr + SCBCmd);
+	}
+}
+
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
 static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
@@ -1883,8 +1910,15 @@
 	/* Shut off the media monitoring timer. */
 	del_timer_sync(&sp->timer);
 
+	speedo_intrmask(dev, 0);
+
 	/* Shutting down the chip nicely fails to disable flow control. So.. */
 	outl(PortPartialReset, ioaddr + SCBPort);
+	inl(ioaddr + SCBPort); /* flush posted write */
+	/*
+	 * The chip requires a 10 microsecond quiet period.  Wait here!
+	 */
+	udelay(10);
 
 	free_irq(dev->irq, dev);
 
