patch-2.4.19 linux-2.4.19/drivers/net/via-rhine.c
Next file: linux-2.4.19/drivers/net/wan/8253x/8253x.h
Previous file: linux-2.4.19/drivers/net/tun.c
Back to the patch index
Back to the overall index
- Lines: 277
- Date:
Fri Aug 2 17:39:44 2002
- Orig file:
linux-2.4.18/drivers/net/via-rhine.c
- Orig date:
Mon Feb 25 11:38:00 2002
diff -urN linux-2.4.18/drivers/net/via-rhine.c linux-2.4.19/drivers/net/via-rhine.c
@@ -9,8 +9,8 @@
a complete program and may only be used when the entire operating
system is licensed under the GPL.
- This driver is designed for the VIA VT86c100A Rhine-II PCI Fast Ethernet
- controller. It also works with the older 3043 Rhine-I chip.
+ This driver is designed for the VIA VT86C100A Rhine-I.
+ It also works with the 6102 Rhine-II, and 6105/6105M Rhine-III.
The author may be reached as becker@scyld.com, or C/O
Scyld Computing Corporation
@@ -81,11 +81,24 @@
- Add ethtool support
- Replace some MII-related magic numbers with constants
+ LK1.1.14 (Ivan G.):
+ - fixes comments for Rhine-III
+ - removes W_MAX_TIMEOUT (unused)
+ - adds HasDavicomPhy for Rhine-I (basis: linuxfet driver; my card
+ is R-I and has Davicom chip, flag is referenced in kernel driver)
+ - sends chip_id as a parameter to wait_for_reset since np is not
+ initialized on first call
+ - changes mmio "else if (chip_id==VT6102)" to "else" so it will work
+ for Rhine-III's (documentation says same bit is correct)
+ - transmit frame queue message is off by one - fixed
+ - adds IntrNormalSummary to "Something Wicked" exclusion list
+ so normal interrupts will not trigger the message (src: Donald Becker)
+
*/
#define DRV_NAME "via-rhine"
-#define DRV_VERSION "1.1.13"
-#define DRV_RELDATE "Nov-17-2001"
+#define DRV_VERSION "1.1.14"
+#define DRV_RELDATE "May-3-2002"
/* A few user-configurable values.
@@ -136,9 +149,6 @@
#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
-/* max time out delay time */
-#define W_MAX_TIMEOUT 0x0FFFU
-
#if !defined(__OPTIMIZE__) || !defined(__KERNEL__)
#warning You must compile this file with the correct options!
#warning See the last lines of the source file.
@@ -161,6 +171,7 @@
#include <linux/delay.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
+#include <linux/crc32.h>
#include <asm/processor.h> /* Processor type for cache alignment. */
#include <asm/bitops.h>
#include <asm/io.h>
@@ -316,7 +327,8 @@
enum via_rhine_chips {
VT86C100A = 0,
VT6102,
- VT3043,
+ VT6105,
+ VT6105M
};
struct via_rhine_chip_info {
@@ -341,18 +353,21 @@
static struct via_rhine_chip_info via_rhine_chip_info[] __devinitdata =
{
{ "VIA VT86C100A Rhine", RHINE_IOTYPE, 128,
- CanHaveMII | ReqTxAlign },
+ CanHaveMII | ReqTxAlign | HasDavicomPhy },
{ "VIA VT6102 Rhine-II", RHINE_IOTYPE, 256,
CanHaveMII | HasWOL },
- { "VIA VT3043 Rhine", RHINE_IOTYPE, 128,
- CanHaveMII | ReqTxAlign }
+ { "VIA VT6105 Rhine-III", RHINE_IOTYPE, 256,
+ CanHaveMII | HasWOL },
+ { "VIA VT6105M Rhine-III", RHINE_IOTYPE, 256,
+ CanHaveMII | HasWOL },
};
static struct pci_device_id via_rhine_pci_tbl[] __devinitdata =
{
- {0x1106, 0x6100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A},
+ {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A},
{0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6102},
- {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT3043},
+ {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105},
+ {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M},
{0,} /* terminate list */
};
MODULE_DEVICE_TABLE(pci, via_rhine_pci_tbl);
@@ -371,6 +386,11 @@
StickyHW=0x83, WOLcrClr=0xA4, WOLcgClr=0xA7, PwrcsrClr=0xAC,
};
+/* Bits in ConfigD (select backoff algorithm (Ethernet capture effect)) */
+enum backoff_bits {
+ BackOpt=0x01, BackAMD=0x02, BackDEC=0x04, BackRandom=0x08
+};
+
#ifdef USE_MEM
/* Registers we check that mmio and reg are the same. */
int mmio_verify_registers[] = {
@@ -419,11 +439,11 @@
u32 next_desc;
};
-/* Bits in *_desc.status */
enum rx_status_bits {
RxOK=0x8000, RxWholePkt=0x0300, RxErr=0x008F
};
+/* Bits in *_desc.status */
enum desc_status_bits {
DescOwn=0x80000000, DescEndPacket=0x4000, DescIntr=0x1000,
};
@@ -471,13 +491,10 @@
u16 chip_cmd; /* Current setting for ChipCmd */
/* These values are keep track of the transceiver/media in use. */
- unsigned int full_duplex:1; /* Full-duplex operation requested. */
- unsigned int duplex_lock:1;
unsigned int default_port:4; /* Last dev->if_port value. */
u8 tx_thresh, rx_thresh;
/* MII transceiver section. */
- u16 advertising; /* NWay media advertisement */
unsigned char phys[MAX_MII_CNT]; /* MII device addresses. */
unsigned int mii_cnt; /* number of MIIs found, but only the first one is used */
u16 mii_status; /* last read MII status */
@@ -501,15 +518,13 @@
static int via_rhine_close(struct net_device *dev);
static inline void clear_tally_counters(long ioaddr);
-static void wait_for_reset(struct net_device *dev, char *name)
+static void wait_for_reset(struct net_device *dev, int chip_id, char *name)
{
- struct netdev_private *np = dev->priv;
long ioaddr = dev->base_addr;
- int chip_id = np->chip_id;
int i;
- /* 3043 may need long delay after reset (dlink) */
- if (chip_id == VT3043 || chip_id == VT86C100A)
+ /* VT86C100A may need long delay after reset (dlink) */
+ if (chip_id == VT86C100A)
udelay(100);
i = 0;
@@ -530,11 +545,11 @@
static void __devinit enable_mmio(long ioaddr, int chip_id)
{
int n;
- if (chip_id == VT3043 || chip_id == VT86C100A) {
+ if (chip_id == VT86C100A) {
/* More recent docs say that this bit is reserved ... */
n = inb(ioaddr + ConfigA) | 0x20;
outb(n, ioaddr + ConfigA);
- } else if (chip_id == VT6102) {
+ } else {
n = inb(ioaddr + ConfigD) | 0x80;
outb(n, ioaddr + ConfigD);
}
@@ -658,7 +673,7 @@
writew(CmdReset, ioaddr + ChipCmd);
dev->base_addr = ioaddr;
- wait_for_reset(dev, shortname);
+ wait_for_reset(dev, chip_id, shortname);
/* Reload the station address from the EEPROM. */
#ifdef USE_IO
@@ -779,7 +794,7 @@
(option & 0x300 ? 100 : 10),
(option & 0x220 ? "full" : "half"));
if (np->mii_cnt)
- mdio_write(dev, np->phys[0], 0,
+ mdio_write(dev, np->phys[0], MII_BMCR,
((option & 0x300) ? 0x2000 : 0) | /* 100mbps? */
((option & 0x220) ? 0x0100 : 0)); /* Full duplex? */
}
@@ -963,9 +978,9 @@
writeb(dev->dev_addr[i], ioaddr + StationAddr + i);
/* Initialize other registers. */
- writew(0x0006, ioaddr + PCIBusConfig); /* Tune configuration??? */
- /* Configure the FIFO thresholds. */
- writeb(0x20, ioaddr + TxConfig); /* Initial threshold 32 bytes */
+ writew(0x0006, ioaddr + PCIBusConfig); /* Store & forward */
+ /* Configure initial FIFO thresholds. */
+ writeb(0x20, ioaddr + TxConfig);
np->tx_thresh = 0x20;
np->rx_thresh = 0x60; /* Written in via_rhine_set_rx_mode(). */
@@ -1024,13 +1039,13 @@
if (phy_id == np->phys[0]) {
switch (regnum) {
- case 0: /* Is user forcing speed/duplex? */
+ case MII_BMCR: /* Is user forcing speed/duplex? */
if (value & 0x9000) /* Autonegotiation. */
np->mii_if.duplex_lock = 0;
else
np->mii_if.full_duplex = (value & 0x0100) ? 1 : 0;
break;
- case 4:
+ case MII_ADVERTISE:
np->mii_if.advertising = value;
break;
}
@@ -1069,7 +1084,7 @@
return i;
alloc_rbufs(dev);
alloc_tbufs(dev);
- wait_for_reset(dev, dev->name);
+ wait_for_reset(dev, np->chip_id, dev->name);
init_registers(dev);
if (debug > 2)
printk(KERN_DEBUG "%s: Done via_rhine_open(), status %4.4x "
@@ -1176,7 +1191,7 @@
alloc_rbufs(dev);
/* Reinitialize the hardware. */
- wait_for_reset(dev, dev->name);
+ wait_for_reset(dev, np->chip_id, dev->name);
init_registers(dev);
spin_unlock(&np->lock);
@@ -1246,7 +1261,7 @@
if (debug > 4) {
printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
- dev->name, np->cur_tx, entry);
+ dev->name, np->cur_tx-1, entry);
}
return 0;
}
@@ -1497,8 +1512,8 @@
printk(KERN_INFO "%s: Transmitter underrun, increasing Tx "
"threshold setting to %2.2x.\n", dev->name, np->tx_thresh);
}
- if ((intr_status & ~( IntrLinkChange | IntrStatsMax |
- IntrTxAbort | IntrTxAborted))) {
+ if (intr_status & ~( IntrLinkChange | IntrStatsMax |
+ IntrTxAbort | IntrTxAborted | IntrNormalSummary)) {
if (debug > 1)
printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
dev->name, intr_status);
@@ -1535,26 +1550,6 @@
readw(ioaddr + RxMissed);
}
-
-/* The big-endian AUTODIN II ethernet CRC calculation.
- N.B. Do not use for bulk data, use a table-based routine instead.
- This is common code and should be moved to net/core/crc.c */
-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc(int length, unsigned char *data)
-{
- int crc = -1;
-
- while(--length >= 0) {
- unsigned char current_octet = *data++;
- int bit;
- for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
- crc = (crc << 1) ^
- ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
- }
- }
- return crc;
-}
-
static void via_rhine_set_rx_mode(struct net_device *dev)
{
struct netdev_private *np = dev->priv;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)