patch-2.2.15 linux/drivers/net/tlan.c

Next file: linux/drivers/net/tlan.h
Previous file: linux/drivers/net/syncppp.c
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/drivers/net/tlan.c linux/drivers/net/tlan.c
@@ -1,4 +1,4 @@
-/********************************************************************
+/********************************************************************************
  *
  *  Linux ThunderLAN Driver
  *
@@ -7,6 +7,7 @@
  *
  *  (C) 1997-1998 Caldera, Inc.
  *  (C) 1998 James Banks
+ *  (C) 1999-2000 Torben Mathiasen 
  *
  *  This software may be used and distributed according to the terms
  *  of the GNU Public License, incorporated herein by reference.
@@ -34,7 +35,16 @@
  *
  *	Torben Mathiasen <torben.mathiasen@compaq.com> New Maintainer!
  *
- ********************************************************************/
+ * 	v1.2 Feb 14, 2000	- Fixed a timer bug that would cause
+ * 				  the tlan driver to get stuck if no 
+ * 				  cable/link were present.
+ * 				- We now allow higher priority timers
+ * 				  to overwrite timers like TLAN_TIMER_ACTIVITY
+ * 				  Patch from John Cagle <john.cagle@compaq.com>
+ * 				- Removed dependency of HZ being 100.
+ *				- Statistics is now fixed.
+ *				- Minor stuff.
+ ********************************************************************************/
 
 
 #include <linux/module.h>
@@ -76,7 +86,7 @@
 static	u8		*TLanPadBuffer;
 static	char		TLanSignature[] = "TLAN";
 static	int		TLanVersionMajor = 1;
