patch-2.4.0-test7 linux/drivers/net/tlan.c
Next file: linux/drivers/net/tlan.h
Previous file: linux/drivers/net/sunlance.c
Back to the patch index
Back to the overall index
- Lines: 180
- Date:
Mon Aug 21 12:57:48 2000
- Orig file:
v2.4.0-test6/linux/drivers/net/tlan.c
- Orig date:
Fri Jun 23 21:55:09 2000
diff -u --recursive --new-file v2.4.0-test6/linux/drivers/net/tlan.c linux/drivers/net/tlan.c
@@ -97,6 +97,12 @@
*
* v1.8a May 28, 2000 - Minor updates.
*
+ * v1.9 July 25, 2000 - Fixed a few remaining Full-Duplex issues.
+ * - Updated with timer fixes from Andrew Morton.
+ * - Fixed module race in TLan_Open.
+ * - Added routine to monitor PHY status.
+ * - Added activity led support for Proliant devices.
+ *
*******************************************************************************/
@@ -138,7 +144,7 @@
static int bbuf = 0;
static u8 *TLanPadBuffer;
static char TLanSignature[] = "TLAN";
-static const char *tlan_banner = "ThunderLAN driver v1.8a\n";
+static const char *tlan_banner = "ThunderLAN driver v1.9\n";
const char *media[] = {
"10BaseT-HD ", "10BaseT-FD ","100baseTx-HD ",
@@ -181,7 +187,7 @@
{ PCI_VENDOR_ID_COMPAQ,
PCI_DEVICE_ID_NETELLIGENT_10_100_PROLIANT,
"Compaq Netelligent Integrated 10/100 TX UTP",
- TLAN_ADAPTER_NONE,
+ TLAN_ADAPTER_ACTIVITY_LED,
0x83
},
{ PCI_VENDOR_ID_COMPAQ,
@@ -272,6 +278,7 @@
static void TLan_PhyReset( struct net_device * );
static void TLan_PhyStartLink( struct net_device * );
static void TLan_PhyFinishAutoNeg( struct net_device * );
+static void TLan_PhyMonitor( struct net_device * );
/*
static int TLan_PhyNop( struct net_device * );
static int TLan_PhyInternalCheck( struct net_device * );
@@ -701,7 +708,8 @@
if ( err ) {
printk(KERN_ERR "TLAN: Cannot open %s because IRQ %d is already in use.\n", dev->name, dev->irq );
- return -EAGAIN;
+ MOD_DEC_USE_COUNT;
+ return err;
}
netif_start_queue(dev);
@@ -942,7 +950,7 @@
TLan_ReadAndClearStats( dev, TLAN_RECORD );
outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
if ( priv->timer.function != NULL ) {
- del_timer( &priv->timer );
+ del_timer_sync( &priv->timer );
priv->timer.function = NULL;
}
free_irq( dev->irq, dev );
@@ -1590,6 +1598,9 @@
priv->timer.function = NULL;
switch ( priv->timerType ) {
+ case TLAN_TIMER_LINK_BEAT:
+ TLan_PhyMonitor( dev );
+ break;
case TLAN_TIMER_PHY_PDOWN:
TLan_PhyPowerDown( dev );
break;
@@ -2041,6 +2052,12 @@
}
TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
+
+ /* We have link beat..for now anyway */
+ priv->link = 1;
+ /*Enabling link beat monitoring */
+ TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_LINK_BEAT );
+
}
}
@@ -2062,7 +2079,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 {
+
+ } else {
printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name );
TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET );
return;
@@ -2329,12 +2347,14 @@
TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0000);
} else if ( priv->speed == TLAN_SPEED_10 &&
priv->duplex == TLAN_DUPLEX_FULL) {
+ priv->tlanFullDuplex = TRUE;
TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100);
} else if ( priv->speed == TLAN_SPEED_100 &&
priv->duplex == TLAN_DUPLEX_HALF) {
TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000);
} else if ( priv->speed == TLAN_SPEED_100 &&
priv->duplex == TLAN_DUPLEX_FULL) {
+ priv->tlanFullDuplex = TRUE;
TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100);
} else {
@@ -2418,9 +2438,9 @@
TLan_MiiReadReg( dev, phy, MII_AN_LPA, &an_lpa );
mode = an_adv & an_lpa & 0x03E0;
if ( mode & 0x0100 ) {
- priv->tlanFullDuplex = TRUE;
+ priv->tlanFullDuplex = TRUE;
} else if ( ! ( mode & 0x0080 ) && ( mode & 0x0040 ) ) {
- priv->tlanFullDuplex = TRUE;
+ priv->tlanFullDuplex = TRUE;
}
if ( ( ! ( mode & 0x0180 ) ) && ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) && ( priv->phyNum != 0 ) ) {
@@ -2448,6 +2468,61 @@
} /* TLan_PhyFinishAutoNeg */
+
+
+ /*********************************************************************
+ *
+ * TLan_PhyMonitor
+ *
+ * Returns:
+ * None
+ *
+ * Params:
+ * dev The device structure of this device.
+ *
+ *
+ * This function monitors PHY condition by reading the status
+ * register via the MII bus. This can be used to give info
+ * about link changes (up/down), and possible switch to alternate
+ * media.
+ *
+ * ******************************************************************/
+
+void TLan_PhyMonitor( struct net_device *dev )
+{
+ TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv;
+ u16 phy;
+ u16 phy_status;
+
+ phy = priv->phy[priv->phyNum];
+
+ /* Get PHY status register */
+ TLan_MiiReadReg( dev, phy, MII_GEN_STS, &phy_status );
+
+ /* Check if link has been lost */
+ if (!(phy_status & MII_GS_LINK)) {
+ if (priv->link) {
+ priv->link = 0;
+ printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name);
+ dev->flags &= ~IFF_RUNNING;
+ TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
+ return;
+ }
+ }
+
+ /* Link restablished? */
+ if ((phy_status & MII_GS_LINK) && !priv->link) {
+ priv->link = 1;
+ printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name);
+ dev->flags |= IFF_RUNNING;
+ TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
+ }
+
+ /* Setup a new monitor */
+ TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
+
+}
+
/*****************************************************************************
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)