# --------------------------------------------
# 02/10/16	thockin@freakshow.cobalt.com	1.737.3.3
# drivers/net/eepro100.c:
# * use netif_msg_xxx() instead of speedo_debug
# * better default debug mask, proper use of debug module param
# * add ETHTOOL_[GS]MSGLVL
# --------------------------------------------
#
diff -Nru a/drivers/net/eepro100.c b/drivers/net/eepro100.c
--- a/drivers/net/eepro100.c	Wed Oct 23 21:16:33 2002
+++ b/drivers/net/eepro100.c	Wed Oct 23 21:16:33 2002
@@ -65,7 +65,6 @@
    e.g. "options=16" for FD, "options=32" for 100mbps-only. */
 static int full_duplex[] = {-1, -1, -1, -1, -1, -1, -1, -1};
 static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int debug = -1;			/* The debug level */
 
 /* A few values that may be tweaked. */
 /* The ring sizes should be a power of two for efficiency. */
@@ -121,6 +120,15 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 
+static int debug = -1;
+#define DEBUG_DEFAULT		(NETIF_MSG_DRV		| \
+				 NETIF_MSG_IFDOWN	| \
+				 NETIF_MSG_IFUP		| \
+				 NETIF_MSG_RX_ERR	| \
+				 NETIF_MSG_TX_ERR)
+#define DEBUG			((debug >= 0) ? (1<<debug)-1 : DEBUG_DEFAULT)
+
+
 MODULE_AUTHOR("Maintainer: Andrey V. Savochkin <saw@saw.sw.com.sg>");
 MODULE_DESCRIPTION("Intel i82557/i82558/i82559 PCI EtherExpressPro driver");
 MODULE_LICENSE("GPL");
@@ -168,7 +176,6 @@
 								} while(0)
 
 
-static int speedo_debug = 1;
 
 /*
 				Theory of Operation
@@ -496,6 +503,7 @@
 	unsigned short phy[2];			/* PHY media interfaces available. */
 	unsigned short partner;			/* Link partner caps. */
 	struct mii_if_info mii_if;		/* MII API hooks, info */
+	u32 msg_enable;				/* debug message level */
 #ifdef CONFIG_PM
 	u32 pm_state[16];
 #endif
@@ -566,9 +574,12 @@
 	int acpi_idle_state = 0, pm;
 	static int cards_found /* = 0 */;
 
-	static int did_version /* = 0 */;		/* Already printed version info. */
-	if (speedo_debug > 0  &&  did_version++ == 0)
+#ifndef MODULE
+	/* when built-in, we only print version if device is found */
+	static int did_version;
+	if (did_version++ == 0)
 		printk(version);
+#endif
 
 	/* save power state before pci_enable_device overwrites it */
 	pm = pci_find_capability(pdev, PCI_CAP_ID_PM);
@@ -597,7 +608,7 @@
 	irq = pdev->irq;
 #ifdef USE_IO
 	ioaddr = pci_resource_start(pdev, 1);
-	if (speedo_debug > 2)
+	if (DEBUG & NETIF_MSG_PROBE)
 		printk("Found Intel i82557 PCI Speedo at I/O %#lx, IRQ %d.\n",
 			   ioaddr, irq);
 #else
@@ -608,7 +619,7 @@
 				pci_resource_len(pdev, 0), pci_resource_start(pdev, 0));
 		goto err_out_free_mmio_region;
 	}
-	if (speedo_debug > 2)
+	if (DEBUG & NETIF_MSG_PROBE)
 		printk("Found Intel i82557 PCI Speedo, MMIO at %#lx, IRQ %d.\n",
 			   pci_resource_start(pdev, 0), irq);
 #endif
@@ -814,6 +825,7 @@
 
 	sp = dev->priv;
 	sp->pdev = pdev;
+	sp->msg_enable = DEBUG;
 	sp->acpi_pwr = acpi_idle_state;
 	sp->tx_ring = tx_ring_space;
 	sp->tx_ring_dma = tx_ring_dma;
@@ -959,7 +971,7 @@
 	long ioaddr = dev->base_addr;
 	int retval;
 
-	if (speedo_debug > 1)
+	if (netif_msg_ifup(sp))
 		printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq);
 
 	pci_set_power_state(sp->pdev, 0);