-static	int		TLanVersionMinor = 0;
+static	int		TLanVersionMinor = 2;
 
 
 static	TLanAdapterEntry TLanAdapterList[] = {
@@ -238,7 +248,8 @@
 	TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv;
 
 	cli();
-	if ( priv->timer.function != NULL ) {
+	if ( priv->timer.function != NULL && 
+		priv->timerType != TLAN_TIMER_ACTIVITY) {
 		return;
 	}
 	priv->timer.function = &TLan_Timer;
@@ -294,7 +305,7 @@
 	u8		irq;
 	u8		rev;
 
-	printk( "TLAN driver, v%d.%d, (C) 1997-8 Caldera, Inc.\n",
+	printk(KERN_INFO "TLAN driver, v%d.%d, (C) 1997-8 Caldera, Inc.\n",
 		TLanVersionMajor,
 		TLanVersionMinor
 	      );
@@ -350,7 +361,7 @@
 			priv->nextDevice = TLanDevices;
 			TLanDevices = dev;
 			TLanDevicesInstalled++;
-			printk("TLAN:  %s irq=%2d io=%04x, %s, Rev. %d\n",
+			printk(KERN_INFO "TLAN:  %s irq=%2d io=%04x, %s, Rev. %d\n",
 				dev->name,
 				(int) dev->irq,
 				(int) dev->base_addr,
@@ -489,7 +500,7 @@
 	priv->debug =      dev->mem_end;
 
 
-	printk("TLAN %d.%d:  %s irq=%2d io=%04x, %s, Rev. %d\n",
+	printk(KERN_INFO "TLAN %d.%d:  %s irq=%2d io=%04x, %s, Rev. %d\n",
 		TLanVersionMajor,
 		TLanVersionMinor,
 		dev->name, 
@@ -712,6 +723,9 @@
 	int		err;
 
 	priv->tlanRev = TLan_DioRead8( dev->base_addr, TLAN_DEF_REVISION );
+	
+	MOD_INC_USE_COUNT;
+
 	if ( priv->sa_int ) {
 		TLAN_DBG( TLAN_DEBUG_GNRL, "TLAN:   Using SA_INTERRUPT\n" ); 
 		err = request_irq( dev->irq, TLan_HandleInterrupt, SA_SHIRQ | SA_INTERRUPT, TLanSignature, dev );
@@ -723,8 +737,6 @@
 		return -EAGAIN;
 	}
 	
-	MOD_INC_USE_COUNT;
-
 	dev->tbusy = 0;
 	dev->interrupt = 0;
 	dev->start = 1;
@@ -735,7 +747,6 @@
 	TLan_ResetLists( dev );
 	TLan_ReadAndClearStats( dev, TLAN_IGNORE );
 	TLan_ResetAdapter( dev );
-
 	TLAN_DBG( TLAN_DEBUG_GNRL, "TLAN:  %s: Opened.  TLAN Chip Rev: %x\n", dev->name, priv->tlanRev );
 
 	return 0;
@@ -927,6 +938,7 @@
 	outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
 	if ( priv->timer.function != NULL )
 		del_timer( &priv->timer );
+		priv->timer.function = NULL;
 	free_irq( dev->irq, dev );
 	TLan_FreeLists( dev );
 	TLAN_DBG( TLAN_DEBUG_GNRL, "TLAN:  Device %s closed.\n", dev->name );
@@ -1132,9 +1144,7 @@
 		printk( "TLAN:  Received interrupt for uncompleted TX frame.\n" );
 	}
 
-#if LINUX_KERNEL_VERSION > 0x20100
-	priv->stats->tx_bytes += head_list->frameSize;
-#endif
+	priv->stats.tx_bytes += head_list->frameSize;
 
 	head_list->cStat = TLAN_CSTAT_UNUSED;
 	dev->tbusy = 0;
@@ -1252,9 +1262,7 @@
 			skb_reserve( skb, 2 );
 			t = (void *) skb_put( skb, head_list->frameSize );
 
-#if LINUX_KERNEL_VERSION > 0x20100
-			priv->stats->rx_bytes += head_list->frameSize;
-#endif
+			priv->stats.rx_bytes += head_list->frameSize;
 
 			memcpy( t, head_buffer, head_list->frameSize );
 			skb->protocol = eth_type_trans( skb, dev );
@@ -1276,9 +1284,8 @@
 			skb = (struct sk_buff *) head_list->buffer[9].address;
 			head_list->buffer[9].address = 0;
 			skb_trim( skb, head_list->frameSize );
-#if LINUX_KERNEL_VERSION > 0x20100
-			priv->stats->rx_bytes += head_list->frameSize;
-#endif
+
+			priv->stats.rx_bytes += head_list->frameSize;
 
 			skb->protocol = eth_type_trans( skb, dev );
 			netif_rx( skb );
@@ -1884,7 +1891,7 @@
 	u32		addr;
 	u32		data;
 	u8		data8;
-
+	
 	priv->tlanFullDuplex = FALSE;
 	priv->phyOnline=0;
 /*  1.	Assert reset bit. */
@@ -1984,13 +1991,13 @@
 
 	if ( ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) || ( priv->aui ) ) {
 		status = MII_GS_LINK;
-		printk( "TLAN:  %s: Link forced.\n", dev->name );
+		printk(KERN_INFO "TLAN:  %s: Link forced.\n", dev->name );
 	} else {
 		TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
 		udelay( 1000 );
 		TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
 		if ( status & MII_GS_LINK ) {
-			printk( "TLAN:  %s: Link active.\n", dev->name );
+			printk(KERN_INFO "TLAN:  %s: Link active.\n", dev->name );
 			TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
 		}
 	}
@@ -2014,8 +2021,8 @@
 		outl( virt_to_bus( priv->rxList ), dev->base_addr + TLAN_CH_PARM );
 		outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD );
 	} else {
-		printk( "TLAN:  %s: Link inactive, will retry in 10 secs...\n", dev->name );
-		TLan_SetTimer( dev, 1000, TLAN_TIMER_FINISH_RESET );
+		printk(KERN_INFO "TLAN:  %s: Link inactive, will retry in 10 secs...\n", dev->name );
+		TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET );
 		return;
 	}
 
@@ -2197,11 +2204,11 @@
 		TLan_MiiWriteReg( dev, priv->phy[1], MII_GEN_CTL, value );
 	}
 
-	/* Wait for 5 jiffies (50 ms) and powerup
+	/* Wait for 50 ms and powerup
 	 * This is abitrary.  It is intended to make sure the
 	 * tranceiver settles.
 	 */
-	TLan_SetTimer( dev, 5, TLAN_TIMER_PHY_PUP );
+	TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP );
 
 } /* TLan_PhyPowerDown */
 
@@ -2212,17 +2219,17 @@
 {
 	TLanPrivateInfo	*priv = (TLanPrivateInfo *) dev->priv;
 	u16		value;
-
+	
 	TLAN_DBG( TLAN_DEBUG_GNRL, "TLAN:  %s: Powering up PHY.\n", dev->name );
 	TLan_MiiSync( dev->base_addr );
 	value = MII_GC_LOOPBK;
 	TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
 
-	/* Wait for 50 jiffies (500 ms) and reset the
+	/* Wait for 500 ms and reset the
 	 * tranceiver.  The TLAN docs say both 50 ms and
 	 * 500 ms, so do the longer, just in case
 	 */
-	TLan_SetTimer( dev, 50, TLAN_TIMER_PHY_RESET );
+	TLan_SetTimer( dev, (HZ/2), TLAN_TIMER_PHY_RESET );
 
 } /* TLan_PhyPowerUp */
 
