patch-2.4.15 linux/drivers/net/via-rhine.c
Next file: linux/drivers/net/wan/dscc4.c
Previous file: linux/drivers/net/tulip/tulip_core.c
Back to the patch index
Back to the overall index
- Lines: 230
- Date:
Fri Nov 9 13:45:36 2001
- Orig file:
v2.4.14/linux/drivers/net/via-rhine.c
- Orig date:
Tue Oct 23 22:48:51 2001
diff -u --recursive --new-file v2.4.14/linux/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
@@ -73,6 +73,9 @@
- David Woodhouse: Set dev->base_addr before the first time we call
wait_for_reset(). It's a lot happier that way.
Free np->tx_bufs only if we actually allocated it.
+
+ LK1.1.12:
+ - Martin Eriksson: Allow Memory-Mapped IO to be enabled.
*/
@@ -155,7 +158,7 @@
/* These identify the driver base version and may not be removed. */
static char version[] __devinitdata =
-KERN_INFO "via-rhine.c:v1.10-LK1.1.11 20/08/2001 Written by Donald Becker\n"
+KERN_INFO "via-rhine.c:v1.10-LK1.1.12 03/11/2001 Written by Donald Becker\n"
KERN_INFO " http://www.scyld.com/network/via-rhine.html\n";
static char shortname[] __devinitdata = "via-rhine";
@@ -163,9 +166,8 @@
/* This driver was written to use PCI memory space, however most versions
of the Rhine only work correctly with I/O space accesses. */
-#if defined(VIA_USE_MEMORY)
-#warning Many adapters using the VIA Rhine chip are not configured to work
-#warning with PCI memory space accesses.
+#ifdef CONFIG_VIA_RHINE_MMIO
+#define USE_MEM
#else
#define USE_IO
#undef readb
@@ -318,12 +320,10 @@
CanHaveMII=1, HasESIPhy=2, HasDavicomPhy=4,
ReqTxAlign=0x10, HasWOL=0x20, };
-#if defined(VIA_USE_MEMORY)
+#ifdef USE_MEM
#define RHINE_IOTYPE (PCI_USES_MEM | PCI_USES_MASTER | PCI_ADDR1)
-#define RHINEII_IOSIZE 4096
#else
#define RHINE_IOTYPE (PCI_USES_IO | PCI_USES_MASTER | PCI_ADDR0)
-#define RHINEII_IOSIZE 256
#endif
/* directly indexed by enum via_rhine_chips, above */
@@ -331,7 +331,7 @@
{
{ "VIA VT86C100A Rhine", RHINE_IOTYPE, 128,
CanHaveMII | ReqTxAlign },
- { "VIA VT6102 Rhine-II", RHINE_IOTYPE, RHINEII_IOSIZE,
+ { "VIA VT6102 Rhine-II", RHINE_IOTYPE, 256,
CanHaveMII | HasWOL },
{ "VIA VT3043 Rhine", RHINE_IOTYPE, 128,
CanHaveMII | ReqTxAlign }
@@ -355,10 +355,19 @@
RxRingPtr=0x18, TxRingPtr=0x1C, GFIFOTest=0x54,
MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIBusConfig=0x6E,
MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74,
- Config=0x78, ConfigA=0x7A, RxMissed=0x7C, RxCRCErrs=0x7E,
+ ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B,
+ RxMissed=0x7C, RxCRCErrs=0x7E,
StickyHW=0x83, WOLcrClr=0xA4, WOLcgClr=0xA7, PwrcsrClr=0xAC,
};
+#ifdef USE_MEM
+/* Registers we check that mmio and reg are the same. */
+int mmio_verify_registers[] = {
+ RxConfig, TxConfig, IntrEnable, ConfigA, ConfigB, ConfigC, ConfigD,
+ 0
+};
+#endif
+
/* Bits in the interrupt status/mask registers. */
enum intr_status_bits {
IntrRxDone=0x0001, IntrRxErr=0x0004, IntrRxEmpty=0x0020,
@@ -505,6 +514,31 @@
name, 5*i);
}
+#ifdef USE_MEM
+static void __devinit enable_mmio(long ioaddr, int chip_id)
+{
+ int n;
+ if (chip_id == VT3043 || 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) {
+ n = inb(ioaddr + ConfigD) | 0x80;
+ outb(n, ioaddr + ConfigD);
+ }
+}
+#endif
+
+static void __devinit reload_eeprom(long ioaddr)
+{
+ int i;
+ outb(0x20, ioaddr + MACRegEEcsr);
+ /* Typically 2 cycles to reload. */
+ for (i = 0; i < 150; i++)
+ if (! (inb(ioaddr + MACRegEEcsr) & 0x20))
+ break;
+}
+
static int __devinit via_rhine_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -514,8 +548,12 @@
int chip_id = (int) ent->driver_data;
static int card_idx = -1;
long ioaddr;
+ long memaddr;
int io_size;
int pci_flags;
+#ifdef USE_MEM
+ long ioaddr0;
+#endif
/* when built into the kernel, we only print version if device is found */
#ifndef MODULE
@@ -545,8 +583,9 @@
goto err_out;
}
- ioaddr = pci_resource_start (pdev, pci_flags & PCI_ADDR0 ? 0 : 1);
-
+ ioaddr = pci_resource_start (pdev, 0);
+ memaddr = pci_resource_start (pdev, 1);
+
if (pci_flags & PCI_USES_MASTER)
pci_set_master (pdev);
@@ -560,14 +599,29 @@
if (pci_request_regions(pdev, shortname))
goto err_out_free_netdev;
-#ifndef USE_IO
- ioaddr = (long) ioremap (ioaddr, io_size);
+#ifdef USE_MEM
+ ioaddr0 = ioaddr;
+ enable_mmio(ioaddr0, chip_id);
+
+ ioaddr = (long) ioremap (memaddr, io_size);
if (!ioaddr) {
- printk (KERN_ERR "ioremap failed for device %s, region 0x%X @ 0x%X\n",
- pdev->slot_name, io_size,
- pci_resource_start (pdev, 1));
+ printk (KERN_ERR "ioremap failed for device %s, region 0x%X @ 0x%lX\n",
+ pdev->slot_name, io_size, memaddr);
goto err_out_free_res;
}
+
+ /* Check that selected MMIO registers match the PIO ones */
+ i = 0;
+ while (mmio_verify_registers[i]) {
+ int reg = mmio_verify_registers[i++];
+ unsigned char a = inb(ioaddr0+reg);
+ unsigned char b = readb(ioaddr+reg);
+ if (a != b) {
+ printk (KERN_ERR "MMIO do not match PIO [%02x] (%02x != %02x)\n",
+ reg, a, b);
+ goto err_out_unmap;
+ }
+ }
#endif
/* D-Link provided reset code (with comment additions) */
@@ -595,11 +649,16 @@
wait_for_reset(dev, shortname);
/* Reload the station address from the EEPROM. */
- writeb(0x20, ioaddr + MACRegEEcsr);
- /* Typically 2 cycles to reload. */
- for (i = 0; i < 150; i++)
- if (! (readb(ioaddr + MACRegEEcsr) & 0x20))
- break;
+#ifdef USE_IO
+ reload_eeprom(ioaddr);
+#else
+ reload_eeprom(ioaddr0);
+ /* 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);
+#endif
+
for (i = 0; i < 6; i++)
dev->dev_addr[i] = readb(ioaddr + StationAddr + i);
@@ -660,7 +719,9 @@
goto err_out_unmap;
printk(KERN_INFO "%s: %s at 0x%lx, ",
- dev->name, via_rhine_chip_info[chip_id].name, ioaddr);
+ dev->name, via_rhine_chip_info[chip_id].name,
+ (pci_flags & PCI_USES_IO) ? ioaddr : memaddr);
+
for (i = 0; i < 5; i++)
printk("%2.2x:", dev->dev_addr[i]);
printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], pdev->irq);
@@ -711,7 +772,7 @@
return 0;
err_out_unmap:
-#ifndef USE_IO
+#ifdef USE_MEM
iounmap((void *)ioaddr);
err_out_free_res:
#endif
@@ -1587,18 +1648,17 @@
static void __devexit via_rhine_remove_one (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
- struct netdev_private *np = dev->priv;
unregister_netdev(dev);
pci_release_regions(pdev);
-#ifndef USE_IO
+#ifdef USE_MEM
iounmap((char *)(dev->base_addr));
#endif
kfree(dev);
-
+ pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)