patch-2.3.11 linux/drivers/net/pcnet32.c
Next file: linux/drivers/net/rcpci45.c
Previous file: linux/drivers/net/mace.c
Back to the patch index
Back to the overall index
- Lines: 169
- Date:
Mon Jul 12 14:58:46 1999
- Orig file:
v2.3.10/linux/drivers/net/pcnet32.c
- Orig date:
Sat Apr 24 17:51:48 1999
diff -u --recursive --new-file v2.3.10/linux/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c
@@ -13,7 +13,7 @@
* This driver is for PCnet32 and PCnetPCI based ethercards
*/
-static const char *version = "pcnet32.c:v1.21 31.3.99 tsbogend@alpha.franken.de\n";
+static const char *version = "pcnet32.c:v1.23 6.7.1999 tsbogend@alpha.franken.de\n";
#include <linux/config.h>
#include <linux/module.h>
@@ -149,6 +149,13 @@
* rewritten PCI card detection
* added dwio mode to get driver working on some PPC machines
* v1.21: added mii selection and mii ioctl
+ * v1.22: changed pci scanning code to make PPC people happy
+ * fixed switching to 32bit mode in pcnet32_open() (thanks
+ * to Michael Richard <mcr@solidum.com> for noticing this one)
+ * added sub vendor/device id matching (thanks again to
+ * Michael Richard <mcr@solidum.com>)
+ * added chip id for 79c973/975 (thanks to Zach Brown <zab@zabbo.net>)
+ * v1.23 fixed small bug, when manual selecting MII speed/duplex
*/
@@ -185,6 +192,16 @@
#define PCNET32_TOTAL_SIZE 0x20
+/* some PCI ids */
+#ifndef PCI_DEVICE_ID_AMD_LANCE
+#define PCI_VENDOR_ID_AMD 0x1022
+#define PCI_DEVICE_ID_AMD_LANCE 0x2000
+#endif
+#ifndef PCI_DEVICE_ID_AMD_PCNETHOME
+#define PCI_DEVICE_ID_AMD_PCNETHOME 0x2001
+#endif
+
+
#define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */
/* The PCNET32 Rx and Tx ring descriptors. */
@@ -272,14 +289,19 @@
struct pcnet32_pci_id_info {
const char *name;
- u16 vendor_id, device_id, device_id_mask, flags;
+ u16 vendor_id, device_id, svid, sdid, flags;
int io_size;
int (*probe1) (struct device *, unsigned long, unsigned char, int, int);
};
static struct pcnet32_pci_id_info pcnet32_tbl[] = {
{ "AMD PCnetPCI series",
- 0x1022, 0x2000, 0xfffe, PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE,
+ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0, 0,
+ PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE,
+ pcnet32_probe1},
+ { "AMD PCnetHome series",
+ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_PCNETHOME, 0, 0,
+ PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE,
pcnet32_probe1},
{0,}
};
@@ -418,30 +440,27 @@
#if defined(CONFIG_PCI)
if (pci_present()) {
- struct pci_dev *pdev;
- unsigned char pci_bus, pci_device_fn;
- int pci_index;
+ struct pci_dev *pdev = NULL;
printk("pcnet32.c: PCI bios is present, checking for devices...\n");
- for (pci_index = 0; pci_index < 0xff; pci_index++) {
- u16 vendor, device, pci_command;
+ while ((pdev = pci_find_class (PCI_CLASS_NETWORK_ETHERNET<<8, pdev))) {
+ u16 pci_command;
int chip_idx;
+ u16 sdid,svid;
- if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
- pci_index, &pci_bus, &pci_device_fn) != PCIBIOS_SUCCESSFUL)
- break;
-
- pcibios_read_config_word(pci_bus, pci_device_fn, PCI_VENDOR_ID, &vendor);
- pcibios_read_config_word(pci_bus, pci_device_fn, PCI_DEVICE_ID, &device);
-
+ pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &sdid);
+ pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &svid);
for (chip_idx = 0; pcnet32_tbl[chip_idx].vendor_id; chip_idx++)
- if (vendor == pcnet32_tbl[chip_idx].vendor_id &&
- (device & pcnet32_tbl[chip_idx].device_id_mask) == pcnet32_tbl[chip_idx].device_id)
+ if ((pdev->vendor == pcnet32_tbl[chip_idx].vendor_id) &&
+ (pdev->device == pcnet32_tbl[chip_idx].device_id) &&
+ (pcnet32_tbl[chip_idx].svid == 0 ||
+ (svid == pcnet32_tbl[chip_idx].svid)) &&
+ (pcnet32_tbl[chip_idx].sdid == 0 ||
+ (sdid == pcnet32_tbl[chip_idx].sdid)))
break;
if (pcnet32_tbl[chip_idx].vendor_id == 0)
continue;
- pdev = pci_find_slot(pci_bus, pci_device_fn);
ioaddr = pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
#if defined(ADDR_64BITS) && defined(__alpha__)
ioaddr |= ((long)pdev->base_address[1]) << 32;
@@ -541,6 +560,10 @@
chipname = "PCnet/FAST+ 79C972";
fdx = 1; mii = 1;
break;
+ case 0x2625:
+ chipname = "PCnet/FAST III 79C973";
+ fdx = 1; mii = 1;
+ break;
case 0x2626:
chipname = "PCnet/Home 79C978";
fdx = 1;
@@ -561,6 +584,9 @@
printk("pcnet32: pcnet32 media reset to %#x.\n", media);
a->write_bcr (ioaddr, 49, media);
break;
+ case 0x2627:
+ chipname = "PCnet/FAST III 79C975";
+ fdx = 1; mii = 1;
default:
printk("pcnet32: PCnet version %#x, no PCnet32 chip.\n",chip_version);
return ENODEV;
@@ -693,7 +719,7 @@
lp->a.reset (ioaddr);
/* switch pcnet32 to 32bit mode */
- lp->a.write_csr (ioaddr, 20, 2);
+ lp->a.write_bcr (ioaddr, 20, 2);
if (pcnet32_debug > 1)
printk("%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n",
@@ -725,7 +751,7 @@
val |= 0x10;
lp->a.write_csr (ioaddr, 124, val);
- if (lp->mii & (lp->options & PORT_ASEL)) {
+ if (lp->mii & !(lp->options & PORT_ASEL)) {
val = lp->a.read_bcr (ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mpbs, HD */
if (lp->options & PORT_FD)
val |= 0x10;
@@ -952,7 +978,7 @@
struct device *dev = (struct device *)dev_id;
struct pcnet32_private *lp;
unsigned long ioaddr;
- u16 csr0;
+ u16 csr0,rap;
int boguscnt = max_interrupt_work;
int must_restart;
@@ -968,6 +994,7 @@
dev->interrupt = 1;
+ rap = lp->a.read_rap(ioaddr);
while ((csr0 = lp->a.read_csr (ioaddr, 0)) & 0x8600 && --boguscnt >= 0) {
/* Acknowledge all of the current interrupt sources ASAP. */
lp->a.write_csr (ioaddr, 0, csr0 & ~0x004f);
@@ -1069,6 +1096,7 @@
/* Clear any other interrupt, and set interrupt enable. */
lp->a.write_csr (ioaddr, 0, 0x7940);
+ lp->a.write_rap(ioaddr,rap);
if (pcnet32_debug > 4)
printk("%s: exiting interrupt, csr0=%#4.4x.\n",
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)