* Patch by Pavel Bartusek, 21 Mar 2004
  Add Reiserfs support

* Patch by Hinko Kocevar, 20 Mar 2004
  - Add auto-release for SMSC LAN91c111 driver
  - Add save/restore of PTR and PNR regs as suggested in datasheet
diff --git a/drivers/smc91111.c b/drivers/smc91111.c
index 45bc248..4e180ec 100644
--- a/drivers/smc91111.c
+++ b/drivers/smc91111.c
@@ -481,7 +481,13 @@
 	int try = 0;
 	int time_out;
 	byte status;
+	byte saved_pnr;
+	word saved_ptr;
 
+	/* save PTR and PNR registers before manipulation */
+	SMC_SELECT_BANK (2);	
+	saved_pnr = SMC_inb( PN_REG );
+	saved_ptr = SMC_inw( PTR_REG );
 
 	PRINTK3 ("%s:smc_hardware_send_packet\n", SMC_DEV_NAME);
 
@@ -559,6 +565,10 @@
 	/* we have a packet address, so tell the card to use it */
 	SMC_outb (packet_no, PN_REG);
 
+	/* do not write new ptr value if Write data fifo not empty */	
+	while ( saved_ptr & PTR_NOTEMPTY ) 
+		printf ("Write data fifo not empty!\n");
+
 	/* point to the beginning of the packet */
 	SMC_outw (PTR_AUTOINC, PTR_REG);
 
@@ -607,12 +617,15 @@
 	SMC_outw (MC_ENQUEUE, MMU_CMD_REG);
 
 	/* poll for TX INT */
-	if (poll4int (IM_TX_INT, SMC_TX_TIMEOUT)) {
+	/* if (poll4int (IM_TX_INT, SMC_TX_TIMEOUT)) { */
+	/* poll for TX_EMPTY INT - autorelease enabled */
+	if (poll4int(IM_TX_EMPTY_INT, SMC_TX_TIMEOUT)) {
 		/* sending failed */
 		PRINTK2 ("%s: TX timeout, sending failed...\n", SMC_DEV_NAME);
 
 		/* release packet */
-		SMC_outw (MC_FREEPKT, MMU_CMD_REG);
+		/* no need to release, MMU does that now */
+		/* SMC_outw (MC_FREEPKT, MMU_CMD_REG); */
 
 		/* wait for MMU getting ready (low) */
 		while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
@@ -625,12 +638,14 @@
 		return 0;
 	} else {
 		/* ack. int */
-		SMC_outb (IM_TX_INT, SMC91111_INT_REG);
+		SMC_outb (IM_TX_EMPTY_INT, SMC91111_INT_REG);
+		/* SMC_outb (IM_TX_INT, SMC91111_INT_REG); */
 		PRINTK2 ("%s: Sent packet of length %d \n", SMC_DEV_NAME,
 			 length);
 
 		/* release packet */
-		SMC_outw (MC_FREEPKT, MMU_CMD_REG);
+		/* no need to release, MMU does that now */
+		/* SMC_outw (MC_FREEPKT, MMU_CMD_REG); */
 
 		/* wait for MMU getting ready (low) */
 		while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
@@ -642,6 +657,10 @@
 
 	}
 
+	/* restore previously saved registers */
+	SMC_outb( saved_pnr, PN_REG );
+	SMC_outw( saved_ptr, PTR_REG );
+
 	return length;
 }
 
@@ -730,8 +749,14 @@
 #ifdef USE_32_BIT
 	dword stat_len;
 #endif
+	byte saved_pnr;
+	word saved_ptr;
 
 	SMC_SELECT_BANK(2);
+	/* save PTR and PTR registers */
+	saved_pnr = SMC_inb( PN_REG );
+	saved_ptr = SMC_inw( PTR_REG );
+
 	packet_number = SMC_inw( RXFIFO_REG );
 
 	if ( packet_number & RXFIFO_REMPTY ) {
@@ -810,6 +835,10 @@
 	while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY )
 		udelay(1); /* Wait until not busy */
 
+	/* restore saved registers */
+	SMC_outb( saved_pnr, PN_REG );
+	SMC_outw( saved_ptr, PTR_REG );
+
 	if (!is_error) {
 		/* Pass the packet up to the protocol layers. */
 		NetReceive(NetRxPackets[0], packet_length);
@@ -1252,6 +1281,11 @@
 	/* Update our Auto-Neg Advertisement Register */
 	smc_write_phy_register (PHY_AD_REG, my_ad_caps);
 
+	/* Read the register back.  Without this, it appears that when */
+	/* auto-negotiation is restarted, sometimes it isn't ready and */
+	/* the link does not come up. */
+	smc_read_phy_register(PHY_AD_REG);
+
 	PRINTK2 ("%s:phy caps=%x\n", SMC_DEV_NAME, my_phy_caps);
 	PRINTK2 ("%s:phy advertised caps=%x\n", SMC_DEV_NAME, my_ad_caps);