--- kmi/drivers/net/cs89x0_0.c
+++ usgs/drivers/net/cs89x0_0.c
@@ -22,3 +22,3 @@
  */
-#define DEBUGGING	0
+#define DEBUGGING	1
 
@@ -107,2 +107,5 @@
 
+#define CS_TIMER_LINK		(60 * HZ)
+#define CS_TIMER_NO_LINK	(5 * HZ)
+
 /* Information that need to be kept for each board. */
@@ -124,2 +127,3 @@
     spinlock_t lock;
+    struct timer_list	media_timer;
 };
@@ -149,2 +153,3 @@
 #endif
+static void cs_media_timer(unsigned long data);
 
@@ -472,4 +477,6 @@
 #endif
-
     }
+    init_timer(&lp->media_timer);
+    lp->media_timer.function = cs_media_timer;
+    lp->media_timer.data = (unsigned long) dev;
 
@@ -763,4 +770,2 @@
     printk("\n");
-    if (net_debug)
-        printk("cs89x0_probe1() successful\n");
 
@@ -769,3 +774,7 @@
         goto out3;
+
+    if (net_debug)
+        printk("cs89x0_probe1() successful\n");
     return (0);
+
     out3:
@@ -914,2 +923,59 @@
 
+static void cs_stop_hw(struct net_device *dev)
+{
+
+    udelay(5);
+
+    writereg(dev, PP_RxCFG, 0);
+    writereg(dev, PP_TxCFG, 0);
+    writereg(dev, PP_BufCFG, 0);
+    writereg(dev, PP_BusCTL, 0);
+
+    udelay(10);
+}
+
+static void cs_link_up(struct net_device *dev)
+{
+    if (!netif_carrier_ok(dev)) {
+	netif_carrier_on(dev);
+	printk(KERN_INFO "%s: link up\n", dev->name);
+    }
+}
+
+static void cs_link_down(struct net_device *dev)
+{
+    if (netif_carrier_ok(dev)) {
+	netif_carrier_off(dev);
+	printk(KERN_INFO "%s: link down\n", dev->name);
+    }
+}
+
+static void cs_media_timer(unsigned long data)
+{
+    struct net_device *dev = (struct net_device *) data;
+    struct net_local *lp = netdev_priv(dev);
+    unsigned int carrier;
+
+    /* Normally multiple media checks would be done, but */
+    /* KMI_ROCK_PXA forces 10Base-T, half-duplex         */
+    carrier = ( readreg(dev, PP_LineST) & ( LINK_OK | TENBASET_ON ) ) ==
+	      ( LINK_OK | TENBASET_ON );
+
+    if (carrier) {
+	if (!netif_carrier_ok(dev))
+	    cs_link_up(dev);
+	else if (net_debug > 1)
+	    printk("%s: link ok\n", dev->name);
+	lp->media_timer.expires = jiffies + CS_TIMER_LINK;
+	add_timer(&lp->media_timer);
+    } else {
+	if (netif_carrier_ok(dev))
+	    cs_link_down(dev);
+	else if (net_debug > 1)
+	    printk(KERN_INFO "%s: no link, try later\n", dev->name);
+	lp->media_timer.expires = jiffies + CS_TIMER_NO_LINK;
+	add_timer(&lp->media_timer);
+    }
+}
+
 /* send a test packet - return true if carrier bits are ok */
@@ -1029,2 +1095,5 @@
 
+    if (net_debug)
+	printk("%s: enabling interface\n", dev->name);
+
     if (dev->irq < 2)
@@ -1207,3 +1276,6 @@
             );
+
     netif_start_queue(dev);
+    mod_timer(&lp->media_timer, jiffies + CS_TIMER_NO_LINK);
+
     if (net_debug > 1)
@@ -1211,2 +1283,3 @@
     return(0);
+
     bad_out:
@@ -1425,8 +1498,15 @@
 {
-    netif_stop_queue(dev);
+    struct net_local *lp = netdev_priv(dev);
+    unsigned long flags;
 
-    writereg(dev, PP_RxCFG, 0);
-    writereg(dev, PP_TxCFG, 0);
-    writereg(dev, PP_BufCFG, 0);
-    writereg(dev, PP_BusCTL, 0);
+    if (net_debug)
+	printk("%s: disabling interface\n", dev->name);
+
+    del_timer_sync(&lp->media_timer);
+
+    spin_lock_irqsave(&lp->lock, flags);
+    cs_stop_hw(dev);
+    netif_stop_queue(dev);
+    netif_carrier_off(dev);
+    spin_unlock_irqrestore(&lp->lock, flags);
 
@@ -1508,2 +1588,16 @@
 
+/*
+ * Support the 'debug' module parm even if we're compiled for non-debug to
+ * avoid breaking someone's startup scripts
+ */
+
+static int debug;
+
+module_param(debug, int, 0);
+#if DEBUGGING
+MODULE_PARM_DESC(debug, "cs89x0 debug level (0-6)");
+#else
+MODULE_PARM_DESC(debug, "(ignored)");
+#endif
+
 MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton");
@@ -1517,2 +1611,8 @@
 
+#if DEBUGGING
+    net_debug = debug;
+#else
+    debug = 0;
+#endif
+
     dev = alloc_etherdev(sizeof(struct net_local));
--- kmi/drivers/net/cs89x0_1.c
+++ usgs/drivers/net/cs89x0_1.c
@@ -22,3 +22,3 @@
  */
-#define DEBUGGING	0
+#define DEBUGGING	1
 
@@ -107,2 +107,5 @@
 
+#define CS_TIMER_LINK		(60 * HZ)
+#define CS_TIMER_NO_LINK	(5 * HZ)
+
 /* Information that need to be kept for each board. */
@@ -124,2 +127,3 @@
     spinlock_t lock;
+    struct timer_list	media_timer;
 };
