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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).