patch-2.4.18 linux/drivers/net/natsemi.c

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

diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/natsemi.c linux/drivers/net/natsemi.c
@@ -100,7 +100,10 @@
 		* ETHTOOL_* further support (Tim Hockin)
 
 	version 1.0.13:
-		* ETHTOOL_[GS]EEPROM support (Tim Hockin)
+		* ETHTOOL_GEEPROM support (Tim Hockin)
+
+	version 1.0.14:
+		* Cleanup some messages and autoneg in ethtool (Tim Hockin)
 
 	TODO:
 	* big endian support with CFG:BEM instead of cpu_to_le32
@@ -108,9 +111,40 @@
 	* flow control
 */
 
+#if !defined(__OPTIMIZE__)
+#warning  You must compile this file with the correct options!
+#warning  See the last lines of the source file.
+#error You must compile this driver with "-O".
+#endif
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/ethtool.h>
+#include <linux/delay.h>
+#include <linux/rtnetlink.h>
+#include <linux/mii.h>
+#include <asm/processor.h>	/* Processor type for cache alignment. */
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
 #define DRV_NAME	"natsemi"
-#define DRV_VERSION	"1.07+LK1.0.13"
-#define DRV_RELDATE	"Oct 19, 2001"
+#define DRV_VERSION	"1.07+LK1.0.14"
+#define DRV_RELDATE	"Nov 27, 2001"
 
 /* Updated to recommendations in pci-skeleton v2.03. */
 
@@ -129,7 +163,12 @@
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
 
-static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
+#define NATSEMI_DEF_MSG		(NETIF_MSG_DRV		| \
+				 NETIF_MSG_LINK		| \
+				 NETIF_MSG_WOL		| \
+				 NETIF_MSG_RX_ERR	| \
+				 NETIF_MSG_TX_ERR)
+static int debug = NATSEMI_DEF_MSG;
 
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 20;
@@ -180,37 +219,6 @@
 
 #define PKT_BUF_SZ		1536 /* Size of each temporary Rx buffer. */
 
-#if !defined(__OPTIMIZE__)
-#warning  You must compile this file with the correct options!
-#warning  See the last lines of the source file.
-#error You must compile this driver with "-O".
-#endif
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/rtnetlink.h>
-#include <linux/mii.h>
-#include <asm/processor.h>	/* Processor type for cache alignment. */
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
 KERN_INFO DRV_NAME ".c:v1.07 1/9/2001  Written by Donald Becker <becker@scyld.com>\n"
@@ -229,7 +237,7 @@
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM_DESC(max_interrupt_work, "DP8381x maximum events handled per interrupt");
 MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)");
-MODULE_PARM_DESC(debug, "DP8381x debug level (0-5)");
+MODULE_PARM_DESC(debug, "DP8381x debug bitmask");
 MODULE_PARM_DESC(rx_copybreak, "DP8381x copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(options, "DP8381x: Bits 0-3: media type, bit 17: full duplex");
 MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)");
@@ -391,7 +399,11 @@
 	SDCFG			= 0xF8
 };
 /* the values for the 'magic' registers above (PGSEL=1) */
+#ifdef CONFIG_NATSEMI_CABLE_MAGIC
+#define PMDCSR_VAL	0x1898
+#else
 #define PMDCSR_VAL	0x189C
+#endif
 #define TSTDAT_VAL	0x0
 #define DSPCFG_VAL	0x5040
 #define SDCFG_VAL	0x008c
@@ -414,6 +426,7 @@
 enum ChipConfig_bits {
 	CfgPhyDis		= 0x200,
 	CfgPhyRst		= 0x400,
+	CfgExtPhy		= 0x1000,
 	CfgAnegEnable		= 0x2000,
 	CfgAneg100		= 0x4000,
 	CfgAnegFull		= 0x8000,
@@ -627,6 +640,7 @@
 	u16 advertising; /* NWay media advertisement */
 	unsigned int iosize;
 	spinlock_t lock;
+	u32 msg_enable;
 };
 
 static int eeprom_read(long ioaddr, int location);
@@ -746,6 +760,7 @@
 	pci_set_drvdata(pdev, dev);
 	np->iosize = iosize;
 	spin_lock_init(&np->lock);
+	np->msg_enable = debug;
 
 	/* Reset the chip to erase previous misconfiguration. */
 	natsemi_reload_eeprom(dev);