@@ -1018,7 +1030,7 @@
 
 	mii_check_link(&sp->mii_if);
 
-	if (speedo_debug > 2) {
+	if (netif_msg_ifup(sp)) {
 		printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n",
 			   dev->name, inw(ioaddr + SCBStatus));
 	}
@@ -1073,7 +1085,7 @@
 	wait_for_cmd_done(ioaddr + SCBCmd);
 
 	if (sp->rx_ringp[sp->cur_rx % RX_RING_SIZE] == NULL) {
-		if (speedo_debug > 2)
+		if (netif_msg_rx_err(sp))
 			printk(KERN_DEBUG "%s: NULL cur_rx in speedo_resume().\n",
 					dev->name);
 	} else {
@@ -1168,7 +1180,7 @@
 		int partner = mdio_read(dev, phy_num, MII_LPA);
 		if (partner != sp->partner) {
 			int flow_ctrl = sp->mii_if.advertising & partner & 0x0400 ? 1 : 0;
-			if (speedo_debug > 2) {
+			if (netif_msg_link(sp)) {
 				printk(KERN_DEBUG "%s: Link status change.\n", dev->name);
 				printk(KERN_DEBUG "%s: Old partner %x, new %x, adv %x.\n",
 					   dev->name, sp->partner, partner, sp->mii_if.advertising);
@@ -1181,7 +1193,7 @@
 		}
 	}
 	mii_check_link(&sp->mii_if);
-	if (speedo_debug > 3) {
+	if (netif_msg_timer(sp)) {
 		printk(KERN_DEBUG "%s: Media control tick, status %4.4x.\n",
 			   dev->name, inw(ioaddr + SCBStatus));
 	}
@@ -1190,7 +1202,7 @@
 		/* We haven't received a packet in a Long Time.  We might have been
 		   bitten by the receiver hang bug.  This can be cleared by sending
 		   a set multicast list command. */
-		if (speedo_debug > 3)
+		if (netif_msg_rx_err(sp))
 			printk(KERN_DEBUG "%s: Sending a multicast list set command"
 				   " from a timer routine,"
 				   " m=%d, j=%ld, l=%ld.\n",
@@ -1211,20 +1223,17 @@
 	int i;
 
 	/* Print a few items for debugging. */
-	if (speedo_debug > 0) {
-		int i;
-		printk(KERN_DEBUG "%s: Tx ring dump,  Tx queue %u / %u:\n", dev->name,
-			   sp->cur_tx, sp->dirty_tx);
-		for (i = 0; i < TX_RING_SIZE; i++)
-			printk(KERN_DEBUG "%s:  %c%c%2d %8.8x.\n", dev->name,
-				   i == sp->dirty_tx % TX_RING_SIZE ? '*' : ' ',
-				   i == sp->cur_tx % TX_RING_SIZE ? '=' : ' ',
-				   i, sp->tx_ring[i].status);
-	}
+	printk(KERN_DEBUG "%s: Tx ring dump,  Tx queue %u / %u:\n", dev->name,
+		   sp->cur_tx, sp->dirty_tx);
+	for (i = 0; i < TX_RING_SIZE; i++)
+		printk(KERN_DEBUG "%s:  %c%c%2d %8.8x.\n", dev->name,
+			   i == sp->dirty_tx % TX_RING_SIZE ? '*' : ' ',
+			   i == sp->cur_tx % TX_RING_SIZE ? '=' : ' ',
+			   i, sp->tx_ring[i].status);
+
 	printk(KERN_DEBUG "%s: Printing Rx ring"
 		   " (next to receive into %u, dirty index %u).\n",
 		   dev->name, sp->cur_rx, sp->dirty_rx);
-
 	for (i = 0; i < RX_RING_SIZE; i++)
 		printk(KERN_DEBUG "%s: %c%c%c%2d %8.8x.\n", dev->name,
 			   sp->rx_ringp[i] == sp->last_rxf ? 'l' : ' ',
@@ -1317,7 +1326,7 @@
 	}
 	while (sp->mc_setup_head != NULL) {
 		struct speedo_mc_block *t;
-		if (speedo_debug > 1)
+		if (netif_msg_tx_err(sp))
 			printk(KERN_DEBUG "%s: freeing mc frame.\n", dev->name);
 		pci_unmap_single(sp->pdev, sp->mc_setup_head->frame_dma,
 				sp->mc_setup_head->len, PCI_DMA_TODEVICE);
@@ -1360,13 +1369,15 @@
 	int status = inw(ioaddr + SCBStatus);
 	unsigned long flags;
 
-	printk(KERN_WARNING "%s: Transmit timed out: status %4.4x "
+	if (netif_msg_tx_err(sp)) {
+		printk(KERN_WARNING "%s: Transmit timed out: status %4.4x "
 		   " %4.4x at %d/%d command %8.8x.\n",
 		   dev->name, status, inw(ioaddr + SCBCmd),
 		   sp->dirty_tx, sp->cur_tx,
 		   sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status);
 
-	speedo_show_state(dev);
+		speedo_show_state(dev);
+	}
 #if 0
 	if ((status & 0x00C0) != 0x0080
 		&&  (status & 0x003C) == 0x0010) {
@@ -1493,14 +1504,14 @@
 		int entry = dirty_tx % TX_RING_SIZE;
 		int status = le32_to_cpu(sp->tx_ring[entry].status);
 
-		if (speedo_debug > 5)
+		if (netif_msg_tx_done(sp))
 			printk(KERN_DEBUG " scavenge candidate %d status %4.4x.\n",
 				   entry, status);
 		if ((status & StatusComplete) == 0)
 			break;			/* It still hasn't been processed. */
 		if (status & TxUnderrun)
 			if (sp->tx_threshold < 0x01e08000) {
-				if (speedo_debug > 2)
+				if (netif_msg_tx_err(sp))
 					printk(KERN_DEBUG "%s: TX underrun, threshold adjusted.\n",
 						   dev->name);
 				sp->tx_threshold += 0x00040000;
@@ -1518,7 +1529,7 @@
 		dirty_tx++;
 	}
 
-	if (speedo_debug && (int)(sp->cur_tx - dirty_tx) > TX_RING_SIZE) {
+	if (netif_msg_tx_err(sp) && (int)(sp->cur_tx - dirty_tx) > TX_RING_SIZE) {
 		printk(KERN_ERR "out-of-sync dirty pointer, %d vs. %d,"
 			   " full=%d.\n",
 			   dirty_tx, sp->cur_tx, sp->tx_full);
@@ -1528,7 +1539,7 @@
 	while (sp->mc_setup_head != NULL
 		   && (int)(dirty_tx - sp->mc_setup_head->tx - 1) > 0) {
 		struct speedo_mc_block *t;
-		if (speedo_debug > 1)
+		if (netif_msg_tx_err(sp))
 			printk(KERN_DEBUG "%s: freeing mc frame.\n", dev->name);
 		pci_unmap_single(sp->pdev, sp->mc_setup_head->frame_dma,
 				sp->mc_setup_head->len, PCI_DMA_TODEVICE);
@@ -1578,7 +1589,7 @@
 		   FCP and ER interrupts --Dragan */
 		outw(status & 0xfc00, ioaddr + SCBStatus);
 
-		if (speedo_debug > 4)
+		if (netif_msg_intr(sp))
 			printk(KERN_DEBUG "%s: interrupt  status=%#4.4x.\n",
 				   dev->name, status);
 
@@ -1640,7 +1651,7 @@
 		}
 	} while (1);
 
-	if (speedo_debug > 3)
+	if (netif_msg_intr(sp))
 		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
 			   dev->name, inw(ioaddr + SCBStatus));
 
@@ -1701,7 +1712,7 @@
 		if (rxf == NULL) {
 			unsigned int forw;
 			int forw_entry;
-			if (speedo_debug > 2 || !(sp->rx_ring_state & RrOOMReported)) {
+			if (netif_msg_rx_err(sp) || !(sp->rx_ring_state & RrOOMReported)) {
 				printk(KERN_WARNING "%s: can't fill rx buffer (force %d)!\n",
 						dev->name, force);
 				speedo_show_state(dev);
@@ -1748,7 +1759,7 @@
 	int rx_work_limit = sp->dirty_rx + RX_RING_SIZE - sp->cur_rx;
 	int alloc_ok = 1;
 
-	if (speedo_debug > 4)
+	if (netif_msg_intr(sp))
 		printk(KERN_DEBUG " In speedo_rx().\n");
 	/* If we own the next entry, it's a new packet. Send it up. */
 	while (sp->rx_ringp[entry] != NULL) {
@@ -1771,14 +1782,14 @@
 		if (sp->last_rxf == sp->rx_ringp[entry]) {
 			/* Postpone the packet.  It'll be reaped at an interrupt when this
 			   packet is no longer the last packet in the ring. */
-			if (speedo_debug > 2)
+			if (netif_msg_rx_err(sp))
 				printk(KERN_DEBUG "%s: RX packet postponed!\n",
 					   dev->name);
 			sp->rx_ring_state |= RrPostponed;
 			break;
 		}
 
-		if (speedo_debug > 4)
+		if (netif_msg_intr(sp))
 			printk(KERN_DEBUG "  speedo_rx() status %8.8x len %d.\n", status,
 				   pkt_len);
 		if ((status & (RxErrTooBig|RxOK|0x0f90)) != RxOK) {
@@ -1858,7 +1869,7 @@
 	netdevice_stop(dev);
 	netif_stop_queue(dev);
 
-	if (speedo_debug > 1)
+	if (netif_msg_ifdown(sp))
 		printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
 			   dev->name, inw(ioaddr + SCBStatus));
 
@@ -1871,7 +1882,7 @@
 	free_irq(dev->irq, dev);
 
 	/* Print a few items for debugging. */
-	if (speedo_debug > 3)
+	if (netif_msg_ifdown(sp))
 		speedo_show_state(dev);
 
     /* Free all the skbuffs in the Rx and Tx queues. */
@@ -1907,7 +1918,7 @@
 		sp->mc_setup_head = t;
 	}
 	sp->mc_setup_tail = NULL;
-	if (speedo_debug > 0)
+	if (netif_msg_ifdown(sp))
 		printk(KERN_DEBUG "%s: %d multicast blocks dropped.\n", dev->name, i);
 
 	pci_set_power_state(sp->pdev, 2);
@@ -2010,6 +2021,22 @@
 			return -EFAULT;
 		return 0;
 	}
+	/* get message-level */
+	case ETHTOOL_GMSGLVL: {
+		struct ethtool_value edata = {ETHTOOL_GMSGLVL};
+		edata.data = sp->msg_enable;
+		if (copy_to_user(useraddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	/* set message-level */
+	case ETHTOOL_SMSGLVL: {
+		struct ethtool_value edata;
+		if (copy_from_user(&edata, useraddr, sizeof(edata)))
+			return -EFAULT;
+		sp->msg_enable = edata.data;
+		return 0;
+	}
 
         }
 	
@@ -2087,7 +2114,7 @@
 	} else
 		new_rx_mode = 0;
 
-	if (speedo_debug > 3)
+	if (netif_msg_rx_status(sp))
 		printk(KERN_DEBUG "%s: set_rx_mode %d -> %d\n", dev->name,
 				sp->rx_mode, new_rx_mode);
 
@@ -2198,7 +2225,7 @@
 		mc_setup_frm = &mc_blk->frame;
 
 		/* Fill the setup frame. */
-		if (speedo_debug > 1)
+		if (netif_msg_ifup(sp))
 			printk(KERN_DEBUG "%s: Constructing a setup frame at %p.\n",
 				   dev->name, mc_setup_frm);
 		mc_setup_frm->cmd_status =
@@ -2252,7 +2279,7 @@
 		}
 		spin_unlock_irqrestore(&sp->lock, flags);
 
-		if (speedo_debug > 5)
+		if (netif_msg_rx_status(sp))
 			printk(" CmdMCSetup frame length %d in entry %d.\n",
 				   dev->mc_count, entry);
 	}
@@ -2395,11 +2422,9 @@
 
 static int __init eepro100_init_module(void)
 {
-	if (debug >= 0 && speedo_debug != debug)
-		printk(KERN_INFO "eepro100.c: Debug level is %d.\n", debug);
-	if (debug >= 0)
-		speedo_debug = debug;
-
+#ifdef MODULE
+	printk(version);
+#endif
 	return pci_module_init(&eepro100_driver);
 }
 