@@ -2247,10 +2254,10 @@
 	}
 	TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0 );
 
-	/* Wait for 50 jiffies (500 ms) and initialize.
+	/* Wait for 500 ms and initialize.
 	 * I don't remember why I wait this long.
 	 */
-	TLan_SetTimer( dev, 50, TLAN_TIMER_PHY_START_LINK );
+	TLan_SetTimer( dev, (HZ/2), TLAN_TIMER_PHY_START_LINK );
 
 } /* TLan_PhyReset */
 
@@ -2293,13 +2300,13 @@
        		TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1000 );
 		TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1200 );
 
-		/* Wait for 400 jiffies (4 sec) for autonegotiation
+		/* Wait for 4 sec for autonegotiation
 		 * to complete.  The max spec time is less than this
 		 * but the card need additional time to start AN.
 		 * .5 sec should be plenty extra.
 		 */
-		printk( "TLAN:  %s: Starting autonegotiation.\n", dev->name );
-		TLan_SetTimer( dev, 400, TLAN_TIMER_PHY_FINISH_AN );
+		printk(KERN_INFO "TLAN:  %s: Starting autonegotiation.\n", dev->name );
+		TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_PHY_FINISH_AN );
 		return;
 	}
 
@@ -2307,7 +2314,7 @@
 		priv->phyNum = 0;
 		data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
 		TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
-		TLan_SetTimer( dev, 4, TLAN_TIMER_PHY_PDOWN );
+		TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN );
 		return;
 	} else if ( priv->phyNum == 0 ) {
         	TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tctl );
@@ -2328,10 +2335,10 @@
         	TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl );
 	}
 
-	/* Wait for 100 jiffies (1 sec) to give the tranceiver time
+	/* Wait for 1 sec to give the tranceiver time
 	 * to establish link.
 	 */
-	TLan_SetTimer( dev, 100, TLAN_TIMER_FINISH_RESET );
+	TLan_SetTimer( dev, HZ, TLAN_TIMER_FINISH_RESET );
 
 } /* TLan_PhyStartLink */
 
@@ -2352,15 +2359,15 @@
 
 	TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
 	if ( ! ( status & MII_GS_AUTOCMPLT ) ) {
-		/* Wait for 800 jiffies (8 sec) to give the process
+		/* Wait for 8 sec to give the process
 		 * more time.  Perhaps we should fail after a while.
 		 */
-		printk( "TLAN:  Giving autonegotiation more time.\n" );
-		TLan_SetTimer( dev, 800, TLAN_TIMER_PHY_FINISH_AN );
+		printk(KERN_INFO "TLAN:  Giving autonegotiation more time.\n" );
+		TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN );
 		return;
 	}
 
-	printk( "TLAN:  %s: Autonegotiation complete.\n", dev->name );
+	printk(KERN_INFO "TLAN:  %s: Autonegotiation complete.\n", dev->name );
 	TLan_MiiReadReg( dev, phy, MII_AN_ADV, &an_adv );
 	TLan_MiiReadReg( dev, phy, MII_AN_LPA, &an_lpa );
 	mode = an_adv & an_lpa & 0x03E0;
@@ -2374,23 +2381,23 @@
 		priv->phyNum = 0;
 		data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
 		TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
-		TLan_SetTimer( dev, 40, TLAN_TIMER_PHY_PDOWN );
+		TLan_SetTimer( dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN );
 		return;
 	}
 
 	if ( priv->phyNum == 0 ) {
 		if ( ( priv->duplex == TLAN_DUPLEX_FULL ) || ( an_adv & an_lpa & 0x0040 ) ) {
 			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB | MII_GC_DUPLEX );
-			printk( "TLAN:  Starting internal PHY with DUPLEX\n" );
+			printk(KERN_INFO "TLAN:  Starting internal PHY with DUPLEX\n" );
 		} else {
 			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB );
-			printk( "TLAN:  Starting internal PHY with HALF-DUPLEX\n" );
+			printk(KERN_INFO "TLAN:  Starting internal PHY with HALF-DUPLEX\n" );
 		}
 	}
 
-	/* Wait for 10 jiffies (100 ms).  No reason in partiticular.
+	/* Wait for 100 ms.  No reason in partiticular.
 	 */
-	TLan_SetTimer( dev, 10, TLAN_TIMER_FINISH_RESET );
+	TLan_SetTimer( dev, (HZ/10), TLAN_TIMER_FINISH_RESET );
 		
 } /* TLan_PhyFinishAutoNeg */
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)