--- saw/eepro100.orig.c Mon Mar 27 17:07:37 2000 +++ saw/eepro100.c Thu Mar 30 19:16:55 2000 @@ -27,6 +27,9 @@ Disabled FC and ER, to avoid lockups when when we get FCP interrupts. Dragan Stancevic March 24th, 2000. + + Added more detailed device recognition + Dragan Stancevic March 30th, 2000. */ static const char *version = @@ -273,7 +276,8 @@ */ /* This table drives the PCI probe routines. */ -static struct net_device *speedo_found1(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_idx, int fnd_cnt); +static struct net_device *speedo_found1(int pci_bus, int pci_devfn, + long ioaddr, int irq, int chip_idx, int fnd_cnt, int dev_id, unsigned char rev_id); #ifdef USE_IO #define SPEEDO_IOTYPE PCI_USES_MASTER|PCI_USES_IO|PCI_ADDR1 @@ -299,7 +303,8 @@ const char *name; u16 vendor_id, device_id, device_id_mask, flags; int io_size; - struct net_device *(*probe1)(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_idx, int fnd_cnt); + struct net_device *(*probe1)(int pci_bus, int pci_devfn, long ioaddr, + int irq, int chip_idx, int fnd_cnt, int dev_id, unsigned char rev_id); } static pci_tbl[] = { { "Intel PCI EtherExpress Pro100", 0x8086, 0x1229, 0xffff, PCI_USES_IO|PCI_USES_MASTER, 32, speedo_found1 }, @@ -511,6 +516,13 @@ static const char is_mii[] = { 0, 1, 1, 0, 1, 1, 0, 1 }; #define EE_READ_CMD (6) +/* Device specific Revision IDs */ +#define REV_ID_82558_A 0x5 +#define REV_ID_82558_B0 0x5 +#define REV_ID_82559_B 0x8 +#define REV_ID_82559_C 0x9 + + static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len); static int mdio_read(long ioaddr, int phy_id, int location); static int mdio_write(long ioaddr, int phy_id, int location, int value); @@ -552,7 +564,7 @@ return cards_found; for (; pci_index < 8; pci_index++) { - unsigned char pci_bus, pci_device_fn, pci_latency; + unsigned char pci_bus, pci_device_fn, pci_latency, rev_id; unsigned long pciaddr; long ioaddr; int irq; @@ -583,9 +595,22 @@ pciaddr); continue; } - if (speedo_debug > 2) - printk("Found Intel i82557 PCI Speedo at I/O %#lx, IRQ %d.\n", - ioaddr, irq); + /* Read the device revision ID */ + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_REVISION_ID, &rev_id); + + /* Display device version */ + if (speedo_debug > 2){ + printk("Found Intel i"); + if(rev_id < REV_ID_82558_A) + printk("82557"); + else if(rev_id == REV_ID_82558_A) + printk("82558"); + else if(rev_id >= REV_ID_82559_B) + printk("82559"); + printk(" PCI Speedo at I/O %#lx, IRQ %d, Rev. ID 0x%x.\n", + ioaddr, irq, rev_id); + } /* Get and check the bus-master and latency values. */ pcibios_read_config_word(pci_bus, pci_device_fn, @@ -608,12 +633,13 @@ } else if (speedo_debug > 1) printk(" PCI latency timer (CFLT) is %#x.\n", pci_latency); - if (speedo_found1(pci_bus, pci_device_fn, ioaddr, irq, 0, cards_found)) + if (speedo_found1(pci_bus, pci_device_fn, ioaddr, irq, 0, cards_found, + PCI_DEVICE_ID_INTEL_82557, rev_id)) cards_found++; } for (; pci_index < 8; pci_index++) { - unsigned char pci_bus, pci_device_fn, pci_latency; + unsigned char pci_bus, pci_device_fn, pci_latency, rev_id; long ioaddr; int irq; @@ -631,9 +657,15 @@ } /* Remove I/O space marker in bit 0. */ ioaddr &= ~3; + + /* Read the device revision ID */ + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_REVISION_ID, &rev_id); + + /* Display device version */ if (speedo_debug > 2) - printk("Found Intel i82559ER PCI Speedo at I/O %#lx, IRQ %d.\n", - ioaddr, irq); + printk("Found Intel i82559ER PCI Speedo at I/O %#lx, IRQ %d," + " Rev. ID 0x%x.\n", ioaddr, irq, rev_id); /* Get and check the bus-master and latency values. */ pcibios_read_config_word(pci_bus, pci_device_fn, @@ -656,7 +688,8 @@ } else if (speedo_debug > 1) printk(" PCI latency timer (CFLT) is %#x.\n", pci_latency); - if(speedo_found1(pci_bus, pci_device_fn, ioaddr, irq, 0, cards_found)) + if(speedo_found1(pci_bus, pci_device_fn, ioaddr, irq, 0, cards_found, + PCI_DEVICE_ID_INTEL_82559ER, rev_id)) cards_found++; } @@ -665,11 +698,11 @@ #endif static struct net_device *speedo_found1(int pci_bus, int pci_devfn, - long ioaddr, int irq, int chip_idx, int card_idx) + long ioaddr, int irq, int chip_idx, int card_idx, int dev_id, unsigned char rev_id) { struct net_device *dev; struct speedo_private *sp; - const char *product; + char *product; int i, option; u16 eeprom[0x100]; int acpi_idle_state = 0; @@ -678,7 +711,7 @@ if (speedo_debug > 0 && did_version++ == 0) printk(version); #endif - + product = kmalloc(33, GFP_KERNEL); dev = init_etherdev(NULL, sizeof(struct speedo_private)); if (dev->mem_start > 0) @@ -732,13 +765,47 @@ This takes less than 10usec and will easily finish before the next action. */ outl(PortReset, ioaddr + SCBPort); + + /* Device is an OEM */ + if (eeprom[3] & 0x0100){ + if(dev_id == PCI_DEVICE_ID_INTEL_82559ER){ + sprintf(product, "OEM Ethernet (82559ER)" + " Rev:%x", rev_id); + } else { + char temp[6]; + + if(rev_id < REV_ID_82558_A) + strcpy(temp,"82557"); + else if(rev_id == REV_ID_82558_A) + strcpy(temp, "82558"); + else if(rev_id >= REV_ID_82559_B) + strcpy(temp, "82559"); + sprintf(product, "OEM Ethernet (%s)" + " Rev:%x", temp, rev_id); + } + + /* It's an Intel device */ + } else { + if(dev_id == PCI_DEVICE_ID_INTEL_82559ER){ + sprintf(product, "Intel EEPro 100 (82559ER)" + " Rev:%x", rev_id); + } else { + char temp[6]; + + if(rev_id < REV_ID_82558_A) + strcpy(temp,"82557"); + else if(rev_id == REV_ID_82558_A) + strcpy(temp, "82558"); + else if(rev_id >= REV_ID_82559_B) + strcpy(temp, "82559"); + sprintf(product, "Intel EEPro 100 (%s)" + " Rev:%x", temp, rev_id); + } + + } - if (eeprom[3] & 0x0100) - product = "OEM i82557/i82558 10/100 Ethernet"; - else - product = pci_tbl[chip_idx].name; - - printk(KERN_INFO "%s: %s at %#3lx, ", dev->name, product, ioaddr); + printk(KERN_INFO "%s: PCI %s at %#3lx, ", dev->name, + product, ioaddr); for (i = 0; i < 5; i++) printk("%2.2X:", dev->dev_addr[i]); @@ -820,7 +887,7 @@ #endif /* We do a request_region() only to register /proc/ioports info. */ - request_region(ioaddr, SPEEDO3_TOTAL_SIZE, "Intel Speedo3 Ethernet"); + request_region(ioaddr, SPEEDO3_TOTAL_SIZE, product); dev->base_addr = ioaddr; dev->irq = irq; @@ -835,6 +902,7 @@ sp->next_module = root_speedo_dev; root_speedo_dev = dev; + sp->product_name = product; sp->pci_bus = pci_bus; sp->pci_devfn = pci_devfn; sp->chip_id = chip_idx; @@ -2168,6 +2236,7 @@ next_dev = sp->next_module; if (sp->priv_addr) kfree(sp->priv_addr); + kfree(sp->product_name); kfree(root_speedo_dev); root_speedo_dev = next_dev; }