@@ -760,7 +775,8 @@
 		if (option & 0x200)
 			np->full_duplex = 1;
 		if (option & 15)
-			printk(KERN_INFO "%s: ignoring user supplied media type %d",
+			printk(KERN_INFO 
+				"%s: ignoring user supplied media type %d",
 				dev->name, option & 15);
 	}
 	if (find_cnt < MAX_UNITS  &&  full_duplex[find_cnt] > 0)
@@ -789,14 +805,17 @@
 	}
 	netif_carrier_off(dev);
 
-	printk(KERN_INFO "%s: %s at 0x%lx, ",
-		   dev->name, natsemi_pci_info[chip_idx].name, ioaddr);
-	for (i = 0; i < ETH_ALEN-1; i++)
-			printk("%2.2x:", dev->dev_addr[i]);
-	printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
+	if (netif_msg_drv(np)) {
+		printk(KERN_INFO "%s: %s at %#08lx, ",
+			   dev->name, natsemi_pci_info[chip_idx].name, ioaddr);
+		for (i = 0; i < ETH_ALEN-1; i++)
+				printk("%02x:", dev->dev_addr[i]);
+		printk("%02x, IRQ %d.\n", dev->dev_addr[i], irq);
+	}
 
 	np->advertising = mdio_read(dev, 1, MII_ADVERTISE);
-	if ((readl(ioaddr + ChipConfig) & 0xe000) != 0xe000) {
+	if ((readl(ioaddr + ChipConfig) & 0xe000) != 0xe000 
+	 && netif_msg_probe(np)) {
 		u32 chip_config = readl(ioaddr + ChipConfig);
 		printk(KERN_INFO "%s: Transceiver default autonegotiation %s "
 			   "10%s %s duplex.\n",
@@ -805,12 +824,18 @@
 			   chip_config & CfgAneg100 ? "0" : "",
 			   chip_config & CfgAnegFull ? "full" : "half");
 	}
-	printk(KERN_INFO "%s: Transceiver status 0x%4.4x advertising %4.4x.\n",
-		   dev->name, mdio_read(dev, 1, MII_BMSR), 
-		   np->advertising);
+	if (netif_msg_probe(np))
+		printk(KERN_INFO 
+			"%s: Transceiver status %#04x advertising %#04x.\n",
+			dev->name, mdio_read(dev, 1, MII_BMSR), 
+			np->advertising);
 
 	/* save the silicon revision for later querying */
 	np->srr = readl(ioaddr + SiliconRev);
+	if (netif_msg_hw(np))
+		printk(KERN_INFO "%s: silicon revision %#04x.\n",
+				dev->name, np->srr);
+
 
 	return 0;
 }
@@ -907,6 +932,7 @@
 	u32 rfcr;
 	u16 pmatch[3];
 	u16 sopass[3];
+	struct netdev_private *np = dev->priv;
 
 	/* 
 	 * Resetting the chip causes some registers to be lost.
@@ -940,10 +966,10 @@
 			break;
 		udelay(5);
 	}
-	if (i==NATSEMI_HW_TIMEOUT && debug) {
+	if (i==NATSEMI_HW_TIMEOUT && netif_msg_hw(np)) {
 		printk(KERN_INFO "%s: reset did not complete in %d usec.\n",
 		   dev->name, i*5);
-	} else if (debug > 2) {
+	} else if (netif_msg_hw(np)) {
 		printk(KERN_DEBUG "%s: reset completed in %d usec.\n",
 		   dev->name, i*5);
 	}
@@ -972,6 +998,7 @@
 
 static void natsemi_reload_eeprom(struct net_device *dev)
 {
+	struct netdev_private *np = dev->priv;
 	int i;
 
 	writel(EepromReload, dev->base_addr + PCIBusCfg);
@@ -980,10 +1007,10 @@
 			break;
 		udelay(5);
 	}
-	if (i==NATSEMI_HW_TIMEOUT && debug) {
+	if (i==NATSEMI_HW_TIMEOUT && netif_msg_hw(np)) {
 		printk(KERN_INFO "%s: EEPROM did not reload in %d usec.\n",
 		   dev->name, i*5);
-	} else if (debug > 2) {
+	} else if (netif_msg_hw(np)) {
 		printk(KERN_DEBUG "%s: EEPROM reloaded in %d usec.\n",
 		   dev->name, i*5);
 	}
@@ -992,6 +1019,7 @@
 static void natsemi_stop_rxtx(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
+	struct netdev_private *np = dev->priv;
 	int i;
 
 	writel(RxOff | TxOff, ioaddr + ChipCmd);
@@ -1000,10 +1028,10 @@
 			break;
 		udelay(5);
 	}
-	if (i==NATSEMI_HW_TIMEOUT && debug) {
+	if (i==NATSEMI_HW_TIMEOUT && netif_msg_hw(np)) {
 		printk(KERN_INFO "%s: Tx/Rx process did not stop in %d usec.\n",
 				dev->name, i*5);
-	} else if (debug > 2) {
+	} else if (netif_msg_hw(np)) {
 		printk(KERN_DEBUG "%s: Tx/Rx process stopped in %d usec.\n",
 				dev->name, i*5);
 	}
@@ -1021,7 +1049,7 @@
 	i = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev);
 	if (i) return i;
 
-	if (debug > 1)
+	if (netif_msg_ifup(np))
 		printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
 			   dev->name, dev->irq);
 	i = alloc_ring(dev);
@@ -1036,8 +1064,8 @@
 
 	netif_start_queue(dev);
 
-	if (debug > 2)
-		printk(KERN_DEBUG "%s: Done netdev_open(), status: %x.\n",
+	if (netif_msg_ifup(np))
+		printk(KERN_DEBUG "%s: Done netdev_open(), status: %#08x.\n",
 			   dev->name, (int)readl(ioaddr + ChipCmd));
 
 	/* Set the timer to check for link beat. */
