From: Roger Luethi <rl@hellgate.ch>
To: Jeff Garzik <jgarzik@pobox.com>, Andrew Morton <akpm@osdl.org>
Cc: netdev@oss.sgi.com
Subject: [7/9][PATCH 2.6] Rewrite special-casing
Date: Wed, 2 Jun 2004 13:59:00 +0200 [thread overview]
Message-ID: <20040602115900.GA17578@k3.hellgate.ch> (raw)
In-Reply-To: <20040602115703.GA16079@k3.hellgate.ch>
Use PCI revision to determine special cases. One bit field replaces a
bunch of data structures holding special case information.
Replace chip_id, drv_flags in rhine_private with quirks
Remove enum rhine_chips, struct rhine_chip_info (and array),
enum chip_capability_flags
Add enum rhine_revs, enum rhine_quirks (some values in preparation for
subsequent changes)
wait_for_reset() and enable_mmio() now use quirks instead of chip_id
Remove model names from ident strings for now.
Signed-off-by: Roger Luethi <rl@hellgate.ch>
--- orig/drivers/net/via-rhine.c
+++ mod/drivers/net/via-rhine.c
@@ -354,48 +354,46 @@
second only the 1234 card.
*/
-enum rhine_chips {
- VT86C100A = 0,
- VT6102,
- VT6105,
- VT6105M
+enum rhine_revs {
+ VT86C100A = 0x00,
+ VT6102 = 0x40,
+ VT8231 = 0x50, /* Integrated MAC */
+ VT8233 = 0x60, /* Integrated MAC */
+ VT8235 = 0x74, /* Integrated MAC */
+ VT8237 = 0x78, /* Integrated MAC */
+ VTunknown0 = 0x7C,
+ VT6105 = 0x80,
+ VT6105_B0 = 0x83,
+ VT6105L = 0x8A,
+ VT6107 = 0x8C,
+ VTunknown1 = 0x8E,
+ VT6105M = 0x90,
};
-struct rhine_chip_info {
- const char *name;
- int io_size;
- int drv_flags;
-};
-
-
-enum chip_capability_flags {
- HasDavicomPhy=4,
- ReqTxAlign=0x10, HasWOL=0x20,
+enum rhine_quirks {
+ rqWOL = 0x0001, /* Wake-On-LAN support */
+ rqForceReset = 0x0002,
+ rqDavicomPhy = 0x0020,
+ rq6patterns = 0x0040, /* 6 instead of 4 patterns for WOL */
+ rqStatusWBRace = 0x0080, /* Tx Status Writeback Error possible */
+ rqRhineI = 0x0100, /* See comment below */
};
+/*
+ * rqRhineI: VT86C100A (aka Rhine-I) uses different bits to enable
+ * MMIO as well as for the collision counter and the Tx FIFO underflow
+ * indicator. In addition, Tx and Rx buffers need to 4 byte aligned.
+ */
/* Beware of PCI posted writes */
#define IOSYNC do { readb(dev->base_addr + StationAddr); } while (0)
-/* directly indexed by enum rhine_chips, above */
-static struct rhine_chip_info rhine_chip_info[] __devinitdata =
-{
- { "VIA VT86C100A Rhine", 128,
- ReqTxAlign | HasDavicomPhy },
- { "VIA VT6102 Rhine-II", 256,
- HasWOL },
- { "VIA VT6105 Rhine-III", 256,
- HasWOL },
- { "VIA VT6105M Rhine-III", 256,
- HasWOL },
-};
-
static struct pci_device_id rhine_pci_tbl[] =
{
- {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A},
- {0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6102},
- {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105}, /* 6105{,L,LOM} */
- {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M},
- {0,} /* terminate list */
+ {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT86C100A */
+ {0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT6102 */
+ {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* 6105{,L,LOM} */
+ {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT6105M */
+ { } /* terminate list */
};
MODULE_DEVICE_TABLE(pci, rhine_pci_tbl);
@@ -503,7 +501,7 @@
spinlock_t lock;
/* Frequently used values: keep some adjacent for cache effect. */
- int chip_id, drv_flags;
+ u32 quirks;
struct rx_desc *rx_head_desc;
unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */
unsigned int cur_tx, dirty_tx;
@@ -545,12 +543,12 @@
intr_status = readw(ioaddr + IntrStatus);
/* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */
- if (rp->chip_id == VT6102)
+ if (rp->quirks & rqStatusWBRace)
intr_status |= readb(ioaddr + IntrStatus2) << 16;
return intr_status;
}
-static void wait_for_reset(struct net_device *dev, int chip_id, char *name)
+static void wait_for_reset(struct net_device *dev, u32 quirks, char *name)
{
long ioaddr = dev->base_addr;
int boguscnt = 20;
@@ -562,7 +560,7 @@
"Trying harder.\n", name);
/* Rhine-II needs to be forced sometimes */
- if (chip_id == VT6102)
+ if (quirks & rqForceReset)
writeb(0x40, ioaddr + MiscCmd);
/* VT86C100A may need long delay after reset (dlink) */
@@ -578,10 +576,10 @@
}
#ifdef USE_MMIO
-static void __devinit enable_mmio(long ioaddr, int chip_id)
+static void __devinit enable_mmio(long ioaddr, u32 quirks)
{
int n;
- if (chip_id == VT86C100A) {
+ if (quirks & rqRhineI) {
/* More recent docs say that this bit is reserved ... */
n = inb(ioaddr + ConfigA) | 0x20;
outb(n, ioaddr + ConfigA);
@@ -617,7 +615,8 @@
struct net_device *dev;
struct rhine_private *rp;
int i, option, rc;
- int chip_id = (int) ent->driver_data;
+ u8 pci_rev;
+ u32 quirks;
static int card_idx = -1;
long ioaddr;
long memaddr;
@@ -626,6 +625,7 @@
#ifdef USE_MMIO
long ioaddr0;
#endif
+ const char *name;
/* when built into the kernel, we only print version if device is found */
#ifndef MODULE
@@ -636,7 +636,26 @@
card_idx++;
option = card_idx < MAX_UNITS ? options[card_idx] : 0;
- io_size = rhine_chip_info[chip_id].io_size;
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
+
+ io_size = 256;
+ if (pci_rev < VT6102) {
+ quirks = rqRhineI | rqDavicomPhy;
+ io_size = 128;
+ name = "VT86C100A Rhine";
+ }
+ else {
+ quirks = rqWOL | rqForceReset;
+ if (pci_rev < VT6105) {
+ name = "Rhine II";
+ quirks |= rqStatusWBRace; /* Rhine-II exclusive */
+ }
+ else {
+ name = "Rhine III";
+ if (pci_rev >= VT6105_B0)
+ quirks |= rq6patterns;
+ }
+ }
rc = pci_enable_device(pdev);
if (rc)
@@ -679,7 +698,7 @@
#ifdef USE_MMIO
ioaddr0 = ioaddr;
- enable_mmio(ioaddr0, chip_id);
+ enable_mmio(ioaddr0, quirks);
ioaddr = (long) ioremap(memaddr, io_size);
if (!ioaddr) {
@@ -705,7 +724,7 @@
#endif /* USE_MMIO */
/* D-Link provided reset code (with comment additions) */
- if (rhine_chip_info[chip_id].drv_flags & HasWOL) {
+ if (quirks & rqWOL) {
unsigned char byOrgValue;
/* clear sticky bit before reset & read ethernet address */
@@ -726,7 +745,7 @@
writew(CmdReset, ioaddr + ChipCmd);
dev->base_addr = ioaddr;
- wait_for_reset(dev, chip_id, shortname);
+ wait_for_reset(dev, quirks, shortname);
/* Reload the station address from the EEPROM. */
#ifdef USE_MMIO
@@ -734,7 +753,7 @@
/* Reloading from eeprom overwrites cfgA-D, so we must re-enable MMIO.
If reload_eeprom() was done first this could be avoided, but it is
not known if that still works with the "win98-reboot" problem. */
- enable_mmio(ioaddr0, chip_id);
+ enable_mmio(ioaddr0, quirks);
#else
reload_eeprom(ioaddr);
#endif
@@ -748,7 +767,7 @@
goto err_out_unmap;
}
- if (chip_id == VT6102) {
+ if (quirks & rqWOL) {
/*
* for 3065D, EEPROM reloaded will cause bit 0 in MAC_REG_CFGA
* turned on. it makes MAC receive magic packet
@@ -766,9 +785,8 @@
rp = netdev_priv(dev);
spin_lock_init(&rp->lock);
- rp->chip_id = chip_id;
- rp->drv_flags = rhine_chip_info[chip_id].drv_flags;
rp->pdev = pdev;
+ rp->quirks = quirks;
rp->mii_if.dev = dev;
rp->mii_if.mdio_read = mdio_read;
rp->mii_if.mdio_write = mdio_write;
@@ -791,7 +809,7 @@
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = rhine_poll;
#endif
- if (rp->drv_flags & ReqTxAlign)
+ if (rp->quirks & rqRhineI)
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
/* dev->name not defined before register_netdev()! */
@@ -813,8 +831,8 @@
rp->mii_if.force_media = 1;
}
- printk(KERN_INFO "%s: %s at 0x%lx, ",
- dev->name, rhine_chip_info[chip_id].name,
+ printk(KERN_INFO "%s: VIA %s at 0x%lx, ",
+ dev->name, name,
#ifdef USE_MMIO
memaddr
#else
@@ -896,7 +914,7 @@
printk(KERN_ERR "Could not allocate DMA memory.\n");
return -ENOMEM;
}
- if (rp->drv_flags & ReqTxAlign) {
+ if (rp->quirks & rqRhineI) {
rp->tx_bufs = pci_alloc_consistent(rp->pdev,
PKT_BUF_SZ * TX_RING_SIZE,
&rp->tx_bufs_dma);
@@ -1154,7 +1172,7 @@
return i;
alloc_rbufs(dev);
alloc_tbufs(dev);
- wait_for_reset(dev, rp->chip_id, dev->name);
+ wait_for_reset(dev, rp->quirks, dev->name);
init_registers(dev);
if (debug > 2)
printk(KERN_DEBUG "%s: Done rhine_open(), status %4.4x "
@@ -1260,7 +1278,7 @@
alloc_rbufs(dev);
/* Reinitialize the hardware. */
- wait_for_reset(dev, rp->chip_id, dev->name);
+ wait_for_reset(dev, rp->quirks, dev->name);
init_registers(dev);
spin_unlock(&rp->lock);
@@ -1291,7 +1309,7 @@
rp->tx_skbuff[entry] = skb;
- if ((rp->drv_flags & ReqTxAlign) &&
+ if ((rp->quirks & rqRhineI) &&
(((long)skb->data & 3) || skb_shinfo(skb)->nr_frags != 0 || skb->ip_summed == CHECKSUM_HW)) {
/* Must use alignment buffer. */
if (skb->len > PKT_BUF_SZ) {
@@ -1440,7 +1458,7 @@
if (txstatus & 0x0200) rp->stats.tx_window_errors++;
if (txstatus & 0x0100) rp->stats.tx_aborted_errors++;
if (txstatus & 0x0080) rp->stats.tx_heartbeat_errors++;
- if (((rp->chip_id == VT86C100A) && txstatus & 0x0002) ||
+ if (((rp->quirks & rqRhineI) && txstatus & 0x0002) ||
(txstatus & 0x0800) || (txstatus & 0x1000)) {
rp->stats.tx_fifo_errors++;
rp->tx_ring[entry].tx_status = cpu_to_le32(DescOwn);
@@ -1448,7 +1466,7 @@
}
/* Transmitter restarted in 'abnormal' handler. */
} else {
- if (rp->chip_id == VT86C100A)
+ if (rp->quirks & rqRhineI)
rp->stats.collisions += (txstatus >> 3) & 0x0F;
else
rp->stats.collisions += txstatus & 0x0F;
@@ -1660,7 +1678,7 @@
if (intr_status & (IntrLinkChange)) {
if (readb(ioaddr + MIIStatus) & 0x02) {
/* Link failed, restart autonegotiation. */
- if (rp->drv_flags & HasDavicomPhy)
+ if (rp->quirks & rqRhineI)
mdio_write(dev, rp->phys[0], MII_BMCR, 0x3300);
} else
rhine_check_duplex(dev);
next prev parent reply other threads:[~2004-06-02 11:59 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-06-02 11:57 [0/9][2.6] via-rhine patches Roger Luethi
2004-06-02 11:57 ` [1/9][PATCH 2.6] Nuke HAS_IP_COPYSUM Roger Luethi
2004-06-02 11:58 ` [2/9][PATCH 2.6] Nuke CanHaveMII and related code Roger Luethi
2004-06-02 11:58 ` [3/9][PATCH 2.6] Nuke HasESIPhy " Roger Luethi
2004-06-02 11:58 ` [4/9][PATCH 2.6] Nuke default_port, references to if_port, medialock Roger Luethi
2004-06-02 11:58 ` [5/9][PATCH 2.6] Nuke all pci_flags Roger Luethi
2004-06-02 11:58 ` [6/9][PATCH 2.6] Return codes for rhine_init_one Roger Luethi
2004-06-02 11:59 ` Roger Luethi [this message]
2004-06-02 11:59 ` [8/9][PATCH 2.6] Add rhine_power_init(): get power regs into sane state Roger Luethi
2004-06-02 11:59 ` [9/9][PATCH 2.6] Restructure reset code Roger Luethi
2004-06-02 19:41 ` Jeff Garzik
[not found] ` <40BE2DE0.4040102@pobox.com>
2004-06-02 20:30 ` Roger Luethi
2004-06-14 10:03 ` Roger Luethi
2004-06-14 10:40 ` Andrew Morton
2004-06-14 11:00 ` Roger Luethi
[not found] ` <40BE2A90.7020508@pobox.com>
2004-06-02 19:53 ` [0/9][2.6] via-rhine patches Roger Luethi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040602115900.GA17578@k3.hellgate.ch \
--to=rl@hellgate.ch \
--cc=akpm@osdl.org \
--cc=jgarzik@pobox.com \
--cc=netdev@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.