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
- Lines: 776
- Date:
Wed Feb 13 16:34:21 2002
- Orig file:
linux.orig/drivers/net/natsemi.c
- Orig date:
Mon Feb 18 20:18:39 2002
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)