@@ -1057,19 +1085,18 @@
 	int duplex;
 	int chipcfg = readl(ioaddr + ChipConfig);
 
-	if(!(chipcfg & CfgLink)) {
+	if (!(chipcfg & CfgLink)) {
 		if (netif_carrier_ok(dev)) {
-			if (debug)
-				printk(KERN_INFO "%s: no link. Disabling watchdog.\n",
+			if (netif_msg_link(np))
+				printk(KERN_NOTICE "%s: link down.\n", 
 					dev->name);
 			netif_carrier_off(dev);
 		}
 		return;
 	}
 	if (!netif_carrier_ok(dev)) {
-		if (debug)
-			printk(KERN_INFO "%s: link is back. Enabling watchdog.\n",
-					dev->name);
+		if (netif_msg_link(np))
+			printk(KERN_NOTICE "%s: link up.\n", dev->name);
 		netif_carrier_on(dev);
 	}
 
@@ -1077,10 +1104,11 @@
 
 	/* if duplex is set then bit 28 must be set, too */
 	if (duplex ^ !!(np->rx_config & RxAcceptTx)) {
-		if (debug)
-			printk(KERN_INFO "%s: Setting %s-duplex based on negotiated link"
-				   " capability.\n", dev->name,
-				   duplex ? "full" : "half");
+		if (netif_msg_link(np))
+			printk(KERN_INFO 
+				"%s: Setting %s-duplex based on negotiated "
+				"link capability.\n", dev->name,
+				duplex ? "full" : "half");
 		if (duplex) {
 			np->rx_config |= RxAcceptTx;
 			np->tx_config |= TxCarrierIgn | TxHeartIgn;
@@ -1099,17 +1127,12 @@
 	long ioaddr = dev->base_addr;
 	int i;
 
-	/* save the silicon revision for later */
-	if (debug > 4)
-		printk(KERN_DEBUG "%s: found silicon revision %xh.\n",
-				dev->name, np->srr);
-
 	for (i=0;i<NATSEMI_HW_TIMEOUT;i++) {
 		if (readl(dev->base_addr + ChipConfig) & CfgAnegDone)
 			break;
 		udelay(10);
 	}
-	if (i==NATSEMI_HW_TIMEOUT && debug) {
+	if (i==NATSEMI_HW_TIMEOUT && netif_msg_link(np)) {
 		printk(KERN_INFO 
 			"%s: autonegotiation did not complete in %d usec.\n",
 			dev->name, i*10);
@@ -1174,8 +1197,8 @@
 	 * nothing will be written to memory. */
 	np->SavedClkRun = readl(ioaddr + ClkRun);
 	writel(np->SavedClkRun & ~PMEEnable, ioaddr + ClkRun);
-	if (np->SavedClkRun & PMEStatus) {
-		printk(KERN_NOTICE "%s: Wake-up event %8.8x\n", 
+	if (np->SavedClkRun & PMEStatus && netif_msg_wol(np)) {
+		printk(KERN_NOTICE "%s: Wake-up event %#08x\n", 
 			dev->name, readl(ioaddr + WOLCmd));
 	}
 
@@ -1205,7 +1228,7 @@
 	long ioaddr = dev->base_addr;
 	u16 dspcfg;
 
-	if (debug > 3) {
+	if (netif_msg_timer(np)) {
 		/* DO NOT read the IntrStatus register, 
 		 * a read clears any pending interrupts.
 		 */
@@ -1219,9 +1242,9 @@
 	writew(0, ioaddr+PGSEL);
 	if (dspcfg != DSPCFG_VAL) {
 		if (!netif_queue_stopped(dev)) {
-			printk(KERN_INFO 
-				"%s: possible phy reset: re-initializing\n",
-				dev->name);
+			if (netif_msg_hw(np))
+				printk(KERN_NOTICE "%s: possible phy reset: "
+					"re-initializing\n", dev->name);
 			disable_irq(dev->irq);
 			spin_lock_irq(&np->lock);
 			init_registers(dev);
@@ -1244,18 +1267,18 @@
 {
 	struct netdev_private *np = dev->priv;
 
-	if (debug > 2) {
+	if (netif_msg_pktdata(np)) {
 		int i;
 		printk(KERN_DEBUG "  Tx ring at %p:\n", np->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++) {
-			printk(KERN_DEBUG " #%d desc. %8.8x %8.8x %8.8x.\n",
+			printk(KERN_DEBUG " #%d desc. %#08x %#08x %#08x.\n",
 				   i, np->tx_ring[i].next_desc,
 				   np->tx_ring[i].cmd_status, 
 				   np->tx_ring[i].addr);
 		}
 		printk(KERN_DEBUG "  Rx ring %p:\n", np->rx_ring);
 		for (i = 0; i < RX_RING_SIZE; i++) {
-			printk(KERN_DEBUG " #%d desc. %8.8x %8.8x %8.8x.\n",
+			printk(KERN_DEBUG " #%d desc. %#08x %#08x %#08x.\n",
 				   i, np->rx_ring[i].next_desc,
 				   np->rx_ring[i].cmd_status, 
 				   np->rx_ring[i].addr);
@@ -1271,9 +1294,11 @@
 	disable_irq(dev->irq);
 	spin_lock_irq(&np->lock);
 	if (netif_device_present(dev)) {
-		printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
-			" resetting...\n", 
-			dev->name, readl(ioaddr + IntrStatus));
+		if (netif_msg_tx_err(np))
+			printk(KERN_WARNING 
+				"%s: Transmit timed out, status %#08x,"
+				" resetting...\n", 
+				dev->name, readl(ioaddr + IntrStatus));
 		dump_ring(dev);
 
 		natsemi_reset(dev);
@@ -1431,7 +1456,7 @@
 
 	dev->trans_start = jiffies;
 
-	if (debug > 4) {
+	if (netif_msg_tx_queued(np)) {
 		printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
 			   dev->name, np->cur_tx, entry);
 	}
@@ -1444,14 +1469,11 @@
 
 	for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
 		int entry = np->dirty_tx % TX_RING_SIZE;
-		if (np->tx_ring[entry].cmd_status & cpu_to_le32(DescOwn)) {
-			if (debug > 4)
-				printk(KERN_DEBUG "%s: tx frame #%d is busy.\n",
-						dev->name, np->dirty_tx);
+		if (np->tx_ring[entry].cmd_status & cpu_to_le32(DescOwn))
 			break;
-		}
-		if (debug > 4)
-			printk(KERN_DEBUG "%s: tx frame #%d finished with status %8.8xh.\n",
+		if (netif_msg_tx_done(np))
+			printk(KERN_DEBUG 
+				"%s: tx frame #%d finished, status %#08x.\n",
 					dev->name, np->dirty_tx,
 					le32_to_cpu(np->tx_ring[entry].cmd_status));
 		if (np->tx_ring[entry].cmd_status & cpu_to_le32(DescPktOK)) {
@@ -1488,21 +1510,18 @@
 static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
 {
 	struct net_device *dev = dev_instance;
-	struct netdev_private *np;
-	long ioaddr;
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
 	int boguscnt = max_interrupt_work;
 
-	ioaddr = dev->base_addr;
-	np = dev->priv;
-	
 	if (!netif_device_present(dev))
 		return;
 	do {
 		/* Reading automatically acknowledges all int sources. */
 		u32 intr_status = readl(ioaddr + IntrStatus);
 
-		if (debug > 4)
-			printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n",
+		if (netif_msg_intr(np))
+			printk(KERN_DEBUG "%s: Interrupt, status %#08x.\n",
 				   dev->name, intr_status);
 
 		if (intr_status == 0)
@@ -1523,13 +1542,13 @@
 
 		if (--boguscnt < 0) {
 			printk(KERN_WARNING "%s: Too much work at interrupt, "
-				   "status=0x%4.4x.\n",
+				   "status=%#08x.\n",
 				   dev->name, intr_status);
 			break;
 		}
 	} while (1);
 
-	if (debug > 4)
+	if (netif_msg_intr(np))
 		printk(KERN_DEBUG "%s: exiting interrupt.\n",
 			   dev->name);
 }
@@ -1545,22 +1564,24 @@
 
 	/* If the driver owns the next entry it's a new packet. Send it up. */
 	while (desc_status < 0) {        /* e.g. & DescOwn */
-		if (debug > 4)
-			printk(KERN_DEBUG "  In netdev_rx() entry %d status was %8.8x.\n",
-				   entry, desc_status);
+		if (netif_msg_rx_status(np))
+			printk(KERN_DEBUG 
+				"  netdev_rx() entry %d status was %#08x.\n",
+				entry, desc_status);
 		if (--boguscnt < 0)
 			break;
-		if ((desc_status & (DescMore|DescPktOK|DescRxLong)) != DescPktOK) {
+		if ((desc_status&(DescMore|DescPktOK|DescRxLong)) != DescPktOK){
 			if (desc_status & DescMore) {
-				printk(KERN_WARNING "%s: Oversized(?) Ethernet frame spanned "
-					   "multiple buffers, entry %#x status %x.\n",
-					   dev->name, np->cur_rx, desc_status);
+				if (netif_msg_rx_err(np))
+					printk(KERN_WARNING 
+						"%s: Oversized(?) Ethernet "
+						"frame spanned multiple "
+						"buffers, entry %#08x "
+						"status %#08x.\n", dev->name, 
+						np->cur_rx, desc_status);
 				np->stats.rx_length_errors++;
 			} else {
-				/* There was a error. */
-				if (debug > 2)
-					printk(KERN_DEBUG "  netdev_rx() Rx error was %8.8x.\n",
-						   desc_status);
+				/* There was an error. */
 				np->stats.rx_errors++;
 				if (desc_status & (DescRxAbort|DescRxOver)) 
 					np->stats.rx_over_errors++;
@@ -1575,8 +1596,8 @@
 			struct sk_buff *skb;
 			/* Omit CRC size. */
 			int pkt_len = (desc_status & DescSizeMask) - 4;
-			/* Check if the packet is long enough to accept without copying
-			   to a minimally-sized skbuff. */
+			/* Check if the packet is long enough to accept 
+			 * without copying to a minimally-sized skbuff. */
 			if (pkt_len < rx_copybreak
 				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
 				skb->dev = dev;
@@ -1639,11 +1660,16 @@
 
 	spin_lock(&np->lock);
 	if (intr_status & LinkChange) {
-		printk(KERN_NOTICE 
-			"%s: Link changed: Autonegotiation advertising"
-			" %4.4x  partner %4.4x.\n", dev->name,
-			(int)mdio_read(dev, 1, MII_ADVERTISE), 
-			(int)mdio_read(dev, 1, MII_LPA));
+		u16 adv = mdio_read(dev, 1, MII_ADVERTISE);
+		u16 lpa = mdio_read(dev, 1, MII_LPA);
+		if (mdio_read(dev, 1, MII_BMCR) & BMCR_ANENABLE 
+		 && netif_msg_link(np)) {
+			printk(KERN_INFO 
+				"%s: Autonegotiation advertising"
+				" %#04x  partner %#04x.\n", dev->name,
+				adv, lpa);
+		}
+
 		/* read MII int status to clear the flag */
 		readw(ioaddr + MIntrStatus);
 		check_link(dev);
@@ -1654,18 +1680,19 @@
 	if (intr_status & IntrTxUnderrun) {
 		if ((np->tx_config & TxDrthMask) < 62)
 			np->tx_config += 2;
-		if (debug > 2)
-			printk(KERN_NOTICE "%s: increasing Tx theshold, new tx cfg %8.8xh.\n",
-					dev->name, np->tx_config);
+		if (netif_msg_tx_err(np))
+			printk(KERN_NOTICE 
+				"%s: increased Tx theshold, txcfg %#08x.\n",
+				dev->name, np->tx_config);
 		writel(np->tx_config, ioaddr + TxConfig);
 	}
-	if (intr_status & WOLPkt) {
+	if (intr_status & WOLPkt && netif_msg_wol(np)) {
 		int wol_status = readl(ioaddr + WOLCmd);
-		printk(KERN_NOTICE "%s: Link wake-up event %8.8x\n",
+		printk(KERN_NOTICE "%s: Link wake-up event %#08x\n",
 			   dev->name, wol_status);
 	}
 	if (intr_status & RxStatusFIFOOver) {
-		if (debug >= 2) {
+		if (netif_msg_rx_err(np) && netif_msg_intr(np)) {
 			printk(KERN_NOTICE "%s: Rx status FIFO overrun\n", 
 				dev->name);
 		}
@@ -1673,10 +1700,8 @@
 	}
 	/* Hmmmmm, it's not clear how to recover from PCI faults. */
 	if (intr_status & IntrPCIErr) {
-		if (debug) {
-			printk(KERN_NOTICE "%s: PCI error %08x\n", dev->name,
-				intr_status & IntrPCIErr);
-		}
+		printk(KERN_NOTICE "%s: PCI error %#08x\n", dev->name,
+			intr_status & IntrPCIErr);
 		np->stats.tx_fifo_errors++;
 		np->stats.rx_fifo_errors++;
 	}
@@ -1775,7 +1800,8 @@
 
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		/* Unconditionally log net taps. */
-		printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+		printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", 
+			dev->name);
 		rx_mode = RxFilterEnable | AcceptBroadcast 
 			| AcceptAllMulticast | AcceptAllPhys | AcceptMyPhys;
 	} else if ((dev->mc_count > multicast_filter_limit)
@@ -1910,7 +1936,7 @@
 	/* get message-level */
 	case ETHTOOL_GMSGLVL: {
 		struct ethtool_value edata = {ETHTOOL_GMSGLVL};
-		edata.data = debug;
+		edata.data = np->msg_enable;
 		if (copy_to_user(useraddr, &edata, sizeof(edata)))
 			return -EFAULT;
 		return 0;
@@ -1920,7 +1946,7 @@
 		struct ethtool_value edata;
 		if (copy_from_user(&edata, useraddr, sizeof(edata)))
 			return -EFAULT;
-		debug = edata.data;
+		np->msg_enable = edata.data;
 		return 0;
 	}
 	/* restart autonegotiation */
@@ -2108,18 +2134,22 @@
 	ecmd->supported = 
 		(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
 		SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
-		SUPPORTED_Autoneg | SUPPORTED_TP);
+		SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
 	
-	/* only supports twisted-pair */
-	ecmd->port = PORT_TP;
+	/* only supports twisted-pair or MII */
+	tmp = readl(dev->base_addr + ChipConfig);
+	if (tmp & CfgExtPhy)
+		ecmd->port = PORT_MII;
+	else
+		ecmd->port = PORT_TP;
 
 	/* only supports internal transceiver */
 	ecmd->transceiver = XCVR_INTERNAL;
 
-	/* this isn't fully supported at higher layers */
+	/* not sure what this is for */
 	ecmd->phy_address = readw(dev->base_addr + PhyCtrl) & PhyAddrMask;
 
-	ecmd->advertising = ADVERTISED_TP;
+	ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
 	tmp = mdio_read(dev, 1, MII_ADVERTISE);
 	if (tmp & ADVERTISE_10HALF)
 		ecmd->advertising |= ADVERTISED_10baseT_Half;
@@ -2130,20 +2160,21 @@
 	if (tmp & ADVERTISE_100FULL)
 		ecmd->advertising |= ADVERTISED_100baseT_Full;
 
-	tmp = readl(dev->base_addr + ChipConfig);
-	if (tmp & CfgAnegEnable) {
+	tmp = mdio_read(dev, 1, MII_BMCR);
+	if (tmp & BMCR_ANENABLE) {
 		ecmd->advertising |= ADVERTISED_Autoneg;
 		ecmd->autoneg = AUTONEG_ENABLE;
 	} else {
 		ecmd->autoneg = AUTONEG_DISABLE;
 	}
 
+	tmp = readl(dev->base_addr + ChipConfig);
 	if (tmp & CfgSpeed100) {
 		ecmd->speed = SPEED_100;
 	} else {
 		ecmd->speed = SPEED_10;
 	}
-
+		
 	if (tmp & CfgFullDuplex) {
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
@@ -2164,7 +2195,7 @@
 		return -EINVAL;
 	if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
 		return -EINVAL;
-	if (ecmd->port != PORT_TP)
+	if (ecmd->port != PORT_TP && ecmd->port != PORT_MII)
 		return -EINVAL;
 	if (ecmd->transceiver != XCVR_INTERNAL)
 		return -EINVAL;
@@ -2174,39 +2205,22 @@
 	
 	/* WHEW! now lets bang some bits */
 	
+	tmp = mdio_read(dev, 1, MII_BMCR);
 	if (ecmd->autoneg == AUTONEG_ENABLE) {
-		/* advertise only what has been requested */
-		tmp = readl(dev->base_addr + ChipConfig);
-		tmp &= ~(CfgAneg100 | CfgAnegFull);
-		tmp |= CfgAnegEnable;
-		if (ecmd->advertising & ADVERTISED_100baseT_Half 
-		 || ecmd->advertising & ADVERTISED_100baseT_Full) {
-			tmp |= CfgAneg100;
-		}
-		if (ecmd->advertising & ADVERTISED_10baseT_Full 
-		 || ecmd->advertising & ADVERTISED_100baseT_Full) {
-			tmp |= CfgAnegFull;
-		}
-		writel(tmp, dev->base_addr + ChipConfig);
-		/* turn on autonegotiation, and force a renegotiate */
-		tmp = mdio_read(dev, 1, MII_BMCR);
-		tmp |= (BMCR_ANENABLE | BMCR_ANRESTART);
-		mdio_write(dev, 1, MII_BMCR, tmp);
+		/* turn on autonegotiation */
+		tmp |= BMCR_ANENABLE;
 		np->advertising = mdio_read(dev, 1, MII_ADVERTISE);
 	} else {
 		/* turn off auto negotiation, set speed and duplexity */
-		tmp = mdio_read(dev, 1, MII_BMCR);
 		tmp &= ~(BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX);
-		if (ecmd->speed == SPEED_100) {
+		if (ecmd->speed == SPEED_100)
 			tmp |= BMCR_SPEED100;
-		}
-		if (ecmd->duplex == DUPLEX_FULL) {
+		if (ecmd->duplex == DUPLEX_FULL)
 			tmp |= BMCR_FULLDPLX;
-		} else {
+		else
 			np->full_duplex = 0;
-		}
-		mdio_write(dev, 1, MII_BMCR, tmp);
 	}
+	mdio_write(dev, 1, MII_BMCR, tmp);
 	return 0;
 }
 
@@ -2241,7 +2255,7 @@
 	/* the interrupt status is clear-on-read - see if we missed any */
 	if (rbuf[4] & rbuf[5]) {
 		printk(KERN_WARNING 
-			"%s: shoot, we dropped an interrupt (0x%x)\n", 
+			"%s: shoot, we dropped an interrupt (%#08x)\n", 
 			dev->name, rbuf[4] & rbuf[5]);
 	}
 
@@ -2308,7 +2322,7 @@
 	long ioaddr = dev->base_addr;
 	struct netdev_private *np = dev->priv;
 
-	if (debug > 1)
+	if (netif_msg_wol(np))
 		printk(KERN_INFO "%s: remaining active for wake-on-lan\n", 
 			dev->name);
 
@@ -2343,12 +2357,15 @@
 	netif_stop_queue(dev);
 	netif_carrier_off(dev);
 
-	if (debug > 1) {
-		printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
-			   dev->name, (int)readl(ioaddr + ChipCmd));
-		printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d,  Rx %d / %d.\n",
-			   dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx);
-	}
+	if (netif_msg_ifdown(np))
+		printk(KERN_DEBUG 
+			"%s: Shutting down ethercard, status was %#04x.\n",
+			dev->name, (int)readl(ioaddr + ChipCmd));
+	if (netif_msg_pktdata(np))
+		printk(KERN_DEBUG 
+			"%s: Queue pointers were Tx %d / %d,  Rx %d / %d.\n",
+			dev->name, np->cur_tx, np->dirty_tx, 
+			np->cur_rx, np->dirty_rx);
 
 	del_timer_sync(&np->timer);
 

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