@@ -149,2 +153,3 @@
 #endif
+static void cs_media_timer(unsigned long data);
 
@@ -472,4 +477,6 @@
 #endif
-
     }
+    init_timer(&lp->media_timer);
+    lp->media_timer.function = cs_media_timer;
+    lp->media_timer.data = (unsigned long) dev;
 
@@ -763,4 +770,2 @@
     printk("\n");
-    if (net_debug)
-        printk("cs89x0_probe1() successful\n");
 
@@ -769,3 +774,7 @@
         goto out3;
-    return(0);
+
+    if (net_debug)
+        printk("cs89x0_probe1() successful\n");
+    return (0);
+
     out3:
@@ -775,3 +784,3 @@
     out1:
-    return(retval);
+    return (retval);
 }
@@ -914,2 +923,59 @@
 
+static void cs_stop_hw(struct net_device *dev)
+{
+
+    udelay(5);
+
+    writereg(dev, PP_RxCFG, 0);
+    writereg(dev, PP_TxCFG, 0);
+    writereg(dev, PP_BufCFG, 0);
+    writereg(dev, PP_BusCTL, 0);
+
+    udelay(10);
+}
+
+static void cs_link_up(struct net_device *dev)
+{
+    if (!netif_carrier_ok(dev)) {
+	netif_carrier_on(dev);
+	printk(KERN_INFO "%s: link up\n", dev->name);
+    }
+}
+
+static void cs_link_down(struct net_device *dev)
+{
+    if (netif_carrier_ok(dev)) {
+	netif_carrier_off(dev);
+	printk(KERN_INFO "%s: link down\n", dev->name);
+    }
+}
+
+static void cs_media_timer(unsigned long data)
+{
+    struct net_device *dev = (struct net_device *) data;
+    struct net_local *lp = netdev_priv(dev);
+    unsigned int carrier;
+
+    /* Normally multiple media checks would be done, but */
+    /* KMI_ROCK_PXA forces 10Base-T, half-duplex         */
+    carrier = ( readreg(dev, PP_LineST) & ( LINK_OK | TENBASET_ON ) ) ==
+	      ( LINK_OK | TENBASET_ON );
+
+    if (carrier) {
+	if (!netif_carrier_ok(dev))
+	    cs_link_up(dev);
+	else if (net_debug > 1)
+	    printk("%s: link ok\n", dev->name);
+	lp->media_timer.expires = jiffies + CS_TIMER_LINK;
+	add_timer(&lp->media_timer);
+    } else {
+	if (netif_carrier_ok(dev))
+	    cs_link_down(dev);
+	else if (net_debug > 1)
+	    printk(KERN_INFO "%s: no link, try later\n", dev->name);
+	lp->media_timer.expires = jiffies + CS_TIMER_NO_LINK;
+	add_timer(&lp->media_timer);
+    }
+}
+
 /* send a test packet - return true if carrier bits are ok */
@@ -1029,2 +1095,5 @@
 
+    if (net_debug)
+	printk("%s: enabling interface\n", dev->name);
+
     if (dev->irq < 2)
@@ -1207,3 +1276,6 @@
             );
+
     netif_start_queue(dev);
+    mod_timer(&lp->media_timer, jiffies + CS_TIMER_NO_LINK);
+
     if (net_debug > 1)
@@ -1211,2 +1283,3 @@
     return(0);
+
     bad_out:
@@ -1425,8 +1498,15 @@
 {
-    netif_stop_queue(dev);
+    struct net_local *lp = netdev_priv(dev);
+    unsigned long flags;
 
-    writereg(dev, PP_RxCFG, 0);
-    writereg(dev, PP_TxCFG, 0);
-    writereg(dev, PP_BufCFG, 0);
-    writereg(dev, PP_BusCTL, 0);
+    if (net_debug)
+	printk("%s: disabling interface\n", dev->name);
+
+    del_timer_sync(&lp->media_timer);
+
+    spin_lock_irqsave(&lp->lock, flags);
+    cs_stop_hw(dev);
+    netif_stop_queue(dev);
+    netif_carrier_off(dev);
+    spin_unlock_irqrestore(&lp->lock, flags);
 
@@ -1508,2 +1588,16 @@
 
+/*
+ * Support the 'debug' module parm even if we're compiled for non-debug to
+ * avoid breaking someone's startup scripts
+ */
+
+static int debug;
+
+module_param(debug, int, 0);
+#if DEBUGGING
+MODULE_PARM_DESC(debug, "cs89x0 debug level (0-6)");
+#else
+MODULE_PARM_DESC(debug, "(ignored)");
+#endif
+
 MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton");
@@ -1517,2 +1611,8 @@
 
+#if DEBUGGING
+    net_debug = debug;
+#else
+    debug = 0;
+#endif
+
     dev = alloc_etherdev(sizeof(struct net_local));