diff -u kernel-source-2.2.20/drivers/net/tulip.c.orig kernel-source-2.2.20/drivers/net/tulip.c --- kernel-source-2.2.20/drivers/net/tulip.c.orig Fri Jul 4 17:58:17 2003 +++ kernel-source-2.2.20/drivers/net/tulip.c Sun Feb 1 20:40:36 2004 @@ -26,6 +26,11 @@ 2002 Dec 21 Neale Banks Gracefully handle the case where init_etherdev() returns NULL + + 2004 Jan 31 David D. Kilzer + Moved check for needing to byte-swap MAC address into its own + function. Added code to function to check for the Asante Fast + 10/100 PCI Adapter Rev B P/N 99-00493-87. */ #define SMP_CHECK @@ -678,6 +683,73 @@ } #endif /* not CARDBUS */ +static int needs_mac_addr_byte_swapped(int pci_bus, int pci_devfn, + struct device *dev) +{ + /* + * Lite-On boards have the mac address byte-swapped. + * + * The code below is checking for the following ethernet MAC + * address combinations (in byte-swapped order): + * + * 00:A0:** + * 00:C0:** + * + * However, only one of these maps directly to a Lite-On + * ethernet vendor code: + * + * 00-A0-CC LITE-ON COMMUNICATIONS, INC. + * + * The other code is probably for Kingston Technology, who + * distributed their own ethernet cards using Lite-On chips + * (confirmed via Google search of "00:C0 lite-on"): + * + * 00-C0-F0 KINGSTON TECHNOLOGY CORP. + * + * Ethernet vendor codes were found here: + * + * http://standards.ieee.org/regauth/oui/index.shtml + */ + if ((dev->dev_addr[0] == 0xA0 || dev->dev_addr[0] == 0xC0) + && dev->dev_addr[1] == 0x00) + return 1; + + /* + * Asante Technologies also produced an ethernet card based on + * the Lite-On chipset. + */ + { +#if defined(PCI_SUPPORT_VER1) + /* + * Fall back to checking for the ethernet vendor code: + * 00-00-94 ASANTE TECHNOLOGIES + */ + if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0x00 + && dev->dev_addr[3] == 0x94) + return 1; +#elif defined(PCI_SUPPORT_VER2) + /* + * Check the PCI (sub)vendor and (sub)device instead. + */ + struct pci_dev *pdev = pci_find_slot(pci_bus, pci_devfn); + u16 sub_vendor_id, sub_device_id; + + pcibios_read_config_word(pci_bus, pci_devfn, + PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id); + pcibios_read_config_word(pci_bus, pci_devfn, + PCI_SUBSYSTEM_ID, &sub_device_id); + + if (pdev->vendor == PCI_VENDOR_ID_LITEON + && pdev->device == PCI_DEVICE_ID_LITEON_LNE100TX + && sub_vendor_id == PCI_SUBVENDOR_ID_ASANTE + && sub_device_id == PCI_SUBDEVICE_ID_ASANTE_FAST_10_100_REV_B) + return 1; +#endif + } + + return 0; +} + static struct device *tulip_probe1(int pci_bus, int pci_devfn, struct device *dev, long ioaddr, int irq, int chip_idx, int board_idx) @@ -786,9 +858,9 @@ sum += ee_data[i + sa_offset]; } } - /* Lite-On boards have the address byte-swapped. */ - if ((dev->dev_addr[0] == 0xA0 || dev->dev_addr[0] == 0xC0) - && dev->dev_addr[1] == 0x00) + /* Boards with the Lite-On LC82C168 chipset have the address + byte-swapped. */ + if (needs_mac_addr_byte_swapped(pci_bus, pci_devfn, dev)) for (i = 0; i < 6; i+=2) { char tmp = dev->dev_addr[i]; dev->dev_addr[i] = dev->dev_addr[i+1]; diff -u kernel-source-2.2.20/include/linux/pci.h.orig kernel-source-2.2.20/include/linux/pci.h --- kernel-source-2.2.20/include/linux/pci.h.orig Fri Jul 4 18:33:54 2003 +++ kernel-source-2.2.20/include/linux/pci.h Sun Feb 1 20:16:55 2004 @@ -994,6 +994,9 @@ #define PCI_VENDOR_ID_LITEON 0x11ad #define PCI_DEVICE_ID_LITEON_LNE100TX 0x0002 +#define PCI_SUBVENDOR_ID_ASANTE 0x128a +#define PCI_SUBDEVICE_ID_ASANTE_FAST_10_100_REV_B 0xf001 + #define PCI_VENDOR_ID_NP 0x11bc #define PCI_DEVICE_ID_NP_PCI_FDDI 0x0001